CodeNarc-0.23/0000775000175000017500000000000012623571301012446 5ustar ebourgebourgCodeNarc-0.23/docs/0000775000175000017500000000000012623571301013376 5ustar ebourgebourgCodeNarc-0.23/docs/codenarc-rules-serialization.html0000644000175000017500000003744512471222417022062 0ustar ebourgebourg CodeNarc - CodeNarc - Serialization Rules

Serialization Rules ("rulesets/serialization.xml")

EnumCustomSerializationIgnored Rule

Since CodeNarc 0.19

Checks for enums that define writeObject() or writeReplace() methods, or declare serialPersistentFields or serialVersionUID fields, all of which are ignored for enums.

From the javadoc for ObjectOutputStream:

The process by which enum constants are serialized cannot be customized; any class-specific writeObject and writeReplace methods defined by enum types are ignored during serialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored--all enum types have a fixed serialVersionUID of 0L.

Example of violations:

    enum MyEnum {
        ONE, TWO, THREE
        private static final long serialVersionUID = 1234567L               // violation
        private static final ObjectStreamField[] serialPersistentFields =   // violation
            { new ObjectStreamField("name", String.class) }
        String name;

        Object writeReplace() throws ObjectStreamException { .. }      // violation
        private void writeObject(ObjectOutputStream stream) { .. }     // violation
    }

SerialPersistentFields Rule

New in CodeNarc 0.14

To use a Serializable object's serialPersistentFields correctly, it must be declared private, static, and final.

The Java Object Serialization Specification allows developers to manually define Serializable fields for a class by specifying them in the serialPersistentFields array. This feature will only work if serialPersistentFields is declared as private, static, and final. Also, specific to Groovy, the field must be of type ObjectStreamField[], and cannot be Object.

References:

  • Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 485
  • Sun Microsystems, Inc. Java Sun Tutorial

Example of violations:

    class MyClass implements Serializable {
        public ObjectStreamField[] serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[]
    }

    // the JVM sees the field type as Object, which won't work
    class MyOtherClass implements Serializable {
        private static final serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[]
    }

SerialVersionUID Rule

Since CodeNarc 0.11

A serialVersionUID is normally intended to be used with Serialization. It needs to be of type long, static, and final. Also, it should be declared private. Providing no modifier creates a Property and Groovy generates a getter, which is probably not intended.

From API javadoc for java.io.Serializable: It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.

SerializableClassMustDefineSerialVersionUID Rule

New in CodeNarc 0.13

Classes that implement Serializable should define a serialVersionUID. Deserialization uses this number to ensure that a loaded class corresponds exactly to a serialized object. If you don't define serialVersionUID, the system will make one by hashing most of your class's features. Then if you change anything, the UID will change and Java won't let you reload old data.

An example of a missing serialVersionUID:

    class MyClass imlements Serializable {
        // missing serialVersionUID
    }

CodeNarc-0.23/docs/codenarc-rules-exceptions.html0000644000175000017500000005066012471222412021353 0ustar ebourgebourg CodeNarc - CodeNarc - Exceptions Rules

Exceptions Rules ("rulesets/exceptions.xml")

CatchArrayIndexOutOfBoundsException Rule

Since CodeNarc 0.12

Checks for catching a ArrayIndexOutOfBoundsException. Catching ArrayIndexOutOfBoundsException should be avoided in the first place by checking the array size before accessing an array element. Catching the exception may mask underlying errors.

CatchError Rule

Checks for catching a Error. In most cases that is much too broad, and is also dangerous because it can catch exceptions such as ThreadDeath and OutOfMemoryError.

CatchException Rule

Checks for catching a Exception. In most cases that is too broad or general. It should usually be restricted to framework or infrastructure code, rather than application code.

CatchIllegalMonitorStateException Rule

Since CodeNarc 0.11

Dubious catching of IllegalMonitorStateException. IllegalMonitorStateException is generally only thrown in case of a design flaw in your code (calling wait or notify on an object you do not hold a lock on).

CatchIndexOutOfBoundsException Rule

Since CodeNarc 0.12

Checks for catching a IndexOutOfBoundsException. Catching IndexOutOfBoundsException should be avoided in the first place by checking for a valid index before accessing an indexed element. Catching the exception may mask underlying errors.

CatchNullPointerException Rule

Checks for catching a NullPointerException. Catching NullPointerException is never appropriate. It should be avoided in the first place with proper null checking, and it can mask underlying errors.

CatchRuntimeException Rule

Checks for catching a RuntimeException. In most cases that is too broad or general. It should usually be restricted to framework or infrastructure code, rather than application code.

CatchThrowable Rule

Checks for catching a Throwable. In most cases that is much too broad, and is also dangerous because it can catch exceptions such as ThreadDeath and OutOfMemoryError.

ConfusingClassNamedException Rule

Since CodeNarc 0.11

This class is not derived from another exception, but ends with 'Exception'. This will be confusing to users of this class.

ExceptionExtendsError Rule

New in CodeNarc 0.13

Errors are system exceptions. Do not extend them.

Examples:

    class MyError extends Error { }  // violation
    class MyError extends java.lang.Error { }  // violation

    class MyException extends Exception { }  // OK

ExceptionExtendsThrowable Rule

Since CodeNarc 0.21

Checks for classes that extend Throwable. Custom exception classes should subclass Exception or one of its descendants.

Example of violations:

    class MyException extends Throwable { }   // violation

ExceptionNotThrown Rule

Since CodeNarc 0.18

Checks for an exception constructor call without a throw as the last statement within a catch block. This rule treats any constructor call for a class named xxxException as an exception constructor call.

Example of violations:

    void execute() {
        try { } catch(Exception e) { new Exception(e) }     // violation
    }

    try {
        doStuff()
    } catch(DaoException e) {
        log.warning("Ooops", e)
        new ServiceException(e)                             // violation
    } catch(Exception e) {
        new SystemException(e)                              // violation
    }

    try {
        doStuff()
    } catch(Exception e) { throw new DaoException(e) }      // ok

MissingNewInThrowStatement Rule

Since CodeNarc 0.12

A common Groovy mistake when throwing exceptions is to forget the new keyword. For instance, throw RuntimeException() instead of throw new RuntimeException(). If the error path is not unit tested then the production system will throw a Method Missing exception and hide the root cause. This rule finds constructs like throw RuntimeException() that look like a new keyword was meant to be used but forgotten.

The following code will all cause violations:

    throw RuntimeException()    // ends in Exceptions, first letter Capitalized
    throw RuntimeFailure()      // ends in Failure, first letter Capitalized
    throw RuntimeFault(foo)     // ends in Fault, first letter Capitalized

The following code will not cause any exceptions:

    throw new RuntimeException()
    throw runtimeFailure()      // first letter lowercase, assumed to be method call

ReturnNullFromCatchBlock Rule

Since CodeNarc 0.11

Returning null from a catch block often masks errors and requires the client to handle error codes. In some coding styles this is discouraged. This rule ignores methods with void return type.

SwallowThreadDeath Rule

New in CodeNarc 0.14 Detects code that catches java.lang.ThreadDeath without re-throwing it.

Example of violations:

    try {
        def a = 0
    } catch (ThreadDeath td) {
        td.printStackTrace()
    }

ThrowError Rule

Checks for throwing an instance of java.lang.Error. This is not appropriate within normal application code. Throw an instance of a more specific exception subclass instead.

ThrowException Rule

Checks for throwing an instance of java.lang.Exception. Throw an instance of a more specific exception subclass instead.

ThrowNullPointerException Rule

Checks for throwing an instance of java.lang.NullPointerException. Applications should never throw a NullPointerException.

ThrowRuntimeException Rule

Checks for throwing an instance of java.lang.RuntimeException. Throw an instance of a more specific exception subclass instead.

ThrowThrowable Rule

Checks for throwing an instance of java.lang.Throwable. Throw an instance of a more specific exception subclass instead.


CodeNarc-0.23/docs/codenarc-XmlReportWriter.html0000644000175000017500000003424512471222421021174 0ustar ebourgebourg CodeNarc - CodeNarc XmlReportWriter

XmlReportWriter

Description

The org.codenarc.report.XmlReportWriter class (type="xml") produces an XML report of the CodeNarc results.

Note: This XML format is still being refined and is subject to change. Contact me if you have specific requirements or suggestions.

See a Sample XML Report. Also see the mrhaki blog post about creating custom CodeNarc HTML reports using XSLT.

Option Nested Elements

The option element is a child of the report element and defines a report-specific option for a report.

org.codenarc.report.XmlReportWriter supports the following options:

Attribute Description Required
outputFile The path and filename for the output report file. No
title The title for the output report. No
writeToStandardOut Set to "true" or true to write out the report to stdout (System.out) instead of writing to a file. No

Example

Here is an example Ant XML build file illustrating configuration of org.codenarc.report.XmlReportWriter. Note that the report type is specified as "xml".

<taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/>
<target name="runCodeNarc">
    <codenarc
            ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml"
            maxPriority1Violations="0">

        <report type="xml">
            <option name="outputFile" value="reports/CodeNarcXmlReport.xml" />
            <option name="title" value="My Sample Code" />
        </report>

        <fileset dir="src">
            <include name="**/*.groovy"/>
        </fileset>
    </codenarc>
</target>

CodeNarc-0.23/docs/codenarc-HtmlReportWriter.html0000644000175000017500000003524412471222403021340 0ustar ebourgebourg CodeNarc - CodeNarc HtmlReportWriter

HtmlReportWriter

Description

The org.codenarc.report.HtmlReportWriter class (type="html") produces an HTML report containing a table with summary results by package and a separate section for each package containing violations, and then a table of the rules applied, along with their descriptions.

See a Sample Report.

Alternatively, see the mrhaki blog post about creating custom CodeNarc HTML reports using XSLT.

Option Nested Elements

The option element is a child of the report element and defines a report-specific option for a report.

org.codenarc.report.HtmlReportWriter supports the following options:

Attribute Description Required
maxPriority The maximum priority level for violations in the report. For instance, setting maxPriority to 2 will result in the report containing only priority 1 and 2 violations (and omitting violations with priority 3). 3
outputFile The path and filename for the output report file. No
title The title for the output report. No
writeToStandardOut Set to true to write out the report to stdout (System.out) instead of writing to a file. No
includeSummaryByPackage Set to false to exclude the violation summary for each package within the "Summary" section of the report. It defaults to true.

Example

Here is an example Ant XML build file illustrating configuration of org.codenarc.report.HtmlReportWriter. Note that the report type is specified as "html".

<taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/>
<target name="runCodeNarc">
    <codenarc
            ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml"
            maxPriority1Violations="0">

        <report type="html">
            <option name="outputFile" value="reports/CodeNarcAntReport.html" />
            <option name="title" value="My Sample Code" />
        </report>

        <fileset dir="src">
            <include name="**/*.groovy"/>
        </fileset>
    </codenarc>
</target>

CodeNarc-0.23/docs/codenarc-rules-unnecessary.html0000644000175000017500000015604312471222420021532 0ustar ebourgebourg CodeNarc - CodeNarc - Unnecessary Rules

Unnecessary Rules ("rulesets/unnecessary.xml")

AddEmptyString Rule

New in CodeNarc 0.13

Finds empty string literals which are being added. This is an inefficient way to convert any type to a String.

Examples:

    // do not add empty strings to things
    def a = '' + 123
    def b = method('' + property)

    // these examples are OK and do not trigger violations
    def c = 456.toString()
    def d = property?.toString() ?: ""

ConsecutiveLiteralAppends Rule

New in CodeNarc 0.13

Violations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation.

Example of violations:

    writer.append('foo').append('bar')      // strings can be joined
    writer.append('foo').append(5)          // string and number can be joined
    writer.append('Hello').append("$World") // GString can be joined

Example of passing code:

    // usage not chained invocation
    writer.append('Hello')
    writer.append('World')

    writer.append(null).append(5)           // nulls cannot be joined

    writer.append().append('Hello')             // no arg append is unknown
    writer.append('a', 'b').append('Hello')     // two arg append is unknown

ConsecutiveStringConcatenation Rule

New in CodeNarc 0.13

Catches concatenation of two string literals on the same line. These can safely by joined. In Java, the Java compiler will join two String literals together and place them in the Constant Pool. However, Groovy will not because the plus() method may override the + operator.

Examples:

    // Violations
    def a = 'Hello' + 'World'   // should be 'HelloWorld'
    def b = "$Hello" + 'World'  // should be "${Hello}World"
    def c = 'Hello' + "$World"  // should be "Hello${World}"
    def d = 'Hello' + 5         // should be 'Hello5'
    def e = 'Hello' + '''
                        world   // should be joined
                      '''
    def f = '''Hello
                  ''' + 'world'   // should be joined


    // Not Violations
    def g = 'Hello' +           // OK because of line break
                'World'
    def h = 'Hello' + null      // OK because not a string
    def i = 'Hello' + method()  // OK because not a string
    def j = 'Hello' - "$World"  // OK because not +

UnnecessaryBigDecimalInstantiation Rule

Since CodeNarc 0.12

It is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G.

This rule does not produce violations when the parameter evaluates to an integer/long, e.g. new BigDecimal(42), new BigDecimal(42L) or new BigDecimal("42"), because using the "G" suffix on an integer value produces a BigInteger, rather than a BigDecimal, e.g. 45G. So that means there is no way to produce a BigDecimal with exactly that value using a literal.

This rule also does not produce violations when the parameter is a double, e.g. new BigDecimal(12.3). That scenario is covered by the BigDecimalInstantiation rule, because that produces an unpredictable (double) value (and so it is unsafe, rather than unnecessary).

UnnecessaryBigIntegerInstantiation Rule

Since CodeNarc 0.12

It is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G.

UnnecessaryBooleanExpression Rule

Checks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or a Map/List/String/Number literal.

This rule also checks for negation (!) of true, false, null, or a Map/List/String/Number literal.

Examples of violations include:

    result = value && true              // AND or OR with boolean constants
    if (false || value) { .. }
    return value && Boolean.FALSE

    result = null && value              // AND or OR with null

    result = value && "abc"             // AND or OR with String literal

    result = value && 123               // AND or OR with Number literal
    result = 678.123 || true

    result = value && [x, y]            // AND or OR with List literal

    result = [a:123] && value           // AND or OR with Map literal

    result = !true                      // Negation of boolean constants
    result = !false
    result = !Boolean.TRUE

    result = !null                      // Negation of null

    result = !"abc"                     // Negation of String literal

    result = ![a:123]                   // Negation of Map literal

    result = ![a,b]                     // Negation of List literal

UnnecessaryBooleanInstantiation Rule

Since CodeNarc 0.12 (formerly BooleanInstantiation Rule in the "basic" rule set)

Checks for direct call to a Boolean constructor. Use Boolean.valueOf() or the Boolean.TRUE and Boolean.FALSE constants instead of calling the Boolean() constructor directly.

Also checks for Boolean.valueOf(true) or Boolean.valueOf(false). Use the Boolean.TRUE or Boolean.FALSE constants instead.

Here is an example of code that produces a violation:

    def b1 = new Boolean(true)             // violation
    def b2 = new java.lang.Boolean(false)  // violation
    def b3 = Boolean.valueOf(true)         // violation
    def b4 = Boolean.valueOf(false)        // violation

UnnecessaryCallForLastElement Rule

Since CodeNarc 0.12

This rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a get, getAt, or array-style access is used with an object size check.

Code like this all cause violations.

    def x = [0, 1, 2]
    def a = x.get(x.size() -1)
    def b = x.get(x.length -1)
    def c = x.getAt(x.size() -1)
    def d = x.getAt(x.length -1)
    def f = x[(x.size() -1]
    def d = x[(x.length -1]

All of this code is fine though:

    def x = [0, 1, 2]
    def a = x.last()
    def b = x[-1]
    def c = x.getAt(-1)
    def d = x.get(z.size() -1)     // different objects
    def e = x.get(z.length -1)     // different objects
    def f = x.getAt(z.size() -1)   // different objects

UnnecessaryCallToSubstring Rule

New in CodeNarc 0.13

Calling String.substring(0) always returns the original string. This code is meaningless.

Examples:

    string.substring(0)         // violation
    method().substring(0)       // violation

    prop.substring(1)           // OK, not constant 0
    prop.substring(0, 1)        // OK, end is specified

UnnecessaryCast Rule

Since CodeNarc 0.21

Checks for unnecessary cast operations.

Example of violations:

    int count = (int)123                    // violation
    def longValue = (long)123456L           // violation
    def bigDecimal = (BigDecimal)1234.56    // violation
    String name = (String) "Joe"            // violation
    def list = (List)[1, 2, 3]              // violation
    def map = (Map)[a:1]                    // violation

UnnecessaryCatchBlock Rule

Since CodeNarc 0.12

Violations are triggered when a catch block does nothing but throw the original exception. In this scenario there is usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out.

UnnecessaryCollectCall Rule

Since CodeNarc 0.12

Some method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect it.multiply(2) can be replaced by list*.multiply(2).

Examples of violations include:

    assert [1, 2, 3].collect { it.multiply(2) }
    assert [1, 2, 3].collect { x -> x.multiply(2) }
    ["1", "2", "3"].collect { it.bytes }

The following code does not produce violations:

    [1, 2, 3].collect { it * it }   // OK, closure parameter is referenced twice

    [1, 2, 3].mapMethod { it.multiply(5) } // OK, method call is not collect

    [1, 2, 3].collect(5) // OK, collect parameter is not a closure

    // OK, the closure is not a simple one line statement
    [1, 2, 3].collect { println it; it.multiply(5) }

    // OK, closure has too many arguments
    [1, 2, 3].collect { a, b -> a.multiply(b) }

    // OK, closure statement references parameter multiple times
    [1, 2, 3].collect { it.multiply(it) }

    // OK, it is referenced several times in the closure
    [1, 2, 3].collect { it.multiply(2).multiply(it) }
    ["1", "2", "3"].collect { it.bytes.foo(it) }

    // OK, chained methods are too complex to analyze at this point
    [1, 2, 3].collect { it.multiply(2).multiply(4) }

    // in general the above examples can be rewritten like this:
    [1, 2, 3]*.multiply(2)
    ["1", "2", "3"]*.bytes

UnnecessaryCollectionCall Rule

Since CodeNarc 0.11

Checks for useless calls to collections. For any collection c, calling c.containsAll(c) should always be true, and c.retainAll(c) should have no effect.

UnnecessaryConstructor Rule

Since CodeNarc 0.11

This rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments, or else contains only a single call to super().

Example of violations:

    class MyClass {
        public MyClass() {          // violation; constructor is not necessary
        }
    }

    class MyClass2 extends OtherClass {
        MyClass2() {                // violation; constructor is not necessary
            super()
        }
    }

UnnecessaryDefInFieldDeclaration Rule

New in CodeNarc 0.16

If a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = ' is redundant and can be simplified to 'static constraints = .

Example of violations:

    class MyClass {
        // def is redundant
        static def constraints = {  }

        // def and private is redundant
        def private field1 = { }

        // def and protected is redundant
        def protected field2 = { }

        // def and public is redundant
        def public field3 = { }

        // def and static is redundant
        def static field4 = { }

        // def and type is redundant
        def Object field5 = { }
    }

UnnecessaryDefInMethodDeclaration Rule

New in CodeNarc 0.13

If a method has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private method() ' is redundant and can be simplified to 'private method() '.

Examples of violations:

    // def and private is redundant
    def private method1() { return 4 }

    // def and protected is redundant
    def protected method2() { return 4 }

    // def and public is redundant
    def public method3() { return 4 }

    // def and static is redundant
    def static method4() { return 4 }

    // def and type is redundant
    def Object method5() { return 4 }

    class MyClass {
        def MyClass() {}    // def is redundant
    }

UnnecessaryDefInVariableDeclaration Rule

New in CodeNarc 0.15

If a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'.

Examples of violations:

    // def and private is redundant
    def private string1 = 'example'

    // def and protected is redundant
    def protected string2 = 'example'

    // def and public is redundant
    def public string3 = 'example'

    // def and static is redundant
    def static string4 = 'example'

    // def and final is redundant
    def final string5 = 'example'

    // def and a type is redundant
    def String string6 = 'example'

UnnecessaryDotClass Rule

New in CodeNarc 0.15

To make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String.

Example of violations:

    // The '.class' identifier is unnecessary, violation occurs
    def x = String.class

    // Ok, unnecessary '.class' identifier has been excluded
    def x = String

UnnecessaryDoubleInstantiation Rule

Since CodeNarc 0.12

It is unnecessary to instantiate Double objects. Instead just use the double literal with 'D' identifier to force the type, such as 123.45d or 0.42d.

UnnecessaryElseStatement Rule

New in CodeNarc 0.14

When an if statement block ends with a return statement, then the else is unnecessary. The logic in the else branch can be run without being in a new scope.

Example of violations:

    if(value){
        println 'Executing if logic...'
        return true
    } else {
        println 'Executing else logic...'
    }

    // can be replaced by:

    if(value){
        println 'Executing if logic...'
        return true
    }
    println 'Executing else logic...'

UnnecessaryFinalOnPrivateMethod Rule

New in CodeNarc 0.14

A private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary.

Example of violations:

    private final method() {}

UnnecessaryFloatInstantiation Rule

Since CodeNarc 0.12

It is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f.

UnnecessaryGetter Rule

Since CodeNarc 0.12

Checks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). Getters do not take method arguments.

These bits of code produce violations:

    x.getProperty()
    x.getFirst()
    x.getFirstName()
    x.getA()

These bits of code do not:

    x.property
    x.first
    x.firstName
    x.a
    x.getURL()
    x.getClass()
    x.getProperty('key')

UnnecessaryGString Rule

New in CodeNarc 0.13

String objects should be created with single quotes, and GString objects created with double quotes. Creating normal String objects with double quotes is confusing to readers.

Example of violations:

    def a = "I am a string"     // violation

    // violation
    def b = """
        I am a string
    """

    def c = "I am a ' string"       // OK

    def d = """I am a ' string"""   // OK

    def e = """I am a ' string"""   // OK

    def f = "I am a \$ string"  // OK

    // OK
    def g = """
        I am a \$ string
    """

    // OK
    def h = """
        I am a $string
    """

    def i = 'i am a string'
    def j = '''i am a
        string
    '''

UnnecessaryIfStatement Rule

Checks for unnecessary if statements. The entire if statement, or at least the if or else block, are considered unnecessary for the four scenarios described below.

(1) When the if and else blocks contain only an explicit return of true and false constants. These cases can be replaced by a simple return statement. Examples of violations include:

    if (someExpression)         // can be replaced by: return someExpression
        return true
    else
        return false

    if (someExpression) {       // can be replaced by: return !someExpression
        return false
    } else {
        return true
    }

    if (someExpression) {       // can be replaced by: return someExpression
        return Boolean.TRUE
    } else {
        return Boolean.FALSE
    }

(2) When the if statement is the last statement in a block and the if and else blocks are only true and false expressions. This is an implicit return of true/false. For example, the if statement in the following code can be replaced by someExpression or someExpression as boolean:

    def myMethod() {
        doSomething()
        if (someExpression)
            true
        else false
    }

(3) When the second-to-last statement in a block is an if statement with no else, where the block contains a single return statement, and the last statement in the block is a return statement, and one return statement returns a true expression and the other returns a false expression. This check is disabled by setting checkLastStatementImplicitElse to false. For example, the if statement in the following code can be replaced by return expression1:

    def myMethod() {
        doSomething()
        if (expression1) {
            return true
        }
        return false
    }

(4) When either the if block or else block of an if statement that is not the last statement in a block contain only a single constant or literal expression. For example, the if statement in the following code has no effect and can be removed:

    def myMethod() {
        if (someExpression) { 123 }
        doSomething()
    }

UnnecessaryInstanceOfCheck Rule

New in CodeNarc 0.15

This rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean.

Example of violations:

    if (!variable instanceof String) { ... }    // always false
    def x = !variable instanceof String         // always false

    if (!variable instanceof Boolean) { ... }    // always true
    def x = !variable instanceof Boolean         // always true

    // this code is OK
    if (!(variable instanceof String)) { ... }

UnnecessaryInstantiationToGetClass Rule

Since in CodeNarc 0.12

Avoid instantiating an object just to call getClass() on it; use the .class public member instead.

    public class Foo {
     // Replace this
     Class c = new String().getClass();

     // with this:
     Class c = String.class;
    }

UnnecessaryIntegerInstantiation Rule

Since CodeNarc 0.12

It is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i.

UnnecessaryLongInstantiation Rule

Since CodeNarc 0.12

It is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L.

UnnecessaryModOne Rule

New in CodeNarc 0.13

Any expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2).

Examples:

    if (exp % 1) {}         // violation
    if (method() % 1) {}    // violation

    if (exp & 1) {}     // ok
    if (exp % 2) {}     // ok

UnnecessaryObjectReferences Rule

Since CodeNarc 0.12

Violations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block. By default, 5 references are allowed. You can override this property using the maxReferencesAllowed> property on the rule.

These two bits of code produce violations:

    def p1 = new Person()
    p1.firstName = 'Hamlet'
    p1.lastName = "D'Arcy"
    p1.employer = 'Canoo'
    p1.street = 'Kirschgaraten 5'
    p1.city = 'Basel'
    p1.zipCode = '4051'

    def p2 = new Person()
    p2.setFirstName('Hamlet')
    p2.setLastName("D'Arcy")
    p2.setEmployer('Canoo')
    p2.setStreet('Kirschgaraten 5')
    p2.setCity('Basel')
    p2.setZipCode('4051')

However, these two bits of code do not because they use either a with or identity block.

    def p1 = new Person().with {
        firstName = 'Hamlet'
        lastName = "D'Arcy"
        employer = 'Canoo'
        street = 'Kirschgaraten 5'
        city = 'Basel'
        zipCode = '4051'
    }

    def p2 = new Person().identity {
        firstName = 'Hamlet'
        lastName = "D'Arcy"
        employer = 'Canoo'
        street = 'Kirschgaraten 5'
        city = 'Basel'
        zipCode = '4051'
    }

UnnecessaryNullCheck Rule

Since CodeNarc 0.12

Groovy contains the safe dereference operator. It can be used in boolean conditional statements to safely replace explicit x == null tests. Also, testing the 'this' or 'super' reference for null equality is pointless and can be removed.

Examples of violations:

    if (obj != null && obj.method()) { }

    if (obj != null && obj.prop) { }

    // this is pointless and won't avoid NullPointerException
    if (obj.method() && obj != null ) { }

    if (this == null) { }
    if (null == this) { }
    if (this != null) { }
    if (null != this) { }

    if (super == null) { }
    if (null == super) { }
    if (super != null) { }
    if (null != super) { }

Examples of acceptable code:

    // null check it OK
    if (obj != null) { }

    // null safe dereference in if is OK
    if (obj?.method()) { }

    // null safe dereference in ternary is OK
    (obj?.prop && obj?.prop2) ? x : y

    // obj is reused in a parameter list, so OK
    if (obj != null && obj.method() && isValid(obj)) { }

    // rule is not so complex yet...
    (obj != null && obj.prop && obj.method()) ? x : y

UnnecessaryNullCheckBeforeInstanceOf Rule

Since CodeNarc 0.12

There is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.

Example:

    if (x != null && x instanceof MyClass) {
        // should drop the "x != null" check
    }

    if (x instanceof MyClass && x != null) {
        // should drop the "x != null" check
    }

    // should drop the "x != null" check
    (x != null && x instanceof MyClass) ? foo : bar

    if (x != null && x instanceof MyClass && x.isValid()) {
        // this is OK and causes no violation because the x.isValid() requires a non null reference
    }

UnnecessaryOverridingMethod Rule

Since CodeNarc 0.11

Checks for an overriding method that merely calls the same method defined in a superclass. Remove it.

UnnecessaryPackageReference Rule

Since CodeNarc 0.14

Checks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, java.util.Map and groovy.lang.Closure, as well as classes that were explicitly imported.

You do not need to specify the package for any classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger.

Examples of violations include:

    // Field types
    class MyClass {
        java.math.BigDecimal amount = 42.10                     // violation
    }

    // Within expressions
    if (value.class == java.math.BigInteger) { }                // violation
    println "isClosure=${v instanceof groovy.lang.Closure}"     // violation
    def p = java.lang.Runtime.availableProcessors()             // violation

    // Constructor calls
    def url = new java.net.URL('http://abc@example.com')        // violation

    // Variable types
    void doSomething() {
        java.math.BigInteger maxValue = 0                       // violation
        java.net.URI uri                                        // violation
    }

    // Method return types
    java.io.Reader getReader() { }                              // violation
    groovy.util.AntBuilder getAntBuilder() { }                  // violation

    // Method parameter types
    void writeCount(java.io.Writer writer, int count) { }       // violation
    void init(String name, groovy.lang.Binding binding) { }     // violation

    // Closure parameter types
    def writeCount = { java.io.Writer writer, int count -> }    // violation

    // Extends and implements
    class MyHashMap extends java.util.HashMap { }               // violation
    class MyList implements java.util.List { }                  // violation

    // Explicitly imported classes
    import javax.servlet.http.Cookie
    import javax.sql.DataSource

    class MyClass {
        void doStuff(javax.servlet.http.Cookie cookie) {        // violation
            def dataSource = [:] as javax.sql.DataSource        // violation
        }
    }

Known limitations:

  • Does not catch class declarations that explicitly extend java.lang.Object. For instance, class MyClass extends java.lang.Object . Just don't do that, okay?
  • Does not catch class declarations that explicitly extend groovy.lang.Script. For instance, class MyScript extends groovy.lang.Script . Don't do that, either!
  • Does not catch unnecessary package references if they are the types of anonymous inner class definitions, for older versions of Groovy ( 1.7.10?). For instance, <<<def runnable = new java.lang.Runnable() ... >>.

UnnecessaryParenthesesForMethodCallWithClosure Rule

New in CodeNarc 0.14

If a method is called and the only parameter to that method is an inline closure then the parentheses of the method call can be omitted.

Example of violations:

    [1,2,3].each() { println it }

UnnecessaryPublicModifier Rule

New in CodeNarc 0.13

The 'public' modifier is not required on methods, constructors or classes.

Example of violations:

    // violation on class
    public class MyClass {
        // violation on constructor
        public MyClass() {}

        // violation on method
        public void myMethod() {}
    }

UnnecessaryReturnKeyword Rule

Since CodeNarc 0.11

In Groovy, the return keyword is often optional. If a statement is the last line in a method or closure then you do not need to have the return keyword.

UnnecessarySafeNavigationOperator Rule

Since CodeNarc 0.22

Check for the safe navigation operator (?.) applied to constants and literals, or this or super, or constructor calls, all of which can never be null.

Example of violations:

    def myMethod() {
        "abc"?.bytes            // violation
        [1,2]?.getSize()        // violation
        [abc:123]?.name         // violation
        [:]?.toString()         // violation
        123?.class              // violation
        123.45?.getClass()      // violation
        Boolean.FALSE?.class    // violation
        Boolean.TRUE?.class     // violation
        this?.class             // violation
        super?.getClass()       // violation
        new Long(100)?.class    // violation
    }

UnnecessarySelfAssignment Rule

New in CodeNarc 0.13

Method contains a pointless self-assignment to a variable or property. Either the code is pointless or the equals()/get() method has been overridden to have a side effect, which is a terrible way to code getters and violates the contract of equals().

Examples:

    x = x               // violation
    def method(y) {
        y = y           // violation
    }
    a.b.c = a.b.c       // violation

    x = y               // acceptable
    a.b = a.zz          // acceptable
    a.b = a().b         // acceptable

UnnecessarySemicolon Rule

New in CodeNarc 0.13

Semicolons as line terminators are not required in Groovy: remove them. Do not use a semicolon as a replacement for empty braces on for and while loops; this is a confusing practice.

The rule contains a String property called 'excludePattern'. Any source code line matching this pattern will not trigger a violation. The default value is '\s?\*.*|/\*.*|.*//.*|.*\*/.*' This is to filter out comments. Any source line that even looks like it is a comment is ignored.

\s?*.* == whitespace plus star character plus anything /*.* == any line that contains the /* sequence .*//.* == any line that contains the // sequence .**/.* == any line that contains the */ sequence

Example of violations:

    package my.company.server;  // violation

    import java.lang.String;    // violation

    println(value) ;             // violation

    for (def x : list);         // violation

    // this code is OK
    println(value); println (otherValue)

UnnecessarySubstring Rule

Since CodeNarc 0.15

This rule finds usages of String.substring(int) and String.substring(int, int) that can be replaced by use of the subscript operator. For instance, var.substring(5) can be replaced with var[5..-1].

Note that the String.substring(beginIndex,endIndex) method specifies a range of beginIndex..endIndex-1, while Groovy's String subscript specifies an inclusive range. So, "123456".substring(1, 5) is equivalent to "123456"[1..4].

Example of violations:

    myVar.substring(5)          // can use myVar[5..-1] instead
    myVar.substring(1, 5)       // can use myVar[1..4] instead

UnnecessaryStringInstantiation Rule

Since CodeNarc 0.12 (formerly StringInstantiation Rule in the "basic" rule set)

Checks for direct call to the String constructor that accepts a String literal. In almost all cases, this is unnecessary. Use a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.

Here is an example of code that produces a violation:

    def s = new String('abc')

UnnecessaryTernaryExpression Rule

Checks for ternary expressions where the conditional expression always evaluates to a boolean and the true and false expressions are merely returning true and false constants. These cases can be replaced by a simple boolean expression. Examples of violations include:

    x==99 ? true : false                    // can be replaced by: x==99
    x && y ? true : false                   // can be replaced by: x && y
    x||y ? false : true                     // can be replaced by: !(x||y)
    x >= 1 ? true: false                    // can be replaced by: x >= 1
    x < 99 ? Boolean.TRUE : Boolean.FALSE   // can be replaced by: x < 99
    !x ? true : false                       // can be replaced by: !x

The rule also checks for ternary expressions where the true and false expressions are the same constant or variable. Examples include:

    x ? '123' : '123'              // can be replaced by: '123'
    x ? null : null                // can be replaced by: null
    x ? 23 : 23                    // can be replaced by: 23
    x ? MAX_VALUE : MAX_VALUE      // can be replaced by: MAX_VALUE
    ready ? minValue : minValue    // can be replaced by: minValue

UnnecessaryTransientModifier Rule

New in CodeNarc 0.13

The field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect. This may be leftover marking from a previous version of the code in which the class was transient, or it may indicate a misunderstanding of how serialization works.

Some Java frameworks change the semantics of the transient keyword. For instance, when using Terracotta the transient keyword may have slightly different semantics. You may need to turn this rule off depending on which Java frameworks are in use.

Examples:

    class MyClass {
        // class not serializable, violation occurs
        transient String property
    }

    class MySerializableClass implements Serializable {
        // OK, class is serializable
        transient String property
    }

UnnecessaryToString Rule

Since CodeNarc 0.21

Checks for unnecessary calls to toString(). This includes:

  • Calls to toString() on a String literal or expression
  • Calls to toString() for the value assigned to a String field or variable (if checkAssignments is true).
Property Description Default Value
checkAssignments If true, then check for calls to toString() for the value assigned to a String field or variable. true

Example of violations:

    def name = "Joe".toString()                             // violation - string literal
    def groupId = ((String)row.get('GroupID')).toString()   // violation - string expression

    class MyClass {
        String name = nameNode.toString()           // violation - field
        String code = account.getCode().toString()  // violation - field

        void run() {
            String name = nameNode.toString()       // violation - variable
            String id = account.id.toString()       // violation - variable
        }
    }

CodeNarc-0.23/docs/codenarc-rules-grails.html0000644000175000017500000006403012471222413020450 0ustar ebourgebourg CodeNarc - CodeNarc - Grails Rules

Grails Rules ("rulesets/grails.xml")

GrailsDomainHasEquals Rule

Since CodeNarc 0.15

Checks that Grails domain classes redefine equals().

Ignores classes annotated with @EqualsAndHashCode or @Canonical.

This rule sets the default value of applyToFilesMatching to only match files under the 'grails-app/domain' folder. You can override this with a different regular expression value if appropriate.

GrailsDomainHasToString Rule

Since CodeNarc 0.15

Checks that Grails domain classes redefine toString().

Ignores classes annotated with @ToString or @Canonical.

This rule sets the default value of applyToFilesMatching to only match files under the 'grails-app/domain' folder. You can override this with a different regular expression value if appropriate.

GrailsDomainReservedSqlKeywordName Rule

Since CodeNarc 0.19

Forbids usage of SQL reserved keywords as class or field names in Grails domain classes. Naming a domain class (or its field) with such a keyword causes SQL schema creation errors and/or redundant table/column name mappings.

Note: due to limited type information available during CodeNarc's operation, this rule will report fields of type java.io.Serializable, but not of its implementations. Please specify any implementations used as domain properties in additionalHibernateBasicTypes.

Property Description Default Value
additionalHibernateBasicTypes Comma-separated list of simple class names of additional classes that Hibernate maps as basic types (creates a column for a field of such class). Add your custom basic types here. ''
additionalReservedSqlKeywords Comma-separated list of additional reserved SQL keywords (just in case the 337 keywords of nowadays SQL-* standards weren't enough). ''

GrailsDomainWithServiceReference Rule

Since CodeNarc 0.19

Checks that Grails Domain classes do not have Service classes injected.

This rule sets the default value of applyToFilesMatching to only match files under the 'grails-app/domain' folder. You can override this with a different regular expression value if appropriate.

GrailsDuplicateConstraint Rule

Since CodeNarc 0.18

Check for duplicate name in a Grails domain class constraints. Duplicate names/entries are legal, but can be confusing and error-prone.

NOTE: This rule does not check that the values of the entries are duplicated, only that there are two entries with the same name.

Example of violations:

    class Person {
        String firstName
        String lastName

        static constraints = {
            firstName nullable:true
            lastName nullable:true, maxSize:30
            firstName nullable:false                // violation
        }
    }

GrailsDuplicateMapping Rule

Since CodeNarc 0.18

Check for duplicate name in a Grails domain class mapping. Duplicate names/entries are legal, but can be confusing and error-prone.

NOTE: This rule does not check that the values of the entries are duplicated, only that there are two entries with the same name.

Example of violations:

    class Person {
        String firstName
        String lastName

        static mapping = {
            table 'people'
            firstName column: 'First_Name'
            lastName column: 'Last_Name'
            firstName column: 'First_Name'      // violation
            table 'people2'                     // violation
        }
    }

GrailsMassAssignment Rule

Since CodeNarc 0.21

Untrusted input should not be allowed to set arbitrary object fields without restriction.

Example of violations:

   // Person would be a grails domain object
   def person = new Person(params)
   person.save()

   // or using .properties
   def person = Person.get(1)
   person.properties = params
   person.save()

GrailsPublicControllerMethod Rule (disabled)

NOTE: This rule has been disabled by default (i.e., by setting its enabled property to false). Given that Grails 2.x allows and encourages controller actions to be defined as methods instead of closures, this rule makes no sense for Grails 2.x projects.

Rule that checks for public methods on Grails controller classes. Static methods are ignored.

Grails controller actions and interceptors are defined as properties on the controller class. Public methods on a controller class are unnecessary. They break encapsulation and can be confusing.

Property Description Default Value
ignoreMethodNames Specifies one or more (comma-separated) method names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

This rule sets the default value of applyToFilesMatching to only match files under the 'grails-app/controllers' folder. You can override this with a different regular expression value if appropriate.

This rule also sets the default value of applyToClassNames to only match class names ending in 'Controller'. You can override this with a different class name pattern (String with wildcards) if appropriate.

GrailsServletContextReference Rule

Rule that checks for references to the servletContext object from within Grails controller and taglib classes.

This rule is intended as a "governance" rule to enable monitoring and controlling access to the servletContext from within application source code. Storing objects in the servletContext may inhibit scalability and/or performance and should be carefully considered. Furthermore, access to the servletContext is not synchronized, so reading/writing objects from the servletConext must be manually synchronized, as described in The Definitive Guide to Grails (2nd edition).

Note that this rule does not check for direct access to the servletContext from within GSP (Groovy Server Pages) files.

Enabling this rule may make most sense in a team environment where team members exhibit a broad range of skill and experience levels. Appropriate servletContext access can be configured as exceptions to this rule by configuring either the doNotApplyToFilenames or doNotApplyToFilesMatching property of the rule. And, as always, it is easy to just turn off the rule if it does not make sense it your environment.

This rule sets the default value of applyToFilesMatching to only match files under the 'grails-app/controllers' or 'grails-app/taglib' folders. You can override this with a different regular expression value if appropriate.

GrailsSessionReference Rule (deprecated)

NOTE: This rule has been DEPRECATED, and disabled by default (i.e., by setting its enabled property to false). Please email the CodeNarc User Mailing List if you have an opinion for/against deprecation and eventual removal of this rule.

Rule that checks for references to the session object from within Grails controller and taglib classes.

This rule is intended as a "governance" rule to enable monitoring and controlling access to the session from within application source code. Storing objects in the session may inhibit scalability and/or performance and should be carefully considered.

Note that this rule does not check for direct access to the session from within GSP (Groovy Server Pages) files.

Enabling this rule may make most sense in a team environment where team members exhibit a broad range of skill and experience levels. Appropriate session access can be configured as exceptions to this rule by configuring either the doNotApplyToFilenames or doNotApplyToFilesMatching property of the rule. And, as always, it is easy to just turn off the rule if it does not make sense it your environment.

This rule sets the default value of applyToFilesMatching to only match files under the 'grails-app/controllers' or 'grails-app/taglib' folders. You can override this with a different regular expression value if appropriate.

GrailsStatelessService Rule

Checks for non-final fields on a Grails service class. Grails service classes are singletons by default, and so they should be reentrant. In most cases, this implies (or at least encourages) that they should be stateless.

This rule ignores (i.e., does not cause violations for) the following:

  • All final fields (either instance or static). Note that fields that are static and non-final, however, do cause a violation.
  • Non-static properties (i.e., no visibility modifier specified) declared with def.
  • All classes annotated with the @Immutable transformation. See http://groovy.codehaus.org/Immutable+transformation.
  • All fields annotated with the @Inject annotation.
  • All fields with names matching the ignoreFieldNames property.
  • All fields with types matching the ignoreFieldTypes property.

The ignoreFieldNames property of this rule is preconfigured to ignore the standard Grails service configuration field names ('scope', 'transactional') and the standard injected bean names ('dataSource', 'sessionFactory'), as well as all other field names ending with 'Service'.

Property Description Default Value
ignoreFieldNames Specifies one or more (comma-separated) field names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). 'dataSource,scope,sessionFactory, transactional,*Service'
addToIgnoreFieldNames Specifies one or more (comma-separated) field names to be added to the ignoreFieldNames property value. This is a special write-only property, and each call to setAddIgnoreFieldNames() adds to (rather than overwrites) the list of field names to be ignored. null
ignoreFieldTypes Specifies one or more (comma-separated) field types that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

This rule sets the default value of applyToFilesMatching to only match files under the 'grails-app/services' folder. You can override this with a different regular expression value if appropriate.

This rule also sets the default value of applyToClassNames to only match class names ending in 'Service'. You can override this with a different class name pattern (String with wildcards) if appropriate.

Notes

  1. The ignoreFieldTypes property matches the field type name as indicated in the field declaration, only including a full package specification IF it is included in the source code. For example, the field declaration BigDecimal value matches an ignoreFieldTypes value of BigDecimal, but not java.lang.BigDecimal.
  2. There is one exception for the ignoreFieldTypes property: if the field is declared with a modifier/type of def, then the type resolves to java.lang.Object.

CodeNarc-0.23/docs/codenarc-roadmap.html0000644000175000017500000003032212471222406017461 0ustar ebourgebourg CodeNarc - CodeNarc Road Map

CodeNarc - Road Map

Suggestions or preferences? Create a Feature Request.

Short-Term Goals (Imminent)

  • More rules
  • Performance improvements.

Long-Term Goals

  • Even more rules, perhaps including framework-specific rules for Grails (additional), Griffon, Gradle, etc..
  • Improve performance
  • Analyze source code within jar files or zip files, and/or within Subversion, Git or CVS repositories.

Considering (Optional)

  • Create Netbeans plugin.
  • Localization of report text.

CodeNarc-0.23/docs/codenarc-rules-groovyism.html0000644000175000017500000010302212471222414021221 0ustar ebourgebourg CodeNarc - CodeNarc - Groovyism Rules

Groovy-ism Rules ("rulesets/groovyism.xml")

These are rules covering Groovy idiomatic usage, and Groovy-specific bad practices.

AssignCollectionSort Rule

New in CodeNarc 0.15

The Collections.sort() method mutates the list and returns the list as a value. If you are assigning the result of sort() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. This violation is triggered when a sort() method call appears as the right hand side of an assignment, or when it appears as the first method call in a series of chained method calls.

Example of violations:

  def a = myList.sort()
  def b = myList.sort() { it }
  def c = myList.sort().findAll { x < 1 }

AssignCollectionUnique Rule

New in CodeNarc 0.15

The Collections.unique() method mutates the list and returns the list as a value. If you are assigning the result of unique() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. This violation is triggered when a unique() method call appears as the right hand side of an assignment, or when it appears as the first method call in a series of chained method calls.

Example of violations:

  def a = myList.unique()
  def b = myList.unique() { it }
  def c = myList.unique().findAll { x < 1 }

ClosureAsLastMethodParameter Rule

New in CodeNarc 0.14

If a method is called and the last parameter is an inline closure then it can be declared outside of the method call parentheses.

Example of violations:

    // creates violation: poor Groovy style
    [1,2,3].each({ println it })

    // no violation
    [1,2,3].each { println it }

CollectAllIsDeprecated Rule

New in CodeNarc 0.16

The collectAll method is deprecated since Groovy 1.8.1. Use collectNested instead.

Example of violations:

def list = [1, 2, [3, 4, [5, 6]], 7]

list.collectAll { it * 2 }      // deprecated

list.collectNested { it * 2 }   // replacement

ConfusingMultipleReturns Rule

New in CodeNarc 0.16

Multiple return values can be used to set several variables at once. To use multiple return values, the left hand side of the assignment must be enclosed in parenthesis. If not, then you are not using multiple return values, you're only assigning the last element.

Example of violations:

def a, b = [1, 2] // bad, b is null
def c, d, e = [1, 2, 3] // bad, c and d are null
class MyClass {
    def a, b, c = [1, 2, 3]  // bad, a and b are null
}

def x = 1              // ok
def (f, g) = [1, 2]    // ok
(a, b, c) = [1, 2, 3]  // ok

ExplicitArrayListInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of ArrayList. In Groovy, it is best to write new ArrayList() as [], which creates the same object.

ExplicitCallToAndMethod Rule

Since CodeNarc 0.11

This rule detects when the and(Object) method is called directly in code instead of using the & operator. A groovier way to express this: a.and(b) is this: a & b. This rule can be configured to ignore this.and(Object) using the ignoreThisReference property. It defaults to true, so even and(x) will not trigger a violation. The default is true because and appears commonly in Grails criteria.

This rule also ignores all calls to super.and(Object).

ExplicitCallToCompareToMethod Rule

Since CodeNarc 0.11

This rule detects when the compareTo(Object) method is called directly in code instead of using the <=>, >, >=, <, and <= operators. A groovier way to express this: a.compareTo(b) is this: a <=> b, or using the other operators. Here are some other ways to write groovier code:

    a.compareTo(b) == 0               // can be replaced by: a == b
    a.compareTo(b)                    // can be replaced by: a <=> b
    a.compareTo(b) > 0                // can be replaced by: a > b
    a.compareTo(b) >= 0               // can be replaced by: a >= b
    a.compareTo(b) < 0                // can be replaced by: a < b
    a.compareTo(b) <= 0               // can be replaced by: a <= b

This rule can be configured to ignore this.compareTo(Object) using the ignoreThisReference property. It defaults to false, so even compareTo(x) will trigger a violation.

This rule also ignores all calls to super.compareTo(Object).

ExplicitCallToDivMethod Rule

Since CodeNarc 0.11

This rule detects when the div(Object) method is called directly in code instead of using the / operator. A groovier way to express this: a.div(b) is this: a / b. This rule can be configured to ignore div.xor(Object) using the ignoreThisReference property. It defaults to false, so even div(x) will trigger a violation.

This rule also ignores all calls to super.div(Object).

ExplicitCallToEqualsMethod Rule

Since CodeNarc 0.11

This rule detects when the equals(Object) method is called directly in code instead of using the == or != operator. A groovier way to express this: a.equals(b) is this: a == b and a groovier way to express : !a.equals(b) is: a != b. This rule can be configured to ignore this.equals(Object) using the ignoreThisReference property. It defaults to false, so even equals(x) will trigger a violation.

This rule also ignores all calls to super.equals(Object).

ExplicitCallToGetAtMethod Rule

Since CodeNarc 0.11

This rule detects when the getAt(Object) method is called directly in code instead of using the [] index operator. A groovier way to express this: a.getAt(b) is this: a[b]. This rule can be configured to ignore this.getAt(Object) using the ignoreThisReference property. It defaults to false, so even getAt(x) will trigger a violation.

This rule also ignores all calls to super.getAt(Object).

ExplicitCallToLeftShiftMethod Rule

Since CodeNarc 0.11

This rule detects when the leftShift(Object) method is called directly in code instead of using the << operator. A groovier way to express this: a.leftShift(b) is this: a << b. This rule can be configured to ignore this.leftShift(Object) using the ignoreThisReference property. It defaults to false, so even leftShift(x) will trigger a violation.

This rule also ignores all calls to super.leftShift(Object).

ExplicitCallToMinusMethod Rule

Since CodeNarc 0.11

This rule detects when the minus(Object) method is called directly in code instead of using the - operator. A groovier way to express this: a.minus(b) is this: a - b. This rule can be configured to ignore minus.xor(Object) using the ignoreThisReference property. It defaults to false, so even minus(x) will trigger a violation.

This rule also ignores all calls to super.minus(Object).

ExplicitCallToMultiplyMethod Rule

Since CodeNarc 0.11

This rule detects when the multiply(Object) method is called directly in code instead of using the * operator. A groovier way to express this: a.multiply(b) is this: a * b. This rule can be configured to ignore this.multiply(Object) using the ignoreThisReference property. It defaults to false, so even multiply(x) will trigger a violation.

This rule also ignores all calls to super.multiply(Object).

ExplicitCallToModMethod Rule

Since CodeNarc 0.11

This rule detects when the mod(Object) method is called directly in code instead of using the % operator. A groovier way to express this: a.mod(b) is this: a % b. This rule can be configured to ignore this.mod(Object) using the ignoreThisReference property. It defaults to false, so even mod(x) will trigger a violation.

This rule also ignores all calls to super.mod(Object).

ExplicitCallToOrMethod Rule

Since CodeNarc 0.11

This rule detects when the or(Object) method is called directly in code instead of using the | operator. A groovier way to express this: a.or(b) is this: a | b. This rule can be configured to ignore this.or(Object) using the ignoreThisReference property. It defaults to true, so even or(x) will not trigger a violation. This is the default because it is commonly used in Grails criteria.

This rule also ignores all calls to super.or(Object).

ExplicitCallToPlusMethod Rule

Since CodeNarc 0.11

This rule detects when the plus(Object) method is called directly in code instead of using the + operator. A groovier way to express this: a.plus(b) is this: a + b. This rule can be configured to ignore this.plus(Object) using the ignoreThisReference property. It defaults to false, so even plus(x) will trigger a violation.

This rule also ignores all calls to super.plus(Object).

ExplicitCallToPowerMethod Rule

Since CodeNarc 0.11

This rule detects when the power(Object) method is called directly in code instead of using the ** operator. A groovier way to express this: a.power(b) is this: a ** b. This rule can be configured to ignore this.power(Object) using the ignoreThisReference property. It defaults to false, so even power(x) will trigger a violation.

This rule also ignores all calls to super.power(Object).

ExplicitCallToRightShiftMethod Rule

Since CodeNarc 0.11

This rule detects when the rightShift(Object) method is called directly in code instead of using the >> operator. A groovier way to express this: a.rightShift(b) is this: a >> b. This rule can be configured to ignore this.rightShift(Object) using the ignoreThisReference property. It defaults to false, so even rightShift(x) will trigger a violation.

This rule also ignores all calls to super.rightShift(Object).

ExplicitCallToXorMethod Rule

Since CodeNarc 0.11

This rule detects when the xor(Object) method is called directly in code instead of using the ^ operator. A groovier way to express this: a.xor(b) is this: a ^ b. This rule can be configured to ignore this.xor(Object) using the ignoreThisReference property. It defaults to false, so even xor(x) will trigger a violation.

This rule also ignores all calls to super.xor(Object).

ExplicitHashMapInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of HashMap. In Groovy, it is best to replace new HashMap() with [:], which creates (mostly) the same object. [:] is technically a LinkedHashMap but it is very rare that someone absolutely needs an instance of HashMap and not a subclass.

ExplicitLinkedHashMapInstantiation Rule

Since in CodeNarc 0.14

This rule checks for the explicit instantiation of a LinkedHashMap using the no-arg constructor. In Groovy, it is best to replace new LinkedHashMap() with [:], which creates the same object.

ExplicitHashSetInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of HashSet. In Groovy, it is best to replace new HashSet() with [] as Set, which creates the same object.

ExplicitLinkedListInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of LinkedList. In Groovy, it is best to replace new LinkedList() with [] as Queue, which creates the same object.

ExplicitStackInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of Stack. In Groovy, it is best to replace new Stack() with [] as Stack, which creates the same object.

ExplicitTreeSetInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of TreeSet. In Groovy, it is best to replace new TreeSet() with [] as SortedSet, which creates the same object.

GetterMethodCouldBeProperty Rule

New in CodeNarc 0.16

If a class defines a public method that follows the Java getter notation and that returns a constant, then it is cleaner to provide a Groovy property for the value rather than a Groovy method.

Example of violations:

    interface Parent {
        String getSomething()
        String getSomethingElse()
    }

    class Child extends Parent {
        static VALUE = 'value'

        @Override
        String getSomething() {
            'something'         // this could be simplified
        }

        @Override
        String getSomethingElse() {
            VALUE       // this could be simplified
        }

        int getOtherValue() {
            123
        }

        static String getName() {
            'MyName'
        }
    }

    class Child2 extends Parent {
        static VALUE = 'value'
        final String something = 'something'    // this is cleaner
        final String somethingElse = VALUE      // this is cleaner
        final int otherValue = 123              // this is cleaner
        static final String name = 'MyName'     // this is cleaner
    }

GroovyLangImmutable Rule

New in CodeNarc 0.13

The groovy.lang.Immutable annotation has been deprecated and replaced by groovy.transform.Immutable. Do not use the Immutable in groovy.lang.

Example of violations:

    @Immutable
    class Person { }

    @groovy.lang.Immutable
    class Person { }

    import groovy.lang.Immutable as Imtl
    @Imtl
    class Person { }

    // the following code is OK
    @groovy.transform.Immutable
    class Person { }

    import groovy.transform.Immutable
    @Immutable
    class Person { }

    import groovy.transform.*
    @Immutable
    class Person { }

    import groovy.transform.Immutable as Imtl
    @Imtl
    class Person { }

GStringAsMapKey Rule

Since CodeNarc 0.11

A GString should not be used as a map key since its hashcode is not guaranteed to be stable. Consider calling key.toString().

Here is an example of code that produces a violation:

    Map map = ["${someRef}" : 'invalid' ]       // violation

GStringExpressionWithinString Rule

Since CodeNarc 0.19

Check for regular (single quote) strings containing a GString-type expression ($..).

Example of violations:

    def str1 = 'total: ${count}'                // violation
    def str2 = 'average: ${total / count}'      // violation

    def str3 = "abc ${count}"                   // ok; GString
    def str4 = '$123'                           // ok
    def str5 = 'abc {123}'                      // ok

UseCollectMany Rule

New in CodeNarc 0.16

In many case collectMany() yields the same result as collect.flatten(). It is easier to understand and more clearly conveys the intent.

Example of violations:

def l = [1, 2, 3, 4]

l.collect{ [it, it*2] }.flatten() // suboptimal

l.collectMany{ [it, it*2] }       // same functionality, better readability

UseCollectNested Rule

New in CodeNarc 0.16

Instead of nested collect calls use collectNested.

Example of violations:

def list = [1, 2, [3, 4, 5, 6], [7]]

println list.collect { elem ->
    if (elem instanceof List)
        elem.collect {it *2} // violation
    else elem * 2
}

println list.collect([8]) {
    if (it instanceof List)
        it.collect {it *2} // violation
    else it * 2
}

println list.collectNested { it * 2 } // same functionality, better readability

CodeNarc-0.23/docs/codenarc-rules-security.html0000644000175000017500000005227312471222417021050 0ustar ebourgebourg CodeNarc - CodeNarc - Security Rules

Security Rules ("rulesets/security.xml")

Also see GrailsMassAssignment.

FileCreateTempFile Rule

New in CodeNarc 0.14

The File.createTempFile() method is insecure, and has been deprecated by the ESAPI secure coding library. It has been replaced by the ESAPI Randomizer.getRandomFilename(String) method.

For more information see the ESAPI website: http://code.google.com/p/owasp-esapi-java/ and the Randomizer Javadoc: http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/Randomizer.html

InsecureRandom Rule

New in CodeNarc 0.14

Reports usages of java.util.Random, which can produce very predictable results. If two instances of Random are created with the same seed and sequence of method calls, they will generate the exact same results. Use java.security.SecureRandom instead, which provides a cryptographically strong random number generator. SecureRandom uses PRNG, which means they are using a deterministic algorithm to produce a pseudo-random number from a true random seed. SecureRandom produces non-deterministic output.

By default, this rule ignores test classes are ignored.

For more information see: http://www.klocwork.com/products/documentation/current/Checkers:SV.RANDOM

Example of violations:

     def r1 = new Random()
     def r2 = new java.util.Random()
     Math.random()
     java.lang.Math.random()

     // this is OK
     new java.security.SecureRandom()
     new SecureRandom()

JavaIoPackageAccess Rule

New in CodeNarc 0.14

This rule reports violations of the Enterprise JavaBeans specification by using the java.io package to access files or the file system.

The Enterprise JavaBeans specification requires that every bean provider follow a set of programming guidelines designed to ensure that the bean will be portable and behave consistently in any EJB container [1].

In this case, the program violates the following EJB guideline: "An enterprise bean must not use the java.io package to attempt to access files and directories in the file system."

A requirement that the specification justifies in the following way: "The file system APIs are not well-suited for business components to access data. Business components should use a resource manager API, such as JDBC, to store data."

REFERENCES

  1. Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 576
  2. The Enterprise JavaBeans 2.1 Specification Sun Microsystems

By default, this rule is not applied to tests and test cases.

Example of violations:

    FileSystem.getFileSystem()          // any method on FileSystem
    FileSystem.fileSystem.delete(aFile) // property access of FileSystem

    // shouldn't create files
    new File(name)
    new File(name, parent)

    // don't create file readers
    new FileReader(name)

    // don't create file output streams
    new FileOutputStream(name)
    new FileOutputStream(name, true)

    // don't create random access file
    new RandomAccessFile(name, parent)

NonFinalPublicField Rule

New in CodeNarc 0.14

Finds code that violates secure coding principles for mobile code by declaring a member variable public but not final.

All public member variables in an Applet and in classes used by an Applet should be declared final to prevent an attacker from manipulating or gaining unauthorized access to the internal state of the Applet.

References:

  • Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 493
  • G. McGraw Securing Java. Chapter 7: Java Security Guidelines

NonFinalSubclassOfSensitiveInterface Rule

New in CodeNarc 0.14

The permissions classes such as java.security.Permission and java.security.BasicPermission are designed to be extended. Classes that derive from these permissions classes, however, must prohibit extension. This prohibition ensures that malicious subclasses cannot change the properties of the derived class. Classes that implement sensitive interfaces such as java.security.PrivilegedAction and java.security.PrivilegedActionException must also be declared final for analogous reasons.

For more information see: https://www.securecoding.cert.org/confluence/display/java/SEC07-J.+Classes+that+derive+from+a+sensitive+class+or+implement+a+sensitive+interface+must+be+declared+final

Example of violations:

    class MyPermission extends java.security.Permission {
        MyPermission(String name) { super(name) }
        boolean implies(Permission permission) { true }
        boolean equals(Object obj) { true }
        int hashCode() { 0 }
        String getActions() { "action" }
    }

    class MyBasicPermission extends BasicPermission {
        MyBasicPermission(String name) { super(name) }
    }

    class MyPrivilegedAction implements PrivilegedAction {
        Object run() { 0 }
    }

    class MyPrivilegedActionException extends PrivilegedActionException {
        MyPrivilegedActionException(Exception exception) { super(exception) }
    }

PublicFinalizeMethod Rule

New in CodeNarc 0.14

Creates a violation when the program violates secure coding principles by declaring a finalize() method public.

A program should never call finalize explicitly, except to call super.finalize() inside an implementation of finalize(). In mobile code situations, the otherwise error prone practice of manual garbage collection can become a security threat if an attacker can maliciously invoke one of your finalize() methods because it is declared with public access. If you are using finalize() as it was designed, there is no reason to declare finalize() with anything other than protected access.

References:

  • Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 583
  • G. McGraw Securing Java. Chapter 7: Java Security Guidelines

ObjectFinalize Rule

New in CodeNarc 0.14

The finalize() method should only be called by the JVM after the object has been garbage collected.

While the Java Language Specification allows an object's finalize() method to be called from outside the finalizer, doing so is usually a bad idea. For example, calling finalize() explicitly means that finalize() will be called more than once: the first time will be the explicit call and the last time will be the call that is made after the object is garbage collected.

References: Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 586

SystemExit Rule

New in CodeNarc 0.14

Web applications should never call System.exit(). A call to System.exit() is probably part of leftover debug code or code imported from a non-J2EE application.

  1. Standards Mapping - OWASP Top 10 2004 - (OWASP 2004) A9 Application Denial of Service
  2. Standards Mapping - Security Technical Implementation Guide Version 3 - (STIG 3) APP6080 CAT II
  3. Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 382
  4. Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 - (PCI 1.1) Requirement 6.5.9

UnsafeArrayDeclaration Rule

New in CodeNarc 0.14

Triggers a violation when an array is declared public, final, and static.

In most cases an array declared public, final and static is a bug. Because arrays are mutable objects, the final constraint requires that the array object itself be assigned only once, but makes no guarantees about the values of the array elements. Since the array is public, a malicious program can change the values stored in the array. In most situations the array should be made private.

Example of violations:

    class MyClass {
        public static final String[] myArray = init()
        public static final def myArray = [] as String[]
    }

CodeNarc-0.23/docs/CodeNarc-Grails-Report.html0000644000175000017500000605342412471222451020446 0ustar ebourgebourgCodeNarc Report: Grails-core-2.0.0.RC1

CodeNarc Report

Report title:Grails-core-2.0.0.RC1
Date:Mar 23, 2012 5:46:27 PM
Generated with:CodeNarc v0.17

Summary by Package

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages933475-8391722
buildSrc/src/main/groovy/org/grails/gradle11--2
grails-bootstrap/src/main/groovy/grails/build/interactive/completors148-18
grails-bootstrap/src/main/groovy/grails/util43-649
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli1----
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/interactive21-36
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/interactive/completors11-1-
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/support1----
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/plugins33-2551
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/plugins/build/scopes1----
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/resolve55-626
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/resolve/config31--2
grails-core/src/main/groovy/grails/validation2----
grails-core/src/main/groovy/org/codehaus/groovy/grails/commons/cfg22--10
grails-core/src/main/groovy/org/codehaus/groovy/grails/commons/metaclass21--1
grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler22-17
grails-core/src/main/groovy/org/codehaus/groovy/grails/documentation1----
grails-core/src/main/groovy/org/codehaus/groovy/grails/exceptions21-714
grails-core/src/main/groovy/org/codehaus/groovy/grails/plugins21--3
grails-core/src/main/groovy/org/codehaus/groovy/grails/plugins/publishing33-53
grails-core/src/main/groovy/org/codehaus/groovy/grails/plugins/support22-11
grails-core/src/main/groovy/org/codehaus/groovy/grails/support1----
grails-core/src/main/groovy/org/codehaus/groovy/grails/validation1----
grails-crud/src/main/groovy/org/codehaus/groovy/grails/scaffolding11-44
grails-docs/src/main/groovy/grails/doc43-127
grails-docs/src/main/groovy/grails/doc/ant1----
grails-docs/src/main/groovy/grails/doc/filters32-29
grails-docs/src/main/groovy/grails/doc/gradle31--6
grails-docs/src/main/groovy/grails/doc/internal4----
grails-docs/src/main/groovy/grails/doc/macros21-1-
grails-docs/src/test/groovy/grails/doc/internal1----
grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/orm/hibernate22-27
grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/orm/hibernate/cfg123-311
grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/plugins/orm/hibernate11-711
grails-plugin-async/src/main/groovy/org/codehaus/groovy/grails/plugins/web/async22--7
grails-plugin-async/src/main/groovy/org/codehaus/groovy/grails/plugins/web/async/api11-1-
grails-plugin-codecs/src/main/groovy/org/codehaus/groovy/grails/plugins11--3
grails-plugin-codecs/src/main/groovy/org/codehaus/groovy/grails/plugins/codecs114--10
grails-plugin-codecs/src/test/groovy/org/codehaus/groovy/grails/web/codecs113-32
grails-plugin-controllers/src/main/groovy/org/codehaus/groovy/grails/plugins/web11-310
grails-plugin-controllers/src/main/groovy/org/codehaus/groovy/grails/web/metaclass32-36
grails-plugin-controllers/src/main/groovy/org/codehaus/groovy/grails/web/plugins/support11-210
grails-plugin-converters/src/main/groovy/grails/web1----
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/plugins/converters22-13
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/plugins/converters/api1----
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/plugins/converters/codecs2----
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/web/converters32--2
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/web/converters/configuration11--5
grails-plugin-datasource/src/main/groovy/org/codehaus/groovy/grails/plugins/datasource11-36
grails-plugin-domain-class/src/main/groovy/org/codehaus/groovy/grails/domain11--1
grails-plugin-domain-class/src/main/groovy/org/codehaus/groovy/grails/plugins22-213
grails-plugin-filters/src/main/groovy/org/codehaus/groovy/grails/plugins/web/filters63-66
grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web11-214
grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web/taglib98-1048
grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/web/filters1----
grails-plugin-i18n/src/main/groovy/org/codehaus/groovy/grails/plugins/i18n11--1
grails-plugin-log4j/src/main/groovy/org/codehaus/groovy/grails/plugins/log4j22--10
grails-plugin-mimetypes/src/main/groovy/org/codehaus/groovy/grails/plugins/web/api43-25
grails-plugin-mimetypes/src/main/groovy/org/codehaus/groovy/grails/plugins/web/mimes31--1
grails-plugin-mimetypes/src/main/groovy/org/codehaus/groovy/grails/web/mime21-12
grails-plugin-scaffolding/src/main/groovy/org/codehaus/groovy/grails/plugins/scaffolding11-12
grails-plugin-services/src/main/groovy/org/codehaus/groovy/grails/plugins/services11--3
grails-plugin-servlets/src/main/groovy/org/codehaus/groovy/grails/plugins/web21--1
grails-plugin-servlets/src/main/groovy/org/codehaus/groovy/grails/plugins/web/api1----
grails-plugin-testing/src/main/groovy/grails/test76-2310
grails-plugin-testing/src/main/groovy/grails/test/mixin/domain11--1
grails-plugin-testing/src/main/groovy/grails/test/mixin/services1----
grails-plugin-testing/src/main/groovy/grails/test/mixin/support11--6
grails-plugin-testing/src/main/groovy/grails/test/mixin/web44-120
grails-plugin-testing/src/main/groovy/grails/test/mixin/webflow2----
grails-plugin-testing/src/test/groovy/grails/test/mixin4----
grails-plugin-tomcat/src/main/groovy/org/grails/plugins/tomcat54-1011
grails-plugin-url-mappings/src/main/groovy/grails/test11-1713
grails-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/plugins/web/mapping11-216
grails-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping1----
grails-plugin-validation/src/main/groovy/org/codehaus/groovy/grails/plugins11-16
grails-plugin-validation/src/main/groovy/org/codehaus/groovy/grails/validation1----
grails-plugin-validation/src/main/groovy/org/codehaus/groovy/grails/web/plugins/support1----
grails-plugin-validation/src/test/groovy/org/codehaus/groovy/grails/plugins11--2
grails-resources/src/grails/grails-app/conf6----
grails-resources/src/grails/grails-app/conf/spring1----
grails-resources/src/grails/plugin/grails-app/conf2----
grails-spring/src/main/groovy/grails/spring11-16
grails-test-suite-base/src/main/groovy/org/codehaus/groovy/grails/plugins/web11-12
grails-test-suite-base/src/main/groovy/org/codehaus/groovy/grails/web/servlet/mvc11-35
grails-test-suite-base/src/main/groovy/org/codehaus/groovy/grails/web/taglib11-185
grails-test-suite-persistence/src/test/groovy/grails/test/mixin/domain1----
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate21690-115199
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/binding42-23
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/cfg64-1032
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/metaclass11-22
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/support22--25
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/validation81-228
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/support11--1
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/plugins11-2-
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/plugins/scaffolding11--2
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/plugins/services22-12
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/reload21-1-
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/scaffolding22-24
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/scaffolding/view22-22
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/validation31--1
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/web/binding32-22
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/web/converters11-2-
grails-test-suite-uber/src/test/groovy/grails/ant11-2-
grails-test-suite-uber/src/test/groovy/grails/persistence1----
grails-test-suite-uber/src/test/groovy/grails/spring21-1021
grails-test-suite-uber/src/test/groovy/grails/test1110-4827
grails-test-suite-uber/src/test/groovy/grails/test/mixin1913-1943
grails-test-suite-uber/src/test/groovy/grails/util75-940
grails-test-suite-uber/src/test/groovy/grails/web1----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/cli21-24
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/cli/support22-18
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/commons116-1626
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/commons/cfg3----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/commons/metaclass43-115
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/compiler11--4
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/compiler/injection11--2
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/context/support11-32
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/documentation11--2
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/domain8----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins76-1110
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/datasource1----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/grails-app/conf2----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/grails-app/services1----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/i18n11--5
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/logging11-15
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/metadata1----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/publishing11-2-
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/testing3----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/web33-69
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/web/mapping11-1-
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/reload21-31
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/resolve21-914
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/test/support2----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/validation63-4164
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/context11-23
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/errors11-21
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/filters11--3
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/i18n11-112
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/json11--1
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/metaclass31-31
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/servlet65-711
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/servlet/filter11-1-
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/servlet/mvc147-623
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/sitemesh32-142
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/util42-47
grails-test-suite-uber/src/test/resources/grails/spring1----
grails-test-suite-uber/src/test/resources/org/codehaus/groovy/grails/commons1----
grails-test-suite-uber/src/test/resources/org/codehaus/groovy/grails/commons/cfg2----
grails-test-suite-uber/src/test/resources/org/codehaus/groovy/grails/plugins11-3-
grails-test-suite-uber/test/resources/grails-app/conf1----
grails-test-suite-uber/test/resources/grails-plugin-utils/global-plugins/logging-0.11----
grails-test-suite-uber/test/resources/grails-plugin-utils/global-plugins/logging-0.1/scripts2----
grails-test-suite-uber/test/resources/grails-plugin-utils/grails-debug/scripts1----
grails-test-suite-uber/test/resources/grails-plugin-utils/plugins/jsecurity-0.31----
grails-test-suite-uber/test/resources/grails-plugin-utils/plugins/jsecurity-0.3/scripts2----
grails-test-suite-uber/test/resources/spring1----
grails-test-suite-uber/test/test-projects/inline-plugins/app/grails-app/conf1----
grails-test-suite-uber/test/test-projects/inline-plugins/plugins/foo1----
grails-test-suite-uber/test/test-projects/inline-plugins/plugins/foo/grails-app/controllers/foo1----
grails-test-suite-uber/test/test-projects/inline-plugins/plugins/foobar1----
grails-test-suite-uber/test/test-projects/inline-plugins/plugins/foobar/grails-app/controllers/foobar1----
grails-test-suite-uber/test/test-projects/nested-inline-plugins/app/grails-app/conf1----
grails-test-suite-uber/test/test-projects/nested-inline-plugins/plugins/plugin-one1----
grails-test-suite-uber/test/test-projects/nested-inline-plugins/plugins/plugin-one/grails-app/conf1----
grails-test-suite-uber/test/test-projects/nested-inline-plugins/plugins/plugin-two1----
grails-test-suite-uber/test/test-projects/plugin-build-settings/grails-app/conf5----
grails-test-suite-uber/test/test-projects/plugin-build-settings/grails-app/conf/spring1----
grails-test-suite-uber/test/test-projects/plugin-build-settings/plugins/hibernate-1.2-SNAPSHOT2----
grails-test-suite-uber/test/test-projects/plugin-build-settings/plugins/hibernate-1.2-SNAPSHOT/scripts3----
grails-test-suite-uber/test/test-projects/plugin-build-settings/plugins/webflow-1.2-SNAPSHOT2----
grails-test-suite-uber/test/test-projects/plugin-build-settings/plugins/webflow-1.2-SNAPSHOT/scripts3----
grails-test-suite-web/src/test/groovy/grails/test11-438
grails-test-suite-web/src/test/groovy/grails/test/mixin22-11
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/plugins/web1----
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/plugins/web/filters51-23
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/plugins/webflow21--1
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/binding143-42
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/converters73-35
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/filters11--4
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/mapping2214-532
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/mapping/filter21--3
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/mime21-2-
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/pages179-189
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/pages/ext/jsp99-833
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/servlet/view11-11
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/taglib3926-5873
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/webflow55-615
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/webflow/engine/builder88-129
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/webflow/support11-610
grails-test/src/main/groovy/grails/test11--1
grails-test/src/main/groovy/org/codehaus/groovy/grails/plugins/testing43-319
grails-test/src/main/groovy/org/codehaus/groovy/grails/test31--2
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/event21-4-
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/io2----
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/junit411--2
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/junit4/listener21-51
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/junit4/result1----
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/junit4/runner31--2
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/report/junit1----
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/support73-17
grails-web/src/jsp21/groovy/org/codehaus/groovy/grails/web/pages/ext/jsp22--6
grails-web/src/main/groovy/grails/gsp11-4911
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/errors1----
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/i18n1----
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping22-28
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mime11--1
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/pages33--8
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/pages/ext/jsp76-2024
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/mvc1----
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/mvc/exceptions1----
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/taglib22-13
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/util11--1
grails-webflow/src/main/groovy/grails/test11-47
grails-webflow/src/main/groovy/org/codehaus/groovy/grails/webflow11--21
grails-webflow/src/main/groovy/org/codehaus/groovy/grails/webflow/context/servlet11--4
grails-webflow/src/main/groovy/org/codehaus/groovy/grails/webflow/engine/builder139-1633
scripts7324-1781

Package: buildSrc.src.main.groovy.org.grails.gradle

➥ GrailsBuildPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport310

[SRC]import org.gradle.api.DefaultTask

[MSG]The [org.gradle.api.DefaultTask] import is never referenced

UnusedImport312

[SRC]import org.gradle.api.specs.Specs

[MSG]The [org.gradle.api.specs.Specs] import is never referenced

Package: grails-bootstrap.src.main.groovy.grails.build.interactive.completors

➥ CreateController.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.CreateController. getURL() can probably be rewritten as URL

➥ CreateScaffoldController.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.CreateScaffoldController. getURL() can probably be rewritten as URL

➥ CreateService.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.CreateService. getURL() can probably be rewritten as URL

➥ CreateTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.CreateTagLib. getURL() can probably be rewritten as URL

➥ GenerateAll.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.GenerateAll. getURL() can probably be rewritten as URL

➥ GenerateController.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.GenerateController. getURL() can probably be rewritten as URL

➥ GenerateViews.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.GenerateViews. getURL() can probably be rewritten as URL

➥ RegexCompletor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter234

[SRC]int complete(String buffer, int cursor, List candidates) {

[MSG]Violation in class RegexCompletor. Method parameter [cursor] is never referenced in the method complete of class grails.build.interactive.completors.RegexCompletor

UnnecessaryElseStatement339

[SRC]else return -1

[MSG]When an if statement block ends with a return statement the else is unnecessary

Package: grails-bootstrap.src.main.groovy.grails.util

➥ BuildSettings.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity21003

[SRC]protected void postLoadConfig() {

[MSG]Violation in class grails.util.BuildSettings. The cyclomatic complexity for method [postLoadConfig] is [21]

CyclomaticComplexity21316

[SRC]private void establishProjectStructure() {

[MSG]Violation in class grails.util.BuildSettings. The cyclomatic complexity for method [establishProjectStructure] is [25]

UnnecessaryElseStatement3488

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3589

[SRC]getCompileDependencies()

[MSG]Violation in class grails.util.BuildSettings. getCompileDependencies() can probably be rewritten as compileDependencies

UnnecessaryGetter3603

[SRC]getProvidedDependencies()

[MSG]Violation in class grails.util.BuildSettings. getProvidedDependencies() can probably be rewritten as providedDependencies

UnnecessaryGetter3616

[SRC]getRuntimeDependencies()

[MSG]Violation in class grails.util.BuildSettings. getRuntimeDependencies() can probably be rewritten as runtimeDependencies

UnnecessaryGetter3630

[SRC]getTestDependencies()

[MSG]Violation in class grails.util.BuildSettings. getTestDependencies() can probably be rewritten as testDependencies

UnnecessaryGetter3644

[SRC]getBuildDependencies()

[MSG]Violation in class grails.util.BuildSettings. getBuildDependencies() can probably be rewritten as buildDependencies

UnnecessaryDefInMethodDeclaration3783

[SRC]protected def loadBuildPropertiesFromClasspath(Propertie..uildProps) {

[MSG]Violation in class grails.util.BuildSettings. The def keyword is unneeded when a method is marked protected

UnnecessaryGetter31011

[SRC]def configURL = config.getConfigFile()

[MSG]Violation in class grails.util.BuildSettings. getConfigFile() can probably be rewritten as configFile

UnnecessaryGetter31012

[SRC]def configFile = configURL ? new File(configURL.getFile()) : null

[MSG]Violation in class grails.util.BuildSettings. getFile() can probably be rewritten as file

UnnecessaryGetter31014

[SRC]def metadataFile = Metadata.current.getMetadataFile()

[MSG]Violation in class grails.util.BuildSettings. getMetadataFile() can probably be rewritten as metadataFile

UnnecessaryGetter31148

[SRC]gcl = rootLoader != null ? new GroovyClassLoader(rootLoa..assLoader())

[MSG]Violation in class grails.util.BuildSettings. getSystemClassLoader() can probably be rewritten as systemClassLoader

UnnecessaryGetter31157

[SRC]def appName = metadata.getApplicationName() ?: "grails"

[MSG]Violation in class grails.util.BuildSettings. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter31158

[SRC]def appVersion = metadata.getApplicationVersion() ?: grailsVersion

[MSG]Violation in class grails.util.BuildSettings. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter31217

[SRC]def pluginDirs = getPluginDirectories()

[MSG]Violation in class grails.util.BuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter31311

[SRC]appName: Metadata.current.getApplicationName(),

[MSG]Violation in class grails.util.BuildSettings. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter31312

[SRC]appVersion: Metadata.current.getApplicationVersion())

[MSG]Violation in class grails.util.BuildSettings. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter31335

[SRC]def workingDirName = metadata.getApplicationName() ?: CO..ING_DIR_NAME

[MSG]Violation in class grails.util.BuildSettings. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter31344

[SRC]def version = metadata.getApplicationVersion()

[MSG]Violation in class grails.util.BuildSettings. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter31345

[SRC]def appName = metadata.getApplicationName() ?: baseDir.name

[MSG]Violation in class grails.util.BuildSettings. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter31512

[SRC]getBasePluginDescriptor() != null

[MSG]Violation in class grails.util.BuildSettings. getBasePluginDescriptor() can probably be rewritten as basePluginDescriptor

➥ GrailsMain.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter324

[SRC]props.load(getClass().getClassLoader().getResourceAsStre..roperties"))

[MSG]Violation in class grails.util.None. getClassLoader() can probably be rewritten as classLoader

➥ PluginBuildSettings.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2187

[SRC]GrailsPluginInfo[] getPluginInfos(String pluginDirPath=t..inDirPath) {

[MSG]Violation in class PluginBuildSettings. Method parameter [pluginDirPath] is never referenced in the method getPluginInfos of class grails.util.PluginBuildSettings

EmptyCatchBlock2203

[SRC]catch (e) {

[MSG]The catch block is empty

EmptyCatchBlock2739

[SRC]catch (e) {

[MSG]The catch block is empty

UnusedVariable2759

[SRC]def (name, version, xml) = result

[MSG]The variable [xml] in class grails.util.PluginBuildSettings is not used

UnnecessaryGetter3112

[SRC]for (pluginDir in getInlinePluginDirectories()) {

[MSG]Violation in class grails.util.PluginBuildSettings. getInlinePluginDirectories() can probably be rewritten as inlinePluginDirectories

UnnecessaryDefInMethodDeclaration3160

[SRC]protected def addPluginScopeInfoForDirAndInfo(PluginScop..ource dir) {

[MSG]Violation in class grails.util.PluginBuildSettings. The def keyword is unneeded when a method is marked protected

UnnecessaryGetter3192

[SRC]Resource[] pluginDescriptors = getPluginDescriptors()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDescriptors() can probably be rewritten as pluginDescriptors

UnnecessaryGetter3215

[SRC]buildSettings?.isInlinePluginLocation(pluginLocation?.getFile())

[MSG]Violation in class grails.util.PluginBuildSettings. getFile() can probably be rewritten as file

UnnecessaryGetter3226

[SRC]locations = buildSettings.getInlinePluginDirectories().c..source(it) }

[MSG]Violation in class grails.util.PluginBuildSettings. getInlinePluginDirectories() can probably be rewritten as inlinePluginDirectories

UnnecessaryGetter3239

[SRC]if (!pluginInfosMap) getPluginInfos() // initialize the infos

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3252

[SRC]if (!pluginInfosMap) getPluginInfos() // initialize the infos

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3264

[SRC]def pluginDirs = getPluginDirectories()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessarySubstring3275

[SRC]sourcePath = sourcePath.substring(pluginPath.length())

[MSG]Violation in class grails.util.PluginBuildSettings. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3287

[SRC]def baseDir = buildSettings?.getBaseDir()?.getCanonicalPath()

[MSG]Violation in class grails.util.PluginBuildSettings. getCanonicalPath() can probably be rewritten as canonicalPath

UnnecessaryGetter3287

[SRC]def baseDir = buildSettings?.getBaseDir()?.getCanonicalPath()

[MSG]Violation in class grails.util.PluginBuildSettings. getBaseDir() can probably be rewritten as baseDir

UnnecessaryGetter3386

[SRC]return getPluginSourceDirectories()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginSourceDirectories() can probably be rewritten as pluginSourceDirectories

UnnecessaryGetter3414

[SRC]getPluginSourceDirectories() // initialize cache

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginSourceDirectories() can probably be rewritten as pluginSourceDirectories

UnnecessaryGetter3454

[SRC]pluginDirectoryResources = buildSettings.getPluginDirect..s Resource[]

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3469

[SRC]if (pluginManager == null) return getPluginInfos()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3471

[SRC]def pluginInfos = getPluginInfos().findAll {GrailsPluginInfo info ->

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3472

[SRC]def plugin = pluginManager.getGrailsPlugin(info.getName())

[MSG]Violation in class grails.util.PluginBuildSettings. getName() can probably be rewritten as name

UnnecessaryGetter3486

[SRC]implicitPluginDirectories = buildSettings.getImplicitPlu..source(it) }

[MSG]Violation in class grails.util.PluginBuildSettings. getImplicitPluginDirectories() can probably be rewritten as implicitPluginDirectories

UnnecessaryGetter3498

[SRC]return buildSettings?.getPluginBaseDirectories() ?: []

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginBaseDirectories() can probably be rewritten as pluginBaseDirectories

UnnecessaryGetter3578

[SRC]artefactResources.addAll compileScopePluginInfo.getArtefactResources()

[MSG]Violation in class grails.util.PluginBuildSettings. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3579

[SRC]artefactResources.addAll providedScopePluginInfo.getArte..tResources()

[MSG]Violation in class grails.util.PluginBuildSettings. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3581

[SRC]if (Environment.getCurrent() == Environment.TEST) {

[MSG]Violation in class grails.util.PluginBuildSettings. getCurrent() can probably be rewritten as current

UnnecessaryGetter3582

[SRC]artefactResources.addAll testScopePluginInfo.getArtefactResources()

[MSG]Violation in class grails.util.PluginBuildSettings. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3584

[SRC]def inlineDirectories = getInlinePluginDirectories()

[MSG]Violation in class grails.util.PluginBuildSettings. getInlinePluginDirectories() can probably be rewritten as inlinePluginDirectories

UnnecessaryGetter3615

[SRC]def baseDescriptor = getBasePluginDescriptor()

[MSG]Violation in class grails.util.PluginBuildSettings. getBasePluginDescriptor() can probably be rewritten as basePluginDescriptor

UnnecessaryGetter3619

[SRC]for (inlinePluginDir in getInlinePluginDirectories()) {

[MSG]Violation in class grails.util.PluginBuildSettings. getInlinePluginDirectories() can probably be rewritten as inlinePluginDirectories

UnnecessaryGetter3635

[SRC]def pluginDirs = getPluginDirectories().toList()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3824

[SRC]Resource[] pluginDirs = getPluginDirectories()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.cli.interactive

➥ InteractiveMode.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity285

[SRC]void run() {

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. The cyclomatic complexity for method [run] is [31]

EmptyCatchBlock2203

[SRC]catch(ScriptExitException e) {

[MSG]The catch block is empty

EmptyCatchBlock2226

[SRC]} catch (e) {

[MSG]The catch block is empty

UnnecessaryGetter348

[SRC]@Delegate GrailsConsole console = GrailsConsole.getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getInstance() can probably be rewritten as instance

UnnecessaryGetter364

[SRC]GroovySystem.getMetaClassRegistry().addMetaClassRegistry..stryCleaner)

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

UnnecessaryGetter382

[SRC]getCurrent() != null && getCurrent().interactiveModeActive

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getCurrent() can probably be rewritten as current

UnnecessaryGetter382

[SRC]getCurrent() != null && getCurrent().interactiveModeActive

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getCurrent() can probably be rewritten as current

UnnecessaryGetter3136

[SRC]final desktop = Desktop.getDesktop()

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getDesktop() can probably be rewritten as desktop

UnnecessaryGetter3238

[SRC]def parser = GrailsScriptRunner.getCommandLineParser()

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getCommandLineParser() can probably be rewritten as commandLineParser

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.cli.interactive.completors

➥ ClassNameCompletor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter261

[SRC]boolean shouldInclude(Resource res) { true }

[MSG]Violation in class ClassNameCompletor. Method parameter [res] is never referenced in the method shouldInclude of class org.codehaus.groovy.grails.cli.interactive.completors.ClassNameCompletor

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ GrailsPluginUtils.groovy

Rule NamePriorityLine #Source Line / Message
SynchronizedMethod2120

[SRC]static synchronized PluginBuildSettings getPluginBuildSettings() {

[MSG]Violation in class GrailsPluginUtils. The method getPluginBuildSettings is synchronized at the method level

SynchronizedMethod2127

[SRC]static synchronized setPluginBuildSettings(PluginBuildSe.. settings) {

[MSG]Violation in class GrailsPluginUtils. The method setPluginBuildSettings is synchronized at the method level

UnusedMethodParameter2134

[SRC]static GrailsPluginInfo[] getPluginInfos(String pluginDi..Dir?.path) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginInfos of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2144

[SRC]static GrailsPluginInfo[] getSupportedPluginInfos(String..Dir?.path) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getSupportedPluginInfos of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2152

[SRC]static List<String> getPluginBaseDirectories(String pluginDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginBaseDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2167

[SRC]static Resource[] getPluginDirectories(String pluginDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2174

[SRC]static List<Resource> getImplicitPluginDirectories(Strin..Dir?.path) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getImplicitPluginDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2185

[SRC]static Resource[] getArtefactResources(String basedir) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [basedir] is never referenced in the method getArtefactResources of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2199

[SRC]static Resource[] getPluginXmlMetadata(String pluginsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginXmlMetadata of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2206

[SRC]static Resource[] getAvailableScripts(String grailsHome,..g basedir) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [grailsHome] is never referenced in the method getAvailableScripts of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2206

[SRC]static Resource[] getAvailableScripts(String grailsHome,..g basedir) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getAvailableScripts of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2206

[SRC]static Resource[] getAvailableScripts(String grailsHome,..g basedir) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [basedir] is never referenced in the method getAvailableScripts of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2213

[SRC]static Resource[] getPluginScripts(String pluginDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginScripts of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2220

[SRC]static Resource[] getPluginResourceBundles(String pluginDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginResourceBundles of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2227

[SRC]static Resource[] getPluginSourceFiles(String pluginsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginSourceFiles of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2234

[SRC]static Resource[] getPluginJarFiles(String pluginsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginJarFiles of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2241

[SRC]static Resource[] getPluginDescriptors(String basedir, S..nsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [basedir] is never referenced in the method getPluginDescriptors of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2241

[SRC]static Resource[] getPluginDescriptors(String basedir, S..nsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginDescriptors of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2260

[SRC]static Resource[] getPluginLibDirectories(String pluginsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginLibDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2267

[SRC]static Resource[] getPluginI18nDirectories(String plugin..Dir?.path) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginI18nDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2302

[SRC]static Resource getPluginDirForName(String pluginsDirPat..luginName) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginDirForName of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

SynchronizedMethod2309

[SRC]static synchronized clearCaches() {

[MSG]Violation in class GrailsPluginUtils. The method clearCaches is synchronized at the method level

UnnecessaryGetter3135

[SRC]return getPluginBuildSettings().getPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3135

[SRC]return getPluginBuildSettings().getPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3145

[SRC]final PluginBuildSettings settings = getPluginBuildSettings()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3146

[SRC]return settings.getSupportedPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getSupportedPluginInfos() can probably be rewritten as supportedPluginInfos

UnnecessaryGetter3153

[SRC]getPluginBuildSettings().getPluginBaseDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBaseDirectories() can probably be rewritten as pluginBaseDirectories

UnnecessaryGetter3153

[SRC]getPluginBuildSettings().getPluginBaseDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3160

[SRC]getPluginBuildSettings().getPluginBaseDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBaseDirectories() can probably be rewritten as pluginBaseDirectories

UnnecessaryGetter3160

[SRC]getPluginBuildSettings().getPluginBaseDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3164

[SRC]getPluginBuildSettings().getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3164

[SRC]getPluginBuildSettings().getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3168

[SRC]getPluginBuildSettings().getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3168

[SRC]getPluginBuildSettings().getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3175

[SRC]getPluginBuildSettings().getImplicitPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getImplicitPluginDirectories() can probably be rewritten as implicitPluginDirectories

UnnecessaryGetter3175

[SRC]getPluginBuildSettings().getImplicitPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3179

[SRC]getPluginBuildSettings().isGlobalPluginLocation(pluginDir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3186

[SRC]getPluginBuildSettings().getArtefactResources()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3186

[SRC]getPluginBuildSettings().getArtefactResources()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3193

[SRC]getPluginBuildSettings().getArtefactResourcesForOne(projectDir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3200

[SRC]getPluginBuildSettings().getPluginXmlMetadata()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginXmlMetadata() can probably be rewritten as pluginXmlMetadata

UnnecessaryGetter3200

[SRC]getPluginBuildSettings().getPluginXmlMetadata()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3207

[SRC]getPluginBuildSettings().getAvailableScripts()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getAvailableScripts() can probably be rewritten as availableScripts

UnnecessaryGetter3207

[SRC]getPluginBuildSettings().getAvailableScripts()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3214

[SRC]getPluginBuildSettings().getPluginScripts()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginScripts() can probably be rewritten as pluginScripts

UnnecessaryGetter3214

[SRC]getPluginBuildSettings().getPluginScripts()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3221

[SRC]getPluginBuildSettings().getPluginResourceBundles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginResourceBundles() can probably be rewritten as pluginResourceBundles

UnnecessaryGetter3221

[SRC]getPluginBuildSettings().getPluginResourceBundles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3228

[SRC]getPluginBuildSettings().getPluginSourceFiles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginSourceFiles() can probably be rewritten as pluginSourceFiles

UnnecessaryGetter3228

[SRC]getPluginBuildSettings().getPluginSourceFiles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3235

[SRC]getPluginBuildSettings().getPluginJarFiles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginJarFiles() can probably be rewritten as pluginJarFiles

UnnecessaryGetter3235

[SRC]getPluginBuildSettings().getPluginJarFiles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3242

[SRC]getPluginBuildSettings().getPluginDescriptors()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginDescriptors() can probably be rewritten as pluginDescriptors

UnnecessaryGetter3242

[SRC]getPluginBuildSettings().getPluginDescriptors()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3246

[SRC]getPluginBuildSettings().getBasePluginDescriptor(basedir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3254

[SRC]getPluginBuildSettings().getDescriptorForPlugin(pluginDir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3261

[SRC]getPluginBuildSettings().getPluginLibDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginLibDirectories() can probably be rewritten as pluginLibDirectories

UnnecessaryGetter3261

[SRC]getPluginBuildSettings().getPluginLibDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3268

[SRC]getPluginBuildSettings().getPluginI18nDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginI18nDirectories() can probably be rewritten as pluginI18nDirectories

UnnecessaryGetter3268

[SRC]getPluginBuildSettings().getPluginI18nDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3275

[SRC]getPluginBuildSettings().getGlobalPluginsPath()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getGlobalPluginsPath() can probably be rewritten as globalPluginsPath

UnnecessaryGetter3275

[SRC]getPluginBuildSettings().getGlobalPluginsPath()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3282

[SRC]getPluginBuildSettings().getPluginDirForName(pluginName)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3289

[SRC]getPluginBuildSettings().getMetadataForPlugin(pluginName)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3296

[SRC]getPluginBuildSettings().getMetadataForPlugin(pluginDir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3303

[SRC]getPluginBuildSettings().getPluginDirForName(pluginName)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3310

[SRC]getPluginBuildSettings().clearCache()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

➥ GrailsVersionUtils.groovy

Rule NamePriorityLine #Source Line / Message
EqualsAndHashCode2100

[SRC]class VersionComparator implements Comparator {

[MSG]The class org.codehaus.groovy.grails.plugins.VersionComparator defines equals(Object) but not hashCode()

UnusedMethodParameter2167

[SRC]boolean equals(obj) { false }

[MSG]Violation in class VersionComparator. Method parameter [obj] is never referenced in the method equals of class org.codehaus.groovy.grails.plugins.VersionComparator

➥ PluginInfo.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock244

[SRC]catch(e) {

[MSG]The catch block is empty

UnnecessaryGetter356

[SRC]input = pluginXml.getInputStream()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getInputStream() can probably be rewritten as inputStream

UnnecessaryGetter397

[SRC]"${getName()}-${getVersion()}"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getName() can probably be rewritten as name

UnnecessaryGetter397

[SRC]"${getName()}-${getVersion()}"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getVersion() can probably be rewritten as version

UnnecessaryGetter3101

[SRC][name:getName(), version:getVersion()]

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getName() can probably be rewritten as name

UnnecessaryGetter3101

[SRC][name:getName(), version:getVersion()]

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getVersion() can probably be rewritten as version

UnnecessaryDefInMethodDeclaration3119

[SRC]private def lookupFromMetadata(String name) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. The def keyword is unneeded when a method is marked private

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.resolve

➥ EnhancedDefaultDependencyDescriptor.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3121

[SRC]Field field = getClass().getSuperclass().getDeclaredFiel..Transitive")

[MSG]Violation in class org.codehaus.groovy.grails.resolve.EnhancedDefaultDependencyDescriptor. getSuperclass() can probably be rewritten as superclass

UnnecessaryGetter3128

[SRC]Field field = getClass().getSuperclass().getDeclaredFiel..isChanging")

[MSG]Violation in class org.codehaus.groovy.grails.resolve.EnhancedDefaultDependencyDescriptor. getSuperclass() can probably be rewritten as superclass

➥ IvyDependencyManager.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport334

[SRC]import org.apache.ivy.plugins.resolver.ChainResolver

[MSG]The [org.apache.ivy.plugins.resolver.ChainResolver] import is never referenced

UnusedImport335

[SRC]import org.apache.ivy.util.Message

[MSG]The [org.apache.ivy.util.Message] import is never referenced

UnusedImport336

[SRC]import org.apache.ivy.util.MessageLogger

[MSG]The [org.apache.ivy.util.MessageLogger] import is never referenced

UnnecessaryElseStatement3254

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3396

[SRC]def candidates = getPluginDependencyDescriptors().findAl..pplication }

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManager. getPluginDependencyDescriptors() can probably be rewritten as pluginDependencyDescriptors

➥ PluginInstallEngine.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2366

[SRC]def (name, version, xml) = readMetadataFromZip(zipLocation)

[MSG]The variable [xml] in class org.codehaus.groovy.grails.resolve.PluginInstallEngine is not used

UnusedMethodParameter2429

[SRC]protected void resolvePluginJarDependencies(fullPluginNa..ies = [:]) {

[MSG]Violation in class PluginInstallEngine. Method parameter [pluginName] is never referenced in the method resolvePluginJarDependencies of class org.codehaus.groovy.grails.resolve.PluginInstallEngine

BooleanGetBoolean2446

[SRC]def runningUpgrade = Boolean.getBoolean('runningGrailsUpgrade')

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. Boolean.getBoolean(String) is a confusing API for reading System properties. Prefer the System.getProperty(String) API.

UnusedMethodParameter2504

[SRC]protected Map processPluginDependencies(String pluginNam..pluginXml) {

[MSG]Violation in class PluginInstallEngine. Method parameter [pluginName] is never referenced in the method processPluginDependencies of class org.codehaus.groovy.grails.resolve.PluginInstallEngine

UnusedPrivateMethod2731

[SRC]private registerMetadataForPluginLocation(Resource pluginDir) {

[MSG]The method registerMetadataForPluginLocation is not used within PluginInstallEngine.groovy

UnnecessaryGetter391

[SRC]applicationPluginsLocation = settings.getProjectPluginsDir()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getProjectPluginsDir() can probably be rewritten as projectPluginsDir

UnnecessaryGetter3228

[SRC]cacheDir currentDependencyManager.ivySettings.getDefault..absolutePath

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getDefaultCache() can probably be rewritten as defaultCache

UnnecessaryObjectReferences3237

[SRC]pluginResolver.setCheckmodified(true)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessarySelfAssignment3390

[SRC]PluginBuildSettings pluginSettings = pluginSettings

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter3461

[SRC]grails.build.logging.GrailsConsole.getInstance().warn("""

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getInstance() can probably be rewritten as instance

UnnecessaryPackageReference3461

[SRC]grails.build.logging.GrailsConsole.getInstance().warn("""

[MSG]The grails.build.logging.GrailsConsole class was explicitly imported, so specifying the package name is not necessary

UnnecessaryGetter3510

[SRC]def grailsVersion = settings.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter3563

[SRC]GrailsConsole.getInstance().addStatus("Uninstalled plugin [$name]")

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getInstance() can probably be rewritten as instance

UnnecessaryGetter3566

[SRC]GrailsConsole.getInstance().warning("No plugin [$name${v.. uninstall")

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getInstance() can probably be rewritten as instance

UnnecessaryDefInMethodDeclaration3585

[SRC]private def addToMetadata(pluginName, pluginVersion) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. The def keyword is unneeded when a method is marked private

UnnecessaryGetter3649

[SRC]GrailsConsole.getInstance().userInput(msg, ['y','n'] as ..ng[]) == 'y'

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getInstance() can probably be rewritten as instance

UnnecessaryGetter3657

[SRC]def pluginInfos = pluginSettings.getPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getPluginInfos() can probably be rewritten as pluginInfos

➥ PluginResolveEngine.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2273

[SRC]catch(e) {

[MSG]The catch block is empty

UnnecessaryGetter374

[SRC]output.println getPluginInfoHeader()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. getPluginInfoHeader() can probably be rewritten as pluginInfoHeader

UnnecessaryGetter3129

[SRC]output.println getPluginInfoFooter()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. getPluginInfoFooter() can probably be rewritten as pluginInfoFooter

UnnecessaryDefInMethodDeclaration3136

[SRC]protected def printDependencies(output, dependencies) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. The def keyword is unneeded when a method is marked protected

UnnecessaryDefInMethodDeclaration3145

[SRC]protected def printSectionTitle(PrintWriter output, String title) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. The def keyword is unneeded when a method is marked protected

UnnecessaryDefInMethodDeclaration3151

[SRC]protected def printLineSeparator(PrintWriter output) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. The def keyword is unneeded when a method is marked protected

➥ ResolveException.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter328

[SRC]for(IvyNode node in confReport.getUnresolvedDependencies()) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.ResolveException. getUnresolvedDependencies() can probably be rewritten as unresolvedDependencies

UnnecessaryGetter331

[SRC]def failedDownloads = confReport.getFailedArtifactsReports()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.ResolveException. getFailedArtifactsReports() can probably be rewritten as failedArtifactsReports

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.resolve.config

➥ RepositoriesConfigurer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences391

[SRC]fileSystemResolver.settings = dependencyManager.ivySettings

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3169

[SRC]urlResolver.setCheckmodified(true)

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.commons.cfg

➥ ConfigurationHelper.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGroovyImport321

[SRC]import java.util.Map

UnnecessaryGetter353

[SRC]getCachedConfigs().clear()

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getCachedConfigs() can probably be rewritten as cachedConfigs

UnnecessaryGetter364

[SRC]classLoader = application.getClassLoader()

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getClassLoader() can probably be rewritten as classLoader

UnnecessaryGetter377

[SRC]co = getCachedConfigs().get(cacheKey)

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getCachedConfigs() can probably be rewritten as cachedConfigs

UnnecessaryGetter3111

[SRC]getCachedConfigs().put(cacheKey, co)

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getCachedConfigs() can probably be rewritten as cachedConfigs

UnnecessaryGetter3127

[SRC]binding.put(CONFIG_BINDING_APP_NAME, application.getMeta..ATION_NAME))

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getMetadata() can probably be rewritten as metadata

UnnecessaryGetter3128

[SRC]binding.put(CONFIG_BINDING_APP_VERSION, application.getM..ON_VERSION))

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getMetadata() can probably be rewritten as metadata

UnnecessaryGetter3142

[SRC]getCachedConfigs().put(DEV_CACHE_KEY, config)

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getCachedConfigs() can probably be rewritten as cachedConfigs

UnnecessaryGetter3192

[SRC]stream = resource.getInputStream()

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getInputStream() can probably be rewritten as inputStream

➥ MapBasedSmartPropertyOverrideConfigurer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter345

[SRC]def beans = getBeansConfig()

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.MapBasedSmartPropertyOverrideConfigurer. getBeansConfig() can probably be rewritten as beansConfig

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.commons.metaclass

➥ MetaClassEnhancer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]method.invoke(method.getDeclaringClass(), instance, *args)

[MSG]Violation in class org.codehaus.groovy.grails.commons.metaclass.MetaClassEnhancer$1. getDeclaringClass() can probably be rewritten as declaringClass

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.compiler

➥ GrailsProjectCompiler.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField243

[SRC]private static final List<String> PLUGIN_EXCLUDE_PATHS =..ial handling

[MSG]The field PLUGIN_EXCLUDE_PATHS is not used within the class org.codehaus.groovy.grails.compiler.GrailsProjectCompiler

UnnecessaryGetter397

[SRC]pluginSettings.getArtefactResourcesForCurrentEnvironment())

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectCompiler. getArtefactResourcesForCurrentEnvironment() can probably be rewritten as artefactResourcesForCurrentEnvironment

UnnecessaryGetter3142

[SRC]def jarFiles = getJarFiles()

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectCompiler. getJarFiles() can probably be rewritten as jarFiles

UnnecessaryGetter3195

[SRC]jarFiles.addAll(getExtraDependencies())

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectCompiler. getExtraDependencies() can probably be rewritten as extraDependencies

➥ GrailsProjectPackager.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter342

[SRC]GrailsConsole grailsConsole = GrailsConsole.getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectPackager. getInstance() can probably be rewritten as instance

UnnecessaryGetter3119

[SRC]ant.copy(todir:buildSettings.getClassesDir(), failonerror:false) {

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectPackager. getClassesDir() can probably be rewritten as classesDir

UnnecessaryGetter3269

[SRC]def pluginInfos = pluginSettings.getSupportedPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectPackager. getSupportedPluginInfos() can probably be rewritten as supportedPluginInfos

UnnecessaryGetter3295

[SRC]def pluginInfos = pluginSettings.getSupportedPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectPackager. getSupportedPluginInfos() can probably be rewritten as supportedPluginInfos

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.exceptions

➥ DefaultStackTracePrinter.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity243

[SRC]String prettyPrint(Throwable t) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. The cyclomatic complexity for method [prettyPrint] is [23]

CyclomaticComplexity2167

[SRC]String prettyPrintCodeSnippet(Throwable exception) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. The cyclomatic complexity for method [prettyPrintCodeSnippet] is [21]

EmptyCatchBlock2239

[SRC]catch (e) {

[MSG]The catch block is empty

EmptyCatchBlock2245

[SRC]} catch (e) {

[MSG]The catch block is empty

EmptyCatchBlock2278

[SRC]} catch (e) {

[MSG]The catch block is empty

UnusedMethodParameter2318

[SRC]String formatCodeSnippetEnd(Resource resource, int lineNumber) {

[MSG]Violation in class DefaultStackTracePrinter. Method parameter [resource] is never referenced in the method formatCodeSnippetEnd of class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter

UnusedMethodParameter2318

[SRC]String formatCodeSnippetEnd(Resource resource, int lineNumber) {

[MSG]Violation in class DefaultStackTracePrinter. Method parameter [lineNumber] is never referenced in the method formatCodeSnippetEnd of class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter

UnnecessaryDefInMethodDeclaration3139

[SRC]protected def printCausedByMessage(PrintWriter sb, Throwable e) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. The def keyword is unneeded when a method is marked protected

UnnecessaryDefInMethodDeclaration3144

[SRC]protected def printHeader(PrintWriter sb, String header) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. The def keyword is unneeded when a method is marked protected

UnnecessaryGetter3164

[SRC]res == null ? te.className : res.getFilename()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getFilename() can probably be rewritten as filename

UnnecessaryGetter3284

[SRC]Object message = mcee.getErrorCollector().getErrors().it..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getErrors() can probably be rewritten as errors

UnnecessaryGetter3284

[SRC]Object message = mcee.getErrorCollector().getErrors().it..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getErrorCollector() can probably be rewritten as errorCollector

UnnecessaryGetter3287

[SRC]final tmp = new FileSystemResource(sem.getCause().getSourceLocator())

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getSourceLocator() can probably be rewritten as sourceLocator

UnnecessaryGetter3287

[SRC]final tmp = new FileSystemResource(sem.getCause().getSourceLocator())

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

UnnecessaryGetter3309

[SRC]Object message = mcee.getErrorCollector().getErrors().it..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getErrors() can probably be rewritten as errors

UnnecessaryGetter3309

[SRC]Object message = mcee.getErrorCollector().getErrors().it..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getErrorCollector() can probably be rewritten as errorCollector

UnnecessaryGetter3312

[SRC]lineNumber = sem.getCause().getLine()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getLine() can probably be rewritten as line

UnnecessaryGetter3312

[SRC]lineNumber = sem.getCause().getLine()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

UnnecessaryGetter3344

[SRC]while (ex.getCause() != null && !ex.equals(ex.getCause())) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

UnnecessaryGetter3344

[SRC]while (ex.getCause() != null && !ex.equals(ex.getCause())) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

UnnecessaryGetter3345

[SRC]ex = ex.getCause()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ CoreGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter345

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter380

[SRC]if (getParentCtx()?.containsBean('pluginManager')) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPlugin. getParentCtx() can probably be rewritten as parentCtx

UnnecessaryCollectCall399

[SRC]def locations = new ArrayList(settings.pluginDirectories..olutePath })

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPlugin. The call to collect could probably be rewritten as a spread expression: settings.pluginDirectories*.absolutePath

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.plugins.publishing

➥ DefaultPluginPublisher.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2157

[SRC]protected GPathResult getPluginMetadata(String pluginName) {

[MSG]Violation in class DefaultPluginPublisher. Method parameter [pluginName] is never referenced in the method getPluginMetadata of class org.codehaus.groovy.grails.plugins.publishing.DefaultPluginPublisher

UnnecessaryCallForLastElement3120

[SRC]def lastPlugin = allPlugins[allPlugins.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to allPlugins.last() or allPlugins[-1]

UnnecessaryGetter3140

[SRC]InputStream stream = pluginsListFile.getInputStream()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.publishing.DefaultPluginPublisher. getInputStream() can probably be rewritten as inputStream

➥ PluginDescriptorGenerator.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity283

[SRC]protected void generatePluginXml(pluginProps, MarkupBuilder xml) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.publishing.PluginDescriptorGenerator. The cyclomatic complexity for method [generatePluginXml] is [28]

UnusedImport327

[SRC]import org.apache.ivy.plugins.resolver.URLResolver

[MSG]The [org.apache.ivy.plugins.resolver.URLResolver] import is never referenced

➥ PluginPackager.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2139

[SRC]String packageSource(String pluginName, File classesDir,..targetDir) {

[MSG]Violation in class PluginPackager. Method parameter [classesDir] is never referenced in the method packageSource of class org.codehaus.groovy.grails.plugins.publishing.PluginPackager

UnusedMethodParameter2139

[SRC]String packageSource(String pluginName, File classesDir,..targetDir) {

[MSG]Violation in class PluginPackager. Method parameter [targetDir] is never referenced in the method packageSource of class org.codehaus.groovy.grails.plugins.publishing.PluginPackager

UnusedVariable2149

[SRC]def pluginGrailsVersion = "${GrailsUtil.grailsVersion} > *"

[MSG]The variable [pluginGrailsVersion] in class org.codehaus.groovy.grails.plugins.publishing.PluginPackager is not used

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.plugins.support

➥ GrailsPluginUtils.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter313

[SRC]return GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.support.GrailsPluginUtils. getGrailsVersion() can probably be rewritten as grailsVersion

➥ WatchPattern.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock259

[SRC]} catch (e) {

[MSG]The catch block is empty

Package: grails-crud.src.main.groovy.org.codehaus.groovy.grails.scaffolding

➥ DefaultGrailsTemplateGenerator.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethod2144

[SRC]private generateListView(domainClass, destDir) {

[MSG]The method generateListView is not used within DefaultGrailsTemplateGenerator.groovy

UnusedPrivateMethod2154

[SRC]private generateShowView(domainClass, destDir) {

[MSG]The method generateShowView is not used within DefaultGrailsTemplateGenerator.groovy

UnusedPrivateMethod2164

[SRC]private generateEditView(domainClass, destDir) {

[MSG]The method generateEditView is not used within DefaultGrailsTemplateGenerator.groovy

UnusedPrivateMethod2174

[SRC]private generateCreateView(domainClass, destDir) {

[MSG]The method generateCreateView is not used within DefaultGrailsTemplateGenerator.groovy

UnnecessaryGetter3113

[SRC]for (t in getTemplateNames()) {

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator. getTemplateNames() can probably be rewritten as templateNames

UnnecessaryGetter3255

[SRC]def response = GrailsConsole.getInstance().userInput("Fi..as String[])

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator. getInstance() can probably be rewritten as instance

UnnecessaryGetter3284

[SRC]return templateFile.inputStream.getText()

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator. getText() can probably be rewritten as text

UnnecessarySubstring3306

[SRC]template = template.substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator. The String.substring(int) method can be replaced with the subscript operator

Package: grails-docs.src.main.groovy.grails.doc

➥ DocEngine.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2227

[SRC]void appendCreateLink(StringBuffer buffer, String name, String view) {

[MSG]Violation in class DocEngine. Method parameter [view] is never referenced in the method appendCreateLink of class grails.doc.DocEngine

UnusedMethodParameter2301

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class BlockQuoteFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.BlockQuoteFilter

UnusedMethodParameter2310

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class ItalicFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.ItalicFilter

UnusedMethodParameter2319

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class BoldFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.BoldFilter

UnusedMethodParameter2329

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class CodeFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.CodeFilter

UnusedMethodParameter2363

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class TextileLinkFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.TextileLinkFilter

UnusedImport321

[SRC]import java.util.regex.Pattern

[MSG]The [java.util.regex.Pattern] import is never referenced

UnusedImport330

[SRC]import org.radeox.macro.CodeMacro

[MSG]The [org.radeox.macro.CodeMacro] import is never referenced

UnusedImport332

[SRC]import org.radeox.macro.parameter.BaseMacroParameter

[MSG]The [org.radeox.macro.parameter.BaseMacroParameter] import is never referenced

UnusedImport336

[SRC]import org.radeox.util.Encoder

[MSG]The [org.radeox.util.Encoder] import is never referenced

➥ DocPublisher.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2101

[SRC]catch (e) {

[MSG]The catch block is empty

CyclomaticComplexity2130

[SRC]private void catPublish() {

[MSG]Violation in class grails.doc.DocPublisher. The cyclomatic complexity for method [catPublish] is [28]

UnusedVariable2251

[SRC]def fullToc = new StringBuilder()

[MSG]The variable [fullToc] in class grails.doc.DocPublisher is not used

UnusedVariable2295

[SRC]def reference = [:]

[MSG]The variable [reference] in class grails.doc.DocPublisher is not used

UnnecessaryObjectReferences3404

[SRC]varsCopy.content = engine.render(sourceFile.text, context)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3586

[SRC]URL url = getClass().getClassLoader().getResource(src)

[MSG]Violation in class grails.doc.DocPublisher. getClassLoader() can probably be rewritten as classLoader

➥ PdfBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField225

[SRC]private static final String LIVE_DOC_SITE = 'http://grails.org'

[MSG]The field LIVE_DOC_SITE is not used within the class grails.doc.PdfBuilder

UnusedMethodParameter227

[SRC]static void build(String baseDir, String styleDir = null) {

[MSG]Violation in class PdfBuilder. Method parameter [styleDir] is never referenced in the method build of class grails.doc.PdfBuilder

UnnecessaryGetter373

[SRC]Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()))

[MSG]Violation in class grails.doc.PdfBuilder. getBytes() can probably be rewritten as bytes

Package: grails-docs.src.main.groovy.grails.doc.filters

➥ HeaderFilter.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter232

[SRC]void handleMatch(StringBuffer out, MatchResult matchResu..erContext) {

[MSG]Violation in class HeaderFilter. Method parameter [filterContext] is never referenced in the method handleMatch of class grails.doc.filters.HeaderFilter

UnusedImport317

[SRC]import org.radeox.filter.regex.RegexFilter

[MSG]The [org.radeox.filter.regex.RegexFilter] import is never referenced

➥ LinkTestFilter.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable254

[SRC]Writer writer = new StringBufferWriter(buffer)

[MSG]The variable [writer] in class grails.doc.filters.LinkTestFilter is not used

UnusedImport322

[SRC]import org.radeox.filter.interwiki.InterWiki

[MSG]The [org.radeox.filter.interwiki.InterWiki] import is never referenced

UnnecessaryGetter348

[SRC]def engine = context.getRenderContext().getRenderEngine()

[MSG]Violation in class grails.doc.filters.LinkTestFilter. getRenderEngine() can probably be rewritten as renderEngine

UnnecessaryGetter348

[SRC]def engine = context.getRenderContext().getRenderEngine()

[MSG]Violation in class grails.doc.filters.LinkTestFilter. getRenderContext() can probably be rewritten as renderContext

UnnecessarySubstring371

[SRC]alias = name.substring(0, pipeIndex)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessarySubstring372

[SRC]name = name.substring(pipeIndex + 1)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring379

[SRC]hash = name.substring(hashIndex + 1)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring380

[SRC]name = name.substring(0, hashIndex)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessaryGetter3106

[SRC]context.getRenderContext().setCacheable(false)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. getRenderContext() can probably be rewritten as renderContext

Package: grails-docs.src.main.groovy.grails.doc.gradle

➥ PublishGuide.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences356

[SRC]publisher.css = project.file("${resourcesDir}/css")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences357

[SRC]publisher.js = project.file("${resourcesDir}/js")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences358

[SRC]publisher.style = project.file("${resourcesDir}/style")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences359

[SRC]publisher.version = props."grails.version"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences360

[SRC]publisher.logo = '<a href="http://grails.org" target="_b..r="0"/></a>'

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences361

[SRC]publisher.sponsorLogo = '<a href="http://springsource.co..r="0"/></a>'

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-docs.src.main.groovy.grails.doc.macros

➥ GspTagSourceMacro.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable227

[SRC]String code

[MSG]The variable [code] in class grails.doc.macros.GspTagSourceMacro is not used

Package: grails-hibernate.src.main.groovy.org.codehaus.groovy.grails.orm.hibernate

➥ GrailsHibernateTransactionManager.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import org.hibernate.Session

[MSG]The [org.hibernate.Session] import is never referenced

➥ HibernateGormEnhancer.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2194

[SRC]} catch (e) {

[MSG]The catch block is empty

ThrowExceptionFromFinallyBlock2961

[SRC]throw e

[MSG]Throwing an exception from a finally block can hide an underlying error

UnnecessaryGetter3148

[SRC]this.sessionFactory = datastore.getSessionFactory()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormStaticApi. getSessionFactory() can probably be rewritten as sessionFactory

UnnecessaryGetter3156

[SRC]grailsApplication = domainClassMappingContext.getGrailsApplication()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormStaticApi. getGrailsApplication() can probably be rewritten as grailsApplication

UnnecessaryGetter3668

[SRC]def sessionFactory = datastore.getSessionFactory()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormValidationApi. getSessionFactory() can probably be rewritten as sessionFactory

UnnecessaryGetter3673

[SRC]def grailsApplication = domainClassMappingContext.getGra..pplication()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormValidationApi. getGrailsApplication() can probably be rewritten as grailsApplication

UnnecessaryGetter3736

[SRC]sessionFactory = datastore.getSessionFactory()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi. getSessionFactory() can probably be rewritten as sessionFactory

UnnecessaryGetter3741

[SRC]def grailsApplication = domainClassMappingContext.getGra..pplication()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi. getGrailsApplication() can probably be rewritten as grailsApplication

Package: grails-hibernate.src.main.groovy.org.codehaus.groovy.grails.orm.hibernate.cfg

➥ GORMEnhancingBeanPostProcessor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter243

[SRC]def postProcessBeforeInitialization(Object bean, String ..me) { bean }

[MSG]Violation in class GORMEnhancingBeanPostProcessor. Method parameter [beanName] is never referenced in the method postProcessBeforeInitialization of class org.codehaus.groovy.grails.orm.hibernate.cfg.GORMEnhancingBeanPostProcessor

UnusedMethodParameter245

[SRC]Object postProcessAfterInitialization(Object bean, String beanName) {

[MSG]Violation in class GORMEnhancingBeanPostProcessor. Method parameter [beanName] is never referenced in the method postProcessAfterInitialization of class org.codehaus.groovy.grails.orm.hibernate.cfg.GORMEnhancingBeanPostProcessor

➥ HibernateMappingBuilder.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2373

[SRC]private handleMethodMissing = { String name, args ->

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.HibernateMappingBuilder. The cyclomatic complexity for method [handleMethodMissing] is [46]

UnnecessaryObjectReferences3382

[SRC]property.cascade = namedArgs.cascade ?: property.cascade

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3383

[SRC]property.sort = namedArgs.sort ?: property.sort

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3384

[SRC]property.order = namedArgs.order ?: property.order

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3385

[SRC]property.batchSize = namedArgs.batchSize instanceof Inte..ty.batchSize

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3386

[SRC]property.ignoreNotFound = namedArgs.ignoreNotFound != nu..noreNotFound

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3387

[SRC]property.typeParams = namedArgs.params ?: property.typeParams

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3577

[SRC]column.length = args["length"] ?: -1

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3578

[SRC]column.precision = args["precision"] ?: -1

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3579

[SRC]column.scale = args["scale"] ?: -1

[MSG]The code could be more concise by using a with() or identity() block

➥ HibernateNamedQueriesBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3231

[SRC]def preparedClosure = getPreparedCriteriaClosure()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.NamedCriteriaProxy. getPreparedCriteriaClosure() can probably be rewritten as preparedCriteriaClosure

UnnecessaryGetter3287

[SRC]def previousClosure = previousInChain.getPreparedCriteriaClosure()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.NamedCriteriaProxy. getPreparedCriteriaClosure() can probably be rewritten as preparedCriteriaClosure

Package: grails-hibernate.src.main.groovy.org.codehaus.groovy.grails.plugins.orm.hibernate

➥ HibernatePluginSupport.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity279

[SRC]static doWithSpring = {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. The cyclomatic complexity for method [doWithSpring] is [55]

UnusedVariable2186

[SRC]def cacheClass = getClass().classLoader.loadClass(cacheProvider)

[MSG]The variable [cacheClass] in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport is not used

UnusedVariable2349

[SRC]String prefix = isDefault ? '' : datasourceName + '_'

[MSG]The variable [prefix] in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport is not used

UnusedPrivateMethod2590

[SRC]private static List<String> removeNullNames(Map query) {

[MSG]The method removeNullNames is not used within HibernatePluginSupport.groovy

ThrowExceptionFromFinallyBlock2612

[SRC]throw e

[MSG]Throwing an exception from a finally block can hide an underlying error

EmptyCatchBlock2638

[SRC]} catch (TypeMismatchException e) {

[MSG]The catch block is empty

EmptyCatchBlock2669

[SRC]} catch (FileNotFoundException fnfe) {

[MSG]The catch block is empty

UnusedImport332

[SRC]import org.codehaus.groovy.grails.orm.hibernate.cfg.Defa..onfiguration

[MSG]The [org.codehaus.groovy.grails.orm.hibernate.cfg.DefaultGrailsDomainConfiguration] import is never referenced

UnusedImport367

[SRC]import org.codehaus.groovy.grails.domain.GrailsDomainCla..istentEntity

[MSG]The [org.codehaus.groovy.grails.domain.GrailsDomainClassPersistentEntity] import is never referenced

UnnecessaryGetter381

[SRC]if (getSpringConfig().containsBean(ConstraintsEvaluator.BEAN_NAME)) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter396

[SRC]if (getSpringConfig().containsBean('dataSource')) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3107

[SRC]new PersistentConstraintFactory(getSpringConfig().getUnr..onContext(),

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter3107

[SRC]new PersistentConstraintFactory(getSpringConfig().getUnr..onContext(),

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryCollectCall3252

[SRC]hibConfigLocations.addAll(explicitLocations.collect { it.toString() })

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. The call to collect could probably be rewritten as a spread expression: explicitLocations*.toString()

UnnecessaryGetter3320

[SRC]if (getSpringConfig().containsBean("controllerHandlerMappings")) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3323

[SRC]if (getSpringConfig().containsBean("annotationHandlerMapping")) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3510

[SRC]for (PersistentEntity entity in mappingContext.getPersis..ntities()) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getPersistentEntities() can probably be rewritten as persistentEntities

UnnecessaryObjectReferences3701

[SRC]validateMethods.remove 'setValidateMethod'

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-plugin-async.src.main.groovy.org.codehaus.groovy.grails.plugins.web.async

➥ ControllersAsyncGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.ControllersAsyncGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

➥ GrailsAsyncContext.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport325

[SRC]import org.codehaus.groovy.grails.web.sitemesh.SpringMVCViewDecorator

[MSG]The [org.codehaus.groovy.grails.web.sitemesh.SpringMVCViewDecorator] import is never referenced

UnnecessaryGetter345

[SRC]def applicationContext = webRequest.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter358

[SRC]GrailsWebRequest webRequest = new GrailsWebRequest(reque..etContext())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter384

[SRC]def targetResponse = bufferingResponse.getTargetResponse()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getTargetResponse() can probably be rewritten as targetResponse

UnnecessaryGetter385

[SRC]def content = bufferingResponse.getContent()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getContent() can probably be rewritten as content

UnnecessaryGetter391

[SRC]content.writeOriginal(targetResponse.getWriter())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getWriter() can probably be rewritten as writer

Package: grails-plugin-async.src.main.groovy.org.codehaus.groovy.grails.plugins.web.async.api

➥ ControllersAsyncApi.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter239

[SRC]AsyncContext startAsync(instance) {

[MSG]Violation in class ControllersAsyncApi. Method parameter [instance] is never referenced in the method startAsync of class org.codehaus.groovy.grails.plugins.web.async.api.ControllersAsyncApi

Package: grails-plugin-codecs.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ CodecsGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter332

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CodecsGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter372

[SRC]def encodeMethod = codecClass.getEncodeMethod()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CodecsGrailsPlugin. getEncodeMethod() can probably be rewritten as encodeMethod

UnnecessaryGetter384

[SRC]def decodeMethod = codecClass.getDecodeMethod()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CodecsGrailsPlugin. getDecodeMethod() can probably be rewritten as decodeMethod

Package: grails-plugin-codecs.src.main.groovy.org.codehaus.groovy.grails.plugins.codecs

➥ Base64Codec.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import org.codehaus.groovy.runtime.DefaultGroovyMethods

[MSG]The [org.codehaus.groovy.runtime.DefaultGroovyMethods] import is never referenced

UnnecessaryGetter349

[SRC]return Base64.decodeBase64(theTarget.toString().getBytes())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.Base64Codec. getBytes() can probably be rewritten as bytes

➥ HexCodec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure332

[SRC]theTarget.each() {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.HexCodec. Parentheses in the 'each' method call are unnecessary and can be removed.

➥ SHA256Codec.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import java.security.MessageDigest

[MSG]The [java.security.MessageDigest] import is never referenced

➥ URLCodec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGroovyImport318

[SRC]import java.net.URLEncoder

UnnecessaryGroovyImport319

[SRC]import java.net.URLDecoder

UnnecessaryGetter330

[SRC]URLEncoder.encode(obj.toString(), URLCodec.getEncoding())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.URLCodec. getEncoding() can probably be rewritten as encoding

UnnecessaryGetter334

[SRC]URLDecoder.decode(obj.toString(), URLCodec.getEncoding())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.URLCodec. getEncoding() can probably be rewritten as encoding

UnnecessaryDefInMethodDeclaration337

[SRC]private static def getEncoding() {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.URLCodec. The def keyword is unneeded when a method is marked private

UnnecessaryGetter338

[SRC]def request = RequestContextHolder.getRequestAttributes()?.request

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.URLCodec. getRequestAttributes() can probably be rewritten as requestAttributes

Package: grails-plugin-codecs.src.test.groovy.org.codehaus.groovy.grails.web.codecs

➥ Base64CodecTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper214

[SRC]protected void setUp() {

[MSG]Violation in class Base64CodecTests. The method setUp() does not call super.setUp()

➥ HexCodecTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertNullInsteadOfAssertEquals321

[SRC]assertEquals(codec.encode(null), null)

[MSG]Violation in class org.codehaus.groovy.grails.web.codecs.HexCodecTests. assertEquals can be simplified using assertNull

UseAssertNullInsteadOfAssertEquals330

[SRC]assertEquals(codec.decode(null), null)

[MSG]Violation in class org.codehaus.groovy.grails.web.codecs.HexCodecTests. assertEquals can be simplified using assertNull

➥ URLCodecTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper214

[SRC]protected void setUp() {

[MSG]Violation in class URLCodecTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper219

[SRC]protected void tearDown() {

[MSG]Violation in class URLCodecTests. The method tearDown() does not call super.tearDown()

Package: grails-plugin-controllers.src.main.groovy.org.codehaus.groovy.grails.plugins.web

➥ ControllersGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2109

[SRC]def basedir = System.getProperty("base.dir")

[MSG]The variable [basedir] in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin is not used

UnusedVariable2110

[SRC]def grailsEnv = Environment.current.name

[MSG]The variable [grailsEnv] in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin is not used

UnusedMethodParameter2201

[SRC]static void enhanceDomainWithBinding(ApplicationContext ..aClass mc) {

[MSG]Violation in class ControllersGrailsPlugin. Method parameter [ctx] is never referenced in the method enhanceDomainWithBinding of class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin

UnnecessaryGetter350

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryCallForLastElement3113

[SRC]mappingElement = mappingElement[mappingElement.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to mappingElement.last() or mappingElement[-1]

UnnecessaryCallForLastElement3113

[SRC]mappingElement = mappingElement[mappingElement.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to mappingElement.last() or mappingElement[-1]

UnnecessaryCallForLastElement3125

[SRC]def lastFilter = filters[filters.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filters.last() or filters[-1]

UnnecessaryCallForLastElement3125

[SRC]def lastFilter = filters[filters.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filters.last() or filters[-1]

UnnecessaryCallForLastElement3126

[SRC]def lastFilterMapping = filterMappings[filterMappings.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filterMappings.last() or filterMappings[-1]

UnnecessaryCallForLastElement3126

[SRC]def lastFilterMapping = filterMappings[filterMappings.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filterMappings.last() or filterMappings[-1]

UnnecessaryGetter3169

[SRC]Object gspEnc = application.getFlatConfig().get("grails....encoding");

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin. getFlatConfig() can probably be rewritten as flatConfig

UnnecessaryDotClass3175

[SRC]def redirectListeners = ctx.getBeansOfType(RedirectEvent..tener.class)

[MSG]RedirectEventListener.class can be rewritten as RedirectEventListener

UnnecessaryGetter3178

[SRC]Object o = application.getFlatConfig().get(RedirectDynam..JSESSIONID);

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin. getFlatConfig() can probably be rewritten as flatConfig

Package: grails-plugin-controllers.src.main.groovy.org.codehaus.groovy.grails.web.metaclass

➥ ChainMethod.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]def flash = webRequest.getFlashScope()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.ChainMethod. getFlashScope() can probably be rewritten as flashScope

UnnecessaryGetter365

[SRC]def appCtx = webRequest.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.ChainMethod. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter374

[SRC]def response = webRequest.getCurrentResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.ChainMethod. getCurrentResponse() can probably be rewritten as currentResponse

➥ WithFormMethod.groovy

Rule NamePriorityLine #Source Line / Message
SynchronizedMethod266

[SRC]protected synchronized boolean isTokenValid(GrailsWebReq..ebRequest) {

[MSG]Violation in class WithFormMethod. The method isTokenValid is synchronized at the method level

SynchronizedMethod288

[SRC]protected synchronized resetToken(GrailsWebRequest webRequest) {

[MSG]Violation in class WithFormMethod. The method resetToken is synchronized at the method level

UnusedMethodParameter2118

[SRC]protected Object invalidTokenInternal(Closure callable) { model }

[MSG]Violation in class ValidResponseHandler. Method parameter [callable] is never referenced in the method invalidTokenInternal of class org.codehaus.groovy.grails.web.metaclass.ValidResponseHandler

UnusedImport317

[SRC]import javax.servlet.http.HttpServletRequest

[MSG]The [javax.servlet.http.HttpServletRequest] import is never referenced

UnnecessaryGetter367

[SRC]final request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.WithFormMethod. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter389

[SRC]final request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.WithFormMethod. getCurrentRequest() can probably be rewritten as currentRequest

Package: grails-plugin-controllers.src.main.groovy.org.codehaus.groovy.grails.web.plugins.support

➥ WebMetaUtils.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter285

[SRC]static void prepareCommandObjectBindingAction(Method act..ntext ctx) {

[MSG]Violation in class WebMetaUtils. Method parameter [action] is never referenced in the method prepareCommandObjectBindingAction of class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils

UnusedMethodParameter2230

[SRC]static registerCommonWebProperties(MetaClass mc, GrailsA..plication) {

[MSG]Violation in class WebMetaUtils. Method parameter [application] is never referenced in the method registerCommonWebProperties of class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils

UnnecessaryGetter3101

[SRC]def paramTypes = originalAction.getParameterTypes()

[MSG]Violation in class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils. getParameterTypes() can probably be rewritten as parameterTypes

UnnecessaryGetter3137

[SRC]constrainedProperty.getPropertyName()), errors)

[MSG]Violation in class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils. getPropertyName() can probably be rewritten as propertyName

UnnecessarySubstring3164

[SRC]return result.substring(0, result.size() - 8)

[MSG]Violation in class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessaryObjectReferences3250

[SRC]mc.getResponse = responseObject

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3252

[SRC]mc.getGrailsAttributes = grailsAttrsObject

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3254

[SRC]mc.getGrailsApplication = {-> RCH.currentRequestAttribut..pplication }

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3256

[SRC]mc.getActionName = {-> RCH.currentRequestAttributes().actionName }

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3257

[SRC]mc.getControllerName = {-> RCH.currentRequestAttributes(..rollerName }

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3258

[SRC]mc.getWebRequest = {-> RCH.currentRequestAttributes() }

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3264

[SRC]final MetaClass mc = taglib.getMetaClass()

[MSG]Violation in class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils. getMetaClass() can probably be rewritten as metaClass

Package: grails-plugin-converters.src.main.groovy.org.codehaus.groovy.grails.plugins.converters

➥ ConvertersGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter340

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.converters.ConvertersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter352

[SRC]controllers: GrailsUtil.getGrailsVersion(),

[MSG]Violation in class org.codehaus.groovy.grails.plugins.converters.ConvertersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter353

[SRC]domainClass: GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.converters.ConvertersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

➥ ConvertersPluginSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter244

[SRC]static void enhanceApplication(GrailsApplication applica..onContext) {

[MSG]Violation in class ConvertersPluginSupport. Method parameter [application] is never referenced in the method enhanceApplication of class org.codehaus.groovy.grails.plugins.converters.ConvertersPluginSupport

Package: grails-plugin-converters.src.main.groovy.org.codehaus.groovy.grails.web.converters

➥ JSONParsingParameterCreationListener.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter336

[SRC]def request = params.getRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONParsingParameterCreationListener. getRequest() can probably be rewritten as request

➥ XMLParsingParameterCreationListener.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]def request = params.getRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.XMLParsingParameterCreationListener. getRequest() can probably be rewritten as request

Package: grails-plugin-converters.src.main.groovy.org.codehaus.groovy.grails.web.converters.configuration

➥ configtest.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSamePackage33

[SRC]import org.codehaus.groovy.grails.web.converters.configu..nInitializer

ImportFromSamePackage34

[SRC]import org.codehaus.groovy.grails.web.converters.configu..rationHolder

ImportFromSamePackage36

[SRC]import org.codehaus.groovy.grails.web.converters.configu..onfiguration

ImportFromSamePackage37

[SRC]import org.codehaus.groovy.grails.web.converters.configu..onfiguration

UnnecessaryDotClass315

[SRC]def defcfg = ConvertersConfigurationHolder.getConverterC..(JSON.class)

[MSG]JSON.class can be rewritten as JSON

Package: grails-plugin-datasource.src.main.groovy.org.codehaus.groovy.grails.plugins.datasource

➥ DataSourceGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity272

[SRC]def createDatasource = { String datasourceName, ds ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. The cyclomatic complexity for method [createDatasource] is [22]

ClassForName2186

[SRC]codecClass = Class.forName(encryptionCodec, true, applic..classLoader)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)

EmptyCatchBlock2275

[SRC]} catch (e) {

[MSG]The catch block is empty

UnnecessaryGetter346

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter347

[SRC]def dependsOn = [core: GrailsUtil.getGrailsVersion()]

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryElseStatement3191

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryCallForLastElement3221

[SRC]listeners[listeners.size() - 1] + {

[MSG]Unnecessarily complex access of last element. This can be simplified to listeners.last() or listeners[-1]

UnnecessaryCallForLastElement3221

[SRC]listeners[listeners.size() - 1] + {

[MSG]Unnecessarily complex access of last element. This can be simplified to listeners.last() or listeners[-1]

UnnecessaryGetter3269

[SRC]connection = dataSource.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. getConnection() can probably be rewritten as connection

Package: grails-plugin-domain-class.src.main.groovy.org.codehaus.groovy.grails.domain

➥ GormApiSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter334

[SRC]PersistentEntity entity = ctx.getPersistentEntity(cls.getName())

[MSG]Violation in class org.codehaus.groovy.grails.domain.GormApiSupport. getName() can probably be rewritten as name

Package: grails-plugin-domain-class.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ DomainClassGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2113

[SRC]} catch (e) {

[MSG]The catch block is empty

CyclomaticComplexity2289

[SRC]public static addRelationshipManagementMethods(GrailsDom..ntext ctx) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. The cyclomatic complexity for method [addRelationshipManagementMethods] is [27]

UnusedImport319

[SRC]import grails.util.ClosureToMapPopulator

[MSG]The [grails.util.ClosureToMapPopulator] import is never referenced

UnusedImport340

[SRC]import org.codehaus.groovy.grails.commons.spring.GrailsR..Configurator

[MSG]The [org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator] import is never referenced

UnnecessaryGetter355

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryPackageReference3112

[SRC]org.grails.datastore.mapping.reflect.ClassPropertyFetche..hers.clear()

[MSG]The org.grails.datastore.mapping.reflect.ClassPropertyFetcher class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3112

[SRC]org.grails.datastore.mapping.reflect.ClassPropertyFetche..hers.clear()

[MSG]The org.grails.datastore.mapping.reflect.ClassPropertyFetcher class was explicitly imported, so specifying the package name is not necessary

UnnecessaryGetter3170

[SRC]for (GrailsDomainClass component in dc.getComponents()) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getComponents() can probably be rewritten as components

UnnecessaryGetter3225

[SRC]def attributes = rch.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3232

[SRC]def attributes = rch.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3261

[SRC]delegate.setErrors (new BeanPropertyBindingResult(delega...getName()))

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getName() can probably be rewritten as name

UnnecessaryElseStatement3306

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ DomainClassPluginSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import org.springframework.validation.BeanPropertyBindingResult

[MSG]The [org.springframework.validation.BeanPropertyBindingResult] import is never referenced

UnnecessaryGetter341

[SRC]prop.validate(object, object.getProperty(prop.getPropert..localErrors)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassPluginSupport. getPropertyName() can probably be rewritten as propertyName

UnnecessaryGetter346

[SRC]def fieldName = localError.getField()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassPluginSupport. getField() can probably be rewritten as field

Package: grails-plugin-filters.src.main.groovy.org.codehaus.groovy.grails.plugins.web.filters

➥ FilterConfig.groovy

Rule NamePriorityLine #Source Line / Message
ConsecutiveStringConcatenation3100

[SRC]"Invalid filter definition in ${filtersDefinition.getCla..} - trying "

[MSG]String concatenation in class org.codehaus.groovy.grails.plugins.web.filters.FilterConfig can be joined into a single literal

➥ FilterToHandlerAdapter.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2116

[SRC]boolean preHandle(HttpServletRequest request, HttpServle.. Object o) {

[MSG]Violation in class FilterToHandlerAdapter. Method parameter [o] is never referenced in the method preHandle of class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter

UnusedMethodParameter2138

[SRC]void postHandle(HttpServletRequest request, HttpServletR..elAndView) {

[MSG]Violation in class FilterToHandlerAdapter. Method parameter [o] is never referenced in the method postHandle of class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter

UnusedMethodParameter2182

[SRC]void afterCompletion(HttpServletRequest request, HttpSer...Exception {

[MSG]Violation in class FilterToHandlerAdapter. Method parameter [response] is never referenced in the method afterCompletion of class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter

UnusedMethodParameter2182

[SRC]void afterCompletion(HttpServletRequest request, HttpSer...Exception {

[MSG]Violation in class FilterToHandlerAdapter. Method parameter [o] is never referenced in the method afterCompletion of class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter

UnnecessaryGetter3112

[SRC]if (!uri) uri = request.getRequestURI()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter. getRequestURI() can probably be rewritten as requestURI

UnnecessaryGetter3113

[SRC]return uri.substring(request.getContextPath().length())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter. getContextPath() can probably be rewritten as contextPath

UnnecessarySubstring3113

[SRC]return uri.substring(request.getContextPath().length())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3223

[SRC]actionName = controllerClass?.getDefaultAction()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter. getDefaultAction() can probably be rewritten as defaultAction

➥ FiltersGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2100

[SRC]def filterClass = applicationContext.getBean("${c.fullName}Class")

[MSG]The variable [filterClass] in class org.codehaus.groovy.grails.plugins.web.filters.FiltersGrailsPlugin is not used

UnusedVariable2149

[SRC]def filterClass = applicationContext.getBean("${c.fullName}Class")

[MSG]The variable [filterClass] in class org.codehaus.groovy.grails.plugins.web.filters.FiltersGrailsPlugin is not used

UnnecessaryGetter340

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FiltersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-gsp.src.main.groovy.org.codehaus.groovy.grails.plugins.web

➥ GroovyPagesGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity289

[SRC]def doWithSpring = {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. The cyclomatic complexity for method [doWithSpring] is [23]

UnusedVariable2289

[SRC]GrailsPluginManager pluginManager = getManager()

[MSG]The variable [pluginManager] in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin is not used

UnusedImport325

[SRC]import org.codehaus.groovy.grails.commons.GrailsClassUtils

[MSG]The [org.codehaus.groovy.grails.commons.GrailsClassUtils] import is never referenced

UnusedImport326

[SRC]import org.codehaus.groovy.grails.commons.GrailsTagLibClass

[MSG]The [org.codehaus.groovy.grails.commons.GrailsTagLibClass] import is never referenced

UnnecessaryGetter361

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessarySelfAssignment3167

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3167

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3172

[SRC]jspTagLibraryResolver = jspTagLibraryResolver

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3172

[SRC]jspTagLibraryResolver = jspTagLibraryResolver

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3178

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3178

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3202

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3202

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter3269

[SRC]if (Modifier.isAbstract(superClass.getModifiers()) && !s..Enhanced)) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. getModifiers() can probably be rewritten as modifiers

UnnecessaryGetter3278

[SRC]nonEnhancedClasses.each { enhancer.enhance it.getMetaClass() }

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. getMetaClass() can probably be rewritten as metaClass

UnnecessaryGetter3289

[SRC]GrailsPluginManager pluginManager = getManager()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. getManager() can probably be rewritten as manager

Package: grails-plugin-gsp.src.main.groovy.org.codehaus.groovy.grails.plugins.web.taglib

➥ ApplicationTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport326

[SRC]import org.codehaus.groovy.runtime.DefaultGroovyMethods;

[MSG]The [org.codehaus.groovy.runtime.DefaultGroovyMethods] import is never referenced

UnnecessaryElseStatement380

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryElseStatement3203

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3233

[SRC]def writer = getOut()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib. getOut() can probably be rewritten as out

UnnecessaryElseStatement3398

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ CountryTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall3274

[SRC]ISO3166_3.entrySet().sort { a, b -> a.value.compareTo(b...) { it.key }

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.CountryTagLib. The call to collect could probably be rewritten as a spread expression: ISO3166_3.entrySet().sort(<not implemented yet for class: org.codehaus.groovy.ast.expr.ClosureExpression>)*.key

UnnecessaryParenthesesForMethodCallWithClosure3274

[SRC]ISO3166_3.entrySet().sort { a, b -> a.value.compareTo(b...) { it.key }

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.CountryTagLib. Parentheses in the 'collect' method call are unnecessary and can be removed.

➥ FormTagLib.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2477

[SRC]Closure datePicker = { attrs ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. The cyclomatic complexity for method [datePicker] is [58]

AddEmptyString2667

[SRC]def h = '' + i

[MSG]Concatenating an empty string is an inefficient way to convert an object to a String. Consider using toString() or String.valueOf(Object)

AddEmptyString2696

[SRC]def m = '' + i

[MSG]Concatenating an empty string is an inefficient way to convert an object to a String. Consider using toString() or String.valueOf(Object)

CyclomaticComplexity2813

[SRC]Closure select = { attrs ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. The cyclomatic complexity for method [select] is [26]

EmptyCatchBlock2952

[SRC]catch (e) {

[MSG]The catch block is empty

UnusedImport325

[SRC]import org.codehaus.groovy.grails.web.util.StreamCharBuffer

[MSG]The [org.codehaus.groovy.grails.web.util.StreamCharBuffer] import is never referenced

UnnecessaryGetter3319

[SRC]def writer = getOut()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getOut() can probably be rewritten as out

UnnecessarySelfAssignment3478

[SRC]def out = out // let x = x ?

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3478

[SRC]def out = out // let x = x ?

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter3485

[SRC]xdefault = DateFormat.getInstance().parse(xdefault)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getInstance() can probably be rewritten as instance

UnnecessaryGetter3723

[SRC]attrs.from = TimeZone.getAvailableIDs()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getAvailableIDs() can probably be rewritten as availableIDs

UnnecessaryGetter3724

[SRC]attrs.value = (attrs.value ? attrs.value.ID : TimeZone.g..efault().ID)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getDefault() can probably be rewritten as default

UnnecessaryGetter3755

[SRC]attrs.from = Locale.getAvailableLocales()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getAvailableLocales() can probably be rewritten as availableLocales

UnnecessaryGetter3820

[SRC]def messageSource = grailsAttributes.getApplicationConte..sageSource")

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getApplicationContext() can probably be rewritten as applicationContext

➥ FormatTagLib.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2227

[SRC]Closure formatNumber = { attrs ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib. The cyclomatic complexity for method [formatNumber] is [26]

UnnecessaryGetter3162

[SRC]timeZone = TimeZone.getDefault()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib. getDefault() can probably be rewritten as default

UnnecessaryGetter3281

[SRC]dcfs = decimalFormat.getDecimalFormatSymbols()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib. getDecimalFormatSymbols() can probably be rewritten as decimalFormatSymbols

UnnecessaryGetter3338

[SRC]locale = Locale.getDefault()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib. getDefault() can probably be rewritten as default

➥ JavascriptTagLib.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock255

[SRC]} catch (e) {

[MSG]The catch block is empty

UnusedPrivateMethod262

[SRC]private void initHasResourceProcessor() {

[MSG]The method initHasResourceProcessor is not used within JavascriptTagLib.groovy

UnnecessarySubstring3162

[SRC]reqResCtx = (requestPluginContext.startsWith("/") ? requ..ntext) + '/'

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3193

[SRC]getProvider().doRemoteFunction(owner, attrs, out)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib. getProvider() can probably be rewritten as provider

UnnecessaryGetter3349

[SRC]def p = getProvider()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib. getProvider() can probably be rewritten as provider

UnnecessaryGetter3388

[SRC]def p = getProvider()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib. getProvider() can probably be rewritten as provider

➥ RenderTagLib.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2329

[SRC]Closure paginate = { attrs ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. The cyclomatic complexity for method [paginate] is [40]

UnnecessaryGetter352

[SRC]return getRequest().getAttribute(PAGE)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getRequest() can probably be rewritten as request

UnnecessaryGetter3107

[SRC]def oldPage = getPage()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3151

[SRC]def parser = getFactory().getPageParser(contentType)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getFactory() can probably be rewritten as factory

UnnecessaryGetter3158

[SRC]def decoratorMapper = getFactory().getDecoratorMapper()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getDecoratorMapper() can probably be rewritten as decoratorMapper

UnnecessaryGetter3158

[SRC]def decoratorMapper = getFactory().getDecoratorMapper()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getFactory() can probably be rewritten as factory

UnnecessaryGetter3165

[SRC]def t = groovyPagesTemplateEngine.createTemplate(d.getPage())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3177

[SRC]return FactoryHolder.getFactory()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getFactory() can probably be rewritten as factory

UnnecessaryGetter3197

[SRC]def htmlPage = getPage()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessarySubstring3216

[SRC]out << propertyName.substring(propertyName.lastIndexOf('.') + 1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3244

[SRC]def htmlPage = getPage()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3291

[SRC]getPage().writeBody(out)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3302

[SRC]getPage().writeHead(out)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3565

[SRC]groovyPagesTemplateRenderer.render(getWebRequest(), getP..y, getOut())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getWebRequest() can probably be rewritten as webRequest

UnnecessaryGetter3565

[SRC]groovyPagesTemplateRenderer.render(getWebRequest(), getP..y, getOut())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPageScope() can probably be rewritten as pageScope

UnnecessaryGetter3565

[SRC]groovyPagesTemplateRenderer.render(getWebRequest(), getP..y, getOut())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getOut() can probably be rewritten as out

➥ SitemeshTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2172

[SRC]def content = captureTagContent(out, 'meta', attrs, body, true)

[MSG]The variable [content] in class org.codehaus.groovy.grails.plugins.web.taglib.SitemeshTagLib is not used

➥ ValidationTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall3115

[SRC]checkList = model.findAll {it.value?.errors instanceof E..t {it.value}

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The call to collect could probably be rewritten as a spread expression: model.findAll(<not implemented yet for class: org.codehaus.groovy.ast.expr.ClosureExpression>)*.value

UnnecessaryParenthesesForMethodCallWithClosure3249

[SRC]mkp.errors() {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. Parentheses in the 'errors' method call are unnecessary and can be removed.

UnnecessarySubstring3348

[SRC]def againstClass = attrs.against ?: form.substring(0,1)...substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessarySubstring3348

[SRC]def againstClass = attrs.against ?: form.substring(0,1)...substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryCollectCall3356

[SRC]appliedConstraints += it.collect{ it.appliedConstraints }

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The call to collect could probably be rewritten as a spread expression: it*.appliedConstraints

UnnecessarySubstring3384

[SRC]def scriptName = "org/apache/commons/validator/javascrip..g(1) + ".js"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessarySubstring3384

[SRC]def scriptName = "org/apache/commons/validator/javascrip..g(1) + ".js"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3410

[SRC]def validateType = k.substring(0,1).toUpperCase() + k.substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessarySubstring3410

[SRC]def validateType = k.substring(0,1).toUpperCase() + k.substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3426

[SRC]PropertyEditorRegistry registry = RequestContextHolder.c..orRegistry()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. getPropertyEditorRegistry() can probably be rewritten as propertyEditorRegistry

Package: grails-plugin-i18n.src.main.groovy.org.codehaus.groovy.grails.plugins.i18n

➥ I18nGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]String version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.i18n.I18nGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-log4j.src.main.groovy.org.codehaus.groovy.grails.plugins.log4j

➥ Log4jConfig.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3181

[SRC]Logger root = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3229

[SRC]BuildSettings settings = BuildSettingsHolder.getSettings()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getSettings() can probably be rewritten as settings

UnnecessaryGetter3230

[SRC]def targetDir = settings?.getProjectTargetDir()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getProjectTargetDir() can probably be rewritten as projectTargetDir

UnnecessaryGetter3240

[SRC]def root = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3320

[SRC]LogLog.error "Appender $appender not found configuring l...getName()}"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getName() can probably be rewritten as name

UnnecessaryGetter3375

[SRC]Logger.getRootLogger().removeAppender name

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryDefInMethodDeclaration3444

[SRC]def EnvironmentsLog4JConfig(Log4jConfig config) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.EnvironmentsLog4JConfig. The def keyword is unneeded on constructors

➥ LoggingGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.LoggingGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryCallForLastElement355

[SRC]mappingElement = mappingElement[mappingElement.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to mappingElement.last() or mappingElement[-1]

UnnecessaryCallForLastElement355

[SRC]mappingElement = mappingElement[mappingElement.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to mappingElement.last() or mappingElement[-1]

Package: grails-plugin-mimetypes.src.main.groovy.org.codehaus.groovy.grails.plugins.web.api

➥ ControllersMimeTypesApi.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter250

[SRC]def withFormat(instance, Closure callable) {

[MSG]Violation in class ControllersMimeTypesApi. Method parameter [instance] is never referenced in the method withFormat of class org.codehaus.groovy.grails.plugins.web.api.ControllersMimeTypesApi

➥ RequestMimeTypesApi.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter376

[SRC]parser.configuredMimeTypes = getMimeTypes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.RequestMimeTypesApi. getMimeTypes() can probably be rewritten as mimeTypes

➥ ResponseMimeTypesApi.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter2122

[SRC]private MimeType[] getMimeTypesInternal(HttpServletReque.. response) {

[MSG]Violation in class ResponseMimeTypesApi. Method parameter [response] is never referenced in the method getMimeTypesInternal of class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi

UnnecessaryGetter372

[SRC]HttpServletRequest request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter377

[SRC]def allMimes = getMimeTypes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi. getMimeTypes() can probably be rewritten as mimeTypes

UnnecessaryGetter379

[SRC]result = mime ? mime.extension : getMimeTypes()[0].extension

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi. getMimeTypes() can probably be rewritten as mimeTypes

UnnecessaryGetter3130

[SRC]parser.configuredMimeTypes = getMimeTypes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi. getMimeTypes() can probably be rewritten as mimeTypes

Package: grails-plugin-mimetypes.src.main.groovy.org.codehaus.groovy.grails.plugins.web.mimes

➥ MimeTypesGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.mimes.MimeTypesGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-mimetypes.src.main.groovy.org.codehaus.groovy.grails.web.mime

➥ DefaultAcceptHeaderParser.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable245

[SRC]def qualifiedMimes = []

[MSG]The variable [qualifiedMimes] in class org.codehaus.groovy.grails.web.mime.DefaultAcceptHeaderParser is not used

UnnecessaryGetter343

[SRC]def config = application?.getConfig()

[MSG]Violation in class org.codehaus.groovy.grails.web.mime.DefaultAcceptHeaderParser. getConfig() can probably be rewritten as config

UnnecessaryGetter356

[SRC]return MimeType.getConfiguredMimeTypes()

[MSG]Violation in class org.codehaus.groovy.grails.web.mime.DefaultAcceptHeaderParser. getConfiguredMimeTypes() can probably be rewritten as configuredMimeTypes

Package: grails-plugin-scaffolding.src.main.groovy.org.codehaus.groovy.grails.plugins.scaffolding

➥ ScaffoldingGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2188

[SRC]catch (Exception e) {

[MSG]The catch block is empty

UnusedImport329

[SRC]import org.springframework.beans.factory.config.BeanDefinition

[MSG]The [org.springframework.beans.factory.config.BeanDefinition] import is never referenced

UnnecessaryGetter350

[SRC]def version = grails.util.GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.scaffolding.ScaffoldingGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-services.src.main.groovy.org.codehaus.groovy.grails.plugins.services

➥ ServicesGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter339

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.services.ServicesGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter390

[SRC]"${serviceClass.propertyName}"(serviceClass.getClazz()) { bean ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.services.ServicesGrailsPlugin. getClazz() can probably be rewritten as clazz

UnnecessaryGetter3158

[SRC]"$serviceName"(serviceClass.getClazz()) { bean ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.services.ServicesGrailsPlugin. getClazz() can probably be rewritten as clazz

Package: grails-plugin-servlets.src.main.groovy.org.codehaus.groovy.grails.plugins.web

➥ ServletsGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-testing.src.main.groovy.grails.test

➥ AbstractCliTestCase.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField222

[SRC]private final Condition waiting = lock.newCondition()

[MSG]The field waiting is not used within the class grails.test.AbstractCliTestCase

JUnitPublicNonTestMethod291

[SRC]String getOutput() {

[MSG]Violation in class AbstractCliTestCase. The method getOutput is public but not a test method

JUnitPublicNonTestMethod295

[SRC]void setOutput(String output) {

[MSG]Violation in class AbstractCliTestCase. The method setOutput is public but not a test method

JUnitPublicNonTestMethod2103

[SRC]File getWorkDir() {

[MSG]Violation in class AbstractCliTestCase. The method getWorkDir is public but not a test method

JUnitPublicNonTestMethod2107

[SRC]void setWorkDir(File dir) {

[MSG]Violation in class AbstractCliTestCase. The method setWorkDir is public but not a test method

JUnitPublicNonTestMethod2117

[SRC]void enterInput(String input) {

[MSG]Violation in class AbstractCliTestCase. The method enterInput is public but not a test method

JUnitPublicNonTestMethod2127

[SRC]int waitForProcess() {

[MSG]Violation in class AbstractCliTestCase. The method waitForProcess is public but not a test method

UnusedVariable2129

[SRC]final monitor = "monitor"

[MSG]The variable [monitor] in class grails.test.AbstractCliTestCase is not used

EmptyCatchBlock2139

[SRC]catch (InterruptedException ex) {

[MSG]The catch block is empty

JUnitPublicNonTestMethod2214

[SRC]public boolean isWindows() {

[MSG]Violation in class AbstractCliTestCase. The method isWindows is public but not a test method

➥ ControllerUnitTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod258

[SRC]Class getControllerClass() {

[MSG]Violation in class ControllerUnitTestCase. The method getControllerClass is public but not a test method

➥ GroovyPagesTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod237

[SRC]void setControllerName(String name) {

[MSG]Violation in class GroovyPagesTestCase. The method setControllerName is public but not a test method

JUnitPublicNonTestMethod249

[SRC]void assertOutputEquals(expected, template, params = [:]..tring() }) {

[MSG]Violation in class GroovyPagesTestCase. The method assertOutputEquals is public but not a test method

JUnitPublicNonTestMethod261

[SRC]String applyTemplate(template, params = [:]) {

[MSG]Violation in class GroovyPagesTestCase. The method applyTemplate is public but not a test method

JUnitPublicNonTestMethod267

[SRC]void applyTemplate(StringWriter sw, template, params = [:]) {

[MSG]Violation in class GroovyPagesTestCase. The method applyTemplate is public but not a test method

➥ MockUtils.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter2567

[SRC]private static void addDynamicFinders(Class clazz, List ..Instances) {

[MSG]Violation in class MockUtils. Method parameter [testInstances] is never referenced in the method addDynamicFinders of class grails.test.MockUtils

UnusedPrivateMethodParameter2655

[SRC]private static void addCountMethods(Class clazz, GrailsD..Instances) {

[MSG]Violation in class MockUtils. Method parameter [dc] is never referenced in the method addCountMethods of class grails.test.MockUtils

UnusedPrivateMethodParameter2732

[SRC]private static void addOtherStaticMethods(Class clazz, L..Instances) {

[MSG]Violation in class MockUtils. Method parameter [testInstances] is never referenced in the method addOtherStaticMethods of class grails.test.MockUtils

CyclomaticComplexity2752

[SRC]private static void addDynamicInstanceMethods(Class claz..Instances) {

[MSG]Violation in class grails.test.MockUtils. The cyclomatic complexity for method [addDynamicInstanceMethods] is [24]

CyclomaticComplexity2917

[SRC]private static void addValidateMethod(

[MSG]Violation in class grails.test.MockUtils. The cyclomatic complexity for method [addValidateMethod] is [27]

CyclomaticComplexity21097

[SRC]private static processInstances(instances, property, com..tor, args) {

[MSG]Violation in class grails.test.MockUtils. The cyclomatic complexity for method [processInstances] is [26]

UnusedImport342

[SRC]import org.springframework.validation.BeanPropertyBindingResult

[MSG]The [org.springframework.validation.BeanPropertyBindingResult] import is never referenced

ConstantAssertExpression3295

[SRC]assert false : "'template' attribute must be provided."

[MSG]The assert statement within class grails.test.MockUtils has a constant boolean expression [false]

UnnecessaryGetter3315

[SRC]clazz.metaClass.getSession = {-> mockRequest.getSession() }

[MSG]Violation in class grails.test.MockUtils. getSession() can probably be rewritten as session

UnnecessarySubstring3359

[SRC]def shortName = clazz.name.substring(pos + 1)

[MSG]Violation in class grails.test.MockUtils. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryElseStatement3633

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryDotClass3945

[SRC]while (clazz != Object.class) {

[MSG]Object.class can be rewritten as Object

UnnecessaryGetter3947

[SRC]clazz = clazz.getSuperclass()

[MSG]Violation in class grails.test.MockUtils. getSuperclass() can probably be rewritten as superclass

UnnecessaryDotClass31322

[SRC]if (value instanceof Number && Long.class.equals(targetType)) {

[MSG]Long.class can be rewritten as Long

➥ MvcUnitTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod285

[SRC]Class getTestClass() {

[MSG]Violation in class MvcUnitTestCase. The method getTestClass is public but not a test method

UnusedImport317

[SRC]import grails.util.GrailsNameUtils

[MSG]The [grails.util.GrailsNameUtils] import is never referenced

UnnecessaryDefInMethodDeclaration3122

[SRC]protected def bindMockWebRequest(GrailsMockHttpServletRe..kResponse) {

[MSG]Violation in class grails.test.MvcUnitTestCase. The def keyword is unneeded when a method is marked protected

➥ TagLibUnitTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod265

[SRC]Class getTagLibClass() {

[MSG]Violation in class TagLibUnitTestCase. The method getTagLibClass is public but not a test method

Package: grails-plugin-testing.src.main.groovy.grails.test.mixin.domain

➥ DomainClassUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass3153

[SRC]def validator = applicationContext.getBean(validationBea..dator.class)

[MSG]Validator.class can be rewritten as Validator

Package: grails-plugin-testing.src.main.groovy.grails.test.mixin.support

➥ GrailsUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass380

[SRC]CachedIntrospectionResults.clearClassLoader(GrailsUnitTe..classLoader)

[MSG]GrailsUnitTestMixin.class can be rewritten as GrailsUnitTestMixin

UnnecessaryGetter3169

[SRC]result = ScriptBytecodeAdapter.unwrap(gre).getMessage()

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getMessage() can probably be rewritten as message

UnnecessaryGetter3173

[SRC]result = e.getMessage()

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getMessage() can probably be rewritten as message

UnnecessaryGetter3201

[SRC]throw new AssertionFailedError("Closure " + code + " sho..z.getName())

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getName() can probably be rewritten as name

UnnecessaryGetter3203

[SRC]throw new AssertionFailedError("Closure " + code + " sho..ion " + th);

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getName() can probably be rewritten as name

UnnecessaryGetter3205

[SRC]return th.getMessage();

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getMessage() can probably be rewritten as message

Package: grails-plugin-testing.src.main.groovy.grails.test.mixin.web

➥ ControllerUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3124

[SRC]webRequest.getParams()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getParams() can probably be rewritten as params

UnnecessaryGetter3159

[SRC]webRequest.getFlashScope()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getFlashScope() can probably be rewritten as flashScope

UnnecessaryGetter3184

[SRC]final classLoader = ControllerUnitTestMixin.class.getClassLoader()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getClassLoader() can probably be rewritten as classLoader

UnnecessaryDotClass3184

[SRC]final classLoader = ControllerUnitTestMixin.class.getClassLoader()

[MSG]ControllerUnitTestMixin.class can be rewritten as ControllerUnitTestMixin

UnnecessaryGetter3252

[SRC]request = webRequest.getCurrentRequest()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter3253

[SRC]response = webRequest.getCurrentResponse()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getCurrentResponse() can probably be rewritten as currentResponse

UnnecessaryGetter3254

[SRC]servletContext = webRequest.getServletContext()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter3349

[SRC]return factory.getObject()

[MSG]Violation in class grails.test.mixin.web.TestResponseMimeTypesApi. getObject() can probably be rewritten as object

UnnecessaryGetter3359

[SRC]return factory.getObject()

[MSG]Violation in class grails.test.mixin.web.TestRequestMimeTypesApi. getObject() can probably be rewritten as object

➥ FiltersUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter364

[SRC]getCompositeInterceptor().handlers?.clear()

[MSG]Violation in class grails.test.mixin.web.FiltersUnitTestMixin. getCompositeInterceptor() can probably be rewritten as compositeInterceptor

UnnecessaryGetter394

[SRC]return getCompositeInterceptor()

[MSG]Violation in class grails.test.mixin.web.FiltersUnitTestMixin. getCompositeInterceptor() can probably be rewritten as compositeInterceptor

UnnecessaryGetter3116

[SRC]final interceptor = getCompositeInterceptor()

[MSG]Violation in class grails.test.mixin.web.FiltersUnitTestMixin. getCompositeInterceptor() can probably be rewritten as compositeInterceptor

➥ GroovyPageUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter397

[SRC]MetaClass mc = tagLib.getMetaClass()

[MSG]Violation in class grails.test.mixin.web.GroovyPageUnitTestMixin. getMetaClass() can probably be rewritten as metaClass

➥ UrlMappingsUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2182

[SRC]void assertForwardUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. The cyclomatic complexity for method [assertForwardUrlMapping] is [23]

MisorderedStaticImports328

[SRC]import static junit.framework.Assert.assertEquals

[MSG]Static imports should appear before normal imports

MisorderedStaticImports329

[SRC]import static junit.framework.Assert.assertNotNull

[MSG]Static imports should appear before normal imports

UnnecessarySelfAssignment354

[SRC]grailsApplication = grailsApplication

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter360

[SRC]getUrlMappingsHolder()

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. getUrlMappingsHolder() can probably be rewritten as urlMappingsHolder

UnnecessaryGetter377

[SRC]UrlMappingsHolder mappingsHolder = getUrlMappingsHolder()

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. getUrlMappingsHolder() can probably be rewritten as urlMappingsHolder

UnnecessarySubstring3217

[SRC]if (actual[0] == "/") actual = actual.substring(1)

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3218

[SRC]if (expected[0] == "/") expected = expected.substring(1)

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. The String.substring(int) method can be replaced with the subscript operator

Package: grails-plugin-tomcat.src.main.groovy.org.grails.plugins.tomcat

➥ InlineExplodedTomcatServer.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock255

[SRC]} catch (e) {

[MSG]The catch block is empty

MisorderedStaticImports325

[SRC]import static grails.build.logging.GrailsConsole.instance as CONSOLE

[MSG]Static imports should appear before normal imports

UnnecessaryGetter373

[SRC]def pluginManager = PluginManagerHolder.getPluginManager()

[MSG]Violation in class org.grails.plugins.tomcat.InlineExplodedTomcatServer. getPluginManager() can probably be rewritten as pluginManager

UnnecessaryObjectReferences3120

[SRC]sslConnector.setAttribute("keystorePass", keyPassword)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3121

[SRC]sslConnector.URIEncoding = 'UTF-8'

[MSG]The code could be more concise by using a with() or identity() block

➥ IsolatedWarTomcatServer.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock295

[SRC]try { err = errFile.text } catch (IOException e) {}

[MSG]The catch block is empty

EmptyCatchBlock2126

[SRC]} catch(e) {

[MSG]The catch block is empty

UnnecessaryGetter375

[SRC]for (entry in getConfigParams()) {

[MSG]Violation in class org.grails.plugins.tomcat.IsolatedWarTomcatServer. getConfigParams() can probably be rewritten as configParams

➥ TomcatLoader.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod252

[SRC]void addPropertyChangeListener(PropertyChangeListener listener) {}

[MSG]Violation in class TomcatLoader. The method addPropertyChangeListener is both empty and not marked with @Override

UnusedMethodParameter252

[SRC]void addPropertyChangeListener(PropertyChangeListener listener) {}

[MSG]Violation in class TomcatLoader. Method parameter [listener] is never referenced in the method addPropertyChangeListener of class org.grails.plugins.tomcat.TomcatLoader

EmptyMethod258

[SRC]void backgroundProcess() {}

[MSG]Violation in class TomcatLoader. The method backgroundProcess is both empty and not marked with @Override

EmptyMethod268

[SRC]void removePropertyChangeListener(PropertyChangeListener listener) {}

[MSG]Violation in class TomcatLoader. The method removePropertyChangeListener is both empty and not marked with @Override

UnusedMethodParameter268

[SRC]void removePropertyChangeListener(PropertyChangeListener listener) {}

[MSG]Violation in class TomcatLoader. Method parameter [listener] is never referenced in the method removePropertyChangeListener of class org.grails.plugins.tomcat.TomcatLoader

UnnecessaryGetter382

[SRC]log.info("Dual registration of jndi stream handler: " + ..etMessage())

[MSG]Violation in class org.grails.plugins.tomcat.TomcatLoader. getMessage() can probably be rewritten as message

UnnecessaryGetter386

[SRC]DirContextURLStreamHandler.bind(classLoader, container.getResources())

[MSG]Violation in class org.grails.plugins.tomcat.TomcatLoader. getResources() can probably be rewritten as resources

➥ TomcatServer.groovy

Rule NamePriorityLine #Source Line / Message
ClassForName2161

[SRC]Class.forName('sun.security.tools.KeyTool')

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)

ClassForName2164

[SRC]Class.forName('com.ibm.crypto.tools.KeyTool')

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)

MisorderedStaticImports323

[SRC]import static grails.build.logging.GrailsConsole.instance as CONSOLE

[MSG]Static imports should appear before normal imports

UnnecessaryGetter350

[SRC]buildSettings = BuildSettingsHolder.getSettings()

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. getSettings() can probably be rewritten as settings

UnnecessaryGetter351

[SRC]pluginSettings = GrailsPluginUtils.getPluginBuildSettings()

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3145

[SRC]getKeyToolClass().main(

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. getKeyToolClass() can probably be rewritten as keyToolClass

Package: grails-plugin-url-mappings.src.main.groovy.grails.test

➥ GrailsUrlMappingsTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod256

[SRC]def createMappingsHolder() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method createMappingsHolder is public but not a test method

JUnitPublicNonTestMethod263

[SRC]def createControllerMap() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method createControllerMap is public but not a test method

JUnitPublicNonTestMethod271

[SRC]def getUrlMappingEvaluatees() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method getUrlMappingEvaluatees is public but not a test method

JUnitSetUpCallsSuper284

[SRC]void setUp() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper291

[SRC]void tearDown() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method tearDown() does not call super.tearDown()

JUnitPublicNonTestMethod295

[SRC]def getActions(controller) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method getActions is public but not a test method

JUnitPublicNonTestMethod2104

[SRC]def getDefaultAction(controllerName) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method getDefaultAction is public but not a test method

JUnitPublicNonTestMethod2109

[SRC]def assertController(controller, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertController is public but not a test method

JUnitPublicNonTestMethod2115

[SRC]def assertAction(controller, action, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertAction is public but not a test method

JUnitPublicNonTestMethod2121

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertView is public but not a test method

JUnitPublicNonTestMethod2129

[SRC]void assertUrlMapping(assertions, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertUrlMapping is public but not a test method

JUnitPublicNonTestMethod2133

[SRC]void assertUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertUrlMapping is public but not a test method

JUnitPublicNonTestMethod2140

[SRC]void assertForwardUrlMapping(assertions, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertForwardUrlMapping is public but not a test method

JUnitPublicNonTestMethod2144

[SRC]void assertForwardUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertForwardUrlMapping is public but not a test method

CyclomaticComplexity2144

[SRC]void assertForwardUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class grails.test.GrailsUrlMappingsTestCase. The cyclomatic complexity for method [assertForwardUrlMapping] is [21]

JUnitPublicNonTestMethod2202

[SRC]void assertReverseUrlMapping(assertions, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertReverseUrlMapping is public but not a test method

JUnitPublicNonTestMethod2206

[SRC]void assertReverseUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertReverseUrlMapping is public but not a test method

UnusedImport318

[SRC]import grails.util.GrailsWebUtil

[MSG]The [grails.util.GrailsWebUtil] import is never referenced

UnusedImport320

[SRC]import org.codehaus.groovy.grails.commons.DefaultGrailsApplication

[MSG]The [org.codehaus.groovy.grails.commons.DefaultGrailsApplication] import is never referenced

UnusedImport321

[SRC]import org.codehaus.groovy.grails.commons.GrailsApplication

[MSG]The [org.codehaus.groovy.grails.commons.GrailsApplication] import is never referenced

UnusedImport324

[SRC]import org.codehaus.groovy.grails.plugins.web.mapping.Ur..GrailsPlugin

[MSG]The [org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin] import is never referenced

UnusedImport325

[SRC]import org.codehaus.groovy.grails.support.MockApplicationContext

[MSG]The [org.codehaus.groovy.grails.support.MockApplicationContext] import is never referenced

UnusedImport328

[SRC]import org.codehaus.groovy.grails.web.multipart.ContentL..partResolver

[MSG]The [org.codehaus.groovy.grails.web.multipart.ContentLengthAwareCommonsMultipartResolver] import is never referenced

UnusedImport330

[SRC]import org.springframework.web.context.WebApplicationContext

[MSG]The [org.springframework.web.context.WebApplicationContext] import is never referenced

UnusedImport332

[SRC]import org.springframework.web.servlet.DispatcherServlet

[MSG]The [org.springframework.web.servlet.DispatcherServlet] import is never referenced

UnusedImport334

[SRC]import org.springframework.web.context.ServletContextAware

[MSG]The [org.springframework.web.context.ServletContextAware] import is never referenced

UnusedImport335

[SRC]import javax.servlet.ServletContext

[MSG]The [javax.servlet.ServletContext] import is never referenced

DuplicateImport336

[SRC]import org.codehaus.groovy.grails.commons.GrailsClassUtils

UnnecessarySubstring3176

[SRC]if (actual[0] == "/") actual = actual.substring(1)

[MSG]Violation in class grails.test.GrailsUrlMappingsTestCase. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3177

[SRC]if (expected[0] == "/") expected = expected.substring(1)

[MSG]Violation in class grails.test.GrailsUrlMappingsTestCase. The String.substring(int) method can be replaced with the subscript operator

Package: grails-plugin-url-mappings.src.main.groovy.org.codehaus.groovy.grails.plugins.web.mapping

➥ UrlMappingsGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter2161

[SRC]private UrlMappingsHolder createUrlMappingsHolder(Grails..inManager) {

[MSG]Violation in class UrlMappingsGrailsPlugin. Method parameter [application] is never referenced in the method createUrlMappingsHolder of class org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin

UnusedPrivateMethodParameter2161

[SRC]private UrlMappingsHolder createUrlMappingsHolder(Grails..inManager) {

[MSG]Violation in class UrlMappingsGrailsPlugin. Method parameter [pluginManager] is never referenced in the method createUrlMappingsHolder of class org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin

UnnecessaryGetter347

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryPackageReference363

[SRC]urlMappingsTargetSource(org.springframework.aop.target.H..)) { bean ->

[MSG]The org.springframework.aop.target.HotSwappableTargetSource class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference363

[SRC]urlMappingsTargetSource(org.springframework.aop.target.H..)) { bean ->

[MSG]The org.springframework.aop.target.HotSwappableTargetSource class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference369

[SRC]proxyInterfaces = [org.codehaus.groovy.grails.web.mappin..pingsHolder]

[MSG]The org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference369

[SRC]proxyInterfaces = [org.codehaus.groovy.grails.web.mappin..pingsHolder]

[MSG]The org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder class was explicitly imported, so specifying the package name is not necessary

UnnecessaryCallForLastElement375

[SRC]def lastFilter = filters[filters.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filters.last() or filters[-1]

UnnecessaryCallForLastElement375

[SRC]def lastFilter = filters[filters.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filters.last() or filters[-1]

UnnecessaryCallForLastElement385

[SRC]def lastServlet = servlets[servlets.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to servlets.last() or servlets[-1]

UnnecessaryCallForLastElement385

[SRC]def lastServlet = servlets[servlets.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to servlets.last() or servlets[-1]

UnnecessaryCallForLastElement395

[SRC]def lastMapping = servletMappings[servletMappings.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to servletMappings.last() or servletMappings[-1]

UnnecessaryCallForLastElement395

[SRC]def lastMapping = servletMappings[servletMappings.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to servletMappings.last() or servletMappings[-1]

UnnecessaryCallForLastElement3124

[SRC]welcomeFileList = welcomeFileList[welcomeFileList.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to welcomeFileList.last() or welcomeFileList[-1]

UnnecessaryCallForLastElement3124

[SRC]welcomeFileList = welcomeFileList[welcomeFileList.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to welcomeFileList.last() or welcomeFileList[-1]

UnnecessaryCallForLastElement3132

[SRC]def lastFilterMapping = filterMappings[filterMappings.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filterMappings.last() or filterMappings[-1]

UnnecessaryCallForLastElement3132

[SRC]def lastFilterMapping = filterMappings[filterMappings.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filterMappings.last() or filterMappings[-1]

UnnecessaryGetter3166

[SRC]final urlMappingsHolder = factory.getObject()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin. getObject() can probably be rewritten as object

Package: grails-plugin-validation.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ ValidationGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter255

[SRC]private static addValidationMethods(application, validat..lass, ctx) {

[MSG]Violation in class ValidationGrailsPlugin. Method parameter [ctx] is never referenced in the method addValidationMethods of class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin

UnusedImport326

[SRC]import org.springframework.core.type.filter.AnnotationTypeFilter

[MSG]The [org.springframework.core.type.filter.AnnotationTypeFilter] import is never referenced

UnnecessaryGetter333

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter364

[SRC]def attributes = rch.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter371

[SRC]def attributes = rch.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter390

[SRC]errors = new BeanPropertyBindingResult(delegate, delegat..).getName())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getName() can probably be rewritten as name

UnnecessaryGetter3100

[SRC]delegate.setErrors(new BeanPropertyBindingResult(delegat...getName()))

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getName() can probably be rewritten as name

Package: grails-plugin-validation.src.test.groovy.org.codehaus.groovy.grails.plugins

➥ ValidationGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSamePackage33

[SRC]import org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin

UnnecessaryGetter312

[SRC]def registry = GroovySystem.getMetaClassRegistry()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPluginTests. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

Package: grails-spring.src.main.groovy.grails.spring

➥ DynamicElementReader.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod275

[SRC]protected void afterInvocation() {

[MSG]Violation in class DynamicElementReader. The method afterInvocation is both empty and not marked with @Override

UnnecessaryGetter353

[SRC]EntityResolver entityResolver = new DelegatingEntityReso..assLoader())

[MSG]Violation in class grails.spring.DynamicElementReader. getClassLoader() can probably be rewritten as classLoader

UnnecessaryDotClass353

[SRC]EntityResolver entityResolver = new DelegatingEntityReso..assLoader())

[MSG]DynamicElementReader.class can be rewritten as DynamicElementReader

UnnecessaryGetter3121

[SRC]Element element = documentLoader.loadDocument(is, entity..entElement()

[MSG]Violation in class grails.spring.DynamicElementReader. getDocumentElement() can probably be rewritten as documentElement

UnnecessaryGetter3126

[SRC]BeanDefinitionHolder holder = new BeanDefinitionHolder(b..n.getName())

[MSG]Violation in class grails.spring.DynamicElementReader. getBeanDefinition() can probably be rewritten as beanDefinition

UnnecessaryGetter3126

[SRC]BeanDefinitionHolder holder = new BeanDefinitionHolder(b..n.getName())

[MSG]Violation in class grails.spring.DynamicElementReader. getName() can probably be rewritten as name

UnnecessaryGetter3128

[SRC]beanConfiguration.setBeanDefinition(holder.getBeanDefinition())

[MSG]Violation in class grails.spring.DynamicElementReader. getBeanDefinition() can probably be rewritten as beanDefinition

Package: grails-test-suite-base.src.main.groovy.org.codehaus.groovy.grails.plugins.web

➥ AbstractGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper282

[SRC]protected final void tearDown() {

[MSG]Violation in class AbstractGrailsPluginTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter350

[SRC]ga = new DefaultGrailsApplication(gcl.getLoadedClasses(),gcl)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.AbstractGrailsPluginTests. getLoadedClasses() can probably be rewritten as loadedClasses

UnnecessaryGetter375

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.AbstractGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test-suite-base.src.main.groovy.org.codehaus.groovy.grails.web.servlet.mvc

➥ AbstractGrailsControllerTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2150

[SRC]def withConfig(String text, Closure callable) {

[MSG]Violation in class AbstractGrailsControllerTests. The method withConfig is public but not a test method

JUnitPublicNonTestMethod2162

[SRC]GrailsWebRequest buildMockRequest(ConfigObject config) t.. Exception {

[MSG]Violation in class AbstractGrailsControllerTests. The method buildMockRequest is public but not a test method

JUnitPublicNonTestMethod2174

[SRC]void runTest(Closure callable) {

[MSG]Violation in class AbstractGrailsControllerTests. The method runTest is public but not a test method

UnnecessaryGetter376

[SRC]ga = new DefaultGrailsApplication(gcl.getLoadedClasses(), gcl)

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getLoadedClasses() can probably be rewritten as loadedClasses

UnnecessaryGetter3112

[SRC]servletContext = ctx.getServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter3119

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3169

[SRC]appCtx.getServletContext().setAttribute(GrailsApplicatio..EXT, appCtx)

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter3170

[SRC]appCtx.getServletContext().setAttribute(WebApplicationCo..UTE, appCtx)

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getServletContext() can probably be rewritten as servletContext

Package: grails-test-suite-base.src.main.groovy.org.codehaus.groovy.grails.web.taglib

➥ AbstractGrailsTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod268

[SRC]def withConfig(String text, Closure callable) {

[MSG]Violation in class AbstractGrailsTagTests. The method withConfig is public but not a test method

JUnitPublicNonTestMethod280

[SRC]GrailsWebRequest buildMockRequest(ConfigObject config) t.. Exception {

[MSG]Violation in class AbstractGrailsTagTests. The method buildMockRequest is public but not a test method

JUnitPublicNonTestMethod289

[SRC]def profile(String name, Closure callable) {

[MSG]Violation in class AbstractGrailsTagTests. The method profile is public but not a test method

JUnitPublicNonTestMethod299

[SRC]def withTag(String tagName, Writer out, Closure callable) {

[MSG]Violation in class AbstractGrailsTagTests. The method withTag is public but not a test method

UnusedVariable2122

[SRC]GroovyPageOutputStack stack=GroovyPageOutputStack.createNew(out)

[MSG]The variable [stack] in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests is not used

JUnitSetUpCallsSuper2150

[SRC]protected void setUp() throws Exception {

[MSG]Violation in class AbstractGrailsTagTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper2240

[SRC]protected void tearDown() {

[MSG]Violation in class AbstractGrailsTagTests. The method tearDown() does not call super.tearDown()

JUnitPublicNonTestMethod2265

[SRC]void runTest(Closure callable) {

[MSG]Violation in class AbstractGrailsTagTests. The method runTest is public but not a test method

JUnitPublicNonTestMethod2269

[SRC]void printCompiledSource(template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method printCompiledSource is public but not a test method

JUnitPublicNonTestMethod2275

[SRC]def getCompiledSource(template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method getCompiledSource is public but not a test method

UnusedVariable2289

[SRC]String text = sw.toString()

[MSG]The variable [text] in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests is not used

JUnitPublicNonTestMethod2292

[SRC]def assertCompiledSourceContains(expected, template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method assertCompiledSourceContains is public but not a test method

JUnitPublicNonTestMethod2297

[SRC]void assertOutputContains(expected, template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method assertOutputContains is public but not a test method

JUnitPublicNonTestMethod2302

[SRC]void assertOutputNotContains(expected, template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method assertOutputNotContains is public but not a test method

JUnitPublicNonTestMethod2320

[SRC]void assertOutputEquals(expected, template, params = [:]..tring() }) {

[MSG]Violation in class AbstractGrailsTagTests. The method assertOutputEquals is public but not a test method

JUnitPublicNonTestMethod2356

[SRC]def applyTemplate(template, params = [:], target = null,..me = null) {

[MSG]Violation in class AbstractGrailsTagTests. The method applyTemplate is public but not a test method

JUnitPublicNonTestMethod2381

[SRC]String sitemeshPreprocess(String template) {

[MSG]Violation in class AbstractGrailsTagTests. The method sitemeshPreprocess is public but not a test method

JUnitPublicNonTestMethod2386

[SRC]String applyLayout(String layout, String template, Map params=[:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method applyLayout is public but not a test method

UnnecessaryGetter385

[SRC]initThemeSource(request.getCurrentRequest(), messageSource)

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter3204

[SRC]JstlUtils.exposeLocalizationContext webRequest.getRequest(),null

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. getRequest() can probably be rewritten as request

UnnecessaryGetter3215

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryDefInMethodDeclaration3235

[SRC]private def initThemeSource(request, StaticMessageSource..ageSource) {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3343

[SRC]protected def assertTemplateOutputEquals(expected, Groov..tring() }) {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. The def keyword is unneeded when a method is marked protected

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate

➥ AbstractGrailsHibernateTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2121

[SRC]void onApplicationCreated() {}

[MSG]Violation in class AbstractGrailsHibernateTests. The method onApplicationCreated is public but not a test method

JUnitPublicNonTestMethod2137

[SRC]GrailsWebRequest buildMockRequest(ConfigObject config = .. Exception {

[MSG]Violation in class AbstractGrailsHibernateTests. The method buildMockRequest is public but not a test method

EmptyCatchBlock2158

[SRC]catch(e) {

[MSG]The catch block is empty

EmptyCatchBlock2165

[SRC]catch(e) {

[MSG]The catch block is empty

UnnecessaryGetter372

[SRC]ga = new DefaultGrailsApplication(gcl.getLoadedClasses(), gcl)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getLoadedClasses() can probably be rewritten as loadedClasses

UnnecessaryGetter386

[SRC]ga.setMainContext(springConfig.getUnrefreshedApplicationContext())

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter387

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3162

[SRC]getClass().classLoader.loadClass("net.sf.ehcache.CacheManager")

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getInstance() can probably be rewritten as instance

UnnecessaryGetter3198

[SRC]GroovySystem.getMetaClassRegistry().removeMetaClass meta..tyMode.POJO)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

➥ AbstractInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable283

[SRC]def Abstract = ga.getDomainClass("AbstractInheritanceAbs..Base").clazz

[MSG]The variable [Abstract] in class org.codehaus.groovy.grails.orm.hibernate.AbstractInheritanceTests is not used

UnusedVariable2104

[SRC]def Comment = ga.getDomainClass("AbstractInheritanceComment").clazz

[MSG]The variable [Comment] in class org.codehaus.groovy.grails.orm.hibernate.AbstractInheritanceTests is not used

➥ AllDeleteOrphanMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert236

[SRC]void testDeleteOrphanMapping() {

[MSG]Violation in class AllDeleteOrphanMappingTests. Test method 'testDeleteOrphanMapping' makes no assertions

➥ AssertionFailureInEventTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert216

[SRC]void testNoAssertionErrorInEvent() {

[MSG]Violation in class AssertionFailureInEventTests. Test method 'testNoAssertionErrorInEvent' makes no assertions

➥ AutoImportPackedDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertEqualsInsteadOfAssertTrue327

[SRC]assertTrue models.size() == 1

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AutoImportPackedDomainTests. Replace assertTrue with a call to assertEquals()

UseAssertEqualsInsteadOfAssertTrue330

[SRC]assertTrue models.size() == 1

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AutoImportPackedDomainTests. Replace assertTrue with a call to assertEquals()

UseAssertEqualsInsteadOfAssertTrue333

[SRC]assertTrue models.size() == 1

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AutoImportPackedDomainTests. Replace assertTrue with a call to assertEquals()

➥ BidirectionalHasOneMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert227

[SRC]void testRefreshHasOneAssociation() {

[MSG]Violation in class BidirectionalHasOneMappingTests. Test method 'testRefreshHasOneAssociation' makes no assertions

➥ BidirectionalListMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper222

[SRC]protected void setUp() {

[MSG]Violation in class BidirectionalListMappingTests. The method setUp() does not call super.setUp()

UnusedVariable259

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable297

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable2147

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable2169

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable2188

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable2276

[SRC]SimpleValue indexColumnValue = indexColumn.getValue()

[MSG]The variable [indexColumnValue] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

JUnitUnnecessaryTearDown354

[SRC]protected void tearDown() {

[MSG]Violation in class BidirectionalListMappingTests. The tearDown() method contains no logic and can be removed

UnnecessaryOverridingMethod354

[SRC]protected void tearDown() {

[MSG]Violation in class BidirectionalListMappingTests. The method tearDown contains no logic and can be safely deleted

UnnecessaryGetter374

[SRC]assertNull elementsIndexBackref.getCascade()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascade() can probably be rewritten as cascade

UnnecessaryGetter375

[SRC]assertEquals CascadeStyle.NONE, elementsIndexBackref.getCascadeStyle()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascadeStyle() can probably be rewritten as cascadeStyle

UnnecessaryGetter376

[SRC]assertEquals "TestFaqSection.elements", elementsIndexBa..ectionRole()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCollectionRole() can probably be rewritten as collectionRole

UnnecessaryGetter377

[SRC]assertEquals 1, elementsIndexBackref.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter378

[SRC]assertEquals "TestFaqSection", elementsIndexBackref.getEntityName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getEntityName() can probably be rewritten as entityName

UnnecessaryGetter379

[SRC]assertEquals PropertyGeneration.NEVER, elementsIndexBack..Generation()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getGeneration() can probably be rewritten as generation

UnnecessaryGetter380

[SRC]assertEquals "_elementsIndexBackref", elementsIndexBackref.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter381

[SRC]assertNull elementsIndexBackref.getNodeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNodeName() can probably be rewritten as nodeName

UnnecessaryGetter382

[SRC]assertNull elementsIndexBackref.getPropertyAccessorName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPropertyAccessorName() can probably be rewritten as propertyAccessorName

UnnecessaryGetter383

[SRC]assertEquals IntegerType, elementsIndexBackref.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter384

[SRC]assertEquals SimpleValue, elementsIndexBackref.getValue().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter386

[SRC]SimpleValue value = elementsIndexBackref.getValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3112

[SRC]assertNull elementsBackref.getCascade()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascade() can probably be rewritten as cascade

UnnecessaryGetter3113

[SRC]assertEquals CascadeStyle.NONE, elementsBackref.getCascadeStyle()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascadeStyle() can probably be rewritten as cascadeStyle

UnnecessaryGetter3114

[SRC]assertEquals "TestFaqSection.elements", elementsBackref...ectionRole()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCollectionRole() can probably be rewritten as collectionRole

UnnecessaryGetter3115

[SRC]assertEquals 1, elementsBackref.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3116

[SRC]assertEquals "TestFaqSection", elementsBackref.getEntityName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getEntityName() can probably be rewritten as entityName

UnnecessaryGetter3117

[SRC]assertEquals PropertyGeneration.NEVER, elementsBackref.getGeneration()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getGeneration() can probably be rewritten as generation

UnnecessaryGetter3118

[SRC]assertEquals "_TestFaqSection_elementsBackref", elements..ef.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter3119

[SRC]assertNull elementsBackref.getNodeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNodeName() can probably be rewritten as nodeName

UnnecessaryGetter3120

[SRC]assertEquals "TestFaqElement", elementsBackref.getPersis..tClassName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getClassName() can probably be rewritten as className

UnnecessaryGetter3120

[SRC]assertEquals "TestFaqElement", elementsBackref.getPersis..tClassName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPersistentClass() can probably be rewritten as persistentClass

UnnecessaryGetter3121

[SRC]assertNull elementsBackref.getPropertyAccessorName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPropertyAccessorName() can probably be rewritten as propertyAccessorName

UnnecessaryGetter3122

[SRC]assertEquals LongType, elementsBackref.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3123

[SRC]assertEquals DependantValue, elementsBackref.getValue().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3125

[SRC]DependantValue value = elementsBackref.getValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3133

[SRC]assertEquals 1,value.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3134

[SRC]assertTrue value.getColumnInsertability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3135

[SRC]assertEquals 1,value.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3136

[SRC]assertTrue value.getColumnUpdateability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3138

[SRC]assertEquals 1, value.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3139

[SRC]assertEquals FetchMode.SELECT, value.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3140

[SRC]assertNull value.getForeignKeyName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getForeignKeyName() can probably be rewritten as foreignKeyName

UnnecessaryGetter3141

[SRC]assertEquals "assigned", value.getIdentifierGeneratorStrategy()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getIdentifierGeneratorStrategy() can probably be rewritten as identifierGeneratorStrategy

UnnecessaryGetter3142

[SRC]assertNull value.getNullValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNullValue() can probably be rewritten as nullValue

UnnecessaryGetter3143

[SRC]assertEquals LongType, value.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3161

[SRC]assertEquals "none", section.getCascade()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascade() can probably be rewritten as cascade

UnnecessaryGetter3162

[SRC]assertEquals CascadeStyle.NONE, section.getCascadeStyle()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascadeStyle() can probably be rewritten as cascadeStyle

UnnecessaryGetter3163

[SRC]assertEquals 1, section.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3164

[SRC]assertEquals PropertyGeneration.NEVER, section.getGeneration()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getGeneration() can probably be rewritten as generation

UnnecessaryGetter3165

[SRC]assertEquals "section", section.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter3172

[SRC]Column sectionColumn = section.getColumnIterator().next()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnIterator() can probably be rewritten as columnIterator

UnnecessaryGetter3174

[SRC]assertEquals "section_id", sectionColumn.getCanonicalName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCanonicalName() can probably be rewritten as canonicalName

UnnecessaryGetter3175

[SRC]assertNull sectionColumn.getCheckConstraint()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCheckConstraint() can probably be rewritten as checkConstraint

UnnecessaryGetter3176

[SRC]assertNull sectionColumn.getComment()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getComment() can probably be rewritten as comment

UnnecessaryGetter3177

[SRC]assertNull sectionColumn.getDefaultValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getDefaultValue() can probably be rewritten as defaultValue

UnnecessaryGetter3178

[SRC]assertEquals 255, sectionColumn.getLength()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getLength() can probably be rewritten as length

UnnecessaryGetter3179

[SRC]assertEquals "section_id", sectionColumn.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter3180

[SRC]assertEquals 19, sectionColumn.getPrecision()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPrecision() can probably be rewritten as precision

UnnecessaryGetter3181

[SRC]assertEquals "section_id", sectionColumn.getQuotedName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getQuotedName() can probably be rewritten as quotedName

UnnecessaryGetter3182

[SRC]assertEquals 2, sectionColumn.getScale()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getScale() can probably be rewritten as scale

UnnecessaryGetter3183

[SRC]assertEquals "section_id", sectionColumn.getText()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getText() can probably be rewritten as text

UnnecessaryGetter3184

[SRC]assertEquals 0, sectionColumn.getTypeIndex()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getTypeIndex() can probably be rewritten as typeIndex

UnnecessaryGetter3192

[SRC]ManyToOne manyToOne = section.getValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3193

[SRC]assertEquals 1,manyToOne.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3194

[SRC]assertTrue manyToOne.getColumnInsertability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3195

[SRC]assertEquals 1,manyToOne.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3196

[SRC]assertTrue manyToOne.getColumnUpdateability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3208

[SRC]assertEquals 1, manyToOne.getConstraintColumns().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getConstraintColumns() can probably be rewritten as constraintColumns

UnnecessaryGetter3209

[SRC]assertEquals FetchMode.DEFAULT, manyToOne.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3210

[SRC]assertNull manyToOne.getForeignKeyName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getForeignKeyName() can probably be rewritten as foreignKeyName

UnnecessaryGetter3211

[SRC]assertEquals "assigned", manyToOne.getIdentifierGeneratorStrategy()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getIdentifierGeneratorStrategy() can probably be rewritten as identifierGeneratorStrategy

UnnecessaryGetter3212

[SRC]assertNull manyToOne.getNullValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNullValue() can probably be rewritten as nullValue

UnnecessaryGetter3213

[SRC]assertEquals "TestFaqSection", manyToOne.getReferencedEntityName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getReferencedEntityName() can probably be rewritten as referencedEntityName

UnnecessaryGetter3214

[SRC]assertNull manyToOne.getReferencedPropertyName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getReferencedPropertyName() can probably be rewritten as referencedPropertyName

UnnecessaryGetter3215

[SRC]assertEquals ManyToOneType, manyToOne.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3216

[SRC]assertEquals "TestFaqSection", manyToOne.getTypeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getTypeName() can probably be rewritten as typeName

UnnecessaryGetter3246

[SRC]assertEquals 0,list.getBaseIndex()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getBaseIndex() can probably be rewritten as baseIndex

UnnecessaryGetter3248

[SRC]Table t = list.getCollectionTable()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCollectionTable() can probably be rewritten as collectionTable

UnnecessaryGetter3250

[SRC]assertEquals 0, list.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3251

[SRC]assertNull list.getCacheConcurrencyStrategy()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCacheConcurrencyStrategy() can probably be rewritten as cacheConcurrencyStrategy

UnnecessaryGetter3252

[SRC]assertEquals "TestFaqSection.elements", list.getCacheRegionName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCacheRegionName() can probably be rewritten as cacheRegionName

UnnecessaryGetter3253

[SRC]assertEquals 0,list.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3254

[SRC]assertEquals 0, list.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3255

[SRC]assertNull list.getElementNodeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getElementNodeName() can probably be rewritten as elementNodeName

UnnecessaryGetter3256

[SRC]SimpleValue index = list.getIndex()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getIndex() can probably be rewritten as index

UnnecessaryGetter3258

[SRC]assertEquals 1,index.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3259

[SRC]assertTrue index.getColumnInsertability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3260

[SRC]assertEquals 1,index.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3261

[SRC]assertTrue index.getColumnUpdateability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3263

[SRC]assertEquals 1, index.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3265

[SRC]Column indexColumn = index.getColumnIterator().next()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnIterator() can probably be rewritten as columnIterator

UnnecessaryGetter3266

[SRC]assertEquals "elements_idx", indexColumn.getCanonicalName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCanonicalName() can probably be rewritten as canonicalName

UnnecessaryGetter3267

[SRC]assertNull indexColumn.getCheckConstraint()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCheckConstraint() can probably be rewritten as checkConstraint

UnnecessaryGetter3268

[SRC]assertNull indexColumn.getComment()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getComment() can probably be rewritten as comment

UnnecessaryGetter3269

[SRC]assertNull indexColumn.getDefaultValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getDefaultValue() can probably be rewritten as defaultValue

UnnecessaryGetter3270

[SRC]assertEquals 255, indexColumn.getLength()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getLength() can probably be rewritten as length

UnnecessaryGetter3271

[SRC]assertEquals "elements_idx", indexColumn.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter3272

[SRC]assertEquals 19, indexColumn.getPrecision()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPrecision() can probably be rewritten as precision

UnnecessaryGetter3273

[SRC]assertEquals "elements_idx", indexColumn.getQuotedName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getQuotedName() can probably be rewritten as quotedName

UnnecessaryGetter3274

[SRC]assertEquals 2, indexColumn.getScale()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getScale() can probably be rewritten as scale

UnnecessaryGetter3275

[SRC]assertEquals "elements_idx", indexColumn.getText()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getText() can probably be rewritten as text

UnnecessaryGetter3276

[SRC]SimpleValue indexColumnValue = indexColumn.getValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3278

[SRC]assertEquals FetchMode.SELECT, index.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3279

[SRC]assertNull index.getForeignKeyName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getForeignKeyName() can probably be rewritten as foreignKeyName

UnnecessaryGetter3280

[SRC]assertEquals "assigned", index.getIdentifierGeneratorStrategy()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getIdentifierGeneratorStrategy() can probably be rewritten as identifierGeneratorStrategy

UnnecessaryGetter3281

[SRC]assertNull index.getNullValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNullValue() can probably be rewritten as nullValue

UnnecessaryGetter3282

[SRC]assertEquals IntegerType, index.getType()?.getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3283

[SRC]assertEquals "integer", index.getTypeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getTypeName() can probably be rewritten as typeName

UnnecessaryGetter3284

[SRC]assertNull index.getTypeParameters()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getTypeParameters() can probably be rewritten as typeParameters

UnnecessaryGetter3286

[SRC]KeyValue key = list.getKey()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getKey() can probably be rewritten as key

UnnecessaryGetter3288

[SRC]assertEquals 1,key.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3289

[SRC]assertTrue key.getColumnInsertability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3290

[SRC]assertEquals 1,key.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3291

[SRC]assertTrue key.getColumnUpdateability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3293

[SRC]assertEquals 1, key.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3294

[SRC]assertEquals FetchMode.SELECT, key.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3295

[SRC]assertNull key.getNullValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNullValue() can probably be rewritten as nullValue

UnnecessaryGetter3296

[SRC]assertEquals LongType, key.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3298

[SRC]OneToMany element = list.getElement()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getElement() can probably be rewritten as element

UnnecessaryGetter3300

[SRC]assertEquals 1, element.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3301

[SRC]assertEquals FetchMode.JOIN, element.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3302

[SRC]PersistentClass associatedClass = element.getAssociatedClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getAssociatedClass() can probably be rewritten as associatedClass

UnnecessaryGetter3303

[SRC]assertEquals "TestFaqElement", associatedClass.getClassName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getClassName() can probably be rewritten as className

UnnecessaryGetter3304

[SRC]assertEquals ManyToOneType, element.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

➥ BidirectionalListPersistTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]section = session.get(sectionClass.getClazz(),1L)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListPersistTests. getClazz() can probably be rewritten as clazz

➥ BidirectionalOneToManyAndCircularOneToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter367

[SRC]assertEquals uploadsProperty.getOtherSide(), recipientProperty

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyAndCircularOneToManyTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter368

[SRC]assertEquals recipientProperty.getOtherSide(), uploadsProperty

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyAndCircularOneToManyTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter380

[SRC]assertEquals uploadLogsProperty.getOtherSide(), senderProperty

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyAndCircularOneToManyTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter381

[SRC]assertEquals senderProperty.getOtherSide(), uploadLogsProperty

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyAndCircularOneToManyTests. getOtherSide() can probably be rewritten as otherSide

➥ BidirectionalOneToManyAndOneToOneTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert230

[SRC]void testSaveAndLoad() {

[MSG]Violation in class BidirectionalOneToManyAndOneToOneTests. Test method 'testSaveAndLoad' makes no assertions

➥ BidirectionalOneToManyWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable252

[SRC]def configItemClass = ga.getDomainClass("ConfigurationItem").clazz

[MSG]The variable [configItemClass] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyWithInheritanceTests is not used

➥ BidirectionalOnetoManyWithInheritanceRelationshipManagementTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter344

[SRC]def otherSide = collection.getOtherSide()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOnetoManyWithInheritanceRelationshipManagementTests. getOtherSide() can probably be rewritten as otherSide

➥ CascadingDeleteBehaviour2Tests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod255

[SRC]void onSetUp() {

[MSG]Violation in class CascadingDeleteBehaviour2Tests. The method onSetUp is public but not a test method

➥ CascadingDeleteBehaviour3Tests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod237

[SRC]void onSetUp() {

[MSG]Violation in class CascadingDeleteBehaviour3Tests. The method onSetUp is public but not a test method

UnusedImport33

[SRC]import org.codehaus.groovy.grails.commons.GrailsDomainClass

[MSG]The [org.codehaus.groovy.grails.commons.GrailsDomainClass] import is never referenced

➥ CascadingDeleteBehaviourTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod285

[SRC]void onSetUp() {

[MSG]Violation in class CascadingDeleteBehaviourTests. The method onSetUp is public but not a test method

➥ CascadingSaveAndUniqueConstraintTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert231

[SRC]void testCascadingSaveAndUniqueConstraint() {

[MSG]Violation in class CascadingSaveAndUniqueConstraintTests. Test method 'testCascadingSaveAndUniqueConstraint' makes no assertions

UnusedVariable234

[SRC]def face = faceClass.newInstance(nose:noseClass.newInstance()).save()

[MSG]The variable [face] in class org.codehaus.groovy.grails.orm.hibernate.CascadingSaveAndUniqueConstraintTests is not used

➥ CircularRelationshipTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod228

[SRC]void onSetUp() {

[MSG]Violation in class CircularRelationshipTests. The method onSetUp is public but not a test method

➥ CircularUnidirectionalOneToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod233

[SRC]void onSetUp() {

[MSG]Violation in class CircularUnidirectionalOneToManyTests. The method onSetUp is public but not a test method

➥ ClassHeirarchyInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod232

[SRC]void onSetUp() {

[MSG]Violation in class ClassHeirarchyInheritanceTests. The method onSetUp is public but not a test method

➥ CreateCriteriaTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod258

[SRC]void onSetUp() {

[MSG]Violation in class CreateCriteriaTests. The method onSetUp is public but not a test method

➥ CreateMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod227

[SRC]void onSetUp() {

[MSG]Violation in class CreateMethodTests. The method onSetUp is public but not a test method

➥ CriteriaBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3135

[SRC]def criteriaInstance = getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.CriteriaBuilderTests. getInstance() can probably be rewritten as instance

UnnecessaryGetter3149

[SRC]def criteriaInstance = getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.CriteriaBuilderTests. getInstance() can probably be rewritten as instance

➥ CriteriaListDistinctTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable232

[SRC]def Plant = ga.getDomainClass("Plant").clazz

[MSG]The variable [Plant] in class org.codehaus.groovy.grails.orm.hibernate.CriteriaListDistinctTests is not used

UnusedVariable266

[SRC]def Plant = ga.getDomainClass("Plant").clazz

[MSG]The variable [Plant] in class org.codehaus.groovy.grails.orm.hibernate.CriteriaListDistinctTests is not used

➥ CustomCascadeMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable238

[SRC]def twoClass = ga.getDomainClass("CustomCascadeMappingTwo").clazz

[MSG]The variable [twoClass] in class org.codehaus.groovy.grails.orm.hibernate.CustomCascadeMappingTests is not used

➥ CyclicManyToManyWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert247

[SRC]void testCyclicManyToManyWithInheritance() {

[MSG]Violation in class CyclicManyToManyWithInheritanceTests. Test method 'testCyclicManyToManyWithInheritance' makes no assertions

➥ DataBindingDynamicConstructorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod211

[SRC]void onSetUp() {

[MSG]Violation in class DataBindingDynamicConstructorTests. The method onSetUp is public but not a test method

➥ DataSourceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter327

[SRC]sessionFactoryConnection = sessionFactoryConnection.getW..Connection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getWrappedConnection() can probably be rewritten as wrappedConnection

UnnecessaryGetter330

[SRC]sessionFactoryConnection = sessionFactoryConnection.getT..Connection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getTargetConnection() can probably be rewritten as targetConnection

UnnecessaryGetter336

[SRC]dataSourceConnection = dataSourceConnection.getTargetConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getTargetConnection() can probably be rewritten as targetConnection

UnnecessaryGetter339

[SRC]dataSourceConnection = dataSourceConnection.getWrappedConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getWrappedConnection() can probably be rewritten as wrappedConnection

UnnecessaryGetter342

[SRC]dataSourceConnection = dataSourceConnection.getTargetConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getTargetConnection() can probably be rewritten as targetConnection

UseAssertSameInsteadOfAssertTrue348

[SRC]assertTrue sessionFactoryConnection.is(dataSourceConnection)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. assert method can be simplified using the assertSame method

UseAssertSameInsteadOfAssertTrue349

[SRC]assertFalse unproxiedConnection.is(dataSourceConnection)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. assert method can be simplified using the assertSame method

➥ DeepHierarchyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod280

[SRC]void onSetUp() {

[MSG]Violation in class DeepHierarchyTests. The method onSetUp is public but not a test method

➥ DefaultSortOrderForCollectionTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable230

[SRC]def Book = ga.getDomainClass("DefaultSortOrderForCollect..Book").clazz

[MSG]The variable [Book] in class org.codehaus.groovy.grails.orm.hibernate.DefaultSortOrderForCollectionTests is not used

➥ DeleteFromCollectionTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable236

[SRC]def bookClass = ga.getDomainClass("DeleteBook").clazz

[MSG]The variable [bookClass] in class org.codehaus.groovy.grails.orm.hibernate.DeleteFromCollectionTests is not used

➥ DeleteMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod225

[SRC]void onSetUp() {

[MSG]Violation in class DeleteMethodTests. The method onSetUp is public but not a test method

➥ DerivedPropertiesTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod246

[SRC]protected void afterPluginInitialization() {

[MSG]Violation in class DerivedPropertiesTests. The method afterPluginInitialization is both empty and not marked with @Override

EmptyMethod249

[SRC]protected void onTearDown() {

[MSG]Violation in class DerivedPropertiesTests. The method onTearDown is both empty and not marked with @Override

UnusedVariable254

[SRC]def mc = mdc.clazz

[MSG]The variable [mc] in class org.codehaus.groovy.grails.orm.hibernate.DerivedPropertiesTests is not used

➥ DirtyTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3126

[SRC]assertEquals 0, d.getDirtyPropertyNames().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DirtyTests. getDirtyPropertyNames() can probably be rewritten as dirtyPropertyNames

➥ DiscriminatorColumnMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable245

[SRC]def Child2 = ga.getDomainClass("Child2").clazz

[MSG]The variable [Child2] in class org.codehaus.groovy.grails.orm.hibernate.DiscriminatorColumnMappingTests is not used

➥ DiscriminatorFormulaMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2116

[SRC]def Root = ga.getDomainClass("Root").clazz

[MSG]The variable [Root] in class org.codehaus.groovy.grails.orm.hibernate.DiscriminatorFormulaMappingTests is not used

UseAssertNullInsteadOfAssertEquals3101

[SRC]assertEquals null, rs.getString("tree")

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DiscriminatorFormulaMappingTests. assertEquals can be simplified using assertNull

UnnecessaryObjectReferences3111

[SRC]rs.close()

[MSG]The code could be more concise by using a with() or identity() block

➥ DomainEventsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert240

[SRC]void testNoModifyVersion() {

[MSG]Violation in class DomainEventsTests. Test method 'testNoModifyVersion' makes no assertions

UnusedVariable2154

[SRC]def success = false

[MSG]The variable [success] in class org.codehaus.groovy.grails.orm.hibernate.DomainEventsTests is not used

➥ DomainEventsWithMethodsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2276

[SRC]void onSetUp() {

[MSG]Violation in class DomainEventsWithMethodsTests. The method onSetUp is public but not a test method

➥ DontFlushAfterDataAccessExceptionTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter348

[SRC]assertEquals FlushMode.AUTO, session.getFlushMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DontFlushAfterDataAccessExceptionTests. getFlushMode() can probably be rewritten as flushMode

UnnecessaryGetter358

[SRC]assertEquals FlushMode.MANUAL, session.getFlushMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DontFlushAfterDataAccessExceptionTests. getFlushMode() can probably be rewritten as flushMode

➥ EagerFindByQueryTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable233

[SRC]def tagClass = ga.getDomainClass("EagerFindByQueryTag").clazz

[MSG]The variable [tagClass] in class org.codehaus.groovy.grails.orm.hibernate.EagerFindByQueryTests is not used

UnusedVariable250

[SRC]def tagClass = ga.getDomainClass("EagerFindByQueryTag").clazz

[MSG]The variable [tagClass] in class org.codehaus.groovy.grails.orm.hibernate.EagerFindByQueryTests is not used

UnusedVariable267

[SRC]def tagClass = ga.getDomainClass("EagerFindByQueryTag").clazz

[MSG]The variable [tagClass] in class org.codehaus.groovy.grails.orm.hibernate.EagerFindByQueryTests is not used

UnusedVariable283

[SRC]def tagClass = ga.getDomainClass("EagerFindByQueryTag").clazz

[MSG]The variable [tagClass] in class org.codehaus.groovy.grails.orm.hibernate.EagerFindByQueryTests is not used

➥ EnumMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter381

[SRC]def con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.EnumMappingTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3104

[SRC]def con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.EnumMappingTests. getConnection() can probably be rewritten as connection

➥ ExecuteUpdateTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod220

[SRC]def init() {

[MSG]Violation in class ExecuteUpdateTests. The method init is public but not a test method

➥ ExistsTests.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSamePackage33

[SRC]import org.codehaus.groovy.grails.orm.hibernate.Abstract..bernateTests

➥ FindAllMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences350

[SRC]theClass.findAll("from FindAllTest where name = 'Angus'"..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences355

[SRC]theClass.findAll("from FindAllTest where name = 'Malcolm..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences360

[SRC]theClass.findAll("from FindAllTest where name = 'Malcolm..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3103

[SRC]theClass.findAll("from FindAllTest where name = :name", ..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3108

[SRC]theClass.findAll("from FindAllTest where name = :name", ..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3113

[SRC]theClass.findAll("from FindAllTest where name = :name", ..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

➥ FindByMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2186

[SRC]def jakeB = new Person(firstName: 'Jake', lastName: 'Bro..: 11).save()

[MSG]The variable [jakeB] in class org.codehaus.groovy.grails.orm.hibernate.FindByMethodTests is not used

➥ FindMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod25

[SRC]void onSetUp() {

[MSG]Violation in class FindMethodTests. The method onSetUp is public but not a test method

UnnecessaryObjectReferences374

[SRC]theClass.find("from FindMethodTestClass where one = 'Ang..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences379

[SRC]theClass.find("from FindMethodTestClass where one = 'Mal..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences384

[SRC]theClass.find("from FindMethodTestClass where one = 'Mal..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences389

[SRC]theClass.find("from FindMethodTestClass where one = :nam..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences394

[SRC]theClass.find("from FindMethodTestClass where one = :nam..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences399

[SRC]theClass.find("from FindMethodTestClass where one = :nam..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3104

[SRC]theClass.find("from FindMethodTestClass where one = :nam..che: false])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3109

[SRC]theClass.find("from FindMethodTestClass where one = :nam..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

➥ FindOrCreateWherePersistenceMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import grails.persistence.Entity

[MSG]The [grails.persistence.Entity] import is never referenced

➥ FindOrSaveWherePersistenceMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import grails.persistence.Entity

[MSG]The [grails.persistence.Entity] import is never referenced

➥ HibernateCriteriaBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod219

[SRC]List retrieveListOfNames() { ['bart'] }

[MSG]Violation in class HibernateCriteriaBuilderTests. The method retrieveListOfNames is public but not a test method

UnusedVariable21004

[SRC]List results = parse("{ " +

[MSG]The variable [results] in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests is not used

UnusedVariable21032

[SRC]List results = parse("{ " +

[MSG]The variable [results] in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests is not used

UnnecessaryGetter3437

[SRC]assertEquals clazzName , result.getClass().getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests. getName() can probably be rewritten as name

UnnecessaryGetter31689

[SRC]GroovyClassLoader cl = grailsApplication.getClassLoader()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests. getClassLoader() can probably be rewritten as classLoader

UnnecessaryGetter31706

[SRC]Class tc = grailsApplication.getArtefact(DomainClassArte..).getClazz()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests. getClazz() can probably be rewritten as clazz

➥ HibernateEventListenerTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod251

[SRC]void onPostInsert(PostInsertEvent event) {}

[MSG]Violation in class TestAuditListener. The method onPostInsert is both empty and not marked with @Override

UnusedMethodParameter251

[SRC]void onPostInsert(PostInsertEvent event) {}

[MSG]Violation in class TestAuditListener. Method parameter [event] is never referenced in the method onPostInsert of class org.codehaus.groovy.grails.orm.hibernate.TestAuditListener

EmptyMethod252

[SRC]void onPostDelete(PostDeleteEvent event) {}

[MSG]Violation in class TestAuditListener. The method onPostDelete is both empty and not marked with @Override

UnusedMethodParameter252

[SRC]void onPostDelete(PostDeleteEvent event) {}

[MSG]Violation in class TestAuditListener. Method parameter [event] is never referenced in the method onPostDelete of class org.codehaus.groovy.grails.orm.hibernate.TestAuditListener

EmptyMethod253

[SRC]void onSaveOrUpdate(SaveOrUpdateEvent event) {}

[MSG]Violation in class TestAuditListener. The method onSaveOrUpdate is both empty and not marked with @Override

UnusedMethodParameter253

[SRC]void onSaveOrUpdate(SaveOrUpdateEvent event) {}

[MSG]Violation in class TestAuditListener. Method parameter [event] is never referenced in the method onSaveOrUpdate of class org.codehaus.groovy.grails.orm.hibernate.TestAuditListener

➥ ListDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable29

[SRC]def authorClass = ga.getDomainClass("Author")

[MSG]The variable [authorClass] in class org.codehaus.groovy.grails.orm.hibernate.ListDomainTests is not used

JUnitPublicNonTestMethod223

[SRC]void onSetUp() {

[MSG]Violation in class ListDomainTests. The method onSetUp is public but not a test method

➥ ListMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable245

[SRC]def ids = [a1.id, a2.id, a2.id]

[MSG]The variable [ids] in class org.codehaus.groovy.grails.orm.hibernate.ListMappingTests is not used

JUnitPublicNonTestMethod254

[SRC]void onSetUp() {

[MSG]Violation in class ListMappingTests. The method onSetUp is public but not a test method

➥ LoadMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2107

[SRC]def o = clazz.newInstance()

[MSG]The variable [o] in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests is not used

UnusedImport37

[SRC]import org.springframework.orm.hibernate3.HibernateObjec..ureException

[MSG]The [org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException] import is never referenced

UnnecessaryGetter329

[SRC]assertEquals "id is accessible even if object doesn't ex..ance.getId()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests. getId() can probably be rewritten as id

UnnecessaryGetter351

[SRC]assertEquals "id is accessible even if object doesn't ex..ance.getId()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests. getId() can probably be rewritten as id

UseAssertSameInsteadOfAssertTrue377

[SRC]assertTrue getInstance.is(loadInstance)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests. assert method can be simplified using the assertSame method

UseAssertSameInsteadOfAssertTrue396

[SRC]assertFalse getInstance.is(loadInstance)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests. assert method can be simplified using the assertSame method

➥ ManyToManyCompositeIdTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod272

[SRC]void onSetUp() {

[MSG]Violation in class ManyToManyCompositeIdTests. The method onSetUp is public but not a test method

UnusedImport33

[SRC]import junit.framework.TestCase

[MSG]The [junit.framework.TestCase] import is never referenced

➥ ManyToManyLazinessTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod228

[SRC]void onSetUp() {

[MSG]Violation in class ManyToManyLazinessTests. The method onSetUp is public but not a test method

➥ ManyToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2114

[SRC]void onSetUp() {

[MSG]Violation in class ManyToManyTests. The method onSetUp is public but not a test method

➥ ManyToManyWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable232

[SRC]def ShapeAttribute = ga.getDomainClass("ShapeAttribute").clazz

[MSG]The variable [ShapeAttribute] in class org.codehaus.groovy.grails.orm.hibernate.ManyToManyWithInheritanceTests is not used

➥ MapDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod228

[SRC]void onSetUp() {

[MSG]Violation in class MapDomainTests. The method onSetUp is public but not a test method

➥ MapMappingJoinTableTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod230

[SRC]void onSetUp() {

[MSG]Violation in class MapMappingJoinTableTests. The method onSetUp is public but not a test method

➥ MapMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertFalseInsteadOfNegation226

[SRC]assertTrue !book.hasErrors()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MapMappingTests. assertTrue(!book.hasErrors()) can be simplified to assertFalse(book.hasErrors())

JUnitPublicNonTestMethod290

[SRC]void onSetUp() {

[MSG]Violation in class MapMappingTests. The method onSetUp is public but not a test method

➥ MappedByColumn2Tests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod226

[SRC]void onSetUp() {

[MSG]Violation in class MappedByColumn2Tests. The method onSetUp is public but not a test method

➥ MappedByColumnTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod242

[SRC]void onSetUp() {

[MSG]Violation in class MappedByColumnTests. The method onSetUp is public but not a test method

➥ MappingDefaultsTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertFalseInsteadOfNegation273

[SRC]assertTrue "should have inherited blank from shared cons..", !cp.blank

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDefaultsTests. assertTrue(!cp.blank) can be simplified to assertFalse(cp.blank)

UseAssertFalseInsteadOfNegation275

[SRC]assertTrue "should not have inherited matches from [anot..", !cp.email

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDefaultsTests. assertTrue(!cp.email) can be simplified to assertFalse(cp.email)

ChainedTest279

[SRC]testMappingDefaults()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDefaultsTests. The test method testMappingDefaults() is being invoked explicitly from within a unit test. Tests should be isolated and not dependent on one another

UseAssertEqualsInsteadOfAssertTrue374

[SRC]assertTrue "size should have been in the specified range..0 == cp.size

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDefaultsTests. Replace assertTrue with a call to assertEquals()

➥ MappingDefinitionInheritedBySubclassTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertTrueInsteadOfAssertEquals348

[SRC]assert rs.next() == true

[MSG]The expression '(rs.next() == true)' can be simplified to 'rs.next()'

➥ MappingDslTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testTableMapping() {

[MSG]Violation in class MappingDslTests. Test method 'testTableMapping' makes no assertions

UnusedVariable2113

[SRC]DataSource ds = applicationContext.dataSource

[MSG]The variable [ds] in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests is not used

UnusedVariable2203

[SRC]def personClass = ga.getDomainClass("MappedPerson").clazz

[MSG]The variable [personClass] in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests is not used

JUnitTestMethodWithoutAssert2283

[SRC]void testCompositeIdAssignedGenerator_GRAILS_6289() {

[MSG]Violation in class MappingDslTests. Test method 'testCompositeIdAssignedGenerator_GRAILS_6289' makes no assertions

UnnecessaryGetter317

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter335

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter382

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3121

[SRC]final cmd = session.getSessionFactory().getClassMetadata..Class.clazz)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getSessionFactory() can probably be rewritten as sessionFactory

UnnecessaryGetter3153

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3192

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3220

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3248

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3273

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3303

[SRC]connection = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

➥ MultipleDataSourceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2348

[SRC]def Library = ga.getDomainClass('MdsLibrary').clazz

[MSG]The variable [Library] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2349

[SRC]def Visit = ga.getDomainClass('MdsVisit').clazz

[MSG]The variable [Visit] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2379

[SRC]def Library = ga.getDomainClass('MdsLibrary').clazz

[MSG]The variable [Library] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2380

[SRC]def Visit = ga.getDomainClass('MdsVisit').clazz

[MSG]The variable [Visit] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2409

[SRC]def Library = ga.getDomainClass('MdsLibrary').clazz

[MSG]The variable [Library] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2410

[SRC]def Visit = ga.getDomainClass('MdsVisit').clazz

[MSG]The variable [Visit] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

➥ NamedCriteriaInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import grails.persistence.Entity

[MSG]The [grails.persistence.Entity] import is never referenced

➥ NamedCriteriaPublication.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure379

[SRC]thisWeeksPaperbacks() {

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.NamedCriteriaPublication. Parentheses in the 'thisWeeksPaperbacks' method call are unnecessary and can be removed.

➥ NamedCriteriaTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2504

[SRC]def titles = publications.title

[MSG]The variable [titles] in class org.codehaus.groovy.grails.orm.hibernate.NamedCriteriaTests is not used

➥ NamingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring377

[SRC]names << ddl.substring(0, ddl.indexOf(' '))

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.NamingTests. The String.substring(int, int) method can be replaced with the subscript operator

➥ OneToManySelfInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable235

[SRC]def Root = ga.getDomainClass("onetomanyselfinheritancete..Root").clazz

[MSG]The variable [Root] in class org.codehaus.groovy.grails.orm.hibernate.OneToManySelfInheritanceTests is not used

➥ OneToManyWithComposideIdentifierTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert247

[SRC]void testPersistAssociationWithCompositeId() {

[MSG]Violation in class OneToManyWithComposideIdentifierTests. Test method 'testPersistAssociationWithCompositeId' makes no assertions

JUnitTestMethodWithoutAssert257

[SRC]void testUpdateInverseSide() {

[MSG]Violation in class OneToManyWithComposideIdentifierTests. Test method 'testUpdateInverseSide' makes no assertions

➥ OneToManyWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.springframework.util.Log4jConfigurer

[MSG]The [org.springframework.util.Log4jConfigurer] import is never referenced

➥ OneToManyWithSelfAndInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable239

[SRC]def orgB = Organization.newInstance(name:'Org B', descri..org1).save()

[MSG]The variable [orgB] in class org.codehaus.groovy.grails.orm.hibernate.OneToManyWithSelfAndInheritanceTests is not used

UnusedVariable240

[SRC]def orgaa = Organization.newInstance(name:'Org aa', desc..orgA).save()

[MSG]The variable [orgaa] in class org.codehaus.groovy.grails.orm.hibernate.OneToManyWithSelfAndInheritanceTests is not used

UnusedVariable244

[SRC]def xorgB = ExtOrganization.newInstance(name:'ExtOrg B',..org1).save()

[MSG]The variable [xorgB] in class org.codehaus.groovy.grails.orm.hibernate.OneToManyWithSelfAndInheritanceTests is not used

UnusedVariable245

[SRC]def xorgaa = ExtOrganization.newInstance(name:'ExtOrg aa..orgA).save()

[MSG]The variable [xorgaa] in class org.codehaus.groovy.grails.orm.hibernate.OneToManyWithSelfAndInheritanceTests is not used

➥ PersistenceMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2750

[SRC]MetaClass domain = obj.getMetaClass()

[MSG]The variable [domain] in class org.codehaus.groovy.grails.orm.hibernate.PersistenceMethodTests is not used

UnnecessaryGetter3438

[SRC]returnValue = domainClass.getAll()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.PersistenceMethodTests. getAll() can probably be rewritten as all

UnnecessaryGetter3750

[SRC]MetaClass domain = obj.getMetaClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.PersistenceMethodTests. getMetaClass() can probably be rewritten as metaClass

➥ PessimisticLockingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert211

[SRC]void testLockMethod() {

[MSG]Violation in class PessimisticLockingTests. Test method 'testLockMethod' makes no assertions

JUnitPublicNonTestMethod243

[SRC]void onSetUp() {

[MSG]Violation in class PessimisticLockingTests. The method onSetUp is public but not a test method

➥ SavePersistentMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3159

[SRC]datastore.getEventTriggeringInterceptor().failOnError = true

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.SavePersistentMethodTests. getEventTriggeringInterceptor() can probably be rewritten as eventTriggeringInterceptor

UnnecessaryGetter3177

[SRC]def interceptor = datastore.getEventTriggeringInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.SavePersistentMethodTests. getEventTriggeringInterceptor() can probably be rewritten as eventTriggeringInterceptor

➥ SimpleBelongsToMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable210

[SRC]def bookClass = ga.getDomainClass("Book")

[MSG]The variable [bookClass] in class org.codehaus.groovy.grails.orm.hibernate.SimpleBelongsToMappingTests is not used

JUnitPublicNonTestMethod215

[SRC]void onSetUp() {

[MSG]Violation in class SimpleBelongsToMappingTests. The method onSetUp is public but not a test method

➥ TablePerHierarchyAssocationTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable236

[SRC]def sub1Class = ga.getDomainClass("TablePerHierarchSub1").clazz

[MSG]The variable [sub1Class] in class org.codehaus.groovy.grails.orm.hibernate.TablePerHierarchyAssocationTests is not used

➥ TablePerSubclassIdentityMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert237

[SRC]void testMappedIdentityForSubclass() {

[MSG]Violation in class TablePerSubclassIdentityMappingTests. Test method 'testMappedIdentityForSubclass' makes no assertions

UnnecessaryGetter342

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.TablePerSubclassIdentityMappingTests. getConnection() can probably be rewritten as connection

➥ TablePerSubclassWithCustomTableNameTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert237

[SRC]void testGeneratedTables() {

[MSG]Violation in class TablePerSubclassWithCustomTableNameTests. Test method 'testGeneratedTables' makes no assertions

UnnecessaryGetter342

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.TablePerSubclassWithCustomTableNameTests. getConnection() can probably be rewritten as connection

➥ TwoManyToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2100

[SRC]void onSetUp() {

[MSG]Violation in class TwoManyToManyTests. The method onSetUp is public but not a test method

➥ TwoUnidirectionalOneToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert27

[SRC]void testTwoUniOneToManys() {

[MSG]Violation in class TwoUnidirectionalOneToManyTests. Test method 'testTwoUniOneToManys' makes no assertions

JUnitPublicNonTestMethod223

[SRC]void onSetUp() {

[MSG]Violation in class TwoUnidirectionalOneToManyTests. The method onSetUp is public but not a test method

➥ URLMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod222

[SRC]void onSetUp() {

[MSG]Violation in class URLMappingTests. The method onSetUp is public but not a test method

UnnecessaryObjectReferences316

[SRC]b.discard()

[MSG]The code could be more concise by using a with() or identity() block

➥ UnidirectionalOneToManyHibernateMappedTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testAnnotatedOneToManyDomain() {

[MSG]Violation in class UnidirectionalOneToManyHibernateMappedTests. Test method 'testAnnotatedOneToManyDomain' makes no assertions

➥ UnidirectionalOneToManyWithJoinTableTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert226

[SRC]void testUnidirectionalOneToManyWithExplicityJoinTable() {

[MSG]Violation in class UnidirectionalOneToManyWithJoinTableTests. Test method 'testUnidirectionalOneToManyWithExplicityJoinTable' makes no assertions

➥ UserTypeMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3148

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.UserTypeMappingTests. getConnection() can probably be rewritten as connection

➥ ValidationFailureTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod25

[SRC]void onSetUp() {

[MSG]Violation in class ValidationFailureTests. The method onSetUp is public but not a test method

➥ VersionColumnTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert240

[SRC]void testVersionColumnMapping() {

[MSG]Violation in class VersionColumnTests. Test method 'testVersionColumnMapping' makes no assertions

UnusedImport33

[SRC]import java.sql.Connection

[MSG]The [java.sql.Connection] import is never referenced

➥ WithCriteriaMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod224

[SRC]void onSetUp() {

[MSG]Violation in class WithCriteriaMethodTests. The method onSetUp is public but not a test method

➥ WithTransactionMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod233

[SRC]void onSetUp() {

[MSG]Violation in class WithTransactionMethodTests. The method onSetUp is public but not a test method

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.binding

➥ AssociationDataBindingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2197

[SRC]def book = Book.newInstance(title: "Pattern Recognition"..Error: true)

[MSG]The variable [book] in class org.codehaus.groovy.grails.orm.hibernate.binding.AssociationDataBindingTests is not used

UnnecessaryObjectReferences3332

[SRC]request.addParameter("books[0].reviewers['bob'].name", "Bob Bloggs")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3333

[SRC]request.addParameter("books[0].reviewers['chuck'].name",..uck Bloggs")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3334

[SRC]request.addParameter("books[1].title", "The Stand")

[MSG]The code could be more concise by using a with() or identity() block

➥ NonDomainCollectionBindingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod211

[SRC]void onSetUp() {

[MSG]Violation in class NonDomainCollectionBindingTests. The method onSetUp is public but not a test method

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.cfg

➥ GrailsDomainBinderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3672

[SRC]ConstrainedProperty constrainedProperty = getConstrained..ngProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3677

[SRC]constrainedProperty = getConstrainedStringProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3682

[SRC]constrainedProperty = getConstrainedStringProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3686

[SRC]constrainedProperty = getConstrainedStringProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3692

[SRC]constrainedProperty = getConstrainedStringProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3702

[SRC]ConstrainedProperty constrainedProperty = getConstrained..alProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryGetter3709

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3710

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...l("123.45"))

[MSG]Can be rewritten as 123.45 or 123.45G

UnnecessaryGetter3715

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3717

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...("-123.45"))

[MSG]Can be rewritten as -123.45 or -123.45G

UnnecessaryGetter3721

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3722

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...("123.45")))

[MSG]Can be rewritten as 123.45 or 123.45G

UnnecessaryGetter3726

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3727

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...mal("123")))

[MSG]Can be rewritten as -123.45 or -123.45G

UnnecessaryGetter3731

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryGetter3737

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3738

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...l("123.45"))

[MSG]Can be rewritten as 123.45 or 123.45G

UnnecessaryGetter3744

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3745

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty..."123.4567"))

[MSG]Can be rewritten as 123.4567 or 123.4567G

UnnecessaryGetter3751

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3752

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty..."123.4567"))

[MSG]Can be rewritten as 123.4567 or 123.4567G

UnnecessaryGetter3754

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3755

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...7890.4567"))

[MSG]Can be rewritten as 12345678901234567890.4567 or 12345678901234567890.4567G

UnnecessaryGetter3757

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3758

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...-123.4567"))

[MSG]Can be rewritten as -123.4567 or -123.4567G

UnnecessaryGetter3760

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3761

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...7890.4567"))

[MSG]Can be rewritten as -12345678901234567890.4567 or -12345678901234567890.4567G

➥ GrailsHibernateUtilTests.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports34

[SRC]import static org.codehaus.groovy.grails.orm.hibernate.c..ernateUtil.*

[MSG]Static imports should appear before normal imports

JUnitUnnecessarySetUp38

[SRC]@Override protected void setUp() {

[MSG]Violation in class GrailsHibernateUtilTests. The setUp() method contains no logic and can be removed

UnnecessaryOverridingMethod38

[SRC]@Override protected void setUp() {

[MSG]Violation in class GrailsHibernateUtilTests. The method setUp contains no logic and can be safely deleted

JUnitUnnecessaryTearDown312

[SRC]@Override protected void tearDown() {

[MSG]Violation in class GrailsHibernateUtilTests. The tearDown() method contains no logic and can be removed

UnnecessaryOverridingMethod312

[SRC]@Override protected void tearDown() {

[MSG]Violation in class GrailsHibernateUtilTests. The method tearDown contains no logic and can be safely deleted

➥ MonetaryAmountUserType.groovy

Rule NamePriorityLine #Source Line / Message
EqualsOverloaded216

[SRC]boolean equals(Object x, Object y) { x == y }

[MSG]Violation in class MonetaryAmountUserType. The class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType overloads the equals method, it does not override it.

UnusedMethodParameter221

[SRC]Object nullSafeGet(ResultSet resultSet, String[] names, ..LException {

[MSG]Violation in class MonetaryAmountUserType. Method parameter [owner] is never referenced in the method nullSafeGet of class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType

UnusedMethodParameter244

[SRC]Object assemble(Serializable cached, Object owner) { cached }

[MSG]Violation in class MonetaryAmountUserType. Method parameter [owner] is never referenced in the method assemble of class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType

UnusedMethodParameter246

[SRC]Object replace(Object original, Object target, Object ow..{ original }

[MSG]Violation in class MonetaryAmountUserType. Method parameter [target] is never referenced in the method replace of class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType

UnusedMethodParameter246

[SRC]Object replace(Object original, Object target, Object ow..{ original }

[MSG]Violation in class MonetaryAmountUserType. Method parameter [owner] is never referenced in the method replace of class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType

➥ MyUserType.groovy

Rule NamePriorityLine #Source Line / Message
EqualsOverloaded222

[SRC]boolean equals(Object x, Object y) { x.name == y.name }

[MSG]Violation in class MyUserType. The class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType overloads the equals method, it does not override it.

UnusedMethodParameter227

[SRC]Object nullSafeGet(ResultSet resultSet, String[] names, ..LException {

[MSG]Violation in class MyUserType. Method parameter [owner] is never referenced in the method nullSafeGet of class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType

UnusedMethodParameter243

[SRC]Object assemble(Serializable cached, Object owner) { cached }

[MSG]Violation in class MyUserType. Method parameter [owner] is never referenced in the method assemble of class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType

UnusedMethodParameter245

[SRC]Object replace(Object original, Object target, Object ow..{ original }

[MSG]Violation in class MyUserType. Method parameter [target] is never referenced in the method replace of class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType

UnusedMethodParameter245

[SRC]Object replace(Object original, Object target, Object ow..{ original }

[MSG]Violation in class MyUserType. Method parameter [owner] is never referenced in the method replace of class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.metaclass

➥ BeforeValidateHelperTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter265

[SRC]def beforeValidate(List properties) {

[MSG]Violation in class ClassWithListArgBeforeValidate. Method parameter [properties] is never referenced in the method beforeValidate of class org.codehaus.groovy.grails.orm.hibernate.metaclass.ClassWithListArgBeforeValidate

UnusedMethodParameter276

[SRC]def beforeValidate(List properties) {

[MSG]Violation in class ClassWithOverloadedBeforeValidate. Method parameter [properties] is never referenced in the method beforeValidate of class org.codehaus.groovy.grails.orm.hibernate.metaclass.ClassWithOverloadedBeforeValidate

UnusedImport33

[SRC]import groovy.mock.interceptor.MockFor

[MSG]The [groovy.mock.interceptor.MockFor] import is never referenced

ImportFromSamePackage34

[SRC]import org.codehaus.groovy.grails.orm.hibernate.metaclas..idateHelper;

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.support

➥ FlushOnRedirectTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport36

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest] import is never referenced

➥ HibernatePersistenceContextInterceptorTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport36

[SRC]import org.springframework.orm.hibernate3.SessionHolder

[MSG]The [org.springframework.orm.hibernate3.SessionHolder] import is never referenced

UnnecessaryGetter328

[SRC]def interceptor = getInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptorTests. getInterceptor() can probably be rewritten as interceptor

UseAssertTrueInsteadOfAssertEquals329

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals331

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals333

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals335

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals337

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryGetter341

[SRC]def interceptor = getInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptorTests. getInterceptor() can probably be rewritten as interceptor

UseAssertTrueInsteadOfAssertEquals342

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals345

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals347

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals349

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals351

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals354

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryObjectReferences355

[SRC]interceptor.destroy()

[MSG]The code could be more concise by using a with() or identity() block

UseAssertTrueInsteadOfAssertEquals356

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryGetter360

[SRC]def interceptor = getInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptorTests. getInterceptor() can probably be rewritten as interceptor

UseAssertTrueInsteadOfAssertEquals370

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals372

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals374

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryGetter381

[SRC]def interceptor = getInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptorTests. getInterceptor() can probably be rewritten as interceptor

UseAssertTrueInsteadOfAssertEquals393

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals395

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals397

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.validation

➥ UniqueConstraintTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable215

[SRC]def userClass = ga.getDomainClass("User")

[MSG]The variable [userClass] in class org.codehaus.groovy.grails.orm.hibernate.validation.UniqueConstraintTests is not used

JUnitPublicNonTestMethod2265

[SRC]void onSetUp() {

[MSG]Violation in class UniqueConstraintTests. The method onSetUp is public but not a test method

UnnecessaryObjectReferences350

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences352

[SRC]user.save(true)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences363

[SRC]user.organization = "organization1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences364

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences368

[SRC]user.id = 123L

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences369

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences379

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences383

[SRC]user.code = "321"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences384

[SRC]user.login = "login1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences385

[SRC]user.grp = "group1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences386

[SRC]user.department = "department1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences387

[SRC]user.organization = "organization2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences388

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences392

[SRC]user.grp = "group2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences393

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences397

[SRC]user.grp = "group1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences398

[SRC]user.department = "department2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences399

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3103

[SRC]user.login = "login2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3104

[SRC]user.grp = "group2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3105

[SRC]user.department = "department1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3106

[SRC]user.organization = "organization1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3107

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3111

[SRC]user.organization = "organization2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3112

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3228

[SRC]user1.save(true)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3236

[SRC]user2.save(true)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3244

[SRC]user3.save(true)

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.support

➥ TransactionManagerPostProcessorTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySelfAssignment328

[SRC]dataSource = dataSource

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.plugins

➥ RelationshipManagementMethodsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable259

[SRC]def addressClass = ga.getDomainClass("Address")

[MSG]The variable [addressClass] in class org.codehaus.groovy.grails.plugins.RelationshipManagementMethodsTests is not used

JUnitPublicNonTestMethod2142

[SRC]void onSetUp() {

[MSG]Violation in class RelationshipManagementMethodsTests. The method onSetUp is public but not a test method

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.plugins.scaffolding

➥ ScaffoldingGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter375

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.scaffolding.ScaffoldingGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter387

[SRC]gcl.getLoadedClasses().find { it.name.endsWith("TagLib") })

[MSG]Violation in class org.codehaus.groovy.grails.plugins.scaffolding.ScaffoldingGrailsPluginTests. getLoadedClasses() can probably be rewritten as loadedClasses

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.plugins.services

➥ ScopedProxyAndServiceClassTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport35

[SRC]import org.springframework.web.context.support.WebApplic..ContextUtils

[MSG]The [org.springframework.web.context.support.WebApplicationContextUtils] import is never referenced

➥ ServicesGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod212

[SRC]void onSetUp() {

[MSG]Violation in class ServicesGrailsPluginTests. The method onSetUp is public but not a test method

UnnecessaryGetter3110

[SRC]springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.services.ServicesGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.reload

➥ ServiceReloadTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod246

[SRC]void onSetUp() {

[MSG]Violation in class ServiceReloadTests. The method onSetUp is public but not a test method

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.scaffolding

➥ DefaultGrailsTemplateGeneratorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper226

[SRC]protected void setUp() {

[MSG]Violation in class DefaultGrailsTemplateGeneratorTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper233

[SRC]protected void tearDown() {

[MSG]Violation in class DefaultGrailsTemplateGeneratorTests. The method tearDown() does not call super.tearDown()

UnusedImport314

[SRC]import org.codehaus.groovy.grails.plugins.PluginManagerHolder

[MSG]The [org.codehaus.groovy.grails.plugins.PluginManagerHolder] import is never referenced

UseAssertTrueInsteadOfAssertEquals368

[SRC]assert sw.toString().contains('g:datePicker name="regula..}"') == true

[MSG]The expression '(sw.toString().contains(g:datePicker name="regularDate" precision="day" value="${scaffoldingTestInstance?.regularDate}") == true)' can be simplified to 'sw.toString().contains(g:datePicker name="regularDate" precision="day" value="${scaffoldingTestInstance?.regularDate}")'

UseAssertTrueInsteadOfAssertEquals369

[SRC]assert sw.toString().contains('datePicker name="sqlDate"..e}') == true

[MSG]The expression '(sw.toString().contains(datePicker name="sqlDate" precision="day" value="${scaffoldingTestInstance?.sqlDate}) == true)' can be simplified to 'sw.toString().contains(datePicker name="sqlDate" precision="day" value="${scaffoldingTestInstance?.sqlDate})'

➥ TemplateGeneratingResponseHandlerTests.groovy

Rule NamePriorityLine #Source Line / Message
DuplicateImport37

[SRC]import org.springframework.web.context.request.*

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.scaffolding.view

➥ ScaffoldedGroovyPageViewTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper233

[SRC]void tearDown() {

[MSG]Violation in class ScaffoldedGroovyPageViewTests. The method tearDown() does not call super.tearDown()

➥ ScaffoldingViewResolverTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter260

[SRC]protected String generateViewSource(String viewName, Gra..mainClass) {

[MSG]Violation in class TestScaffoldingViewResolver. Method parameter [domainClass] is never referenced in the method generateViewSource of class org.codehaus.groovy.grails.scaffolding.view.TestScaffoldingViewResolver

UnnecessaryGetter338

[SRC]viewResolver.servletContext = webRequest.getServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.view.ScaffoldingViewResolverTests. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter348

[SRC]def view = viewResolver.loadView("/foo/list", Locale.getDefault())

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.view.ScaffoldingViewResolverTests. getDefault() can probably be rewritten as default

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.validation

➥ VetoingNullableBehaviourTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertEqualsInsteadOfAssertTrue3100

[SRC]assertTrue("Error not found for field ${field}, errors w..ld) == null)

[MSG]Violation in class org.codehaus.groovy.grails.validation.VetoingNullableBehaviourTests. Replace assertTrue with a call to assertEquals()

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.web.binding

➥ DataBindingWithAssociationTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable293

[SRC]def Book = ga.getDomainClass("databindingwithassociation..ook3").clazz

[MSG]The variable [Book] in class org.codehaus.groovy.grails.web.binding.DataBindingWithAssociationTests is not used

UnusedVariable2120

[SRC]def Book = ga.getDomainClass("databindingwithassociation..ook3").clazz

[MSG]The variable [Book] in class org.codehaus.groovy.grails.web.binding.DataBindingWithAssociationTests is not used

➥ DataBindingWithEmbeddedTests.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports36

[SRC]import static org.hamcrest.CoreMatchers.*

[MSG]Static imports should appear before normal imports

MisorderedStaticImports37

[SRC]import static org.junit.Assert.assertThat

[MSG]Static imports should appear before normal imports

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.web.converters

➥ ConvertsWithHibernateProxiesTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable255

[SRC]def converter = parent as JSON

[MSG]The variable [converter] in class org.codehaus.groovy.grails.web.converters.ConvertsWithHibernateProxiesTests is not used

UnusedVariable274

[SRC]def converter = parent as XML

[MSG]The variable [converter] in class org.codehaus.groovy.grails.web.converters.ConvertsWithHibernateProxiesTests is not used

Package: grails-test-suite-uber.src.test.groovy.grails.ant

➥ GrailsTaskTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod210

[SRC]void testWithClasspath() {

[MSG]Violation in class GrailsTaskTests. The method testWithClasspath is both empty and not marked with @Override

JUnitTestMethodWithoutAssert210

[SRC]void testWithClasspath() {

[MSG]Violation in class GrailsTaskTests. Test method 'testWithClasspath' makes no assertions

Package: grails-test-suite-uber.src.test.groovy.grails.spring

➥ BeanBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2706

[SRC]def dataSource = ctx.getBean("dataSource")

[MSG]The variable [dataSource] in class grails.spring.BeanBuilderTests is not used

JUnitTestMethodWithoutAssert2709

[SRC]void testHolyGrailWiring() {

[MSG]Violation in class BeanBuilderTests. Test method 'testHolyGrailWiring' makes no assertions

JUnitTestMethodWithoutAssert2760

[SRC]void testBeanBuilderWithScript() {

[MSG]Violation in class BeanBuilderTests. Test method 'testBeanBuilderWithScript' makes no assertions

EmptyMethod2867

[SRC]Object remove(String name) {

[MSG]Violation in class TestScope. The method remove is both empty and not marked with @Override

UnusedMethodParameter2867

[SRC]Object remove(String name) {

[MSG]Violation in class TestScope. Method parameter [name] is never referenced in the method remove of class grails.spring.TestScope

EmptyMethod2871

[SRC]void registerDestructionCallback(String name, Runnable callback) {}

[MSG]Violation in class TestScope. The method registerDestructionCallback is both empty and not marked with @Override

UnusedMethodParameter2871

[SRC]void registerDestructionCallback(String name, Runnable callback) {}

[MSG]Violation in class TestScope. Method parameter [name] is never referenced in the method registerDestructionCallback of class grails.spring.TestScope

UnusedMethodParameter2871

[SRC]void registerDestructionCallback(String name, Runnable callback) {}

[MSG]Violation in class TestScope. Method parameter [callback] is never referenced in the method registerDestructionCallback of class grails.spring.TestScope

UnusedMethodParameter2875

[SRC]Object get(String name, ObjectFactory<?> objectFactory) {

[MSG]Violation in class TestScope. Method parameter [name] is never referenced in the method get of class grails.spring.TestScope

UnusedMethodParameter2880

[SRC]Object resolveContextualObject(String s) { null }

[MSG]Violation in class TestScope. Method parameter [s] is never referenced in the method resolveContextualObject of class grails.spring.TestScope

UnusedImport318

[SRC]import org.codehaus.groovy.grails.plugins.GrailsPluginManager;

[MSG]The [org.codehaus.groovy.grails.plugins.GrailsPluginManager] import is never referenced

UnnecessaryGetter3149

[SRC]GenericApplicationContext appCtx = bb.getSpringConfig()...ionContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter3149

[SRC]GenericApplicationContext appCtx = bb.getSpringConfig()...ionContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3150

[SRC]appCtx.getBeanFactory().registerScope("test", scope)

[MSG]Violation in class grails.spring.BeanBuilderTests. getBeanFactory() can probably be rewritten as beanFactory

UnnecessaryGetter3176

[SRC]appCtx = bb.getSpringConfig().getUnrefreshedApplicationContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter3176

[SRC]appCtx = bb.getSpringConfig().getUnrefreshedApplicationContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3177

[SRC]appCtx.getBeanFactory().registerScope("test", scope)

[MSG]Violation in class grails.spring.BeanBuilderTests. getBeanFactory() can probably be rewritten as beanFactory

UnnecessaryGetter3237

[SRC]GenericApplicationContext appCtx = bb.getSpringConfig()...ionContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter3237

[SRC]GenericApplicationContext appCtx = bb.getSpringConfig()...ionContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3239

[SRC]appCtx.getBeanFactory().registerScope("test", scope)

[MSG]Violation in class grails.spring.BeanBuilderTests. getBeanFactory() can probably be rewritten as beanFactory

UnnecessarySelfAssignment3305

[SRC]quest = quest

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryPackageReference3312

[SRC]shouldFail(org.springframework.beans.factory.BeanIsAbstr..Exception) {

[MSG]The org.springframework.beans.factory.BeanIsAbstractException class was explicitly imported, so specifying the package name is not necessary

UnnecessarySelfAssignment3327

[SRC]quest = quest

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UseAssertTrueInsteadOfAssertEquals3376

[SRC]assertEquals true, bean1.props?.overweight

[MSG]assertEquals can be simplified using assertTrue or assertFalse

ConstantAssertExpression3590

[SRC]assert "marge", marge.person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [marge]

ConstantAssertExpression3608

[SRC]assert "marge", marge.person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [marge]

ConstantAssertExpression3632

[SRC]assert "homer", homer.person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [homer]

ConstantAssertExpression3633

[SRC]assert 45, homer.age

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [45]

ConstantAssertExpression3635

[SRC]assert "marge", ctx.getBean("marge").person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [marge]

ConstantAssertExpression3637

[SRC]assert "mcBain", ctx.getBean("mcBain").person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [mcBain]

UnnecessaryGetter3877

[SRC]objectFactory.getObject()

[MSG]Violation in class grails.spring.TestScope. getObject() can probably be rewritten as object

Package: grails-test-suite-uber.src.test.groovy.grails.test

➥ ControllerUnitTestCaseTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert210

[SRC]void testControllerClass() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testControllerClass' makes no assertions

JUnitTestMethodWithoutAssert217

[SRC]void testExplicitControllerClass() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testExplicitControllerClass' makes no assertions

JUnitTestMethodWithoutAssert225

[SRC]void testMockCommandObject() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testMockCommandObject' makes no assertions

JUnitTestMethodWithoutAssert232

[SRC]void testGetSetModelAndView() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testGetSetModelAndView' makes no assertions

JUnitTestMethodWithoutAssert239

[SRC]void testResetWithResponseNotCommitted() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testResetWithResponseNotCommitted' makes no assertions

JUnitTestMethodWithoutAssert246

[SRC]void testResetWithResponseCommitted() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testResetWithResponseCommitted' makes no assertions

JUnitTestMethodWithoutAssert256

[SRC]void testModelAndView() {

[MSG]Violation in class UnitTestControllerTestCase. Test method 'testModelAndView' makes no assertions

JUnitTestMethodWithoutAssert289

[SRC]void testResetWithResponseNotCommitted() {

[MSG]Violation in class UnitTestControllerTestCase. Test method 'testResetWithResponseNotCommitted' makes no assertions

➥ GrailsMockTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2386

[SRC]String multiMethod(String str) { "static" }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [str] is never referenced in the method multiMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2388

[SRC]String multiMethod(String str, Map map) { "static" }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [str] is never referenced in the method multiMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2388

[SRC]String multiMethod(String str, Map map) { "static" }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [map] is never referenced in the method multiMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2390

[SRC]String someMethod(String str1, Object[] args, String str..{ 'static' }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [str1] is never referenced in the method someMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2390

[SRC]String someMethod(String str1, Object[] args, String str..{ 'static' }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [args] is never referenced in the method someMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2390

[SRC]String someMethod(String str1, Object[] args, String str..{ 'static' }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [str2] is never referenced in the method someMethod of class grails.test.GrailsMockCollaborator

UnnecessaryParenthesesForMethodCallWithClosure397

[SRC]mockControl.demand.update() { -> "Success!"}

[MSG]Violation in class grails.test.GrailsMockTests. Parentheses in the 'update' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3151

[SRC]mockControl.demand.static.findByNothing() { -> "Success!"}

[MSG]Violation in class grails.test.GrailsMockTests. Parentheses in the 'findByNothing' method call are unnecessary and can be removed.

UnnecessaryGetter3407

[SRC]setMetaClass(GroovySystem.getMetaClassRegistry().getMeta..erty.class);

[MSG]Violation in class grails.test.GrailsMockWithMetaClassGetProperty. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

UnnecessaryDotClass3407

[SRC]setMetaClass(GroovySystem.getMetaClassRegistry().getMeta..erty.class);

[MSG]GrailsMockWithMetaClassGetProperty.class can be rewritten as GrailsMockWithMetaClassGetProperty

UnnecessaryDotClass3407

[SRC]setMetaClass(GroovySystem.getMetaClassRegistry().getMeta..erty.class);

[MSG]GrailsMockWithMetaClassGetProperty.class can be rewritten as GrailsMockWithMetaClassGetProperty

UnnecessaryGetter3417

[SRC]GroovySystem.getMetaClassRegistry().setMetaClass(nodeCla..wMetaClass);

[MSG]Violation in class grails.test.GrailsMockWithMetaClassGetProperty. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

➥ GrailsUnitTestCaseTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper232

[SRC]protected void setUp() {

[MSG]Violation in class GrailsUnitTestCaseTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper237

[SRC]protected void tearDown() {

[MSG]Violation in class GrailsUnitTestCaseTests. The method tearDown() does not call super.tearDown()

JUnitTestMethodWithoutAssert242

[SRC]void testMockConfig() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockConfig' makes no assertions

JUnitTestMethodWithoutAssert265

[SRC]void testMockConfigReturnsConfig() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockConfigReturnsConfig' makes no assertions

JUnitTestMethodWithoutAssert272

[SRC]void testMockLogging() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockLogging' makes no assertions

JUnitTestMethodWithoutAssert282

[SRC]void testMockLoggingWithDebugEnabled() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockLoggingWithDebugEnabled' makes no assertions

JUnitTestMethodWithoutAssert292

[SRC]void testMockDomainErrors() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockDomainErrors' makes no assertions

JUnitTestMethodWithoutAssert2106

[SRC]void testMockForConstraintsTests() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockForConstraintsTests' makes no assertions

JUnitTestMethodWithoutAssert2118

[SRC]void testMockFor() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockFor' makes no assertions

JUnitTestMethodWithoutAssert2141

[SRC]void testCascadingValidation() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testCascadingValidation' makes no assertions

JUnitTestMethodWithoutAssert2148

[SRC]void testMockDynamicMethodsWithInstanceList() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockDynamicMethodsWithInstanceList' makes no assertions

JUnitTestMethodWithoutAssert2162

[SRC]void testLoadCodec() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testLoadCodec' makes no assertions

JUnitTestMethodWithoutAssert2169

[SRC]void testConverters() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testConverters' makes no assertions

UnusedMethodParameter2412

[SRC]def foo(s) { 1 }

[MSG]Violation in class ClassToMock. Method parameter [s] is never referenced in the method foo of class grails.test.ClassToMock

UnnecessaryObjectReferences3126

[SRC]testCase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3128

[SRC]testCase.setUp()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3129

[SRC]testCase.testMockInterface1()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3130

[SRC]testCase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3132

[SRC]testCase.setUp()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3133

[SRC]testCase.testMockInterface2()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3134

[SRC]testCase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3177

[SRC]testCase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryParenthesesForMethodCallWithClosure3223

[SRC]mocker.demand.foo() {s -> 1 }

[MSG]Violation in class grails.test.TestUnitTestCase. Parentheses in the 'foo' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3231

[SRC]mocker.demand.foo() {s -> 1 }

[MSG]Violation in class grails.test.TestUnitTestCase. Parentheses in the 'foo' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3239

[SRC]mocker.demand.foo() {s -> 1 }

[MSG]Violation in class grails.test.TestUnitTestCase. Parentheses in the 'foo' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3247

[SRC]mocker.demand.foo() {s -> 1 }

[MSG]Violation in class grails.test.TestUnitTestCase. Parentheses in the 'foo' method call are unnecessary and can be removed.

UnnecessaryObjectReferences3365

[SRC]log.warn "Test warning with exception", new Exception("s..ent wrong!")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3366

[SRC]log.info "Test info message"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3367

[SRC]log.info "Test info message with exception", new Excepti..ent wrong!")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3368

[SRC]log.debug "Test debug"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3369

[SRC]log.debug "Test debug with exception", new Exception("so..ent wrong!")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3370

[SRC]log.trace "Test trace"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3371

[SRC]log.trace "Test trace with exception", new Exception("so..ent wrong!")

[MSG]The code could be more concise by using a with() or identity() block

➥ MockDomainWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper214

[SRC]protected void tearDown() {

[MSG]Violation in class MockDomainWithInheritanceTests. The method tearDown() does not call super.tearDown()

JUnitTestMethodWithoutAssert218

[SRC]void testMockDomainWithInheritance() {

[MSG]Violation in class MockDomainWithInheritanceTests. Test method 'testMockDomainWithInheritance' makes no assertions

JUnitTearDownCallsSuper234

[SRC]protected void tearDown() {

[MSG]Violation in class PersonTests. The method tearDown() does not call super.tearDown()

➥ MockForTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert211

[SRC]void testUnregisteredMockedStaticMethods() {

[MSG]Violation in class MockForTests. Test method 'testUnregisteredMockedStaticMethods' makes no assertions

UnnecessaryObjectReferences319

[SRC]testcase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

➥ MockUtilsAndHasManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper217

[SRC]protected void setUp() {

[MSG]Violation in class MockUtilsAndHasManyTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper222

[SRC]protected void tearDown() {

[MSG]Violation in class MockUtilsAndHasManyTests. The method tearDown() does not call super.tearDown()

JUnitTestMethodWithoutAssert226

[SRC]void testMockDomainWithHasMany() {

[MSG]Violation in class MockUtilsAndHasManyTests. Test method 'testMockDomainWithHasMany' makes no assertions

JUnitTearDownCallsSuper236

[SRC]protected void tearDown() {

[MSG]Violation in class MagazineTests. The method tearDown() does not call super.tearDown()

➥ MockUtilsDeleteDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper230

[SRC]void setUp() {

[MSG]Violation in class MockUtilsDeleteDomainTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper235

[SRC]void tearDown() {

[MSG]Violation in class MockUtilsDeleteDomainTests. The method tearDown() does not call super.tearDown()

➥ MockUtilsSaveDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper234

[SRC]protected void setUp() {

[MSG]Violation in class MockUtilsSaveDomainTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper241

[SRC]protected void tearDown() {

[MSG]Violation in class MockUtilsSaveDomainTests. The method tearDown() does not call super.tearDown()

UnusedVariable278

[SRC]def domain1 = new TestDomainWithUUID(name: "Alice Doe", ..: 35).save()

[MSG]The variable [domain1] in class grails.test.MockUtilsSaveDomainTests is not used

➥ MockUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertFalseInsteadOfNegation21135

[SRC]assertTrue !model

[MSG]Violation in class grails.test.MockUtilsTests. assertTrue(!model) can be simplified to assertFalse(model)

EqualsAndHashCode21589

[SRC]class TestDomain {

[MSG]The class grails.test.TestDomain defines equals(Object) but not hashCode()

EqualsAndHashCode21685

[SRC]class TestDomainWithUUID {

[MSG]The class grails.test.TestDomainWithUUID defines equals(Object) but not hashCode()

UnusedMethodParameter21882

[SRC]def beforeValidate(List properties) {

[MSG]Violation in class ClassWithListArgBeforeValidate. Method parameter [properties] is never referenced in the method beforeValidate of class grails.test.ClassWithListArgBeforeValidate

UnusedMethodParameter21896

[SRC]def beforeValidate(List properties) {

[MSG]Violation in class ClassWithOverloadedBeforeValidate. Method parameter [properties] is never referenced in the method beforeValidate of class grails.test.ClassWithOverloadedBeforeValidate

UnnecessaryObjectReferences31202

[SRC]cmd.validate()

[MSG]The code could be more concise by using a with() or identity() block

➥ TagLibUnitTestCaseTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert28

[SRC]void testTagThatPopulatesPageScope() {

[MSG]Violation in class TagLibUnitTestCaseTests. Test method 'testTagThatPopulatesPageScope' makes no assertions

JUnitTestMethodWithoutAssert216

[SRC]void testTagThatAccessesPageScope() {

[MSG]Violation in class TagLibUnitTestCaseTests. Test method 'testTagThatAccessesPageScope' makes no assertions

Package: grails-test-suite-uber.src.test.groovy.grails.test.mixin

➥ AstEnhancedControllerUnitTestMixinTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter322

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter334

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter342

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter350

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter360

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter370

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter381

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3104

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3112

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3121

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3131

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3149

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3159

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3168

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3178

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3188

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3196

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

➥ AutowireServiceViaDefineBeansTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert216

[SRC]void testThatBeansAreWired() {

[MSG]Violation in class AutowireServiceViaDefineBeansTests. Test method 'testThatBeansAreWired' makes no assertions

UnusedImport33

[SRC]import org.junit.Before

[MSG]The [org.junit.Before] import is never referenced

UnusedImport37

[SRC]import org.junit.BeforeClass

[MSG]The [org.junit.BeforeClass] import is never referenced

➥ BidirectionalOneToManyUnitTestTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testRelationship() {

[MSG]Violation in class BidirectionalOneToManyUnitTestTests. Test method 'testRelationship' makes no assertions

➥ ControllerAndFilterMixinInteractionTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod225

[SRC]def index() { }

[MSG]Violation in class SecureUserController. The method index is both empty and not marked with @Override

➥ ControllerAndMockForTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert29

[SRC]void testIndexWithoutUsingMockFor() {

[MSG]Violation in class ControllerAndMockForTests. Test method 'testIndexWithoutUsingMockFor' makes no assertions

JUnitTestMethodWithoutAssert229

[SRC]void testIndexWithoutUsingMockForAgain() {

[MSG]Violation in class ControllerAndMockForTests. Test method 'testIndexWithoutUsingMockForAgain' makes no assertions

➥ ControllerUnitTestMixinTests.groovy

Rule NamePriorityLine #Source Line / Message
BrokenOddnessCheck2564

[SRC]if(val.size() % 2 == 1) {

[MSG]The code uses '(val.size() % 2 == 1)' to check for oddness, which does not work for negative numbers. Use (val.size() & 1 == 1) or (val.size() % 2 != 0) instead

BrokenOddnessCheck2564

[SRC]if(val.size() % 2 == 1) {

[MSG]The code uses '(val.size() % 2 == 1)' to check for oddness, which does not work for negative numbers. Use (val.size() & 1 == 1) or (val.size() % 2 != 0) instead

UnnecessaryGetter326

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter347

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter355

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter363

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter373

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter383

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter394

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3117

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3125

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3134

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3143

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3154

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3172

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3182

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3191

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3201

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3211

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3219

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3229

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3251

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryOverridingMethod3552

[SRC]def method1() {

[MSG]Violation in class SubController. The method method1 contains no logic and can be safely deleted

➥ ControllerWithMockCollabTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testFirstCall() {

[MSG]Violation in class ControllerWithMockCollabTests. Test method 'testFirstCall' makes no assertions

JUnitTestMethodWithoutAssert217

[SRC]void testSecondCall() {

[MSG]Violation in class ControllerWithMockCollabTests. Test method 'testSecondCall' makes no assertions

UseAssertTrueInsteadOfAssertEquals335

[SRC]assert called == true

[MSG]The expression '(called == true)' can be simplified to 'called'

➥ DomainClassAnnotatedSetupMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod216

[SRC]void testSaveInSetup() {

[MSG]Violation in class DomainClassAnnotatedSetupMethodTests. The method testSaveInSetup is both empty and not marked with @Override

JUnitTestMethodWithoutAssert216

[SRC]void testSaveInSetup() {

[MSG]Violation in class DomainClassAnnotatedSetupMethodTests. Test method 'testSaveInSetup' makes no assertions

➥ DomainClassControllerUnitTestMixinTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport36

[SRC]import grails.validation.ValidationErrors

[MSG]The [grails.validation.ValidationErrors] import is never referenced

UseAssertTrueInsteadOfAssertEquals357

[SRC]assert book.validate() == false

[MSG]The expression '(book.validate() == false)' can be simplified to '!book.validate()'

➥ DomainClassSetupMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper212

[SRC]void setUp() {

[MSG]Violation in class DomainClassSetupMethodTests. The method setUp() does not call super.setUp()

➥ MockForTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter246

[SRC]void request(HttpServletRequest request) {

[MSG]Violation in class SolrServer. Method parameter [request] is never referenced in the method request of class grails.test.mixin.SolrServer

➥ ServiceAndMockForTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert235

[SRC]void testIndexWithoutUsingMockForAgain() {

[MSG]Violation in class ServiceAndMockForTests. Test method 'testIndexWithoutUsingMockForAgain' makes no assertions

➥ UrlMappingsTestMixinTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock273

[SRC]catch (e) {}

[MSG]The catch block is empty

EmptyMethod2151

[SRC]@Action def action1(){}

[MSG]Violation in class GrailsUrlMappingsTestCaseFakeController. The method action1 is both empty and not marked with @Override

EmptyMethod2152

[SRC]@Action def action2(){}

[MSG]Violation in class GrailsUrlMappingsTestCaseFakeController. The method action2 is both empty and not marked with @Override

EmptyMethod2153

[SRC]@Action def action3(){}

[MSG]Violation in class GrailsUrlMappingsTestCaseFakeController. The method action3 is both empty and not marked with @Override

EmptyMethod2157

[SRC]@Action def publicProfile() {}

[MSG]Violation in class UserController. The method publicProfile is both empty and not marked with @Override

Package: grails-test-suite-uber.src.test.groovy.grails.util

➥ BuildScopeTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper29

[SRC]protected void tearDown() {

[MSG]Violation in class BuildScopeTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter314

[SRC]assertEquals BuildScope.ALL, BuildScope.getCurrent()

[MSG]Violation in class grails.util.BuildScopeTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter318

[SRC]assertEquals BuildScope.WAR, BuildScope.getCurrent()

[MSG]Violation in class grails.util.BuildScopeTests. getCurrent() can probably be rewritten as current

➥ BuildSettingsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper215

[SRC]protected void setUp() {

[MSG]Violation in class BuildSettingsTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper229

[SRC]protected void tearDown() {

[MSG]Violation in class BuildSettingsTests. The method tearDown() does not call super.tearDown()

EmptyMethod2332

[SRC]void receiveGrailsBuildEvent(String name, Object[] args) {}

[MSG]Violation in class BuildSettingsTestsGrailsBuildListener. The method receiveGrailsBuildEvent is both empty and not marked with @Override

UnusedMethodParameter2332

[SRC]void receiveGrailsBuildEvent(String name, Object[] args) {}

[MSG]Violation in class BuildSettingsTestsGrailsBuildListener. Method parameter [name] is never referenced in the method receiveGrailsBuildEvent of class grails.util.BuildSettingsTestsGrailsBuildListener

UnusedMethodParameter2332

[SRC]void receiveGrailsBuildEvent(String name, Object[] args) {}

[MSG]Violation in class BuildSettingsTestsGrailsBuildListener. Method parameter [args] is never referenced in the method receiveGrailsBuildEvent of class grails.util.BuildSettingsTestsGrailsBuildListener

➥ EnvironmentTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper29

[SRC]protected void tearDown() {

[MSG]Violation in class EnvironmentTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter314

[SRC]Metadata.getCurrent().clear()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter320

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter351

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter368

[SRC]assertEquals Environment.CUSTOM, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter388

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3107

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3126

[SRC]assertEquals Environment.CUSTOM, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3148

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3151

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3154

[SRC]assertEquals Environment.CUSTOM, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3169

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3172

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3175

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3178

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3186

[SRC]assertFalse "reload should be disabled by default in pro..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3189

[SRC]assertFalse "reload should be disabled by default in dev..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3192

[SRC]assertTrue "reload should be enabled by default in devel..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3196

[SRC]assertFalse "reload should be disabled by default in pro..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3199

[SRC]assertFalse "reload should be disabled by default in pro..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryObjectReferences3201

[SRC]System.setProperty(Environment.RELOAD_LOCATION, ".")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3202

[SRC]assertTrue "reload should be enabled by default in produ..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

➥ MetadataTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter315

[SRC]assertEquals "1.1", m.getInstalledPlugins().tomcat

[MSG]Violation in class grails.util.MetadataTests. getInstalledPlugins() can probably be rewritten as installedPlugins

UnnecessaryGetter316

[SRC]assertEquals "1.2", m.getInstalledPlugins().hibernate

[MSG]Violation in class grails.util.MetadataTests. getInstalledPlugins() can probably be rewritten as installedPlugins

➥ PluginBuildSettingsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod228

[SRC]PluginBuildSettings createPluginBuildSettings(File proje.._PROJ_DIR) {

[MSG]Violation in class PluginBuildSettingsTests. The method createPluginBuildSettings is public but not a test method

UseAssertFalseInsteadOfNegation2277

[SRC]assertTrue("should not be a plugin-two dir in same dir a..pp.exists())

[MSG]Violation in class grails.util.PluginBuildSettingsTests. assertTrue(!pluginTwoInSameDirAsRootApp.exists()) can be simplified to assertFalse(pluginTwoInSameDirAsRootApp.exists())

UnnecessaryGetter371

[SRC]def sourceFiles = pluginSettings.getPluginSourceFiles()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginSourceFiles() can probably be rewritten as pluginSourceFiles

UnnecessaryGetter3102

[SRC]assertEquals 2, pluginSettings.getPluginLibDirectories().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginLibDirectories() can probably be rewritten as pluginLibDirectories

UnnecessaryGetter3103

[SRC]assertEquals 2, pluginSettings.getPluginLibDirectories().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginLibDirectories() can probably be rewritten as pluginLibDirectories

UnnecessaryGetter3108

[SRC]assertEquals 2, pluginSettings.getPluginDescriptors().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginDescriptors() can probably be rewritten as pluginDescriptors

UnnecessaryGetter3109

[SRC]assertEquals 2, pluginSettings.getPluginDescriptors().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginDescriptors() can probably be rewritten as pluginDescriptors

UnnecessaryGetter3116

[SRC]assertEquals 6, pluginSettings.getArtefactResources().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3117

[SRC]assertEquals 6, pluginSettings.getArtefactResources().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3131

[SRC]def scripts = pluginSettings.getAvailableScripts()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getAvailableScripts() can probably be rewritten as availableScripts

UnnecessaryGetter3143

[SRC]def scripts = pluginSettings.getPluginScripts()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginScripts() can probably be rewritten as pluginScripts

UnnecessaryGetter3151

[SRC]assertEquals 2, pluginSettings.getPluginXmlMetadata().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginXmlMetadata() can probably be rewritten as pluginXmlMetadata

UnnecessaryGetter3152

[SRC]assertEquals 2, pluginSettings.getPluginXmlMetadata().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginXmlMetadata() can probably be rewritten as pluginXmlMetadata

UnnecessaryGetter3158

[SRC]def pluginInfos = pluginSettings.getPluginInfos()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3177

[SRC]def pluginDirs = createPluginBuildSettings().getImplicit..irectories()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getImplicitPluginDirectories() can probably be rewritten as implicitPluginDirectories

UnnecessaryGetter3199

[SRC]def pluginDirs = pluginSettings.getPluginDirectories()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3282

[SRC]def pluginInfos = pluginSettings.getPluginInfos()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginInfos() can probably be rewritten as pluginInfos

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.cli

➥ AbstractCliTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper242

[SRC]protected void setUp() {

[MSG]Violation in class AbstractCliTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper251

[SRC]protected void tearDown() {

[MSG]Violation in class AbstractCliTests. The method tearDown() does not call super.tearDown()

UnnecessaryObjectReferences3100

[SRC]settings.resourcesDir = new File("$projectDir/resources")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3101

[SRC]settings.testClassesDir = new File("$projectDir/test-classes")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3102

[SRC]settings.projectPluginsDir = new File("$projectDir/plugins")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3103

[SRC]settings.globalPluginsDir = new File("$workDir/global-plugins")

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.cli.support

➥ GrailsBuildHelperTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert213

[SRC]void testSetDepedenciesExternallyConfigured() {

[MSG]Violation in class GrailsBuildHelperTests. Test method 'testSetDepedenciesExternallyConfigured' makes no assertions

UnnecessaryObjectReferences342

[SRC]testHelper.projectPluginsDir = new File("plugins")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences343

[SRC]testHelper.globalPluginsDir = new File("global-work/plugins")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences344

[SRC]testHelper.testReportsDir = new File("target/test-reports")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences345

[SRC]testHelper.compileDependencies = testCompileDeps

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences346

[SRC]testHelper.testDependencies = testTestDeps

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences347

[SRC]testHelper.runtimeDependencies = testRuntimeDeps

[MSG]The code could be more concise by using a with() or identity() block

➥ JndiBindingSupportTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import javax.naming.Context

[MSG]The [javax.naming.Context] import is never referenced

UnusedImport35

[SRC]import javax.naming.spi.ObjectFactory

[MSG]The [javax.naming.spi.ObjectFactory] import is never referenced

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.commons

➥ DefaultGrailsCodecClassTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper29

[SRC]protected void setUp() {

[MSG]Violation in class DefaultGrailsCodecClassTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper213

[SRC]protected void tearDown() {

[MSG]Violation in class DefaultGrailsCodecClassTests. The method tearDown() does not call super.tearDown()

UnusedMethodParameter236

[SRC]def encode(obj) { "encoded" }

[MSG]Violation in class CodecWithMethodsCodec. Method parameter [obj] is never referenced in the method encode of class org.codehaus.groovy.grails.commons.CodecWithMethodsCodec

UnusedMethodParameter237

[SRC]def decode(obj) { "decoded" }

[MSG]Violation in class CodecWithMethodsCodec. Method parameter [obj] is never referenced in the method decode of class org.codehaus.groovy.grails.commons.CodecWithMethodsCodec

UnnecessaryGetter319

[SRC]assertEquals "encoded", codecClass.getEncodeMethod().call("stuff")

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsCodecClassTests. getEncodeMethod() can probably be rewritten as encodeMethod

UnnecessaryGetter320

[SRC]assertEquals "decoded", codecClass.getDecodeMethod().call("stuff")

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsCodecClassTests. getDecodeMethod() can probably be rewritten as decodeMethod

➥ DefaultGrailsDomainClassPropertyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper213

[SRC]void setUp() {

[MSG]Violation in class DefaultGrailsDomainClassPropertyTests. The method setUp() does not call super.setUp()

ComparisonWithSelf224

[SRC]assertTrue(prop1Child.equals(prop1Child))

[MSG]Comparing an object to itself is useless and may indicate a bug: prop1Child.equals(prop1Child)

UnnecessaryGroovyImport33

[SRC]import groovy.util.GroovyTestCase

UnnecessaryDotClass315

[SRC]parentClass = new DefaultGrailsDomainClass(ParentClass.class)

[MSG]ParentClass.class can be rewritten as ParentClass

UnnecessaryDotClass316

[SRC]childClass = new DefaultGrailsDomainClass(ChildClass.class)

[MSG]ChildClass.class can be rewritten as ChildClass

➥ DefaultGrailsDomainClassTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2272

[SRC]Class topClass = gcl.parseClass("class Top {\n" +

[MSG]The variable [topClass] in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests is not used

UnusedVariable2279

[SRC]Class middleClass = gcl.parseClass("class Middle extends Top {\n" +

[MSG]The variable [middleClass] in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests is not used

UnusedVariable2284

[SRC]Class bottomClass = gcl.parseClass("class Bottom extends Middle {\n" +

[MSG]The variable [bottomClass] in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests is not used

EmptyCatchBlock2372

[SRC]catch(InvalidPropertyException ipe) {

[MSG]The catch block is empty

UnnecessaryGetter338

[SRC]assertEquals(GrailsDomainClassProperty.FETCH_EAGER, test..FetchMode())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter341

[SRC]assertEquals(GrailsDomainClassProperty.FETCH_LAZY, other..FetchMode())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3200

[SRC]domainMap.put(dc.getFullName(),dc)

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getFullName() can probably be rewritten as fullName

UnnecessaryGetter3207

[SRC]assertTrue(dc.getPropertyByName("children").getOtherSide..("parent")))

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter3208

[SRC]assertTrue(dc.getPropertyByName("parent").getOtherSide()..children")))

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter3256

[SRC]assertEquals(c1dc.getPropertyByName("ones").getOtherSide..me("other"))

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter3263

[SRC]assertEquals(c2dc.getPropertyByName("other").getOtherSid..ame("ones"))

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter3362

[SRC]assertEquals("UserTest",domainClass.getName())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getName() can probably be rewritten as name

UnnecessaryGetter3364

[SRC]assertNotNull(domainClass.getIdentifier())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getIdentifier() can probably be rewritten as identifier

UnnecessaryGetter3365

[SRC]assertNotNull(domainClass.getVersion())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getVersion() can probably be rewritten as version

UnnecessaryGetter3366

[SRC]assertTrue(domainClass.getIdentifier().isIdentity())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getIdentifier() can probably be rewritten as identifier

UnnecessaryGetter3390

[SRC]GrailsDomainClassProperty[] persistantProperties = domai..Properties()

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getPersistentProperties() can probably be rewritten as persistentProperties

➥ GrailsMetaClassUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter315

[SRC]assertNotNull(GrailsMetaClassUtils.getRegistry())

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsMetaClassUtilsTests. getRegistry() can probably be rewritten as registry

UnnecessaryGetter339

[SRC]assertEquals "bar", d.getFoo()

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsMetaClassUtilsTests. getFoo() can probably be rewritten as foo

UnnecessaryGetter348

[SRC]assertEquals "bar", d.getFoo()

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsMetaClassUtilsTests. getFoo() can probably be rewritten as foo

➥ GrailsPluginManagerDescriptorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert28

[SRC]void testDoWithWebDescriptor() {

[MSG]Violation in class GrailsPluginManagerDescriptorTests. Test method 'testDoWithWebDescriptor' makes no assertions

UnusedVariable220

[SRC]def xml = new XmlSlurper().parseText(text)

[MSG]The variable [xml] in class org.codehaus.groovy.grails.commons.GrailsPluginManagerDescriptorTests is not used

JUnitTestMethodWithoutAssert223

[SRC]void testDevelopmentDescriptor() {

[MSG]Violation in class GrailsPluginManagerDescriptorTests. Test method 'testDevelopmentDescriptor' makes no assertions

UnusedVariable236

[SRC]def xml = new XmlSlurper().parseText(text)

[MSG]The variable [xml] in class org.codehaus.groovy.grails.commons.GrailsPluginManagerDescriptorTests is not used

➥ GrailsPluginManagerTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2122

[SRC]void testWithLoadLastPlugin() {

[MSG]Violation in class GrailsPluginManagerTests. Test method 'testWithLoadLastPlugin' makes no assertions

JUnitTestMethodWithoutAssert2134

[SRC]void testDependencyResolutionSucces() {

[MSG]Violation in class GrailsPluginManagerTests. Test method 'testDependencyResolutionSucces' makes no assertions

UnusedImport35

[SRC]import org.codehaus.groovy.grails.plugins.exceptions.PluginException

[MSG]The [org.codehaus.groovy.grails.plugins.exceptions.PluginException] import is never referenced

UnnecessaryGetter3103

[SRC]assertEquals(1, manager.getPluginResources().length)

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getPluginResources() can probably be rewritten as pluginResources

UnnecessaryGetter3112

[SRC]assertEquals("classEditor",plugin.getName())

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getName() can probably be rewritten as name

UnnecessaryGetter3113

[SRC]assertEquals("1.1", plugin.getVersion())

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getVersion() can probably be rewritten as version

UnnecessaryGetter3153

[SRC]def ctx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3171

[SRC]def ctx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.commons.metaclass

➥ DynamicMethodsExpandoMetaClassTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import org.springframework.beans.BeanUtils

[MSG]The [org.springframework.beans.BeanUtils] import is never referenced

UnnecessaryDotClass326

[SRC]def metaClass = new DynamicMethodsExpandoMetaClass(Book.class)

[MSG]Book.class can be rewritten as Book

UnnecessaryDotClass344

[SRC]def metaClass = new DynamicMethodsExpandoMetaClass(Book.class, true)

[MSG]Book.class can be rewritten as Book

UnnecessaryDotClass357

[SRC]def metaClass = new DynamicMethodsExpandoMetaClass(Book.class, true)

[MSG]Book.class can be rewritten as Book

UnnecessaryGetter376

[SRC]assertEquals "bar", b.getFoo()

[MSG]Violation in class org.codehaus.groovy.grails.commons.metaclass.DynamicMethodsExpandoMetaClassTests. getFoo() can probably be rewritten as foo

➥ LazyMetaPropertyMapTests.groovy

Rule NamePriorityLine #Source Line / Message
CoupledTestCase211

[SRC]def obj = new PropertyMapTest(name:"Homer", age:45)

[MSG]new PropertyMapTest([name:Homer, age:45]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase219

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..er:"stuff"))

[MSG]new PropertyMapTest([name:Bart, age:11, other:stuff]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase228

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest())

[MSG]new PropertyMapTest() creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase233

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest())

[MSG]new PropertyMapTest() creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase238

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest())

[MSG]new PropertyMapTest() creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase246

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..r", age:45))

[MSG]new PropertyMapTest([name:Homer, age:45]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase254

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..r", age:45))

[MSG]new PropertyMapTest([name:Homer, age:45]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase270

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..t", age:11))

[MSG]new PropertyMapTest([name:Bart, age:11]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase285

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..t", age:11))

[MSG]new PropertyMapTest([name:Bart, age:11]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase294

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..t", age:11))

[MSG]new PropertyMapTest([name:Bart, age:11]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

➥ MetaClassEnhancerTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper241

[SRC]protected void tearDown() throws Exception {

[MSG]Violation in class MetaClassEnhancerTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.compiler

➥ GrailsClassLoaderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.control.CompilerConfiguration

[MSG]The [org.codehaus.groovy.control.CompilerConfiguration] import is never referenced

UnusedImport34

[SRC]import org.codehaus.groovy.grails.compiler.support.Grail..sourceLoader

[MSG]The [org.codehaus.groovy.grails.compiler.support.GrailsResourceLoader] import is never referenced

UnnecessaryGetter332

[SRC]assert e == gcl.getCompilationError() : "should have sto..ation error"

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsClassLoaderTests. getCompilationError() can probably be rewritten as compilationError

UnnecessaryGetter338

[SRC]assert !gcl.getCompilationError() : "shouldn't have any ..tion errors"

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsClassLoaderTests. getCompilationError() can probably be rewritten as compilationError

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.compiler.injection

➥ GrailsASTUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertTrueInsteadOfAssertEquals364

[SRC]assert true == firstNameBindableExpression.value

[MSG]The expression '(true == firstNameBindableExpression.value)' can be simplified to 'firstNameBindableExpression.value'

UseAssertTrueInsteadOfAssertEquals372

[SRC]assert false == lastNameBindableExpression.value

[MSG]The expression '(false == lastNameBindableExpression.value)' can be simplified to '!lastNameBindableExpression.value'

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.context.support

➥ PluginAwareResourceBundleMessageSourceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper216

[SRC]protected void setUp() {

[MSG]Violation in class PluginAwareResourceBundleMessageSourceTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper220

[SRC]protected void tearDown() {

[MSG]Violation in class PluginAwareResourceBundleMessageSourceTests. The method tearDown() does not call super.tearDown()

UnusedMethodParameter261

[SRC]protected Resource[] getPluginBundles(String pluginName) {

[MSG]Violation in class TestPluginAwareResourceBundleMessageSource. Method parameter [pluginName] is never referenced in the method getPluginBundles of class org.codehaus.groovy.grails.context.support.TestPluginAwareResourceBundleMessageSource

UnnecessaryGetter317

[SRC]Metadata.getCurrent().put(Metadata.WAR_DEPLOYED, "true")

[MSG]Violation in class org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSourceTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter321

[SRC]Metadata.getCurrent().put(Metadata.WAR_DEPLOYED, "")

[MSG]Violation in class org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSourceTests. getCurrent() can probably be rewritten as current

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.documentation

➥ MetadataGeneratingExpandoMetaClassTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import groovy.xml.StreamingMarkupBuilder

[MSG]The [groovy.xml.StreamingMarkupBuilder] import is never referenced

UnusedImport35

[SRC]import org.codehaus.groovy.grails.commons.ControllerArtefactHandler

[MSG]The [org.codehaus.groovy.grails.commons.ControllerArtefactHandler] import is never referenced

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins

➥ CoreGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testComponentScan() {

[MSG]Violation in class CoreGrailsPluginTests. Test method 'testComponentScan' makes no assertions

UnusedVariable225

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]The variable [appCtx] in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests is not used

UnnecessaryGetter325

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter338

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter355

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3119

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

➥ DomainClassGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod212

[SRC]void onSetUp() {

[MSG]Violation in class DomainClassGrailsPluginTests. The method onSetUp is public but not a test method

UnusedMethodParameter2202

[SRC]boolean shouldInject(URL url) { true }

[MSG]Violation in class AlwaysInjector. Method parameter [url] is never referenced in the method shouldInject of class org.codehaus.groovy.grails.plugins.AlwaysInjector

UnusedMethodParameter2204

[SRC]protected boolean isDomainClass(ClassNode classNode, Sou..e) { true }

[MSG]Violation in class AlwaysInjector. Method parameter [classNode] is never referenced in the method isDomainClass of class org.codehaus.groovy.grails.plugins.AlwaysInjector

UnusedMethodParameter2204

[SRC]protected boolean isDomainClass(ClassNode classNode, Sou..e) { true }

[MSG]Violation in class AlwaysInjector. Method parameter [sourceNode] is never referenced in the method isDomainClass of class org.codehaus.groovy.grails.plugins.AlwaysInjector

UnusedMethodParameter2206

[SRC]protected boolean shouldInjectClass(ClassNode classNode) { true }

[MSG]Violation in class AlwaysInjector. Method parameter [classNode] is never referenced in the method shouldInjectClass of class org.codehaus.groovy.grails.plugins.AlwaysInjector

UnnecessaryObjectReferences343

[SRC]gcl.parseClass("""class Child3 extends grails.test.Parent2 {

[MSG]The code could be more concise by using a with() or identity() block

➥ GrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport34

[SRC]import grails.util.BuildSettings

[MSG]The [grails.util.BuildSettings] import is never referenced

UnnecessaryGetter3181

[SRC]System.setProperty(Environment.KEY, Environment.PRODUCTION.getName())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginTests. getName() can probably be rewritten as name

➥ GrailsPluginUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper217

[SRC]protected void setUp() {

[MSG]Violation in class GrailsPluginUtilsTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper237

[SRC]void tearDown() {

[MSG]Violation in class GrailsPluginUtilsTests. The method tearDown() does not call super.tearDown()

UnusedImport36

[SRC]import org.apache.commons.io.FileUtils

[MSG]The [org.apache.commons.io.FileUtils] import is never referenced

UnnecessaryGetter3146

[SRC]def pluginDirs = GrailsPluginUtils.getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtilsTests. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3155

[SRC]def pluginDirs = GrailsPluginUtils.getImplicitPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtilsTests. getImplicitPluginDirectories() can probably be rewritten as implicitPluginDirectories

➥ PluginDescriptorReaderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter250

[SRC]Resource createRelative(String relativePath) { new ByteA..xml.bytes) }

[MSG]Violation in class PluginDescriptorReaderTests$1. Method parameter [relativePath] is never referenced in the method createRelative of class org.codehaus.groovy.grails.plugins.PluginDescriptorReaderTests$1

➥ PluginInfoTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter238

[SRC]GPathResult parseMetadata(Resource pluginDir) { null }

[MSG]Violation in class MockPluginInfo. Method parameter [pluginDir] is never referenced in the method parseMetadata of class org.codehaus.groovy.grails.plugins.MockPluginInfo

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.i18n

➥ I18nGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences320

[SRC]ctx.registerMockResource("WEB-INF/grails-app/i18n/sub/di..properties")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences321

[SRC]ctx.registerMockResource("WEB-INF/grails-app/i18n/nobundle")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences322

[SRC]ctx.registerMockResource("WEB-INF/grails-app/i18n/nobundle.txt")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences323

[SRC]ctx.registerMockResource("WEB-INF/grails-app/i18n/nobundle.xml")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter334

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.i18n.I18nGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.logging

➥ Log4jDslTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2201

[SRC]def consoleAppender

[MSG]The variable [consoleAppender] in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests is not used

UnnecessaryGetter3120

[SRC]def r = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3139

[SRC]r = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3158

[SRC]r = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3178

[SRC]def root = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3181

[SRC]def appenders = root.getAllAppenders()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getAllAppenders() can probably be rewritten as allAppenders

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.publishing

➥ DefaultPluginPublisherTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2249

[SRC]protected GPathResult getPluginMetadata(String pluginName) {

[MSG]Violation in class TestPluginPublisher. Method parameter [pluginName] is never referenced in the method getPluginMetadata of class org.codehaus.groovy.grails.plugins.publishing.TestPluginPublisher

UnusedMethodParameter2253

[SRC]GPathResult parsePluginList(Resource pluginsListFile) {

[MSG]Violation in class TestPluginPublisher. Method parameter [pluginsListFile] is never referenced in the method parsePluginList of class org.codehaus.groovy.grails.plugins.publishing.TestPluginPublisher

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.web

➥ ControllersGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2180

[SRC]Class parseTestBean() {

[MSG]Violation in class ControllersGrailsPluginTests. The method parseTestBean is public but not a test method

UseAssertEqualsInsteadOfAssertTrue3115

[SRC]assertTrue ga.config.grails.disableCommonsMultipart.size() == 0

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. Replace assertTrue with a call to assertEquals()

UnnecessaryGetter3131

[SRC]assertNotNull beanDef.getPropertyValues().getPropertyVal..seResource')

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getPropertyValues() can probably be rewritten as propertyValues

UnnecessaryGetter3133

[SRC]assertEquals "file:.", beanDef.getPropertyValues().getPr..).getValue()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getValue() can probably be rewritten as value

UnnecessaryGetter3133

[SRC]assertEquals "file:.", beanDef.getPropertyValues().getPr..).getValue()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getPropertyValues() can probably be rewritten as propertyValues

UnnecessaryGetter3136

[SRC]assertEquals "groovyPageLocator", beanDef.getPropertyVal..()?.beanName

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getValue() can probably be rewritten as value

UnnecessaryGetter3136

[SRC]assertEquals "groovyPageLocator", beanDef.getPropertyVal..()?.beanName

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getPropertyValues() can probably be rewritten as propertyValues

➥ LoggingGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable241

[SRC]def registry = GroovySystem.metaClassRegistry

[MSG]The variable [registry] in class org.codehaus.groovy.grails.plugins.web.LoggingGrailsPluginTests is not used

UnusedVariable247

[SRC]def registry = GroovySystem.metaClassRegistry

[MSG]The variable [registry] in class org.codehaus.groovy.grails.plugins.web.LoggingGrailsPluginTests is not used

UnusedVariable253

[SRC]def registry = GroovySystem.metaClassRegistry

[MSG]The variable [registry] in class org.codehaus.groovy.grails.plugins.web.LoggingGrailsPluginTests is not used

➥ ServletsGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable260

[SRC]def httpSessionMetaClass = GroovySystem.getMetaClassRegi..HttpSession)

[MSG]The variable [httpSessionMetaClass] in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPluginTests is not used

UnusedVariable261

[SRC]def metaClass = GroovySystem.getMetaClassRegistry().getM...getClass())

[MSG]The variable [metaClass] in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPluginTests is not used

UnnecessaryGroovyImport33

[SRC]import groovy.lang.GroovySystem;

UnnecessaryGetter360

[SRC]def httpSessionMetaClass = GroovySystem.getMetaClassRegi..HttpSession)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPluginTests. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

UnnecessaryGetter361

[SRC]def metaClass = GroovySystem.getMetaClassRegistry().getM...getClass())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPluginTests. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.web.mapping

➥ UrlMappingsGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper287

[SRC]protected void tearDown() {

[MSG]Violation in class UrlMappingsGrailsPluginTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.reload

➥ TagLibReloadTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable218

[SRC]Class oldClass = ga.getTagLibClass("TestTagLib").getClazz()

[MSG]The variable [oldClass] in class org.codehaus.groovy.grails.reload.TagLibReloadTests is not used

UnusedVariable219

[SRC]def result

[MSG]The variable [result] in class org.codehaus.groovy.grails.reload.TagLibReloadTests is not used

JUnitPublicNonTestMethod245

[SRC]void onInit() {

[MSG]Violation in class TagLibReloadTests. The method onInit is public but not a test method

UnnecessaryGetter318

[SRC]Class oldClass = ga.getTagLibClass("TestTagLib").getClazz()

[MSG]Violation in class org.codehaus.groovy.grails.reload.TagLibReloadTests. getClazz() can probably be rewritten as clazz

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.resolve

➥ IvyDependencyManagerTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper223

[SRC]protected void setUp() {

[MSG]Violation in class IvyDependencyManagerTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper227

[SRC]protected void tearDown() {

[MSG]Violation in class IvyDependencyManagerTests. The method tearDown() does not call super.tearDown()

JUnitTestMethodWithoutAssert2119

[SRC]void testPluginResolve() {

[MSG]Violation in class IvyDependencyManagerTests. Test method 'testPluginResolve' makes no assertions

UnusedVariable2132

[SRC]def report = manager.resolveDependencies()

[MSG]The variable [report] in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests is not used

JUnitTestMethodWithoutAssert2449

[SRC]void testResolveApplicationDependencies() {

[MSG]Violation in class IvyDependencyManagerTests. Test method 'testResolveApplicationDependencies' makes no assertions

UnusedVariable2638

[SRC]def grailsVersion = getCurrentGrailsVersion()

[MSG]The variable [grailsVersion] in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests is not used

JUnitPublicNonTestMethod2671

[SRC]def getCurrentGrailsVersion() {

[MSG]Violation in class IvyDependencyManagerTests. The method getCurrentGrailsVersion is public but not a test method

JUnitTestMethodWithoutAssert2799

[SRC]void testResolve() {

[MSG]Violation in class IvyDependencyManagerTests. Test method 'testResolve' makes no assertions

UnusedVariable2831

[SRC]ModuleRevisionId junit = manager.dependencies.find { Mo.. == 'junit'}

[MSG]The variable [junit] in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests is not used

UseAssertTrueInsteadOfAssertEquals338

[SRC]assert manager.ivySettings.defaultUseOrigin == true

[MSG]The expression '(manager.ivySettings.defaultUseOrigin == true)' can be simplified to 'manager.ivySettings.defaultUseOrigin'

UnnecessaryGetter3219

[SRC]assertEquals "1.5", dd.getDependencyRevisionId().revision

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyRevisionId() can probably be rewritten as dependencyRevisionId

UnnecessaryGetter3226

[SRC]assertEquals "0.5.5", dd.getDependencyRevisionId().revision

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyRevisionId() can probably be rewritten as dependencyRevisionId

UnnecessaryGetter3233

[SRC]assertEquals "0.5.6", dd.getDependencyRevisionId().revision

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyRevisionId() can probably be rewritten as dependencyRevisionId

UnnecessaryGetter3298

[SRC]assertEquals 1, dep.getModuleConfigurations().length

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getModuleConfigurations() can probably be rewritten as moduleConfigurations

UnnecessaryGetter3486

[SRC]assertEquals 2, manager.getApplicationDependencyDescriptors().size()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getApplicationDependencyDescriptors() can probably be rewritten as applicationDependencyDescriptors

UnnecessaryGetter3617

[SRC]def grailsVersion = getCurrentGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getCurrentGrailsVersion() can probably be rewritten as currentGrailsVersion

UnnecessaryGetter3638

[SRC]def grailsVersion = getCurrentGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getCurrentGrailsVersion() can probably be rewritten as currentGrailsVersion

UnnecessaryGetter3741

[SRC]DefaultDependencyDescriptor dd = manager.getDependencyDe..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyDescriptors() can probably be rewritten as dependencyDescriptors

UnnecessaryGetter3757

[SRC]dd = manager.getDependencyDescriptors().iterator().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyDescriptors() can probably be rewritten as dependencyDescriptors

UnnecessaryGetter3772

[SRC]DefaultDependencyDescriptor dd = manager.getPluginDepend..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getPluginDependencyDescriptors() can probably be rewritten as pluginDependencyDescriptors

UnnecessaryGetter3786

[SRC]DefaultDependencyDescriptor dd = manager.getPluginDepend..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getPluginDependencyDescriptors() can probably be rewritten as pluginDependencyDescriptors

UnnecessaryGetter3850

[SRC]DefaultDependencyDescriptor dd = manager.getDependencyDe..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyDescriptors() can probably be rewritten as dependencyDescriptors

UnnecessaryGetter3866

[SRC]dd = manager.getDependencyDescriptors().iterator().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyDescriptors() can probably be rewritten as dependencyDescriptors

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.validation

➥ ConstrainedPropertyBuilderForCommandsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences3106

[SRC]gcl.parseClass('''

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3119

[SRC]gcl.parseClass('''

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3132

[SRC]gcl.parseClass('''

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3153

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3154

[SRC]assertEquals(5, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3155

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3156

[SRC]assertNotNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3160

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3161

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3162

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3163

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryObjectReferences3181

[SRC]personCommand.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3184

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3184

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3185

[SRC]assertEquals(1, personCommand.getErrors().getFieldErrors..me").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3186

[SRC]assertNull(personCommand.getErrors().getFieldErrors("fir..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3186

[SRC]assertNull(personCommand.getErrors().getFieldErrors("fir..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryObjectReferences3199

[SRC]person.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3202

[SRC]assertEquals(1, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3202

[SRC]assertEquals(1, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3203

[SRC]assertEquals(1, person.getErrors().getFieldErrors("firstName").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3204

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3204

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3214

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3215

[SRC]assertEquals(2, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3216

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3217

[SRC]assertNotNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3221

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3222

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3223

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3224

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3225

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryObjectReferences3243

[SRC]personCommand.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3246

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3246

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3247

[SRC]assertEquals(1, personCommand.getErrors().getFieldErrors..me").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3248

[SRC]assertNull(personCommand.getErrors().getFieldErrors("fir..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3248

[SRC]assertNull(personCommand.getErrors().getFieldErrors("fir..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryObjectReferences3261

[SRC]person.email = "wrongEmail"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3262

[SRC]person.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3265

[SRC]assertEquals(1, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3265

[SRC]assertEquals(1, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3266

[SRC]assertEquals(1, person.getErrors().getFieldErrors("email").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3267

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3267

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3277

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3278

[SRC]assertEquals(5, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3279

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3280

[SRC]assertNotNull(personCommand.getConstraints().get("telephone"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3282

[SRC]assertEquals(30, personCommand.getConstraints().get("fir..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3282

[SRC]assertEquals(30, personCommand.getConstraints().get("fir..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3283

[SRC]assertEquals(50, personCommand.getConstraints().get("las..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3283

[SRC]assertEquals(50, personCommand.getConstraints().get("las..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3286

[SRC]personCommand.getConstraints().get("telephone").getAppli..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3286

[SRC]personCommand.getConstraints().get("telephone").getAppli..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3290

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3291

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3292

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3293

[SRC]assertNotNull(person.getConstraints().get("telephone"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3295

[SRC]assertEquals(30, person.getConstraints().get("firstName"..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3295

[SRC]assertEquals(30, person.getConstraints().get("firstName"..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3296

[SRC]assertEquals(50, person.getConstraints().get("lastName")..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3296

[SRC]assertEquals(50, person.getConstraints().get("lastName")..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3297

[SRC]assertEquals("123123", person.getConstraints().get("tele..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3297

[SRC]assertEquals("123123", person.getConstraints().get("tele..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryObjectReferences3315

[SRC]personCommand.lastName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3316

[SRC]personCommand.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3319

[SRC]assertEquals(2, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3319

[SRC]assertEquals(2, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryObjectReferences3332

[SRC]person.firstName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3333

[SRC]person.email = "wrongEmail"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3334

[SRC]person.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3337

[SRC]assertEquals(2, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3337

[SRC]assertEquals(2, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3338

[SRC]assertEquals(1, person.getErrors().getFieldErrors("firstName").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3339

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3339

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3340

[SRC]assertEquals(1, person.getErrors().getFieldErrors("email").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3341

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3341

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3351

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3352

[SRC]assertEquals(5, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3353

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3354

[SRC]assertNotNull(personCommand.getConstraints().get("telephone"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3356

[SRC]assertEquals(10, personCommand.getConstraints().get("fir..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3356

[SRC]assertEquals(10, personCommand.getConstraints().get("fir..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3357

[SRC]assertEquals(20, personCommand.getConstraints().get("las..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3357

[SRC]assertEquals(20, personCommand.getConstraints().get("las..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3360

[SRC]personCommand.getConstraints().get("telephone").getAppli..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3360

[SRC]personCommand.getConstraints().get("telephone").getAppli..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3364

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3365

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3366

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3367

[SRC]assertNotNull(person.getConstraints().get("telephone"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3369

[SRC]assertEquals(30, person.getConstraints().get("firstName"..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3369

[SRC]assertEquals(30, person.getConstraints().get("firstName"..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3370

[SRC]assertEquals(50, person.getConstraints().get("lastName")..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3370

[SRC]assertEquals(50, person.getConstraints().get("lastName")..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3371

[SRC]assertEquals("123123", person.getConstraints().get("tele..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3371

[SRC]assertEquals("123123", person.getConstraints().get("tele..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryObjectReferences3389

[SRC]personCommand.firstName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3390

[SRC]personCommand.lastName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3391

[SRC]personCommand.email = "wrongEmail"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3392

[SRC]personCommand.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3395

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3395

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryObjectReferences3408

[SRC]person.firstName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3409

[SRC]person.email = "wrongEmail"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3410

[SRC]person.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3413

[SRC]assertEquals(2, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3413

[SRC]assertEquals(2, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3414

[SRC]assertEquals(1, person.getErrors().getFieldErrors("firstName").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3415

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3415

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3416

[SRC]assertEquals(1, person.getErrors().getFieldErrors("email").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3417

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3417

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3427

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3428

[SRC]assertEquals(2, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3429

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3430

[SRC]assertNotNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3431

[SRC]assertNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3435

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3436

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3437

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3438

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3439

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3449

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3450

[SRC]assertEquals(3, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3451

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3452

[SRC]assertNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3453

[SRC]assertNull(personCommand.getConstraints().get("lastName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3454

[SRC]assertNotNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3458

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3459

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3460

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3461

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3462

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3472

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3473

[SRC]assertEquals(3, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3474

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3475

[SRC]assertNotNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3476

[SRC]assertNotNull(personCommand.getConstraints().get("lastName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3477

[SRC]assertNotNull(personCommand.getConstraints().get("middleName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3478

[SRC]assertNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3482

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3483

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3484

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3485

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3486

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3497

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3498

[SRC]assertEquals(2, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3499

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3500

[SRC]assertNotNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3501

[SRC]assertNotNull(personCommand.getConstraints().get("lastName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3502

[SRC]assertNull(personCommand.getConstraints().get("middleName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3503

[SRC]assertNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3507

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3508

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3509

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3510

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3511

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

➥ ConstraintMessageTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter254

[SRC]void processValidate(Object target, Object propertyValue..rs errors) {

[MSG]Violation in class TestConstraint. Method parameter [propertyValue] is never referenced in the method processValidate of class org.codehaus.groovy.grails.validation.TestConstraint

UnusedMethodParameter258

[SRC]boolean supports(Class type) { true }

[MSG]Violation in class TestConstraint. Method parameter [type] is never referenced in the method supports of class org.codehaus.groovy.grails.validation.TestConstraint

UnnecessaryGetter339

[SRC]'test'] as String[], errors.getFieldError().getCodes())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstraintMessageTests. getCodes() can probably be rewritten as codes

UnnecessaryGetter339

[SRC]'test'] as String[], errors.getFieldError().getCodes())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstraintMessageTests. getFieldError() can probably be rewritten as fieldError

➥ ConstraintsBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod274

[SRC]Errors validateInstance(instance, validator) {

[MSG]Violation in class ConstraintsBuilderTests. The method validateInstance is public but not a test method

JUnitPublicNonTestMethod280

[SRC]GrailsDomainClassValidator configureValidator(theClass, instance) {

[MSG]Violation in class ConstraintsBuilderTests. The method configureValidator is public but not a test method

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.context

➥ GrailsConfigUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable264

[SRC]def configurator = GrailsConfigUtils.determineGrailsRunt..ontext, ctx)

[MSG]The variable [configurator] in class org.codehaus.groovy.grails.web.context.GrailsConfigUtilsTests is not used

JUnitTearDownCallsSuper279

[SRC]protected void tearDown() {

[MSG]Violation in class GrailsConfigUtilsTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter348

[SRC]servletContext.addInitParameter("grailsConfiguratorClass..s.getName())

[MSG]Violation in class org.codehaus.groovy.grails.web.context.GrailsConfigUtilsTests. getName() can probably be rewritten as name

UnnecessaryDotClass348

[SRC]servletContext.addInitParameter("grailsConfiguratorClass..s.getName())

[MSG]MyGrailsRuntimeConfigurator.class can be rewritten as MyGrailsRuntimeConfigurator

UnnecessaryDotClass353

[SRC]assertEquals configurator.class.name, MyGrailsRuntimeCon..r.class.name

[MSG]MyGrailsRuntimeConfigurator.class can be rewritten as MyGrailsRuntimeConfigurator

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.errors

➥ GrailsExceptionResolverTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper237

[SRC]protected void tearDown() {

[MSG]Violation in class GrailsExceptionResolverTests. The method tearDown() does not call super.tearDown()

UnusedMethodParameter2264

[SRC]View resolveViewName(String viewName, Locale locale) {

[MSG]Violation in class DummyViewResolver. Method parameter [locale] is never referenced in the method resolveViewName of class org.codehaus.groovy.grails.web.errors.DummyViewResolver

UnnecessaryGetter3120

[SRC]assertEquals "/grails/foo/bar.dispatch",response.getForwardedUrl()

[MSG]Violation in class org.codehaus.groovy.grails.web.errors.GrailsExceptionResolverTests. getForwardedUrl() can probably be rewritten as forwardedUrl

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.filters

➥ HiddenHttpMethodFilterTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.springframework.mock.web.MockServletContext;

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

UnusedImport35

[SRC]import org.codehaus.groovy.grails.web.servlet.GrailsAppl..nAttributes;

[MSG]The [org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes] import is never referenced

UnusedImport36

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest;

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest] import is never referenced

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.i18n

➥ ParamsAwareLocaleChangeInterceptorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper216

[SRC]protected void tearDown() {

[MSG]Violation in class ParamsAwareLocaleChangeInterceptorTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter324

[SRC]def request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter325

[SRC]def response = webRequest.getCurrentResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentResponse() can probably be rewritten as currentResponse

UnnecessaryGetter347

[SRC]assertEquals "de", locale.getLanguage()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getLanguage() can probably be rewritten as language

UnnecessaryGetter348

[SRC]assertEquals "DE", locale.getCountry()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCountry() can probably be rewritten as country

UnnecessaryGetter355

[SRC]def request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter356

[SRC]def response = webRequest.getCurrentResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentResponse() can probably be rewritten as currentResponse

UnnecessaryGetter378

[SRC]assertEquals "de", locale.getLanguage()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getLanguage() can probably be rewritten as language

UnnecessaryGetter379

[SRC]assertEquals "DE", locale.getCountry()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCountry() can probably be rewritten as country

UnnecessaryGetter386

[SRC]MockHttpServletRequest request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter387

[SRC]def response = webRequest.getCurrentResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentResponse() can probably be rewritten as currentResponse

UnnecessaryGetter3109

[SRC]assertEquals "de", locale.getLanguage()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getLanguage() can probably be rewritten as language

UnnecessaryGetter3110

[SRC]assertEquals "DE", locale.getCountry()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCountry() can probably be rewritten as country

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.json

➥ JSONObjectTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertEqualsInsteadOfAssertTrue332

[SRC]assertTrue j1 == j2

[MSG]Violation in class org.codehaus.groovy.grails.web.json.JSONObjectTests. Replace assertTrue with a call to assertEquals()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.metaclass

➥ WithFormMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper230

[SRC]@Override protected void tearDown() {

[MSG]Violation in class WithFormMethodTests. The method tearDown() does not call super.tearDown()

UnusedVariable2146

[SRC]def result = withForm.withForm(request) {

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.metaclass.WithFormMethodTests is not used

UnusedVariable2170

[SRC]def result = withForm.withForm(request) {

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.metaclass.WithFormMethodTests is not used

UnusedImport320

[SRC]import org.apache.commons.lang.StringUtils;

[MSG]The [org.apache.commons.lang.StringUtils] import is never referenced

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.servlet

➥ BindDataMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2160

[SRC]void onSetUp() {

[MSG]Violation in class BindDataMethodTests. The method onSetUp is public but not a test method

UnnecessaryParenthesesForMethodCallWithClosure334

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure346

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure360

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure374

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure386

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3100

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3113

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3117

[SRC]input.each() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3133

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3147

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

➥ DefaultGrailsApplicationAttributesTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper212

[SRC]void setUp() {

[MSG]Violation in class DefaultGrailsApplicationAttributesTests. The method setUp() does not call super.setUp()

➥ FlashScopeWithErrorsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport321

[SRC]import org.springframework.mock.web.MockHttpServletRequest

[MSG]The [org.springframework.mock.web.MockHttpServletRequest] import is never referenced

➥ GrailsHttpSessionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod230

[SRC]void onSetUp() {

[MSG]Violation in class GrailsHttpSessionTests. The method onSetUp is public but not a test method

UnusedVariable242

[SRC]def mock = new MockHttpSession()

[MSG]The variable [mock] in class org.codehaus.groovy.grails.web.servlet.GrailsHttpSessionTests is not used

➥ RenderMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2199

[SRC]def resopnse = mockController.response

[MSG]The variable [resopnse] in class org.codehaus.groovy.grails.web.servlet.RenderMethodTests is not used

UnusedVariable2213

[SRC]def resopnse = mockController.response

[MSG]The variable [resopnse] in class org.codehaus.groovy.grails.web.servlet.RenderMethodTests is not used

JUnitPublicNonTestMethod2291

[SRC]String toString() { foo }

[MSG]Violation in class RenderTest. The method toString is public but not a test method

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.servlet.filter

➥ AbstractServletFilterTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper254

[SRC]void tearDown() {

[MSG]Violation in class AbstractServletFilterTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.servlet.mvc

➥ CommandObjectEnhancementAppliedOnceTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertTrueInsteadOfAssertEquals319

[SRC]assert WebMetaUtils.isCommandObjectAction(action) == true

[MSG]The expression '(WebMetaUtils.isCommandObjectAction(action) == true)' can be simplified to 'WebMetaUtils.isCommandObjectAction(action)'

UseAssertTrueInsteadOfAssertEquals323

[SRC]assert WebMetaUtils.isCommandObjectAction(fresh.index) == false

[MSG]The expression '(WebMetaUtils.isCommandObjectAction(fresh.index) == false)' can be simplified to '!WebMetaUtils.isCommandObjectAction(fresh.index)'

➥ ControllerInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert223

[SRC]void testCallSuperMethod() {

[MSG]Violation in class ControllerInheritanceTests. Test method 'testCallSuperMethod' makes no assertions

➥ ControllersDynamicMethodsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod217

[SRC]void onSetUp() {

[MSG]Violation in class ControllersDynamicMethodsTests. The method onSetUp is public but not a test method

JUnitPublicNonTestMethod228

[SRC]void runTest(Closure callable) {

[MSG]Violation in class ControllersDynamicMethodsTests. The method runTest is public but not a test method

JUnitTestMethodWithoutAssert2135

[SRC]void testRenderMethod() {

[MSG]Violation in class ControllersDynamicMethodsTests. Test method 'testRenderMethod' makes no assertions

UnnecessaryGetter353

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.ControllersDynamicMethodsTests. getApplicationContext() can probably be rewritten as applicationContext

➥ GrailsParameterMapTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2240

[SRC]void testIterateOverMapContainingDate() {

[MSG]Violation in class GrailsParameterMapTests. Test method 'testIterateOverMapContainingDate' makes no assertions

UnusedImport34

[SRC]import grails.util.GrailsWebUtil

[MSG]The [grails.util.GrailsWebUtil] import is never referenced

UnusedImport36

[SRC]import org.springframework.web.context.WebApplicationContext

[MSG]The [org.springframework.web.context.WebApplicationContext] import is never referenced

UnnecessaryPackageReference321

[SRC]final webRequest = grails.util.GrailsWebUtil.bindMockWebRequest(ctx)

[MSG]The grails.util.GrailsWebUtil class was explicitly imported, so specifying the package name is not necessary

UnnecessaryObjectReferences3112

[SRC]map.aList = [1,2]

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3113

[SRC]map.array = ["one", "two" ] as String[]

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3114

[SRC]map.longNumber = 1234567890

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3115

[SRC]map.z = 'z'

[MSG]The code could be more concise by using a with() or identity() block

UseAssertTrueInsteadOfAssertEquals3209

[SRC]assertEquals false, map.boolean('one')

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals3210

[SRC]assertEquals true, map.boolean('nonexistent', Boolean.TRUE)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals3211

[SRC]assertEquals false, map.boolean('nonexistent', Boolean.FALSE)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals3212

[SRC]assertEquals true, map.boolean('bool')

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryObjectReferences3262

[SRC]mockRequest.addParameter("a.e.g", "gValue")

[MSG]The code could be more concise by using a with() or identity() block

➥ ParamsObjectTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences324

[SRC]request.addParameter("book.id", "10")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences325

[SRC]request.addParameter("publisher.name", "Apress")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences326

[SRC]request.addParameter("publisher.authors[0].name", "Fred")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences327

[SRC]request.addParameter("publisher.authors[1].name", "Joe")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences328

[SRC]request.addParameter("test..foo..bar", "Stuff")

[MSG]The code could be more concise by using a with() or identity() block

➥ RenderDynamicMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
ConsecutiveStringConcatenation3107

[SRC]render "${'te' + 'xt'}"

[MSG]String concatenation in class org.codehaus.groovy.grails.web.servlet.mvc.RenderDynamicMethodTestController can be joined into the literal 'text'

ConsecutiveStringConcatenation3107

[SRC]render "${'te' + 'xt'}"

[MSG]String concatenation in class org.codehaus.groovy.grails.web.servlet.mvc.RenderDynamicMethodTestController can be joined into the literal 'text'

➥ TagLibDynamicMethodsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod217

[SRC]void onSetUp() {

[MSG]Violation in class TagLibDynamicMethodsTests. The method onSetUp is public but not a test method

ImportFromSamePackage38

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.*

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.sitemesh

➥ FactoryHolderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter236

[SRC]boolean isPathExcluded(String path) { false }

[MSG]Violation in class DummyFactory. Method parameter [path] is never referenced in the method isPathExcluded of class org.codehaus.groovy.grails.web.sitemesh.DummyFactory

UnusedMethodParameter237

[SRC]boolean shouldParsePage(String contentType) { false }

[MSG]Violation in class DummyFactory. Method parameter [contentType] is never referenced in the method shouldParsePage of class org.codehaus.groovy.grails.web.sitemesh.DummyFactory

EmptyMethod239

[SRC]void refresh() {}

[MSG]Violation in class DummyFactory. The method refresh is both empty and not marked with @Override

UnusedMethodParameter240

[SRC]PageParser getPageParser(String contentType) { null }

[MSG]Violation in class DummyFactory. Method parameter [contentType] is never referenced in the method getPageParser of class org.codehaus.groovy.grails.web.sitemesh.DummyFactory

UnnecessaryGetter312

[SRC]assertSame factory, FactoryHolder.getFactory()

[MSG]Violation in class org.codehaus.groovy.grails.web.sitemesh.FactoryHolderTests. getFactory() can probably be rewritten as factory

UnnecessaryGetter318

[SRC]FactoryHolder.getFactory()

[MSG]Violation in class org.codehaus.groovy.grails.web.sitemesh.FactoryHolderTests. getFactory() can probably be rewritten as factory

➥ GSPSitemeshPageTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable215

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable223

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable231

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable239

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable252

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable261

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable279

[SRC]def result = applyTemplate(template, [:], target1)

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable296

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable2113

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

JUnitTearDownCallsSuper2125

[SRC]void tearDown() {

[MSG]Violation in class GSPSitemeshPageTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.util

➥ StreamCharBufferGroovyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper27

[SRC]protected void setUp() {

[MSG]Violation in class StreamCharBufferGroovyTests. The method setUp() does not call super.setUp()

➥ WebUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper222

[SRC]protected void setUp() {

[MSG]Violation in class WebUtilsTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper242

[SRC]protected void tearDown() {

[MSG]Violation in class WebUtilsTests. The method tearDown() does not call super.tearDown()

JUnitPublicNonTestMethod2141

[SRC]void clearGrailsWebRequest() {

[MSG]Violation in class WebUtilsTests. The method clearGrailsWebRequest is public but not a test method

UnnecessaryDefInMethodDeclaration361

[SRC]private def bindMockRequest(DefaultGrailsApplication ga) {

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. The def keyword is unneeded when a method is marked private

UnnecessaryGetter367

[SRC]ctx.registerMockBean(MimeType.BEAN_NAME, factory.getObject())

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getObject() can probably be rewritten as object

UnnecessaryGetter3103

[SRC]assertNull RequestContextHolder.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3123

[SRC]assertNull RequestContextHolder.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3137

[SRC]assertEquals mockWebRequest, RequestContextHolder.getReq..Attributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3154

[SRC]assertNull RequestContextHolder.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3160

[SRC]assertNull RequestContextHolder.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

Package: grails-test-suite-uber.src.test.resources.org.codehaus.groovy.grails.plugins

➥ ClassEditorGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod25

[SRC]def withSpring() {}

[MSG]Violation in class ClassEditorGrailsPlugin. The method withSpring is both empty and not marked with @Override

EmptyMethod27

[SRC]def withApplicationContext(ctx) {}

[MSG]Violation in class ClassEditorGrailsPlugin. The method withApplicationContext is both empty and not marked with @Override

UnusedMethodParameter27

[SRC]def withApplicationContext(ctx) {}

[MSG]Violation in class ClassEditorGrailsPlugin. Method parameter [ctx] is never referenced in the method withApplicationContext of class ClassEditorGrailsPlugin

Package: grails-test-suite-web.src.test.groovy.grails.test

➥ GrailsUrlMappingsTestCaseTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert263

[SRC]void testSetup() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'testSetup' makes no assertions

JUnitTestMethodWithoutAssert273

[SRC]void testSetupExplicitMappingClass() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'testSetupExplicitMappingClass' makes no assertions

JUnitTestMethodWithoutAssert2176

[SRC]void test_GRAILS_3571_Bug() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'test_GRAILS_3571_Bug' makes no assertions

EmptyCatchBlock2209

[SRC]catch (e) {}

[MSG]The catch block is empty

JUnitTestMethodWithoutAssert2265

[SRC]void testGrails5786() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'testGrails5786' makes no assertions

JUnitTestMethodWithoutAssert2272

[SRC]void testGrails5222() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'testGrails5222' makes no assertions

JUnitPublicNonTestMethod2353

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class MultipleMappingsTestCase. The method assertView is public but not a test method

UnusedMethodParameter2353

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class MultipleMappingsTestCase. Method parameter [controller] is never referenced in the method assertView of class grails.test.MultipleMappingsTestCase

UnusedMethodParameter2353

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class MultipleMappingsTestCase. Method parameter [view] is never referenced in the method assertView of class grails.test.MultipleMappingsTestCase

UnusedMethodParameter2353

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class MultipleMappingsTestCase. Method parameter [url] is never referenced in the method assertView of class grails.test.MultipleMappingsTestCase

EqualsAndHashCode2396

[SRC]class MockUrlMapping implements UrlMapping {

[MSG]The class grails.test.MockUrlMapping defines equals(Object) but not hashCode()

UnusedMethodParameter2410

[SRC]UrlMappingInfo match(String uri) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [uri] is never referenced in the method match of class grails.test.MockUrlMapping

UnusedMethodParameter2414

[SRC]int compareTo(Object o) { 0 }

[MSG]Violation in class MockUrlMapping. Method parameter [o] is never referenced in the method compareTo of class grails.test.MockUrlMapping

UnusedMethodParameter2416

[SRC]String createURL(Map parameterValues, String encoding) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2416

[SRC]String createURL(Map parameterValues, String encoding) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2418

[SRC]String createURL(Map parameterValues, String encoding, S..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2418

[SRC]String createURL(Map parameterValues, String encoding, S..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2418

[SRC]String createURL(Map parameterValues, String encoding, S..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [fragment] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2420

[SRC]String createURL(String controller, String action, Map p..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [controller] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2420

[SRC]String createURL(String controller, String action, Map p..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [action] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2420

[SRC]String createURL(String controller, String action, Map p..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2420

[SRC]String createURL(String controller, String action, Map p..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2422

[SRC]String createRelativeURL(String controller, String actio..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [controller] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2422

[SRC]String createRelativeURL(String controller, String actio..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [action] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2422

[SRC]String createRelativeURL(String controller, String actio..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2422

[SRC]String createRelativeURL(String controller, String actio..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [controller] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [action] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [fragment] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [controller] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [action] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [fragment] is never referenced in the method createURL of class grails.test.MockUrlMapping

EmptyMethod2436

[SRC]void setParameterValues(Map parameterValues) {}

[MSG]Violation in class MockUrlMapping. The method setParameterValues is both empty and not marked with @Override

UnusedMethodParameter2436

[SRC]void setParameterValues(Map parameterValues) {}

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method setParameterValues of class grails.test.MockUrlMapping

EmptyMethod2438

[SRC]void setParseRequest(boolean shouldParse) {

[MSG]Violation in class MockUrlMapping. The method setParseRequest is both empty and not marked with @Override

UnusedMethodParameter2438

[SRC]void setParseRequest(boolean shouldParse) {

[MSG]Violation in class MockUrlMapping. Method parameter [shouldParse] is never referenced in the method setParseRequest of class grails.test.MockUrlMapping

EmptyMethod2444

[SRC]void setMappingName(String name) {}

[MSG]Violation in class MockUrlMapping. The method setMappingName is both empty and not marked with @Override

UnusedMethodParameter2444

[SRC]void setMappingName(String name) {}

[MSG]Violation in class MockUrlMapping. Method parameter [name] is never referenced in the method setMappingName of class grails.test.MockUrlMapping

UnusedMethodParameter2446

[SRC]boolean hasRuntimeVariable(String name) { false }

[MSG]Violation in class MockUrlMapping. Method parameter [name] is never referenced in the method hasRuntimeVariable of class grails.test.MockUrlMapping

UnnecessaryObjectReferences3224

[SRC]test.assertUrlMapping(500, controller: "grailsUrlMapping..: "action1")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3226

[SRC]test.assertForwardUrlMapping("/controllerView", controll..iew: "view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3235

[SRC]test.assertUrlMapping("/absoluteView", view: "view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3236

[SRC]test.assertUrlMapping("/absoluteView", view: "/view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3237

[SRC]test.assertUrlMapping("/absoluteViewWithSlash", view: "view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3238

[SRC]test.assertUrlMapping("/absoluteViewWithSlash", view: "/view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3240

[SRC]test.assertUrlMapping("/params/value1/value2", controlle.."action3") {

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3260

[SRC]test.assertUrlMapping("/params/value1", controller: "gra.."action3") {

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-test-suite-web.src.test.groovy.grails.test.mixin

➥ TagLibWithServiceMockTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryConstructor326

[SRC]TimeTagLib() {

[MSG]The constructor can be safely deleted

➥ UrlMappingsTestForTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod223

[SRC]def list() { }

[MSG]Violation in class BookController. The method list is both empty and not marked with @Override

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.plugins.web.filters

➥ FilterConfigTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper227

[SRC]void setUp() {

[MSG]Violation in class FilterConfigTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper2135

[SRC]void tearDown() {

[MSG]Violation in class FilterConfigTests. The method tearDown() does not call super.tearDown()

UseAssertTrueInsteadOfAssertEquals380

[SRC]assert mockDefinition.generateNumberCalled == true

[MSG]The expression '(mockDefinition.generateNumberCalled == true)' can be simplified to 'mockDefinition.generateNumberCalled'

UseAssertTrueInsteadOfAssertEquals385

[SRC]assert mockDefinition.generateNumberCalled == true

[MSG]The expression '(mockDefinition.generateNumberCalled == true)' can be simplified to 'mockDefinition.generateNumberCalled'

UseAssertTrueInsteadOfAssertEquals390

[SRC]assert mockDefinition.generateNumberCalled == true

[MSG]The expression '(mockDefinition.generateNumberCalled == true)' can be simplified to 'mockDefinition.generateNumberCalled'

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.plugins.webflow

➥ MockWebFlowGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter329

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.webflow.MockWebFlowGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.binding

➥ BindingToNullableTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable248

[SRC]def model = controller.update()

[MSG]The variable [model] in class org.codehaus.groovy.grails.web.binding.BindingToNullableTests is not used

UnusedImport34

[SRC]import org.springframework.web.context.request.RequestContextHolder

[MSG]The [org.springframework.web.context.request.RequestContextHolder] import is never referenced

➥ DataBindingLazyMetaPropertyMapTests.groovy

Rule NamePriorityLine #Source Line / Message
CoupledTestCase223

[SRC]def map = new DataBindingLazyMetaPropertyMap(new Propert..er:"stuff"))

[MSG]new PropertyMapTest([name:Bart, age:11, other:stuff]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

➥ DataBindingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2185

[SRC]def error = b.errors.getFieldError('site')

[MSG]The variable [error] in class org.codehaus.groovy.grails.web.binding.DataBindingTests is not used

UnusedVariable2246

[SRC]def authorClass = ga.getDomainClass("databindingtests.Au..).getClazz()

[MSG]The variable [authorClass] in class org.codehaus.groovy.grails.web.binding.DataBindingTests is not used

UnnecessaryGetter3246

[SRC]def authorClass = ga.getDomainClass("databindingtests.Au..).getClazz()

[MSG]Violation in class org.codehaus.groovy.grails.web.binding.DataBindingTests. getClazz() can probably be rewritten as clazz

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.converters

➥ JSONArrayTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter312

[SRC]assertEquals(getJSONArray(), getJSONArray())

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONArrayTests. getJSONArray() can probably be rewritten as JSONArray

UnnecessaryGetter312

[SRC]assertEquals(getJSONArray(), getJSONArray())

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONArrayTests. getJSONArray() can probably be rewritten as JSONArray

UnnecessaryGetter317

[SRC]assertEquals(getJSONArray().hashCode(), getJSONArray().hashCode())

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONArrayTests. getJSONArray() can probably be rewritten as JSONArray

UnnecessaryGetter317

[SRC]assertEquals(getJSONArray().hashCode(), getJSONArray().hashCode())

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONArrayTests. getJSONArray() can probably be rewritten as JSONArray

➥ JSONConverterTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2100

[SRC]void onSetUp() {

[MSG]Violation in class JSONConverterTests. The method onSetUp is public but not a test method

UnnecessaryPackageReference382

[SRC]enumClass.metaClass.asType = {java.lang.Class clazz ->

[MSG]Specifying the package name is not necessary for java.lang.Class

➥ XMLConverterTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable292

[SRC]def proxy = [getHibernateLazyInitializer:{hibernateIniti..bernateProxy

[MSG]The variable [proxy] in class org.codehaus.groovy.grails.web.converters.XMLConverterTests is not used

JUnitPublicNonTestMethod2106

[SRC]void onSetUp() {

[MSG]Violation in class XMLConverterTests. The method onSetUp is public but not a test method

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.filters

➥ FilterToHandlerAdapterTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitUnnecessarySetUp316

[SRC]protected void setUp() {

[MSG]Violation in class FilterToHandlerAdapterTests. The setUp() method contains no logic and can be removed

UnnecessaryOverridingMethod316

[SRC]protected void setUp() {

[MSG]Violation in class FilterToHandlerAdapterTests. The method setUp contains no logic and can be safely deleted

JUnitUnnecessaryTearDown320

[SRC]protected void tearDown() {

[MSG]Violation in class FilterToHandlerAdapterTests. The tearDown() method contains no logic and can be removed

UnnecessaryOverridingMethod320

[SRC]protected void tearDown() {

[MSG]Violation in class FilterToHandlerAdapterTests. The method tearDown contains no logic and can be safely deleted

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.mapping

➥ DefaultUrlCreatorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper233

[SRC]void tearDown() {

[MSG]Violation in class DefaultUrlCreatorTests. The method tearDown() does not call super.tearDown()

➥ DoubleWildcardUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport35

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

UnnecessaryGetter372

[SRC]assertEquals 'wrong controller name', 'someOther', info...rollerName()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DoubleWildcardUrlMappingTests. getControllerName() can probably be rewritten as controllerName

➥ DynamicParameterValuesTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport35

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

➥ IdUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod226

[SRC]void onSetUp() {

[MSG]Violation in class IdUrlMappingTests. The method onSetUp is public but not a test method

UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport35

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

➥ RegexUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2357

[SRC]void testInit() {

[MSG]Violation in class RegexUrlMappingTests. Test method 'testInit' makes no assertions

UnusedVariable2359

[SRC]def m = new RegexUrlMapping(parser.parse("/(*)/hello"), ..vletContext)

[MSG]The variable [m] in class org.codehaus.groovy.grails.web.mapping.RegexUrlMappingTests is not used

UnusedImport36

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

UnnecessaryGetter372

[SRC]assertEquals "/x/y", info.getURI()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.RegexUrlMappingTests. getURI() can probably be rewritten as URI

UnnecessaryDotClass3308

[SRC]def cp = new ConstrainedProperty(RegexUrlMappingTests.cl..tring.class)

[MSG]RegexUrlMappingTests.class can be rewritten as RegexUrlMappingTests

UnnecessaryDotClass3308

[SRC]def cp = new ConstrainedProperty(RegexUrlMappingTests.cl..tring.class)

[MSG]String.class can be rewritten as String

UnnecessaryDotClass3325

[SRC]def cp = new ConstrainedProperty(RegexUrlMappingTests.cl..tring.class)

[MSG]RegexUrlMappingTests.class can be rewritten as RegexUrlMappingTests

UnnecessaryDotClass3325

[SRC]def cp = new ConstrainedProperty(RegexUrlMappingTests.cl..tring.class)

[MSG]String.class can be rewritten as String

➥ ResponseCodeUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport36

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport38

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

UnnecessaryDefInFieldDeclaration322

[SRC]def UrlMappingsHolder holder

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. The def keyword is unneeded when a field type is specified

UnnecessaryGetter359

[SRC]assertEquals("errors", info.getControllerName());

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. getControllerName() can probably be rewritten as controllerName

UnnecessaryGetter360

[SRC]assertEquals("error404", info.getActionName());

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. getActionName() can probably be rewritten as actionName

UnnecessaryGetter366

[SRC]assertEquals("errors", info.getControllerName());

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. getControllerName() can probably be rewritten as controllerName

UnnecessaryGetter367

[SRC]assertEquals("error500", info.getActionName());

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. getActionName() can probably be rewritten as actionName

➥ RestfulMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.validation.ConstrainedProperty;

[MSG]The [org.codehaus.groovy.grails.validation.ConstrainedProperty] import is never referenced

UnusedImport36

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

➥ RestfulReverseUrlRenderingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

➥ ReverseMappingWithDefaultActionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod211

[SRC]void onSetUp() {

[MSG]Violation in class ReverseMappingWithDefaultActionTests. The method onSetUp is public but not a test method

➥ UrlMappingParameterTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport34

[SRC]import org.springframework.core.io.ByteArrayResource

[MSG]The [org.springframework.core.io.ByteArrayResource] import is never referenced

UnusedImport35

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

➥ UrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.validation.ConstrainedProperty;

[MSG]The [org.codehaus.groovy.grails.validation.ConstrainedProperty] import is never referenced

➥ UrlMappingWithCustomValidatorTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInFieldDeclaration321

[SRC]def UrlMappingsHolder holder

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.UrlMappingWithCustomValidatorTests. The def keyword is unneeded when a field type is specified

➥ UrlMappingsHolderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.validation.ConstrainedProperty;

[MSG]The [org.codehaus.groovy.grails.validation.ConstrainedProperty] import is never referenced

➥ ViewUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInFieldDeclaration320

[SRC]def UrlMappingsHolder holder

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ViewUrlMappingTests. The def keyword is unneeded when a field type is specified

UnnecessaryGetter340

[SRC]assertEquals "book.gsp", info.getViewName()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ViewUrlMappingTests. getViewName() can probably be rewritten as viewName

UnnecessaryGetter347

[SRC]assertEquals "book.gsp", info.getViewName()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ViewUrlMappingTests. getViewName() can probably be rewritten as viewName

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.mapping.filter

➥ RestfulMappingsFilterTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport37

[SRC]import org.codehaus.groovy.grails.commons.ControllerArtefactHandler;

[MSG]The [org.codehaus.groovy.grails.commons.ControllerArtefactHandler] import is never referenced

UnusedImport38

[SRC]import org.codehaus.groovy.grails.commons.DefaultGrailsApplication

[MSG]The [org.codehaus.groovy.grails.commons.DefaultGrailsApplication] import is never referenced

UnnecessaryGetter352

[SRC]def mappings = evaluator.evaluateMappings(new ByteArrayR..getBytes()))

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.filter.RestfulMappingsFilterTests. getBytes() can probably be rewritten as bytes

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.mime

➥ AcceptHeaderParserTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper213

[SRC]protected void setUp() {

[MSG]Violation in class AcceptHeaderParserTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper230

[SRC]protected void tearDown() {

[MSG]Violation in class AcceptHeaderParserTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.pages

➥ GroovyPageBindingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter315

[SRC]assertEquals binding.getMetaClass(), binding.metaClass

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageBindingTests. getMetaClass() can probably be rewritten as metaClass

UnnecessaryGetter326

[SRC]assertEquals(shouldbe, binding.getVariables())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageBindingTests. getVariables() can probably be rewritten as variables

UnnecessaryGetter328

[SRC]for(e in binding.getVariables().entrySet()) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageBindingTests. getVariables() can probably be rewritten as variables

➥ GroovyPageLineNumberTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert214

[SRC]void testSpanningMultipleLines() {

[MSG]Violation in class GroovyPageLineNumberTests. Test method 'testSpanningMultipleLines' makes no assertions

➥ GroovyPageMethodDispatchWithNamespaceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod28

[SRC]void onSetUp() {

[MSG]Violation in class GroovyPageMethodDispatchWithNamespaceTests. The method onSetUp is public but not a test method

➥ GroovyPageTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod267

[SRC]def runPageCode(pageCode) {

[MSG]Violation in class GroovyPageTests. The method runPageCode is public but not a test method

JUnitPublicNonTestMethod2146

[SRC]def getBinding(out) {

[MSG]Violation in class GroovyPageTests. The method getBinding is public but not a test method

UnnecessaryGetter3157

[SRC]binding.setVariable(GroovyPage.SESSION, request.getSession())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageTests. getSession() can probably be rewritten as session

UnnecessaryObjectReferences3160

[SRC]binding.setVariable(GroovyPage.OUT, out)

[MSG]The code could be more concise by using a with() or identity() block

➥ GroovyPagesTemplateEngineTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2188

[SRC]def webRequest = GrailsWebUtil.bindMockWebRequest()

[MSG]The variable [webRequest] in class org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngineTests is not used

JUnitTearDownCallsSuper2570

[SRC]void tearDown() {

[MSG]Violation in class GroovyPagesTemplateEngineTests. The method tearDown() does not call super.tearDown()

JUnitSetUpCallsSuper2574

[SRC]void setUp() {

[MSG]Violation in class GroovyPagesTemplateEngineTests. The method setUp() does not call super.setUp()

UnusedImport38

[SRC]import org.codehaus.groovy.grails.plugins.MockGrailsPluginManager;

[MSG]The [org.codehaus.groovy.grails.plugins.MockGrailsPluginManager] import is never referenced

UseAssertEqualsInsteadOfAssertTrue340

[SRC]assertTrue(sw.toString().indexOf("should not be in the output") == -1)

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngineTests. Replace assertTrue with a call to assertEquals()

➥ GroovyPagesWhitespaceParsingTagTests.groovy

Rule NamePriorityLine #Source Line / Message
ComparisonOfTwoConstants229

[SRC]test="${2 > 1}">rejoice</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants236

[SRC]<g:if test="${2 > 1}">rejoice</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants246

[SRC]<g:if test="${2 > 1}">testing</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants259

[SRC]<g:if test="${2 > 1}">testing</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants271

[SRC]def template = """Hello <g:if test="${2 > 1}">one</g:if>..ee</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants271

[SRC]def template = """Hello <g:if test="${2 > 1}">one</g:if>..ee</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants271

[SRC]def template = """Hello <g:if test="${2 > 1}">one</g:if>..ee</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants277

[SRC]def template = """Hello <g:if test="${2 > 1}">one</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants278

[SRC]<g:if test="${2 > 1}">two</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants279

[SRC]<g:if test="${2 > 1}">three</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

➥ ModifyOurScopeWithBodyTagTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport35

[SRC]import junit.framework.TestCase

[MSG]The [junit.framework.TestCase] import is never referenced

➥ StaticContentRenderingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport34

[SRC]import org.codehaus.groovy.grails.commons.ConfigurationHolder

[MSG]The [org.codehaus.groovy.grails.commons.ConfigurationHolder] import is never referenced

➥ TagLibNamespaceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod222

[SRC]void onTearDown() {

[MSG]Violation in class TagLibNamespaceTests. The method onTearDown is public but not a test method

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.pages.ext.jsp

➥ GroovyPageWithJSPTagsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter322

[SRC]def rootLoader = new RootLoader([] as URL[], Thread.curr..assLoader())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPageWithJSPTagsTests. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter324

[SRC]rootLoader.addURL res.getURL()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPageWithJSPTagsTests. getURL() can probably be rewritten as URL

UnnecessaryGetter326

[SRC]rootLoader.addURL it.getURL()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPageWithJSPTagsTests. getURL() can probably be rewritten as URL

UnnecessaryGetter330

[SRC]webRequest.getCurrentRequest().setAttribute(GroovyPagesS..esServlet())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPageWithJSPTagsTests. getCurrentRequest() can probably be rewritten as currentRequest

➥ GroovyPagesPageContextTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper213

[SRC]protected void setUp() {

[MSG]Violation in class GroovyPagesPageContextTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper217

[SRC]protected void tearDown() {

[MSG]Violation in class GroovyPagesPageContextTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter325

[SRC]assert pageContext.getServletConfig()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getServletConfig() can probably be rewritten as servletConfig

UnnecessaryGetter326

[SRC]assert pageContext.getServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter327

[SRC]assert pageContext.getRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getRequest() can probably be rewritten as request

UnnecessaryGetter328

[SRC]assert pageContext.getResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getResponse() can probably be rewritten as response

UnnecessaryGetter329

[SRC]assert pageContext.getPage()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getPage() can probably be rewritten as page

➥ IterativeJspTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper221

[SRC]protected void setUp() {

[MSG]Violation in class IterativeJspTagTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper226

[SRC]protected void tearDown() {

[MSG]Violation in class IterativeJspTagTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter323

[SRC]webRequest.getCurrentRequest().setAttribute(GroovyPagesS..esServlet())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter334

[SRC]def rootLoader = new RootLoader([] as URL[], Thread.curr..assLoader())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter336

[SRC]rootLoader.addURL res.getURL()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getURL() can probably be rewritten as URL

UnnecessaryGetter352

[SRC]JstlUtils.exposeLocalizationContext webRequest.getRequest(),null

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getRequest() can probably be rewritten as request

UnnecessaryGetter355

[SRC]def pageContext = PageContextFactory.getCurrent()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getCurrent() can probably be rewritten as current

➥ MockRootLoaderTagLibraryResolver.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter315

[SRC]def rootLoader = new RootLoader([] as URL[], Thread.curr..assLoader())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockRootLoaderTagLibraryResolver. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter317

[SRC]rootLoader.addURL res.getURL()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockRootLoaderTagLibraryResolver. getURL() can probably be rewritten as URL

➥ SimpleJspTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper222

[SRC]protected void setUp() {

[MSG]Violation in class SimpleJspTagTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper227

[SRC]protected void tearDown() {

[MSG]Violation in class SimpleJspTagTests. The method tearDown() does not call super.tearDown()

UnusedImport39

[SRC]import org.springframework.core.io.FileSystemResource

[MSG]The [org.springframework.core.io.FileSystemResource] import is never referenced

UnnecessaryGetter324

[SRC]webRequest.getCurrentRequest().setAttribute(GroovyPagesS..esServlet())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.SimpleJspTagTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter347

[SRC]JstlUtils.exposeLocalizationContext webRequest.getRequest(),null

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.SimpleJspTagTests. getRequest() can probably be rewritten as request

➥ SimpleTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper221

[SRC]protected void setUp() {

[MSG]Violation in class SimpleTagTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper226

[SRC]protected void tearDown() {

[MSG]Violation in class SimpleTagTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter323

[SRC]webRequest.getCurrentRequest().setAttribute(GroovyPagesS..esServlet())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.SimpleTagTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter361

[SRC]getJspContext().getOut().println("extendsSimpleTagSupport:output");

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.ExtendsSimpleTagSupport. getOut() can probably be rewritten as out

UnnecessaryGetter361

[SRC]getJspContext().getOut().println("extendsSimpleTagSupport:output");

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.ExtendsSimpleTagSupport. getJspContext() can probably be rewritten as jspContext

UnnecessaryGetter368

[SRC]JspWriter out = getJspContext().getOut()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.BodySimpleTagSupport. getOut() can probably be rewritten as out

UnnecessaryGetter368

[SRC]JspWriter out = getJspContext().getOut()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.BodySimpleTagSupport. getJspContext() can probably be rewritten as jspContext

UnnecessaryGetter370

[SRC]super.getJspBody().invoke(out)

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.BodySimpleTagSupport. getJspBody() can probably be rewritten as jspBody

➥ TagLibraryResolverTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter365

[SRC]new RootLoader([] as URL[], Thread.currentThread().getCo..assLoader())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockWebXmlTagLibraryResolver. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter372

[SRC]new ByteArrayResource('''<?xml version="1.0" encoding="UTF-8"?>

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockWebXmlTagLibraryResolver. getInputStream() can probably be rewritten as inputStream

UnnecessaryGetter372

[SRC]new ByteArrayResource('''<?xml version="1.0" encoding="UTF-8"?>

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockWebXmlTagLibraryResolver. getBytes() can probably be rewritten as bytes

UnnecessaryGetter3118

[SRC]new ByteArrayResource('''<?xml version="1.0" encoding="UTF-8"?>

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockWebXmlTagLibraryResolver. getBytes() can probably be rewritten as bytes

➥ TldReaderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter328

[SRC]def is = new InputSource(res.getInputStream())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReaderTests. getInputStream() can probably be rewritten as inputStream

UnnecessaryGetter333

[SRC]def reader = factory.newSAXParser().getXMLReader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReaderTests. getXMLReader() can probably be rewritten as XMLReader

➥ WebXmlTagLibraryReaderTests.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSamePackage320

[SRC]import org.codehaus.groovy.grails.web.pages.ext.jsp.WebX..ibraryReader

UnnecessaryGetter331

[SRC]def reader = factory.newSAXParser().getXMLReader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReaderTests. getXMLReader() can probably be rewritten as XMLReader

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.servlet.view

➥ GroovyPageViewTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper245

[SRC]void tearDown() {

[MSG]Violation in class GroovyPageViewTests. The method tearDown() does not call super.tearDown()

DuplicateImport37

[SRC]import org.springframework.web.context.request.*

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.taglib

➥ ApplicationTagLibResourcesTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod221

[SRC]void onInitMockBeans() {

[MSG]Violation in class ApplicationTagLibResourcesTests. The method onInitMockBeans is public but not a test method

JUnitPublicNonTestMethod225

[SRC]def replaceMetaClass(Object o) {

[MSG]Violation in class ApplicationTagLibResourcesTests. The method replaceMetaClass is public but not a test method

UnusedImport33

[SRC]import grails.util.GrailsUtil

[MSG]The [grails.util.GrailsUtil] import is never referenced

UnusedImport35

[SRC]import javax.servlet.http.Cookie

[MSG]The [javax.servlet.http.Cookie] import is never referenced

UnusedImport37

[SRC]import groovy.mock.interceptor.StubFor

[MSG]The [groovy.mock.interceptor.StubFor] import is never referenced

UnusedImport39

[SRC]import org.codehaus.groovy.grails.commons.ConfigurationHolder

[MSG]The [org.codehaus.groovy.grails.commons.ConfigurationHolder] import is never referenced

UnusedImport311

[SRC]import org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib;

[MSG]The [org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib] import is never referenced

UnusedImport312

[SRC]import org.codehaus.groovy.grails.web.pages.GroovyPageBinding

[MSG]The [org.codehaus.groovy.grails.web.pages.GroovyPageBinding] import is never referenced

UnusedImport313

[SRC]import org.codehaus.groovy.grails.web.servlet.GrailsAppl..onAttributes

[MSG]The [org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes] import is never referenced

UnusedImport314

[SRC]import org.codehaus.groovy.grails.web.taglib.exceptions...TagException

[MSG]The [org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException] import is never referenced

UnusedImport316

[SRC]import org.codehaus.groovy.grails.commons.TagLibArtefactHandler

[MSG]The [org.codehaus.groovy.grails.commons.TagLibArtefactHandler] import is never referenced

UnusedImport317

[SRC]import org.springframework.mock.web.MockHttpServletResponse

[MSG]The [org.springframework.mock.web.MockHttpServletResponse] import is never referenced

UnnecessaryDotClass340

[SRC]def taglib = appCtx.getBean(ApplicationTagLib.class.name)

[MSG]ApplicationTagLib.class can be rewritten as ApplicationTagLib

UnnecessaryDotClass360

[SRC]def taglib = appCtx.getBean(ApplicationTagLib.class.name)

[MSG]ApplicationTagLib.class can be rewritten as ApplicationTagLib

➥ ApplicationTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport37

[SRC]import groovy.mock.interceptor.StubFor

[MSG]The [groovy.mock.interceptor.StubFor] import is never referenced

UnusedImport315

[SRC]import org.codehaus.groovy.grails.commons.TagLibArtefactHandler

[MSG]The [org.codehaus.groovy.grails.commons.TagLibArtefactHandler] import is never referenced

UnnecessaryGetter323

[SRC]assertOutputEquals "/test/plugins/controllers-${GrailsUt..g", template

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.ApplicationTagLibTests. getGrailsVersion() can probably be rewritten as grailsVersion

➥ CoreTagsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import grails.util.GrailsUtil

[MSG]The [grails.util.GrailsUtil] import is never referenced

➥ CountryTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod288

[SRC]void assertResultContains(result, expectedSubstring) {

[MSG]Violation in class CountryTagLibTests. The method assertResultContains is public but not a test method

➥ FormRenderingTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod226

[SRC]void assertOutputEquals(expected, template, params = [:]) {

[MSG]Violation in class FormRenderingTagLibTests. The method assertOutputEquals is public but not a test method

➥ FormTagLib2Tests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField216

[SRC]private static final def SELECT_TAG_NAME = "testSelect"

[MSG]The field SELECT_TAG_NAME is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests

JUnitTestMethodWithoutAssert223

[SRC]void testDatePickerTagWithDefaultDateAndPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithDefaultDateAndPrecision' makes no assertions

JUnitTestMethodWithoutAssert227

[SRC]void testDatePickerTagWithYearPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithYearPrecision' makes no assertions

JUnitTestMethodWithoutAssert231

[SRC]void testDatePickerTagWithMonthPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithMonthPrecision' makes no assertions

JUnitTestMethodWithoutAssert235

[SRC]void testDatePickerTagWithDayPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithDayPrecision' makes no assertions

JUnitTestMethodWithoutAssert239

[SRC]void testDatePickerTagWithHourPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithHourPrecision' makes no assertions

JUnitTestMethodWithoutAssert243

[SRC]void testDatePickerTagWithMinutePrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithMinutePrecision' makes no assertions

JUnitTestMethodWithoutAssert247

[SRC]void testDatePickerTagWithCustomDate() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithCustomDate' makes no assertions

JUnitTestMethodWithoutAssert274

[SRC]void testDatePickerTagWithCustomDateAndPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithCustomDateAndPrecision' makes no assertions

UnusedVariable2121

[SRC]String xp

[MSG]The variable [xp] in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests is not used

UnusedPrivateMethod2230

[SRC]private void assertSelectFieldPresentWithValue(Document ..ing value) {

[MSG]The method assertSelectFieldPresentWithValue is not used within FormTagLib2Tests.groovy

UnusedPrivateMethod2236

[SRC]private void assertSelectFieldPresentWithValueAndText(Do..ing label) {

[MSG]The method assertSelectFieldPresentWithValueAndText is not used within FormTagLib2Tests.groovy

UnusedPrivateMethod2248

[SRC]private void assertSelectPresent(Document document, Stri..fieldName) {

[MSG]The method assertSelectPresent is not used within FormTagLib2Tests.groovy

UnnecessaryDefInFieldDeclaration316

[SRC]private static final def SELECT_TAG_NAME = "testSelect"

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests. The def keyword is unneeded when a field is marked private

UnnecessaryGetter352

[SRC]def defaultDate = Calendar.getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests. getInstance() can probably be rewritten as instance

UnnecessaryGetter354

[SRC]Document document = getDatePickerOutput(null, 'day', def..e.getTime())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests. getTime() can probably be rewritten as time

UnnecessaryGetter369

[SRC]DateFormat defaultFormat = DateFormat.getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests. getInstance() can probably be rewritten as instance

➥ FormTagLib3Tests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField217

[SRC]private static final String DATE_PICKER_TAG_NAME = "testDatePicker"

[MSG]The field DATE_PICKER_TAG_NAME is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnusedPrivateField219

[SRC]private static final Collection DATE_PRECISIONS_INCLUDIN..s String[]))

[MSG]The field DATE_PRECISIONS_INCLUDING_MINUTE is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnusedPrivateField220

[SRC]private static final Collection DATE_PRECISIONS_INCLUDIN..s String[]))

[MSG]The field DATE_PRECISIONS_INCLUDING_HOUR is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnusedPrivateField221

[SRC]private static final Collection DATE_PRECISIONS_INCLUDIN..s String[]))

[MSG]The field DATE_PRECISIONS_INCLUDING_DAY is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnusedPrivateField222

[SRC]private static final Collection DATE_PRECISIONS_INCLUDIN..s String[]))

[MSG]The field DATE_PRECISIONS_INCLUDING_MONTH is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnnecessaryGetter3207

[SRC]final Element inputElement = document.getDocumentElement()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests. getDocumentElement() can probably be rewritten as documentElement

UnnecessaryGetter3233

[SRC]final Element inputElement = document.getDocumentElement()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests. getDocumentElement() can probably be rewritten as documentElement

UnnecessaryGetter3262

[SRC]final Element inputElement = document.getDocumentElement()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests. getDocumentElement() can probably be rewritten as documentElement

UnnecessaryGetter3288

[SRC]final Element inputElement = document.getDocumentElement()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests. getDocumentElement() can probably be rewritten as documentElement

➥ FormTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2234

[SRC]void testBooleanAttributes() {

[MSG]Violation in class FormTagLibTests. Test method 'testBooleanAttributes' makes no assertions

➥ FormatTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter332

[SRC]assertOutputEquals("1980-02-03", template, [date:calender.getTime()])

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormatTagLibTests. getTime() can probably be rewritten as time

UnnecessaryGetter338

[SRC]assertOutputEquals("February 3, 1980", template, [date:c...getTime()])

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormatTagLibTests. getTime() can probably be rewritten as time

UnnecessaryGetter344

[SRC]assertOutputEquals("February 3, 1980 12:00 AM", template...getTime()])

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormatTagLibTests. getTime() can probably be rewritten as time

UnnecessaryGetter379

[SRC]assertOutputEquals("1980-02-03", template, [date:calender.getTime()])

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormatTagLibTests. getTime() can probably be rewritten as time

➥ GroovyEachTagTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.taglib.exceptions...TagException

[MSG]The [org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException] import is never referenced

UnnecessaryGetter321

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyEachTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter321

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyEachTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter337

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyEachTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter337

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyEachTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

➥ GroovyFindAllTagTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGroovyImport33

[SRC]import java.io.ByteArrayInputStream

UnnecessaryGroovyImport34

[SRC]import java.io.PrintWriter

UnnecessaryGroovyImport35

[SRC]import java.util.HashMap

UnnecessaryGroovyImport36

[SRC]import java.util.Map

UnnecessaryDotClass325

[SRC]context.put(GroovyPageParser.class, parser);

[MSG]GroovyPageParser.class can be rewritten as GroovyPageParser

UnnecessaryGetter355

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in eval...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyFindAllTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter355

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in eval...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyFindAllTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter364

[SRC]assertEquals("findAll", tag.getName())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyFindAllTagTests. getName() can probably be rewritten as name

➥ GroovyGrepTagTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock215

[SRC]catch(Exception e) {

[MSG]The catch block is empty

UnnecessaryGetter323

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyGrepTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter323

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyGrepTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

➥ GroovySyntaxTagTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod256

[SRC]void doEndTag() {}

[MSG]Violation in class MyGroovySyntaxTag. The method doEndTag is both empty and not marked with @Override

EmptyMethod258

[SRC]void doStartTag() {}

[MSG]Violation in class MyGroovySyntaxTag. The method doStartTag is both empty and not marked with @Override

➥ InvokeTagLibAsMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod25

[SRC]void onSetUp() {

[MSG]Violation in class InvokeTagLibAsMethodTests. The method onSetUp is public but not a test method

➥ JavascriptTagLibResourcesTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod27

[SRC]def replaceMetaClass(o) {

[MSG]Violation in class JavascriptTagLibResourcesTests. The method replaceMetaClass is public but not a test method

JUnitPublicNonTestMethod218

[SRC]void onInitMockBeans() {

[MSG]Violation in class JavascriptTagLibResourcesTests. The method onInitMockBeans is public but not a test method

UnusedVariable272

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.taglib.JavascriptTagLibResourcesTests is not used

➥ JavascriptTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable246

[SRC]String newLine = EOL

[MSG]The variable [newLine] in class org.codehaus.groovy.grails.web.taglib.JavascriptTagLibTests is not used

JUnitPublicNonTestMethod293

[SRC]def replaceMetaClass(Object o) {

[MSG]Violation in class JavascriptTagLibTests. The method replaceMetaClass is public but not a test method

JUnitPublicNonTestMethod2287

[SRC]def setRequestContext() {

[MSG]Violation in class JavascriptTagLibTests. The method setRequestContext is public but not a test method

JUnitPublicNonTestMethod2291

[SRC]def setRequestContext(path) {

[MSG]Violation in class JavascriptTagLibTests. The method setRequestContext is public but not a test method

JUnitPublicNonTestMethod2295

[SRC]def setupPluginController(tag) {

[MSG]Violation in class JavascriptTagLibTests. The method setupPluginController is public but not a test method

UnusedMethodParameter2295

[SRC]def setupPluginController(tag) {

[MSG]Violation in class JavascriptTagLibTests. Method parameter [tag] is never referenced in the method setupPluginController of class org.codehaus.groovy.grails.web.taglib.JavascriptTagLibTests

UnusedMethodParameter2312

[SRC]def doRemoteFunction(Object taglib, Object attrs, Object out) {

[MSG]Violation in class TestProvider. Method parameter [taglib] is never referenced in the method doRemoteFunction of class org.codehaus.groovy.grails.web.taglib.TestProvider

UnusedMethodParameter2312

[SRC]def doRemoteFunction(Object taglib, Object attrs, Object out) {

[MSG]Violation in class TestProvider. Method parameter [attrs] is never referenced in the method doRemoteFunction of class org.codehaus.groovy.grails.web.taglib.TestProvider

EmptyMethod2316

[SRC]def prepareAjaxForm(Object attrs) {}

[MSG]Violation in class TestProvider. The method prepareAjaxForm is both empty and not marked with @Override

UnusedMethodParameter2316

[SRC]def prepareAjaxForm(Object attrs) {}

[MSG]Violation in class TestProvider. Method parameter [attrs] is never referenced in the method prepareAjaxForm of class org.codehaus.groovy.grails.web.taglib.TestProvider

UnusedImport313

[SRC]import org.codehaus.groovy.grails.commons.TagLibArtefactHandler

[MSG]The [org.codehaus.groovy.grails.commons.TagLibArtefactHandler] import is never referenced

UnnecessaryGetter352

[SRC]def grailsVersion = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.JavascriptTagLibTests. getGrailsVersion() can probably be rewritten as grailsVersion

➥ LayoutWriterStackTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod245

[SRC]void assertEqualsIgnoreWhiteSpace(String s1, String s2) {

[MSG]Violation in class LayoutWriterStackTests. The method assertEqualsIgnoreWhiteSpace is public but not a test method

➥ LinkRenderingTagLib2Tests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod238

[SRC]void assertOutputEquals(expected, template, params = [:]) {

[MSG]Violation in class LinkRenderingTagLib2Tests. The method assertOutputEquals is public but not a test method

UnusedImport33

[SRC]import org.codehaus.groovy.runtime.InvokerHelper

[MSG]The [org.codehaus.groovy.runtime.InvokerHelper] import is never referenced

➥ LinkRenderingTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
DuplicateMapKey246

[SRC]assertOutputEquals '<a href="/demo" class="B">demo</a>',..'7', x: '4']

[MSG]Key 'x' is duplicated.

UnusedImport33

[SRC]import org.codehaus.groovy.runtime.InvokerHelper

[MSG]The [org.codehaus.groovy.runtime.InvokerHelper] import is never referenced

➥ NamespacedTagLibMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport34

[SRC]import org.springframework.validation.MapBindingResult

[MSG]The [org.springframework.validation.MapBindingResult] import is never referenced

➥ PluginTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter313

[SRC]def grailsVersion = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.PluginTagLibTests. getGrailsVersion() can probably be rewritten as grailsVersion

➥ PropertyEditorTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall384

[SRC]assertEquals(["grails", "groovy"], obj.tags.collect {it.name})

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.PropertyEditorTests. The call to collect could probably be rewritten as a spread expression: obj.tags*.name

UnnecessaryGetter3119

[SRC]Object v = getValue()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.TestCustomPropertyEditor. getValue() can probably be rewritten as value

➥ RenderTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert241

[SRC]void testPaginateTag() {

[MSG]Violation in class RenderTagLibTests. Test method 'testPaginateTag' makes no assertions

UnusedVariable2103

[SRC]def head = ""

[MSG]The variable [head] in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests is not used

JUnitTestMethodWithoutAssert2205

[SRC]void testSortableColumnTag() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTag' makes no assertions

JUnitTestMethodWithoutAssert2219

[SRC]void testSortableColumnTagWithTitleKey() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagWithTitleKey' makes no assertions

JUnitTestMethodWithoutAssert2265

[SRC]void testSortableColumnTagWithAction() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagWithAction' makes no assertions

JUnitTestMethodWithoutAssert2279

[SRC]void testSortableColumnTagWithDefaultOrder() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagWithDefaultOrder' makes no assertions

JUnitTestMethodWithoutAssert2323

[SRC]void testSortableColumnTagWithAdditionalAttributes() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagWithAdditionalAttributes' makes no assertions

JUnitTestMethodWithoutAssert2338

[SRC]void testSortableColumnTagSorted() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagSorted' makes no assertions

JUnitPublicNonTestMethod2422

[SRC]void checkTagOutput(output, expectedClassValue, expected..edContent) {

[MSG]Violation in class RenderTagLibTests. The method checkTagOutput is public but not a test method

JUnitPublicNonTestMethod2463

[SRC]void checkTagOutput(output, expectedClassValue, expected..therAttrs) {

[MSG]Violation in class RenderTagLibTests. The method checkTagOutput is public but not a test method

UnnecessaryGetter3347

[SRC]webRequest.getParams().put("sort", "title")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3348

[SRC]webRequest.getParams().put("order", "asc")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3364

[SRC]webRequest.getParams().put("sort", "title")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3365

[SRC]webRequest.getParams().put("order", "desc")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3381

[SRC]webRequest.getParams().put("sort", "price")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3382

[SRC]webRequest.getParams().put("order", "desc")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3398

[SRC]webRequest.getParams().put("sort", "price")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3399

[SRC]webRequest.getParams().put("order", "desc")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3553

[SRC]assertEquals 'my/contenttype', response.getContentType()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getContentType() can probably be rewritten as contentType

UseAssertNullInsteadOfAssertEquals3557

[SRC]assertEquals null, response.getContentType()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. assertEquals can be simplified using assertNull

UnnecessaryGetter3557

[SRC]assertEquals null, response.getContentType()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getContentType() can probably be rewritten as contentType

UnnecessaryGetter3560

[SRC]assertEquals 'my/contenttype', response.getContentType()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getContentType() can probably be rewritten as contentType

➥ ReturnValueTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod24

[SRC]void onSetUp() {

[MSG]Violation in class ReturnValueTagLibTests. The method onSetUp is public but not a test method

➥ SelectTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2255

[SRC]void testMultipleSelect() {

[MSG]Violation in class SelectTagTests. Test method 'testMultipleSelect' makes no assertions

JUnitTestMethodWithoutAssert2267

[SRC]void testMultipleSelectWithObjectValues() {

[MSG]Violation in class SelectTagTests. Test method 'testMultipleSelectWithObjectValues' makes no assertions

JUnitPublicNonTestMethod2281

[SRC]void checkMultiSelect(List categories, List selected, Cl..sSelected) {

[MSG]Violation in class SelectTagTests. The method checkMultiSelect is public but not a test method

UnusedPrivateMethod2370

[SRC]private void assertSelectFieldNotPresent(Document docume..fieldName) {

[MSG]The method assertSelectFieldNotPresent is not used within SelectTagTests.groovy

UnnecessaryParenthesesForMethodCallWithClosure3136

[SRC]range.each() {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3154

[SRC]range.each() {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3201

[SRC]range.each() {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3227

[SRC]categoryMap.each() { value, text ->

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3233

[SRC]categoryMap.each() { value, text ->

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3250

[SRC]categoryMap.each() { value, text ->

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3306

[SRC]categories.each() { cat ->

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

➥ ValidationTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences3214

[SRC]b.publisherURL = new URL("http://canoo.com/gia")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3215

[SRC]b.releaseDate = new Date()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3216

[SRC]b.usPrice = 10.99

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.webflow

➥ FlowCommandObjectsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod287

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowCommandObjectsTests. The method getFlowClosure is public but not a test method

UnusedImport34

[SRC]import org.springframework.webflow.definition.FlowDefinition

[MSG]The [org.springframework.webflow.definition.FlowDefinition] import is never referenced

UnusedImport35

[SRC]import org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder

[MSG]The [org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder] import is never referenced

UnusedImport36

[SRC]import org.springframework.webflow.context.servlet.Servl..ernalContext

[MSG]The [org.springframework.webflow.context.servlet.ServletExternalContext] import is never referenced

UnnecessaryGetter323

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowCommandObjectsTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter351

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowCommandObjectsTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter374

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowCommandObjectsTests. getFlowScope() can probably be rewritten as flowScope

➥ FlowRedirectTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod252

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowRedirectTests. The method getFlowClosure is public but not a test method

UnusedImport310

[SRC]import org.springframework.webflow.definition.FlowDefinition

[MSG]The [org.springframework.webflow.definition.FlowDefinition] import is never referenced

UnnecessaryGetter323

[SRC]assertEquals "contextRelative:/test/foo",context.getExte..edirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowRedirectTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

UnnecessaryGetter332

[SRC]assertEquals "contextRelative:/test/foo/1",context.getEx..edirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowRedirectTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

UnnecessaryGetter344

[SRC]assertEquals "contextRelative:/mycontroller/foo",context..edirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowRedirectTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

➥ FlowTagInvokationTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod233

[SRC]void onInit() {

[MSG]Violation in class FlowTagInvokationTests. The method onInit is public but not a test method

JUnitPublicNonTestMethod242

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowTagInvokationTests. The method getFlowClosure is public but not a test method

UnusedImport34

[SRC]import org.springframework.webflow.definition.FlowDefinition

[MSG]The [org.springframework.webflow.definition.FlowDefinition] import is never referenced

UnusedImport35

[SRC]import org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder

[MSG]The [org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder] import is never referenced

UnnecessaryGetter320

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowTagInvokationTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter329

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowTagInvokationTests. getFlowScope() can probably be rewritten as flowScope

➥ SubflowExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod229

[SRC]Closure getFlowClosure() {

[MSG]Violation in class SubflowExecutionTests. The method getFlowClosure is public but not a test method

➥ SubflowExecutionWithExternalSubflowTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod221

[SRC]Closure getFlowClosure() {

[MSG]Violation in class SubflowExecutionWithExternalSubflowTests. The method getFlowClosure is public but not a test method

UnusedImport33

[SRC]import junit.framework.TestCase

[MSG]The [junit.framework.TestCase] import is never referenced

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.webflow.engine.builder

➥ FlowBuilderDecisionExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod210

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderDecisionExecutionTests. The method getFlowClosure is public but not a test method

➥ FlowBuilderDynamicTransitionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod233

[SRC]String getFlowId() { "myFlow" }

[MSG]Violation in class FlowBuilderDynamicTransitionTests. The method getFlowId is public but not a test method

JUnitPublicNonTestMethod235

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderDynamicTransitionTests. The method getFlowClosure is public but not a test method

UnnecessaryGetter312

[SRC]def startState = flowDefinition.getStartState()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderDynamicTransitionTests. getStartState() can probably be rewritten as startState

➥ FlowBuilderExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod210

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderExecutionTests. The method getFlowClosure is public but not a test method

UnnecessaryGetter341

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderExecutionTests. getFlowScope() can probably be rewritten as flowScope

➥ FlowBuilderSubFlowExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod229

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderSubFlowExecutionTests. The method getFlowClosure is public but not a test method

JUnitPublicNonTestMethod259

[SRC]def foo() { "bar" }

[MSG]Violation in class FlowBuilderSubFlowExecutionTests. The method foo is public but not a test method

UnnecessaryGetter373

[SRC]def theFlow = getFlowDefinition()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderSubFlowExecutionTests. getFlowDefinition() can probably be rewritten as flowDefinition

➥ FlowBuilderSubFlowExecutionWithInputOuputTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod247

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderSubFlowExecutionWithInputOuputTests. The method getFlowClosure is public but not a test method

UnusedVariable289

[SRC]GrailsWebRequest webrequest = grails.util.GrailsWebUtil...WebRequest()

[MSG]The variable [webrequest] in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderSubFlowExecutionWithInputOuputTests is not used

EmptyCatchBlock2124

[SRC]catch (FlowInputMappingException e) {}

[MSG]The catch block is empty

➥ FlowBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper216

[SRC]void setUp() {

[MSG]Violation in class FlowBuilderTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper226

[SRC]void tearDown() {

[MSG]Violation in class FlowBuilderTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter323

[SRC]flowBuilderServices.expressionParser = DefaultExpression..sionParser()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderTests. getExpressionParser() can probably be rewritten as expressionParser

UnnecessaryGetter3154

[SRC]def flow = new FlowBuilder("myFlow",getFlowBuilderServic..pl()).flow {

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderTests. getFlowBuilderServices() can probably be rewritten as flowBuilderServices

➥ FlowBuilderTransitionCriteriaTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod27

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderTransitionCriteriaTests. The method getFlowClosure is public but not a test method

➥ RuntimeRedirectActionTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter327

[SRC]context.getFlowScope().put("id", "1")

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectActionTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter329

[SRC]assert "contextRelative:/book/show/1" == ext.getExternalRedirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectActionTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

UnnecessaryGetter331

[SRC]context.getFlowScope().put("id", "2")

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectActionTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter333

[SRC]assert "contextRelative:/book/show/2" == ext.getExternalRedirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectActionTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.webflow.support

➥ AbstractGrailsTagAwareFlowExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper264

[SRC]final void setUp() throws Exception {

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper2138

[SRC]final void tearDown() {

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method tearDown() does not call super.tearDown()

JUnitPublicNonTestMethod2158

[SRC]FlowDefinition registerFlow(String flowId, Closure flowClosure) {

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method registerFlow is public but not a test method

JUnitPublicNonTestMethod2167

[SRC]FlowDefinition getFlowDefinition() {

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method getFlowDefinition is public but not a test method

JUnitPublicNonTestMethod2175

[SRC]String getFlowId() { 'testFlow' }

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method getFlowId is public but not a test method

JUnitPublicNonTestMethod2177

[SRC]abstract Closure getFlowClosure()

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method getFlowClosure is public but not a test method

UnusedImport315

[SRC]import org.codehaus.groovy.runtime.InvokerHelper

[MSG]The [org.codehaus.groovy.runtime.InvokerHelper] import is never referenced

UnusedImport340

[SRC]import org.springframework.webflow.definition.registry.F..itionLocator

[MSG]The [org.springframework.webflow.definition.registry.FlowDefinitionLocator] import is never referenced

UnnecessaryGetter3111

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3120

[SRC]flowBuilderServices.expressionParser = DefaultExpression..sionParser()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getExpressionParser() can probably be rewritten as expressionParser

UnnecessaryGetter3159

[SRC]FlowBuilder builder = new FlowBuilder(flowId, flowClosur..nRegistry())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowDefinitionRegistry() can probably be rewritten as flowDefinitionRegistry

UnnecessaryGetter3162

[SRC]FlowAssembler assembler = new FlowAssembler(builder, bui..erContext())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowBuilderContext() can probably be rewritten as flowBuilderContext

UnnecessaryGetter3163

[SRC]getFlowDefinitionRegistry().registerFlowDefinition(new D..(assembler))

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowDefinitionRegistry() can probably be rewritten as flowDefinitionRegistry

UnnecessaryGetter3164

[SRC]return getFlowDefinitionRegistry().getFlowDefinition(flowId)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowDefinitionRegistry() can probably be rewritten as flowDefinitionRegistry

UnnecessaryGetter3168

[SRC]return registerFlow(getFlowId(), getFlowClosure())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowId() can probably be rewritten as flowId

UnnecessaryGetter3168

[SRC]return registerFlow(getFlowId(), getFlowClosure())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowClosure() can probably be rewritten as flowClosure

Package: grails-test.src.main.groovy.grails.test

➥ GrailsMock.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3140

[SRC]def methods = demand.mockMetaClass.getMetaMethods()

[MSG]Violation in class grails.test.GrailsMock. getMetaMethods() can probably be rewritten as metaMethods

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.plugins.testing

➥ AbstractGrailsMockHttpServletResponse.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter343

[SRC]HttpServletRequest request = GrailsWebRequest.lookup().g..entRequest()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter389

[SRC]webRequest.setOut(getWriter())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getWriter() can probably be rewritten as writer

UnnecessaryGetter394

[SRC]getRedirectedUrl()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getRedirectedUrl() can probably be rewritten as redirectedUrl

UnnecessaryGetter3106

[SRC]if (getStatus() in [301, 302]) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getStatus() can probably be rewritten as status

UnnecessaryGetter3110

[SRC]return super.getRedirectedUrl()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getRedirectedUrl() can probably be rewritten as redirectedUrl

➥ GrailsMockErrors.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import org.codehaus.groovy.grails.commons.GrailsClassUtils

[MSG]The [org.codehaus.groovy.grails.commons.GrailsClassUtils] import is never referenced

➥ GrailsMockHttpServletRequest.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod2455

[SRC]void delete() {

[MSG]Violation in class MockPart. The method delete is both empty and not marked with @Override

UnusedMethodParameter2497

[SRC]void dispatch(javax.servlet.ServletContext context, String path) {

[MSG]Violation in class MockAsyncContext. Method parameter [context] is never referenced in the method dispatch of class org.codehaus.groovy.grails.plugins.testing.MockAsyncContext

EmptyMethod2501

[SRC]void complete() {

[MSG]Violation in class MockAsyncContext. The method complete is both empty and not marked with @Override

UnusedImport334

[SRC]import javax.servlet.DispatcherType

[MSG]The [javax.servlet.DispatcherType] import is never referenced

UnnecessaryPackageReference363

[SRC]javax.servlet.DispatcherType dispatcherType;

[MSG]The javax.servlet.DispatcherType class was explicitly imported, so specifying the package name is not necessary

UnnecessaryGetter3339

[SRC]multipartFiles.add(file.getName(), file);

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletRequest. getName() can probably be rewritten as name

UnnecessaryGetter3396

[SRC]getFileMap().values().collect {new MockPart(it)}

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletRequest. getFileMap() can probably be rewritten as fileMap

UnnecessaryPackageReference3399

[SRC]javax.servlet.http.Part getPart(String name) {

[MSG]The javax.servlet.http.Part class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3406

[SRC]javax.servlet.AsyncContext startAsync() {

[MSG]The javax.servlet.AsyncContext class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3415

[SRC]javax.servlet.AsyncContext startAsync(javax.servlet.Serv..tResponse) {

[MSG]The javax.servlet.AsyncContext class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3415

[SRC]javax.servlet.AsyncContext startAsync(javax.servlet.Serv..tResponse) {

[MSG]The javax.servlet.ServletRequest class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3415

[SRC]javax.servlet.AsyncContext startAsync(javax.servlet.Serv..tResponse) {

[MSG]The javax.servlet.ServletResponse class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3526

[SRC]void addListener(javax.servlet.AsyncListener listener) {

[MSG]The javax.servlet.AsyncListener class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3530

[SRC]void addListener(javax.servlet.AsyncListener listener, j..tResponse) {

[MSG]The javax.servlet.AsyncListener class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3530

[SRC]void addListener(javax.servlet.AsyncListener listener, j..tResponse) {

[MSG]The javax.servlet.ServletRequest class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3530

[SRC]void addListener(javax.servlet.AsyncListener listener, j..tResponse) {

[MSG]The javax.servlet.ServletResponse class was explicitly imported, so specifying the package name is not necessary

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test

➥ GrailsTestTargetPattern.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring361

[SRC]methodName = rawPattern.substring(pos + 1)

[MSG]Violation in class org.codehaus.groovy.grails.test.GrailsTestTargetPattern. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring362

[SRC]classPattern = rawPattern.substring(0, pos)

[MSG]Violation in class org.codehaus.groovy.grails.test.GrailsTestTargetPattern. The String.substring(int, int) method can be replaced with the subscript operator

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.event

➥ GrailsTestEventConsoleReporter.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter242

[SRC]protected doTestFailure(String name, failure, boolean isError) {

[MSG]Violation in class GrailsTestEventConsoleReporter. Method parameter [failure] is never referenced in the method doTestFailure of class org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter

UnusedMethodParameter242

[SRC]protected doTestFailure(String name, failure, boolean isError) {

[MSG]Violation in class GrailsTestEventConsoleReporter. Method parameter [isError] is never referenced in the method doTestFailure of class org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter

UnusedMethodParameter247

[SRC]protected doTestCaseEnd(String name, String out, String err) {

[MSG]Violation in class GrailsTestEventConsoleReporter. Method parameter [name] is never referenced in the method doTestCaseEnd of class org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter

UnusedMethodParameter247

[SRC]protected doTestCaseEnd(String name, String out, String err) {

[MSG]Violation in class GrailsTestEventConsoleReporter. Method parameter [err] is never referenced in the method doTestCaseEnd of class org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.junit4

➥ JUnit4GrailsTestType.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter353

[SRC]def testClasses = getTestClasses()

[MSG]Violation in class org.codehaus.groovy.grails.test.junit4.JUnit4GrailsTestType. getTestClasses() can probably be rewritten as testClasses

UnnecessaryGetter376

[SRC]new GrailsTestCaseRunnerBuilder(mode, getApplicationCont..getPatterns)

[MSG]Violation in class org.codehaus.groovy.grails.test.junit4.JUnit4GrailsTestType. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.junit4.listener

➥ SuiteRunListener.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod246

[SRC]void testRunStarted(Description description) {

[MSG]Violation in class SuiteRunListener. The method testRunStarted is both empty and not marked with @Override

UnusedMethodParameter246

[SRC]void testRunStarted(Description description) {

[MSG]Violation in class SuiteRunListener. Method parameter [description] is never referenced in the method testRunStarted of class org.codehaus.groovy.grails.test.junit4.listener.SuiteRunListener

UnusedMethodParameter268

[SRC]void testRunFinished(Result result) {

[MSG]Violation in class SuiteRunListener. Method parameter [result] is never referenced in the method testRunFinished of class org.codehaus.groovy.grails.test.junit4.listener.SuiteRunListener

EmptyMethod272

[SRC]void testIgnored(Description description) {

[MSG]Violation in class SuiteRunListener. The method testIgnored is both empty and not marked with @Override

UnusedMethodParameter272

[SRC]void testIgnored(Description description) {

[MSG]Violation in class SuiteRunListener. Method parameter [description] is never referenced in the method testIgnored of class org.codehaus.groovy.grails.test.junit4.listener.SuiteRunListener

UnnecessaryGetter369

[SRC]getPerTestRunListener().finish()

[MSG]Violation in class org.codehaus.groovy.grails.test.junit4.listener.SuiteRunListener. getPerTestRunListener() can probably be rewritten as perTestRunListener

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.junit4.runner

➥ GrailsTestCaseRunner.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport325

[SRC]import org.junit.runner.notification.RunNotifier

[MSG]The [org.junit.runner.notification.RunNotifier] import is never referenced

UnusedImport335

[SRC]import org.codehaus.groovy.grails.test.support.GrailsTestInterceptor

[MSG]The [org.codehaus.groovy.grails.test.support.GrailsTestInterceptor] import is never referenced

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.support

➥ GrailsTestInterceptor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter281

[SRC]protected initRequestEnvironmentIfNecessary(Closure body) {

[MSG]Violation in class GrailsTestInterceptor. Method parameter [body] is never referenced in the method initRequestEnvironmentIfNecessary of class org.codehaus.groovy.grails.test.support.GrailsTestInterceptor

UnnecessaryGetter384

[SRC]def controllerName = getControllerName()

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestInterceptor. getControllerName() can probably be rewritten as controllerName

➥ GrailsTestTransactionInterceptor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import org.springframework.web.context.request.RequestContextHolder

[MSG]The [org.springframework.web.context.request.RequestContextHolder] import is never referenced

➥ GrailsTestTypeSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3117

[SRC]Thread.currentThread().contextClassLoader = getTestClassLoader()

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. getTestClassLoader() can probably be rewritten as testClassLoader

UnnecessaryGetter3157

[SRC]def classPathAdditions = [getSourceDir()]

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. getSourceDir() can probably be rewritten as sourceDir

UnnecessaryGetter3210

[SRC]def basePath = getSourceDir().canonicalPath

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. getSourceDir() can probably be rewritten as sourceDir

UnnecessarySubstring3216

[SRC]def relativePath = filePath.substring(basePath.size() + 1)

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3250

[SRC]getTestClassLoader().loadClass(className)

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. getTestClassLoader() can probably be rewritten as testClassLoader

Package: grails-web.src.jsp21.groovy.org.codehaus.groovy.grails.web.pages.ext.jsp

➥ GroovyPagesJspFactory21.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter317

[SRC]def jspCtx = servletContext.getAttribute(GroovyPagesJspA..t.getName())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory21. getName() can probably be rewritten as name

UnnecessaryGetter321

[SRC]if (!servletContext.getAttribute(GroovyPagesJspApplicati..etName())) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory21. getName() can probably be rewritten as name

UnnecessaryGetter323

[SRC]servletContext.setAttribute(GroovyPagesJspApplicationCon..e(), jspCtx)

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory21. getName() can probably be rewritten as name

➥ GroovyPagesPageContext21.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter330

[SRC]if (JspFactory.getDefaultFactory() == null) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContext21. getDefaultFactory() can probably be rewritten as defaultFactory

UnnecessaryGetter339

[SRC]def jspContext = JspFactory.getDefaultFactory().getJspAp..etContext())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContext21. getDefaultFactory() can probably be rewritten as defaultFactory

UnnecessaryGetter339

[SRC]def jspContext = JspFactory.getDefaultFactory().getJspAp..etContext())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContext21. getServletContext() can probably be rewritten as servletContext

Package: grails-web.src.main.groovy.grails.gsp

➥ PageRenderer.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2165

[SRC]long getDateHeader(String name) { -1L }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getDateHeader of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2167

[SRC]String getHeader(String name) { null }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getHeader of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2169

[SRC]Enumeration getHeaders(String name) {

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getHeaders of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2177

[SRC]int getIntHeader(String name) { -1 }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getIntHeader of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2191

[SRC]boolean isUserInRole(String role) { false }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [role] is never referenced in the method isUserInRole of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2205

[SRC]HttpSession getSession(boolean create) { throw new Unsup..erations") }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [create] is never referenced in the method getSession of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2264

[SRC]String[] getParameterValues(String name) {

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getParameterValues of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2318

[SRC]RequestDispatcher getRequestDispatcher(String path) {

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [path] is never referenced in the method getRequestDispatcher of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2322

[SRC]String getRealPath(String path) {

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [path] is never referenced in the method getRealPath of class grails.gsp.PageRenderer$PageRenderRequest

EmptyMethod2389

[SRC]void addCookie(Cookie cookie) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method addCookie is both empty and not marked with @Override

UnusedMethodParameter2389

[SRC]void addCookie(Cookie cookie) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [cookie] is never referenced in the method addCookie of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2393

[SRC]boolean containsHeader(String name) { false }

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method containsHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2403

[SRC]void sendError(int sc, String msg) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method sendError is both empty and not marked with @Override

UnusedMethodParameter2403

[SRC]void sendError(int sc, String msg) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sc] is never referenced in the method sendError of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2403

[SRC]void sendError(int sc, String msg) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [msg] is never referenced in the method sendError of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2407

[SRC]void sendError(int sc) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method sendError is both empty and not marked with @Override

UnusedMethodParameter2407

[SRC]void sendError(int sc) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sc] is never referenced in the method sendError of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2411

[SRC]void sendRedirect(String location) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method sendRedirect is both empty and not marked with @Override

UnusedMethodParameter2411

[SRC]void sendRedirect(String location) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [location] is never referenced in the method sendRedirect of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2415

[SRC]void setDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setDateHeader is both empty and not marked with @Override

UnusedMethodParameter2415

[SRC]void setDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method setDateHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2415

[SRC]void setDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [date] is never referenced in the method setDateHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2419

[SRC]void addDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method addDateHeader is both empty and not marked with @Override

UnusedMethodParameter2419

[SRC]void addDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method addDateHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2419

[SRC]void addDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [date] is never referenced in the method addDateHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2423

[SRC]void setHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setHeader is both empty and not marked with @Override

UnusedMethodParameter2423

[SRC]void setHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method setHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2423

[SRC]void setHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [value] is never referenced in the method setHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2427

[SRC]void addHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method addHeader is both empty and not marked with @Override

UnusedMethodParameter2427

[SRC]void addHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method addHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2427

[SRC]void addHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [value] is never referenced in the method addHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2431

[SRC]void setIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setIntHeader is both empty and not marked with @Override

UnusedMethodParameter2431

[SRC]void setIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method setIntHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2431

[SRC]void setIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [value] is never referenced in the method setIntHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2435

[SRC]void addIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method addIntHeader is both empty and not marked with @Override

UnusedMethodParameter2435

[SRC]void addIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method addIntHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2435

[SRC]void addIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [value] is never referenced in the method addIntHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2439

[SRC]void setStatus(int sc) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setStatus is both empty and not marked with @Override

UnusedMethodParameter2439

[SRC]void setStatus(int sc) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sc] is never referenced in the method setStatus of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2443

[SRC]void setStatus(int sc, String sm) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setStatus is both empty and not marked with @Override

UnusedMethodParameter2443

[SRC]void setStatus(int sc, String sm) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sc] is never referenced in the method setStatus of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2443

[SRC]void setStatus(int sc, String sm) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sm] is never referenced in the method setStatus of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2451

[SRC]String getHeader(String name) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method getHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2455

[SRC]Collection<String> getHeaders(String name) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method getHeaders of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2467

[SRC]void setContentLength(int len) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setContentLength is both empty and not marked with @Override

UnusedMethodParameter2467

[SRC]void setContentLength(int len) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [len] is never referenced in the method setContentLength of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2471

[SRC]void flushBuffer() {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method flushBuffer is both empty and not marked with @Override

EmptyMethod2475

[SRC]void resetBuffer() {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method resetBuffer is both empty and not marked with @Override

EmptyMethod2481

[SRC]void reset() {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method reset is both empty and not marked with @Override

UnusedImport320

[SRC]import java.util.concurrent.ConcurrentLinkedQueue

[MSG]The [java.util.concurrent.ConcurrentLinkedQueue] import is never referenced

UnusedImport332

[SRC]import org.codehaus.groovy.grails.web.pages.GroovyPagesUriSupport

[MSG]The [org.codehaus.groovy.grails.web.pages.GroovyPagesUriSupport] import is never referenced

UnusedImport337

[SRC]import org.springframework.core.io.ResourceLoader

[MSG]The [org.springframework.core.io.ResourceLoader] import is never referenced

UnusedImport340

[SRC]import org.springframework.web.context.support.ServletCo..sourceLoader

[MSG]The [org.springframework.web.context.support.ServletContextResourceLoader] import is never referenced

UnusedImport343

[SRC]import org.codehaus.groovy.grails.web.pages.discovery.Gr..ScriptSource

[MSG]The [org.codehaus.groovy.grails.web.pages.discovery.GroovyPageResourceScriptSource] import is never referenced

UnusedImport344

[SRC]import org.codehaus.groovy.grails.web.pages.discovery.Gr..ScriptSource

[MSG]The [org.codehaus.groovy.grails.web.pages.discovery.GroovyPageCompiledScriptSource] import is never referenced

UnnecessaryGetter3126

[SRC]def oldRequestAttributes = RequestContextHolder.getRequestAttributes()

[MSG]Violation in class grails.gsp.PageRenderer. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3198

[SRC]return new StringBuffer(getRequestURI())

[MSG]Violation in class grails.gsp.PageRenderer$PageRenderRequest. getRequestURI() can probably be rewritten as requestURI

UnnecessaryGetter3309

[SRC]return Locale.getDefault()

[MSG]Violation in class grails.gsp.PageRenderer$PageRenderRequest. getDefault() can probably be rewritten as default

UnnecessaryGetter3313

[SRC]return new IteratorEnumeration(Locale.getAvailableLocale...iterator())

[MSG]Violation in class grails.gsp.PageRenderer$PageRenderRequest. getAvailableLocales() can probably be rewritten as availableLocales

UnnecessaryGetter3381

[SRC]Locale locale = Locale.getDefault()

[MSG]Violation in class grails.gsp.PageRenderer$PageRenderResponse. getDefault() can probably be rewritten as default

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.mapping

➥ DefaultLinkGenerator.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity264

[SRC]String link(Map attrs, String encoding = 'UTF-8') {

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. The cyclomatic complexity for method [link] is [27]

EmptyCatchBlock2142

[SRC]} catch(e){}

[MSG]The catch block is empty

UnnecessaryGetter374

[SRC]if (cp == null) cp = getContextPath()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getContextPath() can probably be rewritten as contextPath

UnnecessaryGetter397

[SRC]def controller = controllerAttribute != null ? controlle..rollerName()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getControllerName() can probably be rewritten as controllerName

UnnecessaryGetter3149

[SRC]final cp = contextPathAttribute != null ? contextPathAtt..ontextPath()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getContextPath() can probably be rewritten as contextPath

UnnecessaryGetter3177

[SRC]final cp = contextPathAttribute == null ? getContextPath..athAttribute

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getContextPath() can probably be rewritten as contextPath

UnnecessaryGetter3216

[SRC]contextPath = requestStateLookupStrategy.getContextPath()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getContextPath() can probably be rewritten as contextPath

UnnecessaryElseStatement3259

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryElseStatement3263

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ ForwardUrlMappingInfo.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport317

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest] import is never referenced

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.mime

➥ MimeType.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter362

[SRC]def context = webRequest?.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.mime.MimeType. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.pages

➥ GroovyPageCompiler.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter387

[SRC]def relPackagePath = relativePath(viewsDir, gspfile.getParentFile())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompiler. getParentFile() can probably be rewritten as parentFile

UnnecessaryGetter3119

[SRC]gspgroovyfile.getParentFile().mkdirs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompiler. getParentFile() can probably be rewritten as parentFile

➥ GroovyPageCompilerTask.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter358

[SRC]classpath = new Path(getProject())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask. getProject() can probably be rewritten as project

UnnecessaryGetter381

[SRC]throw new BuildException("destination [${destdir}] direc..tLocation())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask. getLocation() can probably be rewritten as location

UnnecessaryGetter387

[SRC]throw new BuildException("source [${srcdir}] directory d..tLocation())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask. getLocation() can probably be rewritten as location

UnnecessaryGetter3100

[SRC]GrailsConsole.getInstance().updateStatus("Compiling ${gs..kagename}]")

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask. getInstance() can probably be rewritten as instance

➥ GroovyPagesMetaUtils.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGroovyImport34

[SRC]import groovy.lang.MetaClass

UnnecessaryGetter320

[SRC]methodMissingForTagLib(mc, mc.getTheClass(), gspTagLibra..ToMetaClass)

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPagesMetaUtils. getTheClass() can probably be rewritten as theClass

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.pages.ext.jsp

➥ GroovyPagesJspFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [servlet] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [servletRequest] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [servletResponse] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [s] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [b] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [i] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [b1] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter219

[SRC]void releasePageContext(PageContext pageContext) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [pageContext] is never referenced in the method releasePageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnnecessaryGetter324

[SRC]return { getSpecificationVersion() } as JspEngineInfo

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory. getSpecificationVersion() can probably be rewritten as specificationVersion

➥ JspTagImpl.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity260

[SRC]void doTag(Writer targetWriter, Map attributes, Closure body) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl. The cyclomatic complexity for method [doTag] is [23]

UnusedMethodParameter2153

[SRC]protected handleSimpleTag(SimpleTag tag, Map attributes,..pageContext,

[MSG]Violation in class JspTagImpl. Method parameter [attributes] is never referenced in the method handleSimpleTag of class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl

UnnecessaryGetter362

[SRC]GroovyPagesPageContext pageContext = PageContextFactory.getCurrent();

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl. getCurrent() can probably be rewritten as current

UnnecessaryGetter399

[SRC]def out = pageContext.getOut()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl. getOut() can probably be rewritten as out

UnnecessaryGetter3121

[SRC]LOG.warn "Tag ${tag.getClass().getName()} returned SKIP_..rted in GSP"

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl. getName() can probably be rewritten as name

➥ PageContextFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter338

[SRC]def classLoader = Thread.currentThread().getContextClassLoader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.PageContextFactory. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter351

[SRC]def request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.PageContextFactory. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter356

[SRC]ServletContext servletContext = webRequest.getServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.PageContextFactory. getServletContext() can probably be rewritten as servletContext

➥ TagLibraryResolver.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter364

[SRC]def jarURLs = grailsApplication.isWarDeployed() ? getJar..().getURLs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getJarsFromServletContext() can probably be rewritten as jarsFromServletContext

UnnecessaryGetter364

[SRC]def jarURLs = grailsApplication.isWarDeployed() ? getJar..().getURLs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getURLs() can probably be rewritten as URLs

UnnecessaryGetter370

[SRC]ZipEntry entry = zipInput.getNextEntry()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getNextEntry() can probably be rewritten as nextEntry

UnnecessaryGetter376

[SRC]entry = zipInput.getNextEntry()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getNextEntry() can probably be rewritten as nextEntry

UnnecessaryGetter386

[SRC]Resource webXml = getWebXmlFromServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getWebXmlFromServletContext() can probably be rewritten as webXmlFromServletContext

UnnecessaryGetter398

[SRC]def jarURLs = grailsApplication.isWarDeployed() ? getJar..().getURLs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getJarsFromServletContext() can probably be rewritten as jarsFromServletContext

UnnecessaryGetter398

[SRC]def jarURLs = grailsApplication.isWarDeployed() ? getJar..().getURLs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getURLs() can probably be rewritten as URLs

UnnecessaryGetter3115

[SRC]def source = new InputSource(webXml.getInputStream())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getInputStream() can probably be rewritten as inputStream

UnnecessaryGetter3120

[SRC]def reader = factory.newSAXParser().getXMLReader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getXMLReader() can probably be rewritten as XMLReader

UnnecessaryGetter3126

[SRC]for (entry in webXmlReader.getTagLocations()) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getTagLocations() can probably be rewritten as tagLocations

UnnecessaryGetter3157

[SRC]ZipEntry entry = zipInput.getNextEntry()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getNextEntry() can probably be rewritten as nextEntry

UnnecessaryGetter3159

[SRC]def name = entry.getName()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getName() can probably be rewritten as name

UnnecessaryGetter3169

[SRC]if ("taglib".equals(pullParser.getName())) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getName() can probably be rewritten as name

UnnecessaryGetter3175

[SRC]if (token == XmlPullParser.START_TAG && "uri".equals(pul..etName())) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getName() can probably be rewritten as name

UnnecessaryGetter3177

[SRC]tagLibURI = pullParser.getText()?.trim()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getText() can probably be rewritten as text

UnnecessaryGetter3191

[SRC]entry = zipInput.getNextEntry()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getNextEntry() can probably be rewritten as nextEntry

UnnecessaryGetter3216

[SRC]def reader = factory.newSAXParser().getXMLReader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getXMLReader() can probably be rewritten as XMLReader

➥ TldReader.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter236

[SRC]void startElement(String nsuri, String localName, String..ttributes) {

[MSG]Violation in class TldReader. Method parameter [nsuri] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

UnusedMethodParameter236

[SRC]void startElement(String nsuri, String localName, String..ttributes) {

[MSG]Violation in class TldReader. Method parameter [localName] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

UnusedMethodParameter236

[SRC]void startElement(String nsuri, String localName, String..ttributes) {

[MSG]Violation in class TldReader. Method parameter [attributes] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

UnusedMethodParameter246

[SRC]void endElement(String nsuri, String localName, String qName) {

[MSG]Violation in class TldReader. Method parameter [nsuri] is never referenced in the method endElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

UnusedMethodParameter246

[SRC]void endElement(String nsuri, String localName, String qName) {

[MSG]Violation in class TldReader. Method parameter [localName] is never referenced in the method endElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

➥ WebXmlTagLibraryReader.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter241

[SRC]void startElement(String ns, String localName, String qN..ttributes) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [ns] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

UnusedMethodParameter241

[SRC]void startElement(String ns, String localName, String qN..ttributes) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [localName] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

UnusedMethodParameter241

[SRC]void startElement(String ns, String localName, String qN..ttributes) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [attributes] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

UnusedMethodParameter251

[SRC]void endElement(String ns, String localName, String qName) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [ns] is never referenced in the method endElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

UnusedMethodParameter251

[SRC]void endElement(String ns, String localName, String qName) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [localName] is never referenced in the method endElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.taglib

➥ NamespacedTagDispatcher.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter359

[SRC]GroovyPagesMetaUtils.methodMissingForTagLib(getMetaClass..lopmentMode)

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.NamespacedTagDispatcher. getMetaClass() can probably be rewritten as metaClass

➥ TemplateNamespacedTagDispatcher.groovy

Rule NamePriorityLine #Source Line / Message
SynchronizedOnThis222

[SRC]synchronized(this) {

[MSG]The synchronized statement uses the 'this' reference

UnusedImport33

[SRC]import grails.util.CollectionUtils;

[MSG]The [grails.util.CollectionUtils] import is never referenced

UnnecessaryGroovyImport35

[SRC]import java.util.Map;

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.util

➥ TypeConvertingMap.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import org.apache.commons.lang.builder.HashCodeBuilder

[MSG]The [org.apache.commons.lang.builder.HashCodeBuilder] import is never referenced

Package: grails-webflow.src.main.groovy.grails.test

➥ WebFlowTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod260

[SRC]abstract getFlow()

[MSG]Violation in class WebFlowTestCase. The method getFlow is public but not a test method

JUnitPublicNonTestMethod265

[SRC]String getFlowId() { "test" }

[MSG]Violation in class WebFlowTestCase. The method getFlowId is public but not a test method

JUnitPublicNonTestMethod2106

[SRC]FlowDefinition registerFlow(String flowId, Closure flowClosure) {

[MSG]Violation in class WebFlowTestCase. The method registerFlow is public but not a test method

JUnitPublicNonTestMethod2115

[SRC]FlowDefinition getFlowDefinition() {

[MSG]Violation in class WebFlowTestCase. The method getFlowDefinition is public but not a test method

UnnecessaryGetter369

[SRC]GrailsWebRequest webRequest = RequestContextHolder.getRe..Attributes()

[MSG]Violation in class grails.test.WebFlowTestCase. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter374

[SRC]mockServletContext = webRequest.getServletContext()

[MSG]Violation in class grails.test.WebFlowTestCase. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter375

[SRC]applicationContext = WebApplicationContextUtils.getWebAp..etContext())

[MSG]Violation in class grails.test.WebFlowTestCase. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter395

[SRC]flowBuilderServices.expressionParser = DefaultExpression..sionParser()

[MSG]Violation in class grails.test.WebFlowTestCase. getExpressionParser() can probably be rewritten as expressionParser

UnnecessaryGetter3110

[SRC]FlowAssembler assembler = new FlowAssembler(builder, bui..erContext())

[MSG]Violation in class grails.test.WebFlowTestCase. getFlowBuilderContext() can probably be rewritten as flowBuilderContext

UnnecessaryGetter3116

[SRC]def flow = getFlow()

[MSG]Violation in class grails.test.WebFlowTestCase. getFlow() can probably be rewritten as flow

UnnecessaryGetter3123

[SRC]return registerFlow(getFlowId(), flow)

[MSG]Violation in class grails.test.WebFlowTestCase. getFlowId() can probably be rewritten as flowId

Package: grails-webflow.src.main.groovy.org.codehaus.groovy.grails.webflow

➥ WebFlowPluginSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport324

[SRC]import org.codehaus.groovy.grails.webflow.persistence.Fl..ssionContext

[MSG]The [org.codehaus.groovy.grails.webflow.persistence.FlowAwareCurrentSessionContext] import is never referenced

UnusedImport325

[SRC]import org.codehaus.groovy.grails.webflow.persistence.Se..tionListener

[MSG]The [org.codehaus.groovy.grails.webflow.persistence.SessionAwareHibernateFlowExecutionListener] import is never referenced

UnusedImport340

[SRC]import org.springframework.webflow.execution.factory.Sta..stenerLoader

[MSG]The [org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader] import is never referenced

UnnecessarySelfAssignment371

[SRC]viewFactoryCreator = viewFactoryCreator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment371

[SRC]viewFactoryCreator = viewFactoryCreator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryPackageReference380

[SRC]hibernateConversationListener(org.codehaus.groovy.grails..tionManager)

[MSG]The org.codehaus.groovy.grails.webflow.persistence.SessionAwareHibernateFlowExecutionListener class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference380

[SRC]hibernateConversationListener(org.codehaus.groovy.grails..tionManager)

[MSG]The org.codehaus.groovy.grails.webflow.persistence.SessionAwareHibernateFlowExecutionListener class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference381

[SRC]executionListenerLoader(org.springframework.webflow.exec..ionListener)

[MSG]The org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference381

[SRC]executionListenerLoader(org.springframework.webflow.exec..ionListener)

[MSG]The org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference382

[SRC]sessionFactory.currentSessionContextClass = org.codehaus..ssionContext

[MSG]The org.codehaus.groovy.grails.webflow.persistence.FlowAwareCurrentSessionContext class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference382

[SRC]sessionFactory.currentSessionContextClass = org.codehaus..ssionContext

[MSG]The org.codehaus.groovy.grails.webflow.persistence.FlowAwareCurrentSessionContext class was explicitly imported, so specifying the package name is not necessary

UnnecessarySelfAssignment3103

[SRC]flowExecutor = flowExecutor

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3103

[SRC]flowExecutor = flowExecutor

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter3122

[SRC]def assembler = new FlowAssembler(builder, builder.getFl..erContext())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getFlowBuilderContext() can probably be rewritten as flowBuilderContext

UnnecessaryGetter3170

[SRC]controller.getReference().getWrappedInstance().metaClass..rollerClass)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getWrappedInstance() can probably be rewritten as wrappedInstance

UnnecessaryGetter3170

[SRC]controller.getReference().getWrappedInstance().metaClass..rollerClass)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getReference() can probably be rewritten as reference

UnnecessaryDefInVariableDeclaration3172

[SRC]def FlowBuilder builder = new FlowBuilder(("${controller..lowRegistry)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. The def keyword is unneeded when a variable is declared with a type

UnnecessaryDefInVariableDeclaration3172

[SRC]def FlowBuilder builder = new FlowBuilder(("${controller..lowRegistry)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. The def keyword is unneeded when a variable is declared with a type

UnnecessaryGetter3176

[SRC]FlowAssembler flowAssembler = new FlowAssembler(builder,..erContext())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getFlowBuilderContext() can probably be rewritten as flowBuilderContext

UnnecessaryGetter3182

[SRC]controller.getReference().getWrappedInstance().metaClass..entMetaClass

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getWrappedInstance() can probably be rewritten as wrappedInstance

UnnecessaryGetter3182

[SRC]controller.getReference().getWrappedInstance().metaClass..entMetaClass

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getReference() can probably be rewritten as reference

Package: grails-webflow.src.main.groovy.org.codehaus.groovy.grails.webflow.context.servlet

➥ GrailsFlowUrlHandler.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport326

[SRC]import org.springframework.webflow.execution.repository...onRepository

[MSG]The [org.springframework.webflow.execution.repository.FlowExecutionRepository] import is never referenced

UnusedImport332

[SRC]import org.codehaus.groovy.grails.webflow.execution.Grai..ExecutorImpl

[MSG]The [org.codehaus.groovy.grails.webflow.execution.GrailsFlowExecutorImpl] import is never referenced

UnnecessarySubstring368

[SRC]String actionName = flowId.substring(flowId.lastIndexOf('/')+1)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.context.servlet.GrailsFlowUrlHandler. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3107

[SRC]String actionName = flowId.substring(flowId.lastIndexOf('/') + 1)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.context.servlet.GrailsFlowUrlHandler. The String.substring(int) method can be replaced with the subscript operator

Package: grails-webflow.src.main.groovy.org.codehaus.groovy.grails.webflow.engine.builder

➥ AbstractDelegate.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInVariableDeclaration366

[SRC]def MetaProperty property = metaClass.getMetaProperty(name)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.AbstractDelegate. The def keyword is unneeded when a variable is declared with a type

UnnecessaryGetter367

[SRC]def ctx = getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.AbstractDelegate. getApplicationContext() can probably be rewritten as applicationContext

➥ AbstractMapper.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod2123

[SRC]void setValue(Object context, Object value) {}

[MSG]Violation in class KeyExpression. The method setValue is both empty and not marked with @Override

UnusedMethodParameter2123

[SRC]void setValue(Object context, Object value) {}

[MSG]Violation in class KeyExpression. Method parameter [context] is never referenced in the method setValue of class org.codehaus.groovy.grails.webflow.engine.builder.KeyExpression

UnusedMethodParameter2123

[SRC]void setValue(Object context, Object value) {}

[MSG]Violation in class KeyExpression. Method parameter [value] is never referenced in the method setValue of class org.codehaus.groovy.grails.webflow.engine.builder.KeyExpression

UnusedMethodParameter2125

[SRC]Class getValueType(Object context) {Object}

[MSG]Violation in class KeyExpression. Method parameter [context] is never referenced in the method getValueType of class org.codehaus.groovy.grails.webflow.engine.builder.KeyExpression

➥ ClosureExpression.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable235

[SRC]def attrs = context?.attributes ? context.attributes : [:]

[MSG]The variable [attrs] in class org.codehaus.groovy.grails.webflow.engine.builder.ClosureExpression is not used

EmptyMethod241

[SRC]void setValue(Object context, Object value) {

[MSG]Violation in class ClosureExpression. The method setValue is both empty and not marked with @Override

UnusedMethodParameter241

[SRC]void setValue(Object context, Object value) {

[MSG]Violation in class ClosureExpression. Method parameter [context] is never referenced in the method setValue of class org.codehaus.groovy.grails.webflow.engine.builder.ClosureExpression

UnusedMethodParameter241

[SRC]void setValue(Object context, Object value) {

[MSG]Violation in class ClosureExpression. Method parameter [value] is never referenced in the method setValue of class org.codehaus.groovy.grails.webflow.engine.builder.ClosureExpression

UnusedMethodParameter245

[SRC]Class getValueType(Object context) { Object }

[MSG]Violation in class ClosureExpression. Method parameter [context] is never referenced in the method getValueType of class org.codehaus.groovy.grails.webflow.engine.builder.ClosureExpression

➥ ClosureInvokingAction.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField241

[SRC]private static final String RESULT = "result"

[MSG]The field RESULT is not used within the class org.codehaus.groovy.grails.webflow.engine.builder.ClosureInvokingAction

EmptyCatchBlock2154

[SRC]catch (MissingPropertyException e) {

[MSG]The catch block is empty

UnnecessaryDotClass353

[SRC]this.hasCommandObjects = noOfParams > 1 || (noOfParams =..ntext.class)

[MSG]Object.class can be rewritten as Object

UnnecessaryDotClass353

[SRC]this.hasCommandObjects = noOfParams > 1 || (noOfParams =..ntext.class)

[MSG]RequestContext.class can be rewritten as RequestContext

UnnecessaryGetter373

[SRC]prop.validate(delegate, delegate.getProperty(prop.getPro..localErrors)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.ClosureInvokingAction. getPropertyName() can probably be rewritten as propertyName

➥ FlowBuilder.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2252

[SRC]catch (MissingPropertyException mpe) {

[MSG]The catch block is empty

EmptyCatchBlock2262

[SRC]catch (MissingPropertyException mpe) {

[MSG]The catch block is empty

UnnecessaryGetter3100

[SRC]this.metaClass = GroovySystem.getMetaClassRegistry().get..ilder.class)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

UnnecessaryDotClass3100

[SRC]this.metaClass = GroovySystem.getMetaClassRegistry().get..ilder.class)

[MSG]FlowBuilder.class can be rewritten as FlowBuilder

UnnecessaryGetter3113

[SRC]super.getContext()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getContext() can probably be rewritten as context

UnnecessaryGetter3124

[SRC]Flow flow = super.getFlow()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3130

[SRC]FlowArtifactFactory flowFactory = getContext().getFlowAr..actFactory()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlowArtifactFactory() can probably be rewritten as flowArtifactFactory

UnnecessaryGetter3130

[SRC]FlowArtifactFactory flowFactory = getContext().getFlowAr..actFactory()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getContext() can probably be rewritten as context

UnnecessaryGetter3171

[SRC]state = flowFactory.createEndState(name, getFlow(), getA..ntryAction),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3195

[SRC]state.getExceptionHandlerSet().add(eh)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getExceptionHandlerSet() can probably be rewritten as exceptionHandlerSet

UnnecessaryGetter3201

[SRC]getFlow().setStartState(startFlow)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessarySubstring3246

[SRC]key = key.substring(GrailsApplicationAttributes.ERRORS.length() + 1)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3276

[SRC]getFlow(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3294

[SRC]def controllerClass = flowInfo.subflow.getThisObject().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getThisObject() can probably be rewritten as thisObject

UnnecessaryGetter3306

[SRC]Class controllerClass = flowClosure.getThisObject().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getThisObject() can probably be rewritten as thisObject

UnnecessaryGetter3313

[SRC]return flowFactory.createSubflowState(stateId, getFlow()..on(subflow),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3321

[SRC]getFlow(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3333

[SRC]return flowFactory.createEndState(stateId, getFlow(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3346

[SRC]ViewFactory viewFactory = flowBuilderServices.getViewFac..ViewFactory(

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getViewFactoryCreator() can probably be rewritten as viewFactoryCreator

UnnecessaryGetter3348

[SRC]flowBuilderServices.getExpressionParser(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getExpressionParser() can probably be rewritten as expressionParser

UnnecessaryGetter3349

[SRC]flowBuilderServices.getConversionService(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getConversionService() can probably be rewritten as conversionService

UnnecessaryGetter3454

[SRC]throw new FlowDefinitionException("Event handler in flow..etFlowId() +

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowInfoCapturer. getFlowId() can probably be rewritten as flowId

➥ GrailsSubflowAttributeMapper.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod247

[SRC]void mapSubflowOutput(AttributeMap output, RequestContext context) {}

[MSG]Violation in class GrailsSubflowAttributeMapper. The method mapSubflowOutput is both empty and not marked with @Override

UnusedMethodParameter247

[SRC]void mapSubflowOutput(AttributeMap output, RequestContext context) {}

[MSG]Violation in class GrailsSubflowAttributeMapper. Method parameter [output] is never referenced in the method mapSubflowOutput of class org.codehaus.groovy.grails.webflow.engine.builder.GrailsSubflowAttributeMapper

UnusedMethodParameter247

[SRC]void mapSubflowOutput(AttributeMap output, RequestContext context) {}

[MSG]Violation in class GrailsSubflowAttributeMapper. Method parameter [context] is never referenced in the method mapSubflowOutput of class org.codehaus.groovy.grails.webflow.engine.builder.GrailsSubflowAttributeMapper

➥ InputMapper.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryElseStatement341

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ RuntimeRedirectAction.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter352

[SRC]return new GroovyShell(new BeanBinding(delegate)).evalua...getValue())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectAction. getValue() can probably be rewritten as value

UnnecessaryGetter369

[SRC]context.getExternalContext().requestExternalRedirect("co..ative:$url")

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectAction. getExternalContext() can probably be rewritten as externalContext

➥ UriRedirectAction.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import org.codehaus.groovy.grails.web.mapping.UrlCreator

[MSG]The [org.codehaus.groovy.grails.web.mapping.UrlCreator] import is never referenced

UnusedImport320

[SRC]import org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder

[MSG]The [org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder] import is never referenced

UnnecessarySelfAssignment337

[SRC]def uri = uri

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter340

[SRC]uri = new GroovyShell(new BeanBinding(delegate)).evaluat...getValue())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.UriRedirectAction. getValue() can probably be rewritten as value

UnnecessaryGetter343

[SRC]context.getExternalContext().requestExternalRedirect(uri)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.UriRedirectAction. getExternalContext() can probably be rewritten as externalContext

Package: scripts

➥ Console.groovy

Rule NamePriorityLine #Source Line / Message
BusyWait248

[SRC]sleep(Integer.MAX_VALUE)

[MSG]Busy wait detected. Switch the usage of Thread.sleep() to a lock or gate from java.util.concurrent

EmptyMethod280

[SRC]void focusLost(FocusEvent e) {}

[MSG]Violation in class ConsoleFocusListener. The method focusLost is both empty and not marked with @Override

UnusedMethodParameter280

[SRC]void focusLost(FocusEvent e) {}

[MSG]Violation in class ConsoleFocusListener. Method parameter [e] is never referenced in the method focusLost of class ConsoleFocusListener

➥ DependencyReport.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable238

[SRC]def ivySettings = ant.project.setProperty("ivy.cache.dir..bsolutePath)

[MSG]The variable [ivySettings] in class None is not used

➥ Help_.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable270

[SRC]def helpText = ""

[MSG]The variable [helpText] in class None is not used

UnnecessaryGetter355

[SRC]String scriptname = script.getName()

[MSG]Violation in class None. getName() can probably be rewritten as name

UnnecessarySubstring356

[SRC]return new File(helpDir, scriptname.substring(0, scriptn..)) + ".txt")

[MSG]Violation in class None. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessaryCollectCall368

[SRC]def scripts = pluginSettings.availableScripts.collect { it.file }

[MSG]Violation in class None. The call to collect could probably be rewritten as a spread expression: pluginSettings.availableScripts*.file

UnnecessaryGetter3112

[SRC]grails ${scriptName} -- ${getDefaultDescription()}

[MSG]Violation in class None. getDefaultDescription() can probably be rewritten as defaultDescription

➥ ListPluginUpdates.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter361

[SRC]def availablePluginVersions = getAvailablePluginVersions()

[MSG]Violation in class None. getAvailablePluginVersions() can probably be rewritten as availablePluginVersions

UnnecessaryGetter362

[SRC]def installedPluginVersions = getInstalledPluginVersions()

[MSG]Violation in class None. getInstalledPluginVersions() can probably be rewritten as installedPluginVersions

➥ ListPlugins_.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter366

[SRC]def pluginInfos = pluginSettings.getPluginInfos()

[MSG]Violation in class None. getPluginInfos() can probably be rewritten as pluginInfos

➥ RefreshDependencies.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport317

[SRC]import groovy.xml.NamespaceBuilder

[MSG]The [groovy.xml.NamespaceBuilder] import is never referenced

UnusedImport318

[SRC]import org.codehaus.groovy.grails.resolve.IvyDependencyManager

[MSG]The [org.codehaus.groovy.grails.resolve.IvyDependencyManager] import is never referenced

➥ Stats.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring371

[SRC]file.path.substring(baseDirPathLength) =~ info.path &&

[MSG]Violation in class None. The String.substring(int) method can be replaced with the subscript operator

➥ Upgrade.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [35]

UnnecessaryParenthesesForMethodCallWithClosure3125

[SRC]['Config.groovy'].each() {template ->

[MSG]Violation in class None. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3131

[SRC]['BuildConfig.groovy'].each() {template ->

[MSG]Violation in class None. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3138

[SRC]['DataSource.groovy'].each() {template ->

[MSG]Violation in class None. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3146

[SRC]['UrlMappings.groovy'].each() {template ->

[MSG]Violation in class None. Parentheses in the 'each' method call are unnecessary and can be removed.

➥ _GrailsArgParsing.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter326

[SRC]if (getBinding().variables.containsKey("_grails_arg_pars..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsBootstrap.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall365

[SRC]def locations = new ArrayList(grailsSettings.pluginDirec..olutePath })

[MSG]Violation in class None. The call to collect could probably be rewritten as a spread expression: grailsSettings.pluginDirectories*.absolutePath

➥ _GrailsClasspath.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter329

[SRC]if (getBinding().variables.containsKey("_grails_classpat..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsClean.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter326

[SRC]if (getBinding().variables.containsKey("_grails_clean_called")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

UnnecessaryObjectReferences348

[SRC]ant.delete(dir:classesDirPath)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences349

[SRC]ant.delete(dir:pluginClassesDirPath, failonerror:false)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences350

[SRC]ant.delete(dir:resourcesDirPath)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences351

[SRC]ant.delete(dir:testDirPath)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences352

[SRC]ant.delete(failonerror:false, includeemptydirs: true) {

[MSG]The code could be more concise by using a with() or identity() block

➥ _GrailsCreateArtifacts.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [26]

➥ _GrailsDocs.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [30]

UnnecessaryGetter3209

[SRC]def context = DocumentationContext.getInstance()

[MSG]Violation in class None. getInstance() can probably be rewritten as instance

UnnecessaryObjectReferences3254

[SRC]publisher.license = ""

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3255

[SRC]publisher.copyright = ""

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3256

[SRC]publisher.footer = ""

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3257

[SRC]publisher.engineProperties = config?.grails?.doc

[MSG]The code could be more concise by using a with() or identity() block

➥ _GrailsEvents.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter328

[SRC]if (getBinding().variables.containsKey("_grails_events_c..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsInit.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport325

[SRC]import org.springframework.core.io.FileSystemResource

[MSG]The [org.springframework.core.io.FileSystemResource] import is never referenced

UnusedImport326

[SRC]import grails.util.GrailsNameUtils

[MSG]The [grails.util.GrailsNameUtils] import is never referenced

UnnecessaryGetter331

[SRC]if (getBinding().variables.containsKey("_init_called")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsPackage.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter328

[SRC]if (getBinding().variables.containsKey("_grails_package_..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsPluginDev.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethod2130

[SRC]private loadBasePlugin() {

[MSG]The method loadBasePlugin is not used within _GrailsPluginDev.groovy

UnusedImport317

[SRC]import groovy.xml.MarkupBuilder

[MSG]The [groovy.xml.MarkupBuilder] import is never referenced

UnusedImport318

[SRC]import grails.util.GrailsNameUtils

[MSG]The [grails.util.GrailsNameUtils] import is never referenced

UnusedImport319

[SRC]import grails.util.PluginBuildSettings

[MSG]The [grails.util.PluginBuildSettings] import is never referenced

UnusedImport321

[SRC]import org.apache.commons.io.FilenameUtils

[MSG]The [org.apache.commons.io.FilenameUtils] import is never referenced

UnusedImport322

[SRC]import org.apache.ivy.core.report.ArtifactDownloadReport

[MSG]The [org.apache.ivy.core.report.ArtifactDownloadReport] import is never referenced

UnnecessaryGetter364

[SRC]def descriptor = pluginSettings.getBasePluginDescriptor()

[MSG]Violation in class None. getBasePluginDescriptor() can probably be rewritten as basePluginDescriptor

UnnecessaryCollectCall3104

[SRC]packager.jarFiles = deps.collect { it.localFile }

[MSG]Violation in class None. The call to collect could probably be rewritten as a spread expression: deps*.localFile

➥ _GrailsPlugins.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport317

[SRC]import groovy.xml.dom.DOMCategory

[MSG]The [groovy.xml.dom.DOMCategory] import is never referenced

UnusedImport319

[SRC]import org.codehaus.groovy.grails.plugins.GrailsPluginInfo

[MSG]The [org.codehaus.groovy.grails.plugins.GrailsPluginInfo] import is never referenced

UnusedImport320

[SRC]import org.codehaus.groovy.grails.resolve.PluginResolveEngine

[MSG]The [org.codehaus.groovy.grails.resolve.PluginResolveEngine] import is never referenced

UnusedImport321

[SRC]import grails.util.BuildSettings

[MSG]The [grails.util.BuildSettings] import is never referenced

➥ _GrailsRun.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [24]

UnusedMethodParameter2183

[SRC]void actionPerformed(ActionEvent e) {

[MSG]Violation in class None$1. Method parameter [e] is never referenced in the method actionPerformed of class None$1

UnnecessaryGroovyImport324

[SRC]import java.net.ServerSocket

UnnecessaryGetter3128

[SRC]Metadata.getCurrent().put(Metadata.WAR_DEPLOYED, "true")

[MSG]Violation in class None. getCurrent() can probably be rewritten as current

➥ _GrailsSettings.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import grails.util.GrailsNameUtils

[MSG]The [grails.util.GrailsNameUtils] import is never referenced

UnusedImport321

[SRC]import grails.util.Metadata

[MSG]The [grails.util.Metadata] import is never referenced

UnusedImport325

[SRC]import org.springframework.core.io.ClassPathResource

[MSG]The [org.springframework.core.io.ClassPathResource] import is never referenced

UnusedImport326

[SRC]import org.springframework.core.io.FileSystemResource

[MSG]The [org.springframework.core.io.FileSystemResource] import is never referenced

UnusedImport327

[SRC]import org.springframework.core.io.Resource

[MSG]The [org.springframework.core.io.Resource] import is never referenced

UnusedImport328

[SRC]import org.springframework.core.io.support.PathMatchingR..ternResolver

[MSG]The [org.springframework.core.io.support.PathMatchingResourcePatternResolver] import is never referenced

UnusedImport329

[SRC]import org.springframework.util.FileCopyUtils

[MSG]The [org.springframework.util.FileCopyUtils] import is never referenced

UnnecessaryGetter340

[SRC]if (getBinding().variables.containsKey("_settings_called")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

UnnecessaryGetter376

[SRC]if (grailsSettings.defaultEnv && getBinding().variables...riptEnv")) {

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

UnnecessaryGetter388

[SRC]if (getBinding().variables.containsKey("scriptScope")) {

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsTest.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [53]

UnusedImport317

[SRC]import grails.util.GrailsUtil

[MSG]The [grails.util.GrailsUtil] import is never referenced

UnusedImport327

[SRC]import org.codehaus.groovy.grails.test.report.junit.JUni..portsFactory

[MSG]The [org.codehaus.groovy.grails.test.report.junit.JUnitReportsFactory] import is never referenced

UnusedImport333

[SRC]import org.codehaus.groovy.grails.test.event.GrailsTestE..soleReporter

[MSG]The [org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter] import is never referenced

UnnecessaryGetter3126

[SRC]if (reRunTests) testNames = getFailedTests()

[MSG]Violation in class None. getFailedTests() can probably be rewritten as failedTests

➥ _GrailsWar.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [32]

UnusedVariable2191

[SRC]def compileScopePluginInfo = ps.compileScopePluginInfo

[MSG]The variable [compileScopePluginInfo] in class None is not used

UnnecessaryGetter3192

[SRC]def compileScopePluginInfos = ps.getCompileScopedSupport..luginInfos()

[MSG]Violation in class None. getCompileScopedSupportedPluginInfos() can probably be rewritten as compileScopedSupportedPluginInfos

UnnecessaryGetter3193

[SRC]def resourceList = ps.getCompileScopedArtefactResources()

[MSG]Violation in class None. getCompileScopedArtefactResources() can probably be rewritten as compileScopedArtefactResources

UnnecessaryGetter3219

[SRC]attribute(name:"Bundle-Version",value:"${metadata.getApp..Version()}")

[MSG]Violation in class None. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter3225

[SRC]switch (metadata.getServletVersion()) {

[MSG]Violation in class None. getServletVersion() can probably be rewritten as servletVersion

UnnecessaryGetter3258

[SRC]attribute(name:"Implementation-Version",value:"${metadat..Version()}")

[MSG]Violation in class None. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter3259

[SRC]attribute(name:"Grails-Version",value:"${metadata.getGra..Version()}")

[MSG]Violation in class None. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryDefInMethodDeclaration3334

[SRC]protected def createDescriptorInternal(pluginInfos, resourceList) {

[MSG]Violation in class None. The def keyword is unneeded when a method is marked protected

UnnecessaryDefInMethodDeclaration3395

[SRC]private def warPluginsInternal(pluginInfos) {

[MSG]Violation in class None. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3405

[SRC]private def warPluginForPluginInfo(GrailsPluginInfo info) {

[MSG]Violation in class None. The def keyword is unneeded when a method is marked private

UnnecessaryGetter3497

[SRC]def version = metadata.getApplicationVersion()

[MSG]Violation in class None. getApplicationVersion() can probably be rewritten as applicationVersion

➥ _PluginDependencies.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [32]

UnusedVariable2151

[SRC]def application

[MSG]The variable [application] in class None is not used

EmptyCatchBlock2302

[SRC]catch (e) {

[MSG]The catch block is empty

UnusedImport317

[SRC]import grails.util.BuildSettings

[MSG]The [grails.util.BuildSettings] import is never referenced

UnusedImport320

[SRC]import grails.util.PluginBuildSettings

[MSG]The [grails.util.PluginBuildSettings] import is never referenced

UnusedImport326

[SRC]import org.codehaus.groovy.control.CompilationUnit

[MSG]The [org.codehaus.groovy.control.CompilationUnit] import is never referenced

UnusedImport328

[SRC]import org.codehaus.groovy.grails.documentation.DocumentationContext

[MSG]The [org.codehaus.groovy.grails.documentation.DocumentationContext] import is never referenced

UnusedImport329

[SRC]import org.codehaus.groovy.grails.documentation.DocumentedMethod

[MSG]The [org.codehaus.groovy.grails.documentation.DocumentedMethod] import is never referenced

UnusedImport330

[SRC]import org.codehaus.groovy.grails.documentation.DocumentedProperty

[MSG]The [org.codehaus.groovy.grails.documentation.DocumentedProperty] import is never referenced

UnnecessaryGetter352

[SRC]if (getBinding().variables.containsKey("_plugin_dependen..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

UnnecessaryGetter3147

[SRC]def pluginFiles = pluginSettings.getPluginDescriptorsFor..nvironment()

[MSG]Violation in class None. getPluginDescriptorsForCurrentEnvironment() can probably be rewritten as pluginDescriptorsForCurrentEnvironment

UnnecessaryObjectReferences3308

[SRC]pluginInstallEngine.pluginDirVariableStore = binding

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3309

[SRC]pluginInstallEngine.pluginScriptRunner = runPluginScript

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3317

[SRC]GrailsResourceLoaderHolder.resourceLoader = new GrailsRe..vironment())

[MSG]Violation in class None. getArtefactResourcesForCurrentEnvironment() can probably be rewritten as artefactResourcesForCurrentEnvironment

Rule Descriptions

#Rule NameDescription
1AddEmptyStringFinds empty string literals which are being added. This is an inefficient way to convert any type to a String.
2AssertWithinFinallyBlockChecks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one.
3AssignmentInConditionalAn assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended.
4BigDecimalInstantiationChecks for calls to the BigDecimal constructors that take a double parameter, which may result in an unexpected BigDecimal value.
5BitwiseOperatorInConditionalChecks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable.
6BooleanGetBooleanThis rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop'].
7BrokenNullCheckLooks for faulty checks for null that can cause a NullPointerException.
8BrokenOddnessCheckThe code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.
9BusyWaitBusy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package.
10ChainedTestA test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another.
11ClassForNameUsing Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time.
12ComparisonOfTwoConstantsChecks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values., e.g.: 23 == 67, Boolean.FALSE != false, 0.17 <= 0.99, "abc" > "ddd", [a:1] <=> [a:2], [1,2].equals([3,4]) or [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE].
13ComparisonWithSelfChecks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x =>= x, x.equals(x) or x.compareTo(x), where x is a variable.
14ConsecutiveLiteralAppendsViolations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation.
15ConsecutiveStringConcatenationCatches concatenation of two string literals on the same line. These can safely by joined.
16ConstantAssertExpressionChecks for assert statements where the assert boolean condition expression is a constant or literal value.
17ConstantIfExpressionChecks for if statements with a constant value for the if expression, such as true, false, null, or a literal constant value.
18ConstantTernaryExpressionChecks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value.
19CoupledTestCaseThis rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused.
20CyclomaticComplexityChecks the cyclomatic complexity for methods/classes.A method (or "closure field") with a cyclomatic complexity value greater than the maxMethodComplexity property (20) causes a violation. Likewise, a class that has an (average method) cyclomatic complexityvalue greater than the maxClassAverageMethodComplexity property (20) causes a violation.
21DeadCodeDead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted.
22DoubleCheckedLockingThis rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern.
23DoubleNegativeThere is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well.
24DuplicateCaseStatementCheck for duplicate case statements in a switch block, such as two equal integers or strings.
25DuplicateImportDuplicate import statements are unnecessary.
26DuplicateMapKeyA map literal is created with duplicated key. The map entry will be overwritten.
27DuplicateSetValueA Set literal is created with duplicate constant value. A set cannot contain two elements with the same value.
28EmptyCatchBlockIn most cases, exceptions should not be caught and ignored (swallowed).
29EmptyElseBlockEmpty else blocks are confusing and serve no purpose.
30EmptyFinallyBlockEmpty finally blocks are confusing and serve no purpose.
31EmptyForStatementEmpty for statements are confusing and serve no purpose.
32EmptyIfStatementEmpty if statements are confusing and serve no purpose.
33EmptyInstanceInitializerAn empty class instance initializer was found. It is safe to remove it.
34EmptyMethodA method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation.
35EmptyStaticInitializerAn empty static initializer was found. It is safe to remove it.
36EmptySwitchStatementEmpty switch statements are confusing and serve no purpose.
37EmptySynchronizedStatementEmpty synchronized statements are confusing and serve no purpose.
38EmptyTryBlockEmpty try blocks are confusing and serve no purpose.
39EmptyWhileStatementEmpty while statements are confusing and serve no purpose.
40EqualsAndHashCodeIf either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden.
41EqualsOverloadedThe class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it.
42ExplicitGarbageCollectionCalls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself.
43ForLoopShouldBeWhileLoopA for loop without an init and update statement can be simplified to a while loop.
44HardCodedWindowsFileSeparatorThis rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant.
45HardCodedWindowsRootDirectoryThis rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative.
46ImportFromSamePackageAn import of a class that is within the same package is unnecessary.
47ImportFromSunPackagesAvoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.
48InconsistentPropertyLockingClass contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all.
49InconsistentPropertySynchronizationClass contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not.
50IntegerGetIntegerThis rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop'].
51JUnitAssertAlwaysFailsChecks for JUnit assert() method calls with constant arguments such that the assertion always fails. This includes: assertTrue(false), assertFalse(true) and assertNull(CONSTANT).
52JUnitAssertAlwaysSucceedsChecks for JUnit assert() method calls with constant arguments such that the assertion always succeeds. This includes: assertTrue(true), assertFalse(false) and assertNull(null).
53JUnitFailWithoutMessageThis rule detects JUnit calling the fail() method without an argument. For better error reporting you should always provide a message.
54JUnitPublicNonTestMethodChecks if a JUnit test class contains public methods other than standard test methods, JUnit framework methods or methods with JUnit annotations.
55JUnitSetUpCallsSuperChecks that if the JUnit setUp() method is defined, that it includes a call to super.setUp().
56JUnitTearDownCallsSuperChecks that if the JUnit tearDown() method is defined, that it includes a call to super.tearDown().
57JUnitTestMethodWithoutAssertThis rule searches for test methods that do not contain assert statements. Either the test method is missing assert statements, which is an error, or the test method contains custom assert statements that do not follow a proper assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test annotation. By default this rule applies to the default test class names, but this can be changed using the rule's applyToClassNames property.
58JUnitUnnecessarySetUpChecks for JUnit setUp() methods that contain only a call to super.setUp().
59JUnitUnnecessaryTearDownChecks for JUnit tearDown() methods that contain only a call to super.tearDown().
60MisorderedStaticImportsStatic imports should never be declared after nonstatic imports.
61NestedSynchronizationNested synchronized statements should be avoided. Nested synchronized statements are either useless (if the lock objects are identical) or prone to deadlock.
62RandomDoubleCoercedToZeroThe Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug.
63RemoveAllOnSelfDon't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException.
64ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
65SpockIgnoreRestUsedIf Spock's @IgnoreRest appears on any method, all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed.
66StaticCalendarFieldCalendar objects should not be used as static fields. Calendars are inherently unsafe for multihtreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
67StaticConnectionCreates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions.
68StaticDateFormatFieldDateFormat objects should not be used as static fields. DateFormat are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
69StaticMatcherFieldMatcher objects should not be used as static fields. Matcher instances are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
70StaticSimpleDateFormatFieldSimpleDateFormat objects should not be used as static fields. SimpleDateFormat are inherently unsafe for multi-threaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
71SynchronizedMethodThis rule reports uses of the synchronized keyword on methods. Synchronized methods are the same as synchronizing on 'this', which effectively make your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.
72SynchronizedOnBoxedPrimitiveThe code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock
73SynchronizedOnGetClassSynchronization on getClass rather than class literal. This instance method synchronizes on this.getClass(). If this class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended.
74SynchronizedOnReentrantLockSynchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method.
75SynchronizedOnStringSynchronization on a String field can lead to deadlock because Strings are interned by the JVM and can be shared.
76SynchronizedOnThisThis rule reports uses of the synchronized blocks where the synchronization reference is 'this'. Doing this effectively makes your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.
77SynchronizedReadObjectMethodCatches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style.
78SystemRunFinalizersOnExitMethod calls to System.runFinalizersOnExit() should not be allowed. This method is inherently non-thread-safe, may result in data corruption, deadlock, and may effect parts of the program far removed from it's call point. It is deprecated, and it's use strongly discouraged.
79ThreadGroupAvoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe.
80ThreadLocalNotStaticFinalThreadLocal fields should be static and final. In the most common case a java.lang.ThreadLocal instance associates state with a thread. A non-static non-final java.lang.ThreadLocal field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior.
81ThreadYieldMethod calls to Thread.yield() should not be allowed. This method has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions.
82ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
83UnnecessaryBigDecimalInstantiationIt is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G.
84UnnecessaryBigIntegerInstantiationIt is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G.
85UnnecessaryBooleanExpressionChecks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or a Map/List/String/Number literal. Also checks for negation (!) of true, false, null, or a Map/List/String/Number literal.
86UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
87UnnecessaryCallForLastElementThis rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a get, getAt, or array-style access is used with an object size check.
88UnnecessaryCallToSubstringCalling String.substring(0) always returns the original string. This code is meaningless.
89UnnecessaryCatchBlockViolations are triggered when a catch block does nothing but throw the original exception. In this scenario there is usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out.
90UnnecessaryCollectCallSome method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect { it.multiply(2) } can be replaced by list*.multiply(2).
91UnnecessaryCollectionCallUseless call to collections. This call doesn't make sense. For any collection c, calling c.containsAll(c) should always be true, and c.retainAll(c) should have no effect.
92UnnecessaryConstructorThis rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments.
93UnnecessaryDefInFieldDeclarationIf a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}.
94UnnecessaryDefInMethodDeclarationIf a method has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'.
95UnnecessaryDefInVariableDeclarationIf a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'.
96UnnecessaryDotClassTo make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String.
97UnnecessaryDoubleInstantiationIt is unnecessary to instantiate Double objects. Instead just use the double literal or the 'D' identifier to force the type, such as 123.45d or 0.42d.
98UnnecessaryElseStatementWhen an if statement block ends with a return statement the else is unnecessary. The logic in the else branch can be run without being in a new scope.
99UnnecessaryFailIn a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all.
100UnnecessaryFinalOnPrivateMethodA private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary.
101UnnecessaryFloatInstantiationIt is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f.
102UnnecessaryGetterChecks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). Getters do not take method arguments.
103UnnecessaryGroovyImportA Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger.
104UnnecessaryIfStatementChecks for if statements where the if and else blocks are merely returning true and false constants. These cases can be replaced by a simple return statement.
105UnnecessaryInstanceOfCheckThis rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean.
106UnnecessaryInstantiationToGetClassAvoid instantiating an object just to call getClass() on it; use the .class public member instead.
107UnnecessaryIntegerInstantiationIt is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i.
108UnnecessaryLongInstantiationIt is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L.
109UnnecessaryModOneAny expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2).
110UnnecessaryNullCheckGroovy contains the safe dereference operator, which can be used in boolean conditional statements to safely replace explicit "x == null" tests.
111UnnecessaryNullCheckBeforeInstanceOfThere is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.
112UnnecessaryObjectReferencesViolations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block.
113UnnecessaryOverridingMethodThe overriding method merely calls the same method defined in a superclass
114UnnecessaryPackageReferenceChecks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, java.util.Map and groovy.lang.Closure.
115UnnecessaryParenthesesForMethodCallWithClosureIf a method is called and the only parameter to that method is an inline closure then the parentheses of the method call can be omitted.
116UnnecessarySelfAssignmentMethod contains a pointless self-assignment to a variable or property.
117UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
118UnnecessarySubstringThis rule finds usages of String.substring(int) and String.substring(int, int) that can be replaced by use of the subscript operator. For instance, var.substring(5) can be replaced with var[5..-1].
119UnnecessaryTernaryExpressionChecks for ternary expressions where the conditional expression always evaluates to a boolean and the true and false expressions are merely returning true and false constants. Also checks for ternary expressions where both expressions are the same constant or variable.
120UnnecessaryTransientModifierThe field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect.
121UnusedArrayChecks for array allocations that are not assigned or used, unless it is the last statement within a block.
122UnusedImportImports for a class that is never referenced within the source file is unnecessary.
123UnusedMethodParameterThis rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override.
124UnusedObjectChecks for object allocations that are not assigned or used, unless it is the last statement within a block
125UnusedPrivateFieldChecks for private fields that are not referenced within the same class.
126UnusedPrivateMethodChecks for private methods that are not referenced within the same class.
127UnusedPrivateMethodParameterChecks for parameters to private methods that are not referenced within the method body.
128UnusedVariableChecks for variables that are never referenced.
129UseAssertEqualsInsteadOfAssertTrueThis rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.
130UseAssertFalseInsteadOfNegationIn unit tests, if a condition is expected to be false then there is no sense using assertTrue with the negation operator. For instance, assertTrue(!condition) can always be simplified to assertFalse(condition)
131UseAssertNullInsteadOfAssertEqualsThis rule detects JUnit calling assertEquals where the first or second parameter is null. These assertion should be made against the assertNull method instead.
132UseAssertSameInsteadOfAssertTrueThis rule detects JUnit calling assertTrue where the first or second parameter is an Object#is() call testing for reference equality. These assertion should be made against the assertSame method instead.
133UseAssertTrueInsteadOfAssertEqualsThis rule detects JUnit calling assertEquals where the first parameter is a boolean. These assertions should be made by more specific methods, like assertTrue or assertFalse.
134UseAssertTrueInsteadOfNegationIn unit tests, if a condition is expected to be true then there is no sense using assertFalse with the negation operator. For instance, assertFalse(!condition) can always be simplified to assertTrue(condition)
135UseOfNotifyMethodThis code calls notify() rather than notifyAll(). Java monitors are often used for multiple conditions. Calling notify() only wakes up one thread, meaning that the thread woken up might not be the one waiting for the condition that the caller just satisfied.
136VolatileArrayFieldVolatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not.
137VolatileLongOrDoubleFieldLong or double fields should not be declared as volatile. Java specifies that reads and writes from such fields are atomic, but many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronize access to such fields rather than declare them volatile. This rule flags fields marked volatile when their type is double or long or the name of their type is "Double" or "Long".
138WaitOutsideOfWhileLoopCalls to Object.wait() must be within a while loop. Consider using the Java concurrency utilities instead of wait() and notify().
CodeNarc-0.23/docs/codenarc-creating-rule.html0000644000175000017500000004440412471222401020600 0ustar ebourgebourg CodeNarc - CodeNarc - Creating a Rule

CodeNarc - Creating a Rule

CodeNarc includes many predefined rules, but you can also create your own custom rules. See the site navigation menu for a list of rules provided out of the box by CodeNarc. CodeNarc provides abstract superclasses and helper classes for creating new rules.

See this screencast showing how easy it is to create a new rule.

The Rule Interface

All rules must implement the org.codenarc.rule.Rule interface. This interface specifies that all rules must define a name, a priority (from 1 to 3), and also implement the List applyTo(SourceCode sourceCode) method. The method returns the List of Violation objects that result from applying the rule to a single source file.

The AbstractRule Class

The org.codenarc.rule.AbstractRule class is the abstract superclass (or ancestor) for all rules provided with CodeNarc. It provides many standard properties and helper methods for subclasses, as described in Standard Properties for Configuring Rules.

A Sample Rule Subclass of AbstractRule

Here is an example rule class that is a subclass of AbstractRule:

import org.codenarc.rule.AbstractRule
import org.codenarc.source.SourceCode

/**
 * Sample rule. Checks for static fields.
 */
class MyStaticFieldRule extends AbstractRule {
    String name = 'MyStaticField'
    int priority = 2

    void applyTo(SourceCode sourceCode, List violations) {
        sourceCode.ast.classes.each { clazz ->
            clazz.fields.each { fieldNode ->
                if (fieldNode.static) {
                    violations << createViolation(sourceCode, fieldNode)
                }
            }
        }
    }
}

Things to note about MyStaticFieldRule class:

  • It extends AbstractRule.
  • It provides name and priority properties as mandated by the Rule interface.
  • It implements the void applyTo(SourceCode sourceCode, List violations) method which is declared abstract in the AbstractRule superclass.
  • It accesses the AST for the source code, which is an instance of the org.codehaus.groovy.ast.ModuleNode class from Groovy.
  • It uses the createViolation() helper method from AbstractRule.

See the CodeNarc source code for other examples (look for rule classes that are direct subclasses of AbstractRule).

The AbstractAstVisitorRule and AbstractAstVisitor Classes

Many of the rules included with CodeNarc are implemented using the Visitor pattern, as supported by the Groovy AST (Abstract Syntax Tree). See the ClassCodeVisitorSupport class within the Groovy distribution (Javadocs).

A Sample Rule Using AbstractAstVisitorRule and AbstractAstVisitor

Here is an example rule class that is a subclass of AbstractAstVisitorRule that uses an associated AST Visitor class that is a subclass of AbstractAstVisitor. This is the code for the EmptyTryBlock rule included with CodeNarc.

import org.codenarc.rule.AbstractAstVisitor
import org.codenarc.rule.AbstractAstVisitorRule
import org.codehaus.groovy.ast.stmt.TryCatchStatement
import org.codenarc.util.AstUtil

class EmptyTryBlockRule extends AbstractAstVisitorRule {
    String name = 'EmptyTryBlock'
    int priority = 2
    Class astVisitorClass = EmptyTryBlockAstVisitor
}

class EmptyTryBlockAstVisitor extends AbstractAstVisitor  {
    void visitTryCatchFinally(TryCatchStatement tryCatchStatement) {
        if (AstUtil.isEmptyBlock(tryCatchStatement.tryStatement)) {
            addViolation(tryCatchStatement)
        }
        super.visitTryCatchFinally(tryCatchStatement)
    }
}

Things to note about this example:

  • This file contains two classes. The EmptyTryBlockRule class extends AbstractAstVisitorRule. The EmptyTryBlockAstVisitor extends AbstractAstVisitor.
  • EmptyTryBlockRule includes an astVisitorClass property that specifies that it uses the EmptyTryBlockAstVisitor class.
  • EmptyTryBlockAstVisitor implements the void visitTryCatchFinally(TryCatchStatement) visitor method defined by the ClassCodeVisitorSupport so that it will visit every try/catch statement within the source code.
  • It uses the AstUtil utility class.

See the CodeNarc source code and javadocs for more information and further examples.

Creating a Rule Script

You can also create a new rule using a Groovy script file (typically a .groovy file). The script must still define a class that implements the org.codenarc.rule.Rule interface.

The main advantage is that the rule does not have to be compiled into a .class file first, so you can avoid the compile/build phase, and its associated hassles. The Groovy script file is parsed (and compiled) at runtime.

A Sample Rule Script

Here is an example rule script. Note that this is the same source code as in the sample rule class shown above.

import org.codenarc.rule.AbstractRule
import org.codenarc.source.SourceCode

/**
 * Sample rule script. Checks for static fields.
 */
class MyStaticFieldRule extends AbstractRule {
    String name = 'MyStaticField'
    int priority = 2

    void applyTo(SourceCode sourceCode, List violations) {
        sourceCode.ast.classes.each { clazz ->
            clazz.fields.each { fieldNode ->
                if (fieldNode.static) {
                    violations << createViolation(sourceCode, fieldNode)
                }
            }
        }
    }
}

CodeNarc-0.23/docs/codenarc-rules-size.html0000644000175000017500000010722312471222417020147 0ustar ebourgebourg CodeNarc - CodeNarc - Size and Complexity Rules

Size and Complexity Rules ("rulesets/size.xml")

AbcComplexity Rule

NOTE: This rule has been DEPRECATED, and disabled by default (i.e., by setting its enabled property to false). Use the AbcMetric rule instead.

Calculates the ABC metric for methods/classes and checks against configured threshold values.

The maxMethodComplexity property holds the threshold value for the ABC complexity value (score) for each method. If this value is non-zero, a method with a complexity value greater than this value is considered a violation.

The maxClassAverageMethodComplexity property holds the threshold value for the average ABC complexity value (score) for each class. If this value is non-zero, a class with an average complexity value greater than this value is considered a violation.

This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), then that Closure is analyzed and checked just like a method.

Property Description Default Value
maxMethodComplexity The maximum ABC complexity value (score) allowed for a single method (or "closure field"). If zero or null, then do not check method-level complexity. 60
maxClassAverageMethodComplexity The maximum ABC complexity average value (score) allowed for a class, calculated as the average complexity of its methods or "closure fields". If zero or null, then do not check class-level average complexity. 60
maxClassComplexity The maximum ABC complexity value (score) allowed for a class, calculated as the total complexity of its methods or "closure fields". If zero or null, then do not check class-level complexity. 0
ignoreMethodNames Specifies one or more (comma-separated) method names that that should not cause a rule violation. The names may optionally contain wildcards (*,?). Note that the ignored methods still contribute to the class complexity value. null

ABC Size/Complexity Metric Calculation Rules

The ABC complexity value (score) is calculated as follows: The ABC metric measures size/complexity by counting the number of Assignments (A), Branches (B) and Conditions (C) and assigns a single numerical score calculated as:

|ABC| = sqrt((A*A)+(B*B)+(C*C))

The ABC Metric calculation rules for Groovy:

  • Add one to the assignment count for each occurrence of an assignment operator, excluding constant declarations: = *= /= %= += = = &= |= ^= >>>=
  • Add one to the assignment count for each occurrence of an increment or decrement operator (prefix or postfix): ++ --
  • Add one to the branch count for each function call or class method call.
  • Add one to the branch count for each occurrence of the new operator.
  • Add one to the condition count for each use of a conditional operator: == != = = = =~ ==~
  • Add one to the condition count for each use of the following keywords: else case default try catch ?
  • Add one to the condition count for each unary conditional expression.

Notes

  • See the ABC Metric specification
  • See the Blog post describing guidelines for interpreting an ABC score
  • This (Spanish) blog post about the eXcentia Sonar ABC Metric Plugin (for Java) includes a table of risk classifications for ABC scores for both methods and classes.
  • See the GMetrics ABC metric. This includes a discussion of guidelines for interpreting ABC scores.
  • This rule requires Groovy 1.6 (or later).
  • This rule requires the GMetrics jar on the classpath. See GMetrics.

AbcMetric Rule

Calculates the ABC size metric for methods/classes and checks against configured threshold values.

The maxMethodAbcScore property holds the threshold value for the ABC score for each method. If this value is non-zero, a method with an ABC score greater than this value is considered a violation. The value does not have to be an integer (e.g., 1.7 is allowed).

The maxClassAverageMethodAbcScore property holds the threshold value for the average ABC score for each class. If this value is non-zero, a class with an average ABC score value greater than this value is considered a violation. The value does not have to be an integer.

The maxClassAbcScore property holds the threshold value for the total ABC score value for each class. If this value is non-zero, a class with a total ABC score greater than this value is considered a violation. The value does not have to be an integer.

This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), then that Closure is analyzed and checked just like a method.

Property Description Default Value
maxMethodAbcScore The maximum ABC score allowed for a single method (or "closure field"). If zero or null, then do not check method-level scores. 60
maxClassAverageMethodAbcScore The maximum average ABC score allowed for a class, calculated as the average score of its methods or "closure fields". If zero or null, then do not check class-level average scores. 60
maxClassAbcScore The maximum ABC score allowed for a class, calculated as the total ABC score of its methods or "closure fields". If zero or null, then do not check class-level scores. 0
ignoreMethodNames Specifies one or more (comma-separated) method names that that should not cause a rule violation. The names may optionally contain wildcards (*,?). Note that the ignored methods still contribute to the class complexity value. null

ABC Size Metric Calculation Rules

The ABC score is calculated as follows: The ABC metric measures size by counting the number of Assignments (A), Branches (B) and Conditions (C) and assigns a single numerical score calculated as:

|ABC| = sqrt((A*A)+(B*B)+(C*C))

The ABC Metric calculation rules for Groovy:

  • Add one to the assignment count for each occurrence of an assignment operator, excluding constant declarations: = *= /= %= += = = &= |= ^= >>>=
  • Add one to the assignment count for each occurrence of an increment or decrement operator (prefix or postfix): ++ --
  • Add one to the branch count for each function call or class method call.
  • Add one to the branch count for each occurrence of the new operator.
  • Add one to the condition count for each use of a conditional operator: == != = = = =~ ==~
  • Add one to the condition count for each use of the following keywords: else case default try catch ?
  • Add one to the condition count for each unary conditional expression.

Notes

  • See the ABC Metric specification
  • See the Blog post describing guidelines for interpreting an ABC score
  • This (Spanish) blog post about the eXcentia Sonar ABC Metric Plugin (for Java) includes a table of risk classifications for ABC scores for both methods and classes.
  • See the GMetrics ABC metric. This includes a discussion of guidelines for interpreting ABC scores.
  • This rule requires Groovy 1.6 (or later).
  • This rule requires the GMetrics jar on the classpath. See GMetrics.

ClassSize Rule

Checks if the size of a class exceeds the number of lines specified by the maxLines property.

Property Description Default Value
maxLines The maximum number of lines allowed in a class definition. 1000

CrapMetric Rule

Calculates the C.R.A.P. (Change Risk Anti-Patterns) metric score for methods/classes and checks against configured threshold values.

The CRAP metric score is based on the cyclomatic complexity and test coverage for individual methods. A method with a CRAP value greater than the maxMethodCrapScore property causes a violation. Likewise, a class that has an (average method) CRAP value greater than the maxClassAverageMethodCrapScore property causes a violation.

NOTE: This rule requires the GMetrics[3] jar, version 0.5 (or later), on the classpath, as well as a Cobertura[4]-[6] XML coverage file. If either of these prerequisites is not available, this rule logs a warning messages and exits (i.e., does nothing).

The maxMethodCrapScore property holds the threshold value for the CRAP value for each method. If this value is non-zero, a method with a cyclomatic complexity value greater than this value is considered a violation.

The maxClassAverageMethodCrapScore property holds the threshold value for the average CRAP value for each class. If this value is non-zero, a class with an average cyclomatic complexity value greater than this value is considered a violation.

NOTE: This rule does NOT treat closure fields as methods (unlike some of the other size/complexity rules).

Property Description Default Value
coberturaXmlFile The path to the Cobertura XML coverage file for the Groovy code By default, the path is relative to the classpath. But the path may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem), or "http:". This property is REQUIRED. null
maxMethodCrapScore The maximum CRAP metric value allowed for a single method. If zero or null, then do not check method-level complexity. 30
maxClassAverageMethodCrapScore The maximum CRAP average metric value allowed for a class, calculated as the average CRAP value of its methods. If zero or null, then do not check the average class-level CRAP value. 30
maxClassCrapScore The maximum total CRAP metric value allowed for a class, calculated as the total CRAP value of its methods. If zero or null, then do not check class-level CRAP value. 0
ignoreMethodNames Specifies one or more (comma-separated) method names that that should not cause a rule violation. The names may optionally contain wildcards (*,?). Note that the ignored methods still contribute to the class complexity value. null

CRAP Formula

Given a Groovy method m, C.R.A.P. for m is calculated as follows:

  C.R.A.P.(m) = comp(m)^2 * (1 - cov(m)/100)^3 + comp(m)

Where comp(m) is the cyclomatic complexity of method m, and cov(m) is the test code coverage provided by automated tests.

References

  • [1] The original 2007 blog post that defined the CRAP metric.
  • [2] A 2011 blog post from Alberto Savoia (the co-creator of the CRAP metric with Bob Evans), describing the formula, the motivation, and the CRAP4J tool for calculating CRAP score for Java code.
  • [3] The GMetrics CRAP Metric.
  • [4] Cobertura -- Cobertura is a free Java tool that calculates the percentage of code accessed by tests. It can be used to identify which parts of your Java program are lacking test coverage.
  • [5] Cobertura Ant Task Reference
  • [6] Cobertura Maven Plugin

CyclomaticComplexity Rule

Calculates the Cyclomatic Complexity for methods/classes and checks against configured threshold values.

The maxMethodComplexity property holds the threshold value for the cyclomatic complexity value for each method. If this value is non-zero, a method with a cyclomatic complexity value greater than this value is considered a violation.

The maxClassAverageMethodComplexity property holds the threshold value for the average cyclomatic complexity value for each class. If this value is non-zero, a class with an average cyclomatic complexity value greater than this value is considered a violation.

This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), then that Closure is analyzed and checked just like a method.

Property Description Default Value
maxMethodComplexity The maximum cyclomatic complexity value allowed for a single method (or "closure field"). If zero or null, then do not check method-level complexity. 20
maxClassAverageMethodComplexity The maximum average cyclomatic complexity value allowed for a class, calculated as the average complexity of its methods or "closure fields". If zero or null, then do not check average class-level complexity. 20
maxClassComplexity The maximum total cyclomatic complexity value allowed for a class, calculated as the total complexity of its methods or "closure fields". If zero or null, then do not check total class-level complexity. 0
ignoreMethodNames Specifies one or more (comma-separated) method names that that should not cause a rule violation. The names may optionally contain wildcards (*,?). Note that the ignored methods still contribute to the class complexity value. null

Cyclomatic Complexity Metric Calculation Rules

The cyclomatic complexity value is calculated as follows:

Start with a initial (default) value of one (1). Add one (1) for each occurrence of each of the following:

  • if statement
  • while statement
  • for statement
  • case statement
  • catch statement
  • && and || boolean operations
  • ?: ternary operator and ?: Elvis operator.
  • ?. null-check operator

Notes

MethodCount Rule

Since CodeNarc 0.11

Checks if the number of methods within a class exceeds the number of lines specified by the maxMethod property.

A class with too many methods is probably a good suspect for refactoring, in order to reduce its complexity and find a way to have more fine grained objects.

Property Description Default Value
maxMethods The maximum number of methods allowed in a class definition. 30

MethodSize Rule

Checks if the size of a method exceeds the number of lines specified by the maxLines property.

Property Description Default Value
maxLines The maximum number of lines allowed in a method definition. 100
ignoreMethodNames Specifies one or more (comma-separated) method names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

Known Limitations:

  • Annotations on a method are included in the size (line count) for that method.

NestedBlockDepthRule Rule

Checks for blocks or closures nested more deeply than a configured maximum number. Blocks include if, for, while, switch, try, catch, finally and synchronized blocks/statements, as well as closures.

Methods calls, constructor calls, and property access through Builder objects are ignore. For instance, this code does not cause a violation:

    myBuilder.root {
        foo {
            bar {
                baz {
                    quix {
                        qux {
                            quaxz {
                            }
                        }
                    }
                }
            }
        }
    }
Property Description Default Value
maxNestedBlockDepth The maximum number of nesting levels. A block or closure nested deeper than that number of levels is considered a violation. 5
ignoreRegex Determines what is a builder call. For instance, closures nested on a method named createBuilder, a property named myBuilder, or a constructor call to object MyBuilder() do not produce violations. .*(b

ParameterCount Rule

Since CodeNarc 0.23

Checks if the number of parameters in method/constructor exceeds the number of parameters specified by the maxParameters property.

Example of violations:

    void someMethod(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) { // violation
    }

    class SampleClass {
        SampleClass(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) { // violation
        }
    }
Property Description Default Value
maxParameters The maximum number of parameters in method/constructor 5

CodeNarc-0.23/docs/codenarc-rules-enhanced.html0000644000175000017500000003465512471222412020745 0ustar ebourgebourg CodeNarc - CodeNarc - Enhanced Classpath Rules

Enhanced Classpath Rules ("rulesets/enhanced.xml")

These rules use a later compilation phase for parsing of the Groovy source code, allowing CodeNarc to use a richer and more complete Abstract Syntax Tree (AST). The downside is that the later compiler phase requires CodeNarc to have the application classes being analyzed, as well as any referenced classes, on the classpath.

Note that these rules may be reorganized and moved to a other rulesets or packages. If possible, include them individually within your ruleset -- refer to them using the rule name, e.g. "CloneWithoutCloneable", rather that pulling in the entire "rulesets/enhanced.xml" ruleset, to protect against future reorganization.

CloneWithoutCloneable Rule

Since CodeNarc 0.19

The method clone() should only be declared if the class implements the Cloneable interface.

NOTE: This is a CodeNarc Enhanced Classpath Rule. It requires CodeNarc to have the application classes being analyzed, as well as any referenced classes, on the classpath.

Example of violations:

    class ValueClass {
        ValueClass clone() {
        }
    }

JUnitAssertEqualsConstantActualValue Rule

Since CodeNarc 0.19

Reports usages of org.junit.Assert.assertEquals([message,] expected, actual) where the actual parameter is a constant or a literal. Most likely it was intended to be the expected value.

NOTE: This is a CodeNarc Enhanced Classpath Rule. It requires CodeNarc to have the application classes being analyzed, as well as any referenced classes, on the classpath.

Example of violations:

    assertEquals(result, 2)
    assertEquals("Message", result, 2)
    assertEquals(result, 2.3d, 0.5d)
    assertEquals("Message", result, 2.3d, 0.5d)

UnsafeImplementationAsMap Rule

Since CodeNarc 0.19

Reports incomplete interface implementations created by map-to-interface coercions.

By default, this rule does not apply to test files.

NOTE: This is a CodeNarc Enhanced Classpath Rule. It requires CodeNarc to have the application classes being analyzed, as well as any referenced classes, on the classpath.

Example of violations:

    [mouseClicked: { ... }] as MouseListener
    //not all MouseListener methods are implemented which can lead to UnsupportedOperationException-s

CodeNarc-0.23/docs/images/0000755000175000017500000000000012623571301014641 5ustar ebourgebourgCodeNarc-0.23/docs/images/expanded.gif0000644000175000017500000000006412471222451017120 0ustar ebourgebourgGIF89a! , j ;CodeNarc-0.23/docs/images/icon_info_sml.gif0000644000175000017500000000113612471222451020147 0ustar ebourgebourgGIF89ar 'SG]}]yVpOgLcJ`EYxCWtI^~FZyehgjlmpXltvdyw|~wunzw…ǘƂ˦ΩЭҬџ԰ӵָؼݲ@TpAUqy}ŞɧŹ!r,r`fg`l\d LG^qqopnQmbj.MObhNgr\oP6 [ig%dmE4k_^eL PRah YcHBjfV F`\- 5Z=97D`] I' 130@KICA@,"c $XA ?tr兊!8h2† @Pab ;CodeNarc-0.23/docs/images/icon_success_sml.gif0000644000175000017500000000173612471222451020672 0ustar ebourgebourgGIF89aΧμc~w˗éSq*/%(#8='*!37,/(CH'AF&>B/2*,)FI"!PrkjtŲFcO7G;ȝȣ֩۴߲2B.ᥳ⦷㫸䬸䭺导屏€㩲ࢲࣜΈޘܙٗۗ]B΅ԋۑ̈́՗]>Ԅሻfrmjb7Jw*U0W2im;Ag$r?o=e8f8b7Z2Y1S.Jt)Qy1WYuQeFcE{{hGv@u?k:h7`3Jr(E^3Q|,S~-Dh%}DEi&QŢIm&Qx+Ot)Mo(Ll&Ig%Gc$!, HA!,XE aCF5pAƏ *01#"NT0A=Y& NRI1bJ':o8b3-e˓у>|¥ (qŋ4hԱ(ЋmT"J;*d("4lp ,P( ;CodeNarc-0.23/docs/images/codenarc-logo.png0000644000175000017500000007725712471222451020105 0ustar ebourgebourgPNG  IHDRf>sRGBbKGDC pHYs.#.#x?vtIME & IDATxw|%u̜޶$ٜ˖ޤ( vݵ\byUDEw"; ȕPIvv7dkzr&_fux3eAw7 @cB^͝[ѢXxvᥥo*2v5ѷC[yH;g[f4и5X jح̔ǎ(EǏbF ECb$7 laxg`WkǢ%nXC2 0LKIJ(XN@ 11L՘$IBuI`@k20{%5GjO4v1X0}vls[>zdm}/J_fIt{w}Vu- J @QxUF15ijo<~%&W>)QXҀåy2i& ox1 L\@3Q4uX|2}$ @B #  XUvǺ|x _IjhJ6D$Xj!xÈAU.lKV jJfTkj`?mM۞Y | +"l7[-"@^- k/H^ߴny4?V_fltJmԳ8ٛ7USTYM\b1USlB=ؙQ?us=U->oJ q4\W_|!\|:= __5p0cA]GɐN'o>cacN4k%)@A #$"NUgnp&pII"E1@UWll&/>̓u@/pas]8Ŀ49xY3T+0ʥMQ\>W;J!$i@@DTa۱_ 'v?cpr& /UXDo=vӻ~rޑUd84`jn;sSѓ:. =."+m(ئb+⇫kg$q lAT]U'8ثRni[?xCEP)@ApPmڶyMϝ&q%bgNz'b!Dqqlyinޢo?+@oޤOj\V!19EDn{oG`E N t7`APEa47Eua @ iyh|H7:šNhr8¯EH%@w7h{^Un/ u[|wow]{e@]v:#v*71{# PGGpW","8?OP׹Ny 9ɦqNs7_nmU4fC @@T~ ([͛߀U&%ҹ(&al?"aaXaXoRoD&y r @kh8)}VDRG N抒á&cCj;3c'\Wtp{^i @@w0k*ښW5,6u\ PUD4u I0C5`'e|rH`p^ cbbc.(#)>Ʀ5D-?KXٽ^_Mh 4,Y˾Uz~%v6ew%6?ѴmcKmsZy>oU?0LjH"Tά';˃@|79`bV+\Hɦ}_˼pJRU|/f˻Ȃ³-wSPƮ>{0eh^DbC L Xt*CW|DdO8C⚢isE t'3Cؙat׵1G1bXXV3 E1(F(*F(lioisIoEuk:ڶ5}lf7и(7zCזuLVzv|h5w.I`š\jc-iWڰdKB}cSh{90 twYǺ̻*bgRLbk'p0n6dQ@0C8bp 3RiE (T$Խ:3rU}p;p+EKqjatQɥU>lVEi17)%/Ag#ʀaVKtSÒ ɦD[U]1j$Z4-T[ ˁsUg`m_UPV]-N6=[eg+Ɂ< g"Z4PaVÊ b.N NE'3DYcq-HlL{^ |Ѧ ĸ4u)0 WIxfL=j#b4,c˪Omr >=L,1"ٻtb@ؙ cĖʆ~ڗ>Ѷ_rRQٽ ,vXAwo,>s%ة4bVˤ18,.n8M(}&%kaE\tamlM-U"_u?e P4d4ivIUR,P @}#wOd%N6M:9ƈ~BU}%jf2zS>+le.Qض4l>k;XR_u#];w5?BqG-;N#}fZ^p92fʧC熫BˢHJv8vV!.7(Xg ]ڭg;:q 7ILH7 z{'R ]ߋk-I9ryb1"*e+ffyRodΊ./sC6C\%<}Vi)[qiEsO+)-@;Cdi'.\G?zp+5qfbj wVenɸ!E$k}ﻛ@sE=M=m  CT0!B\""U5uжjQucnv;:6dQukڨx뺠꺨:...bNMvj/PCuE0{ຫPf>>Y0s'VU+foT׎oU 8ڶ3+U_u;=ڽdfEkzfHlgx}9i۳ l+vj+v*gb` E>Q[]uTݜ u]#u׵εďz+%, -n: 25JiZ [ZrH_d&s [ױ;^>6LHTq-!VH$S},ZPM:qnS7?Di'+aㆅaF 1 0s`^N.68YpDk8kgٺdFp-uӮ>#"mlo@NݦdcML2lCp!"r~pOpqe,b(#g4ݵm4=uz:i?μ+67[IQ#7k ` KEId\JU %G*-ayo`B4ϖ#ۡ(lxN%ˋ6MvӾe+NWɈdPa NqijqD+sڀi!fôPiVwQS<! ,BN ٲ{Q8OOmnshl DyAMٖx-!e.~ۯ[}E׵?JM} c;iO;#qlΙF:ߨcӻ"No<^Jy?!J;FH{pA㋡K%9;T矷EI`oo"ӏ ,VdlXt":v1қvY̙1xTƏ$Z4 s<7Ʋ0iyc` l~ D8VBśJ[Ѣ*&_4uuž<[;X8HFK]=9{ueiQnN#=߾^7?zl~jΤ"~8#'7! iY l:jN[+/~gԾ|pUZJY˩:k9󟿔H *19A>HL,@1mB&Xo`]6=$6'Nj66$giR"? Ocp`r=c듷ӳIC ӔhɌ~#%j?KU,"-"8PYѻUE UhraۻBo\aDSx_?gZAD?DD? dDkkUq MlX|e^tK!״3s̭ƈ)\8'dT]R]a` HaK|ES? ߿?@B=az62$?zly PPčXz,Rn/rXUSwHd(?g箮6O3}i9j;u3uoX <vg燻v]Nk>X%sigΞǜ|;p՜Ľ*[دj89sh "0zگ݅.b"%=Ԭ/f#Xd^sp3O e6o5 Q@QU3C=hgD0߹-Of9v.IP 3DPa;nY7|JU#"olo}lUeeW^?6=cEoUM^6~Y_ҷnx]]ߎCױ$߆杻%__SDhܦX>鼌C=?cյuLi(bȟL7+-(|YXκp@bVׁCkg3|)#L4{|}um|BKD%e%z\<[{ǩjUMD>sfUMݪ]f " Ȼkl1:XMU/QibW<-F.qMbxobP֑"###0U.l[&L6 =˓oTG'K%7b'E![s5^O폓ITp]=>(F4VYkViIl܄Y4F:Gi 7csN_*kIMMa`#1OF>Z0 +PyfK,^y iS+լ3wۀ:CvP \ ^U|*"!r~6obioޖ؟N@Lr+w>>VDޭ-I'w>^;XO"bWUյ||9ʘ"1Lef}vumt_ p Pc "#"?m:U5uT`1/Uדw'Mm/"7ͳ?=sH js s{{{6&%9N~Al $0¨dwba?sBtzN>ם KYXJ)&:'쾫{`=*Vq!u%:Oybù(1a.H)hLLjpmd ?!]B"B(RUMo\\mʤjhd_5J"&hT>VVUDu_aS F[USW*"WjĿ@uvUMF!`p9T6niY3pD F$/VFyPժI)z;`'cZ"r.}oT}0x=*ևؚo Zյw*յqSU? Vfe IDATY=t0׎=Su7pb2ĖTmbأE\3R\VFբ7aƦnH&\Q:QL6E1j.|f[ۍto~UK5YK zvclT͋/2ky?䙏}L,^B >:"]4h '`,mMD Jf,LfY˾6 CE,౦ks2U˪plߴzߊt^(N>7_?RQm9s~n~.o]\' pPUߔCm&'U=!C.V+VM󭱅]|R";U53Gڸ'7>ZU]^(*Oy'z+c U={qPՋEP!oOSxC 4X5_qPŠ 3Ѧ󇛚X|6Ѳ9+Eipg8+1vև."̥f,y#'Y@SÔq)~1ʁo2)8j7}&Oz>J`wRg2U@ʮwX NU|ه9i+'#^f_USg:`,"H!\7yndLyuSG۠BU[M0?Uw"\6c%5#V163bdz{1 hJ(:ln*E3R4*y=o/%Ke;ClMt8b@!|B8oרvTU/""3}$2""G" UsD&&y7$rjQT7%@á\7>­:qxAD?3"gD^|585bR94"%ɑ&YIzv/TWK?m[n͍c0Prd=E˖a=yy4lptaz5Z*`- ^;tH/%;[fD(|OlW#O񣜢N7[ S{֓: e|OhJbҿ&Jwmy9iϺV_un"ohLM++:.{wo~[69s;5T"bXb+'& 3羅R> uJѫXt7}̝C'a(D1G^KGXټy7 V)& I: G @0OJ~!֋Ѭ݁),$[4:>J dڂתp 1e&"+[o V-rN8o<'2ȈH`nL`y6 M:$OjDDjhi7NxKo.>}L:-Z)iH$)-aE9: s1KvlOO739 ,.#PF-!=0H{y'B 3(\aYB;R!zF@1H 2 #$dzέޜ1#y~INjR "%)]1.tK]@sc{ 1GSyigCVU}pDf1v@ 8 G3ʋD:Q̿W>{c\ hWտ[g92Dd;j !U3EUNv=THGdgIzW!"$FrAIZNxo5x=3<{y ({6iGUq)Tk>c{-B5JȟU{}ssM[yOAQpX"5)ƈI@(λGwywaˏ~J.:-E&^v\-E03L{nfQ]YYTNd)s; s &5 ljȼrX.Av_J^l0b[XBp!fPC)PNjlo}`^RF=!vPJ'T{E5c|xnPlb Nr$caHft^С$|-"7/*_d'ݾOn$W#KsUKdKȷe^Ρ(i1/uxY/7/"r7f5^}+ӨTDC8A"TJ,__ɦJ1"B;GXoor'j<8:#C-Q^;l쾽oLlw/C?Ͷ_uW_͓߿v N/ }).He(,(IQQќ#ȓa[PA gw:G"HV人\tKIz~|B`>0s ':܅mwx2U54P&"յ"Oxd?O0XS'no,|%E$)"Nl͇IJ DwD( /#ryR)ܣI-}xۡ>VU:txU{9伱tWt'SGO7z jbU]x{.߳\{c k2F +%-JhCIcNTbۋu_A*n͎Q2q6ف!~R;vзy<IrVsH9ƝqLdX߾]TWDLj*Cخw20rY{w[e!B#Hۆ)XZi*VpW8.W4c"Է[\Ȋb3񄙷GbRU]2y(ﰻO("EDm7xe1q}^8)XDd| +:GϋWq-"ҧ~NDTU)<#_+jN$#W-FTuxՊchO4@yжWt_?j|SyĔ J|ơ7f{VDp1" یdICST(&|~[̏,dplv13Kн{݃dm95"ٺq(/eGvcC 2Y0!wa ³*0cap\d96VXP1h膖xC55&Q@˦xKXtLg&+"s`&RWӈJĶ<_D#17w HUϙUPi=)gΝ/>jUEdgii|WqS٣ITʑ0#,<9 9f*%rzLA#_IaUW3.r[`X1ʘ`b&Νh( wB~\Ɏu" .>0[fKoʹfV۟@XX Ͼd! ]60 \vs Y^ {I(ňs&L(8ٴPl|JU?LjkfdS+:{f4E`q ojDq'8VU'{''P]c64wJf21UdTu2yˏm+:~G?>2"2b^URUOU 2B)+9f~NO6cEkn(&S<݃+:_=0SUB~$8yL!`'U' hx( $ux1CRA$W@+c={R.`vbn1Kfژ̫$ə2Ma,̜r~yx3eXE& ']z\jL""1Q%TV RrPWlu]GL5~W}4NDռFv ng_"hx ʮ|'׻8LD|<"7UôwWEdD_?y)UՓ' [ٞm0{0'|w=Ms2M*o+ 0NTSH""sVYu6>+_\ϪVvul'"wou"WYx\Di>4Tvݥe|ל61\M'' zҬ! lMٵ4M,bq6o를8ʜ 0dƦ0p vޛ tyazmFYi)ٔCAEii03䅷 C0P<˝0Xt6cK8H SF]&s@3eE."P4uזd+"q~=|w+:յ+\8wtlQu r hnjɗ|O )ܙ""Nj*[]?] UQK+:z9m֩I/o{2jqp*NGhntumOajvVꑓhz}:~Vk$Ps]}g/v=Q;Q}:uCEQ4l! !3-GQ$\xV6Շ}f/bg\?EUOSղIڒ/}LUUuTBx/O{<iQSptȣٴ0žSDT^{um|GLdwVvul#[#wyi}i#Wc9(,{Ż׿"?d}/@XjbU"G;7UO L@]{+xsFYG5@]F_ǐ >BP ɺ 1PYZP2pH"^^D&kgh$)BmU!Om}f*Ƶ+1Gk&f?r0"QܤW59GC!PF2 j?:"rZMT 7y"⮮?x ! OU1Pվ]c~|q>ar7֯jr߉Y&!'U5uQ9ȩi1q2J%-.&ޙQyT{O:[ެkXDDܺAFų3#3: t+MX{Y}z?ܤɧ;}s{#"G_(]7ṷ'.7ĂozYUQfU_0S/^Гdfh Ph7n&6c5.Lglq5 3YH 1q1cTZ27p,o+l~2g B%AQS?l]Eo/yb IDATࠞR&P6>EU+8Sr=\cP&6I}sSض#wDsj)AYPg7-'`*W'LlUvm | q-{Hw`+AT n%I)ERD+h'۞z:ҭ_0g:3kr]$T1LnJz`-|KDdpLYrE3׷&)"LuLL`B#6Kw+/k\f\!Q`9س iӥ BUzpfjq; -= ^`g2BU},k_>JUe]INU74m:X:ø*OTYW˗d@ɝXT,ա)sni*H| LD"E\ S[ W"^_ *"r6~KNDmNzqu{EH$OOs}K#9uK J49 x 7p]Xԡz$XBX4'|w0 dNqϧ!7ɊI{{AXJF1 !Bx 8Ě^Pͽ쥪)<ơgyHH3k6$DUup[DDRDm0晘=R[l{AUJ2CLjoٞ́18j6M"4<7I^sTIlwL"8Bw?iϙX* k+ϻ%6; ED#"+f*.[Ddd:wN3$ "eU}tznϰ:3?}q~)E%`T$yVDء^&K:+^3$'V*XΤ{eq=NЄgh^)0xd%x^=шcYJeް-Hw{i=ˏ; ፎUӸBnn + Lvz5Rض<&:EBqni\ˆY4ZĹ+*4&Vt33KpI`xtm=,?EDZ&LZ2^=3A+mgY$L7T4.5=!rUmA?9utklT*io'EiL~s-(=is3DdXU?qAOgת/" _tgv}tJB8b:9~YK&Sg{%ӐZfR *nL6 6}{^K6I TS* i^T$q$ Nχc25E͵$o>I"6#~N\Uq+%~߶9N>flf$gu^K訏 Ls}8& = 8ĢDb)":ƚ\{EQwf變!d!<("?*mdfCU-{{U?v!c$Y`nMga|b4Գ̿T'vTu4}+4%yzx ,MVU*~e=Ͷxs|YU,ܫx 3Mnf-KwXzU@_~}䉆i12@TZ;3ٹ~AUѾK+;Dc/(Qޅ_3A['JCƶmш͂Z6n-۲H%bm #vr8ͯ0?JT"IwRI7.V4D }wxgn v*%jnf-k@z88xn 8[+NݻUd'۷% ag;ҭuH* L/LԦB~nUzhw:U=͚yr"ZinCռ$57Or-VUg;AV Xc%sh*-9U?O>`SGr(va |~|*:ɘ끓T53 wT=xYK8q5dHOC("X@&:E ,"jKtUkegEⰸ@D^TIJxcYL A'Yת({.mlhǶF){>mİxr+5uumJ^qq1ıТ02RcMn9Dؑ1>8W5?pwܙ3=h!hs"CB;uf-τ&=7VXE'7_>d`fS]'!"߭ٞcg ^'"MjDv׊ȻDS`9T޿ 񹠏#Ph!UM`Tn{di!kHod0OP8:ۧ'?aKpO4,YtNfYM"UՆ2k#&Y=_~D~4im߮Ӎ鐲*i AS/[ś}-XXbؖHP3vRpR@hg4]iK~ȣv2y^F XMAO0ׇZppbQh;²$0G0y%궇nl> krugoNmGgj4̷M@#l`ɰf{~e-ˁDXU}a\LjLj+mNIOU1Q=MnTKkD8CMQDnSٻ:rPdH>kR](+`6lylZOnuK25/_ޮ&PAĄ8L{Fhn6N<ⰫzAr®#߼#5i^-v٥T.7z P} ~D ǀ]{HS4̟͸(Rg!5L N4IraX0F>>{@ͪݧܙ~~ xᇿL7A*h 0y63My搞6p*XYKq)6ddaaϗT<g'!;@u2& dfyݳ=""[H^bi  r 0_Ūѐ!tKcYGfL^8MC]q -=ltQz p INت8=l]:UPQQzĵ//8ٿ& -ѴZVH4~ 8KWsK2y(#q M%#$d6Q[ԝrR+3a37G۱'>}! +kYƊDvƷl!uppXSęt5}bw v+y ǼK't(uۖPiiTg=00<2}Lwυ\La1_~-i䟳>8XFټtpP1PQ\ pBUo}=VU?T DblSAE8zRKC>}GGp"6G/9u&cw !8{ ץz(?z?p6C]3g|k~w{gZԝ״P0`xo|= ێ[("SKI!0'SI}% }HF%u 96X=LAgrq;=rU7e >5Qy^Me!MvFL^;=gB|0טO6yϴ- tX{H!"ɤ<ȼS^iu4̿bG ~cP(XzʞG-eK/_7}'G}q~sW1tf߂,M9 ?=Q>jqVbrppqIߖ{ٛ{t8hA}g{"np54OUk{ &l ؞."t+"1n~>)fa¦+0ږ+9XŤ3 OTU~赨)~,s9o2t-"y 3x)绽vr;ҭsTQ+7zadL`blS^ijp(k_K$WfpdJm'YǟȪeMغ{MdoJ`0i'ufsl6VG? %"W+_k:d xuZU?L@nƬW"QrRC}orppn\D6/ĉncJQwj:L{M:4DO89#z:cH"vݏ+Y|9-btv-Ė#~qıߜclK"6Nl"8# ;NL3?>}G?v-s]E+]E R[ycF&8_8{0LRUM"rJ@P$33}dՑn=yHŊ"wԷ꭪z ,RW6[_I4Nt3tӑnMd^UDjTxCP'" #^s~9ϵ81?ʣkW1C{X zx"jVL[s n<=4>`ȴt+ɸiJzG9=h@;? p<[ʂwunW4VPRHui>TRۀuD1 !KP/}[|eJʝu׭:}^&Ͽ\l\t^n <Z#:ODE%۳=_g&[,SX6SD\ޅnܞpyh}mi!gGU?<~DEQD."^m3̯ܖڗbipVխBg&[OP[PˁEx"Ֆ wkH1sꦩ\BW/OVҁUUcF:#ݚjwLתꈈljuCMϜLv@UGF| 4wf^UuC"-"+([r]ߙɮ2"""P{wEf!.F'q"R%T('E\WRj-"OxNQUKmjU9_U"ou @%(?IDk}KWeDeAZ*!Ŷ#AE`; XKcuqRssH\]WmYl+sx2::F?#w۸򥬺[Dp EV^O KLtQ4qI%@A}Śk+q+3v&ka/!$R8lMbY( jdh_1`SMcמ/ɷ~3<+pۋŭ18t[E΄@L Bs06(\ sg&;D)/kӹb*Ҟd>ۚV@h|U]>v*CUҸ:3wEde^+ d߯庴#%9"ÏY, iw8g3YHVDt9;ˀLcm| &OܖO7@qrhA!!Q74@Oˤ$PgjNO푦tGK =bADx|,_|m"))")"Vx-׵3=VՍl1VlNP3=M~n2BiJDR!NĸWߙUCÝU0BS>`]g&;gDp]:v6stkA==ܙ֨;T"rpTsH3qAa €"C9PU_Kjy74զࣝUuSU0R3gLeN^D^$"?0㩌}"rW(ꇀU~:z>Wg/¿BD>c?N~9@Zk BU}G]k$UxeRXbjJSۼqze|{.Np{7YXӂ<q<zgѧ0TPĎ%Z9+mŽTcߥDXޓXtΉQqzjj<(HĻkOTnEa>Dr~RYgN~uB\l4ʁP=&"db.L֢44?6T&V7o6U #s;3ٷm<+r]tJLB_[Ús4ڙɞ]U("d[-LJVևPWU s\ayܛwdxg&{~8MD3Zn~D(|LΏݾt;Ig'S;w)xap0~ _nA]O,;_rg-*hҮ^bVdy~\c͋{[ፏWWß4?==Ɨ2V,$AC> ztcR~|73h/[/#$VA˲>PhGvZT|% VZ,և97~xKK'"oH^ٞ^"t6gm<Ֆd`s v[?i!< 5Бn=iÁ#_7:ҭwOivm/C ;ҭ "2hҽ8 JLl=}*&[DT|6mDafr]V,\vfZ#< ӑnMk37 #"?z}*+SMױ0iU \ p$q{ləJ9(Kc&vb(M<쉼a|sx?`€d}M5ˎ \\}ւkˆ}KS/` ¶fׁځW=ױ^K\ݷtnL"s- oG! m?aId*k4EK8SYfob-^#XW]R,gHX8N`]8l!VĊ~PF}tOZ.iȯ;ҭ \f\x> j+coODWUo4F9͹$ϙ -up$NDl.H=%ݙɆgW*M ̩{e̪)T:1(|L{q࣓(s_Rϋȫͺf{E$jY_r] L0^/"1A:qn鞇` T!R V40OtO>5'jM"rg,ɤkkz/'vLb"r 6"%D1*"?ZӰ==ԑn^h]ٞvg8D}FzDW>'(ek>әC@ _ftfT5e\;eX &q{x5̤Q^D.ub/ Lֿ3A>qMˁsc*=0 >` ':3+L/W'O3VE̵?z?a|siE{kǘ-pȒI@Y;ŭo5W=ߔ1tR Lq3bQl O5࠳"`?ŊKw >\= x4ѷenQ("}e}%\4_.Nn<05UYC4>#DJlNѤ&(A}ۉKuPQ;؈؈e-UG V#~Dq # eRe GtxO.>t׶OnyQ9Ǫ L~n3nL\WVY@Xqs/8}Wi$R+W;[t .ْps{QW>3}[d~qwUc7őZ pIϭ$I ;Î$p)x-D[f'2,9nSG)vr~_ř-\ER;:G'9\]]/(끶\WAl_<,MZL41Gr+`(z$.@HU^D>_H\weU`ѫNM:-}䀾:)iAm1A E5UR%Cx]39I6`G+DWEj_{MŇ{T`rB7l58i-Tb?6gL_Hr~VU^b!TnrH?Ҹz+R/eƴmweMv[ȇE?3ֿ= [RHS 7⁣TGKP-]glj4m&Ѱx]3-2wGq!N6oEq;3/>_[9|_U3iت) U4.;;bT*Uy@ #};\Wm'&TD{q|\|,wG;□]x,+1\XJHf?y,Z?~u%e;ر(V$X>^i0KhvbE?s⯾yGMD6UmŪ*X#Hчv^ezűq ZMT*U94[GݒG}/x?_7љAQ҅5yvr/6wX6EŅWl f'8 F!Mj$jS8N<%&x>' G>,>[\46HilTDŽ&$&&$N,T#d]Yl"/eTͪ؞"=ݏx9tw]Fש{7^:f+*U!x)*NLik8ZiBH&_xzuK/ɢPS>բ`'Mdr&pb5X%qNX\"Dfͯ%=>7){?^Vڷ6ӺUxT Ў9RK{:6s]EYڶ?.P͝uz!,D_{)#R&cYƉbGRSC UHN[ȿHAe[O \.ry6U}/p~lUJU `UAy틎>S>aI.ML|ZDB5*UJU^ўޗ*""WҧzBԪ=㎎Eo.;J@wURT8ЖUOK9<8 qUmLb*UJU^ hYDߙfE\E ru[mմ֪T*U KTLgiwѹ$SW?e{űcHLNk{kW5*UJU.KypmF[RmDVď/[)W~?UpJURRXUx[Ŗ`>e"YEŤ/yΦ;R{cQ+?T*U1Axkial7Zd\Ϋ>^fڷW[RT SGKJ(*"qE˂hm.T*U9PlUt<+|Wi{_y艃D ?!ZW{$^ v񻧭;y§Me&<*g]G '/i S)pQV\XO|Q_SˍlD >n+,=p,']$Ϛ*۔v; M+*#jv,pH]jjȑuUUk u0ۣG:$Aus=+vGq7ߜ3wJW8bhW]Rź ǰD?KKHX;ᇩ* qO0m0a݇Uw'6h_2y8YD:WV}if 5"og@gR7Sҽf-+H3w+ 01p) z&ip{ʕbY_k5"`8 1nᳯՌ!23q1_"c(jL畡-8C tA$MZ8hXTf1WAN ]_Hw }gQXj*E0c}ޭ@&O`xo`(Sjw`CB(fjzϽ\[{?? lR.J\s粋>_FӦp\Nu423O}!8 Tˆn@b2+ٳe*;rDB/2یUxZΕhĉ4UؓjZsFHGMJ)KŻ-Znj5>4|X78{zqq\y*VN [Іo 4"ۡ P 2rf o߮۠rXDD++gHXfRuD jvyۢ@:}0]!Ͻr+*w3SA.~yZ!5 *wK4YJT7\޽1YջCݚE9 Zgwfֲ 3}S:c}%TLM W֯d )`$*X\!}eˈwG;t(ԛoRKSEϞNP4"Tc@E(G\d*OqFKzg"Yu@[Z'=}Pw*Ɇnk)ݏ=9+Wsr(^8L9j]pk}&;7-kĈAUrX'O.bOD}7+HfVeD~]wMc~Zw.ɓ)~޼ħ5V(t6)CSvC a n~X)n})ŽU] V6 r~~559WK :lsPb@!PtR@3cF@ Ued[@CHHa^68Uinn;79 Yn꿸ng\3h"WȫԒ;+rWc!W T,Zcg I;pU"`(0:4`v 7`@~>EϙC-4& 5^_P@W7hV^SŲ hmWWVirf5\GB?]`/!8RtZ zP,ك cY$< jEq_f7.6"$ËbJSOq|&Q?oOuMrX'.|]+q+#XgaG4JhȘ^B "c2dzӧEk>dȀ]`*(^ JzQg o"f?i YY4M[d@i7کST"o )PxM ѯD6QWzjD-{"B xM0vRrW]Əe3dHʭU! E=\:犐7fq$2Q*34]CY`y?dؕ 6ՄNjmc! *w QƍT[NLg1;2bWU~@Sc_!_ )MI%hl>T5`' ff@k (s`U7?Wi4o۴:mZ4Sy&oOJ*D*b,  S.^FQG b^!ܸᵔz)'A }.}e@ "t̽VQAl- 0*j{o7Ѡca@.g8c3av{)A LaVqsW* Uh j A)Ʋٞ%KDhj3p+W2@J{Z!*o(" CZ{R?p:MAxC㎞;W EFh>B5>o,?TBY;nd߾'xLpIv*˹?  Rڬ'(=\ތ.wu^  i /?4f>7|{T6VcYu @yLb=zj슱 m$WAW:s&/՚ |j^8 [XWZCg ЋouK+{Ws !Qbub PR X}!E=ބZZ2rqq>c[pC]]v [ox^ڂ-EfYrdP81-֬9D" YZŽj +5">ŋA`5Rn"(E:tԻD^Bw?K2ހy+Ycn6Ѡ`MFS)SgSRӲDAE~ V{/Hyq+PY =Űq{[]?p K>?EpU KE)MŬP\)Wyb޳WG:0!sJ Ѥddf&%qG !!jz=<\1²# uXB0b03Ug`mn GytiDz:fK a ޓ[A_]壅ڛ(OnR.5 U*ޒ94~)Ȃd }U 7 x4OAëTY>Ydn$j5>|fddwbRx1RlUgvO6f{L!dT6$+>|xj*?v`}umA~A5|XإSXؒ9nWx)Y,s`-$|WZswրM~ Ê3G<)ڲǓ rq5|XiGwf[SZi k)T1쐵wVKdn3/]0aU$!p8Қ{+9bG N6F0 ,#llj_Z OB%KҲg&tj(ᆰ0+P1@@npXH t.i Pɔ$n3J7XkQj "3!z,@_j2V<7zպ:oB0(6+WcM6QyP0 w8*gPƠ0e=H&~d9FjK+ti[~nNr8N`uiy ޘ~sr^ab_aNâ %[jP q`}{d'Gs6^`: ź .W6nu4cY1VauuN7Phb/fA*CCz-W"-L5X{}}vM^E{:s}4S nƚ8vTc6kRB=^1h-Wx,|f 9"gLs<|x[Sf*wlLͽpCmh ˖RTfN1S}I(L-z-@}57bϧkB *mnٳ٨s˦ i+LS1Fhc 2`I5Sic BFTc ׯp5 م99iWc/4){+LcTV`%8,*nM361V\bf*m0@ /OU< 35SicFGPΝT<I))mJ*Nwh]a\ rJW-M4Sic%e_)ȎΦ 4c^T:$F^5Sis`J }r"WҢJ[gDo׿]}h{f EEiPisXo۷.n i+lב7D?M+ *m=VVo>qTz ,W +4X泳Mh6QV´iϺ N~}V?<G;W#끦Z%Amp=۪A7^,P?꤇6o4y\-4yaT4 \PiӦAMJ6mT_YMUQBt-IENDB`CodeNarc-0.23/docs/images/getit.png0000644000175000017500000003533012471222451016467 0ustar ebourgebourgPNG  IHDRu[[bKGD pHYs  tIME38.iTXtCommentCreated with GIMPd.e IDATx}yUՕ((" "2q qjN'Fc;i[_SbŇ/cD;_ԶUg (ŠX<q{ϽU`!P͏w8s^{o}[>~,F20@ }{@!0DȤ_Xc2uk0=OqDyO_??ݝ!Xz l;` 2R t…[Op5 X~0|nFFVl?o g'mc#f -(PӋ+^$b~x^aܼvu=*,Ϭ;8Lf韉3qFƃFpC'Dqvf䮅/.T8Njޏ90.Fh[E>/Np ?40w) C{}J}O=WF00z?Mg =nK$vؠ3\[XD~:}8`B? kD>IOA>ψIPz~I伡C_{oyOploXJFdXaİ# ?|͎A{$Z* Wq"^D2pV $[0|ϞwMdQx3`(I_hswyz3(g һ23~hx8&03A,+Z_Vv\p^%Q"h 9@ 9nU|J'`eXQL"x<#H_ՅF 1$i% jgǕɮNy9n2Z[XoOA׭M:ٵ<%',!~=^\.b}8_Zz Y/R!q(ΘB@axw!XdB@o`lv~PI8, -ę| >v `$ʌ8xX^$pz 0*vIa"^O:?Ɛu\A F.ш_I.l;^ :߽fXg2A?b`H`DxfB\;@JIEV Pw_I4p6@C8=Дu 1<2DFy&*>lg|_(3ηBDWssスa1MEe<6ldH%)'i ,UH/nqq73㶊bmYB9^&TH'vwͥZQOcI'_ f1[[{aCu!߯ e[&3~LX7 Jp f`d:)>>߈CBiD{oVW3H|j'-X^O JKqޔ>ZaD,ܽl/䗘E2#}4NvVv$4 %oNiG2Pb``qS 2֮E[m-rPX^q03q9`ؔ)dq`M !u6ƪylײg ijQotMl9hbRr Z!p& GkH7_M<Sn.zI}-Xkaoe3fEӶkW|V3&uݡ\)M$7H"ʚT/]thaO!X IH;֐.wk)L-7wz[oň~6{2^WѶkWζ5 ~{HL?S4~<Λsx$ LrFw{;Ѽ};\oO?ޮ^P2A_yY-I_݁(lk H4]&T-{*{-`wIWnm5a.IsEWK>gg/G`ÿ{6 Y#O<|Sz}:^N=wQ^Xy<{yLsUeX*'-:#{Q ,oju6`y`…Y81}7Λ/.go z^vw"*Zg{سrunՆ) Brn+:][$8}̙s_ƫwjj$2 Î-'þp>wmBdme}Pؽb3BO\z HsYcvn\ Sf]H*& 諮GŎ^`7tL{>SWQ|ToIQ_j%#`Y/DQ*mqS @cjj ɉk!(D h? ?\-_>T @nI xa1v_zmxqac8&H1(% ݁u!qu H~ؿ~V(3vҥ(9sGx()!0.Ӻ{7=|4or`wg4Š0~"hΈlVV1Q!l(7kfR |:QՂ7C0llۧ °i{z2Bn!|3nUEgG?W\FtaL6 35! vpV 4])*%QOmN4La /?Ib9d 7*_5LlldeڽlyTjZ&ܭ"T-$^j@X-gb!U3,(Vl,FO'M?|Gpyo|ټ}*cQ0|xr҂ukV%S9&X@"ð(r.GoV`#YDtǺЩ%UIfN6W[T={:Qti`#O8a~5k$DYB{daZ$ eIwrvoXأB)fئp2d鍙 uPaT~* ׽^Xgwӆ$ ξz\bXCFd3+3$To(-8` BTa'L5o$L$ k BÙHd3**P]\N; G~+׬]v(ޢ%ȓNTMݲJ&lѕY>$5y2Op% Ij.D^k^J39LTؼpa90[PEt>Jꄺ5k2~HOiaBΐ!}͘ זO6[y0v" 4Z1!MRrz ְVMe׳oc2kP, sάzmZ$;9hNqъ~8Taa:*(6jSG5jb̹=F a-^WkЙZGMX-rϷ۷]͝}{YJR@G5kֈ,u"OK >GD IDtwNeU\oO\5WK…ؽdI(b\{*?G8dw>aflzQlzQV M⨿}.,<tq.m{gI͎Bs22Ȭ!q%>NV `(Ŵ38F[w I~s r0JEFBO>,nLD©jP49%A7;Mƣn :{eN( Wyfc+enH%b#KbeQhȠ ԀFjY AǂPqoyR QwL cC7L}A !z A/PbdhTekTG?U)($[57hi4|D&s1(BRFNATwqii^Ud?,=04+I ^D.% ٰ[1 -&wϿMbSs^ҀEB/c|bKZ(pʨVhޞIwv<kg0 [ Bsddc u[^`Tini+%s-1on $M))rW_ƈd hN $+)񽪜 :>a|Q'b .<G RbhNqIQ: Ga +Sc9Kzw I,R?W26"Hq>;VN ť Qt] {;݄]#Aaݠ(QbߘD[#LQXRx[eإ   zm*fi B#peyF:gB<fE<6بO޴xk[!Ԣs\E@ąrWN}%dEM)%*' LPK&Ӭ(Ҋ3I$lhk $>8cPm} UWn"q%6PBB _^t;K\ ))k3%K16^H my#kQɁ$39l*28rb7Ǖm5ЖAb R'Q!!VYa#OBa(&KpArKsYTh Z᜛@0GpH`(+" ~bR+ 83x+(6 uh8Tg,j2^w5\jh7h˿;}*(0IDATޭD8d NZ-.+N0|_"Ɯsʎ=CƎE^q1lg'jkRU?;-¦GEG}}FϜE0^^p wwhC(:3fdDOA-ݍΦ&VW~zT/[-/7D"%Yc (4 EGEag0hH!'?&7]jmE{M wDgJԯ_Ϊ &\u("WOP"}YA#9Qd8n=4^u!74`~w]͉&QNT.t{Iyt!8s1:o2=Յ|y'kjDߪh6 !SOŸ /İF*7wqsU6?<h޶q:/}]>a-s Ni|!4 [)P8Z7fa`>_Yϝw֮ ޅ8&r/uƟmc;_&vF}jD8G]e%ϟ{"\ I+E!1i`B7p)j矏/QMz Ѭ(R?LBgPtѨMo`8h1g]1O Qr%R[zp5 Pɯk=u],qsp/} ?r3٫sx̙?%K\2B :dHZȜBOg߿hhj; K#X7CǍa_*Q8a!Jh$Ԓ*LP *Zus Zj%T"TU\!.Q<9meNG2 .D-A$L^T|!dw"9k$'IH"QAl,L"EBE\6yeG&#/Æe>_UcM lכرM$rr0{äK/8Ѽx.Pō je֯(5'}{zםRJcG8,$.dA̸⅚4mg׊/˃;Ru/-E[uu/,@&#ۼ%J_jڞ!y$v պgt#^ud)=t%i бղs<{`qEhPS(E ᠤ,IqPR?`4ݻfK|_EcfjkwK"F(9z*{㍌mܲO̙JF; f\sMƢlu-B2$(3c~3X}睨߰AEҀ̃x֭ N܋90)BHT %L&VFï+LNh/Gg_ >9bIP 'pG4j}K~S,S&XXAZߒ{)SP2a?\}5Əz(`Ꜣ"̸Z 32i S @8@zJ;d,|Z GI3ꪭ1+6+83#6\K4lڄGcW`5d=neX}]D3FxB/<|78o̾'}Oz}?_E򆕢AŨsQ~=.EͪUhB[]Z cQ6k*N9y=Wy-w0m($$+!KR wΓP_43Kf,AKji} ozqw0TLrL^/]z80{ pqiQ{AXfA(29#Y|Q9P(+N(!174 \9r>7A4WR<Xu~u?::/ACe%F.?Fu7}aS7 _S).bͽ榰3T-X5AƲ)*(dL5x[],LI"UF-7o^u?~o Ԯ?EW_^Th{zto |d7|%G_S 3~(yqsh5/$!WG:#I `n 0(9R&6n'kB|w ?^1"^dnzx|.9+oJkT v_"79ENJ Tkױ^;BJFy8uE,jr d2H" (v8ddH ,#or  JYNdq51W aWcyeb2[ @KX5>~NJDYDÿX C{M7/뇍0c-ݒԁ)Ѵ⫛wIh8_4}K) i h@@'DBq}Խ,y(N="b LPHac"٨mdIL$ w0'O-ƓLN vڦ67f7^> {`dq^ (n# b2L'YFX?MT%&YNs.PKh'Ҿ{Y˓Xҳە4>Z=e{L ZvVj3'7xws;䢵m#iP kr F5s Q? w 4CP!@bD)$T*a|F 'u>hQs=&D0DOTbph 3@Ç9[7׺:W_p@o$<+ 1nY5ž *. cZJBς CXĨRZxw1[K7}$Rm'h*Ykw%9J.FprN3Ovx{@-EL6RO8V08G3O1:bGm3=4>7 C5AgOx?2ME7TmW|d}gu^V!,; H AJgN޴Yc* FrM/]HIh $5iΌ %BT 0P8$2,ㅋ,Z(DL@;Gk$<Hd >`'!\2?vhp  u@ .X = q0 )f$Tp"FQGr̉C;CodeNarc-0.23/docs/images/external.png0000644000175000017500000000034612471222451017174 0ustar ebourgebourgPNG  IHDR Ӻ&gAMA7tEXtSoftwareAdobe ImageReadyqe< PLTEuuuPtRNS@*PIDATxb`&& @ P6#@ `XĆ2 d@A3 ( *tIENDB`CodeNarc-0.23/docs/images/logos/0000755000175000017500000000000012623571301015764 5ustar ebourgebourgCodeNarc-0.23/docs/images/logos/maven-feather.png0000644000175000017500000000640212471222451021216 0ustar ebourgebourgPNG  IHDRZ#/ pHYs.#.#x?vgAMA|Q cHRMz%u0`:o_F xIDATxb`H  FFblnڳg!߿?x8ߟ? XQtƍ.[LL,##CAAM'O\WW7eooog o߾1cFuu5ABCC&=qߟ7j%7<Ճ Jϟ?yfZZZJJ ''gpp0666mmm c߾}o޼ٰaCoo/\۷oh'.33 366^zW<{sb['>>׌}'|vJzdt9&^=bpE@@*;;ɓ'@ٳg_~ȸz… 1y]>ucǎMO}}ŋդI._ sUU߿֭[@`&F˖-Ѽ}OgU:̪M͟"oo3.?Ú)Jz֝U ݽ?  XTwΝV8P^^2555sa`dxyyZtuu&>}:77䘘ٵk׳gϘ /ԁ&&& 7lxɞ[1K3+J2>eggaA3|~9gǚ37Va㖕e$)8QWW:9s$&&Q T#** 2p XX T`vww[...( ,b`\|1g]*˟ y|?';#?FAvVN=\JzK_`r|y9 y0*r Krp&@!!!'= ~a4)))`2??s;y>/~œO}]_EҜ;q֏, _~:ZGpYGLL"R&X "68~ X@=y`Vd@a?~@9w܃T_\\ ,**rttQUU&+XX@V%=ygO}{;vo/q?Blߘ$lY[{ET8u/NW*pGQ9X*))S{zzXX nnnSS &ܹRkߜ`1  SBl?~rr2<8]>5[V:rn_bz΢U1w?`M=%C.?2~3o=cS@J%+* l71~ ` L u}ߏot?#+'3'&.&L,18 .9}$,f.qfIvvF~t@ X#}݅ÃT~߽~ϯ9}9Y/A2L?M}a]X!DQp Q`'<% ?."T/|ݛ?~{˯nN%A/lls1?l\\<4t3@AM$]VM/` X.B`kXpk޼yR {:"!8Ab 6sssC+u31~QtH#0W ,Ae bh0Zʅ r6"„NSTOr?]PXm;8pKm6{0XbDغ FLKK &R`T4 XkC2`O08 t1#+}@.0^|  c",M7Bv "2<܁l`O!|`[˗/ `Kn.ЕGkY`2`ߙ1> eC`]N3,]UH:t*)$Kxǧ(@ĉᝫOB[l[80??{Ύǖ6$0Ctmذȝ9s& A Ağ AjRRDWcc#XHKx= b9`At+&&owK `3¾r ydx).`xoG€'Q @Cl?{,d0YjT i' ϹV@,D>'OB FV¿ _AVQΐ[) ~102@ԫ[&MD ةb `ρU;$tAvҒO۷oGͭϣ ""$0!xW2002x~"E^Q'+**Acٲeh-1HR0D@5L ρ5Ç ϯ_G `8FED tk.`3 #I… !UV eҥKAQXtApg!9L,l < _߃s-4!##4dD5d= oBB TWbqqq`:@dgF< J@Cх  @q 0*DF̬L> lNΧϮ3Z32rqt1;& H &-THsF0cyyypM^w" (hkkKL } 'ƒ]I@G':`={`Tpr3|~, | HKH`|\v H= ,V^V+*HA< `vY8 P@4P@Z':vrIENDB`CodeNarc-0.23/docs/images/logos/build-by-maven-white.png0000644000175000017500000000432412471222451022426 0ustar ebourgebourgPNG  IHDRZ#/ pHYs.#.#x?vtIME5BasIDATXY}LS[{_b6(_i _ڠA+ D+*5وp dQyFC$XkX\*R>  VDOj G>|a?Ι3̙sJ!`&^`/&)--{hW^1 ;2j0~!pwtt>|СC"hݳu|~`` |8::ZRR%ɖ-[WXA,hܚJY֯^ R߰aåKFg\]]RD"!իW%&&VWWڵݻ[n%$$cǔJׅ~zr<66uuuslll.B!fx<EQnnn*؁Di***fS5>>>]mX***֭[ ))))FoD0L\\\\\ٳg ERRRaa.]G,TVVV=عsg{{}Ε+WH2jl6fQe9! }}}aaa3t.zqUUU``{ω/mccc|>Ņ(,Z(Lfo8>s,A֖޽{-˗hi:44 }S?L!55uƍ$F02á 3{l/n&'S˲ 1CBCC7Z aFquwwJD1e{6wO+l.@ !͛hJc6KU*J*..BVg\.%R$z||\VT覦'Nxzz:99)ʊyd23&&wRh4Vupp ;UvT6Noooݍc^^^& !t9wtt$9rOimmihdWeddd~ਫ#v˱ O:Eؾ}dpqĽ~޾^z }2VY|9U__9(({^RR~:v5** CVSS#UPP@z߭[>}:22DN8rss?m4ׇoB^Ȍ 1M+v-8nŃj*++C]x?n޼8j}'8p:s 6`4?\\}}=f/^Ln5BBB0SҞ!{BOQ fHtL&|]$ ϟ?OQTcc#YVIx28Ÿ!sDzlcc#WZEǏcӓ`D+Woad( ܃)_+lQ+fz}^^^OO*VݝGHPH.3s5/^* ( JBZ@%?h?"jbQd~(d\A $&21 "R`UJ-Z8m4ɴNǩs}~sɚTWWzxxQ(bYU&⥣f_غu+!6<<|8˲NNNΝKMM~~~1118`rrRT@IID"$www???t޶m[JJJ^^_^__q܅ eǏ ϟ_J5gϞ---(++;;;@TTTxxx@@={ݍKjOOOooﴴ4%0 # vh၁'Or3&`0LOO>իWҥKo czz:;;;>>|ܽ{Í  :;;~_ߘZ9q@#iiike@~~~___ppma̯svvvssC]B<==V<2 R&''Yp|y܀jݻwgv;!2<<'J^j2h2nll}ZVHG-3~;ueH/A:3{ CK7lk׮eC,ˢ?G[lXʹ%>5MSSӇnh4>}ZL&H$'ms<-_f˗Ye^z{{ZVMNNx"lCCCtJQQNvӧjo޼V???Á+q^.{{{7n܈)DX8*CthnnYGAKPP~6fq``˷Z~։zXx,rTʾ:X<33P(oeH$r122;vѣh["=..[#""CWWҋ,5&r1}@.f7BE`II :ujkkcF d0322@R2zu twwF1ߍ=p rwc3{ƶeKKK1͉D"@)(((((XBΝ;tvv RPT*2##̃{.3ckM|ĸccceY\{n<ϗ/_D"]Y,'OB-U*أ$4\R@oݺFVukFͿ'9`3cAaUuV!݋M@, 0;;[TTD<_VVQbtuuc,p344DW{{; <Ͽ{hFׯi/xw;{ʘeVX13=fdd"[5oٱ?YrTO}V_׼";=/NEYAЈ|)!P5o–Ot+)ح=oe~g |շŻ%5=H#,;z1knvz=>Mք[?K-?.N+y~9nW2/ܱ4I>2rT9?džRN׷ԑO5ygȁ(=Ȟ)5KD[ q^[ ͝BMA/"4e \҄cn+/F\gs@r+Z vh>7a7a߾'/.-z|ᇟz]G^T̀de )eݘ'Y{1vr( Ck{CfqP1~?O( >w?Gy+oGs1޾gQCå M2is@AkQNx~ oۭQ\RC+P!Cw\l&dx"ʒ9Rvb(6 8?^mv{K7nԵ_ۿfA>Z J5j<5ŵ0-}"5K~FEwԧrlj{ꭙ(dt`~h^ʝ:AF +Tzsړ|Ld_ K"߷}T??! ǜ2c/ ;md &]cmqxɟ|5~^8}ʠrPfRos*Ϗɐ[g `6t=I\ӏo5xu o}Z G]f׸ג` @Zڠ2OYTn Bl"w%G y'A*kÀq _XF8;hZ݇@;B(ɬHѤ,vZ 0yJ6m(6ǠY1SR5 {O<=Vބ4|:;8x`{Ib}̾C363q-cQF5C4#i6-|P7>+je}r$*tM$%bHdQ^s9lOD.g$<ԛKdx>?{gǎLDW}#cξa3ç`hAuxr=rcY^ZQ3WμhZ= 1|ŗĸ[Bs@P a9p@>T+l *ŸoI"vdte!9FN&7joFUPY^ن=D%K+Hlii.r,1l'LÓb8 0W~~|\VG&=SxeI#mx %:FMqg|et"Z9(xYRxzєw$*$k :3D'Njed{Q& ߠMT[U@)5Qcls14-S͟ ѕ> QmM9ÈҜmMhBK 6n\H$r|\FW[Ğ܃#7O+s(;۴td4dMjOA!S8tHMN=skvΊA.D4EA30nNI+q}˦hg -Jx Ь9dJl&4Ohe$~OK?4[薺zqO^v<;ߌPF͢ryh/&:2dvEYZ\ ZMο>v}-q(ڞYgM>!L3ɿe!U# awVu^I2WLbDR{2 |;;d2 @իWHHܧdw񌲻mPIP{M΋Nxye6FCWaJHxR\b 9I />19̥HInK!d$.6@Ck-cw La%Ģ't!ؐQa'SȦUA | # cv0ŭvOPtΒ(PX=$>\&F# I]_ !E[PߔD:[FlF6k D2-"EZ; *aDr$m}fНgQC<ZZ{E7tae1A]TTNgʤ-i] 2Q{Ceكuj-PfU"tSJGi"Y ʪ,Id{ܡ_rH1fz7̘6Mʒ`p:fH%0ki.]JhUwk2m4ghrafګ [V~p4^jd碭!.'UFP|Kzn&#\}mc±E)6aWP-Kn`TvlNCԳ#[lbdfR™'._a^'h,7Rpp@RTJ%\FAv&;9ʆt+`THB?\O JJeUa$K@o$uq'ŢRj׼DkJT>X+Tv1!G8G+dKYir(җZ~\>Q!7E>LcG%$';&d [Cեl@$rĂ˳gj}@W9V^{@0Cre#lpa4>oK"R]eDnYM6!I,'M7.r +GiҢ;;O'r$: )Md{1g0sy#aBQ;i4bs "!koT#uYcP( w(]1TmF_X69(K БA~{]쿳qMCE2GC3R5TWז%!gޱ2G"#z\jS[Nn\ʬn[NUYܞQ"fHg2.,gn`(#ϽDEaK=o2&\wsނ"ڗJ45"f&(Hdb=p5T*.7~r,r|CF Ʈn& IY釣}}ao[KPCW RQg5|j>H!ف㿾M[Vu2"`|74K!pgrZ MkmaE^ ,ĠŘx E){bf&Xx F9v{R ^_ Zv&8QН]縺 ɰeآ'M)YJzB5(i<h|c$e8[ch:QZpS4S4>T~\ԉ4~3s 6-e&sHUT_@' :I6قnj tչAH f, Œ]y!N;ʢgB‚AP"] Abw%}O'l)!Cs (,{082g{< o l:Y@8 SSdB_iL@Ҧ7mtSoBߩJ͓KiV[Ƹ g pFxSI#c3*Q`~M '4)Zpmzdw1eixSF&q襥NDqPna`z8+D:4,|27ڂx+[ҜtkqjIyo Z a9GmJϽ/VU"As Z1b Mwل4Ai׈*1&Rf6hf\V祛FߐCνL g, M8MP+FsSKUbRK`e0tSꭙ537Bbe-ar?Aҙrs+GgIŻV͖($,߳#'5t]<]126&ѓO^fn]:ZLLc+qvMF01p*ݠ;e)FRâ:]/qDNԧPOcaрw}6d=+*\Y3&ޘu ;lϠςN]9jV~Bxe> k}6,yN;&Yyݼ U>Op]x`ԛIt"*Y3.S(+vb$dakvnN jжB`z@ \ 7x%eJXjOֆY8Mh E/#TOg\QzrP;2{OGKh "iЖ^ eShBJubp3 0ՔuP4do֌͎ePX)AC9ў(<4T終}ػmZYn4ցRܜ8X( Y؉D2r-EMc%mRlF 'E;(pNg*!M!@u"97:۲pff+f5(HZG75u,w;h֡lּP; B3fC~ 5|D~P)ll&7o#pnyaJ3h KTɀ 9i[os gh^(JrᎧC45jѽ&Dk0pM")Nj8Wvly9)c f9IyBb̂P=P]nnq}KW2 0mjL"+<./=l=# 5'u E3i% 0Һ1Z ]PY2߁O!QHq@yPСжs >PX#K;({X[/_7A)fcFS5Snݶ24--MV‡++Ŋa䈅܆YKUh Mk#o&vZTGoѡt,U#W:d ms֑˅%Lq~ (A2։NJJGLm3MP(#z9!#KRʓk\Jt#|ݙ޾:VK@FbM.m7XHyrdFŘlr]v|0g%Rw"I0ˍs9,@?yVNJA.x+Jl*f6]AҐ ˮm)&V$O*bDo\eut5)(V[~A4hVY>كK6M|9RSWVZX)0Jg0Tĝ-n#YUp6= 섫͘XQ&t7Մݷ[rSa߽И ]r7Cs2TAƷ'('"byҰȍeQF@g_J Y+e7ej7bnsoskuxTjLbcڂ8W6{:9  xOW{ ʅWUo;:7"TR&\D}wVw%'ұc9TLfmY*%^`!eA*2d0J3-&CQr-9ֱ/lD) /.,Q X,b.~MehW? XҳA[W~U|kNfs\9UA** 9IDAT['''+VpXbcy˃I>).t-TtW]?i:@]peYav>;pYxN H'f4 DhYf JZH*4W FN-N.˻ڜ + 9oDrX(gflD0&e0{pUQ7qX>$Cm^J=8h4zÞ(BgK-iS1U:s6#({3~-&l.(PZ)@m'%7٪:z'cpKt;}=9_2"&:نn+#Ǖ??JXUʩcdR^^VpI=l8LVVYA08PʖL]oZ|8ֈGk,>hM**/n)klW(eSdk+Z#Vb܉!XHCjxb$os>HYI'lNZ5dȯRkdZUϳFIL"0n/^я;W_n}ߡ;> Ҧ_@r搢4^.b+b9;L `dZ[ }X|6r yB^1X٨mB& ukᅶ/ m Go:3 ^ա {D|s^m9RP Į'= %dZUF+Wu˥á 6nX":٭Ч 8'Sy/MDx9Jŵ'J'QY?7zocH uPQvjɠ,ZQ 5D{{?De lRrl>y$ B%Rb^$KeYA.*u^0sfޜbBN-˘p{vImZArP׮E> e? |xD5:O%Z!4, Մ^mbJC M8$M2*Pgfhsm>m8Aۍ؆U'V 8* uUy>>sӁ|ϚeR5jXJ*A!T.LlF$\NZ4i jStP/X)]D׃u>G^Ltc!%4Ѧ;){ &g??s!󚫇OeGFI|-P_Xj81}}3]=r%Ao<~6rC4+ZMQ+ Ohja+kMΟ=g>ēOVʝ-׻aUtK ap ^\˔D +Lg3RiI|5 iAWCMZuX!g򅶧D$59h2pg(7~y^??=ASOeχ-ўà !پ3Bژ⪗plw_B"ET ͽi"hx)aD3 =ghjputͥ֬i-M㟼z7[|%u)` N68dDtRQ'H6Qsb4g$z7f2`fgX_p"bs41R K&1%N;Ns&~xGrxw$i>(nˈqn҃¬DvzDTJ=ak/ؼ#S(Ɂ.b9IoI./(eֽIө3o$$v$[ ]4V7~,~w>;#PSY9X7#\nn\kW=_ׯ}7\[~7>d? 榊JIENDB`CodeNarc-0.23/docs/images/tryit.png0000644000175000017500000003374612471222451016537 0ustar ebourgebourgPNG  IHDRu[[sRGBbKGD pHYs  tIME ;5tEXtCommentCreated with GIMPW IDATx}yUoﺩTUJT AP@\.=Q66Hݸ -tϥԠI@ILH%EԐy|w{oU(IUn/;|>{~Q~8 Sa/"`D3gs3@qx1ߩ] @~ycA; 0@`\|%\*vrέ&{qчxmTo(p K#4`s 0Nidg& ɬ4ˆł jE  מ^PXH-聞74t_]c\ v'fcLҰQxy34`|jA?f#%.aq] T8?ora]߹y>M5{s 'Lm04Ɛń $Ex Y/0] WQ s]ٹ>W&M0zg=27W|H&A9orptv"Bfȏ#& 7)ߟpu:T>e޳!T8!zw{\ / RA(cYQhSQf:񑫯4o0D &&i<{"$1ybE{masDxw&뒽:`h˼E~e,-QC2SIHdlm (dP F:x>CV[#M%EBLxw.$:{o_/=x K(#r?7=NĐYvBSX&L"Z@\r%աY,wXs񉶶7x=['s`$&/"^ q<{' JcS9+A ťOToc_tR芇O9,{q{8ê!0&|@5щ2-3c wx8" J\ݱi3` j]ec ̜_=nk@W:;13}Fے%&DK Wf 7/BG496eF^{x `zنbŁpY%U`ζ! 6ţD#IC-Ozn^xQtVfС0c*~wK,& RLrac^.H3{`o% =E1VH!&2ʳPGD Pc<^^\b7{@o2)02qu4zy,q*LۜG{y20ՕS=;_y@^OZ#DyEo< DC3qpV+uI'؏>?[Z}r}Yl/_\]kaC sY+}EPHϛWt2k8Jt  M/Q\ȯJS'no塇W dô($CrI콥Vbaz.*qB̰ *0Nѓ1YR2$Lr<^ u Oɽ'˟y&mk>[1*54csǖ 4U}Wy`Ǿ{,r#*=yM*НвUhh9qF8c+}ڛ/2YԹ)SqAP-jp8!ƝVb[-'o{7oѹU w-'$z0xCZa'&dC1K8Wk=fgZ!Ih3;zJ0Vd4d",1@0QKl{7oƺx^-=mFNg0tkƾ][Jw{` ڛYwoق vX'P X2.;6))n[dO49pQG+Y}i$m˖a?}S{Ckj_Ry[¾]c CЍ!3IO#Պ3S@AjL jzJg1kdHc((r7CHlky-K׹ Vji?{Г,=4?u?%z1uQYOPWE:׿xg dh[%$*A璚%KԴ URa<8*;Y;cҔ8t\)IϑN $ŹkC/jr)rɩG .A={G|RXG@^qGT&LG-w]>J #@f|*&ܗ!CH!htG6Nlw]A8Œ`r9ߥY4둂Ray$rFiVkUعz:KQJwޅSŊjB0Fh:q:S I #ؒ([~u=jݦ7$RbhUHѩPg*U7j]u\ ~[B$&@2rR튭Հxފ\_{ʃ%բSbr AML虇3ߌvG+>޹ap]Z0iVTky{MuU ݱЄ4JM2/+.!%,K4wFŽ73l|dOf#fPd聜U[D{s3N:F|Vc"~ڴ=+0#Q7> 5#F+-y52szFVPܒ(đظĶZBߎ_"+?8s&M~[z@%uٚi ʒBbA(p [sbz7>L2bSW|ksNRGK7d(tp!y!*4n<ъ z۹_|7XJ U_(@,`6 UΗ^ze}&J-$ $8ߌVs-Œ?Qk/| )SVa-[B5 W{֬Ր Sܶ~ߖ5ՁYg- bѦLd;4 agVb[Ua)=Q{?~GAielX#9N"Ԉw] ($Bx"Tk_C޲%,an.B5RYfhY*,T.RFK~k׾=F) LUzP!snX=kh=f8_܇ןzG|C8S8gJ s6n'RlƆ]*YbDO.wSC잃4?= VH4Q3O?],n_C'c .G!)yr?Y'd=%*-(l9{̾J\~K0$Kkb+1Ba}IV6q? 0kyq;5^'Nx?ޑ4zW.cM_Fсr*IB|FMD 5YmW"3E'ŒY5H,lJG#z5s4/Xq(RO:9ϬlN>P$khqlGZ#Vts*V! LYb 2T%C!1Bfh*hs(S6Oy5cڼq§>S>WލF$Zס $ɣc QJ5t|#yGѡ{0q܉KdWn'JzUnkUWOw؟1kWuxt"~whT2٤6֭mLLT!%+2~H/nRAq1!:aԘH?6Xz}%Pi|.ɑ4₲[}cVl\GqktB LT%oi%)-=3CU0LFR/]'.߽E-zA1[pĬiP-fYfW(MٮQi@0>R;DaeD-ƞ*1*hhu%(ԄS;O%_7/Eģd{$X6 =`d9{8iNK#\ɤRt$:i&#GQ8FwunX?`"ݯ0n <4.tm؀m^^L -Vʊgf(!gZjPM(crg>Km"Smn۳ & )?-% tㄠ2Y&4E#S'򳞵Mnin,kJEDh=F(LHb8G%ځhX%[N클- ,dzVhY|?bEA*Ħ"Oczr'-A**;ؙ"gMAQ`T, yR!-ϝAwq;YU:e LX%~VU z0Qe#$#&;3Q']!\A4Ѳ0L>l*JZ'bb2UH4$s w"YԦ$cˬY/H9t\e.S$uVjY@Tsިb&B8G}H!BI !Ŗ 9Th&}GH8rCOqLV⶗j#{?jc3%-لǯj ]`8$gBHۆ?]W"sgmp2wW Mİ- zr !/#&hOqkU0 q̏f6IlYj F ~C>^̐%Z b6aTʅWQ/ģwY0sn4c\xs|7|X^EOxͽB|G*߳u+~2wvL*DW- Z`4pmG+=SM } sσl]t26E<^?}wixkᆆBUqB MNj 5.<~-w[}ۢ5XDπFpd:Y0w'z$E4"I0).U/AcDF Dz) Dx5 uZaӏ9* pcŊHr'e'yOjBdVTjb֘ |rYYҘ7`zbk[Z>vo=Z`REڷb]AJQE,>2܏&%$T2 Ȣe!ug)5ߕqj&kFƗ?W6n8rk~}s3sLMWPXsXMP4d( r*LItNkR,F.#ũђ욧ydm'rһSXiVAD*3ΨJڳu+zEQk+%tUGf[VJ.ف%M#rn͐W0[~RjIƑPy!N9dGv nԄ1o s׿7Z<[ }&Dh<9g[dק!0E&Z)ʷ!%~DEM{1й'5IDATu^}Ud׾EHt` /n}{6w-uu80?w桾\_N۵ ^x+V`$GLա̶ bC:EeR8^* O,=QZa͛1g)f+V?VȼĹ~E &a$_ՙuW^<| 6-ZyqG%<ӧnt%FVsZ\IQ $v"v 良`L~0}Rq4@/ldU*n.O9wUѰ;;w\{=X,BuvyQma#94m*zч+~{|҉ ׾]2FEԩsj+3BR'2I04ˁ|8趐c1O(5/D%,!wJ%?Ό'ڱz5sV?`5Po/?~hr߯;Dnge$} G]r1J _ t\>77pCf* 0r9u(ElXbᣋCFxXMc?zo{ߋCL>@qWpWc+Y_uz>d<5-{*{|&]*aWTRc,'G_vyrŖFebvm*x~~B~RB) pYUDے% }3Ķ}b:v o;wj(M|o5KģP8wPP$_:d~ɟn[ޞ@S(k TAs /<8Flա"u eKr#ahpf0gK/e8*+N->tY9܊J;y? )C}sH01~!1W]={idSG^rq2I/boC]rTһ3D\Ua~РghR:bح :1l>M fƼ;|L>䐚hU@ϯϡ5Ra --cߎA! TAuS4x1ڝ@vDkh[.( <)B$*+Mc|74]? èjzfy5 YDsf6…c9羝;oGڋp 8QQ݋UB@j&z_P'{ǘUy`.P__IS@&s6.ZP"pBBTAKMS;`OҮNLj -Ú?g:HAhXvȊn2piz|+a}Oz(Fo;6mԘ44fa ծ+8>1;O<]P0RSG^ziz[ =mm^NK))R"lZ/.yketCZ|WɜPGS79@nƤVbr_2aѝ"ضw;Mr`>5'*b&'TWg¯ " $Xs;iEBYUT#\O(RV4"Z6&V:c4!bC[1iœΗ_bmh_tX ILl(QiC@q%"̽}Ż_{ ۟~**/M#?hۻqP .K/=//`HA1h]Z2ڠ3ۿq??#d6%:&Ca ǯ sѱvWtonN/3ގmK<I-wy7qG?ֳŒN(MwBצMsh t,҇QRٕzs<)@Cʆ_vdϑfZfUvEFShR](%r1J j-$v/Vzox 7 d5̆ӝrHMsQϹ4WcIZPP̓ ﲑd;AUi+L_SϯI+p>ɢ̎dƠ?u͚VIR w/[)t>mM[>[wF6"=mi% f7X@hHܽj3gM N۱ݪI`)PS<aӀMj#B`VY ъ1ϰ9|j;|`&wft.l.W0C6FfD `+eaX\Rlo2Ҧ_v̈ٝd&QK]a"ж'TT"{JE xV[n}aےo>hONΑAؒ>pk?8 X3)*9֠ 1'd6Ťv6EZCSϒ*'E)aAkޞK%oXsPx{6ۼxc]*IYA2isfՅ r^s $* ;s0cD ;d$ 9CAjCyu$ ãcELĆ1X,hkL^OvV<9$rB͇%S dH ]GT"͔ Ec@Jʶ_<YO;[ً4guFjDe[_R8|D%wץd?yABjŹ#˨MI|X#G>7P Fb.řOR 6ln񊆟Upqۣl.jKV)@ ų^Wf4# IV۩m5孙{ΐ19/@TRmB'C$6HSc;sE=!{奄E[*&B?FV>oO0*[ۯ=/=9lύn_?Bnm R(:TP5ҡ3ER@6mڙz[59lvoUK3]1V/ р (*FQ$7)*otәpJ9_L %FΒ1t q=9QrgF3 XJy`usgZe"yD{R @4&* YQd P`ÌUv@APްF"aLbB e0lm0ћJR$=HpeKV=$]AN#)w}wrp~ʱb/t剬hY,:so%ozǜ!E?f$ Y,*V-Y~B%IPc`c%8Mxtct aeV+,:9Cjb:Uu096mY_U#18ycR{V1o9!b_: F(T%yCE4slhq{`SԒ!KhL]Ù{wYA $j4NoP絶5=7R@"dʃ&YvP ٻo{&cΛ1Y{wRѱ{Baiw;IWc{Y@A=} e;hYE\aJ0{kS3oe87p=&Mrg!d3!J06!>$! 䠊\ ,lrP:=u-:Y%a!{@r#8D! f,vEΗgJC%}}on_QFi8 Sԍjc$UtCWb6:@O>Ei ur o}b1(7MMV-`}) K+Oɴ塌5P.\*=:e76v{RIENDB`CodeNarc-0.23/docs/images/notes.txt0000644000175000017500000000010512471222451016526 0ustar ebourgebourgFont for button: 42 Point Sans Bold Italic White Sort of centered. CodeNarc-0.23/docs/SampleCodeNarcHtmlReport.html0000644000175000017500000006066512471222451021140 0ustar ebourgebourgCodeNarc Report: Sample Project

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages106--8
<Root>73--3
io33--5

Package: <Root>

➥ ModifiersUtilTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports320

[SRC]import static org.codenarc.test.TestUtil.shouldFailWithM..geContaining

[MSG]Static imports should appear before normal imports

➥ PropertyUtilTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports322

[SRC]import static org.codenarc.test.TestUtil.shouldFail

[MSG]Static imports should appear before normal imports

➥ SourceCodeUtilTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports327

[SRC]import static org.codenarc.test.TestUtil.shouldFail

[MSG]Static imports should appear before normal imports

Package: io

➥ ClassPathResourceTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports321

[SRC]import static org.codenarc.test.TestUtil.shouldFail

[MSG]Static imports should appear before normal imports

MisorderedStaticImports322

[SRC]import static org.codenarc.test.TestUtil.shouldFailWithM..geContaining

[MSG]Static imports should appear before normal imports

➥ DefaultResourceFactoryTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports322

[SRC]import static org.codenarc.test.TestUtil.shouldFailWithM..geContaining

[MSG]Static imports should appear before normal imports

➥ UrlResourceTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports321

[SRC]import static org.codenarc.test.TestUtil.shouldFail

[MSG]Static imports should appear before normal imports

MisorderedStaticImports322

[SRC]import static org.codenarc.test.TestUtil.shouldFailWithM..geContaining

[MSG]Static imports should appear before normal imports

Rule Descriptions

#Rule NameDescription
1AssertWithinFinallyBlockChecks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one.
2AssignmentInConditionalAn assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended.
3BigDecimalInstantiationChecks for calls to the BigDecimal constructors that take a double parameter, which may result in an unexpected BigDecimal value.
4BitwiseOperatorInConditionalChecks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable.
5BooleanGetBooleanThis rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop'].
6BrokenNullCheckLooks for faulty checks for null that can cause a NullPointerException.
7BrokenOddnessCheckThe code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.
8ClassForNameUsing Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time.
9ComparisonOfTwoConstantsChecks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values., e.g.: 23 == 67, Boolean.FALSE != false, 0.17 <= 0.99, "abc" > "ddd", [a:1] <=> [a:2], [1,2].equals([3,4]) or [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE].
10ComparisonWithSelfChecks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x =>= x, x.equals(x) or x.compareTo(x), where x is a variable.
11ConstantAssertExpressionChecks for assert statements where the assert boolean condition expression is a constant or literal value.
12ConstantIfExpressionChecks for if statements with a constant value for the if expression, such as true, false, null, or a literal constant value.
13ConstantTernaryExpressionChecks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value.
14DeadCodeDead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted.
15DoubleNegativeThere is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well.
16DuplicateCaseStatementCheck for duplicate case statements in a switch block, such as two equal integers or strings.
17DuplicateImportDuplicate import statements are unnecessary.
18DuplicateMapKeyA map literal is created with duplicated key. The map entry will be overwritten.
19DuplicateSetValueA Set literal is created with duplicate constant value. A set cannot contain two elements with the same value.
20EmptyCatchBlockIn most cases, exceptions should not be caught and ignored (swallowed).
21EmptyClassReports classes without methods, fields or properties. Why would you need a class like this?
22EmptyElseBlockEmpty else blocks are confusing and serve no purpose.
23EmptyFinallyBlockEmpty finally blocks are confusing and serve no purpose.
24EmptyForStatementEmpty for statements are confusing and serve no purpose.
25EmptyIfStatementEmpty if statements are confusing and serve no purpose.
26EmptyInstanceInitializerAn empty class instance initializer was found. It is safe to remove it.
27EmptyMethodA method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation.
28EmptyStaticInitializerAn empty static initializer was found. It is safe to remove it.
29EmptySwitchStatementEmpty switch statements are confusing and serve no purpose.
30EmptySynchronizedStatementEmpty synchronized statements are confusing and serve no purpose.
31EmptyTryBlockEmpty try blocks are confusing and serve no purpose.
32EmptyWhileStatementEmpty while statements are confusing and serve no purpose.
33EqualsAndHashCodeIf either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden.
34EqualsOverloadedThe class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it.
35ExplicitGarbageCollectionCalls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself.
36ForLoopShouldBeWhileLoopA for loop without an init and update statement can be simplified to a while loop.
37HardCodedWindowsFileSeparatorThis rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant.
38HardCodedWindowsRootDirectoryThis rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative.
39ImportFromSamePackageAn import of a class that is within the same package is unnecessary.
40ImportFromSunPackagesAvoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.
41IntegerGetIntegerThis rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop'].
42MisorderedStaticImportsStatic imports should never be declared after nonstatic imports.
43MultipleUnaryOperatorsChecks for multiple consecutive unary operators. These are confusing, and are likely typos and bugs.
44NoWildcardImportsWildcard imports, static or otherwise, should not be used.
45RandomDoubleCoercedToZeroThe Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug.
46RemoveAllOnSelfDon't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException.
47ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
48ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
49UnnecessaryGroovyImportA Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger.
50UnusedImportImports for a class that is never referenced within the source file is unnecessary.
CodeNarc-0.23/docs/codenarc-command-line.html0000644000175000017500000003724512471222400020406 0ustar ebourgebourg CodeNarc - CodeNarc Command Line

CodeNarc - Run From Command-Line

CodeNarc can be run from the command-line as a Java application. The org.codenarc.CodeNarc class provides the application entry-point.

CodeNarc Command-Line Parameters

Usage: java org.codenarc.CodeNarc [OPTIONS] where OPTIONS are zero or more command-line parameters of the form "-NAME[=VALUE]"

All command-line parameters are optional. If no parameters are supplied, CodeNarc runs from the current directory with reasonable defaults, as described below.

Parameter Description Example
-basedir=DIR The base (root) directory for the source code to be analyzed. Defaults to the current directory ("."). -basedir=src/main/groovy
-includes=PATTERNS The comma-separated list of Ant-style file patterns specifying files that must be included. Defaults to "**/*.groovy". -includes=**/*.gr
-excludes=PATTERNS The comma-separated list of Ant-style file patterns specifying files that must be excluded. No files are excluded when omitted. -excludes=**/templates/**, 
**/*Test.*
-rulesetfiles=FILENAMES The path to the Groovy or XML RuleSet definition files, relative to the classpath. This can be a single file path, or multiple paths separated by commas. Defaults to "rulesets/basic.xml". -rulesetfiles=rulesets/imports.xml, 
rulesets/naming.xml
-report=REPORT-TYPE[:FILENAME] The definition of the report to produce. The option value is of the form TYPE[:FILENAME], where TYPE is one of the predefined type names: "html", "xml", "text", "console" or else the fully-qualified class name of a class (accessible on the classpath) that implements the org.codenarc.report.ReportWriter interface. And FILENAME is the filename (with optional path) of the output report filename. If the report filename is omitted, the default filename for the report type is used ("CodeNarcReport.html" for "html" and "CodeNarcXmlReport.xml" for "xml"). If no report option is specified, default to a single "html" report with the default filename. -report=html -report=html:MyProject.html -report=xml -report=xml:MyXmlReport.xml -report=org.codenarc.report. HtmlReportWriter
-title=REPORT TITLE The title description for this analysis; used in the output report(s), if provided. -title="My Project"
-help Display the command-line help. If present, this must be the only command-line parameter. -help

Executing CodeNarc from the Command-Line

Make sure that the following are included your CLASSPATH:

  1. The Groovy jar
  2. The CodeNarc jar
  3. The Log4J jar
  4. The directories containing (or relative to) CodeNarc config files such as "codenarc.properties" or ruleset files.

The CodeNarc command-line application sets an exit status of zero (0) if the command successfully executes, and an exit status of one (1) if an error occurs executing CodeNarc, or if an invalid command-line option is specified.

Here is an example BAT file for running CodeNarc on Windows.

@set GROOVY_JAR="%GROOVY_HOME%/embeddable/groovy-all-1.5.6.jar"

@java -classpath %GROOVY_JAR%;lib/CodeNarc-0.5.jar;lib/log4j-1.2.14.jar;lib org.codenarc.CodeNarc %*

CodeNarc-0.23/docs/codenarc-rules-basic.html0000644000175000017500000012213412471222407020253 0ustar ebourgebourg CodeNarc - CodeNarc - Basic Rules

Basic Rules ("rulesets/basic.xml")

AssertWithinFinallyBlock

Checks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one.

Here is an example of code that produces a violation:

    int myMethod(int count) {
        try {
            doSomething()
        } finally {
            assert count > 0        // violation
        }
    }

AssignmentInConditional Rule

New in CodeNarc 0.13

An assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended.

Example of violations:

    if ((value = true)) {
        // should be ==
    }

    while (value = true) {
        // should be ==
    }

    (value = true) ? x : y
    (value = true) ?: x

    // the following code has no violations
    if (value == true) {
    }

    value == true ? x : y
    value == true ?: x

BigDecimalInstantiation Rule

Checks for calls to the java.math.BigDecimal constructors that take a double value as the first parameter. As described in the BigDecimal javadoc, the results from these constructors can be somewhat unpredictable, and their use is generally not recommended. This is because some numbers, such as 0.1, cannot be represented exactly as a double.

For instance, executing println new BigDecimal(0.1) prints out 0.1000000000000000055511151231257827021181583404541015625.

Here is an example of code that produces a violation:

    def b1 = new BigDecimal(0.1)               // violation
    def b2 = new java.math.BigDecimal(23.45d)  // violation

BitwiseOperatorInConditional Rule

New in CodeNarc 0.15

Checks for bitwise operations in conditionals. For instance, the condition if (a | b) is almost always a mistake and should be if (a || b). If you need to do a bitwise operation then it is best practice to extract a temp variable.

Example of violations:

    if (a | b) { }
    if (a & b) { }

BooleanGetBoolean Rule

New in CodeNarc 0.13

This rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop̈́'].

Example of violations:

    // produces violation
    Boolean.getBoolean(value)

    // zero or two parameters is OK, must be different method
    Boolean.getBoolean(value, 1)
    Boolean.getBoolean()

BrokenNullCheck Rule

Since CodeNarc 0.17

Looks for faulty checks for null that can cause a NullPointerException.

Examples:

    if (name != null || name.length > 0) { }            // violation
    if (name != null || name.length) { }                // violation
    while (record == null && record.id < 10) { }        // violation
    if (record == null && record.id && doStuff()) { }   // violation
    def isNotValid = record == null && record.id < 10   // violation
    return record == null && !record.id                 // violation

    if (name != null || name.size() > 0) { }            // violation
    if (string == null && string.equals("")) { }        // violation
    def isValid = name != null || name.size() > 0       // violation
    return name != null || !name.size()                 // violation

BrokenOddnessCheck Rule

Since CodeNarc 0.13

The code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.

Examples:

    if (x % 2 == 1) { }             // violation
    if (method() % 2 == 1) { }      // violation

    if (x & 1 == 1) { }             // OK
    if (x % 2 != 0) { }             // OK

ClassForName Rule

New in CodeNarc 0.14

Using Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time. If you're forced to do dynamic class loading then use ClassLoader.loadClass instead. All variations of the Class.forName(...) method suffer from the same problem.

For more information see these links:

Example of violations:

    Class.forName('SomeClassName')
    Class.forName(aClassName, true, aClassLoader)

ComparisonOfTwoConstants Rule

Since CodeNarc 0.14

Checks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values.

Here are examples of code that produces a violation:

    23 == 67                    // violation
    Boolean.FALSE != false      // violation
    23 < 88                     // violation
    0.17 <= 0.99                // violation
    "abc" > "ddd"               // violation
    [Boolean.FALSE] >= [27]     // violation
    [a:1] <=> [a:2]             // violation

    [1,2].equals([3,4])                                     // violation
    [a:123, b:true].equals(['a':222, b:Boolean.FALSE])      // violation

    [a:123, b:456].compareTo([a:222, b:567]                 // violation
    [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE]  // violation

ComparisonWithSelf Rule

Since CodeNarc 0.14

Checks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x >= x, x.equals(x) or x.compareTo(x), where x is a variable.

Here are examples of code that produces a violation:

    if (x == x) { }                 // violation
    if (x != x) { }                 // violation
    while (x < x) { }               // violation
    if (x <= x) { }                 // violation
    while (x > x) { }               // violation
    if (x >= x) { }                 // violation
    def c = (x <=> x) { }           // violation
    println isReady = x.equals(x)   // violation
    println x.compareTo(x)          // violation

ConstantAssertExpression Rule

Checks for assert statements with a constant value for the assert boolean expression, such as true, false, null, or a literal constant value. These assert statements will always pass or always fail, depending on the constant/literal value. Examples of violations include:

    assert true
    assert false, "assertion message"
    assert Boolean.TRUE
    assert Boolean.FALSE
    assert null
    assert 0
    assert 99.7
    assert ""
    assert "abc"
    assert [:]
    assert [a:123, b:456]
    assert [a, b, c]

ConstantIfExpression Rule

Checks for if statements with a constant value for the if boolean expression, such as true, false, null, or a literal constant value. These if statements can be simplified or avoided altogether. Examples of violations include:

    if (true) { .. }
    if (false) { .. }
    if (Boolean.TRUE) { .. }
    if (Boolean.FALSE) { .. }
    if (null) { .. }
    if (0) { .. }
    if (99.7) { .. }
    if ("") { .. }
    if ("abc") { .. }
    if ([:]) { .. }
    if ([a:123, b:456]) { .. }
    if ([a, b, c]) { .. }

ConstantTernaryExpression Rule

Checks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value. Examples of violations include:

    true ? x : y
    false ? x : y
    Boolean.TRUE ? x : y
    Boolean.FALSE ? x : y
    null ? x : y
    0 ? x : y
    99.7 ? x : y
    "" ? x : y
    "abc" ? x : y
    [:] ? x : y
    [a:123, b:456] ? x : y
    [a, b, c] ? x : y

The rule also checks for the same types of constant values for the boolean expressions within the "short" ternary expressions, also known as the "Elvis" operator, e.g.:

    true ?: y
    null ?: y
    99.7 ?: y
    "abc" ?: y
    [:] ?: y
    [a, b, c] ?: y

DeadCode Rule

Since CodeNarc 0.11

Dead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted.

DoubleNegative Rule

Since CodeNarc 0.11

There is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well.

DuplicateCaseStatement Rule

Since CodeNarc 0.11

Check for duplicate case statements in a switch block, such as two equal integers or strings. Here are some examples of code that produces violations:

    switch( 0 ) {
        case 1: break;
        case 2: break;
        case 2: break;          // violation
    }
    
    switch( "test" ) {
        case "$a": break;
        case "$a": break;       // ok; only flags constant values (not GStrings)
        case "ab": break;
        case "ab": break;       // violation
        case "abc": break;
    }

DuplicateMapKey Rule

New in CodeNarc 0.14

A Map literal is created with duplicated key. The map entry will be overwritten.

Example of violations:

    def var1 = [a:1, a:2, b:3]        //violation
    def var2 = [1:1, 1:2, 2:3]        //violation
    def var3 = ["a":1, "a":2, "b":3]  //violation

    // these are OK
    def var4 = [a:1, b:1, c:1]
    def var5 = [1:1, 2:1, 3:1]
    def var6 = ["a":1, "b":1, "c":1]

DuplicateSetValue Rule

New in CodeNarc 0.14

A Set literal is created with duplicate constant value. A set cannot contain two elements with the same value.

Example of violations:

    def a = [1, 2, 2, 4] as Set
    def b = [1, 2, 2, 4] as HashSet
    def c = [1, 2, 2, 4] as SortedSet
    def d = [1, 2, 2, 4] as FooSet
    def e = ['1', '2', '2', '4'] as Set
    def f = ['1', '2', '2', '4'] as HashSet
    def g = ['1', '2', '2', '4'] as SortedSet
    def h = ['1', '2', '2', '4'] as FooSet

    // these are OK
    def a = [1, 2, 3, 4] as Set
    def b = ['1', '2', '3', '4'] as Set
    def c = [1, '1'] as Set

EmptyCatchBlock Rule

Checks for empty catch blocks. In most cases, exceptions should not be caught and ignored (swallowed).

The rule has a property named ignoreRegex that defaults to the value 'ignore|ignored'. If the name of the exception matches this regex then no violations are produced.

Property Description Default Value
ignoreRegex Regular expression - exception parameter names matching this regular expression are ignored and no volations are produced. 'ignore

Here is an example of code that produces a violation:

    def myMethod() {
        try {
            doSomething
        } catch(MyException e) {                //violation
            // should do something here
        }
    }

    def myMethod() {
        try {
            doSomething
        } catch(MyException ignored) {
            //no violations because the parameter name is ignored
        }
    }

EmptyClass Rule

Since CodeNarc 0.19

Reports classes without methods, fields or properties. Why would you need a class like this?

This rule ignores interfaces, enums, anonymous inner classes, subclasses (extends), and classes with annotations.

EmptyElseBlock Rule

Checks for empty else blocks. Empty else blocks are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        if (x==23) {
            println 'ok'
        } else {
            // empty
        }
    }

EmptyFinallyBlock Rule

Checks for empty finally blocks. Empty finally blocks are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        try {
            doSomething()
        } finally {
            // empty
        }
    }

EmptyForStatement Rule

Checks for empty for blocks. Empty for statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        for (int i=0; i < 23; i++) {
            // empty
        }
    }

EmptyIfStatement Rule

Checks for empty if statements. Empty if statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        if (x==23) {
            // empty
        }
    }

EmptyInstanceInitializer Rule

New in CodeNarc 0.13

An empty class instance initializer was found. It is safe to remove it. Example:

    class MyClass {
        { }     // empty instance initializer, not a closure
    }

EmptyMethod Rule

New in CodeNarc 0.13

A method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation. This rule should not be used with Java 5 code because you cannot put @Override on a method implementing an interface. Use with Java 6 and higher.

Example of violations:

    class MyClass {

        // violation, empty method
        public void method1() {}

        // violation, empty method
        def method2() {}

        // OK because of @Override
        @Override
        public void method3() {}
    }

    abstract class MyBaseClass {
        // OK, handled by EmptyMethodInAbstractClass Rule
        public void method() {}
    }

EmptyStaticInitializer Rule

New in CodeNarc 0.13

An empty static initializer was found. It is safe to remove it. Example:

    class MyClass {
        static { }
    }

EmptySwitchStatement Rule

Checks for empty switch statements. Empty switch statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        switch(myVariable) {
            // empty
        }
    }

EmptySynchronizedStatement Rule

Checks for empty synchronized statements. Empty synchronized statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    class MyClass {
        def myMethod() {
            synchronized(lock) {
            }
        }
    }

EmptyTryBlock Rule

Checks for empty try blocks. Empty try blocks are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        try {
            // empty
        } catch(MyException e) {
            e.printStackTrace()
        }
    }

EmptyWhileStatement Rule

Checks for empty while statements. Empty while statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        while (!stopped) {
            // empty
        }
    }

EqualsAndHashCode Rule

Checks that if either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden.

Here is an example of code that produces a violation:

    class MyClass {
        boolean equals(Object object) {
            // do something
        }
    }

And so does this:

    class MyClass {
        int hashCode() {
            return 0
        }
    }

EqualsOverloaded Rule

New in CodeNarc 0.14

The class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it.

Example of violations:

    class Object1 {
        //parameter should be Object not String
        boolean equals(String other) { true }
    }

    class Object2 {
        // Overloading equals() with 2 parameters is just mean
        boolean equals(Object other, String other2) { true }
    }

    class Object3 {
        // a no-arg equals()? What is this supposed to do?
        boolean equals() { true }
    }


    // all of these are OK and do not cause violations
    class Object4 {
        boolean equals(Object other) { true }
    }

    @SuppressWarnings('EqualsOverloaded')
    class Object5 {
        boolean equals(String other) { true }
    }

    class Object6 {
        boolean equals(java.lang.Object other) { true }
    }

    class Object7 {
        boolean equals(other) { true }
    }

ExplicitGarbageCollection Rule

Since CodeNarc 0.12

Calls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" JVMs do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself.

ForLoopShouldBeWhileLoop Rule

New in CodeNarc 0.14

A for loop without an init and update statement can be simplified to a while loop.

Example of violations:

    int i = 0;
    for(; i < 5;) {     // Violation
        println i++
    }

    // These are OK
    for(i in [1,2])         // OK
       println i

    for(int i = 0; i<5;)    // OK
        println i++

    int i = 0;
    for(; i < 5; i++)       // OK
        println i

    for (Plan p : plans) {  // OK
        println "Plan=$p"
    }

HardCodedWindowsFileSeparator Rule

New in CodeNarc 0.15

This rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant.

Example of violations:

   new File('.\\foo\\')
   new File('c:\\dir')
   new File('../foo\\')

HardCodedWindowsRootDirectory Rule

New in CodeNarc 0.15

This rule find cases where a File object is constructed with a windows-based path. This is not portable across operating systems or different machines, and using the File.listRoots() method is a better alternative.

Example of violations:

   new File('c:\\')
   new File('c:\\dir')
   new File('E:\\dir')

IntegerGetInteger Rule

New in CodeNarc 0.13

This rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop'].

Example of violations:

    // violations
    Integer.getInteger(value)
    Integer.getInteger(value, radix)

    // zero or more than 2 parameters is OK, must be different method
    Integer.getInteger()
    Integer.getInteger(value, radix, locale)

MultipleUnaryOperators Rule

Since CodeNarc 0.21

Checks for multiple consecutive unary operators. These are confusing, and are likely typos and bugs.

Example of violations:

    int z = ~~2             // violation
    boolean b = !!true      // violation
    boolean c = !!!false    // 2 violations
    int j = -~7             // violation
    int k = +~8             // violation

RandomDoubleCoercedToZero Rule

New in CodeNarc 0.15

The Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer, Long, int, or long then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug.

Example of violations:

    (int) Math.random()
    (Integer) Math.random()
    int x = Math.random()
    Integer y = Math.random()
    int m() { Math.random() }
    Integer m() { Math.random() }
    (Math.random()) as int
    (Math.random()) as Integer

RemoveAllOnSelf Rule

Since CodeNarc 0.11

Don't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException.

ReturnFromFinallyBlock Rule

Checks for a return from within a finally block. Returning from a finally block is confusing and can hide the original exception.

Here is an example of code that produces a violation:

    int myMethod() {
        try {
            doSomething()
            return 0
        } catch(Exception e) {
            return -1
        } finally {
            return 99               // violation
        }
    }

ThrowExceptionFromFinallyBlock

Checks for throwing an exception from within a finally block. Throwing an exception from a finally block is confusing and can hide the original exception.

Here is an example of code that produces a violation:

    int myMethod() {
        try {
            doSomething()
            throw new Exception()
        } finally {
            println 'finally'
            throw new Exception()   // violation
        }
    }

CodeNarc-0.23/docs/codenarc-rules-braces.html0000644000175000017500000003156212471222407020435 0ustar ebourgebourg CodeNarc - CodeNarc - Braces Rules

Braces Rules ("rulesets/braces.xml")

ElseBlockBraces Rule

Checks that else blocks use braces, even for a single statement.

By default, braces are not required for an else if it is followed immediately by an if. Set the bracesRequiredForElseIf property to true to require braces is that situation as well.

Property Description Default Value
bracesRequiredForElseIf Set to true to require braces for an else block followed immediately by an if statement. false

ForStatementBraces Rule

Checks that for statements use braces, even for a single statement.

IfStatementBraces Rule

Checks that if statements use braces, even for a single statement.

WhileStatementBraces Rule

Checks that while statements use braces, even for a single statement.


CodeNarc-0.23/docs/CodeNarc-Gradle-Report.html0000644000175000017500000121147212471222451020415 0ustar ebourgebourgCodeNarc Report: Gradle-1.0-milestone-9

CodeNarc Report

Summary by Package

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages258125-56389
src/org/gradle/api/internal1----
src/org/gradle/api/internal/artifacts/dsl11--4
src/org/gradle/api/internal/artifacts/dsl/dependencies22--3
src/org/gradle/api/internal/file43--4
src/org/gradle/api/internal/plugins1----
src/org/gradle/api/internal/project33--18
src/org/gradle/api/internal/tasks/compile31-11
src/org/gradle/api/internal/tasks/scala11-12
src/org/gradle/api/plugins75--13
src/org/gradle/api/plugins/announce3----
src/org/gradle/api/plugins/announce/internal126-77
src/org/gradle/api/plugins/osgi1----
src/org/gradle/api/plugins/quality197--25
src/org/gradle/api/plugins/quality/internal11-42
src/org/gradle/api/plugins/scala22-111
src/org/gradle/api/plugins/sonar2----
src/org/gradle/api/plugins/sonar/internal11--1
src/org/gradle/api/plugins/sonar/model42--2
src/org/gradle/api/publication42--3
src/org/gradle/api/publication/maven6----
src/org/gradle/api/publication/maven/internal11--2
src/org/gradle/api/publication/maven/internal/ant22--2
src/org/gradle/api/publication/maven/internal/model31--1
src/org/gradle/api/publication/maven/internal/modelbuilder2----
src/org/gradle/api/tasks2----
src/org/gradle/api/tasks/application11--20
src/org/gradle/api/tasks/bundling22--9
src/org/gradle/api/tasks/compile71--2
src/org/gradle/api/tasks/javadoc21--1
src/org/gradle/api/tasks/scala31-12
src/org/gradle/api/tasks/testing/testng11--4
src/org/gradle/api/tasks/util11-28
src/org/gradle/groovy/scripts22--12
src/org/gradle/initialization32--3
src/org/gradle/integtests/fixtures1715-3052
src/org/gradle/plugins/binaries/model/internal11--1
src/org/gradle/plugins/binaries/tasks1----
src/org/gradle/plugins/cpp3----
src/org/gradle/plugins/cpp/cdt1----
src/org/gradle/plugins/cpp/cdt/model41-1-
src/org/gradle/plugins/cpp/cdt/tasks1----
src/org/gradle/plugins/cpp/gpp32--8
src/org/gradle/plugins/cpp/msvcpp1----
src/org/gradle/plugins/ear22--4
src/org/gradle/plugins/ear/descriptor/internal42-22
src/org/gradle/plugins/ide/api3----
src/org/gradle/plugins/ide/eclipse72--11
src/org/gradle/plugins/ide/eclipse/internal2----
src/org/gradle/plugins/ide/eclipse/model2712--28
src/org/gradle/plugins/ide/eclipse/model/internal82--4
src/org/gradle/plugins/ide/idea43--3
src/org/gradle/plugins/ide/idea/internal1----
src/org/gradle/plugins/ide/idea/model1713--49
src/org/gradle/plugins/ide/idea/model/internal2----
src/org/gradle/plugins/ide/internal22-111
src/org/gradle/plugins/ide/internal/configurer31--3
src/org/gradle/plugins/ide/internal/generator32-22
src/org/gradle/plugins/signing74-128
src/org/gradle/plugins/signing/signatory3----
src/org/gradle/plugins/signing/signatory/pgp41--1
src/org/gradle/plugins/signing/type61--3
src/org/gradle/plugins/signing/type/pgp1----
src/org/gradle/profile11-1-
src/org/gradle/testing/internal/util1----
src/org/gradle/util85-117

Package: src.org.gradle.api.internal.artifacts.dsl

➥ DefaultArtifactHandler.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration335

[SRC]def DefaultArtifactHandler(ConfigurationContainer config..ctFactory) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler. The def keyword is unneeded on constructors

UnnecessaryPackageReference340

[SRC]private PublishArtifact pushArtifact(org.gradle.api.arti..reClosure) {

[MSG]The org.gradle.api.artifacts.Configuration class was explicitly imported, so specifying the package name is not necessary

UnnecessaryDefInMethodDeclaration355

[SRC]public def methodMissing(String name, args) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler. The def keyword is unneeded when a method is marked public

UnnecessaryGetter358

[SRC]if (!getMetaClass().respondsTo(this, name, args.size())) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler. getMetaClass() can probably be rewritten as metaClass

Package: src.org.gradle.api.internal.artifacts.dsl.dependencies

➥ DefaultDependencyHandler.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration334

[SRC]def DefaultDependencyHandler(ConfigurationContainer conf..encyFactory,

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler. The def keyword is unneeded on constructors

UnnecessaryGetter393

[SRC]if (!getMetaClass().respondsTo(this, name, args.size())) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler. getMetaClass() can probably be rewritten as metaClass

➥ ModuleDescriptorDelegate.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration329

[SRC]def ModuleFactoryDelegate(ClientModule clientModule, Dep..cyFactory) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.dependencies.ModuleFactoryDelegate. The def keyword is unneeded on constructors

Package: src.org.gradle.api.internal.file

➥ AntFileCollectionBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure333

[SRC]node."${childNodeName ?: 'resources'}"() {

[MSG]Violation in class org.gradle.api.internal.file.AntFileCollectionBuilder. Parentheses in the 'null' method call are unnecessary and can be removed.

➥ AntFileCollectionMatchingTaskBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration324

[SRC]def AntFileCollectionMatchingTaskBuilder(Iterable<Direct..fileTrees) {

[MSG]Violation in class org.gradle.api.internal.file.AntFileCollectionMatchingTaskBuilder. The def keyword is unneeded on constructors

➥ AntFileTreeBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration324

[SRC]def AntFileTreeBuilder(Map<String, File> files) {

[MSG]Violation in class org.gradle.api.internal.file.AntFileTreeBuilder. The def keyword is unneeded on constructors

UnnecessaryParenthesesForMethodCallWithClosure329

[SRC]node."${childNodeName ?: 'resources'}"() {

[MSG]Violation in class org.gradle.api.internal.file.AntFileTreeBuilder. Parentheses in the 'null' method call are unnecessary and can be removed.

Package: src.org.gradle.api.internal.project

➥ DefaultAntBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration332

[SRC]def DefaultAntBuilder(Project gradleProject) {

[MSG]Violation in class org.gradle.api.internal.project.DefaultAntBuilder. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration336

[SRC]def Object invokeMethod(String methodName, Object args) {

[MSG]Violation in class org.gradle.api.internal.project.DefaultAntBuilder. The def keyword is unneeded when a method returns the Object type

UnnecessaryOverridingMethod336

[SRC]def Object invokeMethod(String methodName, Object args) {

[MSG]Violation in class DefaultAntBuilder. The method invokeMethod contains no logic and can be safely deleted

UnnecessaryDefInMethodDeclaration344

[SRC]private def doSetProperty(String property, newValue) {

[MSG]Violation in class org.gradle.api.internal.project.DefaultAntBuilder. The def keyword is unneeded when a method is marked private

UnnecessaryGetter375

[SRC]antProject.setUserProperty(MagicNames.ANT_FILE, file.get..olutePath())

[MSG]Violation in class org.gradle.api.internal.project.DefaultAntBuilder. getAbsolutePath() can probably be rewritten as absolutePath

➥ DefaultIsolatedAntBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration331

[SRC]def DefaultIsolatedAntBuilder(ClassPathRegistry classPat..erFactory) {

[MSG]Violation in class org.gradle.api.internal.project.DefaultIsolatedAntBuilder. The def keyword is unneeded on constructors

UnnecessaryDotClass3103

[SRC]Object antBuilder = gradleLoader.loadClass(BasicAntBuild..ewInstance()

[MSG]BasicAntBuilder.class can be rewritten as BasicAntBuilder

UnnecessaryDotClass3105

[SRC]Object antLogger = gradleLoader.loadClass(AntLoggingAdap..ewInstance()

[MSG]AntLoggingAdapter.class can be rewritten as AntLoggingAdapter

UnnecessaryGetter3106

[SRC]antBuilder.project.removeBuildListener(antBuilder.projec..teners()[0])

[MSG]Violation in class org.gradle.api.internal.project.DefaultIsolatedAntBuilder. getBuildListeners() can probably be rewritten as buildListeners

UnnecessaryDefInMethodDeclaration3124

[SRC]def AntBuilderDelegate(builder, antlibClassLoader) {

[MSG]Violation in class org.gradle.api.internal.project.AntBuilderDelegate. The def keyword is unneeded on constructors

➥ ProjectScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration329

[SRC]def void apply(Closure closure) {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration333

[SRC]def void apply(Map options) {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration337

[SRC]def ScriptHandler getBuildscript() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration341

[SRC]def void buildscript(Closure configureClosure) {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration345

[SRC]def StandardOutputCapture getStandardOutputCapture() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration349

[SRC]def LoggingManager getLogging() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration353

[SRC]def Logger getLogger() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration357

[SRC]def String toString() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

Package: src.org.gradle.api.internal.tasks.compile

➥ AntGroovyCompiler.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField235

[SRC]private static Logger logger = LoggerFactory.getLogger(A..ovyCompiler)

[MSG]The field logger is not used within the class org.gradle.api.internal.tasks.compile.AntGroovyCompiler

UnnecessaryDefInMethodDeclaration342

[SRC]def AntGroovyCompiler(IsolatedAntBuilder ant, ClassPathR..hRegistry) {

[MSG]Violation in class org.gradle.api.internal.tasks.compile.AntGroovyCompiler. The def keyword is unneeded on constructors

Package: src.org.gradle.api.internal.tasks.scala

➥ AntScalaCompiler.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField227

[SRC]private static Logger logger = LoggerFactory.getLogger(A..alaCompiler)

[MSG]The field logger is not used within the class org.gradle.api.internal.tasks.scala.AntScalaCompiler

UnnecessaryDefInMethodDeclaration333

[SRC]def AntScalaCompiler(IsolatedAntBuilder antBuilder) {

[MSG]Violation in class org.gradle.api.internal.tasks.scala.AntScalaCompiler. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration339

[SRC]def AntScalaCompiler(IsolatedAntBuilder antBuilder, Iter..nsionDirs) {

[MSG]Violation in class org.gradle.api.internal.tasks.scala.AntScalaCompiler. The def keyword is unneeded on constructors

Package: src.org.gradle.api.plugins

➥ ApplicationPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences398

[SRC]installTask.doLast {

[MSG]The code could be more concise by using a with() or identity() block

➥ BasePlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass377

[SRC]Delete clean = project.tasks.add(CLEAN_TASK_NAME, Delete.class)

[MSG]Delete.class can be rewritten as Delete

UnnecessarySubstring392

[SRC]String targetTaskName = taskName.substring(prefix.length())

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3118

[SRC]Configuration configuration = project.configurations.fin...length())))

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3120

[SRC]project.tasks.add(taskName).dependsOn(configuration.getA..figuration))

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. getAllArtifacts() can probably be rewritten as allArtifacts

UnnecessaryGetter3158

[SRC]Upload upload = project.getTasks().add(name, Upload.class)

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. getTasks() can probably be rewritten as tasks

UnnecessaryDotClass3158

[SRC]Upload upload = project.getTasks().add(name, Upload.class)

[MSG]Upload.class can be rewritten as Upload

UnnecessaryGetter3161

[SRC]upload.descriptorDestination = new File(project.getBuild.., "ivy.xml")

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. getBuildDir() can probably be rewritten as buildDir

UnnecessaryGetter3168

[SRC]ConfigurationContainer configurations = project.getConfigurations();

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. getConfigurations() can probably be rewritten as configurations

➥ JavaPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass374

[SRC]sourceSets = instantiator.newInstance(DefaultSourceSetCo..nstantiator)

[MSG]DefaultSourceSetContainer.class can be rewritten as DefaultSourceSetContainer

UnnecessaryGetter3185

[SRC]return ConfigureUtil.configure(closure, new DefaultManif..eResolver));

[MSG]Violation in class org.gradle.api.plugins.JavaPluginConvention. getProject() can probably be rewritten as project

➥ ProjectReportsPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration329

[SRC]def ProjectReportsPluginConvention(Project project) {

[MSG]Violation in class org.gradle.api.plugins.ProjectReportsPluginConvention. The def keyword is unneeded on constructors

➥ WarPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration327

[SRC]def WarPluginConvention(Project project) {

[MSG]Violation in class org.gradle.api.plugins.WarPluginConvention. The def keyword is unneeded on constructors

Package: src.org.gradle.api.plugins.announce.internal

➥ AnnouncingBuildListener.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter235

[SRC]void beforeExecute(Task task) {

[MSG]Violation in class AnnouncingBuildListener. Method parameter [task] is never referenced in the method beforeExecute of class org.gradle.api.plugins.announce.internal.AnnouncingBuildListener

UnnecessaryElseStatement373

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ AppleScriptBackedGrowlAnnouncer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration356

[SRC]private def escape(String value) {

[MSG]Violation in class org.gradle.api.plugins.announce.internal.AppleScriptBackedGrowlAnnouncer. The def keyword is unneeded when a method is marked private

➥ DefaultAnnouncerFactory.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock266

[SRC]} catch (ClassNotFoundException e) {

[MSG]The catch block is empty

UnusedMethodParameter278

[SRC]void send(String title, String message) {

[MSG]Violation in class UnknownAnnouncer. Method parameter [title] is never referenced in the method send of class org.gradle.api.plugins.announce.internal.UnknownAnnouncer

UnusedMethodParameter278

[SRC]void send(String title, String message) {

[MSG]Violation in class UnknownAnnouncer. Method parameter [message] is never referenced in the method send of class org.gradle.api.plugins.announce.internal.UnknownAnnouncer

UnnecessaryElseStatement351

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter365

[SRC]return getClass().getClassLoader().loadClass("org.gradle..conProvider)

[MSG]Violation in class org.gradle.api.plugins.announce.internal.DefaultAnnouncerFactory. getClassLoader() can probably be rewritten as classLoader

➥ GrowlNotifyBackedAnnouncer.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethod246

[SRC]private def escape(String value) {

[MSG]The method escape is not used within GrowlNotifyBackedAnnouncer.groovy

UnnecessaryDefInMethodDeclaration346

[SRC]private def escape(String value) {

[MSG]Violation in class org.gradle.api.plugins.announce.internal.GrowlNotifyBackedAnnouncer. The def keyword is unneeded when a method is marked private

➥ Snarl.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter343

[SRC]with(new PrintWriter(sock.getOutputStream(), true)) { out ->

[MSG]Violation in class org.gradle.api.plugins.announce.internal.Snarl. getOutputStream() can probably be rewritten as outputStream

UnnecessaryElseStatement366

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ Twitter.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSunPackages220

[SRC]import sun.misc.BASE64Encoder

[MSG]The file imports sun.misc.BASE64Encoder, which is not portable and likely to change

UnusedMethodParameter240

[SRC]void send(String title, String message) {

[MSG]Violation in class Twitter. Method parameter [title] is never referenced in the method send of class org.gradle.api.plugins.announce.internal.Twitter

Package: src.org.gradle.api.plugins.quality

➥ Checkstyle.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter366

[SRC]getConfigProperties()

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getConfigProperties() can probably be rewritten as configProperties

UnnecessaryGetter3144

[SRC]antBuilder.withClasspath(getCheckstyleClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getCheckstyleClasspath() can probably be rewritten as checkstyleClasspath

UnnecessaryGetter3147

[SRC]ant.checkstyle(config: getConfigFile(), failOnViolation:..pertyName) {

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getConfigFile() can probably be rewritten as configFile

UnnecessaryGetter3148

[SRC]getSource().addToAntBuilder(ant, 'fileset', FileCollecti..ype.FileSet)

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getSource() can probably be rewritten as source

UnnecessaryGetter3149

[SRC]getClasspath().addToAntBuilder(ant, 'classpath')

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter3155

[SRC]getConfigProperties().each { key, value ->

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getConfigProperties() can probably be rewritten as configProperties

UnnecessaryGetter3160

[SRC]if (!getIgnoreFailures() && ant.project.properties[propertyName]) {

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getIgnoreFailures() can probably be rewritten as ignoreFailures

➥ CodeNarc.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3102

[SRC]antBuilder.withClasspath(getCodenarcClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.CodeNarc. getCodenarcClasspath() can probably be rewritten as codenarcClasspath

UnnecessaryGetter3105

[SRC]ant.codenarc(ruleSetFiles: "file:${getConfigFile()}", ma..ations: 0) {

[MSG]Violation in class org.gradle.api.plugins.quality.CodeNarc. getConfigFile() can probably be rewritten as configFile

UnnecessaryGetter3116

[SRC]if (getIgnoreFailures()) {

[MSG]Violation in class org.gradle.api.plugins.quality.CodeNarc. getIgnoreFailures() can probably be rewritten as ignoreFailures

➥ FindBugs.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3113

[SRC]antBuilder.withClasspath(getFindbugsClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getFindbugsClasspath() can probably be rewritten as findbugsClasspath

UnnecessaryGetter3116

[SRC]getFindbugsClasspath().addToAntBuilder(ant, 'classpath')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getFindbugsClasspath() can probably be rewritten as findbugsClasspath

UnnecessaryGetter3117

[SRC]getPluginClasspath().addToAntBuilder(ant, 'pluginList')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getPluginClasspath() can probably be rewritten as pluginClasspath

UnnecessaryGetter3118

[SRC]getClasses().addToAntBuilder(ant, 'auxAnalyzepath')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getClasses() can probably be rewritten as classes

UnnecessaryGetter3121

[SRC]addUnlessEmpty(ant, getClasspath(), 'auxClasspath')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter3122

[SRC]addUnlessEmpty(ant, getSource(), 'sourcePath')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getSource() can probably be rewritten as source

➥ GroovyCodeQualityPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration340

[SRC]def GroovyCodeQualityPluginConvention(Project project) {

[MSG]Violation in class org.gradle.api.plugins.quality.GroovyCodeQualityPluginConvention. The def keyword is unneeded on constructors

➥ JDepend.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter399

[SRC]antBuilder.withClasspath(getJdependClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.JDepend. getJdependClasspath() can probably be rewritten as jdependClasspath

UnnecessaryGetter3103

[SRC]pathElement(location: getClassesDir())

[MSG]Violation in class org.gradle.api.plugins.quality.JDepend. getClassesDir() can probably be rewritten as classesDir

➥ JavaCodeQualityPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration340

[SRC]def JavaCodeQualityPluginConvention(Project project) {

[MSG]Violation in class org.gradle.api.plugins.quality.JavaCodeQualityPluginConvention. The def keyword is unneeded on constructors

➥ Pmd.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter368

[SRC]antBuilder.withClasspath(getPmdClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getPmdClasspath() can probably be rewritten as pmdClasspath

UnnecessaryGetter370

[SRC]ant.pmd(failOnRuleViolation: !getIgnoreFailures()) {

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getIgnoreFailures() can probably be rewritten as ignoreFailures

UnnecessaryGetter371

[SRC]getSource().addToAntBuilder(ant, 'fileset', FileCollecti..ype.FileSet)

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getSource() can probably be rewritten as source

UnnecessaryGetter372

[SRC]getRuleSets().each {

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getRuleSets() can probably be rewritten as ruleSets

UnnecessaryGetter375

[SRC]getRuleSetFiles().each {

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getRuleSetFiles() can probably be rewritten as ruleSetFiles

Package: src.org.gradle.api.plugins.quality.internal

➥ AbstractCodeQualityPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2106

[SRC]protected void configureTaskDefaults(T task, String baseName) {

[MSG]Violation in class AbstractCodeQualityPlugin. Method parameter [task] is never referenced in the method configureTaskDefaults of class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin

UnusedMethodParameter2106

[SRC]protected void configureTaskDefaults(T task, String baseName) {

[MSG]Violation in class AbstractCodeQualityPlugin. Method parameter [baseName] is never referenced in the method configureTaskDefaults of class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin

UnusedMethodParameter2118

[SRC]protected void configureForSourceSet(SourceSet sourceSet, T task) {

[MSG]Violation in class AbstractCodeQualityPlugin. Method parameter [sourceSet] is never referenced in the method configureForSourceSet of class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin

UnusedMethodParameter2118

[SRC]protected void configureForSourceSet(SourceSet sourceSet, T task) {

[MSG]Violation in class AbstractCodeQualityPlugin. Method parameter [task] is never referenced in the method configureForSourceSet of class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin

UnnecessarySubstring3101

[SRC]prunedName = prunedName[0].toLowerCase() + prunedName.substring(1)

[MSG]Violation in class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryCollectCall3123

[SRC]project.tasks['check'].dependsOn { extension.sourceSets...me, null) }}

[MSG]Violation in class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin. The call to collect could probably be rewritten as a spread expression: extension.sourceSets*.getTaskName(taskBaseName, null)

Package: src.org.gradle.api.plugins.scala

➥ ScalaBasePlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter264

[SRC]private void configureCompileDefaults(final Project proj..avaPlugin) {

[MSG]Violation in class ScalaBasePlugin. Method parameter [javaPlugin] is never referenced in the method configureCompileDefaults of class org.gradle.api.plugins.scala.ScalaBasePlugin

UnnecessaryDotClass335

[SRC]JavaBasePlugin javaPlugin = project.plugins.apply(JavaBa..ugin.class);

[MSG]JavaBasePlugin.class can be rewritten as JavaBasePlugin

UnnecessaryDotClass346

[SRC]project.convention.getPlugin(JavaPluginConvention.class)..sourceSet ->

[MSG]JavaPluginConvention.class can be rewritten as JavaPluginConvention

UnnecessaryDotClass354

[SRC]ScalaCompile scalaCompile = project.tasks.add(taskName, ..pile.class);

[MSG]ScalaCompile.class can be rewritten as ScalaCompile

UnnecessaryDotClass365

[SRC]project.tasks.withType(ScalaCompile.class) {ScalaCompile compile ->

[MSG]ScalaCompile.class can be rewritten as ScalaCompile

UnnecessaryGetter371

[SRC]project.getTasks().withType(ScalaDoc.class) {ScalaDoc scalaDoc ->

[MSG]Violation in class org.gradle.api.plugins.scala.ScalaBasePlugin. getTasks() can probably be rewritten as tasks

UnnecessaryDotClass371

[SRC]project.getTasks().withType(ScalaDoc.class) {ScalaDoc scalaDoc ->

[MSG]ScalaDoc.class can be rewritten as ScalaDoc

➥ ScalaPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass330

[SRC]project.plugins.apply(ScalaBasePlugin.class);

[MSG]ScalaBasePlugin.class can be rewritten as ScalaBasePlugin

UnnecessaryDotClass331

[SRC]project.plugins.apply(JavaPlugin.class);

[MSG]JavaPlugin.class can be rewritten as JavaPlugin

UnnecessaryGetter337

[SRC]project.getTasks().withType(ScalaDoc.class) {ScalaDoc scalaDoc ->

[MSG]Violation in class org.gradle.api.plugins.scala.ScalaPlugin. getTasks() can probably be rewritten as tasks

UnnecessaryDotClass337

[SRC]project.getTasks().withType(ScalaDoc.class) {ScalaDoc scalaDoc ->

[MSG]ScalaDoc.class can be rewritten as ScalaDoc

UnnecessaryDotClass341

[SRC]ScalaDoc scalaDoc = project.tasks.add(SCALA_DOC_TASK_NAM..laDoc.class)

[MSG]ScalaDoc.class can be rewritten as ScalaDoc

Package: src.org.gradle.api.plugins.sonar.internal

➥ SonarCodeAnalyzer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences371

[SRC]projectDef.workDir = sonarProject.workDir

[MSG]The code could be more concise by using a with() or identity() block

Package: src.org.gradle.api.plugins.sonar.model

➥ IncludeProperties.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryPackageReference326

[SRC]public @interface IncludeProperties {}

[MSG]The java.lang.annotation.Annotation class was explicitly imported, so specifying the package name is not necessary

➥ SonarProperty.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryPackageReference326

[SRC]public @interface SonarProperty {

[MSG]The java.lang.annotation.Annotation class was explicitly imported, so specifying the package name is not necessary

Package: src.org.gradle.api.publication

➥ PublicationPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass336

[SRC]project.task("publishArchives", dependsOn: 'assemble', t..ons.class) {

[MSG]PublishPublications.class can be rewritten as PublishPublications

UnnecessaryDotClass339

[SRC]project.task("installArchives", dependsOn: 'assemble', t..ons.class) {

[MSG]InstallPublications.class can be rewritten as InstallPublications

➥ Publications.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter327

[SRC]ConfigureUtil.configure(c, getMaven())

[MSG]Violation in class org.gradle.api.publication.Publications. getMaven() can probably be rewritten as maven

Package: src.org.gradle.api.publication.maven.internal

➥ MavenPublicationPomGenerator.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences344

[SRC]model.description = publication.description

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences355

[SRC]dependency.optional = mavenDep.optional

[MSG]The code could be more concise by using a with() or identity() block

Package: src.org.gradle.api.publication.maven.internal.ant

➥ DefaultGroovyMavenDeployer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryElseStatement347

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ DefaultMavenPublisher.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration355

[SRC]private def execute(MavenPublication publication, Instal..port task) {

[MSG]Violation in class org.gradle.api.publication.maven.internal.ant.DefaultMavenPublisher. The def keyword is unneeded when a method is marked private

Package: src.org.gradle.api.publication.maven.internal.model

➥ DefaultMavenPublication.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter342

[SRC]ConfigureUtil.configure(c, getRepository())

[MSG]Violation in class org.gradle.api.publication.maven.internal.model.DefaultMavenPublication. getRepository() can probably be rewritten as repository

Package: src.org.gradle.api.tasks.application

➥ CreateStartScripts.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter369

[SRC]if (!getApplicationName()) {

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter372

[SRC]return "${GUtil.toConstant(getApplicationName())}_OPTS"

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter380

[SRC]if (!getApplicationName()) {

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter383

[SRC]return "${GUtil.toConstant(getApplicationName())}_EXIT_CONSOLE"

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter388

[SRC]return new File(getOutputDir(), getApplicationName())

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter388

[SRC]return new File(getOutputDir(), getApplicationName())

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter393

[SRC]return new File(getOutputDir(), "${getApplicationName()}.bat")

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter393

[SRC]return new File(getOutputDir(), "${getApplicationName()}.bat")

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter398

[SRC]getOutputDir().mkdirs()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter3101

[SRC]generator.applicationName = getApplicationName()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter3102

[SRC]generator.mainClassName = getMainClassName()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getMainClassName() can probably be rewritten as mainClassName

UnnecessaryGetter3103

[SRC]generator.optsEnvironmentVar = getOptsEnvironmentVar()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getOptsEnvironmentVar() can probably be rewritten as optsEnvironmentVar

UnnecessaryGetter3104

[SRC]generator.exitEnvironmentVar = getExitEnvironmentVar()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getExitEnvironmentVar() can probably be rewritten as exitEnvironmentVar

UnnecessaryGetter3105

[SRC]generator.classpath = getClasspath().collect { "lib/${it.name}" }

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter3106

[SRC]generator.scriptRelPath = "bin/${getUnixScript().name}"

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getUnixScript() can probably be rewritten as unixScript

UnnecessaryObjectReferences3106

[SRC]generator.scriptRelPath = "bin/${getUnixScript().name}"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3107

[SRC]generator.generateUnixScript(getUnixScript())

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getUnixScript() can probably be rewritten as unixScript

UnnecessaryObjectReferences3107

[SRC]generator.generateUnixScript(getUnixScript())

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3108

[SRC]generator.generateWindowsScript(getWindowsScript())

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getWindowsScript() can probably be rewritten as windowsScript

UnnecessaryObjectReferences3108

[SRC]generator.generateWindowsScript(getWindowsScript())

[MSG]The code could be more concise by using a with() or identity() block

Package: src.org.gradle.api.tasks.bundling

➥ Jar.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter347

[SRC]Manifest manifest = getManifest() ?: new DefaultManifest(null)

[MSG]Violation in class org.gradle.api.tasks.bundling.Jar. getManifest() can probably be rewritten as manifest

UnnecessaryGetter386

[SRC]if (getManifest() == null) {

[MSG]Violation in class org.gradle.api.tasks.bundling.Jar. getManifest() can probably be rewritten as manifest

UnnecessaryGetter389

[SRC]ConfigureUtil.configure(configureClosure, getManifest());

[MSG]Violation in class org.gradle.api.tasks.bundling.Jar. getManifest() can probably be rewritten as manifest

UnnecessaryGetter3107

[SRC]return ConfigureUtil.configure(configureClosure, getMetaInf())

[MSG]Violation in class org.gradle.api.tasks.bundling.Jar. getMetaInf() can probably be rewritten as metaInf

➥ War.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]def classpath = getClasspath()

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter352

[SRC]def classpath = getClasspath()

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter358

[SRC]getWebXml()

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getWebXml() can probably be rewritten as webXml

UnnecessaryGetter380

[SRC]return ConfigureUtil.configure(configureClosure, getWebInf())

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getWebInf() can probably be rewritten as webInf

UnnecessaryGetter3110

[SRC]FileCollection oldClasspath = getClasspath()

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getClasspath() can probably be rewritten as classpath

Package: src.org.gradle.api.tasks.compile

➥ AbstractOptions.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter348

[SRC]((field.getModifiers() & Modifier.STATIC) == 0) &&

[MSG]Violation in class org.gradle.api.tasks.compile.AbstractOptions. getModifiers() can probably be rewritten as modifiers

UnnecessaryGetter349

[SRC](field.getName() != "metaClass") &&

[MSG]Violation in class org.gradle.api.tasks.compile.AbstractOptions. getName() can probably be rewritten as name

Package: src.org.gradle.api.tasks.javadoc

➥ AntGroovydoc.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration331

[SRC]def AntGroovydoc(IsolatedAntBuilder ant, ClassPathRegist..hRegistry) {

[MSG]Violation in class org.gradle.api.tasks.javadoc.AntGroovydoc. The def keyword is unneeded on constructors

Package: src.org.gradle.api.tasks.scala

➥ AntScalaDoc.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField224

[SRC]private static Logger logger = LoggerFactory.getLogger(AntScalaDoc)

[MSG]The field logger is not used within the class org.gradle.api.tasks.scala.AntScalaDoc

UnnecessaryDefInMethodDeclaration330

[SRC]def AntScalaDoc(IsolatedAntBuilder antBuilder) {

[MSG]Violation in class org.gradle.api.tasks.scala.AntScalaDoc. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration336

[SRC]def AntScalaDoc(IsolatedAntBuilder antBuilder, Iterable<..nsionDirs) {

[MSG]Violation in class org.gradle.api.tasks.scala.AntScalaDoc. The def keyword is unneeded on constructors

Package: src.org.gradle.api.tasks.testing.testng

➥ TestNGOptions.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3194

[SRC]return suiteXmlBuilder.getMetaClass()."${name}"

[MSG]Violation in class org.gradle.api.tasks.testing.testng.TestNGOptions. getMetaClass() can probably be rewritten as metaClass

UnnecessaryElseStatement3195

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3202

[SRC]return suiteXmlBuilder.getMetaClass().invokeMethod(suite.. name, args)

[MSG]Violation in class org.gradle.api.tasks.testing.testng.TestNGOptions. getMetaClass() can probably be rewritten as metaClass

UnnecessaryElseStatement3203

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

Package: src.org.gradle.api.tasks.util

➥ PatternSet.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2206

[SRC]def addToAntBuilder(node, String childNodeName = null) {

[MSG]Violation in class PatternSet. Method parameter [childNodeName] is never referenced in the method addToAntBuilder of class org.gradle.api.tasks.util.PatternSet

UnusedMethodParameter2242

[SRC]def addToAntBuilder(Object node, String childNodeName) {

[MSG]Violation in class IntersectionPatternSet. Method parameter [childNodeName] is never referenced in the method addToAntBuilder of class org.gradle.api.tasks.util.IntersectionPatternSet

UnnecessaryDefInFieldDeclaration351

[SRC]def boolean caseSensitive = true

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a field type is specified

UnnecessaryDefInMethodDeclaration357

[SRC]static def setGlobalExcludes(Collection<String> excludes) {

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a method is marked static

UnnecessaryDefInMethodDeclaration362

[SRC]static def resetGlobalExcludes() {

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a method is marked static

UnnecessaryDefInMethodDeclaration366

[SRC]def boolean equals(Object o) {

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration376

[SRC]def int hashCode() {

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration3234

[SRC]def IntersectionPatternSet(PatternSet other) {

[MSG]Violation in class org.gradle.api.tasks.util.IntersectionPatternSet. The def keyword is unneeded on constructors

UnnecessaryGetter3239

[SRC]return new AndSpec<FileTreeElement>([super.getAsSpec(), ..] as Spec[])

[MSG]Violation in class org.gradle.api.tasks.util.IntersectionPatternSet. getAsSpec() can probably be rewritten as asSpec

UnnecessaryGetter3239

[SRC]return new AndSpec<FileTreeElement>([super.getAsSpec(), ..] as Spec[])

[MSG]Violation in class org.gradle.api.tasks.util.IntersectionPatternSet. getAsSpec() can probably be rewritten as asSpec

Package: src.org.gradle.groovy.scripts

➥ BasicScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass334

[SRC]standardOutputCapture = services.get(StandardOutputCapture.class)

[MSG]StandardOutputCapture.class can be rewritten as StandardOutputCapture

UnnecessaryDefInMethodDeclaration338

[SRC]def Object getScriptTarget() {

[MSG]Violation in class org.gradle.groovy.scripts.BasicScript. The def keyword is unneeded when a method returns the Object type

UnnecessaryDefInMethodDeclaration342

[SRC]def StandardOutputCapture getStandardOutputCapture() {

[MSG]Violation in class org.gradle.groovy.scripts.BasicScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryGetter365

[SRC]return target.getProperties()

[MSG]Violation in class org.gradle.groovy.scripts.BasicScript. getProperties() can probably be rewritten as properties

➥ DefaultScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass343

[SRC]private static final Logger LOGGER = Logging.getLogger(Script.class)

[MSG]Script.class can be rewritten as Script

UnnecessaryDefInMethodDeclaration349

[SRC]def void init(Object target, ServiceRegistry services) {

[MSG]Violation in class org.gradle.groovy.scripts.DefaultScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDotClass352

[SRC]loggingManager = services.get(LoggingManager.class)

[MSG]LoggingManager.class can be rewritten as LoggingManager

UnnecessaryDotClass368

[SRC]ObjectConfigurationAction action = new DefaultObjectConf..criptTarget)

[MSG]ScriptPluginFactory.class can be rewritten as ScriptPluginFactory

UnnecessaryDotClass374

[SRC]ObjectConfigurationAction action = new DefaultObjectConf..criptTarget)

[MSG]ScriptPluginFactory.class can be rewritten as ScriptPluginFactory

UnnecessaryDotClass380

[SRC]return services.get(ScriptHandler.class);

[MSG]ScriptHandler.class can be rewritten as ScriptHandler

UnnecessaryGetter384

[SRC]ConfigureUtil.configure(configureClosure, getBuildscript())

[MSG]Violation in class org.gradle.groovy.scripts.DefaultScript. getBuildscript() can probably be rewritten as buildscript

UnnecessaryDefInMethodDeclaration3172

[SRC]def String toString() {

[MSG]Violation in class org.gradle.groovy.scripts.DefaultScript. The def keyword is unneeded when a method specifies a return type

Package: src.org.gradle.initialization

➥ InitScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter323

[SRC]getBuildscript()

[MSG]Violation in class org.gradle.initialization.InitScript. getBuildscript() can probably be rewritten as buildscript

UnnecessaryDefInMethodDeclaration330

[SRC]def String toString() {

[MSG]Violation in class org.gradle.initialization.InitScript. The def keyword is unneeded when a method specifies a return type

➥ SettingsScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration321

[SRC]def String toString() {

[MSG]Violation in class org.gradle.initialization.SettingsScript. The def keyword is unneeded when a method specifies a return type

Package: src.org.gradle.integtests.fixtures

➥ AbstractAutoTestedSamplesTest.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod226

[SRC]void runSamplesFrom(String dir) {

[MSG]Violation in class AbstractAutoTestedSamplesTest. The method runSamplesFrom is public but not a test method

JUnitPublicNonTestMethod241

[SRC]void includeOnly(String includes) {

[MSG]Violation in class AbstractAutoTestedSamplesTest. The method includeOnly is public but not a test method

➥ AbstractIntegrationSpec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter344

[SRC]distribution.getTestDir();

[MSG]Violation in class org.gradle.integtests.fixtures.AbstractIntegrationSpec. getTestDir() can probably be rewritten as testDir

UnnecessaryGetter348

[SRC]getTestDir().file(path);

[MSG]Violation in class org.gradle.integtests.fixtures.AbstractIntegrationSpec. getTestDir() can probably be rewritten as testDir

UnnecessaryGetter3130

[SRC]executer.withUserHomeDir(distribution.getUserHomeDir())

[MSG]Violation in class org.gradle.integtests.fixtures.AbstractIntegrationSpec. getUserHomeDir() can probably be rewritten as userHomeDir

UnnecessaryGetter3131

[SRC]return new GradleBackedArtifactBuilder(executer, getTest..artifacts"))

[MSG]Violation in class org.gradle.integtests.fixtures.AbstractIntegrationSpec. getTestDir() can probably be rewritten as testDir

➥ AutoTestedSamplesUtil.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure334

[SRC]list.each() { runSamplesFromFile(it, runner) }

[MSG]Violation in class org.gradle.integtests.fixtures.AutoTestedSamplesUtil. Parentheses in the 'each' method call are unnecessary and can be removed.

➥ CrossVersionIntegrationSpec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]current.getTestDir();

[MSG]Violation in class org.gradle.integtests.fixtures.CrossVersionIntegrationSpec. getTestDir() can probably be rewritten as testDir

➥ CrossVersionTestRunner.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring368

[SRC]def minVersion = targetGradleVersion.substring(0, target..ength() - 1)

[MSG]Violation in class org.gradle.integtests.fixtures.CrossVersionTestRunner$PreviousVersionExecution. The String.substring(int, int) method can be replaced with the subscript operator

➥ HttpServer.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2338

[SRC]boolean reauthenticate(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [user] is never referenced in the method reauthenticate of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

UnusedMethodParameter2342

[SRC]boolean isUserInRole(Principal user, String role) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [user] is never referenced in the method isUserInRole of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

UnusedMethodParameter2342

[SRC]boolean isUserInRole(Principal user, String role) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [role] is never referenced in the method isUserInRole of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

EmptyMethod2346

[SRC]void disassociate(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. The method disassociate is both empty and not marked with @Override

UnusedMethodParameter2346

[SRC]void disassociate(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [user] is never referenced in the method disassociate of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

UnusedMethodParameter2349

[SRC]Principal pushRole(Principal user, String role) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [role] is never referenced in the method pushRole of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

EmptyMethod2357

[SRC]void logout(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. The method logout is both empty and not marked with @Override

UnusedMethodParameter2357

[SRC]void logout(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [user] is never referenced in the method logout of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

UnnecessaryDotClass331

[SRC]private static Logger logger = LoggerFactory.getLogger(H..erver.class)

[MSG]HttpServer.class can be rewritten as HttpServer

UnnecessarySubstring393

[SRC]def relativePath = request.pathInfo.substring(path.length() + 1)

[MSG]Violation in class org.gradle.integtests.fixtures.HttpServer$3. The String.substring(int) method can be replaced with the subscript operator

➥ JUnitTestExecutionResult.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2100

[SRC]TestClassExecutionResult assertTestSkipped(String name) {

[MSG]Violation in class JUnitTestClassExecutionResult. Method parameter [name] is never referenced in the method assertTestSkipped of class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult

UnusedMethodParameter2110

[SRC]TestClassExecutionResult assertConfigMethodPassed(String name) {

[MSG]Violation in class JUnitTestClassExecutionResult. Method parameter [name] is never referenced in the method assertConfigMethodPassed of class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult

UnusedMethodParameter2114

[SRC]TestClassExecutionResult assertConfigMethodFailed(String name) {

[MSG]Violation in class JUnitTestClassExecutionResult. Method parameter [name] is never referenced in the method assertConfigMethodFailed of class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult

MisorderedStaticImports321

[SRC]import static org.hamcrest.Matchers.*

[MSG]Static imports should appear before normal imports

MisorderedStaticImports322

[SRC]import static org.junit.Assert.assertThat

[MSG]Static imports should appear before normal imports

UnnecessaryDefInMethodDeclaration327

[SRC]def JUnitTestExecutionResult(TestFile projectDir, String..= 'build') {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestExecutionResult. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration341

[SRC]private def findTestClass(String testClass) {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration349

[SRC]private def findClasses() {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration369

[SRC]def JUnitTestClassExecutionResult(GPathResult testClassN..ClassName) {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration3130

[SRC]private def findTests() {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3160

[SRC]private def findIgnoredTests() {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult. The def keyword is unneeded when a method is marked private

➥ MavenRepository.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall3106

[SRC]artifactNames = names.collect { it.replace('-SNAPSHOT', ..-${build}")}

[MSG]Violation in class org.gradle.integtests.fixtures.MavenModule. The call to collect could probably be rewritten as a spread expression: names*.replace(-SNAPSHOT, -$timestamp-$build)

UnnecessaryCollectCall3283

[SRC]assert dependencies.collect { it.artifactId} as Set == a..ctIds as Set

[MSG]Violation in class org.gradle.integtests.fixtures.MavenScope. The call to collect could probably be rewritten as a spread expression: dependencies*.artifactId

➥ PreviousGradleVersionExecuter.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration360

[SRC]def String toString() {

[MSG]Violation in class org.gradle.integtests.fixtures.PreviousGradleVersionExecuter. The def keyword is unneeded when a method specifies a return type

UnnecessaryElseStatement3102

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryDefInMethodDeclaration3158

[SRC]def TestFile getGradleHomeDir() {

[MSG]Violation in class org.gradle.integtests.fixtures.PreviousGradleVersionExecuter. The def keyword is unneeded when a method specifies a return type

➥ SFTPServer.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock270

[SRC]} catch (Throwable e) {}

[MSG]The catch block is empty

EmptyCatchBlock273

[SRC]} catch (Throwable e) {}

[MSG]The catch block is empty

EmptyCatchBlock277

[SRC]} catch (Throwable e) {}

[MSG]The catch block is empty

EmptyMethod2105

[SRC]public void showMessage(String message) {

[MSG]Violation in class SFTPServer$1. The method showMessage is both empty and not marked with @Override

UnusedMethodParameter2128

[SRC]boolean authenticate(String username, PublicKey key, Ser..n session) {

[MSG]Violation in class SFTPServer$3. Method parameter [username] is never referenced in the method authenticate of class org.gradle.integtests.fixtures.SFTPServer$3

UnusedMethodParameter2128

[SRC]boolean authenticate(String username, PublicKey key, Ser..n session) {

[MSG]Violation in class SFTPServer$3. Method parameter [key] is never referenced in the method authenticate of class org.gradle.integtests.fixtures.SFTPServer$3

UnusedMethodParameter2128

[SRC]boolean authenticate(String username, PublicKey key, Ser..n session) {

[MSG]Violation in class SFTPServer$3. Method parameter [session] is never referenced in the method authenticate of class org.gradle.integtests.fixtures.SFTPServer$3

UnusedMethodParameter2160

[SRC]boolean authenticate(String username, String password, o..n session) {

[MSG]Violation in class DummyPasswordAuthenticator. Method parameter [session] is never referenced in the method authenticate of class org.gradle.integtests.fixtures.DummyPasswordAuthenticator

UnnecessaryGetter3114

[SRC]FileUtils.copyURLToFile(fileUrl, new File(configDir.getR..-dsa.key"));

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryGetter3118

[SRC]sshServer.setFileSystemFactory(new TestNativeFileSystemF..stLogger() {

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryGetter3125

[SRC]sshServer.setKeyPairProvider(new SimpleGeneratorHostKeyP..-dsa.key"));

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryObjectReferences3126

[SRC]sshServer.setPasswordAuthenticator(new DummyPasswordAuthenticator());

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3127

[SRC]sshServer.setPublickeyAuthenticator(new PublickeyAuthenticator() {

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3136

[SRC]new File(baseDir.getRoot(), filePathToCheck).exists()

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryGetter3140

[SRC]new TestFile(new File(baseDir.getRoot(), expectedPath))

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryPackageReference3160

[SRC]boolean authenticate(String username, String password, o..n session) {

[MSG]The org.apache.sshd.server.session.ServerSession class was explicitly imported, so specifying the package name is not necessary

➥ TestNGExecutionResult.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter284

[SRC]TestClassExecutionResult assertTestsSkipped(String... testNames) {

[MSG]Violation in class TestNgTestClassExecutionResult. Method parameter [testNames] is never referenced in the method assertTestsSkipped of class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult

UnusedMethodParameter2107

[SRC]TestClassExecutionResult assertStdout(Matcher<? super St..> matcher) {

[MSG]Violation in class TestNgTestClassExecutionResult. Method parameter [matcher] is never referenced in the method assertStdout of class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult

UnusedMethodParameter2111

[SRC]TestClassExecutionResult assertStderr(Matcher<? super St..> matcher) {

[MSG]Violation in class TestNgTestClassExecutionResult. Method parameter [matcher] is never referenced in the method assertStderr of class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult

UnnecessaryDefInMethodDeclaration330

[SRC]def TestNGExecutionResult(projectDir) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNGExecutionResult. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration346

[SRC]private def findTestClass(String testClass) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNGExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration354

[SRC]private def findTestClasses() {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNGExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInFieldDeclaration364

[SRC]def String testClass

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a field type is specified

UnnecessaryDefInFieldDeclaration365

[SRC]def GPathResult testClassNode

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a field type is specified

UnnecessaryDefInMethodDeclaration367

[SRC]def TestNgTestClassExecutionResult(String testClass, GPa..resultXml) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration3127

[SRC]private def findConfigMethod(String testName) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3135

[SRC]private def findConfigMethods() {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3143

[SRC]private def findTestMethod(String testName) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3151

[SRC]private def findTestMethods() {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a method is marked private

➥ TestNativeFileSystem.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter367

[SRC]return getFile(baseDir.getAbsolutePath(), file);

[MSG]Violation in class org.gradle.integtests.fixtures.TestNativeFileSystemView. getAbsolutePath() can probably be rewritten as absolutePath

UnnecessarySubstring377

[SRC]String userFileName = physicalName.substring("/".length() - 1);

[MSG]Violation in class org.gradle.integtests.fixtures.TestNativeFileSystemView. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3107

[SRC]String userName = session.getUsername();

[MSG]Violation in class org.gradle.integtests.fixtures.TestNativeFileSystemFactory. getUsername() can probably be rewritten as username

➥ TestProxyServer.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter251

[SRC]void filter(HttpRequest httpRequest) {

[MSG]Violation in class TestProxyServer$1. Method parameter [httpRequest] is never referenced in the method filter of class org.gradle.integtests.fixtures.TestProxyServer$1

➥ UserGuideSamplesRunner.groovy

Rule NamePriorityLine #Source Line / Message
EmptyIfStatement2176

[SRC]if (line.matches('Download .+')) {

[MSG]The if statement is empty

UnnecessaryDefInMethodDeclaration342

[SRC]def UserGuideSamplesRunner(Class<?> testClass) {

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. The def keyword is unneeded on constructors

UnnecessaryGetter345

[SRC]this.dirFilter = getDirFilterPattern()

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. getDirFilterPattern() can probably be rewritten as dirFilterPattern

UnnecessaryDefInMethodDeclaration388

[SRC]private def cleanup(SampleRun run) {

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration399

[SRC]private def runSample(GradleRun run) {

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3138

[SRC]private def compareStrings(String expected, String actua..xtraLines) {

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. The def keyword is unneeded when a method is marked private

UnnecessaryPackageReference3197

[SRC]actual = actual.replaceAll(java.util.regex.Pattern.quote..le/samples')

[MSG]The java.util.regex.Pattern class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3199

[SRC]actual = actual.replaceAll(java.util.regex.Pattern.quote..rator), '/')

[MSG]The java.util.regex.Pattern class was explicitly imported, so specifying the package name is not necessary

➥ WellBehavedPluginTest.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod223

[SRC]String getPluginId() {

[MSG]Violation in class WellBehavedPluginTest. The method getPluginId is public but not a test method

JUnitPublicNonTestMethod231

[SRC]String getMainTask() {

[MSG]Violation in class WellBehavedPluginTest. The method getMainTask is public but not a test method

JUnitPublicNonTestMethod235

[SRC]def "plugin does not force creation of build dir during ..uration"() {

[MSG]Violation in class WellBehavedPluginTest. The method plugin does not force creation of build dir during configuration is public but not a test method

JUnitPublicNonTestMethod246

[SRC]def "plugin can build with empty project"() {

[MSG]Violation in class WellBehavedPluginTest. The method plugin can build with empty project is public but not a test method

UnnecessaryGetter337

[SRC]buildFile << "apply plugin: '${getPluginId()}'"

[MSG]Violation in class org.gradle.integtests.fixtures.WellBehavedPluginTest. getPluginId() can probably be rewritten as pluginId

UnnecessaryGetter348

[SRC]buildFile << "apply plugin: '${getPluginId()}'"

[MSG]Violation in class org.gradle.integtests.fixtures.WellBehavedPluginTest. getPluginId() can probably be rewritten as pluginId

Package: src.org.gradle.plugins.binaries.model.internal

➥ ConfigurationBasedNativeDependencySet.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter350

[SRC]def headersConfiguration = getHeadersConfiguration()

[MSG]Violation in class org.gradle.plugins.binaries.model.internal.ConfigurationBasedNativeDependencySet. getHeadersConfiguration() can probably be rewritten as headersConfiguration

Package: src.org.gradle.plugins.cpp.cdt.model

➥ CprojectDescriptor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2109

[SRC]protected void store(Node xml) {

[MSG]Violation in class CprojectDescriptor. Method parameter [xml] is never referenced in the method store of class org.gradle.plugins.cpp.cdt.model.CprojectDescriptor

Package: src.org.gradle.plugins.cpp.gpp

➥ GppCompileSpec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter367

[SRC]task.outputs.file { getOutputFile() }

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getOutputFile() can probably be rewritten as outputFile

UnnecessaryGetter3143

[SRC]project.file "$project.buildDir/binaries/${getOutputFileName()}"

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getOutputFileName() can probably be rewritten as outputFileName

UnnecessaryGetter3150

[SRC]return "${getBaseName()}.${extension}"

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getBaseName() can probably be rewritten as baseName

UnnecessaryElseStatement3151

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3152

[SRC]return getDefaultOutputFileName()

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getDefaultOutputFileName() can probably be rewritten as defaultOutputFileName

UnnecessaryGetter3157

[SRC]return OperatingSystem.current().getExecutableName(getBaseName())

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getBaseName() can probably be rewritten as baseName

➥ GppLibraryCompileSpec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter334

[SRC]return OperatingSystem.current().getSharedLibraryName(getBaseName())

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppLibraryCompileSpec. getBaseName() can probably be rewritten as baseName

UnnecessaryGetter338

[SRC]return installName ?: getOutputFileName()

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppLibraryCompileSpec. getOutputFileName() can probably be rewritten as outputFileName

Package: src.org.gradle.plugins.ear

➥ Ear.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter355

[SRC]getLibDirName()

[MSG]Violation in class org.gradle.plugins.ear.Ear. getLibDirName() can probably be rewritten as libDirName

UnnecessarySubstring366

[SRC]module = new DefaultEarWebModule(details.path, details.p..dexOf('.')))

[MSG]Violation in class org.gradle.plugins.ear.Ear. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessaryGetter3128

[SRC]return ConfigureUtil.configure(configureClosure, getLib())

[MSG]Violation in class org.gradle.plugins.ear.Ear. getLib() can probably be rewritten as lib

➥ EarPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration365

[SRC]def EarPluginConvention(FileResolver fileResolver) {

[MSG]Violation in class org.gradle.plugins.ear.EarPluginConvention. The def keyword is unneeded on constructors

Package: src.org.gradle.plugins.ear.descriptor.internal

➥ DefaultDeploymentDescriptor.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3189

[SRC]if (file.getParentFile() != null) {

[MSG]Violation in class org.gradle.plugins.ear.descriptor.internal.DefaultDeploymentDescriptor. getParentFile() can probably be rewritten as parentFile

UnnecessaryGetter3190

[SRC]file.getParentFile().mkdirs()

[MSG]Violation in class org.gradle.plugins.ear.descriptor.internal.DefaultDeploymentDescriptor. getParentFile() can probably be rewritten as parentFile

➥ DefaultEarWebModule.groovy

Rule NamePriorityLine #Source Line / Message
UnusedObject239

[SRC]new Node(web, nodeNameFor("web-uri", name), path)

[MSG]The instantiated object is not used

UnusedObject240

[SRC]new Node(web, nodeNameFor("context-root", name), contextRoot)

[MSG]The instantiated object is not used

Package: src.org.gradle.plugins.ide.eclipse

➥ EclipseWtpPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter344

[SRC]EclipsePlugin delegatePlugin = project.getPlugins().appl..ugin.class);

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getPlugins() can probably be rewritten as plugins

UnnecessaryDotClass344

[SRC]EclipsePlugin delegatePlugin = project.getPlugins().appl..ugin.class);

[MSG]EclipsePlugin.class can be rewritten as EclipsePlugin

UnnecessaryGetter350

[SRC]delegatePlugin.getLifecycleTask().dependsOn(getLifecycleTask())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getLifecycleTask() can probably be rewritten as lifecycleTask

UnnecessaryGetter350

[SRC]delegatePlugin.getLifecycleTask().dependsOn(getLifecycleTask())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getLifecycleTask() can probably be rewritten as lifecycleTask

UnnecessaryGetter351

[SRC]delegatePlugin.getCleanTask().dependsOn(getCleanTask())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getCleanTask() can probably be rewritten as cleanTask

UnnecessaryGetter351

[SRC]delegatePlugin.getCleanTask().dependsOn(getCleanTask())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getCleanTask() can probably be rewritten as cleanTask

UnnecessaryDotClass396

[SRC]if (WarPlugin.class.isAssignableFrom(type)) {

[MSG]WarPlugin.class can be rewritten as WarPlugin

UnnecessaryDotClass3102

[SRC]} else if (EarPlugin.class.isAssignableFrom(type)) {

[MSG]EarPlugin.class can be rewritten as EarPlugin

➥ GenerateEclipseJdt.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]jdt = services.get(Instantiator).newInstance(EclipseJdt,..nsformer()))

[MSG]Violation in class org.gradle.plugins.ide.eclipse.GenerateEclipseJdt. getTransformer() can probably be rewritten as transformer

UnnecessaryGetter341

[SRC]return new Jdt(getTransformer())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.GenerateEclipseJdt. getTransformer() can probably be rewritten as transformer

UnnecessaryGetter345

[SRC]def jdtModel = getJdt()

[MSG]Violation in class org.gradle.plugins.ide.eclipse.GenerateEclipseJdt. getJdt() can probably be rewritten as jdt

Package: src.org.gradle.plugins.ide.eclipse.model

➥ AbstractClasspathEntry.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter361

[SRC]def allAttributes = attributes.findAll { it.value } + [k.. path: path]

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry. getKind() can probably be rewritten as kind

➥ AccessRule.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration325

[SRC]def AccessRule(kind, pattern) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.AccessRule. The def keyword is unneeded on constructors

➥ BuildCommand.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration325

[SRC]def BuildCommand(String name, Map arguments = [:]) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.BuildCommand. The def keyword is unneeded on constructors

➥ EclipseWtpComponent.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3144

[SRC]getLibConfigurations()

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.EclipseWtpComponent. getLibConfigurations() can probably be rewritten as libConfigurations

➥ EclipseWtpFacet.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3115

[SRC]xmlFacet.configure(getFacets())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.EclipseWtpFacet. getFacets() can probably be rewritten as facets

➥ Facet.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration330

[SRC]def Facet() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Facet. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration334

[SRC]def Facet(Node node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Facet. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration338

[SRC]def Facet(String name, String version) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Facet. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration342

[SRC]def Facet(FacetType type, String name, String version) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Facet. The def keyword is unneeded on constructors

➥ Link.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration329

[SRC]def Link(String name, String type, String location, Stri..cationUri) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Link. The def keyword is unneeded on constructors

➥ Output.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration327

[SRC]def Output(Node node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Output. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration331

[SRC]def Output(String path) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Output. The def keyword is unneeded on constructors

UnnecessaryGetter341

[SRC]node.appendNode('classpathentry', [kind: getKind(), path: path])

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Output. getKind() can probably be rewritten as kind

➥ Project.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration359

[SRC]def Project(XmlTransformer xmlTransformer) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration376

[SRC]private def readReferencedProjects() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration382

[SRC]private def readNatures() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration386

[SRC]private def readBuildCommands() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration396

[SRC]private def readLinkedResources() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3132

[SRC]private def addReferencedProjectsToXml() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3139

[SRC]private def addNaturesToXml() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3146

[SRC]private def addBuildSpecToXml() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3160

[SRC]private def addLinkedResourcesToXml() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

➥ WbDependentModule.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration328

[SRC]def WbDependentModule(node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbDependentModule. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration332

[SRC]def WbDependentModule(String deployPath, String handle) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbDependentModule. The def keyword is unneeded on constructors

➥ WbProperty.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration326

[SRC]def WbProperty(node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbProperty. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration330

[SRC]def WbProperty(String name, String value) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbProperty. The def keyword is unneeded on constructors

➥ WbResource.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration328

[SRC]def WbResource(node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbResource. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration332

[SRC]def WbResource(String deployPath, String sourcePath) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbResource. The def keyword is unneeded on constructors

Package: src.org.gradle.plugins.ide.eclipse.model.internal

➥ FileReferenceFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring349

[SRC]path = entry.key + filePath.substring(len)

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring391

[SRC]def file = new File(entry.value, path.substring(prefix.length()))

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3130

[SRC]", jarUrl='" + getJarURL() + '\'' +

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory$FileReferenceImpl. getJarURL() can probably be rewritten as jarURL

➥ WtpComponentFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall3100

[SRC]dependencies.collect { it.resolve() }.flatten() as LinkedHashSet

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.internal.WtpComponentFactory. The call to collect could probably be rewritten as a spread expression: dependencies*.resolve()

Package: src.org.gradle.plugins.ide.idea

➥ GenerateIdeaModule.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter343

[SRC]getModule().mergeXmlModule(xmlModule)

[MSG]Violation in class org.gradle.plugins.ide.idea.GenerateIdeaModule. getModule() can probably be rewritten as module

➥ GenerateIdeaProject.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]getIdeaProject().mergeXmlProject(xmlModule)

[MSG]Violation in class org.gradle.plugins.ide.idea.GenerateIdeaProject. getIdeaProject() can probably be rewritten as ideaProject

➥ GenerateIdeaWorkspace.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]getWorkspace().mergeXmlWorkspace(xmlWorkspace)

[MSG]Violation in class org.gradle.plugins.ide.idea.GenerateIdeaWorkspace. getWorkspace() can probably be rewritten as workspace

Package: src.org.gradle.plugins.ide.idea.model

➥ IdeaModel.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter360

[SRC]ConfigureUtil.configure(closure, getModule())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModel. getModule() can probably be rewritten as module

UnnecessaryGetter371

[SRC]ConfigureUtil.configure(closure, getProject())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModel. getProject() can probably be rewritten as project

UnnecessaryGetter382

[SRC]ConfigureUtil.configure(closure, getWorkspace())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModel. getWorkspace() can probably be rewritten as workspace

➥ IdeaModule.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3277

[SRC]ConfigureUtil.configure(closure, getIml())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getIml() can probably be rewritten as iml

UnnecessaryGetter3288

[SRC]new File((File) iml.getGenerateTo(), getName() + ".iml")

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getGenerateTo() can probably be rewritten as generateTo

UnnecessaryGetter3288

[SRC]new File((File) iml.getGenerateTo(), getName() + ".iml")

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getName() can probably be rewritten as name

UnnecessaryGetter3302

[SRC]return new IdeaDependenciesProvider().provide(this, getPathFactory())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getPathFactory() can probably be rewritten as pathFactory

UnnecessaryGetter3330

[SRC]def path = { getPathFactory().path(it) }

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getPathFactory() can probably be rewritten as pathFactory

UnnecessaryGetter3331

[SRC]def contentRoot = path(getContentRoot())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getContentRoot() can probably be rewritten as contentRoot

UnnecessaryGetter3332

[SRC]Set sourceFolders = getSourceDirs().findAll { it.exists(..{ path(it) }

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getSourceDirs() can probably be rewritten as sourceDirs

UnnecessaryGetter3333

[SRC]Set testSourceFolders = getTestSourceDirs().findAll { it..{ path(it) }

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getTestSourceDirs() can probably be rewritten as testSourceDirs

UnnecessaryGetter3334

[SRC]Set excludeFolders = getExcludeDirs().collect { path(it) }

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getExcludeDirs() can probably be rewritten as excludeDirs

UnnecessaryGetter3335

[SRC]def outputDir = getOutputDir() ? path(getOutputDir()) : null

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter3335

[SRC]def outputDir = getOutputDir() ? path(getOutputDir()) : null

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter3336

[SRC]def testOutputDir = getTestOutputDir() ? path(getTestOut..ir()) : null

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getTestOutputDir() can probably be rewritten as testOutputDir

UnnecessaryGetter3336

[SRC]def testOutputDir = getTestOutputDir() ? path(getTestOut..ir()) : null

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getTestOutputDir() can probably be rewritten as testOutputDir

UnnecessaryGetter3340

[SRC]getInheritOutputDirs(), outputDir, testOutputDir, depend..etJdkName())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getInheritOutputDirs() can probably be rewritten as inheritOutputDirs

UnnecessaryGetter3340

[SRC]getInheritOutputDirs(), outputDir, testOutputDir, depend..etJdkName())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getJdkName() can probably be rewritten as jdkName

➥ IdeaProject.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3136

[SRC]getOutputFile().name.replaceFirst(/\.ipr$/, '')

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getOutputFile() can probably be rewritten as outputFile

UnnecessaryGetter3146

[SRC]ConfigureUtil.configure(closure, getIpr())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getIpr() can probably be rewritten as ipr

UnnecessaryGetter3162

[SRC]def modulePaths = getModules().collect {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getModules() can probably be rewritten as modules

UnnecessaryGetter3163

[SRC]getPathFactory().relativePath('PROJECT_DIR', it.outputFile)

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getPathFactory() can probably be rewritten as pathFactory

UnnecessaryGetter3165

[SRC]xmlProject.configure(modulePaths, getJdkName(), getLangu..Wildcards())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getJdkName() can probably be rewritten as jdkName

UnnecessaryGetter3165

[SRC]xmlProject.configure(modulePaths, getJdkName(), getLangu..Wildcards())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getLanguageLevel() can probably be rewritten as languageLevel

UnnecessaryGetter3165

[SRC]xmlProject.configure(modulePaths, getJdkName(), getLangu..Wildcards())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getWildcards() can probably be rewritten as wildcards

➥ IdeaWorkspace.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter348

[SRC]ConfigureUtil.configure(closure, getIws())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaWorkspace. getIws() can probably be rewritten as iws

➥ JarDirectory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration334

[SRC]def JarDirectory(path, recursive) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.JarDirectory. The def keyword is unneeded on constructors

➥ Jdk.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration330

[SRC]def Jdk(String jdkName, IdeaLanguageLevel ideaLanguageLevel) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Jdk. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration346

[SRC]def Jdk(assertKeyword, jdk15, languageLevel, projectJdkName) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Jdk. The def keyword is unneeded on constructors

➥ Module.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration3155

[SRC]protected def configure(Path contentPath, Set sourceFold..ludeFolders,

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Module. The def keyword is unneeded when a method is marked protected

➥ ModuleDependency.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration336

[SRC]def ModuleDependency(name, scope) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleDependency. The def keyword is unneeded on constructors

UnnecessaryGetter343

[SRC]parentNode.appendNode('orderEntry', [type: 'module', 'mo..dExported())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleDependency. getAttributeMapForScopeAndExported() can probably be rewritten as attributeMapForScopeAndExported

UnnecessaryElseStatement368

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter377

[SRC]result = 31 * result + getScopeHash();

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleDependency. getScopeHash() can probably be rewritten as scopeHash

➥ ModuleLibrary.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration351

[SRC]def ModuleLibrary(Collection<Path> classes, Collection<P..ing scope) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleLibrary. The def keyword is unneeded on constructors

UnnecessaryGetter361

[SRC]Node libraryNode = parentNode.appendNode('orderEntry', [..e('library')

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleLibrary. getAttributeMapForScopeAndExported() can probably be rewritten as attributeMapForScopeAndExported

UnnecessaryElseStatement3104

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3117

[SRC]result = 31 * result + getScopeHash()

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleLibrary. getScopeHash() can probably be rewritten as scopeHash

➥ PathFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring384

[SRC]expandedUrl = toUrl('file', new File(expandedUrl.substri..nonicalFile)

[MSG]Violation in class org.gradle.plugins.ide.idea.model.PathFactory. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring386

[SRC]def parts = expandedUrl.substring(6).split('!')

[MSG]Violation in class org.gradle.plugins.ide.idea.model.PathFactory. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryDefInMethodDeclaration394

[SRC]private def toUrl(String scheme, File file) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.PathFactory. The def keyword is unneeded when a method is marked private

UnnecessaryElseStatement3106

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ Project.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration344

[SRC]def Project(XmlTransformer xmlTransformer, pathFactory) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Project. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration396

[SRC]private def findProjectRootManager() {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3100

[SRC]private def findWildcardResourcePatterns() {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3104

[SRC]private def findModules() {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Project. The def keyword is unneeded when a method is marked private

➥ SingleEntryModuleLibrary.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryElseStatement363

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryElseStatement374

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ Workspace.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration328

[SRC]def Workspace(XmlTransformer withXmlActions) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Workspace. The def keyword is unneeded on constructors

Package: src.org.gradle.plugins.ide.internal

➥ IdeDependenciesExtractor.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryPackageReference3118

[SRC]def filter = { it instanceof SelfResolvingDependency && ..Dependency)}

[MSG]The org.gradle.api.artifacts.ProjectDependency class was explicitly imported, so specifying the package name is not necessary

UnnecessaryCollectCall3122

[SRC]def files = deps.collect { it.resolve() }.flatten()

[MSG]Violation in class org.gradle.plugins.ide.internal.IdeDependenciesExtractor. The call to collect could probably be rewritten as a spread expression: deps*.resolve()

UnnecessaryCollectCall3127

[SRC]def files = deps.collect { it.resolve() }.flatten()

[MSG]Violation in class org.gradle.plugins.ide.internal.IdeDependenciesExtractor. The call to collect could probably be rewritten as a spread expression: deps*.resolve()

➥ IdePlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter265

[SRC]protected void onApply(Project target) {

[MSG]Violation in class IdePlugin. Method parameter [target] is never referenced in the method onApply of class org.gradle.plugins.ide.internal.IdePlugin

UnnecessaryGetter332

[SRC]String lifecyleTaskName = getLifecycleTaskName();

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getLifecycleTaskName() can probably be rewritten as lifecycleTaskName

UnnecessaryGetter349

[SRC]return project.getTasks().getByName(cleanName(worker.getName()));

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getTasks() can probably be rewritten as tasks

UnnecessaryGetter349

[SRC]return project.getTasks().getByName(cleanName(worker.getName()));

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getName() can probably be rewritten as name

UnnecessaryGetter358

[SRC]Delete cleanWorker = project.getTasks().add(cleanName(wo..elete.class)

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getTasks() can probably be rewritten as tasks

UnnecessaryGetter358

[SRC]Delete cleanWorker = project.getTasks().add(cleanName(wo..elete.class)

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getName() can probably be rewritten as name

UnnecessaryDotClass358

[SRC]Delete cleanWorker = project.getTasks().add(cleanName(wo..elete.class)

[MSG]Delete.class can be rewritten as Delete

UnnecessaryGetter359

[SRC]cleanWorker.delete(worker.getOutputs().getFiles())

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getFiles() can probably be rewritten as files

UnnecessaryGetter359

[SRC]cleanWorker.delete(worker.getOutputs().getFiles())

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getOutputs() can probably be rewritten as outputs

Package: src.org.gradle.plugins.ide.internal.configurer

➥ DeduplicationTarget.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInFieldDeclaration326

[SRC]def String moduleName

[MSG]Violation in class org.gradle.plugins.ide.internal.configurer.DeduplicationTarget. The def keyword is unneeded when a field type is specified

UnnecessaryDefInFieldDeclaration327

[SRC]def Project project

[MSG]Violation in class org.gradle.plugins.ide.internal.configurer.DeduplicationTarget. The def keyword is unneeded when a field type is specified

UnnecessaryDefInFieldDeclaration328

[SRC]def Closure updateModuleName

[MSG]Violation in class org.gradle.plugins.ide.internal.configurer.DeduplicationTarget. The def keyword is unneeded when a field type is specified

Package: src.org.gradle.plugins.ide.internal.generator

➥ AbstractPersistableConfigurationObject.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter338

[SRC]String defaultResourceName = getDefaultResourceName();

[MSG]Violation in class org.gradle.plugins.ide.internal.generator.AbstractPersistableConfigurationObject. getDefaultResourceName() can probably be rewritten as defaultResourceName

UnnecessaryGetter341

[SRC]throw new IllegalStateException(String.format("Failed to..getName()));

[MSG]Violation in class org.gradle.plugins.ide.internal.generator.AbstractPersistableConfigurationObject. getName() can probably be rewritten as name

➥ XmlPersistableConfigurationObject.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter251

[SRC]protected void load(Node xml) {

[MSG]Violation in class XmlPersistableConfigurationObject. Method parameter [xml] is never referenced in the method load of class org.gradle.plugins.ide.internal.generator.XmlPersistableConfigurationObject

UnusedMethodParameter258

[SRC]protected void store(Node xml) {

[MSG]Violation in class XmlPersistableConfigurationObject. Method parameter [xml] is never referenced in the method store of class org.gradle.plugins.ide.internal.generator.XmlPersistableConfigurationObject

Package: src.org.gradle.plugins.signing

➥ Sign.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2138

[SRC]void signatureType(SignatureType type) {

[MSG]Violation in class Sign. Method parameter [type] is never referenced in the method signatureType of class org.gradle.plugins.signing.Sign

UnnecessaryGetter365

[SRC]isRequired() || getSignatory() != null

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter369

[SRC]inputs.property("signatory") { getSignatory()?.keyId?.asHex }

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter371

[SRC]inputs.files { getSignatures()*.toSign }

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter372

[SRC]outputs.files { getSignatures()*.toSign }

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter3161

[SRC]if (getSignatory() == null) {

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter3162

[SRC]throw new InvalidUserDataException("Cannot perform signi.. signatory")

[MSG]Violation in class org.gradle.plugins.signing.Sign. getPath() can probably be rewritten as path

UnnecessaryGetter3165

[SRC]getSignatures()*.generate()

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter3182

[SRC]def signatureSet = getSignatures()

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter3196

[SRC]new SimpleFileCollection(*getSignatures()*.toSign.findAl.. != null }))

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter3203

[SRC]new SimpleFileCollection(*getSignatures()*.file.findAll(.. != null }))

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

➥ SignOperation.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter361

[SRC]getDisplayName()

[MSG]Violation in class org.gradle.plugins.signing.SignOperation. getDisplayName() can probably be rewritten as displayName

➥ Signature.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3176

[SRC]name == null ? (toSignArtifact?.name ?: getFile()?.name) : name

[MSG]Violation in class org.gradle.plugins.signing.Signature. getFile() can probably be rewritten as file

UnnecessaryGetter3187

[SRC]extension == null ? getSignatureType()?.extension : extension

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3200

[SRC]def toSign = getToSign()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getToSign() can probably be rewritten as toSign

UnnecessaryGetter3201

[SRC]def signatureType = getSignatureType()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3234

[SRC]def file = getFile()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getFile() can probably be rewritten as file

UnnecessaryGetter3260

[SRC]def toSign = getToSign()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getToSign() can probably be rewritten as toSign

UnnecessaryGetter3261

[SRC]def signatureType = getSignatureType()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3279

[SRC]signatureSpec.getSignatory()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter3288

[SRC]signatureSpec.getSignatureType()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3300

[SRC]def toSign = getToSign()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getToSign() can probably be rewritten as toSign

UnnecessaryGetter3309

[SRC]def signatory = getSignatory()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter3318

[SRC]def signatureType = getSignatureType()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

➥ SigningExtension.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3118

[SRC]this.configuration = getDefaultConfiguration()

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getDefaultConfiguration() can probably be rewritten as defaultConfiguration

UnnecessaryGetter3198

[SRC]spec.conventionMapping.map('signatory') { getSignatory() }

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter3199

[SRC]spec.conventionMapping.map('signatureType') { getSignatureType() }

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3222

[SRC]addSignaturesToConfiguration(signTask, getConfiguration())

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getConfiguration() can probably be rewritten as configuration

UnnecessaryGetter3243

[SRC]this.addSignaturesToConfiguration(signTask, getConfiguration())

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getConfiguration() can probably be rewritten as configuration

Package: src.org.gradle.plugins.signing.signatory.pgp

➥ PgpKeyId.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring363

[SRC]normalised = keyIdUpped.substring(2)

[MSG]Violation in class org.gradle.plugins.signing.signatory.pgp.PgpKeyId. The String.substring(int) method can be replaced with the subscript operator

Package: src.org.gradle.plugins.signing.type

➥ AbstractSignatureType.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]new File(toSign.path + ".${getExtension()}")

[MSG]Violation in class org.gradle.plugins.signing.type.AbstractSignatureType. getExtension() can probably be rewritten as extension

UnnecessaryGetter344

[SRC]getExtension()

[MSG]Violation in class org.gradle.plugins.signing.type.AbstractSignatureType. getExtension() can probably be rewritten as extension

UnnecessaryGetter346

[SRC]name[++dotIndex..-1] + ".${getExtension()}"

[MSG]Violation in class org.gradle.plugins.signing.type.AbstractSignatureType. getExtension() can probably be rewritten as extension

Package: src.org.gradle.profile

➥ HTMLProfileReport.groovy

Rule NamePriorityLine #Source Line / Message
StaticSimpleDateFormatField225

[SRC]private static final SimpleDateFormat DATE_FORMAT = new .. HH:mm:ss");

[MSG]Violation in class org.gradle.profile.HTMLProfileReport. SimpleDateFormat instances are not thread safe. Wrap the SimpleDateFormat field DATE_FORMAT in a ThreadLocal or make it an instance field

Package: src.org.gradle.util

➥ ReflectionUtil.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass349

[SRC]return Boolean.class;

[MSG]Boolean.class can be rewritten as Boolean

UnnecessaryDotClass351

[SRC]return Long.class;

[MSG]Long.class can be rewritten as Long

UnnecessaryDotClass353

[SRC]return Integer.class;

[MSG]Integer.class can be rewritten as Integer

UnnecessaryDotClass355

[SRC]return Short.class;

[MSG]Short.class can be rewritten as Short

UnnecessaryDotClass357

[SRC]return Byte.class;

[MSG]Byte.class can be rewritten as Byte

UnnecessaryDotClass359

[SRC]return Float.class;

[MSG]Float.class can be rewritten as Float

UnnecessaryDotClass361

[SRC]return Double.class;

[MSG]Double.class can be rewritten as Double

➥ Requires.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass327

[SRC]@ExtensionAnnotation(TestPreconditionExtension.class)

[MSG]TestPreconditionExtension.class can be rewritten as TestPreconditionExtension

➥ TestDirHelper.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInFieldDeclaration319

[SRC]def TestFile baseDir

[MSG]Violation in class org.gradle.util.TestDirHelper. The def keyword is unneeded when a field type is specified

UnnecessaryDefInMethodDeclaration321

[SRC]def TestDirHelper(TestFile baseDir) {

[MSG]Violation in class org.gradle.util.TestDirHelper. The def keyword is unneeded on constructors

➥ TestFileHelper.groovy

Rule NamePriorityLine #Source Line / Message
AssignmentInConditional240

[SRC]while (entry = zipStr.getNextEntry()) {

[MSG]Assignment used as conditional value, which always results in true. Use the == operator instead

MisorderedStaticImports322

[SRC]import static org.hamcrest.Matchers.equalTo

[MSG]Static imports should appear before normal imports

MisorderedStaticImports323

[SRC]import static org.junit.Assert.assertThat

[MSG]Static imports should appear before normal imports

MisorderedStaticImports324

[SRC]import static org.junit.Assert.assertTrue

[MSG]Static imports should appear before normal imports

UnnecessaryGetter340

[SRC]while (entry = zipStr.getNextEntry()) {

[MSG]Violation in class org.gradle.util.TestFileHelper. getNextEntry() can probably be rewritten as nextEntry

UnnecessarySubstring3110

[SRC]return perms.substring(1, 10)

[MSG]Violation in class org.gradle.util.TestFileHelper. The String.substring(int, int) method can be replaced with the subscript operator

➥ TestPreconditionExtension.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure325

[SRC]spec.skipped = annotation.value().any() { !it.fulfilled }

[MSG]Violation in class org.gradle.util.TestPreconditionExtension. Parentheses in the 'any' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure330

[SRC]feature.skipped = annotation.value().any() { !it.fulfilled }

[MSG]Violation in class org.gradle.util.TestPreconditionExtension. Parentheses in the 'any' method call are unnecessary and can be removed.

Rule Descriptions

#Rule NameDescription
1AddEmptyStringFinds empty string literals which are being added. This is an inefficient way to convert any type to a String.
2AssertWithinFinallyBlockChecks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one.
3AssignmentInConditionalAn assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended.
4BigDecimalInstantiationChecks for calls to the BigDecimal constructors that take a double parameter, which may result in an unexpected BigDecimal value.
5BitwiseOperatorInConditionalChecks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable.
6BooleanGetBooleanThis rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop'].
7BrokenNullCheckLooks for faulty checks for null that can cause a NullPointerException.
8BrokenOddnessCheckThe code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.
9BusyWaitBusy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package.
10ChainedTestA test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another.
11ClassForNameUsing Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time.
12ComparisonOfTwoConstantsChecks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values., e.g.: 23 == 67, Boolean.FALSE != false, 0.17 <= 0.99, "abc" > "ddd", [a:1] <=> [a:2], [1,2].equals([3,4]) or [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE].
13ComparisonWithSelfChecks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x =>= x, x.equals(x) or x.compareTo(x), where x is a variable.
14ConsecutiveLiteralAppendsViolations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation.
15ConsecutiveStringConcatenationCatches concatenation of two string literals on the same line. These can safely by joined.
16ConstantAssertExpressionChecks for assert statements where the assert boolean condition expression is a constant or literal value.
17ConstantIfExpressionChecks for if statements with a constant value for the if expression, such as true, false, null, or a literal constant value.
18ConstantTernaryExpressionChecks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value.
19CoupledTestCaseThis rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused.
20CyclomaticComplexityChecks the cyclomatic complexity for methods/classes.A method (or "closure field") with a cyclomatic complexity value greater than the maxMethodComplexity property (20) causes a violation. Likewise, a class that has an (average method) cyclomatic complexityvalue greater than the maxClassAverageMethodComplexity property (20) causes a violation.
21DeadCodeDead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted.
22DoubleCheckedLockingThis rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern.
23DoubleNegativeThere is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well.
24DuplicateCaseStatementCheck for duplicate case statements in a switch block, such as two equal integers or strings.
25DuplicateImportDuplicate import statements are unnecessary.
26DuplicateMapKeyA map literal is created with duplicated key. The map entry will be overwritten.
27DuplicateSetValueA Set literal is created with duplicate constant value. A set cannot contain two elements with the same value.
28EmptyCatchBlockIn most cases, exceptions should not be caught and ignored (swallowed).
29EmptyElseBlockEmpty else blocks are confusing and serve no purpose.
30EmptyFinallyBlockEmpty finally blocks are confusing and serve no purpose.
31EmptyForStatementEmpty for statements are confusing and serve no purpose.
32EmptyIfStatementEmpty if statements are confusing and serve no purpose.
33EmptyInstanceInitializerAn empty class instance initializer was found. It is safe to remove it.
34EmptyMethodA method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation.
35EmptyStaticInitializerAn empty static initializer was found. It is safe to remove it.
36EmptySwitchStatementEmpty switch statements are confusing and serve no purpose.
37EmptySynchronizedStatementEmpty synchronized statements are confusing and serve no purpose.
38EmptyTryBlockEmpty try blocks are confusing and serve no purpose.
39EmptyWhileStatementEmpty while statements are confusing and serve no purpose.
40EqualsAndHashCodeIf either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden.
41EqualsOverloadedThe class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it.
42ExplicitGarbageCollectionCalls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself.
43ForLoopShouldBeWhileLoopA for loop without an init and update statement can be simplified to a while loop.
44HardCodedWindowsFileSeparatorThis rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant.
45HardCodedWindowsRootDirectoryThis rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative.
46ImportFromSamePackageAn import of a class that is within the same package is unnecessary.
47ImportFromSunPackagesAvoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.
48InconsistentPropertyLockingClass contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all.
49InconsistentPropertySynchronizationClass contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not.
50IntegerGetIntegerThis rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop'].
51JUnitAssertAlwaysFailsChecks for JUnit assert() method calls with constant arguments such that the assertion always fails. This includes: assertTrue(false), assertFalse(true) and assertNull(CONSTANT).
52JUnitAssertAlwaysSucceedsChecks for JUnit assert() method calls with constant arguments such that the assertion always succeeds. This includes: assertTrue(true), assertFalse(false) and assertNull(null).
53JUnitFailWithoutMessageThis rule detects JUnit calling the fail() method without an argument. For better error reporting you should always provide a message.
54JUnitPublicNonTestMethodChecks if a JUnit test class contains public methods other than standard test methods, JUnit framework methods or methods with JUnit annotations.
55JUnitSetUpCallsSuperChecks that if the JUnit setUp() method is defined, that it includes a call to super.setUp().
56JUnitTearDownCallsSuperChecks that if the JUnit tearDown() method is defined, that it includes a call to super.tearDown().
57JUnitTestMethodWithoutAssertThis rule searches for test methods that do not contain assert statements. Either the test method is missing assert statements, which is an error, or the test method contains custom assert statements that do not follow a proper assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test annotation. By default this rule applies to the default test class names, but this can be changed using the rule's applyToClassNames property.
58JUnitUnnecessarySetUpChecks for JUnit setUp() methods that contain only a call to super.setUp().
59JUnitUnnecessaryTearDownChecks for JUnit tearDown() methods that contain only a call to super.tearDown().
60MisorderedStaticImportsStatic imports should never be declared after nonstatic imports.
61NestedSynchronizationNested synchronized statements should be avoided. Nested synchronized statements are either useless (if the lock objects are identical) or prone to deadlock.
62RandomDoubleCoercedToZeroThe Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug.
63RemoveAllOnSelfDon't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException.
64ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
65SpockIgnoreRestUsedIf Spock's @IgnoreRest appears on any method, all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed.
66StaticCalendarFieldCalendar objects should not be used as static fields. Calendars are inherently unsafe for multihtreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
67StaticConnectionCreates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions.
68StaticDateFormatFieldDateFormat objects should not be used as static fields. DateFormat are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
69StaticMatcherFieldMatcher objects should not be used as static fields. Matcher instances are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
70StaticSimpleDateFormatFieldSimpleDateFormat objects should not be used as static fields. SimpleDateFormat are inherently unsafe for multi-threaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
71SynchronizedMethodThis rule reports uses of the synchronized keyword on methods. Synchronized methods are the same as synchronizing on 'this', which effectively make your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.
72SynchronizedOnBoxedPrimitiveThe code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock
73SynchronizedOnGetClassSynchronization on getClass rather than class literal. This instance method synchronizes on this.getClass(). If this class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended.
74SynchronizedOnReentrantLockSynchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method.
75SynchronizedOnStringSynchronization on a String field can lead to deadlock because Strings are interned by the JVM and can be shared.
76SynchronizedOnThisThis rule reports uses of the synchronized blocks where the synchronization reference is 'this'. Doing this effectively makes your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.
77SynchronizedReadObjectMethodCatches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style.
78SystemRunFinalizersOnExitMethod calls to System.runFinalizersOnExit() should not be allowed. This method is inherently non-thread-safe, may result in data corruption, deadlock, and may effect parts of the program far removed from it's call point. It is deprecated, and it's use strongly discouraged.
79ThreadGroupAvoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe.
80ThreadLocalNotStaticFinalThreadLocal fields should be static and final. In the most common case a java.lang.ThreadLocal instance associates state with a thread. A non-static non-final java.lang.ThreadLocal field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior.
81ThreadYieldMethod calls to Thread.yield() should not be allowed. This method has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions.
82ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
83UnnecessaryBigDecimalInstantiationIt is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G.
84UnnecessaryBigIntegerInstantiationIt is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G.
85UnnecessaryBooleanExpressionChecks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or a Map/List/String/Number literal. Also checks for negation (!) of true, false, null, or a Map/List/String/Number literal.
86UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
87UnnecessaryCallForLastElementThis rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a get, getAt, or array-style access is used with an object size check.
88UnnecessaryCallToSubstringCalling String.substring(0) always returns the original string. This code is meaningless.
89UnnecessaryCatchBlockViolations are triggered when a catch block does nothing but throw the original exception. In this scenario there is usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out.
90UnnecessaryCollectCallSome method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect { it.multiply(2) } can be replaced by list*.multiply(2).
91UnnecessaryCollectionCallUseless call to collections. This call doesn't make sense. For any collection c, calling c.containsAll(c) should always be true, and c.retainAll(c) should have no effect.
92UnnecessaryConstructorThis rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments.
93UnnecessaryDefInFieldDeclarationIf a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}.
94UnnecessaryDefInMethodDeclarationIf a method has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'.
95UnnecessaryDefInVariableDeclarationIf a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'.
96UnnecessaryDotClassTo make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String.
97UnnecessaryDoubleInstantiationIt is unnecessary to instantiate Double objects. Instead just use the double literal or the 'D' identifier to force the type, such as 123.45d or 0.42d.
98UnnecessaryElseStatementWhen an if statement block ends with a return statement the else is unnecessary. The logic in the else branch can be run without being in a new scope.
99UnnecessaryFailIn a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all.
100UnnecessaryFinalOnPrivateMethodA private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary.
101UnnecessaryFloatInstantiationIt is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f.
102UnnecessaryGetterChecks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). Getters do not take method arguments.
103UnnecessaryGroovyImportA Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger.
104UnnecessaryIfStatementChecks for if statements where the if and else blocks are merely returning true and false constants. These cases can be replaced by a simple return statement.
105UnnecessaryInstanceOfCheckThis rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean.
106UnnecessaryInstantiationToGetClassAvoid instantiating an object just to call getClass() on it; use the .class public member instead.
107UnnecessaryIntegerInstantiationIt is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i.
108UnnecessaryLongInstantiationIt is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L.
109UnnecessaryModOneAny expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2).
110UnnecessaryNullCheckGroovy contains the safe dereference operator, which can be used in boolean conditional statements to safely replace explicit "x == null" tests.
111UnnecessaryNullCheckBeforeInstanceOfThere is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.
112UnnecessaryObjectReferencesViolations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block.
113UnnecessaryOverridingMethodThe overriding method merely calls the same method defined in a superclass
114UnnecessaryPackageReferenceChecks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, java.util.Map and groovy.lang.Closure.
115UnnecessaryParenthesesForMethodCallWithClosureIf a method is called and the only parameter to that method is an inline closure then the parentheses of the method call can be omitted.
116UnnecessarySelfAssignmentMethod contains a pointless self-assignment to a variable or property.
117UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
118UnnecessarySubstringThis rule finds usages of String.substring(int) and String.substring(int, int) that can be replaced by use of the subscript operator. For instance, var.substring(5) can be replaced with var[5..-1].
119UnnecessaryTernaryExpressionChecks for ternary expressions where the conditional expression always evaluates to a boolean and the true and false expressions are merely returning true and false constants. Also checks for ternary expressions where both expressions are the same constant or variable.
120UnnecessaryTransientModifierThe field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect.
121UnusedArrayChecks for array allocations that are not assigned or used, unless it is the last statement within a block.
122UnusedImportImports for a class that is never referenced within the source file is unnecessary.
123UnusedMethodParameterThis rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override.
124UnusedObjectChecks for object allocations that are not assigned or used, unless it is the last statement within a block
125UnusedPrivateFieldChecks for private fields that are not referenced within the same class.
126UnusedPrivateMethodChecks for private methods that are not referenced within the same class.
127UnusedPrivateMethodParameterChecks for parameters to private methods that are not referenced within the method body.
128UnusedVariableChecks for variables that are never referenced.
129UseAssertEqualsInsteadOfAssertTrueThis rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.
130UseAssertFalseInsteadOfNegationIn unit tests, if a condition is expected to be false then there is no sense using assertTrue with the negation operator. For instance, assertTrue(!condition) can always be simplified to assertFalse(condition)
131UseAssertNullInsteadOfAssertEqualsThis rule detects JUnit calling assertEquals where the first or second parameter is null. These assertion should be made against the assertNull method instead.
132UseAssertSameInsteadOfAssertTrueThis rule detects JUnit calling assertTrue where the first or second parameter is an Object#is() call testing for reference equality. These assertion should be made against the assertSame method instead.
133UseAssertTrueInsteadOfAssertEqualsThis rule detects JUnit calling assertEquals where the first parameter is a boolean. These assertions should be made by more specific methods, like assertTrue or assertFalse.
134UseAssertTrueInsteadOfNegationIn unit tests, if a condition is expected to be true then there is no sense using assertFalse with the negation operator. For instance, assertFalse(!condition) can always be simplified to assertTrue(condition)
135UseOfNotifyMethodThis code calls notify() rather than notifyAll(). Java monitors are often used for multiple conditions. Calling notify() only wakes up one thread, meaning that the thread woken up might not be the one waiting for the condition that the caller just satisfied.
136VolatileArrayFieldVolatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not.
137VolatileLongOrDoubleFieldLong or double fields should not be declared as volatile. Java specifies that reads and writes from such fields are atomic, but many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronize access to such fields rather than declare them volatile. This rule flags fields marked volatile when their type is double or long or the name of their type is "Double" or "Long".
138WaitOutsideOfWhileLoopCalls to Object.wait() must be within a while loop. Consider using the Java concurrency utilities instead of wait() and notify().
CodeNarc-0.23/docs/license.html0000644000175000017500000005631512471222422015714 0ustar ebourgebourg CodeNarc - Project License

Overview

Typically the licenses listed for the project are that of the project itself, and not of dependencies.

Project License

Apache 2

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   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.

CodeNarc-0.23/docs/codenarc-rules-formatting.html0000644000175000017500000010544212471222412021343 0ustar ebourgebourg CodeNarc - CodeNarc - Formatting Rules

Formatting Rules ("rulesets/formatting.xml")

BlankLineBeforePackage Rule

Since CodeNarc 0.21

Makes sure there are no blank lines before the package declaration of a source code file.

BracesForClass Rule

Since CodeNarc 0.15

Checks the location of the opening brace ({) for classes. By default, requires them on the same line, but the sameLine property can be set to false to override this.

NOTE: This rule ignores annotation types, e.g. @interface MyAnnotation .

BracesForForLoop Rule

Since CodeNarc 0.15

Checks the location of the opening brace ({) for for loops. By default, requires them on the same line, but the sameLine property can be set to false to override this.

BracesForIfElse Rule

Since CodeNarc 0.15

Checks the location of the opening brace ({) for if statements. By default, requires them on the same line, but the sameLine property can be set to false to override this.

BracesForMethod Rule

Since CodeNarc 0.15

Checks the location of the opening brace ({) for constructors and methods. By default, requires them on the same line, but the sameLine property can be set to false to override this.

BracesForTryCatchFinally Rule

Since CodeNarc 0.15

Checks the location of the opening brace ({) for try statements. By default, requires them on the line, but the sameLine property can be set to false to override this.

ClassJavadoc Rule

Since CodeNarc 0.15

Makes sure each class and interface definition is preceded by javadoc. Enum definitions are not checked, due to strange behavior in the Groovy AST. By default, only the main class in a file is checked for Javadoc. The main class is defined as the class that has the same name as the source file, for instance MyClass is the main class in MyClass.groovy but the class MyOtherClass defined in the same source file is not the main class. To check all the classes in the file set the rule property applyToNonMainClasses to true.

ClosureStatementOnOpeningLineOfMultipleLineClosure Rule

Since CodeNarc 0.20

Checks for closure logic on first line (after ->) for a multi-line closure. That breaks the symmetry of indentation (if the subsequent statements are indented normally), and that first statement can be easily missed when reading the code.

Example of violations:

    def closure = { name -> println name
        addToCounts()
        println “done” }

ConsecutiveBlankLines Rule

Since CodeNarc 0.21

Makes sure there are no consecutive lines that are either blank or whitespace only. This reduces the need to scroll further than necessary when reading code, and increases the likelihood that a logical block of code will fit on one screen for easier comprehension.

Example of violation:

    def name


    def value



    def id

FileEndsWithoutNewline Rule

Since CodeNarc 0.21

Makes sure each source file ends with a newline character.

LineLength Rule

Since CodeNarc 0.15

Checks the maximum length for each line of source code. It checks for number of characters, so lines that include tabs may appear longer than the allowed number when viewing the file. The maximum line length can be configured by setting the length property, which defaults to 120.

NOTE: This rule does not support the @SuppressAnnotations annotation or the classname-based rule properties (applyToClassNames, doNotApplyToClassNames) to enable/disable the rule. If you want to specify or restrict where this rule is applied, you must use the file-based rule properties: applyToFileNames, doNotApplyToFileNames, applyToFilesMatching and doNotApplyToFilesMatching.

MissingBlankLineAfterImports Rule

Since CodeNarc 0.21

Makes sure there is a blank line after the imports of a source code file.

Example of violation:

    import org.apache.commons.lang.StringUtils
    class MyClass { }                       // violation

MissingBlankLineAfterPackage Rule

Since CodeNarc 0.21

Makes sure there is a blank line after the package statement of a source code file.

Example of violation:

  package org.codenarc
  import java.util.Date                     // violation

  class MyClass {
      void go() { /* ... */ }
  }

SpaceAfterCatch Rule

Since CodeNarc 0.18

Check that there is exactly one space (blank) after the catch keyword and before the opening parenthesis.

Examples of violations:

    try { } catch(Exception e) { }          // violation
    try { } catch  (Exception e) { }        // violation

SpaceAfterComma Rule

Since CodeNarc 0.18

Checks that there is at least one space or whitespace following each comma. That includes checks for method and closure declaration parameter lists, method call parameter lists, Map literals and List literals.

Known limitations:

  • May not catch actual violations if the source line contains unicode character literals, e.g. '\u00A0'

Examples of violations:

    def value = calculate(1,399, 'abc')         // violation on parameter 399

    def method1(int a,String b) { }             // violation on parameter b

    def closure1 = { int a,String b -> }        // violation on parameter b

    def list1 = [a,b, c]                        // violation on list element b

    def map1 = [a:1,b:2, c:3]                   // violation on map element b:2

SpaceAfterClosingBrace Rule

Since CodeNarc 0.18

Check that there is at least one space (blank) or whitespace after each closing brace ("{") for method/class/interface declarations, closure expressions and block statements.

A closure expression followed by a dot operator (.), a comma, a closing parenthesis, the spread-dot operator (*.), a semicolon or the null-safe operator (?.) does not cause a violation.

Property Description Default Value
checkClosureMapEntryValue If false, then do not check for whitespace after closing braces for closure expressions that are literal Map values, e.g. [abc:doStuff()]. true

Known limitations:

  • May not catch actual violations if the source line contains unicode character literals, e.g. '\u00A0'

Examples of violations and exceptions:

    if (ready) { return 9 }else { }             // violation
    try { doStuff() }finally { }                // violation

    def matching = list.find { it.isReady() }.filter()  // no violation for dot operator
    assert list.every { it.isReady() }, "Error"         // no violation for comma
    def m = [a:123, b:{ println 7 },c:99]               // no violation for comma
    processItems(list.select { it.isReady() })          // no violation for closing parenthesis
    def names = records.findAll { it.age > 1 }*.name    // no violation for spread operator
    list?.collect { it?.type }?.join(',')               // no violation for null-safe operator

SpaceAfterFor Rule

Since CodeNarc 0.18

Check that there is exactly one space (blank) after the for keyword and before the opening parenthesis.

Examples of violations:

    for(name in names) { }                  // violation
    for  (int i=0; i < 10; i++) { }         // violation

SpaceAfterIf Rule

Since CodeNarc 0.18

Check that there is exactly one space (blank) after the if keyword and before the opening parenthesis.

Examples of violations:

    if(true) { }                            // violation
    if  (true) { }                          // violation

SpaceAfterOpeningBrace Rule

Since CodeNarc 0.18

Check that there is at least one space (blank) or whitespace after each opening brace ("{") for method/class/interface declarations, closure expressions and block statements.

Property Description Default Value
checkClosureMapEntryValue If false, then do not check for whitespace after opening braces for closure expressions that are literal Map values, e.g. [abc:doStuff()]. true
ignoreEmptyBlock If true, then allow for [] in code false

Examples of violations:

    class MyClass{int count }                   // violation

    interface MyInterface {static final OK = 1 }// violation

    enum MyEnum {OK, BAD }                      // violation

    def myMethod() {int count }                 // violation

    if (ready) {println 9 }                     // violation

    if (ready) {
    } else {println 99}                         // violation

    for (int i=0; i<10; i++) {println i }       // violation

    for (String name in names) {println name }  // violation

    for (String name: names) {println name }    // violation

    while (ready) {println time }               // violation

    try {doStuff()                              // violation
    } catch(Exception e) {x=77 }                // violation
    } finally {println 'error' }                // violation

    list.each {name -> }                        // violation

    shouldFail(Exception) {doStuff() }          // violation

SpaceAfterSemicolon Rule

Since CodeNarc 0.18

Check that there is at least one space (blank) or whitespace following a semicolon that separates:

  • multiple statements on a single line
  • the clauses within a classic for loop, e.g. for (i=0;i<10;i++)

Examples of violations:

    def myMethod() {
        println 1;println 2                         // violation
        def closure = { x -> doStuff();x = 23; }    // violation

        for (int i=0;i < 10;i++) {                  // violations (2)
            for (int j=0; j < 10;j++) { }           // violation
        }
    }

SpaceAfterSwitch Rule

Since CodeNarc 0.18

Check that there is exactly one space (blank) after the switch keyword and before the opening parenthesis.

Examples of violations:

    switch(x) {                                 // violation
        case 1: println 'one'
    }
    switch  (x) {                               // violation
        case 1: println 'one'
    }

SpaceAfterWhile Rule

Since CodeNarc 0.18

Check that there is exactly one space (blank) after the while keyword and before the opening parenthesis.

Examples of violations:

    while(true) { }             // violation
    while  (true) { }           // violation

SpaceAroundClosureArrow Rule

Since CodeNarc 0.19

Checks that there is at least one space (blank) or whitespace around each closure arrow (->) symbol.

Known limitations:

  • Does not catch violations if the closure arrow (->) is on a separate line from the start of the closure.

Example of violations:

    def closure1 = {->}                             // violation
    def closure2 = { ->}                            // violation
    def closure3 = {-> }                            // violation
    def closure4 = { count-> println 123 }          // violation
    def closure5 = { count, name ->println 123 }    // violation

SpaceAroundMapEntryColon Rule

Since CodeNarc 0.20

Check for proper formatting of whitespace around colons for literal Map entries. By default, no whitespace is allowed either before or after the Map entry colon, but you can change that through the configuration properties below.

Property Description Default Value
characterBeforeColonRegex The regular expression that must match the character before the colon (:) for a literal Map entry. For example, /\S/ matches any non-whitespace character and /\s/ matches any whitespace character (thus requiring a space or whitespace). /\S/ (i.e., no space allowed before the colon)
characterAfterColonRegex The regular expression that must match the character after the colon (:) for a literal Map entry. For example, /\S/ matches any non-whitespace character and /\s/ matches any whitespace character (thus requiring a space or whitespace). /\S/ (i.e., no space allowed before the colon)

Example of violations:

    Map m1 = [myKey : 12345]            // violation (both before and after the colon)
    println [a :[1:11, 2:22],           // violation on a (before colon)
                b:[(Integer): 33]]      // violation on Integer (after colon)

SpaceAroundOperator Rule

Since CodeNarc 0.18

Check that there is at least one space (blank) or whitespace around each binary operator, including: +, -, *, /, >>, <<, &&, ||, &, |, ?:, =, "as".

Do not check dot ('.') operator. Do not check unary operators (!, +, -, ++, --, ?.). Do not check array ('[') operator.

Known limitations:

  • Does not catch violations of missing space around equals operator (=) within a declaration expression, e.g. def x=23
  • Does not catch violations of certain ternary expressions and standalone elvis operator (?:) expressions

Examples of violations:

    def myMethod() {
        3+ 5-x*23/ 100              // violation
        list \<\<123                // violation
        other\>\> writer            // violation
        x=99                        // violation
        x&& y                       // violation
        x ||y                       // violation
        x &y                        // violation
        x| y                        // violation
        [1,2]as String              // violation
    }

SpaceBeforeClosingBrace Rule

Since CodeNarc 0.18

Check that there is at least one space (blank) or whitespace before each closing brace ("}") for method/class/interface declarations, closure expressions and block statements.

Property Description Default Value
checkClosureMapEntryValue If false, then do not check for whitespace before closing braces for closure expressions that are literal Map values, e.g. [abc:doStuff()]. true
ignoreEmptyBlock If true, then allow for [] in code false

Known limitations:

  • May not catch actual violations if the source line contains unicode character literals, e.g. '\u00A0'

Examples of violations:

    class MyClass { int count}                  // violation

    interface MyInterface { void doStuff()}     // violation

    enum MyEnum { OK, BAD}                      // violation

    def myMethod() { return 9}                  // violation

    if (ready) { doStuff()}                     // violation

    if (ready) {
    } else { return 9}                          // violation

    for (int i=0; i<10; i++) { println i}       // violation

    for (String name in names) { println name}  // violation

    for (String name: names) { println name}    // violation

    while (ready) { doStuff()}                  // violation

    try { doStuff()}                            // violation
    catch(Exception e) { logError(e)}           // violation
    finally { cleanUp()}                        // violation

    list.each { name -> println name}           // violation

    shouldFail(Exception) { doStuff()}          // violation

SpaceBeforeOpeningBrace Rule

Since CodeNarc 0.18

Check that there is at least one space (blank) or whitespace before each opening brace ("{") for method/class/interface declarations, closure expressions and block statements.

Property Description Default Value
checkClosureMapEntryValue If false, then do not check for whitespace before opening braces for closure expressions that are literal Map values, e.g. [abc:doStuff()]. true

Known limitations:

  • May not catch actual violations if the source line contains unicode character literals, e.g. '\u00A0'

Examples of violations:

    class MyClass{ }                            // violation
    class MyOtherClass extends AbstractClass{ } // violation

    interface MyInterface{ }                    // violation

    enum MyEnum{ OK, BAD }                      // violation

    def myMethod(){ }                           // violation

    if (ready){ }                               // violation

    if (ready) {
    } else{}                                    // violation

    for (int i=0; i<10; i++){ }                 // violation

    for (String name in names){ }               // violation

    for (String name: names){ }                 // violation

    while (ready){ }                            // violation

    try{
    } finally { }                               // violation

    try {
    } catch(Exception e){ }                     // violation

    try {
    } finally{ }                                // violation

    list.each{ name -> }                        // violation

    shouldFail(Exception){ doStuff() }          // violation

TrailingWhitespace Rule

Since CodeNarc 0.21

Checks that no lines of source code end with whitespace characters.


CodeNarc-0.23/docs/codenarc-creating-ruleset.html0000644000175000017500000007253612471222401021323 0ustar ebourgebourg CodeNarc - CodeNarc - Creating a RuleSet

CodeNarc - Creating a RuleSet

Contents

New and Improved Way To Configure a RuleSet

NEW! The preferred way to configure the rules that CodeNarc will use is to create a custom RuleSet specifying the rule names (i.e., without depending on the RuleSet files provided with CodeNarc. This allows finer control over your custom RuleSet and insulates you from the provided RuleSets that can (and often do) change from release to release.

Just Copy and Tweak One of the Starter RuleSet Files

See the Starter RuleSet - All Rules By Category. It contains all of the rules provided with the current version of CodeNarc, organized by category. Just delete or comment out the rules you don't want to use.

Alternatively, there is a Starter RuleSet - All Rules. It contains all of the rules provided with the current version of CodeNarc, in alphabetical order. Just delete or comment out the rules you don't want to use.

The Other RuleSet Options Still Work

You can still create your own custom Groovy RuleSet using the older syntax. You can even mix the new rule-name-only syntax with the older Groovy DSL syntax. It's all good!

You can also continue to use the predefined RuleSets distributed with CodeNarc or you can create your own XML RuleSet. See the site navigation menu for a list of the RuleSets provided out of the box by CodeNarc.

Creating a Groovy RuleSet File

CodeNarc provides a Groovy DSL (domain-specific language) for defining RuleSets.

The preferred syntax for defining a RuleSet is to specify the list of rules using only the rule names. As mentioned above, this allows finer control over your custom RuleSet and insulates you from the provided RuleSets that can (and often do) change from release to release.

A Sample Groovy RuleSet

Here is an example of a Groovy RuleSet file using the preferred syntax:

ruleset {
    description 'A custom Groovy RuleSet'

    CyclomaticComplexity {
        maxMethodComplexity = 1
    }

    ClassName

    MethodName

    ConfusingTernary(priority:3)

    StatelessClass {
        name = 'StatelessDao'
        applyToClassNames = '*Dao'
    }
}

Things to note:

  • The Groovy RuleSet file itself must be accessible on the classpath.
  • Each rule is specified by its rule name.
  • The StatelessClass rule redefines the name for that rule instance. You can have multiple instances of the same rule class as long as they have unique rule names.
  • You can optionally configure a rule instance by specifying rule properties in a Map after the rule name (see ConfusingTernary in the example). Or you can specify rule properties in a Closure after the rule name (see CyclomaticComplexity and StatelessClass in the example).
  • The easiest way to create a new custom RuleSet is to copy the Starter RuleSet (as a .groovy file). It contains all of the rules provided with the current version of CodeNarc, organized by category. Just delete or comment out the rules you don't want to use.

And here is an example that mixes both the preferred (new) syntax along with the older syntax, to illustrate backward-compatibility:

ruleset {
    MethodName

    ConfusingTernary(priority:3)

    StatelessClass {
        name = 'StatelessDao'
        applyToClassNames = '*Dao'
    }

    // Old style
    rule(org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule) {
        priority = 3
    }

    // Old style
    ruleset('rulesets/dry.xml')
}

A Sample Groovy RuleSet Using the Old Syntax

Here is an example of a Groovy RuleSet file using the older syntax:

import org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule

ruleset {

    description 'A sample Groovy RuleSet'

    ruleset('rulesets/basic.xml') {
        'CatchThrowable' {
            priority = 1
            enabled = false
        }
        'EqualsAndHashCode' priority:3
        exclude 'Empty*'
    }

    rule(ThrowExceptionFromFinallyBlockRule) {
        priority = 3
    }

    rule("rules/MyCustomRuleScript.groovy")

    ruleset('MyGroovyRuleSet.groovy')
}

Things to note:

  • The Groovy RuleSet file itself must be accessible on the classpath.
  • The "outer" ruleset defines the contents of the RuleSet (within a closure). It can include an optional description and any combination of ruleset (other RuleSets) and rule statements (individual Rules).

About the "inner" ruleset statements:

  • Each ruleset statement loads a RuleSet file. The path specifies either a Groovy file or an XML file. By default, the paths specified are relative to the classpath. But these paths may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem), or "http:".
  • The 'rulesets/basic.xml' RuleSet file is interpreted as an XML file based on the '.xml' extension. Likewise, the 'MyGroovyRuleSet.groovy' file is interpreted as a Groovy RuleSet file.
  • The RuleSet can be customized by following the RuleSet path with an (optional) closure, containing any combination of the following:
    1. Rule Configurations -- A ruleset statement can optionally provide configuration of the properties for individual rules within the RuleSet. Specify the name of the rule (as a String), followed by its configuration. (Remember to specify the rule name, not the class name. In most cases, the rule name is the class name without the "Rule" suffix). The name of the Rule can be followed by:
      1. A Map of property names and values. See 'EqualsAndHashCode' within the example.
      2. A closure containing property assignments statements. See 'CatchThrowable' within the example.

      Properties set this way can be of type String, int, long or boolean.

    2. Rule Filtering (include or exclude statements) -- A ruleset statement can optionally specify include and/or exclude pattern(s) of rule names to include or exclude from the RuleSet. See Filtering Rules Within a RuleSet.

About the rule statements:

  • Each rule statements loads a single Rule.
  • The rule statement must specify either:
    1. The class name for a Rule. See ThrowExceptionFromFinallyBlockRule within the example. The Rule class must be available on the classpath.
    2. The path to a Rule Script file. See "MyGroovyRuleSet.groovy" within the example. By default, the paths specified are relative to the classpath. But these paths may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem) or "http:".
  • A rule can optionally provide configuration of the Rule properties by specifying a closure containing property assignment statements. See ThrowExceptionFromFinallyBlockRule within the example. As within ruleset statements, properties set this way can be of type String, int, long or boolean.

Creating an XML RuleSet File

The XML schema for a CodeNarc RuleSet file is embodied in the "ruleset-schema.xsd" file which is included within the CodeNarc jar. It contains three sections, all of which are optional, though the sections must be in the order listed:

XML Tag Purpose How many are allowed
<description> Describe the purpose of the RuleSet Zero or one
<ruleset-ref> Include a nested RuleSet, optionally configuring and/or filtering the rules within it. The path to the RuleSet can specify either an XML file or a Groovy RuleSet file. Zero or more
<rule> Include a single rule; specify its fully-qualified classname Zero or more
<rule-script> Include a single rule implemented by a groovy script; specify the path of the script. The path is relative to the classpath by default, but can optionally specify a URL prefix. Zero or more

A Sample XML RuleSet

Here is an example XML RuleSet file:

<ruleset xmlns="http://codenarc.org/ruleset/1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd"
        xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd">

    <description>Sample rule set</description>

    <ruleset-ref path='rulesets/imports.xml'>
        <rule-config name='DuplicateImport'>
            <property name='priority' value='1'/>
        </rule-config>
    </ruleset-ref>

    <ruleset-ref path='rulesets/basic.xml'>
        <exclude name='StringInstantiation'/>
    </ruleset-ref>

    <rule class='org.codenarc.rule.generic.IllegalRegexRule'>
        <property name="name" value="AuthorTagNotAllowed"/>
        <property name='regex' value='\@author'/>
    </rule>

    <rule-script path='rules/MyStaticFieldRule.groovy'/>

</ruleset>

Things to note:

  • The RuleSet file itself must be accessible on the classpath.
  • The top-level <ruleset> element must include the namespace declaration shown.

About the <ruleset-ref> elements:

  • By default, The path of the <ruleset-ref> is relative to the classpath. But these paths may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem) or "http:".
  • You can optionally set arbitrary properties for the rules within the RuleSet by including one or more <property> elements within a <rule-config> element. In the example above, the DuplicateImportRule priority property is set to 1. Properties set this way can be of type String, int, long or boolean.
  • Remember that the name for a <rule-config> specifies the rule name, not the class name. (In most cases, the rule name is the class name without the "Rule" suffix.)

About the <rule> elements:

  • You must specify the fully-qualified class name for each Rule.
  • The Rule class must be available on the classpath.
  • You can optionally set arbitrary properties for individual rules by including a <property> element within a <rule>. For the IllegalRegexRule rule above, the name property is set to "AuthorTagNotAllowed" and the regex property is set to "\@author". Properties set this way can be of type String, int, long or boolean.
  • Because the name property is customized for the IllegalRegexRule, the localized rule description will be retrieved from the custom messages resource bundle file ("codenarc-messages.properties"), if that bundle file exists, otherwise a default generic message will be used. The resource bundle message key will be based on the customized name. In this case, the message key will be "AuthorTagNotAllowed.description".

About the <rule-script> elements:

  • You must specify the path for the rule script Groovy file. By default, this path is relative to the classpath. But these paths may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem) or "http:".
  • The class defined within the rule script Groovy file must implement the org.codenarc.rule.Rule interface.
  • You can optionally set arbitrary properties for the rule by including a <property> element within a <rule-script> the same way you can for a <rule>. That is not shown here.

Filtering Rules Within a RuleSet

You can use the <include> and <exclude> elements within a <ruleset-ref> to filter a RuleSet and include and/or the exclude individual rules. In the following RuleSet excerpt, the entire "rulesets/basic.xml" RuleSet is included, except for the BooleanInstantiationRule and StringInstantiationRule.

    ruleset('rulesets/basic.xml') {
        exclude 'BooleanInstantiation'
        exclude 'StringInstantiation'
    }

And here is the same example in XML RuleSet format:

    <ruleset-ref path='rulesets/basic.xml'>
        <exclude name='BooleanInstantiation'/>
        <exclude name='StringInstantiation'/>
    </ruleset-ref>

Alternatively, you may wish to explicitly specify the rules that you want included from a RuleSet rather than those that are excluded. In the following RuleSet excerpt, ONLY the ReturnFromFinallyBlockRule and StringInstantiationRule rules are included from the "rulesets/basic.xml" RuleSet.

    ruleset('rulesets/basic.xml') {
        include 'ReturnFromFinallyBlockRule'
        include 'StringInstantiation'
    }

And here is the same example in XML RuleSet format:

    <ruleset-ref path='rulesets/basic.xml'>
        <include name='ReturnFromFinallyBlockRule'/>
        <include name='StringInstantiation'/>
    </ruleset-ref>

Note: In all cases, the rule name is specified, not the class name. (In most cases, the rule name is the class name without the "Rule" suffix.)

Note: If you specify at least one <include>, then ONLY rules matching an <include> will be included.

Note: If you specify an <include> and an <exclude> for a rule, then the <exclude> takes precedence.

Using Wildcards Within <include> and <exclude> Names

You may optionally include wildcard characters ('*' or '?') in the rule name for both <include> and an <exclude> elements. The wildcard character '*' within the name matches a sequence of zero or more characters in the rule name, while the wildcard character '?' within the name matches exactly one character in the rule name.

In the following RuleSet excerpt, all rules matching '*Instantiation' are included from the "rulesets/basic.xml" RuleSet. In this case, that will include the StringInstantiationRule and BooleanInstantiationRule rules.

    <ruleset-ref path='rulesets/basic.xml'>
        <include name='*Instantiation'/>
    </ruleset-ref>

CodeNarc-0.23/docs/codenarc-rules-naming.html0000644000175000017500000007324112471222416020447 0ustar ebourgebourg CodeNarc - CodeNarc - Naming Rules

Naming Rules ("rulesets/naming.xml")

AbstractClassName Rule

Verifies that the name of an abstract class matches the regular expression specified in the regex property. If that property is null or empty, then this rule is not applied (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. This rule ignores interfaces and is applied only to abstract classes.

Property Description Default Value
regex Specifies the regular expression used to validate the abstract class name. If null or empty, then this rule does nothing. null

ClassName Rule

Verifies that the name of a class matches a regular expression. By default it checks that the class name starts with an uppercase letter and is followed by zero or more word characters (letters, numbers or underscores) or dollar signs ($).

Property Description Default Value
regex Specifies the regular expression used to validate the class name. It is required and cannot be null or empty. /([A-Z] w* $?)*/

ClassNameSameAsFilename Rule

Since CodeNarc 0.19

Reports files containing only one top level class / enum / interface which is named differently than the file.

ConfusingMethodName Rule

Since CodeNarc 0.11

Checks for very confusing method names. The referenced methods have names that differ only by capitalization. This is very confusing because if the capitalization were identical then one of the methods would override the other.

Also, violations are triggered when methods and fields have very similar names.

    class MyClass {
        int total
        int total() {
            1
        }
    }

FactoryMethodName Rule

Since CodeNarc 0.16

A factory method is a method that creates objects, and they are typically named either buildFoo(), makeFoo(), or createFoo(). This rule enforces that only one naming convention is used. It defaults to allowing makeFoo(), but that can be changed using the property regex. The regex is a negative expression; it specifically bans methods named build* or create*. However, methods named build or build* receive some special treatment because of the popular Builder Pattern. If the 'build' method is in a class named *Builder then it does not cause a violation.

Builder methods are slightly different than factory methods.

Property Description Default Value
regex Specifies the default regular expression used to validate the method name. It is required and cannot be null or empty. /(build.*|create.*)/

Example of violations:

    class MyClass {

        // violation. Factory methods should be named make()
        def create() {
        }

        // violation. Factory methods should be named make()
        def createSomething() {
        }

        // violation. Builder method not in class named *Builder
        def build() {
        }

        // violation. Builder method not in class named *Builder
        def buildSomething() {
        }

        // this is OK because it is called make
        def make() {
        }

        // this is also OK
        def makeSomething() {
        }

        // OK, overriding a parent
        @Override
        build() { }

    }

    class WidgetBuilder {

        // OK, the class name ends in Builder
        def build() {
        }
    }

FieldName Rule

Verifies that the name of each field matches a regular expression. By default it checks that fields that are not static final have field names that start with a lowercase letter and contains only letters or numbers. By default, static final field names start with an uppercase letter and contain only uppercase letters, numbers and underscores.

NOTE: This rule checks only regular fields of a class, not properties. In Groovy, properties are fields declared with no access modifier (public, protected, private). Thus, this rule only checks fields that specify an access modifier. For naming of properties, see PropertyNameRule.

Property Description Default Value
regex Specifies the default regular expression used to validate the field name. It is required and cannot be null or empty. /[a-z][a-zA-Z0-9]*/
finalRegex Specifies the regular expression used to validate final field names. It is optional. If not set, then final fields that are non-static are validated using regex. null
staticRegex Specifies the regular expression used to validate static field names. It is optional. If not set, then static fields that are non-final are validated using regex. null
staticFinalRegex Specifies the regular expression used to validate static final field names. It is optional. If not set, then static final fields are validated using finalRegex, staticRegex or regex. /[A-Z][A-Z0-9_]*/
ignoreFieldNames Specifies one or more (comma-separated) field names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). serialVersionUID

The order of precedence for the regular expression properties is: staticFinalRegex, finalRegex, staticRegex and finally regex. In other words, the first regex in that list matching the modifiers for the field is the one that is applied for the field name validation.

InterfaceName Rule

Verifies that the name of an interface matches the regular expression specified in the regex property. If that property is null or empty, then this rule is not applied (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active.

Property Description Default Value
regex Specifies the regular expression used to validate the name of an interface. If null or empty, then this rule does nothing. null

MethodName Rule

Verifies that the name of each method matches a regular expression. By default it checks that the method name starts with a lowercase letter. Implicit method names are ignored (i.e., 'main' and 'run' methods automatically created for Groovy scripts).

Property Description Default Value
regex Specifies the regular expression used to validate the method name. It is required and cannot be null or empty. /[a-z] w*/
ignoreMethodNames Specifies one or more (comma-separated) method names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

ObjectOverrideMisspelledMethodName Rule

Since CodeNarc 0.11

Verifies that the names of the most commonly overridden methods of Object: equals, hashCode and toString, are correct.

Here are some examples of code that produces violations:

    boolean equal(Object o) {}                  // violation
    boolean equal(int other) {}                 // ok; wrong param type
    boolean equal(Object o, int other) {}       // ok; too many params

    boolean equaLS(Object o) {}                 // violation

    int hashcode() {}                           // violation
    int hashCOde() {}                           // violation
    int hashcode(int value) {}                  // ok; not empty params

    String tostring() {}                        // violation
    String toSTring() {}                        // violation
    String tostring(int value) {}               // ok; not empty params

PackageName Rule

Verifies that the package name of a class matches a regular expression. By default it checks that the package name consists of only lowercase letters and numbers, separated by periods.

Property Description Default Value
regex Specifies the regular expression used to validate the package name. It is required and cannot be null or empty. /[a-z]+[a-z0-9]*( .[a-z0-9]+)*/
packageNameRequired Indicates whether a package name declaration is required for all classes. false

PackageNameMatchesFilePath Rule

Since CodeNarc 0.22

A package source file's path should match the package declaration.

Property Description Default Value
groupId Specifies the common group id part of a package name, that will appear within all checked package names. It must also map to the file path for the corresponding source file. For instance, a groupId of "org.sample" means that for all classes that specify a package, that package name must include "org.sample", and the source file must exist under an "org/sample" directory. Then, a MyClass class in a org.sample.util package must be defined in a "MyClass.groovy" file within a "org/sample/util" directory. That directory can be the child of any arbitrary root path, e.g. "src/main/groovy". To find the sub-path relevant for the package the rule searches for the first appearance of groupId in the file path. It's required to configure this. If groupId is null or empty, this rule does nothing. null

ParameterName Rule

Verifies that the name of each parameter matches a regular expression. This rule applies to method parameters, constructor parameters and closure parameters. By default it checks that parameter names start with a lowercase letter and contains only letters or numbers.

Property Description Default Value
regex Specifies the regular expression used to validate the parameter name. It is required and cannot be null or empty. /[a-z][a-zA-Z0-9]*/
ignoreParameterNames Specifies one or more (comma-separated) parameter names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

PropertyName Rule

Verifies that the name of each property matches a regular expression. By default it checks that property names (other than static final) start with a lowercase letter and contains only letters or numbers. By default, static final property names start with an uppercase letter and contain only uppercase letters, numbers and underscores.

NOTE: This rule checks only properties of a class, not regular fields. In Groovy, properties are fields declared with no access modifier (public, protected, private). For naming of regular fields, see FieldNameRule.

Property Description Default Value
regex Specifies the default regular expression used to validate the property name. It is required and cannot be null or empty. /[a-z][a-zA-Z0-9]*/
finalRegex Specifies the regular expression used to validate final property names. It is optional. If not set, then final properties that are non-static are validated using regex. null
staticRegex Specifies the regular expression used to validate static property names. It is optional. If not set, then static properties that are non-final are validated using regex. null
staticFinalRegex Specifies the regular expression used to validate static final property names. It is optional. If not set, then static final property are validated using finalRegex, staticRegex or regex. /[A-Z][A-Z0-9_]*/
ignorePropertyNames Specifies one or more (comma-separated) property names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

The order of precedence for the regular expression properties is: staticFinalRegex, finalRegex, staticRegex and finally regex. In other words, the first regex in that list matching the modifiers for the property is the one that is applied for the field name validation.

VariableName Rule

Verifies that the name of each variable matches a regular expression. By default it checks that non-final variable names start with a lowercase letter and contains only letters or numbers. By default, final variable names start with an uppercase letter and contain only uppercase letters, numbers and underscores.

Property Description Default Value
regex Specifies the default regular expression used to validate the variable name. It is required and cannot be null or empty. /[a-z][a-zA-Z0-9]*/
finalRegex Specifies the regular expression used to validate final variable names. It is optional. If not set, then regex is used to validate final variable names. /[A-Z][A-Z0-9_]*/
ignoreVariableNames Specifies one or more (comma-separated) variable names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

CodeNarc-0.23/docs/pmd.html0000644000175000017500000003244412471222450015050 0ustar ebourgebourg CodeNarc - PMD Results

PMD Results

The following document contains the results of PMD 5.1.2.

Files

org/codenarc/ant/AntFileSetSourceAnalyzer.java

Violation Line
Avoid unused private methods such as 'addToParentResults(DirectoryResults,Results)'. 196

org/codenarc/util/AstUtil.java

Violation Line
Useless parentheses. 160
Avoid unused private methods such as 'extractExpressions(Expression)'. 238
Useless parentheses. 311
Useless parentheses. 551
Useless parentheses. 562
Useless parentheses. 583
Useless parentheses. 583
Useless parentheses. 626
Useless parentheses. 626
Useless parentheses. 873
Useless parentheses. 939

CodeNarc-0.23/docs/project-reports.html0000644000175000017500000003106612471222450017431 0ustar ebourgebourg CodeNarc - Generated Reports

Generated Reports

This document provides an overview of the various reports that are automatically generated by Maven . Each report is briefly described below.

Overview

Document Description
Cobertura Test Coverage Cobertura Test Coverage Report.
JavaDocs JavaDoc API documentation.
CPD Duplicate code detection.
PMD Verification of coding rules.

CodeNarc-0.23/docs/codenarc-TextReportWriter.html0000644000175000017500000003627412471222421021364 0ustar ebourgebourg CodeNarc - CodeNarc TextReportWriter and IdeTextReportWriter

TextReportWriter and IdeTextReportWriter

Description

The org.codenarc.report.TextReportWriter class (type="text") produces a simple text report of the CodeNarc results. See a Sample Report.

The org.codenarc.report.IdeTextReportWriter class (type="ide") also produces a text report of the CodeNarc results, and includes IDE-compatible (Eclipse, Idea) hyperlinks to source code for violations.

Option Nested Elements

The option element is a child of the report element and defines a report-specific option for a report.

The TextReportWriter and IdeTextReportWriter classes supports the following options:

Attribute Description Required
maxPriority The maximum priority level for violations in the report. For instance, setting maxPriority to 2 will result in the report containing only priority 1 and 2 violations (and omitting violations with priority 3). 3
outputFile The path and filename for the output report file. No
title The title for the output report. No
writeToStandardOut Set to "true" or true to write out the report to stdout (System.out) instead of writing to a file. No

Examples

Here is an example Ant XML build file illustrating configuration of org.codenarc.report.TextReportWriter. Note that the report type is specified as "text".

<taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/>
<target name="runCodeNarc">
    <codenarc
            ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml"
            maxPriority1Violations="0">

        <report type="text">
            <option name="outputFile" value="reports/CodeNarcReport.txt" />
            <option name="title" value="My Sample Code" />
        </report>

        <fileset dir="src">
            <include name="**/*.groovy"/>
        </fileset>
    </codenarc>
</target>

Here is an example Ant XML build file illustrating configuration of org.codenarc.report.IdeTextReportWriter. Note that the report type is specified as "ide". The "ide" report type will automatically write the report to stdout.

<taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/>
<target name="runCodeNarc">
    <codenarc
            ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml"
            maxPriority1Violations="0">

        <report type="ide">
            <option name="title" value="My Sample Code" />
        </report>

        <fileset dir="src">
            <include name="**/*.groovy"/>
        </fileset>
    </codenarc>
</target>

CodeNarc-0.23/docs/codenarc-rules-dry.html0000644000175000017500000004376412471222411017776 0ustar ebourgebourg CodeNarc - CodeNarc - DRY Rules

DRY (Don't Repeat Yourself) Rules ("rulesets/dry.xml")

These rules check for duplicate code, enforcing the DRY (Don't Repeat Yourself) principle.

DuplicateListLiteral Rule

Since CodeNarc 0.16

This rule checks for duplicate List literals within the current class. This rule only checks for Lists where values are all constants or literals.

Code containing duplicate List literals can usually be improved by declaring the List as a constant field.

By default, the rule does not analyze test files. This rule sets the default value of the doNotApplyToFilesMatching property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'.

Examples of violations:

      def var1 = [1, null, Boolean.FALSE, 'x', true]
      def var2 = [1, null, Boolean.FALSE, 'x', true]        // violation

      def var1 = [1, [3, 4]]
      def var2 = [1, [3,4]]     // violation

      def var1 = [123, [3, 4, [x:99], 5]]
      def var2 = [99, [3, 4, [x:99], 5]]        // violation [3, 4, [x:99], 5]

Examples of non-violations:

    def name
    def var1 = [name, 'b', 'c']
    def var2 = [name, 'b', 'c']   // not a violation; name is a variable

    def var1 = [1, 7+5]
    def var2 = [1, 7+5]      // not a violation; contains a non-constant/literal expression

Notes

  • This rule does not search across several files at once, only in the current file, and only within the current class.
  • You can suppress the error by annotating a class or method with the @SuppressWarnings('DuplicateListLiteral') annotation.

DuplicateMapLiteral Rule

Since CodeNarc 0.16

This rule checks for duplicate Map literals within the current class. This rule only checks for Maps where the keys and values are all constants or literals.

Code containing duplicate Map literals can usually be improved by declaring the Map as a constant field.

By default, the rule does not analyze test files. This rule sets the default value of the doNotApplyToFilesMatching property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'.

Examples of violations:

      def var1 = [a:1, b:null, c:Boolean.FALSE, d:'x', e:true]
      def var2 = [a:1, b:null, c:Boolean.FALSE, d:'x', e:true]      // violation

      def var1 = [a:1, b:[x:3,y:4]]
      def var2 = [a:1, b:[x:3,y:4]]     // violation

      def var1 = [a:1, b:[3,4]]
      def var2 = [a:1, b:[3,4]]     // violation

      def var1 = [null:1, 'b':2, (Boolean.FALSE):3, (4):4, (true):5]
      def var2 = [null:1, 'b':2, (Boolean.FALSE):3, (4):4, (true):5]    // violation

Examples of non-violations:

    def name
    def var1 = [(name):1, b:1, c:1]
    def var2 = [(name):1, b:1, c:1]   // not a violation; name is a variable

    def var1 = [a:1, b:['x', name]]
    def var2 = [a:1, b:['x', name]]   // not a violation; name is a variable

    def var1 = [a:7+5]
    def var2 = [a:7+5]      // not a violation; contains a non-constant/literal expression

Notes

  • This rule does not search across several files at once, only in the current file, and only within the current class.
  • You can suppress the error by annotating a class or method with the @SuppressWarnings('DuplicateMapLiteral') annotation.

DuplicateNumberLiteral Rule

Since CodeNarc 0.11

This rule checks for duplicate number literals within the current class.

Code containing duplicate Number literals can usually be improved by declaring the Number as a constant field.

By default, the rule does not analyze test files. This rule sets the default value of the doNotApplyToFilesMatching property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'.

Property Description Default Value
ignoreNumbers The optional comma-separated list of numbers that should be ignored (i.e., not cause a violation). 0,1

Notes

  • This rule does not search across several files at once, only in the current file, and only within the current class.
  • You can suppress the error by annotating a class or method with the @SuppressWarnings('DuplicateNumberLiteral') annotation.

DuplicateStringLiteral Rule

Since CodeNarc 0.11

This rule checks for duplicate String literals within the current class.

Code containing duplicate String literals can usually be improved by declaring the String as a constant field.

By default, the rule does not analyze test files. This rule sets the default value of the doNotApplyToFilesMatching property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'.

Property Description Default Value
ignoreStrings The optional comma-separated list of Strings that should be ignored (i.e., not cause a violation). '' (empty string)

Notes

  • This rule does not search across several files at once, only in the current file, and only within the current class.
  • You can suppress the error by annotating a class or method with the @SuppressWarnings('DuplicateStringLiteral') annotation.

CodeNarc-0.23/docs/codenarc-enhanced-classpath-rules.html0000644000175000017500000003433312471222403022716 0ustar ebourgebourg CodeNarc - CodeNarc - Enhanced Classpath Rules

CodeNarc - Enhanced Classpath Rules

Several newer rules use a later compilation phase for parsing of the Groovy source code, allowing CodeNarc to use a richer and more complete Abstract Syntax Tree (AST). The downside is that the later compiler phase requires CodeNarc to have the application classes being analyzed, as well as any referenced classes, on the classpath.

NOTE: If a rule requiring a later compiler phase is included in the active CodeNarc ruleset and enabled and one or more of the required classes is not on the classpath, then CodeNarc will log a Log4J WARN message for each source file that contains the missing references.

Grails-CodeNarc Plugin

The Grails CodeNarc Plugin supports the new enhanced classpath rules out of the box. You are free to include these rules in your CodeNarc ruleset when you use the Grails CodeNarc plugin.

CodeNarc Ant Task - Expanding the Classpath

TBD...

CodeNarc users that use the Ant Task directly will need to adjust their Ant scripts to expand the classpath, if they want to take advantage of these special new rules.

See the CodeNarc Ant Task for more information on configuring the Ant task.

CodeNarc - Other Tools and Frameworks - Expanding the Classpath?

Other tools/frameworks that use CodeNarc will most likely not be able to use these new rules initially, because the tool classpath will not support it. The hope is that the other CodeNarc tools will eventually be enhanced to provide the expanded classpath to CodeNarc – either optionally or always – so that they can also take advantage of these new rules.

See the CodeNarc - Integration with Other Tools / Frameworks for links to other tools and frameworks that use CodeNarc.

TBD...

Now what?

We also expect to continue to introduce more of these "special" enhanced-classpath rules, since that greatly expands the capabilities for CodeNarc rules.

Anyone who does not want to use the new rules or is unable to expand the classpath as required, can just omit these special rules from the CodeNarc ruleset or else disable the rules.


CodeNarc-0.23/docs/codenarc-rule-index.html0000644000175000017500000013763512471222407020132 0ustar ebourgebourg CodeNarc - CodeNarc - Rule Index

Rule Index

CodeNarc includes 343 rules.

Size


CodeNarc-0.23/docs/codenarc-rules-convention.html0000644000175000017500000004713712471222410021357 0ustar ebourgebourg CodeNarc - CodeNarc - Convention Rules

Convention Rules ("rulesets/convention.xml")

ConfusingTernary Rule

Since CodeNarc 0.12

In a ternary expression avoid negation in the test. For example, rephrase: (x != y) ? diff : same as: (x == y) ? same : diff. Consistent use of this rule makes the code easier to read. Also, this resolves trivial ordering problems, such as "does the error case go first?" or "does the common case go first?".

Example:

    (x != y) ? diff : same      // triggers violation
    (!x) ? diff : same          // triggers violation

    (x == y) ? same : diff      // OK
    (x) ? same : diff           // OK

    // this is OK, because of GroovyTruth there is no inverse of != null
    (x != null) ? diff : same

    // this is OK, because of GroovyTruth there is no inverse of != true
    (x != true) ? diff : same

    // this is OK, because of GroovyTruth there is no inverse of != false
    (x != false) ? diff : same

CouldBeElvis Rule

Since CodeNarc 0.15

Catch an if block that could be written as an elvis expression.

Example of violations:

    if (!x) {                   // violation
        x = 'some value'
    }

    if (!x)                     // violation
        x = "some value"

    if (!params.max) {          // violation
      params.max = 10
    }

    x ?: 'some value'           // OK

HashtableIsObsolete Rule

Since CodeNarc 0.17

Checks for references to the (effectively) obsolete java.util.Hashtable class. Use the Java Collections Framework classes instead, including HashMap or ConcurrentHashMap. See the JDK javadoc.

Example of violations:

    def myMap = new Hashtable()           // violation

IfStatementCouldBeTernary Rule

Since CodeNarc 0.18

Checks for:

  • An if statement where both the if and else blocks contain only a single return statement returning a constant or literal value.
  • A block where the second-to-last statement in a block is an if statement with no else, where the block contains a single return statement, and the last statement in the block is a return statement, and both return statements return a constant or literal value. This check is disabled by setting checkLastStatementImplicitElse to false.

    Example of violations:

        if (condition) { return 44 } else { return 'yes' }                  // violation
        if (check()) { return [1, 2] } else { return "count=$count" }       // violation
    
        if (condition)                                                      // violation
            return null
        else return [a:1]
    
        def method1() {
            if (condition) {                                                // violation
                return 44
            }
            return 'yes'
        }
    

InvertedIfElse Rule

Since CodeNarc 0.11

An inverted if-else statement is one in which there is a single if statement with a single else branch and the boolean test of the if is negated. For instance if (!x) false else true. It is usually clearer to write this as if (x) true else false.

LongLiteralWithLowerCaseL Rule

New in CodeNarc 0.16

In Java and Groovy, you can specify long literals with the L or l character, for instance 55L or 24l. It is best practice to always use an uppercase L and never a lowercase l. This is because 11l rendered in some fonts may look like 111 instead of 11L.

Example of violations:

    def x = 1l
    def y = 55l

NoDef Rule

Since CodeNarc 0.22

Do not allow using the def keyword in code. Use a specific type instead.

Property Description Default Value
excludeRegex Regular expression describing names of attributes, parameters or methods that could be precede by the def keyword.

NOTE: This rule applies to the text contents of a file rather than a specific class, so it does not support the applyToClassNames and doNotApplyToClassNames configuration properties.

ParameterReassignment Rule

Since CodeNarc 0.17

Checks for a method or closure parameter being reassigned to a new value within the body of the method/closure, which is a confusing and questionable practice. Use a temporary variable instead.

Example of violations:

    void myMethod(int a, String b) {
        println a
        b = 'new value'     // violation
    }

    def myClosure1 = { int a, b ->
        a = 123             // violation
    }

TernaryCouldBeElvis Rule

Since CodeNarc 0.17

Checks for ternary expressions where the boolean and true expressions are the same. These can be simplified to an Elvis expression.

Example of violations:

    x ? x : false               // violation; can simplify to x ?: false

    foo() ? foo() : bar()       // violation; can simplify to foo() ?: bar()
    foo(1) ? foo(1) : 123       // violation; can simplify to foo(1) ?: 123

    (x == y) ? same : diff      // OK
    x ? y : z                   // OK
    x ? x + 1 : x + 2           // OK
    x ? 1 : 0                   // OK
    x ? !x : x                  // OK
    !x ? x : null               // OK

    foo() ? bar() : 123         // OK
    foo() ? foo(99) : 123       // OK
    foo(x) ? foo() : 123        // OK
    foo(1) ? foo(2) : 123       // OK

NOTE: If the boolean and true expressions are the same method call, and that method call has side-effects, then converting it to a Elvis expression may produce different behavior. The method will only be called once, rather than twice. But relying on those side-effects as part of a ternary expression behavior is confusing, error-prone and just a bad idea. In any case, that code should be refactored to move the reliance on the side-effects out of the ternary expression.

VectorIsObsolete Rule

Since CodeNarc 0.17

Checks for references to the (effectively) obsolete java.util.Vector class. Use the Java Collections Framework classes instead, including ArrayList or Collections.synchronizedList(). See the JDK javadoc.

Example of violations:

    def myList = new Vector()           // violation

CodeNarc-0.23/docs/codenarc-rules-design.html0000644000175000017500000007310612471222411020442 0ustar ebourgebourg CodeNarc - CodeNarc - Design Rules

Design Rules ("rulesets/design.xml")

AbstractClassWithPublicConstructor Rule

Since CodeNarc 0.14

Checks for abstract classes that define a public constructor, which is useless and confusing.

The following code produces a violation:

    abstract class MyClass {
        MyClass() { }
    }

AbstractClassWithoutAbstractMethod Rule

Since CodeNarc 0.12

The abstract class does not contain any abstract methods. An abstract class suggests an incomplete implementation, which is to be completed by subclasses implementing the abstract methods. If the class is intended to be used as a base class only (not to be instantiated directly) a protected constructor can be provided prevent direct instantiation.

Example:

    public abstract class MyBaseClass {
        void method1() {  }
        void method2() {  }
        // consider using abstract methods or removing
        // the abstract modifier and adding protected constructors
    }

The following examples all pass:

    abstract class MyClass extends AbstractParent {
        // OK because parent is named Abstract.*
    }
    abstract class MyClass extends BaseParent{
        // OK because parent is named Base.*
    }

BooleanMethodReturnsNull Rule

Since CodeNarc 0.11

Checks for a method with Boolean return type that returns an explicit null. A method that returns either Boolean.TRUE, Boolean.FALSE or null is an accident waiting to happen. This method can be invoked as though it returned a value of type boolean, and the compiler will insert automatic unboxing of the Boolean value. If a null value is returned, this will result in a NullPointerException.

BuilderMethodWithSideEffects Rule

New in CodeNarc 0.16

A builder method is defined as one that creates objects. As such, they should never be of void return type. If a method is named build, create, or make, then it should always return a value.

This rule has one property: methodNameRegex. The default value is (make.*|create.*|build.*). Update this property if you have some other naming convention for your builder methods.

Example of violations:

    class MyClass {

            void make() { /* ... */ }
            void makeSomething() { /* ... */ }

            void create() { /* ... */ }
            void createSomething() { /* ... */ }

            void build() { /* ... */ }
            void buildSomething() { /* ... */ }
    }

CloneableWithoutClone Rule

Checks for classes that implement the java.lang.Cloneable interface without implementing the clone() method.

Here is an example of code that produces a violation:

    class BadClass implements Cloneable {
        def someMethod()
    }

CloseWithoutCloseable Rule

Since CodeNarc 0.12

If a class defines a "void close()" then that class should implement java.io.Closeable.

CompareToWithoutComparable Rule

Since CodeNarc 0.12

If you implement a compareTo method then you should also implement the Comparable interface. If you don't then you could possibly get an exception if the Groovy == operator is invoked on your object. This is an issue fixed in Groovy 1.8 but present in previous versions.

Here is an example of code that produces a violation:

    class BadClass {
        int compareTo(Object o) { ... }
    }

ConstantsOnlyInterface Rule

Since CodeNarc 0.12

An interface should be used only to model a behaviour of a class: using an interface as a container of constants is a poor usage pattern. Example:

    public interface ConstantsInterface {
        public static final int CONSTANT_1 = 0
        public static final String CONSTANT_2 = "1"
    }

EmptyMethodInAbstractClass Rule

Since CodeNarc 0.12

An empty method in an abstract class should be abstract instead, as developer may rely on this empty implementation rather than code the appropriate one.

    abstract class MyClass {
        def couldBeAbstract_1() {
            return null  // Should be abstract method
        }

        void couldBeAbstract_2() {
            // Should be abstract method
        }
    }

FinalClassWithProtectedMember Rule

Since CodeNarc 0.12

This rule finds classes marked final that contain protected members. If a class is final then it may not be subclassed, and there is therefore no point in having a member with protected visibility. Either the class should not be final or the member should be private or protected.

ImplementationAsType Rule

Checks for use of the following concrete classes when specifying the type of a method parameter, closure parameter, constructor parameter, method return type or field type. The corresponding interfaces should be used to specify the type instead.

  • java.util.ArrayList
  • java.util.GregorianCalendar
  • java.util.HashMap
  • java.util.HashSet
  • java.util.Hashtable
  • java.util.LinkedHashMap
  • java.util.LinkedHashSet
  • java.util.LinkedList
  • java.util.TreeMap
  • java.util.TreeSet
  • java.util.Vector
  • java.util.concurrent.ArrayBlockingQueue
  • java.util.concurrent.ConcurrentHashMap
  • java.util.concurrent.ConcurrentLinkedQueue
  • java.util.concurrent.CopyOnWriteArrayList
  • java.util.concurrent.CopyOnWriteArraySet
  • java.util.concurrent.DelayQueue
  • java.util.concurrent.LinkedBlockingQueue
  • java.util.concurrent.PriorityBlockingQueue
  • java.util.concurrent.PriorityQueue
  • java.util.concurrent.SynchronousQueue

Here are examples of code that produces violations:

    // Method parameter
    void myMethod(ArrayList list) {                   // violation
        ...
    }

    // Constructor parameter
    class MyClass {
        MyClass(java.util.HashSet set) {              // violation
            ...
        }
    }

    // Closure parameter
    def closure = { PriorityQueue queue -> ... }      // violation

    // Method return type
    GregorianCalendar calculateDate(int num) {        // violation
        ...
    }

    // Field type
    class MyClass {
        Hashtable map                                 // violation
    }

Instanceof Rule

Since CodeNarc 0.22

Checks for use of the instanceof operator. Prefer using polymorphism instead.

Use the ignoreTypeNames property to configure ignored type names (the class name specified as the right-hand expression of the instanceof). It defaults to ignoring instanceof checks against exception classes.

Here are a couple references that discuss the problems with using instanceof and the preference for using polymorphism instead:

By default, the rule does not analyze test files. This rule sets the default value of the doNotApplyToFilesMatching property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'.

Property Description Default Value
ignoreTypeNames Specifies one or more (comma-separated) class names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). *Exceptions

Example of violations:

    class MyClass {
        boolean isRunnable = this instanceof Runnable       // violation
    }

LocaleSetDefault Rule

Since CodeNarc 0.20

Checks for calls to Locale.setDefault(), or Locale.default = Xxx, which sets the Locale across the entire JVM. That can impact other applications on the same web server, for instance.

From the java.util.Locale javadoc for setDefault: Since changing the default locale may affect many different areas of functionality, this method should only be used if the caller is prepared to reinitialize locale-sensitive code running within the same Java Virtual Machine.

Example of violations:

    Locale.setDefault(Locale.UK)                                // violation
    java.util.Locale.setDefault(Locale.FRANCE)                  // violation
    Locale.setDefault(Locale.Category.DISPLAY, Locale.JAPAN)    // violation

    Locale.default = Locale.UK                                  // violation

NestedForLoop Rule

Since CodeNarc 0.23

Reports classes with nested for loops.

Example of violations:

for (int i = 0; i < 100; ++i) {
    for (int j = 0; j < 100; ++j) { // violation
        println i + j
    }
}

for (int i = 0; i < 100; ++i) {
    for (int j = 0; j < 100; ++j) { // violation
        println i + j
    }
    for (int j = 0; j < 100; ++j) { // violation
        println i + j
    }
}

for (int i = 0; i < 100; ++i) {
    for (int j = 0; j < 100; ++j) { // violation
        for (int k = 0; k < 100; ++k) { // violation
            println i + j + k
        }
    }
}

PrivateFieldCouldBeFinal Rule

Since CodeNarc 0.17

This rule finds private fields that are only set within a constructor or field initializer. Such fields can safely be made final.

Property Description Default Value
ignoreFieldNames Specifies one or more (comma-separated) field names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null
ignoreJpaEntities Specifies whether fields defined inside classes annotated with @Entity or @MappedSuperclass JPA annotations should be ignored (i.e., that should not cause a rule violation). false

PublicInstanceField Rule

New in CodeNarc 0.14

Using public fields is considered to be a bad design. Use properties instead.

Example of violations:

    class Person {
        public String name
    }

ReturnsNullInsteadOfEmptyArray Rule

Since CodeNarc 0.11

If you have a method or closure that returns an array, then when there are no results return a zero-length (empty) array rather than null. It is often a better design to return a zero-length array rather than a null reference to indicate that there are no results (i.e., an empty list of results). This way, no explicit check for null is needed by clients of the method.

ReturnsNullInsteadOfEmptyCollection Rule

Since CodeNarc 0.11

If you have a method or closure that returns a collection, then when there are no results return a zero-length (empty) collection rather than null. It is often a better design to return a zero-length collection rather than a null reference to indicate that there are no results (i.e., an empty list of results). This way, no explicit check for null is needed by clients of the method.

SimpleDateFormatMissingLocale Rule

Since CodeNarc 0.12

Be sure to specify a Locale when creating a new instance of SimpleDateFormat; the class is locale-sensitive. If you instantiate SimpleDateFormat without a Locale parameter, it will format the date and time according to the default Locale. Both the pattern and the Locale determine the format. For the same pattern, SimpleDateFormat may format a date and time differently if the Locale varies.

    // violation, missing locale
    new SimpleDateFormat('pattern')

    // OK, includes locale
    new SimpleDateFormat('pattern', Locale.US)

    // OK, includes a variable that perhaps is a locale
    new SimpleDateFormat('pattern', locale)

StatelessSingleton Rule

New in CodeNarc 0.14

There is no point in creating a stateless Singleton because there is nothing within the class that needs guarding and no side effects to calling the constructor. Just create new instances of the object or write a Utility class with static methods. In the long term, Singletons can cause strong coupling and hard to change systems.

If the class has any fields at all, other than a self reference, then it is not considered stateless. A self reference is a field of the same type as the enclosing type, or a field named instance or _instance. The field name self reference is a property named instanceRegex that defaults to the value 'instance|_instance'

Example of violations:

    @groovy.lang.Singleton
    class Service {
       // violation: the class has no fields but is marked Singleton
        void processItem(item){
        }
    }

    class Service {
       // violation: the class has no fields other than 'instance' but is marked Singleton
        static instance
        void processItem(item){
        }
    }

    class Service {                                       // violation
        static Service service
        void processItem(item){
        }
    }

ToStringReturnsNull Rule

Since CodeNarc 0.21

Checks for toString() methods that return null. This is unconventional and could cause unexpected NullPointerExceptions from normal or implicit use of toString().

Example of violations:

    class MyClass {
        String toString() {
            if (foo()) {
                return 'MyClass'
            } else {
                return null         // violation
            }
        }
    }

    class MyClass {
        String toString() {
            calculateStuff()
            null                    // violation
        }
    }

    class MyClass {
        String toString() {         // violation - implicit return of null
        }
    }

CodeNarc-0.23/docs/codenarc-rules-concurrency.html0000644000175000017500000013615212471222410021523 0ustar ebourgebourg CodeNarc - CodeNarc - Concurrency Rules

Concurrency Rules ("rulesets/concurrency.xml")

BusyWait Rule

New in CodeNarc 0.13

Busy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package.

Example of violations:

    while (x) { Thread.sleep(1000) }
    while (x) { Thread.sleep(1000) { /* interruption handler */} }
    for (int x = 10; x; x--) {
        sleep(1000)     // sleep is added to Object in Groovy
    }

    // here is the proper way to wait:
    countDownLatch.await()

    // this is weird code to write, but does not cause a violation
    for (def x : collections) {
        sleep(1000)
    }

    while (x) {
        // you should use a lock here, but technically you are
        // not just busy waiting because you are doing other work
        doSomething()
        sleep(1000)
    }

DoubleCheckedLocking Rule

New in CodeNarc 0.13

This rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern.

A full explanation of why double checked locking is broken in Java is available on Wikipedia:

Example of violations:

    if (object == null) {
        synchronized(this) {
            if (object == null) {
                // createObject() could be called twice depending
                // on the Thread Scheduler.
                object = createObject()
            }
        }
    }

    // there are several idioms to fix this problem.
    def result = object;
    if (result == null) {
        synchronized(this) {
            result = object;
            if (result == null)
                object = result = createObject()
        }
    }

    // and a better solution for a singleton:
    class myClass  {
        private static class ObjectHolder {
           public static Object object = createObject()
        }
        public static Object getObject() {
            return ObjectHolder.object;
        }
    }

InconsistentPropertyLocking Rule

New in CodeNarc 0.13

Class contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all. This may result in incorrect behavior at runtime, as callers of the get and set methods will not necessarily lock correctly and my see an inconsistent state for the object. The get and set method should both be guarded by @WithReadLock/@WithWriteLock or neither should be guarded.

Example of violations:

    class Person {
        String name
        Date birthday
        boolean deceased
        boolean parent

        @WithWriteLock setName(String name) {
            this.name = name
        }
        // violation, get method should be locked
        String getName() {
            name
        }

        // violation, set method should be locked
        void setBirthday(Date birthday) {
            this.birthday = birthday
        }

        @WithReadLock String getBirthday() {
            birthday
        }

        // violation, set method should be locked
        void setDeceased(boolean deceased) {
            this.deceased = deceased
        }

        @WithReadLock boolean isDeceased() {
            deceased
        }

        @WithWriteLock void setParent(boolean parent) {
            this.parent = parent
        }

        // violation, get method should be locked
        boolean isParent() {
            parent
        }
    }

InconsistentPropertySynchronization Rule

New in CodeNarc 0.13

Class contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not. This may result in incorrect behavior at runtime, as callers of the get and set methods will not necessarily see a consistent state for the object. The get and set method should both be synchronized or neither should be synchronized.

Example of violations:

    class Person {
        String name
        Date birthday
        boolean deceased
        boolean parent
        int weight

        synchronized setName(String name) {
            this.name = name
        }
        // violation, get method should be synchronized
        String getName() {
            name
        }

        // violation, set method should be synchronized
        void setBirthday(Date birthday) {
            this.birthday = birthday
        }

        synchronized String getBirthday() {
            birthday
        }

        // violation, set method should be synchronized
        void setDeceased(boolean deceased) {
            this.deceased = deceased
        }

        synchronized boolean isDeceased() {
            deceased
        }

        synchronized void setParent(boolean parent) {
            this.parent = parent
        }

        // violation, get method should be synchronized
        boolean isParent() {
            parent
        }

        // violation get method should be synchronized
        @groovy.transform.Synchronized
        void setWeight(int value) {
            weight = value
        }
    }

NestedSynchronization Rule

This rule reports occurrences of nested synchronized statements.

Nested synchronized statements should be avoided. Nested synchronized statements are either useless (if the lock objects are identical) or prone to deadlock.

Note that a closure or an anonymous inner class carries its own context (scope). A synchronized statement within a closure or an anonymous inner class defined within an outer synchronized statement does not cause a violation (though nested synchronized statements within either of those will).

Here is an example of code that produces a violation:

    def myMethod() {
        synchronized(this) {
            // do something ...
            synchronized(this) {
                // do something else ...
            }
        }
    }

StaticCalendarField Rule

New in CodeNarc 0.13

Calendar objects should not be used as static fields. Calendars are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. Under 1.4 problems seem to surface less often than under Java 5 where you will probably see random ArrayIndexOutOfBoundsException or IndexOutOfBoundsException in sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(). You may also experience serialization problems. Using an instance field or a ThreadLocal is recommended.

For more information on this see Sun Bug #6231579 and Sun Bug #6178997.

Examples:

    // Violations
    class MyClass {
        static Calendar calendar1
        static java.util.Calendar calendar2

        static final CAL1 = Calendar.getInstance()
        static final CAL2 = Calendar.getInstance(Locale.FRANCE)
        static def cal3 = Calendar.getInstance(timezone)
        static Object cal4 = Calendar.getInstance(timezone, locale)
    }

    // These usages are OK
    class MyCorrectClass {
        private final Calendar calendar1
        static ThreadLocal<Calendar> calendar2
    }

StaticConnection Rule

New in CodeNarc 0.14

Creates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions.

A transactional resource object such as database connection can only be associated with one transaction at a time. For this reason, a connection should not be shared between threads and should not be stored in a static field. See Section 4.2.3 of the J2EE Specification for more details.

References:

  • Standards Mapping - Security Technical Implementation Guide Version 3 - (STIG 3) APP3630.1 CAT II
  • Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 362, CWE ID 567
  • Standards Mapping - SANS Top 25 2009 - (SANS 2009) Insecure Interaction - CWE ID 362
  • Standards Mapping - SANS Top 25 2010 - (SANS 2010) Insecure Interaction - CWE ID 362
  • Java 2 Platform Enterprise Edition Specification, v1.4 Sun Microsystems

StaticDateFormatField Rule

New in CodeNarc 0.13

DateFormat objects should not be used as static fields. DateFormats are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. Under 1.4 problems seem to surface less often than under Java 5 where you will probably see random ArrayIndexOutOfBoundsException or IndexOutOfBoundsException in sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(). You may also experience serialization problems. Using an instance field or a ThreadLocal is recommended.

For more information on this see Sun Bug #6231579 and Sun Bug #6178997.

Examples:

    // Violations
    class MyClass {
        static DateFormat dateFormat1
        static java.text.DateFormat dateFormat2

        static final DATE1 = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE)
        static final def DATE2 = DateFormat.getDateInstance(DateFormat.LONG)
        static Object date3 = DateFormat.getDateInstance()

        static final DATETIME1 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.FRANCE)
        static final def DATETIME2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT)
        static final Object DATETIME3 = DateFormat.getDateTimeInstance()

        static final TIME1 = DateFormat.getTimeInstance(DateFormat.LONG, Locale.FRANCE)
        static final def TIME2 = DateFormat.getTimeInstance(DateFormat.LONG)
        static final Object TIME3 = DateFormat.getTimeInstance()
    }

    // These usages are OK
    class MyCorrectClass {
        private DateFormat calendar1
        static ThreadLocal<DateFormat> calendar2
    }

StaticMatcherField Rule

New in CodeNarc 0.13

Matcher objects should not be used as static fields. Calendars are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.

Example of violations:

    // two violations
    class MyClass {
      static Matcher matcher1
      static java.util.regex.Matcher matcher2
    }

    // these usages are OK
    class MyCorrectClass {
      private Matcher matcher1
      static ThreadLocal<Matcher> matcher2
    }

StaticSimpleDateFormatField Rule

New in CodeNarc 0.14

SimpleDateFormat objects should not be used as static fields. SimpleDateFormats are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. Under 1.4 problems seem to surface less often than under Java 5 where you will probably see random ArrayIndexOutOfBoundsException or IndexOutOfBoundsException in sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(). You may also experience serialization problems. Using an instance field or a ThreadLocal is recommended.

For more information on this see Sun Bug #6231579 and Sun Bug #6178997.

Examples:

    // Violations
    class MyClass {
        static SimpleDateFormat dateFormat1
        static java.text.SimpleDateFormat dateFormat2

        static final DATE1 = new SimpleDateFormat()
        static final DATE2 = new SimpleDateFormat('MM/dd')
        static final DATE3 = new SimpleDateFormat('MM/dd', DateFormatSymbols.instance)
        static date4 = new SimpleDateFormat('MM/dd', Locale.FRANCE)
        static date5 = new java.text.SimpleDateFormat('MM/dd')
    }

    // These usages are OK
    class MyCorrectClass {
        private SimpleDateFormat calendar1
        static ThreadLocal<SimpleDateFormat> calendar2
    }

SynchronizedMethod Rule

This rule reports uses of the synchronized keyword on methods. Synchronized methods are the same as synchronizing on 'this', which effectively make your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.

Here is an example of code that produces a violation:

    synchronized def myMethod() {
        // do stuff ...
    }

SynchronizedOnGetClass Rule

Since CodeNarc 0.11

Checks for synchronization on getClass() rather than class literal. This instance method synchronizes on this.getClass(). If this class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended.

SynchronizedOnBoxedPrimitive Rule

New in CodeNarc 0.13

The code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock.

Example of violations:

    class MyClass {
        Byte byte1 = 100
        Short short1 = 1
        Double double1 = 1
        Integer integer1 = 1
        Long long1 = 1
        Float float1 = 1
        Character char1 = 1

        byte byte2 = getValue()
        short short2 = getValue()
        double double2 = getValue()
        int integer2 = getValue()
        long long2 = getValue()
        float float2 = getValue()
        char char2 = getValue()

        def byte3 = new Byte((byte)100)
        def short3 = new Short((short)1)
        def double3 = new Double((double)1)
        def integer3 = new Integer(1)
        def long3 = new Long(1)
        def float3 = new Float(1)
        def char3 = new Character((char)'1')

        def byte4 = 1 as byte
        def short4 = 1 as short
        def double4 = 1 as double
        def integer4 = 1 as int
        def long4 = 1 as long
        def float4 = 1 as float
        def char4 = 1 as char

        def byte5 = 1 as Byte
        def short5 = 1 as Short
        def double5 = 1 as Double
        def integer5 = 1 as Integer
        def long5 = 1 as Long
        def float5 = 1 as Float
        def char5 = 1 as Character

        def byte6 = (byte)1
        def short6 = (short)1
        def double6 = (double)1
        def integer6 = (int)1
        def long6 = (long)1
        def float6 = (float)1
        def char6 = (char)1

        def method() {
            // all of these synchronization blocks produce violations
            synchronized(byte1) {}
            synchronized(short1) {}
            synchronized(double1) {}
            synchronized(integer1) {}
            synchronized(long1) {}
            synchronized(float1) {}
            synchronized(char1) {}

            synchronized(byte2) {}
            synchronized(short2) {}
            synchronized(double2) {}
            synchronized(integer2) {}
            synchronized(long2) {}
            synchronized(float2) {}
            synchronized(char2) {}

            synchronized(byte3) {}
            synchronized(short3) {}
            synchronized(double3) {}
            synchronized(integer3) {}
            synchronized(long3) {}
            synchronized(float3) {}
            synchronized(char3) {}

            synchronized(byte4) {}
            synchronized(short4) {}
            synchronized(double4) {}
            synchronized(integer4) {}
            synchronized(long4) {}
            synchronized(float4) {}
            synchronized(char4) {}

            synchronized(byte5) {}
            synchronized(short5) {}
            synchronized(double5) {}
            synchronized(integer5) {}
            synchronized(long5) {}
            synchronized(float5) {}
            synchronized(char5) {}

            synchronized(byte6) {}
            synchronized(short6) {}
            synchronized(double6) {}
            synchronized(integer6) {}
            synchronized(long6) {}
            synchronized(float6) {}
            synchronized(char6) {}
        }
    }

And here is an in-depth example of how it works within inner classes and such:

    class MyClass {

        final String lock = false

        def method() {
            // violation
            synchronized(lock) { }
        }
    }

    class MyClass {

        final String lock = false

        class MyInnerClass {
            def method() {
                // violation
                synchronized(lock) { }
            }
        }
    }

    class MyClass {
        // implicit typing
        final def lock = true

        def method() {
            // violation
            synchronized(lock) { }
        }
    }

    class MyClass {
        // implicit typing
        final def lock = new Object[0] // correct idiom

        def method() {
            return new Runnable() {
                final def lock = false // shadows parent from inner class
                public void run() {
                    // violation
                    synchronized(stringLock) { }
                }
            }
        }
    }

    class MyClass {
        // implicit typing
        final def lock = new Object[0] // correct idiom

        class MyInnerClass {

            final def lock = true // shadows parent from inner class
            def method() {
                // violation
                synchronized(stringLock) { }
            }
        }
    }

SynchronizedOnString Rule

New in CodeNarc 0.13

Synchronization on a String field can lead to deadlock. Constant Strings are interned and shared across all other classes loaded by the JVM. Thus, this could is locking on something that other code might also be locking. This could result in very strange and hard to diagnose blocking and deadlock behavior.

See JETTY-352.

Examples:

    class MyClass {

        final String stringLock = "stringLock"

        def method() {
            // violation
            synchronized(stringLock) { }
        }
    }

    class MyClass {

        final String stringLock = "stringLock"

        class MyInnerClass {
            def method() {
                synchronized(stringLock) { }
            }
        }
    }

    class MyClass {
        // implicit typing
        final def stringLock = "stringLock"

        def method() {
            // violation
            synchronized(stringLock) { }
        }
    }

    class MyClass {
        // implicit typing
        final def lock = new Object[0] // correct idiom

        def method() {
            return new Runnable() {
                final def lock = "" // shadows parent from inner class
                public void run() {
                    // violation
                    synchronized(stringLock) { }
                }
            }
        }
    }

    class MyClass {
        // implicit typing
        final def lock = new Object[0] // correct idiom

        class MyInnerClass {

            final def lock = "" // shadows parent from inner class
            def method() {
                // violation
                synchronized(stringLock) { }
            }
        }
    }

SynchronizedOnThis Rule

This rule reports uses of the synchronized blocks where the synchronization reference is 'this'. Doing this effectively makes your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.

Here is an example of code that produces a violation:

    def method3() {
        synchronized(this) {
            // do stuff ...
        }
    }

SynchronizedReadObjectMethod Rule

New in CodeNarc 0.13

Catches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style.

Examples:

    class MyClass implements Serializable {

        private synchronized void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
            // violation, no need to synchronized
        }
    }

    class MyClass implements Serializable {

        private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
            synchronized(lock) {
                // violation, no need to synchronized
            }
        }
    }

    // OK, class not Serializable
    class MyClass {

        private synchronized void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { }
    }

    // OK, class not Serializable
    class MyClass {

        private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
            synchronized(lock) { }
        }
    }

    class MyClass implements Serializable {

        private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
            // OK, this block is more than just a simple sync statement
            synchronized(lock) { }
            doSomething()
        }
    }

SynchronizedOnReentrantLock Rule

New in CodeNarc 0.13

Synchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method.

This rule take from Alex Miller's Java Concurrency in Practice slides.

Here is the proper usage of ReentrantLock:

    import java.util.concurrent.locks.ReentrantLock;
    final lock = new ReentrantLock();
    def method()  {
       //Trying to enter the critical section
       lock.lock(); // will wait until this thread gets the lock
       try {
          // critical section
       } finally {
          //releasing the lock so that other threads can get notifies
          lock.unlock();
       }
    }

Example of violations:

    class MyClass {

        final ReentrantLock lock = new ReentrantLock()

        def method() {
            // violation
            synchronized(lock) { }
        }
    }

    class MyClass {

        final ReentrantLock lock = new ReentrantLock()

        class MyInnerClass {
            def method() {
                synchronized(lock) { }
            }
        }
    }

    class MyClass {
        // implicit typing
        final def lock = new ReentrantLock()

        def method() {
            // violation
            synchronized(lock) { }
        }
    }

    class MyClass {
        // implicit typing
        final def lock = new Object[0] // correct idiom

        def method() {
            return new Runnable() {
                final def lock = new ReentrantLock() // shadows parent from inner class
                public void run() {
                    // violation
                    synchronized(lock) { }
                }
            }
        }
    }

    class MyClass {
        // implicit typing
        final def lock = new Object[0] // correct idiom

        class MyInnerClass {

            final def lock = new ReentrantLock() // shadows parent from inner class
            def method() {
                // violation
                synchronized(lock) { }
            }
        }
    }

SystemRunFinalizersOnExit Rule

This rule reports uses of the System.runFinalizersOnExit() method.

Method calls to System.runFinalizersOnExit() should not be allowed. This method is inherently non-thread-safe, may result in data corruption, deadlock, and may affect parts of the program far removed from it's call point. It is deprecated, and it's use strongly discouraged.

Here is an example of code that produces a violation:

    def method() {
        System.runFinalizersOnExit(true)
    }

ThisReferenceEscapesConstructor Rule

Since CodeNarc 0.19

Reports constructors passing the 'this' reference to other methods. This equals exposing a half-baked objects and can lead to race conditions during initialization. For reference, see Java Concurrency in Practice by Alex Miller and Java theory and practice: Safe construction techniques by Brian Goetz.

Example of violations:

    class EventListener {
        EventListener(EventPublisher publisher) {
            publisher.register(this)            
            new WorkThread(publisher, this).start()
            new AnotherWorkThread(listener: this)
        }    
    }

ThreadGroup Rule

New in CodeNarc 0.13

Avoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe.

Here is an example of code that produces a violation:

    new ThreadGroup("...")
    new ThreadGroup(tg, "my thread group")
    Thread.currentThread().getThreadGroup()
    System.getSecurityManager().getThreadGroup()

ThreadLocalNotStaticFinal Rule

This rule reports definition of the ThreadLocal fields that are not static and final.

ThreadLocal fields should be static and final. In the most common case a java.lang.ThreadLocal instance associates state with a thread. A non-static non-final java.lang.ThreadLocal field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior.

Here is an example of code that produces a violation:

    private static ThreadLocal local1 = new ThreadLocal()
    private final ThreadLocal local2 = new ThreadLocal()
    protected ThreadLocal local3 = new ThreadLocal()
    ThreadLocal local4 = new ThreadLocal()

ThreadYield Rule

This rule reports uses of the Thread.yield() method.

Method calls to Thread.yield() should not be allowed. This method has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions.

Here is an example of code that produces a violation:

     def method() {
         Thread.yield()
     }

UseOfNotifyMethod Rule

Since CodeNarc 0.11

Checks for code that calls notify() rather than notifyAll(). Java monitors are often used for multiple conditions. Calling notify() only wakes up one thread, meaning that the awakened thread might not be the one waiting for the condition that the caller just satisfied.

Also see Java_Concurrency_in_Practice, Brian Goetz, p 303.

VolatileArrayField Rule

New in CodeNarc 0.13

Volatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not.

This rule take from Alex Miller's Java Concurrency in Practice slides, available at http://www.slideshare.net/alexmiller/java-concurrency-gotchas-3666977.

Example of violations:

    class MyClass {
        private volatile Object[] field1 = value()
        volatile field2 = value as Object[]
        volatile field3 = (Object[])foo
    }

VolatileLongOrDoubleField Rule

This rule reports on long or double fields that are declared volatile.

Long or double fields should not be declared as volatile. Java specifies that reads and writes from such fields are atomic, but many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronize access to such fields rather than declare them volatile. This rule flags fields marked volatile when their type is double or long or the name of their type is "Double" or "Long".

Here is an example of code that produces a violation:

     def method() {
         private volatile double d
         private volatile long f
     }

WaitOutsideOfWhileLoop Rule

Since CodeNarc 0.13

Calls to Object.wait() must be within a while loop. This ensures that the awaited condition has not already been satisfied by another thread before the wait() is invoked. It also ensures that the proper thread was resumed and guards against incorrect notification. See [1] and [3].

As a more modern and flexible alternative, consider using the Java concurrency utilities instead of wait() and notify(). See discussion in Effective Java [2].

Example of violation:

    class MyClass {
        private data

        void processData()
            synchronized(data) {
                if (!data.isReady()) {
                    data.wait()
                }
                data.calculateStatistics()
            }
        }
    }

Example of correct usage:

    class MyClass {
        private data

        void processData()
            synchronized(data) {
                while (!data.isReady()) {
                    data.wait()
                }
                data.calculateStatistics()
            }
        }
    }

References

  • [1] Effective Java, Programming Language Guide, by Joshua Bloch. Addison Wesley (2001). Chapter 50 (1st edition) is entitled "Never invoke wait outside a loop."
  • [2] Effective Java, 2nd edition, by Joshua Bloch, Addison Wesley (2008). Item #69: Prefer concurrency utilities to wait and notify.
  • [3] Software Engineering Institute - Secure Coding discussion of this issue

CodeNarc-0.23/docs/codenarc-rules-unused.html0000644000175000017500000004750712471222420020502 0ustar ebourgebourg CodeNarc - CodeNarc - Unused Rules

Unused Rules ("rulesets/unused.xml")

UnusedArray Rule

Checks for array allocations that are not assigned or used, unless it is the last statement within a block (because it may be the intentional return value). Examples include:

    int myMethod() {
        new String[3]               // unused
        return -1
    }

    String[] myMethod() {
        new String[3]               // OK (last statement in block)
    }

    def closure = {
        doStuff()
        new Date[3]                 // unused
        doOtherStuff()
    }

    def closure = { new Date[3] }   // OK (last statement in block)

UnusedObject Rule

Checks for object allocations that are not assigned or used, unless it is the last statement within a block (because it may be the intentional return value). Examples include:

By default, this rule does not analyze test files. This rule sets the default value of the doNotApplyToFilesMatching property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'. Invoking constructors without using the result is a common pattern in tests.

    int myMethod() {
        new BigDecimal("23.45")     // unused
        return -1
    }

    BigDecimal myMethod() {
        new BigDecimal("23.45")     // OK (last statement in block)
    }

    def closure = {
        doStuff()
        new Date()                  // unused
        doOtherStuff()
    }

    def closure = { new Date() }    // OK (last statement in block)

UnusedPrivateField Rule

Checks for private fields that are not referenced within the same class. Note that the private modifier is not currently "respected" by Groovy code (i.e., Groovy can access private members within other classes). By default, fields named serialVersionUID are ignored. The rule has a property named ignoreFieldNames, which can be set to ignore other field names as well. For instance, to ignore fields named 'fieldx', set the property to the 'fieldx, serialVersionUID'

Property Description Default Value
ignoreFieldNames Specifies one or more (comma-separated) field names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). serialVersionUID

Known limitations:

  • Does not recognize field access when field name is a GString (e.g. this."$fieldName")
  • Does not recognize access of private field of another instance (i.e. other than this)

UnusedPrivateMethod Rule

Checks for private methods that are not referenced within the same class. Note that the private modifier is not currently "respected" by Groovy code (i.e., Groovy can access private members within other classes).

Known limitations:

  • Does not recognize method reference through property access (e.g. getName() accessed as x.name)
  • Does not recognize method invocations when method name is a GString (e.g. this."$methodName"())
  • Does not recognize invoking private method of another instance (i.e. other than this)
  • Does not differentiate between multiple private methods with the same name but different parameters (i.e., overloaded)
  • Does not check for unused constructors

UnusedPrivateMethodParameter Rule

Since CodeNarc 0.12

Checks for parameters to private methods that are not referenced within the method body. Note that the private modifier is not currently "respected" by Groovy code (i.e., Groovy can access private members within other classes).

Known limitations:

  • Does not recognize parameter references within an inner class. See CodeNarc bug #3155974.
  • Does not recognize parameter references when parameter name is a GString (e.g. println "$parameterName")

    Since CodeNarc 0.14 * You can specify an ignore list using the 'ignoreRegex' property. By default, a parameter named 'ignore' or 'ignored' does not trigger a violation (the regex value is 'ignore|ignored'). You can add your own ignore list using this property.

UnusedMethodParameter Rule

New in CodeNarc 0.16

This rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override.

  • This rule ignores main() methods. In Groovy, the main()>> method can either specify a <<<void return type or else omit a return type (be dynamically typed). The main()>> method must have exactly one parameter. That parameter can either be typed as <<<String[] or else the type can be omitted (be dynamically typed). And the main()>> method must be <<<static.
  • You can specify an ignore list of parameter names using the 'ignoreRegex' property. By default, a parameter named 'ignore' or 'ignored' does not trigger a violation (the regex value is 'ignore|ignored'). You can add your own ignore list using this property.
  • You can specify a class name pattern to ignore using the 'ignoreClassRegex' property. By default classes named '*.Category' are ignored because they are category classes and have unused parameters in static methods.

    Example of violations:

        class MyClass {
            def method(def param) {
                // param is unused
            }
        }
    

    Example of code that does not cause violations:

        class MyClass {
            @Override
            def otherMethod(def param) {
                // this is OK because it overrides a super class
            }
        }
    
        class MyCategory {
            // Category classes are ignored by default
            void myMethod1(String string, int value) { }
            void myMethod1(String string, int value, name) { }
        }
    
        class MainClass1 {
            // main() methods are ignored
            public static void main(String[] args) { }
        }
        class MainClass2 {
            // This is also a valid Groovy main() method
            static main(args) { }
        }
    

UnusedVariable Rule

Checks for variables that are never referenced.

The rule has a property named ignoreVariableNames, which can be set to ignore some variable names. For instance, to ignore fields named 'unused', set the property to 'unused'.

Property Description Default Value
ignoreVariableNames Specifies one or more (comma-separated) variable names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

Known limitations:

  • Incorrectly considers a variable referenced if another variable with the same name is referenced elsewhere (in another scope/block).

CodeNarc-0.23/docs/codenarc-run-as-a-test.html0000644000175000017500000003315212471222420020436 0ustar ebourgebourg CodeNarc - CodeNarc - Run as a Test

CodeNarc - Run as an Automated Test

CodeNarc can be run as part of an automated test suite, for instance using JUnit or TestNG. This approach uses the org.codenarc.ant.CodeNarcTask class and Groovy's built-in support for Apache Ant.

NOTE: This approach may not play well with having CodeNarc also configured to run as part of your "regular" Ant build, especially if you have a classpath defined for your Ant build which is different that your runtime classpath for running your tests (which is likely).

Automated Test That Runs CodeNarc

This is an example JUnit test (JUnit 3.x) that runs CodeNarc.

    private static final GROOVY_FILES = '**/*.groovy'
    private static final RULESET_FILES = [
            'rulesets/basic.xml',
            'rulesets/imports.xml'].join(',')

    void testRunCodeNarc() {
        def ant = new AntBuilder()

        ant.taskdef(name:'codenarc', classname:'org.codenarc.ant.CodeNarcTask')

        ant.codenarc(ruleSetFiles:RULESET_FILES,
           maxPriority1Violations:0, maxPriority2Violations:0) {

           fileset(dir:'src/main/groovy') {
               include(name:GROOVY_FILES)
           }
           fileset(dir:'src/test/groovy') {
               include(name:GROOVY_FILES)
           }

           report(type:'ide')
        }
    }

Things to note:

  • This approach uses the AntBuilder class provided with Groovy.
  • The CodeNarc jar must be on the classpath. Any external resources that you reference must also be on the classpath, including any custom RuleSet files.
  • The maxPriority1Violations and maxPriority2Violations properties are configured to fail the test if any priority 1 or 2 violations are found.
  • An ide report is configured. This will to write (only) to standard out, and will include hyperlinks to the lines within the source code that contained the violations . The report shows the total number of violations (at each priority) and also list the violations by file.

See the CodeNarc Ant Task for more information on configuring the Ant task.


CodeNarc-0.23/docs/project-info.html0000644000175000017500000002766612471222450016701 0ustar ebourgebourg CodeNarc - Project Information

Project Information

This document provides an overview of the various documents and links that are part of this project's general information. All of this content is automatically generated by Maven on behalf of the project.

Overview

Document Description
Project License This is a link to the definitions of project licenses.

CodeNarc-0.23/docs/codenarc-rules-imports.html0000644000175000017500000003461512471222414020673 0ustar ebourgebourg CodeNarc - CodeNarc - Imports Rules

Imports Rules ("rulesets/imports.xml")

DuplicateImport Rule

Checks for a duplicate import statements.

ImportFromSamePackage Rule

Checks for an import of a class that is within the same package as the importing class.

ImportFromSunPackages Rule

New in CodeNarc 0.14 Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.

Example of violations:

    import sun.misc.foo
    import sun.misc.foo as Foo

    public class MyClass{}

MisorderedStaticImports Rule

New in CodeNarc 0.14 Checks for static import statements which should never be after nonstatic imports.

This rule has one property comesBefore, which defaults to true. If you like your static imports to come after the others, then set this property to false.

Examples of violations:

    import my.something.another
    import static foo.bar

    public class MyClass{}

UnnecessaryGroovyImport Rule

Checks for an import from any package that is already automatically imported for Groovy files. A Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger.

UnusedImport Rule

Checks for import statements for classes that are never referenced within the source file. Also checks static imports.

Known limitations:

  • Does not check for unused imports containing wildcards (e.g. import org.codenarc.*)
  • Misses unused imports if the class/alias name is contained within strings, comments or other (longer) names (i.e., if that string shows up almost anywhere within the source code).

NoWildcardImports Rule

Since CodeNarc 0.21

Wildcard imports, static or otherwise, should not be used.

Example of violations:

    import my.something.*
    import static foo.bar.*

    public class MyClass{}

CodeNarc-0.23/docs/codenarc-developer-guide.html0000644000175000017500000003727412471222402021127 0ustar ebourgebourg CodeNarc - CodeNarc - Developer Guide

CodeNarc - Developer Guide

Contents

The codenarc Command-line Script

There is a codenarc.groovy command-line script in the root directory of the project. It is intended to streamline common development tasks. Currently, it supports a create-rule task for creating new CodeNarc rules.

codenarc create-rule

The create-rule task performs the following steps:

  • Prompt for the rule name
  • Prompt for the existing ruleset (category) name to which the rule is added
  • Create a new rule class file in the proper package (under src/main/groovy)
  • Create a new rule test class file (under src/test/groovy)
  • Add placeholder description messages for the new rule to "codenarc-base-messages.properties"
  • Add the new rule to the chosen ruleset XML file

RUNNING

On Unix/Mac, you can run the following from the project root directory:

./codenarc create-rule

On Windows, you can run:

codenarc create-rule.

(If Windows is not configured to automatically run *.groovy files, just can run groovy codenarc create-rule)

AFTER YOU RUN codenarc create-rule

After you run codenarc create-rule, finish up the rule implementation, including the following:

  1. Edit the generated rule class and associated test class to add the proper implementation.
  2. Modify the description messages for the new rule in "codenarc-base-messages.properties". Move the message entries under the proper ruleset/category section within the file.
  3. Add description to "src/main/site/apt/codenarc-rules-XX.apt" document in the site folder.
  4. Run mvn site from the command-line. Make sure all of the tests pass and review the new rule description on the appropriate ruleset page on the project site.

New Rule Checklist

Perform the following steps when creating a new rule. See The codenarc Command-line Script for information on the command-line script that automates a good bit of the boilerplate, as indicated below.

  1. Implement the new Rule class. This is typically a subclass of AbstractAstVisitorRule. [1]
  2. Implement the associated Rule test class. This is typically a subclass of AbstractRuleTestCase. [1]
  3. Add the new rule class name to the appropriate RuleSet file under "src/main/resources/rulesets". [1]
  4. Add the new rule description entries to "src/main/resources/codenarc-base-messages.properties". This includes both "RuleName.description" and "RuleName.description.html" property entries. [1]
  5. Run LoadAllPredefinedRuleSetsTest.
  6. Add a description of the new rule to the appropriate "src/main/site/apt/codenarc-rules-XX.apt" document.

Before You Submit a Patch or Check-In Code

Please do the following before submitting a patch or checking in code:

  • Run the full CodeNarc test suite. This includes a test called RunCodeNarcAgainstProjectSourceCodeTest that runs CodeNarc against its own source code (including any code that you have added or changed).

NOTES

  • [1] These files are created (skeletons) or updated automatically if you run the codenarc create-rule script to create the rule. See The codenarc Command-line Script

CodeNarc-0.23/docs/index.html0000644000175000017500000004001512471222377015400 0ustar ebourgebourg CodeNarc -
Static Analysis for Groovy: Less Bugs, Better Code

CodeNarc analyzes Groovy code for defects, bad practices, inconsistencies, style issues and more. A flexible framework for rules, rulesets and custom rules means it's easy to configure CodeNarc to fit into your project. Build tool, framework support, and report generation are all enterprise ready.

CodeNarc Web Console let's you play with the latest snapshot, containing over 175 rules with more added each week. Enter some text, click execute, and see the violations. Or run some scripts we made. CodeNarc triggers violations based on rules. Click the links to the left to view all the rules, such as the basic, or concurrency rules. Or you can create your own ruleset; see how easy it is in this screencast.

Running CodeNarc

Run CodeNarc with the Ant Task, the command-line runner, or as part of your test suite. Also, plugins exist for Maven, Gradle, Grails, Griffon, Sonar and Hudson. See our Integration page for more details. Reports come in HTML, XML, or text format. Take a look at a Sample CodeNarc HTML Report, or a Sample CodeNarc XML Report.

Requirements

CodeNarc requires:
  • Groovy version 2.1
  • Java 1.6 or later
  • Log4J 1.2.13 or later on the classpath

Get it from Maven2

For projects built using Maven, CodeNarc is available from the Maven Central Repository
  • groupId = org.codenarc
  • artifactId = CodeNarc

Inspirations

We're inspired by the wonderful PMD and Checkstyle Java static analysis tools, as well as the extensive Groovy inspections performed by IntelliJ IDEA.

CodeNarc-0.23/docs/codenarc-rules-junit.html0000644000175000017500000010251712471222415020325 0ustar ebourgebourg CodeNarc - CodeNarc - JUnit Rules

JUnit Rules ("rulesets/junit.xml")

ChainedTest Rule

Since CodeNarc 0.13

A test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another.

Example of violations:

    class MyTest extends GroovyTestCase {
        public void testFoo() {

            // violations, calls test method on self
            5.times { testBar() }
            5.times { this.testBar() }

            // OK, no violation: one arg method is not actually a test method
            5.times { testBar(it) }
        }

        private static void assertSomething() {
            testBar() // violation, even if in helper method
            this.testBar() // violation, even if in helper method
        }

        public void testBar() {
            // ...
        }
    }

CoupledTestCase Rule

Since CodeNarc 0.13

This rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused. Static references to methods on the current test class are ignored.

Example of violations:

    class MyTest extends GroovyTestCase {
        public void testMethod() {
            // violation, static method call to other test
            MyOtherTest.helperMethod()

            // violation, instantiation of another test class
            new MyOtherTest()

            // no violation; same class
            def input = MyTest.getResourceAsStream('sample.txt')
        }
    }

JUnitAssertAlwaysFails Rule

Rule that checks for JUnit assert() method calls with constant or literal arguments such that the assertion always fails. This includes:

  • assertTrue(false)
  • assertTrue(0)
  • assertTrue('')
  • assertTrue([])
  • assertTrue([:])
  • assertFalse(true)
  • assertFalse('abc')
  • assertFalse(99)
  • assertFalse([123])
  • assertFalse([a:123)
  • assertNull(CONSTANT).
  • assertNull([]).
  • assertNull([123]).
  • assertNull([:]).
  • assertNull([a:123]).

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

JUnitAssertAlwaysSucceeds Rule

Rule that checks for JUnit assert() method calls with constant arguments such that the assertion always succeeds. This includes:

  • assertTrue(true)
  • assertTrue(99)
  • assertTrue('abc')
  • assertTrue([123])
  • assertTrue([a:123])
  • assertFalse(false)
  • assertFalse('')
  • assertFalse(0)
  • assertFalse([])
  • assertFalse([:)
  • assertNull(null)

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

JUnitFailWithoutMessage Rule

Since CodeNarc 0.11

This rule detects JUnit calling the fail() method without an argument. For better error reporting you should always provide a message.

JUnitLostTest Rule

Since CodeNarc 0.18

This rule checks for classes that import JUnit 4 classes and contain a public, instance, void, no-arg method named test* that is not annotated with the JUnit 4 @Test annotation.

Note: This rule should be disabled for Grails 2.x projects, since the Grails test framework can use AST Transformations to automatically annotate test methods.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

Example of violations:

    import org.junit.Test

    class MyTestCase {
        void testMe() { }           // missing @Test annotation
    }

JUnitPublicField Rule

Since CodeNarc 0.19

Checks for public fields on a JUnit test class. There is usually no reason to have a public field (even a constant) on a test class.

Fields within interfaces and fields annotated with @Rule are ignored.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

Example of violations:

    import org.junit.Test
    class MyTestCase {
        public int count                        // violation
        public static final MAX_VALUE = 1000    // violation

        @Test
        void testMe() { }
    }

JUnitPublicNonTestMethod Rule

Rule that checks if a JUnit test class contains public methods other than standard test methods, JUnit framework methods or methods with JUnit annotations.

The following public methods are ignored by this rule:

  • Zero-argument methods with names starting with "test"
  • The setUp() and tearDown() methods
  • Methods annotated with @Test
  • Methods annotated with @Before and @After
  • Methods annotated with @BeforeClass and @AfterClass
  • Methods annotated with @Override

Public, non-test methods on a test class violate conventional usage of test classes, and they typically break encapsulation unnecessarily.

Public, non-test methods may also hide unintentional 'Lost Tests'. For instance, the test method declaration may (unintentionally) include methods parameters, and thus be ignored by JUnit. Or the method may (unintentionally) not follow the "test.." naming convention and not have the @Test annotation, and thus be ignored by JUnit.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

JUnitPublicProperty Rule

Since CodeNarc 0.21

Checks for public properties defined on JUnit test classes. There is typically no need to expose a public property (with public getter and setter methods) on a test class.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

Property Description Default Value
ignorePropertyNames Specifies one or more (comma-separated) property names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

Example of violations:

    import org.junit.Test
    class MyTestCase {
        static String id    // violation
        def helper          // violation
        String name         // violation

        @Test
        void testMe() { }
    }

JUnitSetUpCallsSuper Rule

Rule that checks that if the JUnit setUp method is defined, that it includes a call to super.setUp().

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

JUnitStyleAssertions Rule

Since CodeNarc 0.11

This rule detects calling JUnit style assertions like assertEquals, assertTrue, assertFalse, assertNull, assertNotNull. Groovy 1.7 ships with a feature called the "power assert", which is an assert statement with better error reporting. This is preferable to the JUnit assertions.

JUnitTearDownCallsSuper Rule

Rule that checks that if the JUnit tearDown method is defined, that it includes a call to super.tearDown().

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

JUnitTestMethodWithoutAssert Rule

Since CodeNarc 0.12

This rule searches for test methods that do not contain assert statements. Either the test method is missing assert statements, which is an error, or the test method contains custom assert statements that do not follow a proper assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test annotation. By default this rule applies to the default test class names, but this can be changed using the rule's applyToClassNames property. An assertion is defined as either using the assert keyword or invoking a method that starts with the work assert, like assertEquals, assertNull, or assertMyClassIsSimilar. Also, any method named should.* also counts as an assertion so that shouldFail methods do not trigger an assertion, any method that starts with fail>> counts as an assertion, and any method that starts with <<<verify counts as an assertion. Since version 0.23 CodeNarc has support for JUnit's ExpectedException.

What counts as an assertion method can be overridden using the assertMethodPatterns property of the rule. The default value is this comma separated list of regular expressions:

    String assertMethodPatterns = 'assert.*,should.*,fail.*,verify.*,expect.*'

If you'd like to add any method starting with 'ensure' to the ignores then you would set the value to this:

    'assert.*,should.*,fail.*,verify.*,ensure.*'

JUnitUnnecessarySetUp Rule

Rule that checks checks for JUnit setUp() methods that contain only a call to super.setUp(). The method is then unnecessary.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

Here is an example of a violation:

    class MyTest extends TestCase {
        void setUp() {              // violation
            super.setUp()
        }
    }

JUnitUnnecessaryTearDown Rule

Rule that checks checks for JUnit tearDown() methods that contain only a call to super.tearDown(). The method is then unnecessary.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

Here is an example of a violation:

    class MyTest extends TestCase {
        void tearDown() {               // violation
            super.tearDown()
        }
    }

JUnitUnnecessaryThrowsException Rule

Since CodeNarc 0.18

Check for throws clauses on JUnit test methods. That is not necessary in Groovy.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

Example of violations:

    @Test
    void shouldDoStuff() throws Exception { }           // violation

    @BeforeClass void initialize() throws Exception { } // violation
    @Before void setUp() throws RuntimeException { }    // violation
    @After void tearDown() throws Exception { }         // violation
    @AfterClass void cleanUp() throws Exception { }     // violation
    @Ignore void ignored() throws Exception { }         // violation

    class MyTest extends GroovyTestCase {
        void test1() throws Exception { }               // violation
        public void test2() throws IOException { }      // violation
    }

SpockIgnoreRestUsed Rule

Since CodeNarc 0.14

If Spock's @IgnoreRest annotation appears on any method, all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed.

The specificationClassNames and specificationSuperclassNames properties determine which classes are considered Spock Specification classes.

Property Description Default Value
specificationClassNames Specifies one or more (comma-separated) class names that should be treated as Spock Specification classes. The class names may optionally contain wildcards (*,?), e.g. "*Spec". null
specificationSuperclassNames Specifies one or more (comma-separated) class names that should be treated as Spock Specification superclasses. In other words, a class that extends a matching class name is considered a Spock Specification . The class names may optionally contain wildcards (*,?), e.g. "*Spec". "*Specification"

Example of violations:

    public class MySpec extends spock.lang.Specification {
        @spock.lang.IgnoreRest
        def "my first feature"() {
            expect: false
        }

        def "my second feature"() {
            given: def a = 2

            when: a *= 2

            then: a == 4
        }
    }

UnnecessaryFail Rule

Since CodeNarc 0.13

In a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

Example of violations:

    public void testSomething() {
        try {
            something()
        } catch (Exception e) {
            fail(e.message)
        }

        try {
            something()
        } catch (Exception e) {
            fail()
        }
    }

UseAssertEqualsInsteadOfAssertTrue Rule

Since CodeNarc 0.11

This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

UseAssertFalseInsteadOfNegation Rule

Since CodeNarc 0.12

In unit tests, if a condition is expected to be false then there is no sense using assertTrue with the negation operator. For instance, assertTrue(!condition) can always be simplified to assertFalse(condition).

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

UseAssertTrueInsteadOfAssertEqualsRule Rule

Since CodeNarc 0.11

This rule detects JUnit calling assertEquals where the first parameter is a boolean. These assertions should be made by more specific methods, like assertTrue or assertFalse.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

Property Description Default Value
checkAssertStatements If true, then also check assert statements, e.g. assert x == true. false

All of the following examples can be simplified to assertTrue or remove the true literal:

    assertEquals(true, foo())
    assertEquals("message", true, foo())
    assertEquals(foo(), true)
    assertEquals("message", foo(), true)
    assertEquals(false, foo())
    assertEquals("message", false, foo())
    assertEquals(foo(), false)
    assertEquals("message", foo(), false)

    assert true == foo()                    // violation only if checkAssertStatements == true
    assert foo() == true : "message"        // violation only if checkAssertStatements == true
    assert false == foo()                   // violation only if checkAssertStatements == true
    assert foo() == false : "message"       // violation only if checkAssertStatements == true

UseAssertTrueInsteadOfNegation Rule

Since CodeNarc 0.12

In unit tests, if a condition is expected to be true then there is no sense using assertFalse with the negation operator. For instance, assertFalse(!condition) can always be simplified to assertTrue(condition).

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

UseAssertNullInsteadOfAssertEquals Rule

Since CodeNarc 0.11

This rule detects JUnit calling assertEquals where the first or second parameter is null. These assertion should be made against the assertNull method instead.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.

UseAssertSameInsteadOfAssertTrue Rule

Since CodeNarc 0.11

This rule detects JUnit calling assertTrue or assertFalse where the first or second parameter is an Object#is() call testing for reference equality. These assertion should be made against the assertSame or assertNotSame method instead.

This rule sets the default value of the applyToClassNames property to only match class names ending in 'Test', 'Tests' or 'TestCase'.


CodeNarc-0.23/docs/codenarc-configuring-rules.html0000644000175000017500000007424312471222400021504 0ustar ebourgebourg CodeNarc - CodeNarc - Configuring Rules

CodeNarc - Configuring Rules

Contents

You can configure rules within the RuleSet file or within the "codenarc.properties" file. Both of these approaches are described in the sections below.

NOTE: Keep in mind that RuleSet files can be nested (to any depth). That, along with the "codenarc.properties" file support, allows multiple layers of rule configuration. The hierarchical layering of configuration can come in handy within organizations comprised of multiple teams or projects. For instance, you can define an organization RuleSet file. Then each team can define its own RuleSet file and/or a "codenarc.properties" file, customizing the rules from the top-level file.

Configuring Rules Within a RuleSet File

Creating a RuleSet describes how to create a new RuleSet and configure the rules within it.

Here is an example of a Groovy RuleSet file that configures all three rules that it contains:

ruleset {
    CyclomaticComplexity {
        maxMethodComplexity = 1
    }

    ConfusingTernary(priority:3)

    StatelessClass {
        name = 'StatelessDao'
        applyToClassNames = '*Dao'
    }
}

Here is another example of a Groovy RuleSet file. This one includes another RuleSet, and configures a couple of the rules that it contains:

ruleset {
    ruleset('rulesets/basic.xml') {
        CatchThrowable {
            priority = 1
        }
        EqualsAndHashCode priority:3
    }
}

If you have an XML RuleSet, then you can configure rules when you include a whole RuleSet using <ruleset-ref>, as in the following example:

    <ruleset-ref path='rulesets/size.xml'>
        <rule-config name='ClassSize'>
            <property name='maxLines' value='500'/>
        </rule-config>
    </ruleset-ref>

Or you can configure Rules that you include individually using <rule>, as in the following example:

    <rule class='org.codenarc.rule.naming.VariableNameRule'>
        <property name="finalRegex" value="F_[A-Z0-9]*"/>
        <property name='priority' value='1'/>
    </rule>

Configuring Rules Using a Properties File

CodeNarc reads the properties file named "codenarc.properties", if found on the classpath, and applies the property values to any matching Rules. You can optionally override the location of the properties file by setting the "codenarc.properties.file" system property to the path or URL of the properties file. That can include a "file:" URL to load from a relative or absolute path on the filesystem (e.g., "file:relative/path/override-codenarc.properties"). If the properties file is not found, then do nothing.

For each properties entry of the form [rule-name].[property-name]=[property-value], the named property for the rule matching rule-name is set to the specified property-value. Properties entries not of this form or specifying rule names not within the current RuleSet are ignored.

The following example "codenarc.properties" file configures several rules. Note that Fields with Integer, String and Boolean values are configured.

# Sample RuleSet configuration
# Entries should be of the form:    [rule-name].[property-name]=[property-value]

CatchThrowable.doNotApplyToClassNames=BaseController,AbstractTest
CatchThrowable.priority = 1

ReturnFromFinallyBlock.priority = 1

# Turn off this rule
AbstractClassName.enabled=false

# Unset special naming for final fields -- use base 'regex' value for all names
FieldName.finalRegex=
# Make sure all field names are prefixed with '_'
FieldName.regex=_[a-z][a-zA-Z0-9]*

Note that you cannot add new rules using the "codenarc.properties" file, though you can disable (turn off) rules.

Standard Properties for Configuring Rules

The rules included with CodeNarc (as well as any subclasses of AbstractRule) provide several standard properties that can be used to configure how rules are applied to source files.

Applying Rules Based on Class Name and/or Package Name

The applyToClassNames and doNotApplyToClassNames properties enable filtering the classes to which the rule is applied.

If applyToClassNames is not empty or null, then the rule is only applied to classes matching one of the specified class names. Likewise, if doNotApplyToClassNames is not empty or null, then the rule is NOT applied to classes matching any of the specified class names.

Both of these properties can specify either a single class name or a comma-separated list of names. The names may optionally contain wildcard characters ('*' or '?'). The wildcard character '*' matches a sequence of zero or more characters in the input string. The wildcard character '?' matches exactly one character in the input string.

Each class name(s) can be either a fully-qualified class name (including the package) or else a class name without a package.

For instance, in the following example "codenarc.properties" excerpt, the CatchThrowable rule is NOT applied to classes named "BaseController" or "AbstractTest", no matter what package they are in (if any). The FieldName rule, on the other hand, is only applied to the org.codenarc.CodeNarc class or any of the classes within org.codenarc.extra package.

CatchThrowable.doNotApplyToClassNames=BaseController,AbstractTest

FieldName.applyToClassNames=org.codenarc.CodeNarc,org.codenarc.extra.*

Both properties default to null.

These properties are available only to subclasses of AbstractAstVisitorRule, but this includes almost all of the rules provided with CodeNarc -- i.e., all of the rules that deal with the Groovy AST (Abstract Syntax Tree) of a source file. This includes any rule that processes source code elements such as a package, class, method, field, parameter, etc..

Applying Rules Based on File Path or Name

Matching Either Filename or Pathname, With Optional Wildcards

The applyToFileNames and doNotApplyToFileNames properties enable filtering the files to which the rule is applied by specifying a comma-separated list of filenames (with optional path) of source files. If applyToFileNames is not empty or null, then the rule is only applied to source files matching one of the specified filenames. Likewise, if doNotApplyToFilesMatching is not empty or null, then the rule is NOT applied to source files matching any of the specified filenames.

Both properties may optionally specify a path (i.e., if the value contains at least one '/' path separator). In that case, the value is matched against the full pathname of each source file. If no path is specified, then only the filename of each source file is compared (i.e., its path is ignored).

Both properties may optionally contain wildcard characters ('*' or '?'). The wildcard character '*' matches a sequence of zero or more characters in the input string. The wildcard character '?' matches exactly one character in the input string. Both properties default to null.

Matching File Pathnames Against a Regular Expression

The applyToFilesMatching and doNotApplyToFilesMatching properties enable filtering the files to which the rule is applied by matching a regular expression against the full pathname of each source file. If applyToFilesMatching is not empty or null, then the rule is only applied to source files with matching paths. Likewise, if doNotApplyToFilesMatching is not empty or null, then the rule is NOT applied to source files with matching paths. Both properties default to null.

  • NOTE: File separator characters within pathnames are normalized to forward slashes (/). On Windows, for instance, that means that the path "c:\dir\file.txt" is normalized to "c:/dir/file.txt". If your regular expressions contain file separator characters, be sure that they are all the standard '/', no matter what operating system.

Other Standard Rule Properties

The enabled boolean property allows a rule to be completely turned off (by setting it to false). It defaults to true.

The violationMessage property enables overriding the rule violation message. If not null, this is used as the message for all violations of this rule, overriding any message generated by the rule itself. This property defaults to null. Note that setting this to an empty string "hides" the message, if any, generated by the actual rule.

The description property enables overriding the rule description text. If not null, this value is used as the description text for this rule, overriding any description text found in the i18n resource bundles. This property defaults to null. Also see Include Substitutable Message Parameters in a Rule Description

You can also override the default name or priority properties for each rule.

Turning Off A Rule

You can turn off a rule by filtering the containing ruleset to exclude the rule. See Filtering Rules Within a RuleSet.

Alternately, as mentioned above, you can turn off (disable) a rule by setting its enabled boolean property to false (assuming it is a subclass of AbstractRule), as shown in the following "codenarc.properties" excerpt.

# Turn off this rule
AbstractClassName.enabled=false

And here is an example of disabling a rule within a Groovy RuleSet by setting its enabled attribute to false.

ruleset {
    ruleset('rulesets/basic.xml') {
        CatchThrowable(enabled:false)
    }
}

Suppressing A Rule From Within Source Code

You can use the @SuppressWarnings annotation on a class, method, constructor, field or property to suppress one or more CodeNarc rules within its source code.

Specify one or more rule name as the parameter of the @SuppressWarnings annotation. Note that this is the rule name, not the class name (i.e., without the "Rule" suffix). Specify multiple rule names by passing a List of rule names as a single parameter, e.g. @SuppressWarnings(['IfStatementBraces', 'ThrowException'])

NOTE: The @SuppressWarnings annotation only works for rule classes that subclass AbstractAstVisitorRule.

For example, the following code suppresses (prevents) violations of the DuplicateStringLiteral rule within the MyClass class, as well as suppressing the IfStatementBraces and ThrowException rules within its getCount() method.

    @SuppressWarnings('DuplicateStringLiteral')
    class MyClass {
        def y = 'x'
        def z = 'x'

        @SuppressWarnings(['IfStatementBraces', 'ThrowException'])
        int getCount() {
            if (!ready) throw new Exception('Not ready')
        }
    }

Customizing Rule Descriptions Shown in the HTML Report

The descriptions for rules used in a CodeNarc report are shown at the bottom of the resulting HTML report. Those rule descriptions are retrieved from a ResourceBundle. This ResourceBundle consists of a base (parent) bundle, provided with the CodeNarc distribution, and an optional custom (child) bundle, which may be provided by the user.

Because this is based on the standard Java ResourceBundle facility, you can customize (override) or translate these descriptions by providing your own locale-specific message properties file on the classpath. For example, a German one would be named "codenarc-messages_de.properties".

The rule description message key is of the form "<rule-name>.description.html". Examples include "BooleanInstantiation.description.html" and "CatchThrowable.description.html".

(Note that the rule description included in the XML report is specified by the key <rule-name>.description).

See the javadoc for the java.util.ResourceBundle class for more information.

Include Substitutable Message Parameters in a Rule Description

You can optionally include message parameters within a rule description, whether that description is specified in a ResourceBundle properties file or through the description property of the rule. Use the standard Groovy template parameter syntax: ${..}. You can reference rule property values through the "rule" object within the template parameter closure. For example, this description includes the rule priority within the rule description: "Description for rule with priority ${rule.priority}".

The Base Messages Resource Bundle

The base ResourceBundle provided with the CodeNarc distribution has a basename of "codenarc-base-messages". The rules provided with CodeNarc all have associated descriptions within the "codenarc-base-messages.properties" file.

You can provide a locale-specific variant of this file on the classpath if you wish, but in most scenarios, the recommended approach for customizing rule descriptions is to provide a custom messages bundle file, as described below.

The Custom Messages Resource Bundle

You can optionally provide descriptions for new rules or override existing rule descriptions by placing a "codenarc-messages.properties" file on the classpath. This is also a ResourceBundle file, so it can have locale-specific variants, if needed. If this bundle (file) is present, it is searched first. If the desired message key is not found, only then is the base message bundle checked.

You can provide rule description entries within this file for custom rules that you create. You can also include rule description entries for existing rules, in which case the descriptions in this file override the default descriptions.

Customizing the Name and Description for an Existing Rule

You may wish to customize both the name and the description for an existing rule. For example, you may want to have multiple instances of a generic rule, each configured differently. Or you may just want to make the rule name more clearly denote its specific purpose.

For example, in the following excerpt from a RuleSet file, because the name property is customized for the IllegalRegexRule, the new rule name "AuthorTagNotAllowed" will show up at the bottom of the HTML report, instead of the default rule name "IllegalRegex".

    <rule class='org.codenarc.rule.generic.IllegalRegexRule'>
        <property name="name" value="AuthorTagNotAllowed"/>
        <property name='regex' value='\@author'/>
    </rule>

The rule description must be added to the custom messages resource bundle file ("codenarc-messages.properties"). The message key will be "AuthorTagNotAllowed.description.html" to set the description used in the HTML report, and "AuthorTagNotAllowed.description" for the description used in the XML report.


CodeNarc-0.23/docs/codenarc-rules-generic.html0000644000175000017500000007770312471222413020616 0ustar ebourgebourg CodeNarc - CodeNarc - Generic Rules

Generic Rules ("rulesets/generic.xml")

These rules provide a generic check that only makes sense when customized. These rules are not enabled until the necessary configuration is provided.

See CodeNarc – Hidden Gems: Using CodeNarc’s generic rules for examples of using the CodeNarc "generic" rules to enforce your own custom best practices.

IllegalClassMember Rule

Since CodeNarc 0.19

Checks for classes containing fields/properties/methods matching configured illegal member modifiers or not matching any of the configured allowed member modifiers.

Property Description Default Value
allowedFieldModifiers Specifies one or more groups of whitespace-delimited modifier names (e.g. "public static" or "protected"). Multiple groups are separated by commas (e.g. "private final, protected"). If a field does not match all of the modifiers in any group, then trigger a violation. If null or empty, skip this check. null
allowedMethodModifiers Specifies one or more groups of whitespace-delimited modifier names (e.g. "public static" or "protected"). Multiple groups are separated by commas (e.g. "private final, protected"). If a method does not match all of the modifiers in any group, then trigger a violation. If null or empty, skip this check. null
allowedPropertyModifiers Specifies one or more groups of whitespace-delimited modifier names (e.g. "public static" or "protected"). Multiple groups are separated by commas (e.g. "private final, protected"). If a property does not match all of the modifiers in any group, then trigger a violation. If null or empty, skip this check. null
ignoreMethodNames Specifies one or more (comma-separated) method names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null
ignoreMethodsWith- AnnotationNames Specifies one or more (comma-separated) annotation names that should be ignored (i.e., methods with those annotations should not cause a rule violation). The names may optionally contain wildcards (*,?). (Do not include the "@" in the annotation name. null
illegalFieldModifiers Specifies one or more groups of whitespace-delimited modifier names (e.g. "public static" or "protected"). Multiple groups are separated by commas (e.g. "private final, protected"). If a field matches all of the modifiers in any group, then trigger a violation. If null or empty, skip this check. null
illegalMethodModifiers Specifies one or more groups of whitespace-delimited modifier names (e.g. "public static" or "protected"). Multiple groups are separated by commas (e.g. "private final, protected"). If a method matches all of the modifiers in any group, then trigger a violation. If null or empty, skip this check. null
illegalPropertyModifiers Specifies one or more groups of whitespace-delimited modifier names (e.g. "public static" or "protected"). Multiple groups are separated by commas (e.g. "private final, protected"). If a property matches all of the modifiers in any group, then trigger a violation. If null or empty, skip this check. null

Modifiers for fields and methods include:

  • public
  • protected
  • private
  • static
  • final
  • volatile (fields only)
  • transient (fields only)

Modifiers for properties are only:

  • static
  • final

Note that you must use the standard rule properties, such as applyToClassNames, doNotApplyToFileNames and applyToFilesMatching to apply this rule to a subset of all classes/files. These rule properties are described in Standard Properties for Configuring Rules.

Example of violations for methods:

    // IllegalClassMember.allowedMethodModifiers = 'public final, private, protected static'

    class MyClass {
        public method1() { }            // violation
        protected method2() { }         // violation
        protected static method3() { }
    }

Example of violations for properties:

    // IllegalClassMember.illegalPropertyModifiers = 'final'

    class MyClass {
        def property1
        final property2         // violation
        static property3
    }

A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule name and classNames, and (optionally) customized violationMessage and priority.

Notes

  1. At least one the illegalFieldModifiers, allowedFieldModifiers, illegalPropertyModifiers, allowedPropertyModifiers, illegalMethodModifiers or allowedMethodModifiers properties must be set (i.e., not null or empty) or else this rule does nothing. In other words, you must configure this rule with at least one kind of illegal or allowed class member.
  2. At least one of the (standard) applyToClassNames, applyToFileNames or applyToFilesMatching properties must be set (i.e., not null or empty) or else this rule does nothing. In other words, you must configure this rule to apply to a specific set of classes or files.

IllegalClassReference Rule

Since CodeNarc 0.15

Checks for reference to any of the classes configured in classNames.

Property Description Default Value
classNames Specifies the comma-separated list of (fully-qualified) class names. The class name(s) may optionally include wildcard characters ('*' or '?'). Note that the '*' wildcard matches any sequence of zero or more characters in the class/package name, e.g. 'a.*.MyClass' matches a.b.MyClass as well as a.b.c.d.MyClass. If classNames is null or empty, do nothing. null

Note that you can use the standard rule properties, such as applyToClassNames, doNotApplyToFileNames and applyToFilesMatching to only apply this rule to a subset of all classes/files. These rule properties are described in Standard Properties for Configuring Rules.

This rule can be useful for governance and enforcement of architectural layering. For instance, making sure that view or model classes, for instance, do not contain references to DAO classes (e.g., *Dao).

Here is an example configuration of this rule used to ensure that DAO classes are not referenced from within model classes:

    ruleset {
        description "Example CodeNarc Ruleset"

        // ...

        IllegalClassReference {
            name = 'DoNotReferenceDaoFromModelClasses'
            priority = 2
            classNames = '*Dao'
            applyToClassNames = 'com.example.model.*'
            description = 'Do not reference DAOs from model classes.'
        }
    }

A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule name and classNames, and (optionally) customized violationMessage and priority.

IllegalPackageReference Rule

Since CodeNarc 0.14

Checks for reference to any of the packages configured in packageNames.

Property Description Default Value
packageNames Specifies the comma-separated list of package names. The package name(s) may optionally include wildcard characters ('*' or '?'). Note that the '*' wildcard matches any sequence of zero or more characters in the package name, e.g. 'a.*' matches 'a.b' as well as 'a.b.c.d'. If packageNames is null or empty, do nothing. null

Note that you can use the standard rule properties, such as applyToClassNames, doNotApplyToFileNames and applyToFilesMatching to only apply this rule to a subset of all classes/files. These rule properties are described in Standard Properties for Configuring Rules.

This rule can be useful for governance and enforcement of architectural layering. For instance, making sure that view or model classes, for instance, do not contain references to JDBC-specific packages (e.g. java.sql and javax.sql).

Here is an example configuration of this rule used to ensure that JDBC packages/classes are only referenced within DAO classes:

    ruleset {
        description "Example CodeNarc Ruleset"

        // ...

        IllegalPackageReference {
            name = 'UseJdbcOnlyInDaoClasses'
            priority = 2
            packageNames = 'groovy.sql, java.sql, javax.sql'
            doNotApplyToClassNames = 'com.example.framework.dao.*, *Dao, *DaoImpl'
            description = 'Reference to JDBC packages should be restricted to DAO classes.'
        }
    }

A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule name and packageNames, and (optionally) customized violationMessage and priority.

IllegalRegex Rule

Checks for a specified illegal regular expression within the source code.

Property Description Default Value
regex The regular expression to check for. If null or empty then do nothing. null

A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule name and regex, and (optionally) customized violationMessage and priority.

NOTE: This rule applies to the text contents of an entire file rather than a specific class, so it does not support the applyToClassNames and doNotApplyToClassNames configuration properties.

IllegalString Rule

Since CodeNarc 0.20

Checks for a specified illegal string within the source code.

Property Description Default Value
string The String to check for. If null or empty then do nothing. null

A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule name and string, and (optionally) customized violationMessage and priority.

NOTE: This rule applies to the text contents of an entire file rather than a specific class, so it does not support the applyToClassNames and doNotApplyToClassNames configuration properties.

IllegalSubclass Rule

Since CodeNarc 0.21

Checks for classes that extend one of the specified set of illegal superclasses.

Property Description Default Value
superclassNames Specifies the comma-separated list of (fully-qualified) class names. The class name(s) may optionally include wildcard characters ('*' or '?'). Note that the '*' wildcard matches any sequence of zero or more characters in the class/package name, e.g. 'a.*.MyClass' matches a.b.MyClass as well as a.b.c.d.MyClass. If classNames is null or empty, do nothing. null

A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule name and string, and (optionally) customized violationMessage and priority.

RequiredRegex Rule

Checks for a specified regular expression that must exist within the source code.

Property Description Default Value
regex The regular expression to check for. If null or empty then do nothing. null

A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule name and regex, and (optionally) customized violationMessage and priority.

NOTE: This rule applies to the text contents of an entire file rather than a specific class, so it does not support the applyToClassNames and doNotApplyToClassNames configuration properties.

RequiredString Rule

Checks for a specified text string that must exist within the source code.

Property Description Default Value
string The String to check for. If null or empty then do nothing. null

A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule name and string, and (optionally) customized violationMessage and priority.

NOTE: This rule applies to the text contents of an entire file rather than a specific class, so it does not support the applyToClassNames and doNotApplyToClassNames configuration properties.

StatelessClass Rule

Checks for non-final fields on a class. The intent of this rule is to check a configured set of classes that should remain "stateless" and reentrant. One example might be Grails service classes which are singletons, by default, and so they should be reentrant.

This rule ignores final fields (either instance or static). Fields that are static and non-final, however, do cause a violation.

This rule also ignores all classes annotated with the @Immutable transformation. See http://groovy.codehaus.org/Immutable+transformation.

This rule also ignores all fields annotated with the @Inject annotation.

You can configure this rule to ignore certain fields either by name or by type. This can be useful to ignore fields that hold references to (static) dependencies (such as DAOs or Service objects) or static configuration.

Property Description Default Value
ignoreFieldNames Specifies one or more (comma-separated) field names that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null
addToIgnoreFieldNames Specifies one or more (comma-separated) field names to be added to the ignoreFieldNames property value. This is a special write-only property, and each call to setAddIgnoreFieldNames() adds to (rather than overwrites) the list of field names to be ignored. null
ignoreFieldTypes Specifies one or more (comma-separated) field types that should be ignored (i.e., that should not cause a rule violation). The names may optionally contain wildcards (*,?). null

Note that you can use the standard rule properties, such as applyToClassNames, doNotApplyToFileNames and applyToFilesMatching to only apply this rule to a subset of all classes/files. These rule properties are described in Standard Properties for Configuring Rules.

Notes

  1. The ignoreFieldTypes property matches the field type name as indicated in the field declaration, only including a full package specification IF it is included in the source code. For example, the field declaration BigDecimal value matches an ignoreFieldTypes value of BigDecimal, but not java.lang.BigDecimal.
  2. There is one exception for the ignoreFieldTypes property: if the field is declared with a modifier/type of def, then the type resolves to java.lang.Object.
  3. At least one of the (standard) applyToClassNames, applyToFileNames or applyToFilesMatching properties must be set (i.e., not null or empty) or else this rule does nothing. In other words, you must configure this rule to apply to a specific set of classes or files.
  4. This rule will not catch violations of true statelessness/reentrancy if you define a final field whose value is itself mutable, e.g. a final HashMap.

CodeNarc-0.23/docs/codenarc-ant-task.html0000644000175000017500000004166312471222377017601 0ustar ebourgebourg CodeNarc - CodeNarc Ant Task

CodeNarc - Ant Task

Description

The CodeNarc Ant Task is implemented by the org.codenarc.ant.CodeNarcTask class.

Parameters

Attribute Description Required
ruleSetFiles The paths to the Groovy or XML RuleSet definition files. This can be a single file path, or multiple paths separated by commas. By default, the paths specified are relative to the classpath. But each path may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute filesystem path), or "http:". YES
maxPriority1Violations The maximum number of priority 1 violations allowed before failing the build (throwing a BuildException). NO
maxPriority2Violations The maximum number of priority 2 violations allowed before failing the build (throwing a BuildException). NO
maxPriority3Violations The maximum number of priority 3 violations allowed before failing the build (throwing a BuildException). NO

Report Nested Element

The report nested element defines the format and output file for the analysis report.

Attribute Description Required
type The type of the output report. Must be either one of the predefined type names: "html", "xml", "text", "console", "ide" or else the fully-qualified class name of a class (accessible on the classpath) that implements the org.codenarc.report.ReportWriter interface. Yes
toFile (Deprecated) The path and filename for the output report file. This is deprecated. Use the <option> nested element instead. No
title (Deprecated) The title for the output report. This is deprecated. Use the <option> nested element instead. No

Notes:

  • The "ide" report type creates an IdeTextReportWriter and sets its writeToStandardOut property to true. The generated report includes IDE-compatible (Eclipse, Idea) hyperlinks to source code for violations.
  • The "console" report type creates a TextReportWriter and sets its writeToStandardOut property to true.

Option Nested Element

The <option> element is a child of the <report> element and defines a report-specific option for a report. You specify the option name> and <<value as attributes within the <option> element. See the Example below.

Fileset Nested Element

At least one fileset nested element is required, and is used to specify the source files that CodeNarc should analyze. This is the standard Ant FileSet, and is quite powerful and flexible. See the Apache Ant Manual for more information on FileSets.

Example

Here is an example Ant XML build file.

<taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/>
<target name="runCodeNarc">
    <codenarc
            ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml"
            maxPriority1Violations="0">

        <report type="html">
            <option name="outputFile" value="reports/CodeNarcAntReport.html" />
            <option name="title" value="My Sample Code" />
        </report>

        <fileset dir="src">
            <include name="**/*.groovy"/>
        </fileset>
    </codenarc>
</target>

Things to note:

  • Three RuleSet files are specified (basic, exceptions and imports).
  • The fileset specifies that all ".groovy" files are analyzed.
  • Remember that you need the log4j jar (and a "log4j.properties" file) on the classpath.

Logging and Troubleshooting

Be sure to have a "log4j.properties" or "log4j.xml" file on the classpath so that any errors are logged.


CodeNarc-0.23/docs/cpd.html0000644000175000017500000005345612471222450015044 0ustar ebourgebourg CodeNarc - CPD Results

CPD Results

The following document contains the results of PMD's CPD 5.1.2.

Duplications

File Line
org\codenarc\rule\AbstractFieldVisitor.java 110
org\codenarc\rule\AbstractMethodVisitor.java 138
    }

    @Override
    protected final void visitObjectInitializerStatements(ClassNode node) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected final SourceUnit getSourceUnit() {
        throw new RuntimeException("should never be called");
    }

    @Override
    public final void visitPackage(PackageNode node) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitImports(ModuleNode node) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitAnnotations(AnnotatedNode node) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected final void visitClassCodeContainer(Statement code) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitVariableExpression(VariableExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected final void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitConstructor(ConstructorNode node) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitProperty(PropertyNode node) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected final void addError(String msg, ASTNode expr) {
        super.addError(msg, expr);
    }

    @Override
    protected final void visitStatement(Statement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitAssertStatement(AssertStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitBlockStatement(BlockStatement block) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitBreakStatement(BreakStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitCaseStatement(CaseStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitCatchStatement(CatchStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitContinueStatement(ContinueStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitDoWhileLoop(DoWhileStatement loop) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitExpressionStatement(ExpressionStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitForLoop(ForStatement forLoop) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitIfElse(IfStatement ifElse) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitReturnStatement(ReturnStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitSwitch(SwitchStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitSynchronizedStatement(SynchronizedStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitThrowStatement(ThrowStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitTryCatchFinally(TryCatchStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitWhileLoop(WhileStatement loop) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected final void visitEmptyStatement(EmptyStatement statement) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitMethodCallExpression(MethodCallExpression call) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitStaticMethodCallExpression(StaticMethodCallExpression call) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitConstructorCallExpression(ConstructorCallExpression call) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitBinaryExpression(BinaryExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitTernaryExpression(TernaryExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitShortTernaryExpression(ElvisOperatorExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitPostfixExpression(PostfixExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitPrefixExpression(PrefixExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitBooleanExpression(BooleanExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitNotExpression(NotExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitClosureExpression(ClosureExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitTupleExpression(TupleExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitListExpression(ListExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitArrayExpression(ArrayExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitMapExpression(MapExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitMapEntryExpression(MapEntryExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitRangeExpression(RangeExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitSpreadExpression(SpreadExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitSpreadMapExpression(SpreadMapExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitMethodPointerExpression(MethodPointerExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitUnaryMinusExpression(UnaryMinusExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitUnaryPlusExpression(UnaryPlusExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitBitwiseNegationExpression(BitwiseNegationExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitCastExpression(CastExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitConstantExpression(ConstantExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitClassExpression(ClassExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitDeclarationExpression(DeclarationExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitPropertyExpression(PropertyExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitAttributeExpression(AttributeExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitFieldExpression(FieldExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitGStringExpression(GStringExpression expression) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected final void visitListOfExpressions(List<? extends Expression> list) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitArgumentlistExpression(ArgumentListExpression ale) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitClosureListExpression(ClosureListExpression cle) {
        throw new UnsupportedOperationException();
    }

    @Override
    public final void visitBytecodeExpression(BytecodeExpression cle) {
        throw new UnsupportedOperationException();
    }
    @Override
    public final void visitMethod(MethodNode node) {

CodeNarc-0.23/docs/codenarc-other-tools-frameworks.html0000644000175000017500000003504412471222404022477 0ustar ebourgebourg CodeNarc - CodeNarc - Integration with Other Tools / Frameworks

CodeNarc - Integration with Other Tools / Frameworks

Application Frameworks

Build and Code Quality Tools

Customizing ClassLoader for Loading Rule Scripts

Grails (and possibly other tools integrating with CodeNarc) can benefit from using the current thread context ClassLoader for loading rule script files, rather than the default base ClassLoader. Setting the "codenarc.useCurrentThreadContextClassLoader" system property to "true" uses the current thread context ClassLoader for loading rule script files. That enables Grails to load rule script files from within the Grails project, and allows those rule scripts to reference local classes. See GPCODENARC-32. The Grails CodeNarc Plugin automatically sets that system property.


CodeNarc-0.23/docs/codenarc-rules-jdbc.html0000644000175000017500000003545112471222414020077 0ustar ebourgebourg CodeNarc - CodeNarc - JDBC Rules

JDBC Rules ("rulesets/jdbc.xml")

DirectConnectionManagement Rule

New in CodeNarc 0.14

The J2EE standard requires that applications use the container's resource management facilities to obtain connections to resources. Every major web application container provides pooled database connection management as part of its resource management framework. Duplicating this functionality in an application is difficult and error prone, which is part of the reason it is forbidden under the J2EE standard.

For more information see: https://www.fortify.com/vulncat/en/vulncat/java/j2ee_badpractices_getconnection.html

Example of violations:

    DriverManager.getConnection()
    java.sql.DriverManager.getConnection()

JdbcConnectionReference Rule

New in CodeNarc 0.15

Checks for direct use of java.sql.Connection, which is discouraged and almost never necessary in application code.

For a more Groovy alternative, see http://groovy.codehaus.org/Database+features for information on the Groovy Sql abstraction layer for JDBC/SQL.

Note: If a violation is triggered from an import statement, then you may get multiple violations per import if there are multiple classes in the source file. In that case, the imports are processed once per class.

JdbcResultSetReference Rule

New in CodeNarc 0.15

Checks for direct use of java.sql.ResultSet, which is not necessary if using the Groovy Sql facility or an ORM framework such as Hibernate.

See http://groovy.codehaus.org/Database+features for information on the Groovy Sql abstraction layer for JDBC/SQL.

Note: If a violation is triggered from an import statement, then you may get multiple violations per import if there are multiple classes in the source file. In that case, the imports are processed once per class.

JdbcStatementReference Rule

New in CodeNarc 0.15

Checks for direct use of java.sql.Statement, java.sql.PreparedStatement, or java.sql.CallableStatement, which is not necessary if using the Groovy Sql facility or an ORM framework such as Hibernate.

See http://groovy.codehaus.org/Database+features for information on the Groovy Sql abstraction layer for JDBC/SQL.

Note: If a violation is triggered from an import statement, then you may get multiple violations per import if there are multiple classes in the source file. In that case, the imports are processed once per class.


CodeNarc-0.23/docs/codenarc-rules-logging.html0000644000175000017500000004272012471222415020621 0ustar ebourgebourg CodeNarc - CodeNarc - Logging Rules

Logging Rules ("rulesets/logging.xml")

LoggerForDifferentClass Rule

Since CodeNarc 0.12

Checks for instantiating a logger for a class other than the current class. Checks for logger instantiations for Log4J, SLF4J, Logback, Apache Commons Logging and Java Logging API (java.util.logging).

This rule contains a parameter allowDerivedClasses. When set, a logger may be created about this.getClass().

Limitations:

  • Only checks Loggers instantiated within a class field or property (not variables or expressions within a method)
  • For Log4J: Does not catch Logger instantiations if you specify the full package name for the Logger class: e.g. org.apache.log4.Logger.getLogger(..)
  • For SLF4J and Logback: Does not catch Log instantiations if you specify the full package name for the LoggerFactory class: e.g. org.slf4j.LoggerFactory.getLogger(..)
  • For Commons Logging: Does not catch Log instantiations if you specify the full package name for the LogFactory class: e.g. org.apache.commons.logging.LogFactory.getLog(..)
  • For Java Logging API: Does not catch Logger instantiations if you specify the full package name for the Logger class: e.g. java.util.logging.Logger.getLogger(..)

Here are examples of Log4J or Java Logging API code that cause violations:

    class MyClass {
        private static final LOG = Logger.getLogger(SomeOtherClass)  // violation
        def log1 = Logger.getLogger(SomeOtherClass.class)            // violation
        def log2 = Logger.getLogger(SomeOtherClass.class.name)       // violation
    }

Here are examples of Commons Logging code that cause violations:

    class MyClass {
        private static final LOG = LogFactory.getLog(SomeOtherClass)    // violation
        Log log1 = LogFactory.getLog(SomeOtherClass.class)              // violation
        def log2 = LogFactory.getLog(SomeOtherClass.class.getName())    // violation
    }

Here are examples of code that does NOT cause violations:

    // Log4J or Java Logging API

    class MyClass {
        private static final LOG = Logger.getLogger(MyClass)                    // ok
        def log2 = Logger.getLogger(MyClass.class)                              // ok
        private static log3 = Logger.getLogger(MyClass.getClass().getName())    // ok
        private static log4 = Logger.getLogger(MyClass.getClass().name)         // ok
        private static log5 = Logger.getLogger(MyClass.class.getName())         // ok
        private static log6 = Logger.getLogger(MyClass.class.name)              // ok
    }

    // Commons Logging

    class MyClass {
        private static final LOG = LogFactory.getLog(MyClass)                   // ok
        def log2 = LogFactory.getLog(MyClass.class)                             // ok
        private static log3 = LogFactory.getLog(MyClass.getClass().getName())   // ok
        private static log4 = LogFactory.getLog(MyClass.getClass().name)        // ok
        private static log5 = LogFactory.getLog(MyClass.class.getName())        // ok
        private static log6 = LogFactory.getLog(MyClass.class.name)             // ok
    }

LoggingSwallowsStacktrace Rule

Since CodeNarc 0.12

If you are logging an exception then the proper API is to call error(Object, Throwable), which will log the message and the exception stack trace. If you call error(Object) then the stacktrace may not be logged.

LoggerWithWrongModifiers Rule

Since CodeNarc 0.12

Logger objects should be declared private, static and final.

This rule has a property: allowProtectedLogger, which defaults to false. Set it to true if you believe subclasses should have access to a Logger in a parent class and that Logger should be declared protected or public.

This rule has a property: allowNonStaticLogger, which defaults to false. Set it to true if you believe a logger should be allowed to be non-static.

MultipleLoggers Rule

Since CodeNarc 0.12

This rule catches classes that have more than one logger object defined. Typically, a class has zero or one logger objects.

Println Rule

Checks for calls to this.print(), this.println() or this.printf(). Consider using a standard logging facility instead.

PrintStackTrace Rule

Checks for calls to Throwable.printStackTrace() or StackTraceUtils.printSanitizedStackTrace(Throwable). Consider using a standard logging facility instead.

SystemErrPrint Rule

Checks for calls to System.err.print(), System.err.println() or System.err.printf(). Consider using a standard logging facility instead.

SystemOutPrint Rule

Checks for calls to System.out.print(), System.out.println() or System.out.printf(). Consider using a standard logging facility instead.


CodeNarc-0.23/docs/css/0000755000175000017500000000000012623571301014164 5ustar ebourgebourgCodeNarc-0.23/docs/css/maven-theme.css0000644000175000017500000000536112471222451017111 0ustar ebourgebourgbody { padding: 0px 0px 10px 0px; } body, td, select, input, li{ font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 13px; } code{ font-family: Courier, monospace; font-size: 13px; } a { text-decoration: none; } a:link { color:#36a; } a:visited { color:#47a; } a:active, a:hover { color:#69c; } #legend li.externalLink { background: url(../images/external.png) left top no-repeat; padding-left: 18px; } a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover { background: url(../images/external.png) right center no-repeat; padding-right: 18px; } #legend li.newWindow { background: url(../images/newwindow.png) left top no-repeat; padding-left: 18px; } a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover { background: url(../images/newwindow.png) right center no-repeat; padding-right: 18px; } h2 { padding: 4px 4px 4px 6px; border: 1px solid #999; color: #900; background-color: #ddd; font-weight:900; font-size: x-large; } h3 { padding: 4px 4px 4px 6px; border: 1px solid #aaa; color: #900; background-color: #eee; font-weight: normal; font-size: large; } h4 { padding: 4px 4px 4px 6px; border: 1px solid #bbb; color: #900; background-color: #fff; font-weight: normal; font-size: large; } h5 { padding: 4px 4px 4px 6px; color: #900; font-size: normal; } p { line-height: 1.3em; font-size: small; } #breadcrumbs { border-top: 1px solid #aaa; border-bottom: 1px solid #aaa; background-color: #ccc; } #leftColumn { margin: 10px 0 0 5px; border: 1px solid #999; background-color: #eee; } #navcolumn h5 { font-size: smaller; border-bottom: 1px solid #aaaaaa; padding-top: 2px; color: #000; } table.bodyTable th { color: white; background-color: #bbb; text-align: left; font-weight: bold; } table.bodyTable th, table.bodyTable td { font-size: 1em; } table.bodyTable tr.a { background-color: #ddd; } table.bodyTable tr.b { background-color: #eee; } .source { border: 1px solid #999; } dl { padding: 4px 4px 4px 6px; border: 1px solid #aaa; background-color: #ffc; } dt { color: #900; } #organizationLogo img, #projectLogo img, #projectLogo span{ margin: 8px; } #banner { border-bottom: 1px solid #fff; } .errormark, .warningmark, .donemark, .infomark { background: url(../images/icon_error_sml.gif) no-repeat; } .warningmark { background-image: url(../images/icon_warning_sml.gif); } .donemark { background-image: url(../images/icon_success_sml.gif); } .infomark { background-image: url(../images/icon_info_sml.gif); } CodeNarc-0.23/docs/css/print.css0000644000175000017500000000032712471222451016034 0ustar ebourgebourg#banner, #footer, #leftcol, #breadcrumbs, .docs #toc, .docs .courtesylinks, #leftColumn, #navColumn { display: none !important; } #bodyColumn, body.docs div.docs { margin: 0 !important; border: none !important } CodeNarc-0.23/docs/css/maven-base.css0000644000175000017500000000450712471222451016722 0ustar ebourgebourgbody { margin: 0px; padding: 0px; } img { border:none; } table { padding:0px; width: 100%; margin-left: -2px; margin-right: -2px; } acronym { cursor: help; border-bottom: 1px dotted #feb; } table.bodyTable th, table.bodyTable td { padding: 2px 4px 2px 4px; vertical-align: top; } div.clear{ clear:both; visibility: hidden; } div.clear hr{ display: none; } #bannerLeft, #bannerRight { font-size: xx-large; font-weight: bold; } #bannerLeft img, #bannerRight img { margin: 0px; } .xleft, #bannerLeft img { float:left; } .xright, #bannerRight { float:right; } #banner { padding: 0px; } #banner img { border: none; } #breadcrumbs { padding: 3px 10px 3px 10px; } #leftColumn { width: 170px; float:left; overflow: auto; } #bodyColumn { margin-right: 1.5em; margin-left: 197px; } #legend { padding: 8px 0 8px 0; } #navcolumn { padding: 8px 4px 0 8px; } #navcolumn h5 { margin: 0; padding: 0; font-size: small; } #navcolumn ul { margin: 0; padding: 0; font-size: small; } #navcolumn li { list-style-type: none; background-image: none; background-repeat: no-repeat; background-position: 0 0.4em; padding-left: 16px; list-style-position: outside; line-height: 1.2em; font-size: smaller; } #navcolumn li.expanded { background-image: url(../images/expanded.gif); } #navcolumn li.collapsed { background-image: url(../images/collapsed.gif); } #navcolumn li.none { text-indent: -1em; margin-left: 1em; } #poweredBy { text-align: center; } #navcolumn img { margin-top: 10px; margin-bottom: 3px; } #poweredBy img { display:block; margin: 20px 0 20px 17px; } #search img { margin: 0px; display: block; } #search #q, #search #btnG { border: 1px solid #999; margin-bottom:10px; } #search form { margin: 0px; } #lastPublished { font-size: x-small; } .navSection { margin-bottom: 2px; padding: 8px; } .navSectionHead { font-weight: bold; font-size: x-small; } .section { padding: 4px; } #footer { padding: 3px 10px 3px 10px; font-size: x-small; } #breadcrumbs { font-size: x-small; margin: 0pt; } .source { padding: 12px; margin: 1em 7px 1em 7px; } .source pre { margin: 0px; padding: 0px; } #navcolumn img.imageLink, .imageLink { padding-left: 0px; padding-bottom: 0px; padding-top: 0px; padding-right: 2px; border: 0px; margin: 0px; } CodeNarc-0.23/docs/css/site.css0000644000175000017500000000006712471222451015645 0ustar ebourgebourgtt { font-size: 110%; font-weight: bolder; }CodeNarc-0.23/README.txt0000644000175000017500000000210112471223336014137 0ustar ebourgebourgCodeNarc -- http://codenarc.org/ ------------------------------------------------------------------------------- CodeNarc is a static analysis tool for Groovy source code, enabling monitoring and enforcement of many coding standards and best practices. CodeNarc applies a set of Rules (predefined and/or custom) that are applied to each Groovy file, and generates an HTML or XML report of the results, including a list of rules violated for each source file, and a count of the number of violations per package and for the whole project. CodeNarc is similar to popular static analysis tools such as PMD or Checkstyle. Unlike those tools which analyze Java code, CodeNarc analyzes Groovy code. DEPENDENCIES CodeNarc requires - Groovy version 1.7 or later - The Log4J jar, version 1.2.13 or later, accessible on the CLASSPATH (http://logging.apache.org/log4j/index.html). AVAILABLE FROM MAVEN CENTRAL REPOSITORY For projects built using Maven, CodeNarc is available from the Maven Central Repository. - groupId = org.codenarc - artifactId = CodeNarc CodeNarc-0.23/src/0000755000175000017500000000000012303254654013237 5ustar ebourgebourgCodeNarc-0.23/src/main/0000755000175000017500000000000012303254653014162 5ustar ebourgebourgCodeNarc-0.23/src/main/resources/0000755000175000017500000000000012623571301016171 5ustar ebourgebourgCodeNarc-0.23/src/main/resources/rulesets/0000755000175000017500000000000012623571301020037 5ustar ebourgebourgCodeNarc-0.23/src/main/resources/rulesets/concurrency.xml0000644000175000017500000000466412137611550023126 0ustar ebourgebourg Concurrency rule set. These rules check for unsafe or unrecommended practices related to concurrency. CodeNarc-0.23/src/main/resources/rulesets/groovyism.xml0000644000175000017500000000565712130415314022626 0ustar ebourgebourg Groovy-ism rule set. These are rules for Groovy idiomatic usage, and Groovy-specific bad practices CodeNarc-0.23/src/main/resources/rulesets/grails.xml0000644000175000017500000000245512275724374022065 0ustar ebourgebourg Grails rule set. These rules implement standards and best practices related to the Grails framework (http://grails.org). CodeNarc-0.23/src/main/resources/rulesets/naming.xml0000644000175000017500000000250612407655411022042 0ustar ebourgebourg Naming rule set. These rules validate names within the source code. CodeNarc-0.23/src/main/resources/rulesets/formatting.xml0000644000175000017500000000476012312164351022740 0ustar ebourgebourg Formatting rule set. These rules find formatting problems within the source code. CodeNarc-0.23/src/main/resources/rulesets/unnecessary.xml0000644000175000017500000001010612414042210023104 0ustar ebourgebourg Unnecessary rule set. These rules check for unnecessary code. CodeNarc-0.23/src/main/resources/rulesets/size.xml0000644000175000017500000000177012444433061021541 0ustar ebourgebourg Size and complexity rule set. These rules check against thresholds for code size and complexity. CodeNarc-0.23/src/main/resources/rulesets/serialization.xml0000644000175000017500000000141512143045754023444 0ustar ebourgebourg Serialization rule set. These rules check for Java serialization-specific violations. CodeNarc-0.23/src/main/resources/rulesets/exceptions.xml0000644000175000017500000000374012316051000022732 0ustar ebourgebourg Exceptions rule set. These rules implement standards and best practices related to catching and throwing of exceptions. CodeNarc-0.23/src/main/resources/rulesets/generic.xml0000644000175000017500000000203712322630267022202 0ustar ebourgebourg Generic rule set. These rules are generic, and are intended to be customized. CodeNarc-0.23/src/main/resources/rulesets/enhanced.xml0000644000175000017500000000173412167646706022352 0ustar ebourgebourg Enhanced classpath rule set. These rules use a later compilation phase for parsing of the Groovy source code, allowing CodeNarc to use a richer and more complete Abstract Syntax Tree (AST). The downside is that the later compiler phase requires CodeNarc to have the application classes being analyzed, as well as any referenced classes, on the classpath. CodeNarc-0.23/src/main/resources/rulesets/jdbc.xml0000644000175000017500000000130012006632012021445 0ustar ebourgebourg JDBC rule set. These rules check for JDBC-specific violations. CodeNarc-0.23/src/main/resources/rulesets/dry.xml0000644000175000017500000000133512006632014021353 0ustar ebourgebourg Dry rule set. These rules check for duplicate code, enforcing the DRY (Don't Repeat Yourself) principle. CodeNarc-0.23/src/main/resources/rulesets/unused.xml0000644000175000017500000000161712006632016022065 0ustar ebourgebourg Unused rule set. These rules check for unused definitions within the source code. CodeNarc-0.23/src/main/resources/rulesets/design.xml0000644000175000017500000000371612440206243022036 0ustar ebourgebourg Design rule set. These rules implement standards and best practices related to design issues. CodeNarc-0.23/src/main/resources/rulesets/logging.xml0000644000175000017500000000177612006632012022212 0ustar ebourgebourg Logging rule set. These rules implement standards and best practices related to logging and output. CodeNarc-0.23/src/main/resources/rulesets/basic.xml0000644000175000017500000000657012323514421021647 0ustar ebourgebourg Basic rule set. These rules are intended to be broadly (if not universally) applicable. CodeNarc-0.23/src/main/resources/rulesets/security.xml0000644000175000017500000000206212275775662022453 0ustar ebourgebourg Security rule set. These rules find security problems within the source code. CodeNarc-0.23/src/main/resources/rulesets/convention.xml0000644000175000017500000000223112414302051022731 0ustar ebourgebourg Convention rule set. These are rules for coding conventions; not necessarily errors. CodeNarc-0.23/src/main/resources/rulesets/junit.xml0000644000175000017500000000426112323241527021716 0ustar ebourgebourg JUnit rule set. These rules implement standards and best practices related to JUnit tests. CodeNarc-0.23/src/main/resources/rulesets/imports.xml0000644000175000017500000000170312304644133022257 0ustar ebourgebourg Imports rule set. These rules implement standards and best practices related to import statements. CodeNarc-0.23/src/main/resources/rulesets/braces.xml0000644000175000017500000000133712006632014022016 0ustar ebourgebourg Braces rule set. These rules implement standards and best practices related to using braces. CodeNarc-0.23/src/main/resources/codenarc-version.txt0000644000175000017500000000000412466776322022204 0ustar ebourgebourg0.23CodeNarc-0.23/src/main/resources/templates/0000755000175000017500000000000012623571301020167 5ustar ebourgebourgCodeNarc-0.23/src/main/resources/templates/StarterRuleSet-AllRules.groovy.template0000644000175000017500000000063512040564656027735 0ustar ebourgebourgruleset { description ''' A Sample Groovy RuleSet containing all CodeNarc Rules You can use this as a template for your own custom RuleSet. Just delete the rules that you don't want to include. ''' <% rules.each { rule -> def extraInfo = ruleExtraInformation[rule.name] ? " // ${ruleExtraInformation[rule.name]}" : '' %>${rule.name} ${extraInfo} <% } %> }CodeNarc-0.23/src/main/resources/templates/StarterRuleSet-AllRulesByCategory.groovy.template0000644000175000017500000000076412040564672031727 0ustar ebourgebourgruleset { description ''' A Sample Groovy RuleSet containing all CodeNarc Rules, grouped by category. You can use this as a template for your own custom RuleSet. Just delete the rules that you don't want to include. ''' <% ruleSets.each { name, rules -> %>// ${name} <% rules.each { rule -> def extraInfo = ruleExtraInformation[rule.name] ? " // ${ruleExtraInformation[rule.name]}" : '' %>${rule.name} ${extraInfo} <% } %> <% } %> }CodeNarc-0.23/src/main/resources/templates/codenarc-rule-index.apt.template0000644000175000017500000000123512414255261026342 0ustar ebourgebourg -------------------------------------------------- CodeNarc - Rule Index -------------------------------------------------- Rule Index ~~~~~~~~~~ <> includes ${numberOfRules} rules. <% ruleSets.each { name, rules -> %> <% def ruleSetLink = "codenarc-rules-${name}.html" %> <% def capitalizedName = name.capitalize() %> * {{{$ruleSetLink}$capitalizedName}} <% rules.each { rule -> %> <% def extraInfo = ruleExtraInformation[rule.name] ? " (${ruleExtraInformation[rule.name]})" : '' %> * {{{./codenarc-rules-${name}.html#${rule.name}}${rule.name}}} ${extraInfo} <% } %> <% } %> CodeNarc-0.23/src/main/resources/codenarc-base-rules.properties0000644000175000017500000006505112470770455024147 0ustar ebourgebourg# CodeNarc Rules (see PropertiesFileRuleRegistry): Tue Feb 17 20:55:57 EST 2015 AbcComplexity = org.codenarc.rule.size.AbcComplexityRule AbcMetric = org.codenarc.rule.size.AbcMetricRule AbstractClassName = org.codenarc.rule.naming.AbstractClassNameRule AbstractClassWithPublicConstructor = org.codenarc.rule.design.AbstractClassWithPublicConstructorRule AbstractClassWithoutAbstractMethod = org.codenarc.rule.design.AbstractClassWithoutAbstractMethodRule AddEmptyString = org.codenarc.rule.unnecessary.AddEmptyStringRule AssertWithinFinallyBlock = org.codenarc.rule.basic.AssertWithinFinallyBlockRule AssignCollectionSort = org.codenarc.rule.groovyism.AssignCollectionSortRule AssignCollectionUnique = org.codenarc.rule.groovyism.AssignCollectionUniqueRule AssignmentInConditional = org.codenarc.rule.basic.AssignmentInConditionalRule BigDecimalInstantiation = org.codenarc.rule.basic.BigDecimalInstantiationRule BitwiseOperatorInConditional = org.codenarc.rule.basic.BitwiseOperatorInConditionalRule BlankLineBeforePackage = org.codenarc.rule.formatting.BlankLineBeforePackageRule BooleanGetBoolean = org.codenarc.rule.basic.BooleanGetBooleanRule BooleanMethodReturnsNull = org.codenarc.rule.design.BooleanMethodReturnsNullRule BracesForClass = org.codenarc.rule.formatting.BracesForClassRule BracesForForLoop = org.codenarc.rule.formatting.BracesForForLoopRule BracesForIfElse = org.codenarc.rule.formatting.BracesForIfElseRule BracesForMethod = org.codenarc.rule.formatting.BracesForMethodRule BracesForTryCatchFinally = org.codenarc.rule.formatting.BracesForTryCatchFinallyRule BrokenNullCheck = org.codenarc.rule.basic.BrokenNullCheckRule BrokenOddnessCheck = org.codenarc.rule.basic.BrokenOddnessCheckRule BuilderMethodWithSideEffects = org.codenarc.rule.design.BuilderMethodWithSideEffectsRule BusyWait = org.codenarc.rule.concurrency.BusyWaitRule CatchArrayIndexOutOfBoundsException = org.codenarc.rule.exceptions.CatchArrayIndexOutOfBoundsExceptionRule CatchError = org.codenarc.rule.exceptions.CatchErrorRule CatchException = org.codenarc.rule.exceptions.CatchExceptionRule CatchIllegalMonitorStateException = org.codenarc.rule.exceptions.CatchIllegalMonitorStateExceptionRule CatchIndexOutOfBoundsException = org.codenarc.rule.exceptions.CatchIndexOutOfBoundsExceptionRule CatchNullPointerException = org.codenarc.rule.exceptions.CatchNullPointerExceptionRule CatchRuntimeException = org.codenarc.rule.exceptions.CatchRuntimeExceptionRule CatchThrowable = org.codenarc.rule.exceptions.CatchThrowableRule ChainedTest = org.codenarc.rule.junit.ChainedTestRule ClassForName = org.codenarc.rule.basic.ClassForNameRule ClassJavadoc = org.codenarc.rule.formatting.ClassJavadocRule ClassName = org.codenarc.rule.naming.ClassNameRule ClassNameSameAsFilename = org.codenarc.rule.naming.ClassNameSameAsFilenameRule ClassSize = org.codenarc.rule.size.ClassSizeRule CloneWithoutCloneable = org.codenarc.rule.design.CloneWithoutCloneableRule CloneableWithoutClone = org.codenarc.rule.design.CloneableWithoutCloneRule CloseWithoutCloseable = org.codenarc.rule.design.CloseWithoutCloseableRule ClosureAsLastMethodParameter = org.codenarc.rule.groovyism.ClosureAsLastMethodParameterRule ClosureStatementOnOpeningLineOfMultipleLineClosure = org.codenarc.rule.formatting.ClosureStatementOnOpeningLineOfMultipleLineClosureRule CollectAllIsDeprecated = org.codenarc.rule.groovyism.CollectAllIsDeprecatedRule CompareToWithoutComparable = org.codenarc.rule.design.CompareToWithoutComparableRule ComparisonOfTwoConstants = org.codenarc.rule.basic.ComparisonOfTwoConstantsRule ComparisonWithSelf = org.codenarc.rule.basic.ComparisonWithSelfRule ConfusingClassNamedException = org.codenarc.rule.exceptions.ConfusingClassNamedExceptionRule ConfusingMethodName = org.codenarc.rule.naming.ConfusingMethodNameRule ConfusingMultipleReturns = org.codenarc.rule.groovyism.ConfusingMultipleReturnsRule ConfusingTernary = org.codenarc.rule.convention.ConfusingTernaryRule ConsecutiveBlankLines = org.codenarc.rule.formatting.ConsecutiveBlankLinesRule ConsecutiveLiteralAppends = org.codenarc.rule.unnecessary.ConsecutiveLiteralAppendsRule ConsecutiveStringConcatenation = org.codenarc.rule.unnecessary.ConsecutiveStringConcatenationRule ConstantAssertExpression = org.codenarc.rule.basic.ConstantAssertExpressionRule ConstantIfExpression = org.codenarc.rule.basic.ConstantIfExpressionRule ConstantTernaryExpression = org.codenarc.rule.basic.ConstantTernaryExpressionRule ConstantsOnlyInterface = org.codenarc.rule.design.ConstantsOnlyInterfaceRule CouldBeElvis = org.codenarc.rule.convention.CouldBeElvisRule CoupledTestCase = org.codenarc.rule.junit.CoupledTestCaseRule CrapMetric = org.codenarc.rule.size.CrapMetricRule CyclomaticComplexity = org.codenarc.rule.size.CyclomaticComplexityRule DeadCode = org.codenarc.rule.basic.DeadCodeRule DirectConnectionManagement = org.codenarc.rule.jdbc.DirectConnectionManagementRule DoubleCheckedLocking = org.codenarc.rule.concurrency.DoubleCheckedLockingRule DoubleNegative = org.codenarc.rule.basic.DoubleNegativeRule DuplicateCaseStatement = org.codenarc.rule.basic.DuplicateCaseStatementRule DuplicateImport = org.codenarc.rule.imports.DuplicateImportRule DuplicateListLiteral = org.codenarc.rule.dry.DuplicateListLiteralRule DuplicateMapKey = org.codenarc.rule.basic.DuplicateMapKeyRule DuplicateMapLiteral = org.codenarc.rule.dry.DuplicateMapLiteralRule DuplicateNumberLiteral = org.codenarc.rule.dry.DuplicateNumberLiteralRule DuplicateSetValue = org.codenarc.rule.basic.DuplicateSetValueRule DuplicateStringLiteral = org.codenarc.rule.dry.DuplicateStringLiteralRule ElseBlockBraces = org.codenarc.rule.braces.ElseBlockBracesRule EmptyCatchBlock = org.codenarc.rule.basic.EmptyCatchBlockRule EmptyClass = org.codenarc.rule.basic.EmptyClassRule EmptyElseBlock = org.codenarc.rule.basic.EmptyElseBlockRule EmptyFinallyBlock = org.codenarc.rule.basic.EmptyFinallyBlockRule EmptyForStatement = org.codenarc.rule.basic.EmptyForStatementRule EmptyIfStatement = org.codenarc.rule.basic.EmptyIfStatementRule EmptyInstanceInitializer = org.codenarc.rule.basic.EmptyInstanceInitializerRule EmptyMethod = org.codenarc.rule.basic.EmptyMethodRule EmptyMethodInAbstractClass = org.codenarc.rule.design.EmptyMethodInAbstractClassRule EmptyStaticInitializer = org.codenarc.rule.basic.EmptyStaticInitializerRule EmptySwitchStatement = org.codenarc.rule.basic.EmptySwitchStatementRule EmptySynchronizedStatement = org.codenarc.rule.basic.EmptySynchronizedStatementRule EmptyTryBlock = org.codenarc.rule.basic.EmptyTryBlockRule EmptyWhileStatement = org.codenarc.rule.basic.EmptyWhileStatementRule EnumCustomSerializationIgnored = org.codenarc.rule.serialization.EnumCustomSerializationIgnoredRule EqualsAndHashCode = org.codenarc.rule.basic.EqualsAndHashCodeRule EqualsOverloaded = org.codenarc.rule.basic.EqualsOverloadedRule ExceptionExtendsError = org.codenarc.rule.exceptions.ExceptionExtendsErrorRule ExceptionExtendsThrowable = org.codenarc.rule.exceptions.ExceptionExtendsThrowableRule ExceptionNotThrown = org.codenarc.rule.exceptions.ExceptionNotThrownRule ExplicitArrayListInstantiation = org.codenarc.rule.groovyism.ExplicitArrayListInstantiationRule ExplicitCallToAndMethod = org.codenarc.rule.groovyism.ExplicitCallToAndMethodRule ExplicitCallToCompareToMethod = org.codenarc.rule.groovyism.ExplicitCallToCompareToMethodRule ExplicitCallToDivMethod = org.codenarc.rule.groovyism.ExplicitCallToDivMethodRule ExplicitCallToEqualsMethod = org.codenarc.rule.groovyism.ExplicitCallToEqualsMethodRule ExplicitCallToGetAtMethod = org.codenarc.rule.groovyism.ExplicitCallToGetAtMethodRule ExplicitCallToLeftShiftMethod = org.codenarc.rule.groovyism.ExplicitCallToLeftShiftMethodRule ExplicitCallToMinusMethod = org.codenarc.rule.groovyism.ExplicitCallToMinusMethodRule ExplicitCallToModMethod = org.codenarc.rule.groovyism.ExplicitCallToModMethodRule ExplicitCallToMultiplyMethod = org.codenarc.rule.groovyism.ExplicitCallToMultiplyMethodRule ExplicitCallToOrMethod = org.codenarc.rule.groovyism.ExplicitCallToOrMethodRule ExplicitCallToPlusMethod = org.codenarc.rule.groovyism.ExplicitCallToPlusMethodRule ExplicitCallToPowerMethod = org.codenarc.rule.groovyism.ExplicitCallToPowerMethodRule ExplicitCallToRightShiftMethod = org.codenarc.rule.groovyism.ExplicitCallToRightShiftMethodRule ExplicitCallToXorMethod = org.codenarc.rule.groovyism.ExplicitCallToXorMethodRule ExplicitGarbageCollection = org.codenarc.rule.basic.ExplicitGarbageCollectionRule ExplicitHashMapInstantiation = org.codenarc.rule.groovyism.ExplicitHashMapInstantiationRule ExplicitHashSetInstantiation = org.codenarc.rule.groovyism.ExplicitHashSetInstantiationRule ExplicitLinkedHashMapInstantiation = org.codenarc.rule.groovyism.ExplicitLinkedHashMapInstantiationRule ExplicitLinkedListInstantiation = org.codenarc.rule.groovyism.ExplicitLinkedListInstantiationRule ExplicitStackInstantiation = org.codenarc.rule.groovyism.ExplicitStackInstantiationRule ExplicitTreeSetInstantiation = org.codenarc.rule.groovyism.ExplicitTreeSetInstantiationRule FactoryMethodName = org.codenarc.rule.naming.FactoryMethodNameRule FieldName = org.codenarc.rule.naming.FieldNameRule FileCreateTempFile = org.codenarc.rule.security.FileCreateTempFileRule FileEndsWithoutNewline = org.codenarc.rule.formatting.FileEndsWithoutNewlineRule FinalClassWithProtectedMember = org.codenarc.rule.design.FinalClassWithProtectedMemberRule ForLoopShouldBeWhileLoop = org.codenarc.rule.basic.ForLoopShouldBeWhileLoopRule ForStatementBraces = org.codenarc.rule.braces.ForStatementBracesRule GStringAsMapKey = org.codenarc.rule.groovyism.GStringAsMapKeyRule GStringExpressionWithinString = org.codenarc.rule.groovyism.GStringExpressionWithinStringRule GetterMethodCouldBeProperty = org.codenarc.rule.groovyism.GetterMethodCouldBePropertyRule GrailsDomainHasEquals = org.codenarc.rule.grails.GrailsDomainHasEqualsRule GrailsDomainHasToString = org.codenarc.rule.grails.GrailsDomainHasToStringRule GrailsDomainReservedSqlKeywordName = org.codenarc.rule.grails.GrailsDomainReservedSqlKeywordNameRule GrailsDomainWithServiceReference = org.codenarc.rule.grails.GrailsDomainWithServiceReferenceRule GrailsDuplicateConstraint = org.codenarc.rule.grails.GrailsDuplicateConstraintRule GrailsDuplicateMapping = org.codenarc.rule.grails.GrailsDuplicateMappingRule GrailsMassAssignment = org.codenarc.rule.grails.GrailsMassAssignmentRule GrailsPublicControllerMethod = org.codenarc.rule.grails.GrailsPublicControllerMethodRule GrailsServletContextReference = org.codenarc.rule.grails.GrailsServletContextReferenceRule GrailsSessionReference = org.codenarc.rule.grails.GrailsSessionReferenceRule GrailsStatelessService = org.codenarc.rule.grails.GrailsStatelessServiceRule GroovyLangImmutable = org.codenarc.rule.groovyism.GroovyLangImmutableRule HardCodedWindowsFileSeparator = org.codenarc.rule.basic.HardCodedWindowsFileSeparatorRule HardCodedWindowsRootDirectory = org.codenarc.rule.basic.HardCodedWindowsRootDirectoryRule HashtableIsObsolete = org.codenarc.rule.convention.HashtableIsObsoleteRule IfStatementBraces = org.codenarc.rule.braces.IfStatementBracesRule IfStatementCouldBeTernary = org.codenarc.rule.convention.IfStatementCouldBeTernaryRule IllegalClassMember = org.codenarc.rule.generic.IllegalClassMemberRule IllegalClassReference = org.codenarc.rule.generic.IllegalClassReferenceRule IllegalPackageReference = org.codenarc.rule.generic.IllegalPackageReferenceRule IllegalRegex = org.codenarc.rule.generic.IllegalRegexRule IllegalString = org.codenarc.rule.generic.IllegalStringRule IllegalSubclass = org.codenarc.rule.generic.IllegalSubclassRule ImplementationAsType = org.codenarc.rule.design.ImplementationAsTypeRule ImportFromSamePackage = org.codenarc.rule.imports.ImportFromSamePackageRule ImportFromSunPackages = org.codenarc.rule.imports.ImportFromSunPackagesRule InconsistentPropertyLocking = org.codenarc.rule.concurrency.InconsistentPropertyLockingRule InconsistentPropertySynchronization = org.codenarc.rule.concurrency.InconsistentPropertySynchronizationRule InsecureRandom = org.codenarc.rule.security.InsecureRandomRule Instanceof = org.codenarc.rule.design.InstanceofRule IntegerGetInteger = org.codenarc.rule.basic.IntegerGetIntegerRule InterfaceName = org.codenarc.rule.naming.InterfaceNameRule InvertedIfElse = org.codenarc.rule.convention.InvertedIfElseRule JUnitAssertAlwaysFails = org.codenarc.rule.junit.JUnitAssertAlwaysFailsRule JUnitAssertAlwaysSucceeds = org.codenarc.rule.junit.JUnitAssertAlwaysSucceedsRule JUnitAssertEqualsConstantActualValue = org.codenarc.rule.junit.JUnitAssertEqualsConstantActualValueRule JUnitFailWithoutMessage = org.codenarc.rule.junit.JUnitFailWithoutMessageRule JUnitLostTest = org.codenarc.rule.junit.JUnitLostTestRule JUnitPublicField = org.codenarc.rule.junit.JUnitPublicFieldRule JUnitPublicNonTestMethod = org.codenarc.rule.junit.JUnitPublicNonTestMethodRule JUnitPublicProperty = org.codenarc.rule.junit.JUnitPublicPropertyRule JUnitSetUpCallsSuper = org.codenarc.rule.junit.JUnitSetUpCallsSuperRule JUnitStyleAssertions = org.codenarc.rule.junit.JUnitStyleAssertionsRule JUnitTearDownCallsSuper = org.codenarc.rule.junit.JUnitTearDownCallsSuperRule JUnitTestMethodWithoutAssert = org.codenarc.rule.junit.JUnitTestMethodWithoutAssertRule JUnitUnnecessarySetUp = org.codenarc.rule.junit.JUnitUnnecessarySetUpRule JUnitUnnecessaryTearDown = org.codenarc.rule.junit.JUnitUnnecessaryTearDownRule JUnitUnnecessaryThrowsException = org.codenarc.rule.junit.JUnitUnnecessaryThrowsExceptionRule JavaIoPackageAccess = org.codenarc.rule.security.JavaIoPackageAccessRule JdbcConnectionReference = org.codenarc.rule.jdbc.JdbcConnectionReferenceRule JdbcResultSetReference = org.codenarc.rule.jdbc.JdbcResultSetReferenceRule JdbcStatementReference = org.codenarc.rule.jdbc.JdbcStatementReferenceRule LineLength = org.codenarc.rule.formatting.LineLengthRule LocaleSetDefault = org.codenarc.rule.design.LocaleSetDefaultRule LoggerForDifferentClass = org.codenarc.rule.logging.LoggerForDifferentClassRule LoggerWithWrongModifiers = org.codenarc.rule.logging.LoggerWithWrongModifiersRule LoggingSwallowsStacktrace = org.codenarc.rule.logging.LoggingSwallowsStacktraceRule LongLiteralWithLowerCaseL = org.codenarc.rule.convention.LongLiteralWithLowerCaseLRule MethodCount = org.codenarc.rule.size.MethodCountRule MethodName = org.codenarc.rule.naming.MethodNameRule MethodSize = org.codenarc.rule.size.MethodSizeRule MisorderedStaticImports = org.codenarc.rule.imports.MisorderedStaticImportsRule MissingBlankLineAfterImports = org.codenarc.rule.formatting.MissingBlankLineAfterImportsRule MissingBlankLineAfterPackage = org.codenarc.rule.formatting.MissingBlankLineAfterPackageRule MissingNewInThrowStatement = org.codenarc.rule.exceptions.MissingNewInThrowStatementRule MultipleLoggers = org.codenarc.rule.logging.MultipleLoggersRule MultipleUnaryOperators = org.codenarc.rule.basic.MultipleUnaryOperatorsRule NestedBlockDepth = org.codenarc.rule.size.NestedBlockDepthRule NestedForLoop = org.codenarc.rule.design.NestedForLoopRule NestedSynchronization = org.codenarc.rule.concurrency.NestedSynchronizationRule NoDef = org.codenarc.rule.convention.NoDefRule NoWildcardImports = org.codenarc.rule.imports.NoWildcardImportsRule NonFinalPublicField = org.codenarc.rule.security.NonFinalPublicFieldRule NonFinalSubclassOfSensitiveInterface = org.codenarc.rule.security.NonFinalSubclassOfSensitiveInterfaceRule ObjectFinalize = org.codenarc.rule.security.ObjectFinalizeRule ObjectOverrideMisspelledMethodName = org.codenarc.rule.naming.ObjectOverrideMisspelledMethodNameRule PackageName = org.codenarc.rule.naming.PackageNameRule PackageNameMatchesFilePath = org.codenarc.rule.naming.PackageNameMatchesFilePathRule ParameterCount = org.codenarc.rule.size.ParameterCountRule ParameterName = org.codenarc.rule.naming.ParameterNameRule ParameterReassignment = org.codenarc.rule.convention.ParameterReassignmentRule PrintStackTrace = org.codenarc.rule.logging.PrintStackTraceRule Println = org.codenarc.rule.logging.PrintlnRule PrivateFieldCouldBeFinal = org.codenarc.rule.design.PrivateFieldCouldBeFinalRule PropertyName = org.codenarc.rule.naming.PropertyNameRule PublicFinalizeMethod = org.codenarc.rule.security.PublicFinalizeMethodRule PublicInstanceField = org.codenarc.rule.design.PublicInstanceFieldRule RandomDoubleCoercedToZero = org.codenarc.rule.basic.RandomDoubleCoercedToZeroRule RemoveAllOnSelf = org.codenarc.rule.basic.RemoveAllOnSelfRule RequiredRegex = org.codenarc.rule.generic.RequiredRegexRule RequiredString = org.codenarc.rule.generic.RequiredStringRule ReturnFromFinallyBlock = org.codenarc.rule.basic.ReturnFromFinallyBlockRule ReturnNullFromCatchBlock = org.codenarc.rule.exceptions.ReturnNullFromCatchBlockRule ReturnsNullInsteadOfEmptyArray = org.codenarc.rule.design.ReturnsNullInsteadOfEmptyArrayRule ReturnsNullInsteadOfEmptyCollection = org.codenarc.rule.design.ReturnsNullInsteadOfEmptyCollectionRule SerialPersistentFields = org.codenarc.rule.serialization.SerialPersistentFieldsRule SerialVersionUID = org.codenarc.rule.serialization.SerialVersionUIDRule SerializableClassMustDefineSerialVersionUID = org.codenarc.rule.serialization.SerializableClassMustDefineSerialVersionUIDRule SimpleDateFormatMissingLocale = org.codenarc.rule.design.SimpleDateFormatMissingLocaleRule SpaceAfterCatch = org.codenarc.rule.formatting.SpaceAfterCatchRule SpaceAfterClosingBrace = org.codenarc.rule.formatting.SpaceAfterClosingBraceRule SpaceAfterComma = org.codenarc.rule.formatting.SpaceAfterCommaRule SpaceAfterFor = org.codenarc.rule.formatting.SpaceAfterForRule SpaceAfterIf = org.codenarc.rule.formatting.SpaceAfterIfRule SpaceAfterOpeningBrace = org.codenarc.rule.formatting.SpaceAfterOpeningBraceRule SpaceAfterSemicolon = org.codenarc.rule.formatting.SpaceAfterSemicolonRule SpaceAfterSwitch = org.codenarc.rule.formatting.SpaceAfterSwitchRule SpaceAfterWhile = org.codenarc.rule.formatting.SpaceAfterWhileRule SpaceAroundClosureArrow = org.codenarc.rule.formatting.SpaceAroundClosureArrowRule SpaceAroundMapEntryColon = org.codenarc.rule.formatting.SpaceAroundMapEntryColonRule SpaceAroundOperator = org.codenarc.rule.formatting.SpaceAroundOperatorRule SpaceBeforeClosingBrace = org.codenarc.rule.formatting.SpaceBeforeClosingBraceRule SpaceBeforeOpeningBrace = org.codenarc.rule.formatting.SpaceBeforeOpeningBraceRule SpockIgnoreRestUsed = org.codenarc.rule.junit.SpockIgnoreRestUsedRule StatelessClass = org.codenarc.rule.generic.StatelessClassRule StatelessSingleton = org.codenarc.rule.design.StatelessSingletonRule StaticCalendarField = org.codenarc.rule.concurrency.StaticCalendarFieldRule StaticConnection = org.codenarc.rule.concurrency.StaticConnectionRule StaticDateFormatField = org.codenarc.rule.concurrency.StaticDateFormatFieldRule StaticMatcherField = org.codenarc.rule.concurrency.StaticMatcherFieldRule StaticSimpleDateFormatField = org.codenarc.rule.concurrency.StaticSimpleDateFormatFieldRule SwallowThreadDeath = org.codenarc.rule.exceptions.SwallowThreadDeathRule SynchronizedMethod = org.codenarc.rule.concurrency.SynchronizedMethodRule SynchronizedOnBoxedPrimitive = org.codenarc.rule.concurrency.SynchronizedOnBoxedPrimitiveRule SynchronizedOnGetClass = org.codenarc.rule.concurrency.SynchronizedOnGetClassRule SynchronizedOnReentrantLock = org.codenarc.rule.concurrency.SynchronizedOnReentrantLockRule SynchronizedOnString = org.codenarc.rule.concurrency.SynchronizedOnStringRule SynchronizedOnThis = org.codenarc.rule.concurrency.SynchronizedOnThisRule SynchronizedReadObjectMethod = org.codenarc.rule.concurrency.SynchronizedReadObjectMethodRule SystemErrPrint = org.codenarc.rule.logging.SystemErrPrintRule SystemExit = org.codenarc.rule.security.SystemExitRule SystemOutPrint = org.codenarc.rule.logging.SystemOutPrintRule SystemRunFinalizersOnExit = org.codenarc.rule.concurrency.SystemRunFinalizersOnExitRule TernaryCouldBeElvis = org.codenarc.rule.convention.TernaryCouldBeElvisRule ThisReferenceEscapesConstructor = org.codenarc.rule.concurrency.ThisReferenceEscapesConstructorRule ThreadGroup = org.codenarc.rule.concurrency.ThreadGroupRule ThreadLocalNotStaticFinal = org.codenarc.rule.concurrency.ThreadLocalNotStaticFinalRule ThreadYield = org.codenarc.rule.concurrency.ThreadYieldRule ThrowError = org.codenarc.rule.exceptions.ThrowErrorRule ThrowException = org.codenarc.rule.exceptions.ThrowExceptionRule ThrowExceptionFromFinallyBlock = org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule ThrowNullPointerException = org.codenarc.rule.exceptions.ThrowNullPointerExceptionRule ThrowRuntimeException = org.codenarc.rule.exceptions.ThrowRuntimeExceptionRule ThrowThrowable = org.codenarc.rule.exceptions.ThrowThrowableRule ToStringReturnsNull = org.codenarc.rule.design.ToStringReturnsNullRule TrailingWhitespace = org.codenarc.rule.formatting.TrailingWhitespaceRule UnnecessaryBigDecimalInstantiation = org.codenarc.rule.unnecessary.UnnecessaryBigDecimalInstantiationRule UnnecessaryBigIntegerInstantiation = org.codenarc.rule.unnecessary.UnnecessaryBigIntegerInstantiationRule UnnecessaryBooleanExpression = org.codenarc.rule.unnecessary.UnnecessaryBooleanExpressionRule UnnecessaryBooleanInstantiation = org.codenarc.rule.unnecessary.UnnecessaryBooleanInstantiationRule UnnecessaryCallForLastElement = org.codenarc.rule.unnecessary.UnnecessaryCallForLastElementRule UnnecessaryCallToSubstring = org.codenarc.rule.unnecessary.UnnecessaryCallToSubstringRule UnnecessaryCast = org.codenarc.rule.unnecessary.UnnecessaryCastRule UnnecessaryCatchBlock = org.codenarc.rule.unnecessary.UnnecessaryCatchBlockRule UnnecessaryCollectCall = org.codenarc.rule.unnecessary.UnnecessaryCollectCallRule UnnecessaryCollectionCall = org.codenarc.rule.unnecessary.UnnecessaryCollectionCallRule UnnecessaryConstructor = org.codenarc.rule.unnecessary.UnnecessaryConstructorRule UnnecessaryDefInFieldDeclaration = org.codenarc.rule.unnecessary.UnnecessaryDefInFieldDeclarationRule UnnecessaryDefInMethodDeclaration = org.codenarc.rule.unnecessary.UnnecessaryDefInMethodDeclarationRule UnnecessaryDefInVariableDeclaration = org.codenarc.rule.unnecessary.UnnecessaryDefInVariableDeclarationRule UnnecessaryDotClass = org.codenarc.rule.unnecessary.UnnecessaryDotClassRule UnnecessaryDoubleInstantiation = org.codenarc.rule.unnecessary.UnnecessaryDoubleInstantiationRule UnnecessaryElseStatement = org.codenarc.rule.unnecessary.UnnecessaryElseStatementRule UnnecessaryFail = org.codenarc.rule.junit.UnnecessaryFailRule UnnecessaryFinalOnPrivateMethod = org.codenarc.rule.unnecessary.UnnecessaryFinalOnPrivateMethodRule UnnecessaryFloatInstantiation = org.codenarc.rule.unnecessary.UnnecessaryFloatInstantiationRule UnnecessaryGString = org.codenarc.rule.unnecessary.UnnecessaryGStringRule UnnecessaryGetter = org.codenarc.rule.unnecessary.UnnecessaryGetterRule UnnecessaryGroovyImport = org.codenarc.rule.imports.UnnecessaryGroovyImportRule UnnecessaryIfStatement = org.codenarc.rule.unnecessary.UnnecessaryIfStatementRule UnnecessaryInstanceOfCheck = org.codenarc.rule.unnecessary.UnnecessaryInstanceOfCheckRule UnnecessaryInstantiationToGetClass = org.codenarc.rule.unnecessary.UnnecessaryInstantiationToGetClassRule UnnecessaryIntegerInstantiation = org.codenarc.rule.unnecessary.UnnecessaryIntegerInstantiationRule UnnecessaryLongInstantiation = org.codenarc.rule.unnecessary.UnnecessaryLongInstantiationRule UnnecessaryModOne = org.codenarc.rule.unnecessary.UnnecessaryModOneRule UnnecessaryNullCheck = org.codenarc.rule.unnecessary.UnnecessaryNullCheckRule UnnecessaryNullCheckBeforeInstanceOf = org.codenarc.rule.unnecessary.UnnecessaryNullCheckBeforeInstanceOfRule UnnecessaryObjectReferences = org.codenarc.rule.unnecessary.UnnecessaryObjectReferencesRule UnnecessaryOverridingMethod = org.codenarc.rule.unnecessary.UnnecessaryOverridingMethodRule UnnecessaryPackageReference = org.codenarc.rule.unnecessary.UnnecessaryPackageReferenceRule UnnecessaryParenthesesForMethodCallWithClosure = org.codenarc.rule.unnecessary.UnnecessaryParenthesesForMethodCallWithClosureRule UnnecessaryPublicModifier = org.codenarc.rule.unnecessary.UnnecessaryPublicModifierRule UnnecessaryReturnKeyword = org.codenarc.rule.unnecessary.UnnecessaryReturnKeywordRule UnnecessarySafeNavigationOperator = org.codenarc.rule.unnecessary.UnnecessarySafeNavigationOperatorRule UnnecessarySelfAssignment = org.codenarc.rule.unnecessary.UnnecessarySelfAssignmentRule UnnecessarySemicolon = org.codenarc.rule.unnecessary.UnnecessarySemicolonRule UnnecessaryStringInstantiation = org.codenarc.rule.unnecessary.UnnecessaryStringInstantiationRule UnnecessarySubstring = org.codenarc.rule.unnecessary.UnnecessarySubstringRule UnnecessaryTernaryExpression = org.codenarc.rule.unnecessary.UnnecessaryTernaryExpressionRule UnnecessaryToString = org.codenarc.rule.unnecessary.UnnecessaryToStringRule UnnecessaryTransientModifier = org.codenarc.rule.unnecessary.UnnecessaryTransientModifierRule UnsafeArrayDeclaration = org.codenarc.rule.security.UnsafeArrayDeclarationRule UnsafeImplementationAsMap = org.codenarc.rule.security.UnsafeImplementationAsMapRule UnusedArray = org.codenarc.rule.unused.UnusedArrayRule UnusedImport = org.codenarc.rule.imports.UnusedImportRule UnusedMethodParameter = org.codenarc.rule.unused.UnusedMethodParameterRule UnusedObject = org.codenarc.rule.unused.UnusedObjectRule UnusedPrivateField = org.codenarc.rule.unused.UnusedPrivateFieldRule UnusedPrivateMethod = org.codenarc.rule.unused.UnusedPrivateMethodRule UnusedPrivateMethodParameter = org.codenarc.rule.unused.UnusedPrivateMethodParameterRule UnusedVariable = org.codenarc.rule.unused.UnusedVariableRule UseAssertEqualsInsteadOfAssertTrue = org.codenarc.rule.junit.UseAssertEqualsInsteadOfAssertTrueRule UseAssertFalseInsteadOfNegation = org.codenarc.rule.junit.UseAssertFalseInsteadOfNegationRule UseAssertNullInsteadOfAssertEquals = org.codenarc.rule.junit.UseAssertNullInsteadOfAssertEqualsRule UseAssertSameInsteadOfAssertTrue = org.codenarc.rule.junit.UseAssertSameInsteadOfAssertTrueRule UseAssertTrueInsteadOfAssertEquals = org.codenarc.rule.junit.UseAssertTrueInsteadOfAssertEqualsRule UseAssertTrueInsteadOfNegation = org.codenarc.rule.junit.UseAssertTrueInsteadOfNegationRule UseCollectMany = org.codenarc.rule.groovyism.UseCollectManyRule UseCollectNested = org.codenarc.rule.groovyism.UseCollectNestedRule UseOfNotifyMethod = org.codenarc.rule.concurrency.UseOfNotifyMethodRule VariableName = org.codenarc.rule.naming.VariableNameRule VectorIsObsolete = org.codenarc.rule.convention.VectorIsObsoleteRule VolatileArrayField = org.codenarc.rule.concurrency.VolatileArrayFieldRule VolatileLongOrDoubleField = org.codenarc.rule.concurrency.VolatileLongOrDoubleFieldRule WaitOutsideOfWhileLoop = org.codenarc.rule.concurrency.WaitOutsideOfWhileLoopRule WhileStatementBraces = org.codenarc.rule.braces.WhileStatementBracesRule CodeNarc-0.23/src/main/resources/codenarc-htmlreport.css0000644000175000017500000000436512006632012022657 0ustar ebourgebourgbody { font-family: Arial, sans-serif; margin: 20px 20px 20px 30px; } h1, h2, h3 { font-weight: bold; } h1 { width: 400px; text-align: center; color: white; background-color: #557799; padding: 10px; -moz-box-shadow: 3px 3px 4px #AAA; -webkit-box-shadow: 3px 3px 4px #AAA; box-shadow: 3px 3px 4px #AAA; border-radius: 10px; -moz-border-radius: 10px; text-shadow: 2px 2px 2px black; } h2 { font-size: 150%; margin-top: 40px; padding-top: 5px; border-top: 5px solid lightgray; } h3 { margin-left: 10px; margin-top: 30px; } a { text-decoration: underline; color: #D93544; } .logo { float: right; } .metadata { } .summary { margin-bottom: 20px; } .reportInfo { font-size: 110%; } .allPackages { font-weight: bold; } .fileHeader { font-size: 120%; font-weight: bold; } .tableHeader { font-weight: bold; } .number { text-align: center; } .priority1, .priority2, .priority3 { font-weight: bold; text-align: center; color: #990000; } .priority1 { background-color: #FFAAAA; } .priority2 { background-color: #FFCCAA; } .priority3 { background-color: #FFEEAA; } .ruleName { font-weight: bold; color: black; text-align: left; } .violationInfo { margin-bottom: 2px; margin-top: 2px; } .violationInfoPrefix { font-size: 60%; width: 30px; color: #a9a9a9; padding-right: 4px; } .sourceCode { font-family: Arial, sans-serif; font-size: 80%; color: #444444; } .violationMessage { font-style: italic; font-size: 80%; color: black; } .ruleDescriptions { font-size: 85%; } .version { margin-top: 1px; } table { border: 2px solid gray; border-collapse: collapse; -moz-box-shadow: 3px 3px 4px #AAA; -webkit-box-shadow: 3px 3px 4px #AAA; box-shadow: 3px 3px 4px #AAA; } td, th { border: 1px solid #D3D3D3; padding: 4px 20px 4px 20px; } th { text-shadow: 2px 2px 2px white; } th { border-bottom: 1px solid gray; background-color: #DDDDFF; } em, .em { font-weight: bold; }CodeNarc-0.23/src/main/resources/ruleset-schema.xsd0000644000175000017500000000565612006632014021640 0ustar ebourgebourg CodeNarc-0.23/src/main/resources/codenarc-rule-extrainfo.properties0000644000175000017500000000057312055542262025037 0ustar ebourgebourg# Optional extra information display next to rule names in the rule index and sample rule sets AbcComplexity = DEPRECATED: Use the AbcMetric rule instead. Requires the GMetrics jar AbcMetric = Requires the GMetrics jar CrapMetric = Requires the GMetrics jar and a Cobertura coverage file CyclomaticComplexity = Requires the GMetrics jar GrailsSessionReference = DEPRECATED CodeNarc-0.23/src/main/resources/codenarc-base-messages.properties0000644000175000017500000045021712450011363024606 0ustar ebourgebourgUnnecessarySafeNavigationOperator.description=Check for the safe navigation operator (?.) applied to constants and literals, which can never be null. UnnecessarySafeNavigationOperator.description.html=Check for the safe navigation operator (?.) applied to constants and literals, which can never be null. Instanceof.description=Checks for use of the instanceof operator. Use the ignoreTypeNames property to configure ignored type names. Instanceof.description.html=Checks for use of the instanceof operator. Use the ignoreTypeNames property to configure ignored type names. MultipleUnaryOperators.description=Checks for multiple consecutive unary operators. These are confusing, and are likely typos and bugs. MultipleUnaryOperators.description.html=Checks for multiple consecutive unary operators. These are confusing, and are likely typos and bugs. ToStringReturnsNull.description=Checks for toString() methods that return null. ToStringReturnsNull.description.html=Checks for toString() methods that return null. JUnitPublicProperty.description=Checks for public properties defined on JUnit test classes. There should be no need to expose a public property on a test class. JUnitPublicProperty.description.html=Checks for public properties defined on JUnit test classes. There should be no need to expose a public property on a test class. UnnecessaryToString.description=Checks for unnecessary calls to toString(). UnnecessaryToString.description.html=Checks for unnecessary calls to toString(). IllegalSubclass.description=Checks for classes that extend one of the specified set of illegal superclasses configured in superclassNames. IllegalSubclass.description.html=Checks for classes that extend one of the specified set of illegal superclasses configured in superclassNames. UnnecessaryCast.description=Checks for unnecessary cast operations UnnecessaryCast.description.html=Checks for unnecessary cast operations ExceptionExtendsThrowable.description=Checks for classes that extend Throwable. Custom exception classes should subclass Exception or one of its descendants. ExceptionExtendsThrowable.description.html=Checks for classes that extend java.lang.Throwable. Custom exception classes should subclass java.lang.Exception or one of its descendants. ClosureStatementOnOpeningLineOfMultipleLineClosure.description=Checks for closure logic on first line (after ->) for a multi-line closure. ClosureStatementOnOpeningLineOfMultipleLineClosure.description.html=Checks for closure logic on first line (after ->) for a multi-line closure. SpaceAroundMapEntryColon.description=Check for configured formatting of whitespace around colons for literal Map entries. The characterBeforeColonRegex and characterAfterColonRegex properties specify a regular expression that must match the character before/after the colon. SpaceAroundMapEntryColon.description.html=Check for configured formatting of whitespace around colons for literal Map entries. The characterBeforeColonRegex and characterAfterColonRegex properties specify a regular expression that must match the character before/after the colon. IllegalString.description=Checks for a specified illegal string within the source code. IllegalString.description.html=Checks for a specified illegal string within the source code. LocaleSetDefault.description=Checks for calls to Locale.setDefault(), which sets the Locale across the entire JVM. LocaleSetDefault.description.html=Checks for calls to Locale.setDefault(), which sets the Locale across the entire JVM. SpaceAroundClosureArrow.description=Checks that there is whitespace around the closure arrow (->) symbol SpaceAroundClosureArrow.description.html=Checks that there is whitespace around the closure arrow (->) symbol EnumCustomSerializationIgnored.description=Checks for enums that define writeObject() or writeReplace() methods, or declare serialPersistentFields or serialVersionUID fields, all of which are ignored for enums. EnumCustomSerializationIgnored.description.html=Checks for enums that define writeObject() or writeReplace() methods, or declare serialPersistentFields or serialVersionUID fields, all of which are ignored for enums. IllegalClassMember.description=Checks for classes containing fields/properties/methods matching configured illegal member modifiers or not matching any of the configured allowed member modifiers. IllegalClassMember.description.html=Checks for classes containing fields/properties/methods matching configured illegal member modifiers or not matching any of the configured allowed member modifiers. GStringExpressionWithinString.description=Check for regular (single quote) strings containing a GString-type expression (\\${...}). GStringExpressionWithinString.description.html=Check for regular (single quote) strings containing a GString-type expression (\\${...}). JUnitPublicField.description=Checks for public field on a JUnit test class JUnitPublicField.description.html=Checks for public field on a JUnit test class FactoryMethodName.description=A factory method is a method that creates objects, and they are typically named either buildFoo(), makeFoo(), or createFoo(). This rule enforces that only one naming convention is used. It defaults to makeFoo(), but that can be changed using the property 'regex'. FactoryMethodName.description.html=A factory method is a method that creates objects, and they are typically named either buildFoo(), makeFoo(), or createFoo(). This rule enforces that only one naming convention is used. It defaults to makeFoo(), but that can be changed using the property 'regex'. BuilderMethodWithSideEffects.description=A builder method is defined as one that creates objects. As such, they should never be of void return type. If a method is named build, create, or make, then it should always return a value. BuilderMethodWithSideEffects.description.html=A builder method is defined as one that creates objects. As such, they should never be of void return type. If a method is named build, create, or make, then it should always return a value. UnusedMethodParameter.description=This rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override. UnusedMethodParameter.description.html=This rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override. UnnecessaryDefInFieldDeclaration.description=If a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}. UnnecessaryDefInFieldDeclaration.description.html=If a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}. GetterMethodCouldBeProperty.description=If a class defines a public method that follows the Java getter notation, and returns a constant, then it is cleaner to provide a Groovy property for the value rather than a Groovy method. GetterMethodCouldBeProperty.description.html=If a class defines a public method that follows the Java getter notation, and returns a constant, then it is cleaner to provide a Groovy property for the value rather than a Groovy method. ConfusingMultipleReturns.description=Multiple return values can be used to set several variables at once. To use multiple return values, the left hand side of the assignment must be enclosed in parenthesis. If not, then you are not using multiple return values, you're only assigning the last element. ConfusingMultipleReturns.description.html=Multiple return values can be used to set several variables at once. To use multiple return values, the left hand side of the assignment must be enclosed in parenthesis. If not, then you are not using multiple return values, you're only assigning the last element. LongLiteralWithLowerCaseL.description=In Java and Groovy, you can specify long literals with the L or l character, for instance 55L or 24l. It is best practice to always use an uppercase L and never a lowercase l. This is because 11l rendered in some fonts may look like 111 instead of 11L. LongLiteralWithLowerCaseL.description.html=In Java and Groovy, you can specify long literals with the L or l character, for instance 55L or 24l. It is best practice to always use an uppercase L and never a lowercase l. This is because 11l rendered in some fonts may look like 111 instead of 11L. CouldBeElvis.description=Catch an if block that could be written as an elvis expression. CouldBeElvis.description.html=Catch an if block that could be written as an elvis expression. ClassJavadoc.description=Makes sure each class and interface definition is preceded by javadoc. Enum definitions are not checked, due to strange behavior in the Groovy AST. ClassJavadoc.description.html=Makes sure each class and interface definition is preceded by javadoc. Enum definitions are not checked, due to strange behavior in the Groovy AST. BlankLineBeforePackage.description=Makes sure there are no blank lines before the package declaration of a source code file. BlankLineBeforePackage.description.html=Makes sure there are no blank lines before the package declaration of a source code file. BracesForTryCatchFinally.description=Checks the location of the opening brace ({) for try statements. By default, requires them on the line, but the sameLine property can be set to false to override this. BracesForTryCatchFinally.description.html=Checks the location of the opening brace ({) for try statements. By default, requires them on the line, but the sameLine property can be set to false to override this. BracesForMethod.description=Checks the location of the opening brace ({) for constructors and methods. By default, requires them on the same line, but the sameLine property can be set to false to override this. BracesForMethod.description.html=Checks the location of the opening brace ({) for constructors and methods. By default, requires them on the same line, but the sameLine property can be set to false to override this. BracesForIfElse.description=Checks the location of the opening brace ({) for if statements. By default, requires them on the same line, but the sameLine property can be set to false to override this. BracesForIfElse.description.html=Checks the location of the opening brace ({) for if statements. By default, requires them on the same line, but the sameLine property can be set to false to override this. BracesForForLoop.description=Checks the location of the opening brace ({) for for loops. By default, requires them on the same line, but the sameLine property can be set to false to override this. BracesForForLoop.description.html=Checks the location of the opening brace ({) for for loops. By default, requires them on the same line, but the sameLine property can be set to false to override this. FileEndsWithoutNewline.description=Makes sure the source code file ends with a newline character. FileEndsWithoutNewline.description.html=Makes sure the source code file ends with a newline character. LineLength.description=Checks the maximum length for each line of source code. It checks for number of characters, so lines that include tabs may appear longer than the allowed number when viewing the file. The maximum line length can be configured by setting the length property, which defaults to 120. LineLength.description.html=Checks the maximum length for each line of source code. It checks for number of characters, so lines that include tabs may appear longer than the allowed number when viewing the file. The maximum line length can be configured by setting the length property, which defaults to 120. MissingBlankLineAfterPackage.description=Makes sure there is a blank line after the package statement of a source code file. MissingBlankLineAfterPackage.description.html=Makes sure there is a blank line after the package statement of a source code file. ConsecutiveBlankLines.description=Makes sure there are no consecutive lines that are either blank or whitespace only. ConsecutiveBlankLines.description.html=Makes sure there are no consecutive lines that are either blank or whitespace only. MissingBlankLineAfterImports.description=Makes sure there is a blank line after the imports of a source code file. MissingBlankLineAfterImports.description.html=Makes sure there is a blank line after the imports of a source code file. GrailsDomainHasToString.description=Checks that Grails domain classes redefine toString() GrailsDomainHasToString.description.html=Checks that Grails domain classes redefine toString() GrailsDomainHasEquals.description=Checks that Grails domain classes redefine equals(). GrailsDomainHasEquals.description.html=Checks that Grails domain classes redefine equals(). GrailsDomainWithServiceReference.description=Checks that Grails domain classes do not have service classes injected. GrailsDomainWithServiceReference.description.html=Checks that Grails domain classes do not have service classes injected. GrailsDomainReservedSqlKeywordName.description=Forbids usage of SQL reserved keywords as class or field names in Grails domain classes. Naming a domain class (or its field) with such a keyword causes SQL schema creation errors and/or redundant table/column name mappings. GrailsDomainReservedSqlKeywordName.description.html=Forbids usage of SQL reserved keywords as class or field names in Grails domain classes. Naming a domain class (or its field) with such a keyword causes SQL schema creation errors and/or redundant table/column name mappings. BracesForClass.description=Checks the location of the opening brace ({) for classes. By default, requires them on the same line, but the sameLine property can be set to false to override this. BracesForClass.description.html=Checks the location of the opening brace ({) for classes. By default, requires them on the same line, but the sameLine property can be set to false to override this. RandomDoubleCoercedToZero.description=The Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug. RandomDoubleCoercedToZero.description.html=The Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug. HardCodedWindowsFileSeparator.description=This rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant. HardCodedWindowsFileSeparator.description.html=This rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant. HardCodedWindowsRootDirectory.description=This rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative. HardCodedWindowsRootDirectory.description.html=This rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative. UnnecessarySubstring.description=This rule finds usages of String.substring(int) and String.substring(int, int) that can be replaced by use of the subscript operator. For instance, var.substring(5) can be replaced with var[5..-1]. UnnecessarySubstring.description.html=This rule finds usages of String.substring(int) and String.substring(int, int) that can be replaced by use of the subscript operator. For instance, var.substring(5) can be replaced with var[5..-1]. UnnecessaryInstanceOfCheck.description=This rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean. UnnecessaryInstanceOfCheck.description.html=This rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean. BitwiseOperatorInConditional.description=Checks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable. BitwiseOperatorInConditional.description.html=Checks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable. AssignCollectionSort.description=The Collections.sort() method mutates the list and returns the list as a value. If you are assigning the result of sort() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. AssignCollectionSort.description.html=The Collections.sort() method mutates the list and returns the list as a value. If you are assigning the result of sort() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. AssignCollectionUnique.description=The Collections.unique() method mutates the list and returns the list as a value. If you are assigning the result of unique() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. AssignCollectionUnique.description.html=The Collections.unique() method mutates the list and returns the list as a value. If you are assigning the result of unique() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. UnnecessaryDotClass.description=To make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String. UnnecessaryDotClass.description.html=To make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String. ClassForName.description=Using Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time. ClassForName.description.html=Using Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time. IllegalClassReference.description=Checks for reference to any of the classes configured in classNames. IllegalClassReference.description.html=Checks for reference to any of the classes configured in classNames. IllegalPackageReference.description=Checks for reference to any of the packages configured in packageNames. IllegalPackageReference.description.html=Checks for reference to any of the packages configured in packageNames. StaticSimpleDateFormatField.description=SimpleDateFormat objects should not be used as static fields. SimpleDateFormat are inherently unsafe for multi-threaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. StaticSimpleDateFormatField.description.html=SimpleDateFormat objects should not be used as static fields. SimpleDateFormat are inherently unsafe for multi-threaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. AbstractClassWithPublicConstructor.description=Checks for abstract classes that define a public constructor, which is useless and confusing. AbstractClassWithPublicConstructor.description.html=Checks for abstract classes that define a public constructor, which is useless and confusing. UnnecessaryPackageReference.description=Checks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, java.util.Map and groovy.lang.Closure. UnnecessaryPackageReference.description.html=Checks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, java.util.Map and groovy.lang.Closure. StaticConnection.description=Creates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions. StaticConnection.description.html=Creates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions. SerialPersistentFields.description=To use a Serializable object's serialPersistentFields correctly, it must be declared private, static, and final. SerialPersistentFields.description.html=To use a Serializable object's serialPersistentFields correctly, it must be declared private, static, and final. NonFinalPublicField.description=Finds code that violates secure coding principles for mobile code by declaring a member variable public but not final. NonFinalPublicField.description.html=Finds code that violates secure coding principles for mobile code by declaring a member variable public but not final. UnsafeImplementationAsMap.description=Reports incomplete interface implementations created by map-to-interface coercions. Example: [hasNext: { ... }] as Iterator (Not all Iterator methods are implemented. An UnsupportedOperationException will be thrown upon call to e.g. next().) By default, this rule does not apply to test files. UnsafeImplementationAsMap.description.html=Reports incomplete interface implementations created by map-to-interface coercions. Example: [hasNext: { ... }] as Iterator (Not all Iterator methods are implemented. An UnsupportedOperationException will be thrown upon call to e.g. next().) By default, this rule does not apply to test files. PublicInstanceField.description=Using public fields is considered to be a bad design. Use properties instead. PublicInstanceField.description.html=Using public fields is considered to be a bad design. Use properties instead. PublicFinalizeMethod.description=Creates a violation when the program violates secure coding principles by declaring a finalize() method public. PublicFinalizeMethod.description.html=Creates a violation when the program violates secure coding principles by declaring a finalize() method public. UnsafeArrayDeclaration.description=Triggers a violation when an array is declared public, final, and static. Secure coding principles state that, in most cases, an array declared public, final and static is a bug because arrays are mutable objects. UnsafeArrayDeclaration.description.html=Triggers a violation when an array is declared public, final, and static. Secure coding principles state that, in most cases, an array declared public, final and static is a bug because arrays are mutable objects. JavaIoPackageAccess.description=This rule reports violations of the Enterprise JavaBeans specification by using the java.io package to access files or the file system. JavaIoPackageAccess.description.html=This rule reports violations of the Enterprise JavaBeans specification by using the java.io package to access files or the file system. ObjectFinalize.description=The finalize() method should only be called by the JVM after the object has been garbage collected. ObjectFinalize.description.html=The finalize() method should only be called by the JVM after the object has been garbage collected. SystemExit.description=Web applications should never call System.exit(). A call to System.exit() is probably part of leftover debug code or code imported from a non-J2EE application. SystemExit.description.html=Web applications should never call System.exit(). A call to System.exit() is probably part of leftover debug code or code imported from a non-J2EE application. FileCreateTempFile.description=The File.createTempFile() method is insecure, and has been deprecated by the ESAPI secure coding library. It has been replaced by the ESAPI Randomizer.getRandomFilename(String) method. FileCreateTempFile.description.html=The File.createTempFile() method is insecure, and has been deprecated by the ESAPI secure coding library. It has been replaced by the ESAPI Randomizer.getRandomFilename(String) method. ComparisonOfTwoConstants.description=Checks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values, e.g.: 23 == 67, Boolean.FALSE != false, 0.17 <= 0.99, "abc" > "ddd", [a:1] <=> [a:2], [1,2].equals([3,4]) or [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE], where x is a variable. ComparisonOfTwoConstants.description.html=Checks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values., e.g.: 23 == 67, Boolean.FALSE != false, 0.17 <= 0.99, "abc" > "ddd", [a:1] <=> [a:2], [1,2].equals([3,4]) or [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE]. ComparisonWithSelf.description=Checks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x >= x, x.equals(x) or x.compareTo(x), where x is a variable. ComparisonWithSelf.description.html=Checks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x =>= x, x.equals(x) or x.compareTo(x), where x is a variable. DirectConnectionManagement.description=The J2EE standard requires that applications use the container's resource management facilities to obtain connections to resources. Every major web application container provides pooled database connection management as part of its resource management framework. Duplicating this functionality in an application is difficult and error prone, which is part of the reason it is forbidden under the J2EE standard. DirectConnectionManagement.description.html=The J2EE standard requires that applications use the container's resource management facilities to obtain connections to resources. Every major web application container provides pooled database connection management as part of its resource management framework. Duplicating this functionality in an application is difficult and error prone, which is part of the reason it is forbidden under the J2EE standard. JdbcConnectionReference.description=Check for direct use of java.sql.Connection, which is discouraged and almost never necessary in application code. JdbcConnectionReference.description.html=Check for direct use of java.sql.Connection, which is discouraged and almost never necessary in application code. JdbcResultSetReference.description=Check for direct use of java.sql.ResultSet, which is not necessary if using the Groovy Sql facility or an ORM framework such as Hibernate. JdbcResultSetReference.description.html=Check for direct use of java.sql.ResultSet, which is not necessary if using the Groovy Sql facility or an ORM framework such as Hibernate. JdbcStatementReference.description=Check for direct use of java.sql.Statement, java.sql.PreparedStatement, or java.sql.CallableStatement, which is not necessary if using the Groovy Sql facility or an ORM framework such as Hibernate. JdbcStatementReference.description.html=Check for direct use of java.sql.Statement, java.sql.PreparedStatement, or java.sql.CallableStatement, which is not necessary if using the Groovy Sql facility or an ORM framework such as Hibernate. InsecureRandom.description=Reports usages of java.util.Random, which can produce very predictable results. If two instances of Random are created with the same seed and sequence of method calls, they will generate the exact same results. Use java.security.SecureRandom instead, which provides a cryptographically strong random number generator. SecureRandom uses PRNG, which means they are using a deterministic algorithm to produce a pseudo-random number from a true random seed. SecureRandom produces non-deterministic output. InsecureRandom.description.html=Reports usages of java.util.Random, which can produce very predictable results. If two instances of Random are created with the same seed and sequence of method calls, they will generate the exact same results. Use java.security.SecureRandom instead, which provides a cryptographically strong random number generator. SecureRandom uses PRNG, which means they are using a deterministic algorithm to produce a pseudo-random number from a true random seed. SecureRandom produces non-deterministic output. UnnecessaryFinalOnPrivateMethod.description=A private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary. UnnecessaryFinalOnPrivateMethod.description.html=A private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary. ImportFromSunPackages.description=Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change. ImportFromSunPackages.description.html=Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change. DuplicateSetValue.description=A Set literal is created with duplicate constant value. A set cannot contain two elements with the same value. DuplicateSetValue.description.html=A Set literal is created with duplicate constant value. A set cannot contain two elements with the same value. NonFinalSubclassOfSensitiveInterface.description=The permissions classes such as java.security.Permission and java.security.BasicPermission are designed to be extended. Classes that derive from these permissions classes, however, must prohibit extension. This prohibition ensures that malicious subclasses cannot change the properties of the derived class. Classes that implement sensitive interfaces such as java.security.PrivilegedAction and java.security.PrivilegedActionException must also be declared final for analogous reasons. NonFinalSubclassOfSensitiveInterface.description.html=The permissions classes such as java.security.Permission and java.security.BasicPermission are designed to be extended. Classes that derive from these permissions classes, however, must prohibit extension. This prohibition ensures that malicious subclasses cannot change the properties of the derived class. Classes that implement sensitive interfaces such as java.security.PrivilegedAction and java.security.PrivilegedActionException must also be declared final for analogous reasons. DuplicateMapKey.description=A map literal is created with duplicated key. The map entry will be overwritten. DuplicateMapKey.description.html=A map literal is created with duplicated key. The map entry will be overwritten. EqualsOverloaded.description=The class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it. EqualsOverloaded.description.html=The class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it. UnnecessaryGString.description=String objects should be created with single quotes, and GString objects created with double quotes. Creating normal String objects with double quotes is confusing to readers. UnnecessaryGString.description.html=String objects should be created with single quotes, and GString objects created with double quotes. Creating normal String objects with double quotes is confusing to readers. UnnecessarySemicolon.description=Semicolons as line terminators are not required in Groovy: remove them. Do not use a semicolon as a replacement for empty braces on for and while loops; this is a confusing practice. UnnecessarySemicolon.description.html=Semicolons as line terminators are not required in Groovy: remove them. Do not use a semicolon as a replacement for empty braces on for and while loops; this is a confusing practice. UnnecessaryDefInMethodDeclaration.description=If a method has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'. UnnecessaryDefInMethodDeclaration.description.html=If a method has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'. UnnecessaryDefInVariableDeclaration.description=If a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'. UnnecessaryDefInVariableDeclaration.description.html=If a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'. UnnecessaryPublicModifier.description=The 'public' modifier is not required on methods or classes. UnnecessaryPublicModifier.description.html=The 'public' modifier is not required on methods or classes. SpockIgnoreRestUsed.description=If Spock's @IgnoreRest appears on any method, all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed. SpockIgnoreRestUsed.description.html=If Spock's @IgnoreRest appears on any method, all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed. CoupledTestCase.description=This rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused. CoupledTestCase.description.html=This rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused. ChainedTest.description=A test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another. ChainedTest.description.html=A test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another. IntegerGetInteger.description=This rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop']. IntegerGetInteger.description.html=This rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop']. BooleanGetBoolean.description=This rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop']. BooleanGetBoolean.description.html=This rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop']. GroovyLangImmutable.description=The groovy.lang.Immutable annotation has been deprecated and replaced by groovy.transform.Immutable. Do not use the Immutable in groovy.lang. GroovyLangImmutable.description.html=The groovy.lang.Immutable annotation has been deprecated and replaced by groovy.transform.Immutable. Do not use the Immutable in groovy.lang. UnnecessaryFail.description=In a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all. UnnecessaryFail.description.html=In a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all. DoubleCheckedLocking.description=This rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern. DoubleCheckedLocking.description.html=This rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern. BusyWait.description=Busy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package. BusyWait.description.html=Busy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package. AssignmentInConditional.description=An assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended. AssignmentInConditional.description.html=An assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended. SynchronizedOnReentrantLock.description=Synchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method. SynchronizedOnReentrantLock.description.html=Synchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method. StaticMatcherField.description=Matcher objects should not be used as static fields. Matcher instances are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. StaticMatcherField.description.html=Matcher objects should not be used as static fields. Matcher instances are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. VolatileArrayField.description=Volatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not. VolatileArrayField.description.html=Volatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not. SynchronizedOnBoxedPrimitive.description=The code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock SynchronizedOnBoxedPrimitive.description.html=The code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock InconsistentPropertyLocking.description=Class contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all. InconsistentPropertyLocking.description.html=Class contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all. InconsistentPropertySynchronization.description=Class contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not. InconsistentPropertySynchronization.description.html=Class contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not. UnnecessaryTransientModifier.description=The field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect. UnnecessaryTransientModifier.description.html=The field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect. UnnecessarySelfAssignment.description=Method contains a pointless self-assignment to a variable or property. UnnecessarySelfAssignment.description.html=Method contains a pointless self-assignment to a variable or property. SynchronizedReadObjectMethod.description=Catches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style. SynchronizedReadObjectMethod.description.html=Catches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style. SynchronizedOnString.description=Synchronization on a String field can lead to deadlock because Strings are interned by the JVM and can be shared. SynchronizedOnString.description.html=Synchronization on a String field can lead to deadlock because Strings are interned by the JVM and can be shared. UnnecessaryCallToSubstring.description=Calling String.substring(0) always returns the original string. This code is meaningless. UnnecessaryCallToSubstring.description.html=Calling String.substring(0) always returns the original string. This code is meaningless. BrokenOddnessCheck.description=The code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0. BrokenOddnessCheck.description.html=The code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0. StaticDateFormatField.description=DateFormat objects should not be used as static fields. DateFormat are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. StaticDateFormatField.description.html=DateFormat objects should not be used as static fields. DateFormat are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. StaticCalendarField.description=Calendar objects should not be used as static fields. Calendars are inherently unsafe for multihtreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. StaticCalendarField.description.html=Calendar objects should not be used as static fields. Calendars are inherently unsafe for multihtreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. UnnecessaryModOne.description=Any expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2). UnnecessaryModOne.description.html=Any expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2). AddEmptyString.description=Finds empty string literals which are being added. This is an inefficient way to convert any type to a String. AddEmptyString.description.html=Finds empty string literals which are being added. This is an inefficient way to convert any type to a String. ConsecutiveStringConcatenation.description=Catches concatenation of two string literals on the same line. These can safely by joined. ConsecutiveStringConcatenation.description.html=Catches concatenation of two string literals on the same line. These can safely by joined. ConsecutiveLiteralAppends.description=Violations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation. ConsecutiveLiteralAppends.description.html=Violations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation. EmptyMethod.description=A method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation. EmptyMethod.description.html=A method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation. EmptyStaticInitializer.description=An empty static initializer was found. It is safe to remove it. EmptyStaticInitializer.description.html=An empty static initializer was found. It is safe to remove it. EmptyInstanceInitializer.description=An empty class instance initializer was found. It is safe to remove it. EmptyInstanceInitializer.description.html=An empty class instance initializer was found. It is safe to remove it. SerializableClassMustDefineSerialVersionUID.description=Classes that implement Serializable should define a serialVersionUID. If you don't define serialVersionUID, the system will make one by hashing most of your class's features. Then if you change anything, the UID will change and Java won't let you reload old data. SerializableClassMustDefineSerialVersionUID.description.html=Classes that implement Serializable should define a serialVersionUID. If you don't define serialVersionUID, the system will make one by hashing most of your class's features. Then if you change anything, the UID will change and Java won't let you reload old data. ThisReferenceEscapesConstructor.description=Reports constructors passing the 'this' reference to other methods. This equals exposing a half-baked objects and can lead to race conditions during initialization. For reference, see 'Java Concurrency Gotchas' by Alex Miller (http://www.slideshare.net/alexmiller/java-concurrency-gotchas-3666977/38) and 'Java theory and practice: Safe construction techniques' by Brian Goetz (http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html). ThisReferenceEscapesConstructor.description.html=Reports constructors passing the 'this' reference to other methods. This equals exposing a half-baked objects and can lead to race conditions during initialization. For reference, see Java Concurrency Gotchas by Alex Miller and Java theory and practice: Safe construction techniques by Brian Goetz. ThreadGroup.description=Avoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe. ThreadGroup.description.html=Avoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe. BigDecimalInstantiation.description=Checks for calls to the BigDecimal constructors that take a double parameter, which may result in an unexpected BigDecimal value. BigDecimalInstantiation.description.html=Checks for calls to the BigDecimal constructors that take a double parameter, which may result in an unexpected BigDecimal value. BooleanMethodReturnsNull.description=Method with Boolean return type returns explicit null. A method that returns either Boolean.TRUE, Boolean.FALSE or null is an accident waiting to happen. This method can be invoked as though it returned a value of type boolean, and the compiler will insert automatic unboxing of the Boolean value. If a null value is returned, this will result in a NullPointerException. BooleanMethodReturnsNull.description.html=Method with Boolean return type returns explicit null. A method that returns either Boolean.TRUE, Boolean.FALSE or null is an accident waiting to happen. This method can be invoked as though it returned a value of type boolean, and the compiler will insert automatic unboxing of the Boolean value. If a null value is returned, this will result in a NullPointerException. CloneableWithoutClone.description=A class that implements java.lang.Cloneable should define a clone() method. CloneableWithoutClone.description.html=A class that implements java.lang.Cloneable should define a clone() method. CloneWithoutCloneable.description=The method clone() should only be declared if the class implements the Cloneable interface. CloneWithoutCloneable.description.html=The method clone() should only be declared if the class implements the Cloneable interface. CollectAllIsDeprecated.description=collectAll{} is deprecated since Groovy 1.8.1. Use collectNested instead{}. CollectAllIsDeprecated.description.html=collectAll{} is deprecated since Groovy 1.8.1. Use collectNested instead{}. CompareToWithoutComparable.description=If you implement a compareTo method then you should also implement the Comparable interface. If you don't then you could possibly get an exception if the Groovy == operator is invoked on your object. This is an issue fixed in Groovy 1.8 but present in previous versions. CompareToWithoutComparable.description.html=If you implement a compareTo method then you should also implement the Comparable interface. If you don't then you could possibly get an exception if the Groovy == operator is invoked on your object. This is an issue fixed in Groovy 1.8 but present in previous versions. ConfusingTernary.description=In a ternary expression avoid negation in the test. For example, rephrase: "(x != y) ? diff : same" as: "(x == y) ? same : diff". Consistent use of this rule makes the code easier to read. Also, this resolves trivial ordering problems, such as "does the error case go first?" or "does the common case go first?". ConfusingTernary.description.html=In a ternary expression avoid negation in the test. For example, rephrase: "(x != y) ? diff : same" as: "(x == y) ? same : diff". Consistent use of this rule makes the code easier to read. Also, this resolves trivial ordering problems, such as "does the error case go first?" or "does the common case go first?". ConstantIfExpression.description=Checks for if statements with a constant value for the if expression, such as true, false, null, or a literal constant value. ConstantIfExpression.description.html=Checks for if statements with a constant value for the if expression, such as true, false, null, or a literal constant value. ConstantTernaryExpression.description=Checks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value. ConstantTernaryExpression.description.html=Checks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value. DeadCode.description=Dead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted. DeadCode.description.html=Dead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted. DoubleNegative.description=There is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well. DoubleNegative.description.html=There is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well. NestedForLoop.description=Reports classes with nested for loops. NestedForLoop.description.html=Reports classes with nested for loops. DuplicateCaseStatement.description=Check for duplicate case statements in a switch block, such as two equal integers or strings. DuplicateCaseStatement.description.html=Check for duplicate case statements in a switch block, such as two equal integers or strings. EmptyCatchBlock.description=In most cases, exceptions should not be caught and ignored (swallowed). EmptyCatchBlock.description.html=In most cases, exceptions should not be caught and ignored (swallowed). EmptyClass.description=Reports classes without methods, fields or properties. Why would you need a class like this? EmptyClass.description.html=Reports classes without methods, fields or properties. Why would you need a class like this? EmptyTryBlock.description=Empty try blocks are confusing and serve no purpose. EmptyTryBlock.description.html=Empty try blocks are confusing and serve no purpose. EmptyFinallyBlock.description=Empty finally blocks are confusing and serve no purpose. EmptyFinallyBlock.description.html=Empty finally blocks are confusing and serve no purpose. EmptyIfStatement.description=Empty if statements are confusing and serve no purpose. EmptyIfStatement.description.html=Empty if statements are confusing and serve no purpose. EmptyElseBlock.description=Empty else blocks are confusing and serve no purpose. EmptyElseBlock.description.html=Empty else blocks are confusing and serve no purpose. EmptyForStatement.description=Empty for statements are confusing and serve no purpose. EmptyForStatement.description.html=Empty for statements are confusing and serve no purpose. EmptySwitchStatement.description=Empty switch statements are confusing and serve no purpose. EmptySwitchStatement.description.html=Empty switch statements are confusing and serve no purpose. EmptyWhileStatement.description=Empty while statements are confusing and serve no purpose. EmptyWhileStatement.description.html=Empty while statements are confusing and serve no purpose. EmptySynchronizedStatement.description=Empty synchronized statements are confusing and serve no purpose. EmptySynchronizedStatement.description.html=Empty synchronized statements are confusing and serve no purpose. EqualsAndHashCode.description=If either the equals(Object) or the hashCode() methods are overridden within a class, then both must be overridden. EqualsAndHashCode.description.html=If either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden. ExplicitArrayListInstantiation.description=This rule checks for the explicit instantiation of a ArrayList using the no-arg constructor. In Groovy, it is best to write "new ArrayList()" as "[]", which creates the same object. ExplicitArrayListInstantiation.description.html=This rule checks for the explicit instantiation of an ArrayList using the no-arg constructor. In Groovy, it is best to write new ArrayList() as [], which creates the same object. ExplicitCallToModMethod.description=This rule detects when the mod(Object) method is called directly in code instead of using the % operator. A groovier way to express this: a.mod(b) is this: a % b ExplicitCallToModMethod.description.html=This rule detects when the mod(Object) method is called directly in code instead of using the % operator. A groovier way to express this: a.mod(b) is this: a % b ExplicitCallToPowerMethod.description=This rule detects when the power(Object) method is called directly in code instead of using the ** operator. A groovier way to express this: a.power(b) is this: a ** b ExplicitCallToPowerMethod.description.html=This rule detects when the power(Object) method is called directly in code instead of using the ** operator. A groovier way to express this: a.power(b) is this: a ** b ExplicitCallToDivMethod.description=This rule detects when the div(Object) method is called directly in code instead of using the / operator. A groovier way to express this: a.div(b) is this: a / b ExplicitCallToDivMethod.description.html=This rule detects when the div(Object) method is called directly in code instead of using the / operator. A groovier way to express this: a.div(b) is this: a / b ExplicitCallToMultiplyMethod.description=This rule detects when the minus(Object) method is called directly in code instead of using the * operator. A groovier way to express this: a.multiply(b) is this: a * b ExplicitCallToMultiplyMethod.description.html=This rule detects when the minus(Object) method is called directly in code instead of using the * operator. A groovier way to express this: a.multiply(b) is this: a * b ExplicitCallToMinusMethod.description=This rule detects when the minus(Object) method is called directly in code instead of using the - operator. A groovier way to express this: a.minus(b) is this: a - b ExplicitCallToMinusMethod.description.html=This rule detects when the minus(Object) method is called directly in code instead of using the - operator. A groovier way to express this: a.minus(b) is this: a - b ExplicitCallToRightShiftMethod.description=This rule detects when the rightShift(Object) method is called directly in code instead of using the >> operator. A groovier way to express this: a.rightShift(b) is this: a >> b ExplicitCallToRightShiftMethod.description.html=This rule detects when the rightShift(Object) method is called directly in code instead of using the >> operator. A groovier way to express this: a.rightShift(b) is this: a >> b ExplicitCallToLeftShiftMethod.description=This rule detects when the leftShift(Object) method is called directly in code instead of using the << operator. A groovier way to express this: a.leftShift(b) is this: a << b ExplicitCallToLeftShiftMethod.description.html=This rule detects when the leftShift(Object) method is called directly in code instead of using the << operator. A groovier way to express this: a.leftShift(b) is this: a << b ExplicitCallToGetAtMethod.description=This rule detects when the getAt(Object) method is called directly in code instead of using the [] index operator. A groovier way to express this: a.getAt(b) is this: a[b] ExplicitCallToGetAtMethod.description.html=This rule detects when the getAt(Object) method is called directly in code instead of using the [] index operator. A groovier way to express this: a.getAt(b) is this: a[b] ExplicitCallToXorMethod.description=This rule detects when the xor(Object) method is called directly in code instead of using the ^ operator. A groovier way to express this: a.xor(b) is this: a ^ b ExplicitCallToXorMethod.description.html=This rule detects when the xor(Object) method is called directly in code instead of using the ^ operator. A groovier way to express this: a.xor(b) is this: a ^ b ExplicitCallToAndMethod.description=This rule detects when the and(Object) method is called directly in code instead of using the & operator. A groovier way to express this: a.and(b) is this: a & b ExplicitCallToAndMethod.description.html=This rule detects when the and(Object) method is called directly in code instead of using the & operator. A groovier way to express this: a.and(b) is this: a & b ExplicitCallToOrMethod.description=This rule detects when the or(Object) method is called directly in code instead of using the | operator. A groovier way to express this: a.or(b) is this: a | b ExplicitCallToOrMethod.description.html=This rule detects when the or(Object) method is called directly in code instead of using the | operator. A groovier way to express this: a.or(b) is this: a | b ExplicitCallToPlusMethod.description=This rule detects when the plus(Object) method is called directly in code instead of using the + operator. A groovier way to express this: a.plus(b) is this: a + b ExplicitCallToPlusMethod.description.html=This rule detects when the plus(Object) method is called directly in code instead of using the + operator. A groovier way to express this: a.plus(b) is this: a + b ExplicitCallToEqualsMethod.description=This rule detects when the equals(Object) method is called directly in code instead of using the == or != operator. A groovier way to express this: a.equals(b) is this: a == b and a groovier way to express : !a.equals(b) is : a != b ExplicitCallToEqualsMethod.description.html=This rule detects when the equals(Object) method is called directly in code instead of using the == or != operator. A groovier way to express this: a.equals(b) is this: a == b and a groovier way to express : !a.equals(b) is : a != b ExplicitCallToCompareToMethod.description=This rule detects when the compareTo(Object) method is called directly in code instead of using the <=>, >, >=, <, and <= operators. A groovier way to express this: a.compareTo(b) is this: a <=> b, or using the other operators. ExplicitCallToCompareToMethod.description.html=This rule detects when the compareTo(Object) method is called directly in code instead of using the <=>, >, >=, <, and <= operators. A groovier way to express this: a.compareTo(b) is this: a <=> b, or using the other operators. ExplicitGarbageCollection.description=Calls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself. ExplicitGarbageCollection.description.html=Calls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself. ExplicitHashMapInstantiation.description=This rule checks for the explicit instantiation of a HashMap using the no-arg constructor. In Groovy, it is best to write "new HashMap()" as "[:]", which creates the same object. ExplicitHashMapInstantiation.description.html=This rule checks for the explicit instantiation of a HashMap using the no-arg constructor. In Groovy, it is best to write new HashMap() as [:], which creates the same object. ExplicitLinkedHashMapInstantiation.description=This rule checks for the explicit instantiation of a LinkedHashMap using the no-arg constructor. In Groovy, it is best to write "new LinkedHashMap()" as "[:]", which creates the same object. ExplicitLinkedHashMapInstantiation.description.html=This rule checks for the explicit instantiation of a LinkedHashMap using the no-arg constructor. In Groovy, it is best to write new LinkedHashMap() as [:], which creates the same object. ExplicitHashSetInstantiation.description=This rule checks for the explicit instantiation of a HashSet using the no-arg constructor. In Groovy, it is best to write "new HashSet()" as "[] as Set", which creates the same object. ExplicitHashSetInstantiation.description.html=This rule checks for the explicit instantiation of a HashSet using the no-arg constructor. In Groovy, it is best to write new HashSet() as [] as Set, which creates the same object. ExplicitLinkedListInstantiation.description=This rule checks for the explicit instantiation of a LinkedList using the no-arg constructor. In Groovy, it is best to write "new LinkedList()" as "[] as Queue", which creates the same object. ExplicitLinkedListInstantiation.description.html=This rule checks for the explicit instantiation of a LinkedList using the no-arg constructor. In Groovy, it is best to write new LinkedList() as [] as Queue, which creates the same object. ExplicitStackInstantiation.description=This rule checks for the explicit instantiation of a Stack using the no-arg constructor. In Groovy, it is best to write "new Stack()" as "[] as Stack", which creates the same object. ExplicitStackInstantiation.description.html=This rule checks for the explicit instantiation of a Stack using the no-arg constructor. In Groovy, it is best to write new Stack() as [] as Stack, which creates the same object. ExplicitTreeSetInstantiation.description=This rule checks for the explicit instantiation of a TreeSet using the no-arg constructor. In Groovy, it is best to write "new TreeSet()" as "[] as SortedSet", which creates the same object. ExplicitTreeSetInstantiation.description.html=This rule checks for the explicit instantiation of a TreeSet using the no-arg constructor. In Groovy, it is best to write new TreeSet() as [] as SortedSet, which creates the same object. ForLoopShouldBeWhileLoop.description=A for loop without an init and update statement can be simplified to a while loop. ForLoopShouldBeWhileLoop.description.html=A for loop without an init and update statement can be simplified to a while loop. GStringAsMapKey.description=A GString should not be used as a map key since its hashcode is not guaranteed to be stable. Consider calling key.toString(). GStringAsMapKey.description.html=A GString should not be used as a map key since its hashcode is not guaranteed to be stable. Consider calling key.toString(). InvertedIfElse.description=An inverted if-else statement is one in which there is a single if statement with a single else branch and the boolean test of the if is negated. For instance "if (!x) false else true". It is usually clearer to write this as "if (x) true else false". InvertedIfElse.description.html=An inverted if-else statement is one in which there is a single if statement with a single else branch and the boolean test of the if is negated. For instance if (!x) false else true. It is usually clearer to write this as if (x) true else false. RemoveAllOnSelf.description=Don't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException. RemoveAllOnSelf.description.html=Don't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException. ReturnFromFinallyBlock.description=Returning from a finally block is confusing and can hide the original exception. ReturnFromFinallyBlock.description.html=Returning from a finally block is confusing and can hide the original exception. ReturnsNullInsteadOfEmptyArray.description=Consider returning a zero length array rather than null. It is often a better design to return a length zero array rather than a null reference to indicate that there are no results (i.e., an empty list of results). This way, no explicit check for null is needed by clients of the method. ReturnsNullInsteadOfEmptyArray.description.html=Consider returning a zero length array rather than null. It is often a better design to return a length zero array rather than a null reference to indicate that there are no results (i.e., an empty list of results). This way, no explicit check for null is needed by clients of the method. ReturnsNullInsteadOfEmptyCollection.description=Consider returning a zero length collection rather than null. It is often a better design to return a length zero collection rather than a null reference to indicate that there are no results (i.e., an empty list of results). This way, no explicit check for null is needed by clients of the method. ReturnsNullInsteadOfEmptyCollection.description.html=Consider returning a zero length collection rather than null. It is often a better design to return a length zero collection rather than a null reference to indicate that there are no results (i.e., an empty list of results). This way, no explicit check for null is needed by clients of the method. SerialVersionUID.description=A serialVersionUID is normally intended to be used with Serialization. It needs to be of type long, static, and final. Also, it should have a visibility modifier such as public or private. Providing no modifier creates a Property and Groovy generates a getter, which is probably not intended. SerialVersionUID.description.html=A serialVersionUID is normally intended to be used with Serialization. It needs to be of type long, static, and final. Also, it should have a visibility modifier such as public or private. Providing no modifier creates a Property and Groovy generates a getter, which is probably not intended. SimpleDateFormatMissingLocale.description=Be sure to specify a Locale when creating a new instance of SimpleDateFormat; the class is locale-sensitive. If you instantiate SimpleDateFormat without a Locale parameter, it will format the date and time according to the default Locale. Both the pattern and the Locale determine the format. For the same pattern, SimpleDateFormat may format a date and time differently if the Locale varies. SimpleDateFormatMissingLocale.description.html=Be sure to specify a Locale when creating a new instance of SimpleDateFormat; the class is locale-sensitive. If you instantiate SimpleDateFormat without a Locale parameter, it will format the date and time according to the default Locale. Both the pattern and the Locale determine the format. For the same pattern, SimpleDateFormat may format a date and time differently if the Locale varies. ThrowExceptionFromFinallyBlock.description=Throwing an exception from a finally block is confusing and can hide the original exception. ThrowExceptionFromFinallyBlock.description.html=Throwing an exception from a finally block is confusing and can hide the original exception. UnsafeCallToNegativeOffset.description=This possible warns of referencing the element at the index of -1 in an Array or List. It is possible to get the last element of a list by calling list[-1], however an empty list will throw an exception for this operation. It is usually better to use the last() method on the list or array to access the last element. The last() method returns the last element of the collection or null if not found. UnsafeCallToNegativeOffset.description.html=This possible warns of referencing the element at the index of -1 in an Array or List. It is possible to get the last element of a list by calling list[-1], however an empty list will throw an exception for this operation. It is usually better to use the last() method on the list or array to access the last element. The last() method returns the last element of the collection or null if not found. UseCollectMany.description=In many case collectMany() yields the same result as collect{}.flatten(). It is easier to understand and more clearly conveys the intent. UseCollectMany.description.html=In many case collectMany() yields the same result as collect{}.flatten(). It is easier to understand and more clearly conveys the intent. UseCollectNested.description=Instead of nested collect{}-calls use collectNested{} UseCollectNested.description.html=Instead of nested collect{}-calls use collectNested{} ClosureAsLastMethodParameter.description=If a method is called and the last parameter is an inline closure then it can be declared outside of the method call brackets. ClosureAsLastMethodParameter.description.html=If a method is called and the last parameter is an inline closure then it can be declared outside of the method call brackets. ElseBlockBraces.description=Use braces for else blocks, even for a single statement. By default, braces are not required for an else if it is followed immediately by an if. Set the bracesRequiredForElseIf property to true to require braces is that situation as well. ElseBlockBraces.description.html=Use braces for else blocks, even for a single statement. By default, braces are not required for an else if it is followed immediately by an if. Set the bracesRequiredForElseIf property to true to require braces is that situation as well. ForStatementBraces.description=Use braces for for statements, even for a single statement. ForStatementBraces.description.html=Use braces for for statements, even for a single statement. IfStatementBraces.description=Use braces for if statements, even for a single statement. IfStatementBraces.description.html=Use braces for if statements, even for a single statement. WhileStatementBraces.description=Use braces for while statements, even for a single statement. WhileStatementBraces.description.html=Use braces for while statements, even for a single statement. NestedSynchronization.description=Nested synchronized statements should be avoided. Nested synchronized statements are either useless (if the lock objects are identical) or prone to deadlock. NestedSynchronization.description.html=Nested synchronized statements should be avoided. Nested synchronized statements are either useless (if the lock objects are identical) or prone to deadlock. SynchronizedMethod.description=This rule reports uses of the synchronized keyword on methods. Synchronized methods are the same as synchronizing on 'this', which effectively make your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects. SynchronizedMethod.description.html=This rule reports uses of the synchronized keyword on methods. Synchronized methods are the same as synchronizing on 'this', which effectively make your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects. SynchronizedOnGetClass.description=Synchronization on getClass rather than class literal. This instance method synchronizes on this.getClass(). If this class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended. SynchronizedOnGetClass.description.html=Synchronization on getClass rather than class literal. This instance method synchronizes on this.getClass(). If this class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended. SynchronizedOnThis.description=This rule reports uses of the synchronized blocks where the synchronization reference is 'this'. Doing this effectively makes your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects. SynchronizedOnThis.description.html=This rule reports uses of the synchronized blocks where the synchronization reference is 'this'. Doing this effectively makes your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects. SystemRunFinalizersOnExit.description=Method calls to System.runFinalizersOnExit() should not be allowed. This method is inherently non-thread-safe, may result in data corruption, deadlock, and may effect parts of the program far removed from it's call point. It is deprecated, and it's use strongly discouraged. SystemRunFinalizersOnExit.description.html=Method calls to System.runFinalizersOnExit() should not be allowed. This method is inherently non-thread-safe, may result in data corruption, deadlock, and may effect parts of the program far removed from it's call point. It is deprecated, and it's use strongly discouraged. ThreadYield.description=Method calls to Thread.yield() should not be allowed. This method has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions. ThreadYield.description.html=Method calls to Thread.yield() should not be allowed. This method has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions. ThreadLocalNotStaticFinal.description=ThreadLocal fields should be static and final. In the most common case a java.lang.ThreadLocal instance associates state with a thread. A non-static non-final java.lang.ThreadLocal field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior. ThreadLocalNotStaticFinal.description.html=ThreadLocal fields should be static and final. In the most common case a java.lang.ThreadLocal instance associates state with a thread. A non-static non-final java.lang.ThreadLocal field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior. UseOfNotifyMethod.description=This code calls notify() rather than notifyAll(). Java monitors are often used for multiple conditions. Calling notify() only wakes up one thread, meaning that the thread woken up might not be the one waiting for the condition that the caller just satisfied. UseOfNotifyMethod.description.html=This code calls notify() rather than notifyAll(). Java monitors are often used for multiple conditions. Calling notify() only wakes up one thread, meaning that the thread woken up might not be the one waiting for the condition that the caller just satisfied. VolatileLongOrDoubleField.description=Long or double fields should not be declared as volatile. Java specifies that reads and writes from such fields are atomic, but many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronize access to such fields rather than declare them volatile. This rule flags fields marked volatile when their type is double or long or the name of their type is "Double" or "Long". VolatileLongOrDoubleField.description.html=Long or double fields should not be declared as volatile. Java specifies that reads and writes from such fields are atomic, but many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronize access to such fields rather than declare them volatile. This rule flags fields marked volatile when their type is double or long or the name of their type is "Double" or "Long". AbstractClassWithoutAbstractMethod.description=The abstract class does not contain any abstract methods. An abstract class suggests an incomplete implementation, which is to be completed by subclasses implementing the abstract methods. If the class is intended to be used as a base class only (not to be instantiated direcly) a protected constructor can be provided prevent direct instantiation. AbstractClassWithoutAbstractMethod.description.html=The abstract class does not contain any abstract methods. An abstract class suggests an incomplete implementation, which is to be completed by subclasses implementing the abstract methods. If the class is intended to be used as a base class only (not to be instantiated direcly) a protected constructor can be provided prevent direct instantiation. CloseWithoutCloseable.description=If a class defines a "void close()" then that class should implement java.io.Closeable. CloseWithoutCloseable.description.html=If a class defines a "void close()" then that class should implement java.io.Closeable. ConstantsOnlyInterface.description=An interface should be used only to model a behaviour of a class: using an interface as a container of constants is a poor usage pattern. ConstantsOnlyInterface.description.html=An interface should be used only to model a behaviour of a class: using an interface as a container of constants is a poor usage pattern. EmptyMethodInAbstractClass.description=An empty method in an abstract class should be abstract instead, as developer may rely on this empty implementation rather than code the appropriate one. EmptyMethodInAbstractClass.description.html=An empty method in an abstract class should be abstract instead, as developer may rely on this empty implementation rather than code the appropriate one. FinalClassWithProtectedMember.description=This rule finds classes marked final that contain protected methods. If a class is final then it may not be subclassed, and there is therefore no point in having a method with protected visibility. Either the class should not be final or the method should be private or protected. FinalClassWithProtectedMember.description.html=This rule finds classes marked final that contain protected methods. If a class is final then it may not be subclassed, and there is therefore no point in having a method with protected visibility. Either the class should not be final or the method should be private or protected. ImplementationAsType.description=Checks for use of a predefined set of concrete classes (e.g. ArrayList, Hashtable, ConcurrentHashMap) when specifying the type of a method parameter, closure parameter, constructor parameter, method return type or field type. The associated interfaces should be used to specify the type instead. ImplementationAsType.description.html=Checks for use of a predefined set of concrete classes (e.g. ArrayList, Hashtable, ConcurrentHashMap) when specifying the type of a method parameter, closure parameter, constructor parameter, method return type or field type. The associated interfaces should be used to specify the type instead. DuplicateNumberLiteral.description=Code containing duplicate number literals can usually be improved by declaring the number as a constant field. The ignoreNumbers property (${rule.ignoreNumbers}) can optionally specify a comma-separated list of numbers to ignore. DuplicateNumberLiteral.description.html=Code containing number String literals can usually be improved by declaring the number as a constant field. The ignoreNumbers property (${rule.ignoreNumbers}) can optionally specify a comma-separated list of numbers to ignore. DuplicateStringLiteral.description=Code containing duplicate String literals can usually be improved by declaring the String as a constant field. The ignoreStrings property (${rule.ignoreStrings}) can optionally specify a comma-separated list of Strings to ignore. DuplicateStringLiteral.description.html=Code containing duplicate String literals can usually be improved by declaring the String as a constant field. The ignoreStrings property (${rule.ignoreStrings}) can optionally specify a comma-separated list of Strings to ignore. DuplicateListLiteral.description=Code containing duplicate List literals can usually be improved by declaring the List as a constant field. DuplicateListLiteral.description.html=Code containing duplicate List literals can usually be improved by declaring the List as a constant field. DuplicateMapLiteral.description=Code containing duplicate Map literals can usually be improved by declaring the Map as a constant field. DuplicateMapLiteral.description.html=Code containing duplicate Map literals can usually be improved by declaring the Map as a constant field. CatchArrayIndexOutOfBoundsException.description=Check the size of the array before accessing an array element rather than catching ArrayIndexOutOfBoundsException. CatchArrayIndexOutOfBoundsException.description.html=Check the size of the array before accessing an array element rather than catching ArrayIndexOutOfBoundsException. CatchError.description=Catching Error is dangerous; it can catch exceptions such as ThreadDeath and OutOfMemoryError. CatchError.description.html=Catching Error is dangerous; it can catch exceptions such as ThreadDeath and OutOfMemoryError. CatchException.description=Catching Exception is often too broad or general. It should usually be restricted to framework or infrastructure code, rather than application code. CatchException.description.html=Catching Exception is often too broad or general. It should usually be restricted to framework or infrastructure code, rather than application code. CatchIllegalMonitorStateException.description=Dubious catching of IllegalMonitorStateException. IllegalMonitorStateException is generally only thrown in case of a design flaw in your code (calling wait or notify on an object you do not hold a lock on). CatchIllegalMonitorStateException.description.html=Dubious catching of IllegalMonitorStateException. IllegalMonitorStateException is generally only thrown in case of a design flaw in your code (calling wait or notify on an object you do not hold a lock on). CatchIndexOutOfBoundsException.description=Check that an index is valid before accessing an indexed element rather than catching IndexOutOfBoundsException. CatchIndexOutOfBoundsException.description.html=Check that an index is valid before accessing an indexed element rather than catching IndexOutOfBoundsException. CatchNullPointerException.description=Catching NullPointerException is never appropriate. It should be avoided in the first place with proper null checking, and it can mask underlying errors. CatchNullPointerException.description.html=Catching NullPointerException is never appropriate. It should be avoided in the first place with proper null checking, and it can mask underlying errors. CatchRuntimeException.description=Catching RuntimeException is often too broad or general. It should usually be restricted to framework or infrastructure code, rather than application code. CatchRuntimeException.description.html=Catching RuntimeException is often too broad or general. It should usually be restricted to framework or infrastructure code, rather than application code. CatchThrowable.description=Catching Throwable is dangerous; it can catch exceptions such as ThreadDeath and OutOfMemoryError. CatchThrowable.description.html=Catching Throwable is dangerous; it can catch exceptions such as ThreadDeath and OutOfMemoryError. ConfusingClassNamedException.description=This class is not derived from another exception, but ends with 'Exception'. This will be confusing to users of this class. ConfusingClassNamedException.description.html=This class is not derived from another exception, but ends with 'Exception'. This will be confusing to users of this class. ExceptionExtendsError.description=Errors are system exceptions. Do not extend them. ExceptionExtendsError.description.html=Errors are system exceptions. Do not extend them. MissingNewInThrowStatement.description=A common Groovy mistake when throwing exceptions is to forget the new keyword. For instance, "throw RuntimeException()" instead of "throw new RuntimeException()". If the error path is not unit tested then the production system will throw a Method Missing exception and hide the root cause. This rule finds constructs like "throw RuntimeException()" that look like a new keyword was meant to be used but forgotten. MissingNewInThrowStatement.description.html=A common Groovy mistake when throwing exceptions is to forget the new keyword. For instance, "throw RuntimeException()" instead of "throw new RuntimeException()". If the error path is not unit tested then the production system will throw a Method Missing exception and hide the root cause. This rule finds constructs like "throw RuntimeException()" that look like a new keyword was meant to be used but forgotten. ReturnNullFromCatchBlock.description=Returning null from a catch block often masks errors and requires the client to handle error codes. In some coding styles this is discouraged. ReturnNullFromCatchBlock.description.html=Returning null from a catch block often masks errors and requires the client to handle error codes. In some coding styles this is discouraged. ThrowError.description=Checks for throwing an instance of java.lang.Error. ThrowError.description.html=Checks for throwing an instance of java.lang.Error. ThrowException.description=Checks for throwing an instance of java.lang.Exception. ThrowException.description.html=Checks for throwing an instance of java.lang.Exception. ThrowNullPointerException.description=Checks for throwing an instance of java.lang.NullPointerException. ThrowNullPointerException.description.html=Checks for throwing an instance of java.lang.NullPointerException. ThrowRuntimeException.description=Checks for throwing an instance of java.lang.RuntimeException. ThrowRuntimeException.description.html=Checks for throwing an instance of java.lang.RuntimeException. ThrowThrowable.description=Checks for throwing an instance of java.lang.Throwable. ThrowThrowable.description.html=Checks for throwing an instance of java.lang.Throwable. IllegalRegex.description=Checks for a specified illegal regular expression within the source code. The regex property specifies the regular expression to check for. It is required and cannot be null or empty. IllegalRegex.description.html=Checks for a specified illegal regular expression within the source code. The regex property specifies the regular expression to check for. It is required and cannot be null or empty. RequiredRegex.description=Checks for a specified regular expression that must exist within the source code. The regex property specifies the regular expression to check for. It is required and cannot be null or empty. RequiredRegex.description.html=Checks for a specified regular expression that must exist within the source code. The regex property specifies the regular expression to check for. It is required and cannot be null or empty. RequiredString.description=Checks for a specified text string that must exist within the source code. The string property specifies the String to check for. It is required and cannot be null or empty. RequiredString.description.html=Checks for a specified text string that must exist within the source code. The string property specifies the String to check for. It is required and cannot be null or empty. StatelessClass.description=Checks for fields on classes that should remain "stateless" and reentrant. The ignoreFieldNames property (${rule.ignoreFieldNames}) specifies one or more field names that should be ignored. The ignoreFieldTypes property specifies one or more field type names that should be ignored. Both can optionally contain wildcard characters ('*' or '?'). StatelessClass.description.html=Checks for fields on classes that should remain "stateless" and reentrant. The ignoreFieldNames property (${rule.ignoreFieldNames}) specifies one or more field names that should be ignored. The ignoreFieldTypes property specifies one or more field type names that should be ignored. Both can optionally contain wildcard characters ('*' or '?'). GrailsPublicControllerMethod.description=Checks for public methods on Grails controller classes. Static methods are ignored. GrailsPublicControllerMethod.description.html=Checks for public methods on Grails controller classes. Static methods are ignored. GrailsSessionReference.description=Checks for references to the session object from within Grails controller and taglib classes. [DEPRECATED] GrailsSessionReference.description.html=Checks for references to the session object from within Grails controller and taglib classes. [DEPRECATED] GrailsServletContextReference.description=Checks for references to the servletContext object from within Grails controller and taglib classes. GrailsServletContextReference.description.html=Checks for references to the servletContext object from within Grails controller and taglib classes. GrailsStatelessService.description=Checks for fields on Grails service classes. Grails service classes are singletons, by default, and so they should be reentrant and typically stateless. The ignoreFieldNames property (${rule.ignoreFieldNames}) specifies one or more field names that should be ignored. The ignoreFieldTypes property (${rule.ignoreFieldTypes}) specifies one or more field type names that should be ignored. Both can optionally contain wildcard characters ('*' or '?'). GrailsStatelessService.description.html=Checks for fields on Grails service classes. Grails service classes are singletons, by default, and so they should be reentrant and typically stateless. The ignoreFieldNames property (${rule.ignoreFieldNames}) specifies one or more field names that should be ignored. The ignoreFieldTypes property (${rule.ignoreFieldTypes}) specifies one or more field type names that should be ignored. Both can optionally contain wildcard characters ('*' or '?'). DuplicateImport.description=Duplicate import statements are unnecessary. DuplicateImport.description.html=Duplicate import statements are unnecessary. UnnecessaryInstantiationToGetClass.description=Avoid instantiating an object just to call getClass() on it; use the .class public member instead. UnnecessaryInstantiationToGetClass.description.html=Avoid instantiating an object just to call getClass() on it; use the .class public member instead. ImportFromSamePackage.description=An import of a class that is within the same package is unnecessary. ImportFromSamePackage.description.html=An import of a class that is within the same package is unnecessary. UnnecessaryGroovyImport.description=A Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger. UnnecessaryGroovyImport.description.html=A Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger. UnusedImport.description=Imports for a class that is never referenced within the source file is unnecessary. UnusedImport.description.html=Imports for a class that is never referenced within the source file is unnecessary. MisorderedStaticImports.description=Static imports should never be declared after nonstatic imports. MisorderedStaticImports.description.html=Static imports should never be declared after nonstatic imports. NoWildcardImports.description=Wildcard imports, static or otherwise, should not be used. NoWildcardImports.description.html=Wildcard imports, static or otherwise, should not be used. JUnitSetUpCallsSuper.description=Checks that if the JUnit setUp() method is defined, that it includes a call to super.setUp(). JUnitSetUpCallsSuper.description.html=Checks that if the JUnit setUp() method is defined, that it includes a call to super.setUp(). JUnitTearDownCallsSuper.description=Checks that if the JUnit tearDown() method is defined, that it includes a call to super.tearDown(). JUnitTearDownCallsSuper.description.html=Checks that if the JUnit tearDown() method is defined, that it includes a call to super.tearDown(). JUnitAssertAlwaysFails.description=Checks for JUnit assert() method calls with constant arguments such that the assertion always fails. This includes: assertTrue(false), assertFalse(true) and assertNull(CONSTANT). JUnitAssertAlwaysFails.description.html=Checks for JUnit assert() method calls with constant arguments such that the assertion always fails. This includes: assertTrue(false), assertFalse(true) and assertNull(CONSTANT). JUnitAssertAlwaysSucceeds.description=Checks for JUnit assert() method calls with constant arguments such that the assertion always succeeds. This includes: assertTrue(true), assertFalse(false) and assertNull(null). JUnitAssertAlwaysSucceeds.description.html=Checks for JUnit assert() method calls with constant arguments such that the assertion always succeeds. This includes: assertTrue(true), assertFalse(false) and assertNull(null). JUnitAssertEqualsConstantActualValue.description=Reports usages of org.junit.Assert.assertEquals([message,] expected, actual) where the 'actual' parameter is a constant or a literal. Most likely it was intended to be the 'expected' value. JUnitAssertEqualsConstantActualValue.description.html=Reports usages of org.junit.Assert.assertEquals([message,] expected, actual) where the 'actual' parameter is a constant or a literal. Most likely it was intended to be the 'expected' value. JUnitPublicNonTestMethod.description=Checks if a JUnit test class contains public methods other than standard test methods, JUnit framework methods or methods with JUnit annotations. JUnitPublicNonTestMethod.description.html=Checks if a JUnit test class contains public methods other than standard test methods, JUnit framework methods or methods with JUnit annotations. JUnitStyleAssertions.description=This rule detects calling JUnit style assertions like assertEquals, assertTrue, assertFalse, assertNull, assertNotNull. Groovy 1.7 ships with a feature called the "power assert", which is an assert statement with better error reporting. This is preferable to the JUnit assertions. JUnitStyleAssertions.description.html=This rule detects calling JUnit style assertions like assertEquals, assertTrue, assertFalse, assertNull, assertNotNull. Groovy 1.7 ships with a feature called the "power assert", which is an assert statement with better error reporting. This is preferable to the JUnit assertions. JUnitUnnecessarySetUp.description=Checks for JUnit setUp() methods that contain only a call to super.setUp(). JUnitUnnecessarySetUp.description.html=Checks for JUnit setUp() methods that contain only a call to super.setUp(). JUnitUnnecessaryTearDown.description=Checks for JUnit tearDown() methods that contain only a call to super.tearDown(). JUnitUnnecessaryTearDown.description.html=Checks for JUnit tearDown() methods that contain only a call to super.tearDown(). UseAssertEqualsInsteadOfAssertTrue.description=This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals. UseAssertEqualsInsteadOfAssertTrue.description.html=This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals. UseAssertNullInsteadOfAssertEquals.description=This rule detects JUnit calling assertEquals where the first or second parameter is null. These assertion should be made against the assertNull method instead. UseAssertNullInsteadOfAssertEquals.description.html=This rule detects JUnit calling assertEquals where the first or second parameter is null. These assertion should be made against the assertNull method instead. UseAssertSameInsteadOfAssertTrue.description=This rule detects JUnit calling assertTrue where the first or second parameter is an Object#is() call testing for reference equality. These assertion should be made against the assertSame method instead. UseAssertSameInsteadOfAssertTrue.description.html=This rule detects JUnit calling assertTrue where the first or second parameter is an Object#is() call testing for reference equality. These assertion should be made against the assertSame method instead. UseAssertFalseInsteadOfNegation.description=In unit tests, if a condition is expected to be false then there is no sense using assertTrue with the negation operator. For instance, assertTrue(!condition) can always be simplified to assertFalse(condition) UseAssertFalseInsteadOfNegation.description.html=In unit tests, if a condition is expected to be false then there is no sense using assertTrue with the negation operator. For instance, assertTrue(!condition) can always be simplified to assertFalse(condition) UseAssertTrueInsteadOfAssertEquals.description=This rule detects JUnit calling assertEquals where the first parameter is a boolean. These assertions should be made by more specific methods, like assertTrue or assertFalse. UseAssertTrueInsteadOfAssertEquals.description.html=This rule detects JUnit calling assertEquals where the first parameter is a boolean. These assertions should be made by more specific methods, like assertTrue or assertFalse. UseAssertTrueInsteadOfNegation.description=In unit tests, if a condition is expected to be true then there is no sense using assertFalse with the negation operator. For instance, assertFalse(!condition) can always be simplified to assertTrue(condition) UseAssertTrueInsteadOfNegation.description.html=In unit tests, if a condition is expected to be true then there is no sense using assertFalse with the negation operator. For instance, assertFalse(!condition) can always be simplified to assertTrue(condition) JUnitFailWithoutMessage.description=This rule detects JUnit calling the fail() method without an argument. For better error reporting you should always provide a message. JUnitFailWithoutMessage.description.html=This rule detects JUnit calling the fail() method without an argument. For better error reporting you should always provide a message. JUnitTestMethodWithoutAssert.description=This rule searches for test methods that do not contain assert statements. Either the test method is missing assert statements, which is an error, or the test method contains custom assert statements that do not follow a proper assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test annotation. By default this rule applies to the default test class names, but this can be changed using the rule's applyToClassNames property. JUnitTestMethodWithoutAssert.description.html=This rule searches for test methods that do not contain assert statements. Either the test method is missing assert statements, which is an error, or the test method contains custom assert statements that do not follow a proper assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test annotation. By default this rule applies to the default test class names, but this can be changed using the rule's applyToClassNames property. LoggerForDifferentClass.description=Checks for instantiating a logger (Log4J, SLF4J, Logback, Apache Commons Logging or Java Util Logging) for a class other than the current class. LoggerForDifferentClass.description.html=Checks for instantiating a logger (Log4J, SLF4J, Logback, Apache Commons Logging or Java Util Logging) for a class other than the current class. LoggingSwallowsStacktrace.description=If you are logging an exception then the proper API is to call error(Object, Throwable), which will log the message and the exception stack trace. If you call error(Object) then the stacktrace may not be logged. LoggingSwallowsStacktrace.description.html=If you are logging an exception then the proper API is to call error(Object, Throwable), which will log the message and the exception stack trace. If you call error(Object) then the stacktrace may not be logged. LoggerWithWrongModifiers.description=Logger objects should be declared private, static and final. If subclasses should have access to a Logger in a parent class then the Logger should be declared protected, non-static and final. This rule find loggers that are not declared with these modifiers. LoggerWithWrongModifiers.description.html=Logger objects should be declared private, static and final. If subclasses should have access to a Logger in a parent class then the Logger should be declared protected, non-static and final. This rule find loggers that are not declared with these modifiers. MultipleLoggers.description=This rule catches classes that have more than one logger object defined. Typically, a class has zero or one logger objects. MultipleLoggers.description.html=This rule catches classes that have more than one logger object defined. Typically, a class has zero or one logger objects. PrintStackTrace.description=Checks for calls to printStackTrace(). PrintStackTrace.description.html=Checks for calls to printStackTrace(). Println.description=Checks for calls to this.print(), this.println() or this.printf(). Println.description.html=Checks for calls to this.print(), this.println() or this.printf(). SystemErrPrint.description=Checks for calls to System.err.print(), System.err.println() or System.err.printf(). SystemErrPrint.description.html=Checks for calls to System.err.print(), System.err.println() or System.err.printf(). SystemOutPrint.description=Checks for calls to System.out.print(), System.out.println() or System.out.printf(). SystemOutPrint.description.html=Checks for calls to System.out.print(), System.out.println() or System.out.printf(). AbstractClassName.description=Verifies that the name of an abstract class matches a regular expression specified in the regex property. If that property is null or empty, then this rule is not applied (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. This rule ignores interfaces. AbstractClassName.description.html=Verifies that the name of an abstract class matches a regular expression specified in the regex property. If that property is null or empty, then this rule is not applied (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. This rule ignores interfaces. ClassName.description=Verifies that the name of a class matches a regular expression. By default it checks that the class name starts with an uppercase letter and is followed by zero or more word characters (letters, numbers or underscores). The regex property specifies the regular expression used to validate the class name. ClassName.description.html=Verifies that the name of a class matches a regular expression. By default it checks that the class name starts with an uppercase letter and is followed by zero or more word characters (letters, numbers or underscores). The regex property specifies the regular expression used to validate the class name. ClassNameSameAsFilename.description=Reports files containing only one top level class / enum / interface which is named differently than the file. ClassNameSameAsFilename.description.html=Reports files containing only one top level class / enum / interface which is named differently than the file. FieldName.description=Verifies that the name of each field matches a regular expression. By default it checks that non-'final' field names start with a lowercase letter and contains only letters or numbers, and 'final' field names start with an uppercase letter and contain only uppercase letters, numbers and underscores. The regex property specifies the default regular expression used to validate field names. The finalRegex property specifies the regular expression to validate 'final' field names. The staticRegex property specifies the regular expression to validate 'static' field names. The staticFinalRegex property specifies the regular expression to validate 'static final' field names. The ignoreFieldNames property (${rule.ignoreFieldNames}) can specify field names that should be ignored, optionally containing wildcard characters ('*' or '?'). FieldName.description.html=Verifies that the name of each field matches a regular expression. By default it checks that non-'final' field names start with a lowercase letter and contains only letters or numbers, and 'final' field names start with an uppercase letter and contain only uppercase letters, numbers and underscores. The regex property specifies the default regular expression used to validate field names. The finalRegex property specifies the regular expression to validate 'final' field names. The staticRegex property specifies the regular expression to validate 'static' field names. The staticFinalRegex property specifies the regular expression to validate 'static final' field names. The ignoreFieldNames property (${rule.ignoreFieldNames})can specify field names that should be ignored, optionally containing wildcard characters ('*' or '?'). InterfaceName.description=Verifies that the name of an interface matches a regular expression specified in the regex property. If that property is null or empty, then this rule is not applied (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. InterfaceName.description.html=Verifies that the name of an interface matches a regular expression specified in the regex property. If that property is null or empty, then this rule is not applied (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. MethodName.description=Verifies that the name of each method matches a regular expression. By default it checks that the method name starts with a lowercase letter. The regex property specifies the regular expression to check the method name against. The ignoreMethodNames property (${rule.ignoreMethodNames}) can specify method names that should be ignored, optionally containing wildcard characters ('*' or '?'). MethodName.description.html=Verifies that the name of each method matches a regular expression. By default it checks that the method name starts with a lowercase letter. The regex property specifies the regular expression to check the method name against. The ignoreMethodNames property (${rule.ignoreMethodNames}) can specify method names that should be ignored, optionally containing wildcard characters ('*' or '?'). ObjectOverrideMisspelledMethodName.description=Verifies that the names of the most commonly overridden methods of Object: equals, hashCode and toString, are correct. ObjectOverrideMisspelledMethodName.description.html=Verifies that the names of the most commonly overridden methods of Object: equals, hashCode and toString, are correct. PackageName.description=Verifies that the package name for a class matches a regular expression. By default it checks that the package name consists of only lowercase letters, separated by periods. The regex property specifies the regular expression used to validate the package name. The packageNameRequired property indicates whether a package name declaration is required for all classes. PackageName.description.html=Verifies that the package name for a class matches a regular expression. By default it checks that the package name consists of only lowercase letters, separated by periods. The regex property specifies the regular expression used to validate the package name. The packageNameRequired property indicates whether a package name declaration is required for all classes. PackageNameMatchesFilePath.description=A package source file's path should match the package itself. To find the package-relevant subpath in the file path the groupId needs to be configured. It is expected in every package declaration. PackageNameMatchesFilePath.description.html=A package source file's path should match the package itself. To find the package-relevant subpath in the file path the groupId needs to be configured. It is expected in every package declaration. ParameterName.description=Verifies that the name of each parameter matches a regular expression. This rule applies to method parameters, constructor parameters and closure parameters. By default it checks that parameter names start with a lowercase letter and contains only letters or numbers. The regex property specifies the default regular expression used to validate the parameter name. The ignoreParameterNames property (${rule.ignoreParameterNames}) can specify parameter names that should be ignored, optionally containing wildcard characters ('*' or '?'). ParameterName.description.html=Verifies that the name of each parameter matches a regular expression. This rule applies to method parameters, constructor parameters and closure parameters. By default it checks that parameter names start with a lowercase letter and contains only letters or numbers. The regex property specifies the default regular expression used to validate the parameter name. The ignoreParameterNames property (${rule.ignoreParameterNames}) can specify parameter names that should be ignored, optionally containing wildcard characters ('*' or '?'). VariableName.description=Verifies that the name of each method matches a regular expression. By default it checks that non-'final' variable names start with a lowercase letter and contains only letters or numbers, and 'final' variable names start with an uppercase letter and contain only uppercase letters, numbers and underscores. The regex property specifies the default regular expression used to validate a non-'final' variable name. The finalRegex property specifies the regular expression used to validate 'final' variable names. The ignoreVariableNames property (${rule.ignoreVariableNames}) can specify variable names that should be ignored, optionally containing wildcard characters ('*' or '?'). VariableName.description.html=Verifies that the name of each method matches a regular expression. By default it checks that non-'final' variable names start with a lowercase letter and contains only letters or numbers, and 'final' variable names start with an uppercase letter and contain only uppercase letters, numbers and underscores. The regex property specifies the default regular expression used to validate a non-'final' variable name. The finalRegex property specifies the regular expression used to validate 'final' variable names. The ignoreVariableNames property (${rule.ignoreVariableNames}) can specify variable names that should be ignored, optionally containing wildcard characters ('*' or '?'). PropertyName.description=Verifies that the name of each property matches a regular expression. By default it checks that property names other than 'static final' start with a lowercase letter and contains only letters or numbers, and 'static final' property names start with an uppercase letter and contain only uppercase letters, numbers and underscores. The regex property specifies the default regular expression used to validate property names. The finalRegex property specifies the regular expression to validate 'final' property names. The staticRegex property specifies the regular expression to validate 'static' property names. The staticFinalRegex property specifies the regular expression to validate 'static final' property names. The ignorePropertyNames property (${rule.ignorePropertyNames}) can specify property names that should be ignored, optionally containing wildcard characters ('*' or '?'). PropertyName.description.html=Verifies that the name of each property matches a regular expression. By default it checks that property names other than 'static final' start with a lowercase letter and contains only letters or numbers, and 'static final' property names start with an uppercase letter and contain only uppercase letters, numbers and underscores. The regex property specifies the default regular expression used to validate property names. The finalRegex property specifies the regular expression to validate 'final' property names. The staticRegex property specifies the regular expression to validate 'static' property names. The staticFinalRegex property specifies the regular expression to validate 'static final' property names. The ignorePropertyNames property (${rule.ignorePropertyNames}) can specify property names that should be ignored, optionally containing wildcard characters ('*' or '?'). ConfusingMethodName.description=Checks for confusing method names. The referenced methods have names that differ only by capitalization. This is very confusing because if the capitalization were identical then one of the methods would override the other. ConfusingMethodName.description.html=Checks for confusing method names. The referenced methods have names that differ only by capitalization. This is very confusing because if the capitalization were identical then one of the methods would override the other. AbcComplexity.description=Checks the ABC metric of size/complexity for methods/classes.\ A method (or "closure field") with an ABC complexity value (score) greater than the maxMethodComplexity \ property (${rule.maxMethodComplexity}) causes a violation. Likewise, a class that has an (average method) ABC complexity\ value greater than the maxClassAverageMethodComplexity property (${rule.maxClassAverageMethodComplexity}) causes a violation. [DEPRECATED: Use AbcMetric rule instead] AbcComplexity.description.html=Checks the ABC metric of size/complexity for methods/classes.\ A method (or "closure field") with an ABC complexity value (score) greater than the maxMethodComplexity \ property (${rule.maxMethodComplexity}) causes a violation. Likewise, a class that has an (average method) ABC complexity\ value greater than the maxClassAverageMethodComplexity property (${rule.maxClassAverageMethodComplexity}) causes a violation. [DEPRECATED: Use AbcMetric rule instead] AbcMetric.description=Checks the ABC size metric for methods/classes. \ A method (or "closure field") with an ABC score greater than the maxMethodAbcScore \ property (${rule.maxMethodAbcScore}) causes a violation. Likewise, a class that has an (average method) ABC score \ greater than the maxClassAverageMethodAbcScore property (${rule.maxClassAverageMethodAbcScore}) causes a violation. AbcMetric.description.html=Checks the ABC size metric for methods/classes. \ A method (or "closure field") with an ABC score greater than the maxMethodAbcScore \ property (${rule.maxMethodAbcScore}) causes a violation. Likewise, a class that has an (average method) ABC score \ greater than the maxClassAverageMethodAbcScore property (${rule.maxClassAverageMethodAbcScore}) causes a violation. ClassSize.description=Checks if the size of a class exceeds the number of lines specified by the maxLines property (${rule.maxLines}). ClassSize.description.html=Checks if the size of a class exceeds the number of lines specified by the maxLines property (${rule.maxLines}). CyclomaticComplexity.description=Checks the cyclomatic complexity for methods/classes.\ A method (or "closure field") with a cyclomatic complexity value greater than the maxMethodComplexity \ property (${rule.maxMethodComplexity}) causes a violation. Likewise, a class that has an (average method) cyclomatic complexity\ value greater than the maxClassAverageMethodComplexity property (${rule.maxClassAverageMethodComplexity}) causes a violation. CyclomaticComplexity.description.html=Checks the cyclomatic complexity for methods/classes.\ A method (or "closure field") with a cyclomatic complexity value greater than the maxMethodComplexity \ property (${rule.maxMethodComplexity}) causes a violation. Likewise, a class that has an (average method) cyclomatic complexity\ value greater than the maxClassAverageMethodComplexity property (${rule.maxClassAverageMethodComplexity}) causes a violation. MethodCount.description=A class with too many methods is probably a good suspect for refactoring, in order to reduce its \ complexity and find a way to have more fine grained objects. The maxMethods property (${rule.maxMethods}) specifies the threshold. MethodCount.description.html=A class with too many methods is probably a good suspect for refactoring, in order to reduce its \ complexity and find a way to have more fine grained objects.The maxMethods property (${rule.maxMethods}) specifies the threshold. MethodSize.description=Checks if the size of a method exceeds the number of lines specified by the maxLines property (${rule.maxLines}). MethodSize.description.html=Checks if the size of a method exceeds the number of lines specified by the maxLines property (${rule.maxLines}). NestedBlockDepth.description=Checks for blocks or closures nested more than maxNestedBlockDepth (${rule.maxNestedBlockDepth}) levels deep. NestedBlockDepth.description.html=Checks for blocks or closures nested more than maxNestedBlockDepth (${rule.maxNestedBlockDepth}) levels deep. ParameterCount.description=Checks if the number of parameters in method/constructor exceeds the number of parameters specified by the maxParameters property. ParameterCount.description.html=Checks if the number of parameters in method/constructor exceeds the number of parameters specified by the maxParameters property. UnnecessaryBigDecimalInstantiation.description=It is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G. UnnecessaryBigDecimalInstantiation.description.html=It is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G. UnnecessaryBigIntegerInstantiation.description=It is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G. UnnecessaryBigIntegerInstantiation.description.html=It is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G. UnnecessaryBooleanExpression.description=Checks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or a Map/List/String/Number literal. Also checks for negation (!) of true, false, null, or a Map/List/String/Number literal. UnnecessaryBooleanExpression.description.html=Checks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or a Map/List/String/Number literal. Also checks for negation (!) of true, false, null, or a Map/List/String/Number literal. UnnecessaryBooleanInstantiation.description=Use Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false). UnnecessaryBooleanInstantiation.description.html=Use Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false). UnnecessaryCallForLastElement.description=This rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a get, getAt, or array-style access is used with an object size check. UnnecessaryCallForLastElement.description.html=This rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a get, getAt, or array-style access is used with an object size check. UnnecessaryConstructor.description=This rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments. UnnecessaryConstructor.description.html=This rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments. UnnecessaryDoubleInstantiation.description=It is unnecessary to instantiate Double objects. Instead just use the double literal or the 'D' identifier to force the type, such as 123.45d or 0.42d. UnnecessaryDoubleInstantiation.description.html=It is unnecessary to instantiate Double objects. Instead just use the double literal or the 'D' identifier to force the type, such as 123.45d or 0.42d. UnnecessaryFloatInstantiation.description=It is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f. UnnecessaryFloatInstantiation.description.html=It is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f. UnnecessaryGetter.description=Checks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). Getters do not take method arguments. UnnecessaryGetter.description.html=Checks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). Getters do not take method arguments. UnnecessaryIfStatement.description=Checks for if statements where the if and else blocks (or subsequent fall-through to a return), are merely returning true and false constants. These cases can be replaced by a simple return statement. UnnecessaryIfStatement.description.html=Checks for if statements where the if and else blocks (or subsequent fall-through to a return) are merely returning true and false constants. These cases can be replaced by a simple return statement. UnnecessaryNullCheck.description=Groovy contains the safe dereference operator, which can be used in boolean conditional statements to safely replace explicit "x == null" tests. UnnecessaryNullCheck.description.html=Groovy contains the safe dereference operator, which can be used in boolean conditional statements to safely replace explicit "x == null" tests. UnnecessaryNullCheckBeforeInstanceOf.description=There is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument. UnnecessaryNullCheckBeforeInstanceOf.description.html=There is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument. UnnecessaryObjectReferences.description=Violations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block. UnnecessaryObjectReferences.description.html=Violations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block. UnnecessaryTernaryExpression.description=Checks for ternary expressions where the conditional expression always evaluates to a boolean and the true and false expressions are merely returning true and false constants. Also checks for ternary expressions where both expressions are the same constant or variable. UnnecessaryTernaryExpression.description.html=Checks for ternary expressions where the conditional expression always evaluates to a boolean and the true and false expressions are merely returning true and false constants. Also checks for ternary expressions where both expressions are the same constant or variable. UnnecessaryReturnKeyword.description=In Groovy, the return keyword is often optional. If a statement is the last line in a method or closure then you do not need to have the return keyword. UnnecessaryReturnKeyword.description.html=In Groovy, the return keyword is often optional. If a statement is the last line in a method or closure then you do not need to have the return keyword. UnnecessaryIntegerInstantiation.description=It is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i. UnnecessaryIntegerInstantiation.description.html=It is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i. UnnecessaryLongInstantiation.description=It is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L. UnnecessaryLongInstantiation.description.html=It is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L. UnnecessaryOverridingMethod.description=The overriding method merely calls the same method defined in a superclass UnnecessaryOverridingMethod.description.html=The overriding method merely calls the same method defined in a superclass UnnecessaryCollectionCall.description=Useless call to collections. This call doesn't make sense. For any collection c, calling c.containsAll(c) should always be true, and c.retainAll(c) should have no effect. UnnecessaryCollectionCall.description.html=Useless call to collections. This call doesn't make sense. For any collection c, calling c.containsAll(c) should always be true, and c.retainAll(c) should have no effect. UnnecessaryCatchBlock.description=Violations are triggered when a catch block does nothing but throw the original exception. In this scenario there is usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out. UnnecessaryCatchBlock.description.html=Violations are triggered when a catch block does nothing but throw the original exception. In this scenario there is usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out. UnnecessaryCollectCall.description=Some method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect { it.multiply(2) } can be replaced by list*.multiply(2). Warning: if a collection is null, collect will return an empty list, while *. will return null. UnnecessaryCollectCall.description.html=Some method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect { it.multiply(2) } can be replaced by list*.multiply(2). Warning: if a collection is null, collect will return an empty list, while *. will return null. UnnecessaryStringInstantiation.description=Use a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly. UnnecessaryStringInstantiation.description.html=Use a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly. UnnecessaryElseStatement.description=When an if statement block ends with a return statement the else is unnecessary. The logic in the else branch can be run without being in a new scope. UnnecessaryElseStatement.description.html=When an if statement block ends with a return statement the else is unnecessary. The logic in the else branch can be run without being in a new scope. UnnecessaryParenthesesForMethodCallWithClosure.description=If a method is called and the only parameter to that method is an inline closure then the parentheses of the method call can be omitted. UnnecessaryParenthesesForMethodCallWithClosure.description.html=If a method is called and the only parameter to that method is an inline closure then the parentheses of the method call can be omitted. UnusedArray.description=Checks for array allocations that are not assigned or used, unless it is the last statement within a block. UnusedArray.description.html=Checks for array allocations that are not assigned or used, unless it is the last statement within a block. UnusedObject.description=Checks for object allocations that are not assigned or used, unless it is the last statement within a block. UnusedObject.description.html=Checks for object allocations that are not assigned or used, unless it is the last statement within a block UnusedPrivateField.description=Checks for private fields that are not referenced within the same class. UnusedPrivateField.description.html=Checks for private fields that are not referenced within the same class. UnusedPrivateMethod.description=Checks for private methods that are not referenced within the same class. UnusedPrivateMethod.description.html=Checks for private methods that are not referenced within the same class. UnusedPrivateMethodParameter.description=Checks for parameters to private methods that are not referenced within the method body. UnusedPrivateMethodParameter.description.html=Checks for parameters to private methods that are not referenced within the method body. UnusedVariable.description=Checks for variables that are never referenced. The ignoreVariableNames property (${rule.ignoreVariableNames}) specifies one or more variable names that should be ignored, optionally containing wildcard characters ('*' or '?'). UnusedVariable.description.html=Checks for variables that are never referenced. The ignoreVariableNames property (${rule.ignoreVariableNames}) specifies one or more variable names that should be ignored, optionally containing wildcard characters ('*' or '?'). WaitOutsideOfWhileLoop.description=Calls to Object.wait() must be within a while loop. Consider using the Java concurrency utilities instead of wait() and notify(). WaitOutsideOfWhileLoop.description.html=Calls to Object.wait() must be within a while loop. Consider using the Java concurrency utilities instead of wait() and notify(). SwallowThreadDeath.description=Checks for code that catches ThreadDeath without re-throwing it. SwallowThreadDeath.description.html=Checks for code that catches ThreadDeath without re-throwing it. StatelessSingleton.description=There is no point in creating a stateless Singleton because there is nothing within the class that needs guarding and no side effects to calling the constructor. Just create new instances of the object or write a Utility class with static methods. StatelessSingleton.description.html=There is no point in creating a stateless Singleton because there is nothing within the class that needs guarding and no side effects to calling the constructor. Just create new instances of the object or write a Utility class with static methods. PrivateFieldCouldBeFinal.description=Checks for private fields that are only set within a constructor or field initializer. Such fields can safely be made final. PrivateFieldCouldBeFinal.description.html=Checks for private fields that are only set within a constructor or field initializer. Such fields can safely be made final. ParameterReassignment.description=Checks for a method or closure parameter being reassigned to a new value within the body of the method/closure, which is a confusing and questionable practice. Use a temporary variable instead. ParameterReassignment.description.html=Checks for a method or closure parameter being reassigned to a new value within the body of the method/closure, which is a confusing and questionable practice. Use a temporary variable instead. TernaryCouldBeElvis.description=Checks for ternary expressions where the boolean and true expressions are the same. These can be simplified to an Elvis expression. TernaryCouldBeElvis.description.html=Checks for ternary expressions where the boolean and true expressions are the same. These can be simplified to an Elvis expression. AssertWithinFinallyBlock.description=Checks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one. AssertWithinFinallyBlock.description.html=Checks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one. ConstantAssertExpression.description=Checks for assert statements where the assert boolean condition expression is a constant or literal value. ConstantAssertExpression.description.html=Checks for assert statements where the assert boolean condition expression is a constant or literal value. BrokenNullCheck.description=Looks for faulty checks for null that can cause a NullPointerException. BrokenNullCheck.description.html=Looks for faulty checks for null that can cause a NullPointerException. VectorIsObsolete.description=The java.util.Vector class is effectively obsolete. Use the Java Collections Framework classes instead, including ArrayList or Collections.synchronizedList(). See the JDK javadoc. VectorIsObsolete.description.html=The java.util.Vector class is effectively obsolete. Use the Java Collections Framework classes instead, including ArrayList or Collections.synchronizedList(). See the JDK javadoc. HashtableIsObsolete.description=The java.util.Hashtable class is effectively obsolete. Use the Java Collections Framework classes instead, including HashMap or ConcurrentHashMap. See the JDK javadoc. HashtableIsObsolete.description.html=The java.util.Hashtable class is effectively obsolete. Use the Java Collections Framework classes instead, including HashMap or ConcurrentHashMap. See the JDK javadoc. CrapMetric.description=Checks the CRAP (Change Risk Anti-Patterns) score for methods/classes. \ The CRAP metric score is based on the cyclomatic complexity and test coverage for individual methods. \ A method with a CRAP value greater than the maxMethodCrapScore \ property (${rule.maxMethodCrapScore}) causes a violation. Likewise, a class that has an (average method) CRAP \ value greater than the maxClassAverageMethodCrapScore property (${rule.maxClassAverageMethodCrapScore}) causes a violation. CrapMetric.description.html=Checks the CRAP (Change Risk Anti-Patterns) score for methods/classes. \ The CRAP metric score is based on the cyclomatic complexity and test coverage for individual methods. \ A method with a CRAP value greater than the maxMethodCrapScore \ property (${rule.maxMethodCrapScore}) causes a violation. Likewise, a class that has an (average method) CRAP \ value greater than the maxClassAverageMethodCrapScore property (${rule.maxClassAverageMethodCrapScore}) causes a violation. JUnitLostTest.description=Checks for classes that import JUnit 4 classes and contain a public, instance, void, no-arg method named test* that is not annotated with @Test. JUnitLostTest.description.html=Checks for classes that import JUnit 4 classes and contain a public, instance, void, no-arg method named test* that is not annotated with @Test. SpaceAfterComma.description=Checks that there is at least one space or whitespace following each comma. That includes checks for method and closure declaration parameter lists, method call parameter lists, Map literals and List literals. SpaceAfterComma.description.html=Checks that there is at least one space or whitespace following each comma. That includes checks for method and closure declaration parameter lists, method call parameter lists, Map literals and List literals. SpaceAfterSemicolon.description=Checks that there is at least one space or whitespace following each semicolon separating multiple statements on a single line or the clauses within a classic for loop. SpaceAfterSemicolon.description.html=Checks that there is at least one space or whitespace following each semicolon separating multiple statements on a single line or the clauses within a classic for loop. SpaceAroundOperator.description=Check that there is at least one space (blank) or whitespace around each binary operator. SpaceAroundOperator.description.html=Check that there is at least one space (blank) or whitespace around each binary operator. SpaceBeforeOpeningBrace.description=Check that there is at least one space (blank) or whitespace before each opening brace ("{") for method/class/interface declarations, closure expressions and block statements. SpaceBeforeOpeningBrace.description.html=Check that there is at least one space (blank) or whitespace before each opening brace ("{") for method/class/interface declarations, closure expressions and block statements. SpaceAfterOpeningBrace.description=Check that there is at least one space (blank) or whitespace after each opening brace ("{") for method/class/interface declarations, closure expressions and block statements. SpaceAfterOpeningBrace.description.html=Check that there is at least one space (blank) or whitespace after each opening brace ("{") for method/class/interface declarations, closure expressions and block statements. SpaceBeforeClosingBrace.description=Check that there is at least one space (blank) or whitespace before each closing brace ("}") for method/class/interface declarations, closure expressions and block statements. SpaceBeforeClosingBrace.description.html=Check that there is at least one space (blank) or whitespace before each closing brace ("}") for method/class/interface declarations, closure expressions and block statements. SpaceAfterClosingBrace.description=Check that there is at least one space (blank) or whitespace after each closing brace ("}") for method/class/interface declarations, closure expressions and block statements. SpaceAfterClosingBrace.description.html=Check that there is at least one space (blank) or whitespace after each closing brace ("}") for method/class/interface declarations, closure expressions and block statements. SpaceAfterIf.description=Check that there is exactly one space (blank) after the if keyword and before the opening parenthesis. SpaceAfterIf.description.html=Check that there is exactly one space (blank) after the if keyword and before the opening parenthesis. SpaceAfterFor.description=Check that there is exactly one space (blank) after the for keyword and before the opening parenthesis. SpaceAfterFor.description.html=Check that there is exactly one space (blank) after the for keyword and before the opening parenthesis. SpaceAfterWhile.description=Check that there is exactly one space (blank) after the while keyword and before the opening parenthesis. SpaceAfterWhile.description.html=Check that there is exactly one space (blank) after the while keyword and before the opening parenthesis. SpaceAfterSwitch.description=Check that there is exactly one space (blank) after the switch keyword and before the opening parenthesis. SpaceAfterSwitch.description.html=Check that there is exactly one space (blank) after the switch keyword and before the opening parenthesis. SpaceAfterCatch.description=Check that there is exactly one space (blank) after the catch keyword and before the opening parenthesis. SpaceAfterCatch.description.html=Check that there is exactly one space (blank) after the catch keyword and before the opening parenthesis. TrailingWhitespace.description=Checks that no lines of source code end with whitespace characters. TrailingWhitespace.description.html=Checks that no lines of source code end with whitespace characters. JUnitUnnecessaryThrowsException.description=Check for throws clauses on JUnit test methods. That is not necessary in Groovy. JUnitUnnecessaryThrowsException.description.html=Check for throws clauses on JUnit test methods. That is not necessary in Groovy. GrailsDuplicateMapping.description=Check for duplicate name in a domain class mapping GrailsDuplicateMapping.description.html=Check for duplicate name in a domain class mapping GrailsDuplicateConstraint.description=Check for duplicate entry in domain class constraints GrailsDuplicateConstraint.description.html=Check for duplicate entry in domain class constraints GrailsMassAssignment.description=Untrusted input should not be allowed to set arbitrary object fields without restriction. GrailsMassAssignment.description.html=Untrusted input should not be allowed to set arbitrary object fields without restriction. IfStatementCouldBeTernary.description=Checks for if statements where both the if and else blocks contain only a single return statement with a constant or literal value IfStatementCouldBeTernary.description.html=Checks for if statements where both the if and else blocks contain only a single return statement with a constant or literal value ExceptionNotThrown.description=Checks for an exception constructor call without a throw as the last statement within a catch block. ExceptionNotThrown.description.html=Checks for an exception constructor call without a throw as the last statement within a catch block. NoDef.description=def should not be used. You should replace it with concrete type. NoDef.description.html=def should not be used. You should replace it with concrete type. #----------------------------------------------------------------------------------------- # Report labels, etc. #----------------------------------------------------------------------------------------- htmlReport.titlePrefix=CodeNarc Report htmlReport.reportTimestamp.label=Date: htmlReport.reportTitle.title=Report title: htmlReport.reportVersion.label=Generated with: htmlReport.summary.title=Summary htmlReport.summary.packageHeading=Package htmlReport.summary.totalFilesHeading=Total Files htmlReport.summary.filesWithViolationsHeading=Files with Violations htmlReport.summary.priority1Heading=Priority 1 htmlReport.summary.priority2Heading=Priority 2 htmlReport.summary.priority3Heading=Priority 3 htmlReport.summary.priority4Heading=Priority 4 htmlReport.summary.allPackages=All Packages htmlReport.violations.ruleName=Rule Name htmlReport.violations.priority=Priority htmlReport.violations.lineNumber=Line # htmlReport.violations.sourceLine=Source Line / Message htmlReport.ruleDescriptions.title=Rule Descriptions htmlReport.ruleDescriptions.ruleNameHeading=Rule Name htmlReport.ruleDescriptions.descriptionHeading=Description CodeNarc-0.23/src/main/groovy/0000755000175000017500000000000012303254650015504 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/0000755000175000017500000000000012303254650016273 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/0000755000175000017500000000000012623571301020051 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/0000755000175000017500000000000012623571301021534 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/RuleSets.groovy0000644000175000017500000000300712167647052024563 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.ruleset /** * Holds list of all RuleSet files. * * @author Chris Mair */ class RuleSets { static final ALL_RULESET_FILES = [ 'rulesets/basic.xml', 'rulesets/braces.xml', 'rulesets/concurrency.xml', 'rulesets/convention.xml', 'rulesets/design.xml', 'rulesets/dry.xml', 'rulesets/enhanced.xml', 'rulesets/exceptions.xml', 'rulesets/formatting.xml', 'rulesets/generic.xml', 'rulesets/grails.xml', 'rulesets/groovyism.xml', 'rulesets/imports.xml', 'rulesets/jdbc.xml', 'rulesets/junit.xml', 'rulesets/logging.xml', 'rulesets/naming.xml', 'rulesets/security.xml', 'rulesets/serialization.xml', 'rulesets/size.xml', 'rulesets/unnecessary.xml', 'rulesets/unused.xml' ] } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/FilteredRuleSet.groovy0000644000175000017500000000630612311373552026054 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.util.WildcardPattern /** * A RuleSet implementation that is a Decorator for another RuleSet, but provides * the ability to filter included and excluded rules within that RuleSet. *

* If a Rule matches both an include and an exclude, then the exclude takes precedence, i.e. the * Rule is NOT includes in the result from getRules(). * * @author Chris Mair */ class FilteredRuleSet implements RuleSet { private final rules = [] private final includes = [] private final excludes = [] /** * Construct a new instance on the specified RuleSet * @param ruleset - the RuleSet to be filtered (decorated); must not be null. */ FilteredRuleSet(RuleSet ruleSet) { assert ruleSet != null rules.addAll(ruleSet.getRules()) } /** * Add an include criteria. * @param include - the include specification, which is compared against the ids of all of the Rules * within the underlying RuleSet. Only matching Rules are included in the result from getRules(). * The include value must not be null or empty. */ void addInclude(String include) { assert include includes << new WildcardPattern(include) } /** * Add an exclude criteria. * @param exclude - the exclude specification, which is compared against the ids of all of the Rules * within the underlying RuleSet. Any matching Rules are excluded in the result from getRules(). * The exclude value must not be null or empty. */ void addExclude(String exclude) { assert exclude excludes << new WildcardPattern(exclude) } /** * Return the List of Rules that match the include(s) (if specified) AND DO NOT match any exlcude(s) specified. * @return the filtered List of Rule objects. The returned List is immutable. */ List getRules() { def filteredRules = [] rules.each { rule -> def matchesIncludes = includes.empty || includes.find { includePattern -> includePattern.matches(rule.name) } if (matchesIncludes) { def matchesExcludes = !excludes.empty && excludes.find { excludePattern -> excludePattern.matches(rule.name) } if (!matchesExcludes) { filteredRules << rule } } } filteredRules.asImmutable() } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/RuleSet.groovy0000644000175000017500000000163612311373552024376 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.ruleset /** * Represents a set of (configured) Rule objects that can be applied for static analysis. * * @author Chris Mair */ interface RuleSet { /** * @return a List of optionally configured Rule objects */ List getRules() } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/XmlFileRuleSet.groovy0000644000175000017500000000460612311373552025657 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.ruleset import org.apache.log4j.Logger import org.codenarc.util.io.DefaultResourceFactory import org.codenarc.util.io.ResourceFactory /** * A RuleSet implementation that parses Rule definitions from XML read from a * file. The filename passed into the constructor is interpreted relative to the classpath, by * default, but may be optionally prefixed by any of the valid java.net.URL prefixes, such as * "file:" (to load from a relative or absolute path on the filesystem), or "http:". *

* Note that this class attempts to read the file and parse the XML from within the constructor. * * @author Chris Mair */ class XmlFileRuleSet implements RuleSet { private static final LOG = Logger.getLogger(XmlFileRuleSet) private final ResourceFactory resourceFactory = new DefaultResourceFactory() private List rules = [] /** * Construct a new instance on the specified RuleSet file path * @param path - the path to the XML RuleSet definition file. The path is relative to the classpath, * by default, but may be optionally prefixed by any of the valid java.net.URL prefixes, such * as "file:" (to load from a relative or absolute path on the filesystem), or "http:". The * path must not be empty or null. */ XmlFileRuleSet(String path) { assert path LOG.info("Loading ruleset from [$path]") def inputStream = resourceFactory.getResource(path).inputStream inputStream.withReader { reader -> def xmlReaderRuleSet = new XmlReaderRuleSet(reader) this.rules = xmlReaderRuleSet.rules } } /** * @return a List of Rule objects */ List getRules() { rules } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/RuleSetUtil.groovy0000644000175000017500000000451612403436520025231 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.Rule import org.codenarc.util.io.DefaultResourceFactory import org.codenarc.util.io.ResourceFactory /** * A private utility class for the RuleSet classes. All methods are static. *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class RuleSetUtil { protected static final String CLASS_LOADER_SYS_PROP = 'codenarc.useCurrentThreadContextClassLoader' private static final ResourceFactory RESOURCE_FACTORY = new DefaultResourceFactory() protected static void assertClassImplementsRuleInterface(Class ruleClass) { assert ruleClass assert Rule.isAssignableFrom(ruleClass), "The rule class [${ruleClass.name}] does not implement the Rule interface" } static RuleSet loadRuleSetFile(String path) { isXmlFile(path) ? new XmlFileRuleSet(path) : new GroovyDslRuleSet(path) } protected static Rule loadRuleScriptFile(String path) { def inputStream = RESOURCE_FACTORY.getResource(path).inputStream Class ruleClass inputStream.withStream { input -> ClassLoader parentClassLoader = (System.getProperty(CLASS_LOADER_SYS_PROP) == 'true') ? Thread.currentThread().getContextClassLoader() : getClass().classLoader GroovyClassLoader gcl = new GroovyClassLoader(parentClassLoader) ruleClass = gcl.parseClass(input.text) } assertClassImplementsRuleInterface(ruleClass) ruleClass.newInstance() } private static boolean isXmlFile(String path) { path && path.endsWith('.xml') } private RuleSetUtil() { } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/CompositeRuleSet.groovy0000644000175000017500000000277112311373552026262 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.Rule /** * A RuleSet implementation that aggregates a set of RuleSets and Rules. * * @author Chris Mair */ class CompositeRuleSet implements RuleSet { private final rules = [] /** * Add a single Rule to this RuleSet * @param rule - the Rule to add */ void addRule(Rule rule) { assert rule != null rules << rule } /** * Add all of the Rules within the specified RuleSet to this RuleSet * @param ruleSet - the RuleSet whose Rules are to be included */ void addRuleSet(RuleSet ruleSet) { assert ruleSet != null rules.addAll(ruleSet.getRules()) } /** * @return a List of Rule objects. The returned List is immutable. */ List getRules() { rules.asImmutable() } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/MovedRules.groovy0000644000175000017500000001272212006632016025070 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.ruleset /** * Helper class to manage information for moved or renamed rules, and provide helpful error message. * * @author Chris Mair */ class MovedRules { private static final CONVENTION_RULESET = 'rulesets/convention.xml' private static final DESIGN_RULESET = 'rulesets/design.xml' private static final UNNECESSARY_RULESET = 'rulesets/unnecessary.xml' private static final GROOVYISM_RULESET = 'rulesets/groovyism.xml' private static final SERIALIZATION_RULESET = 'rulesets/serialization.xml' private static class MovedToRuleSet { String ruleSetName String messageFor(String name) { "The \"$name\" rule has been moved to the \"$ruleSetName\" ruleset." } } private static class Renamed { String newRuleName String messageFor(String name) { "The \"$name\" rule has been renamed to \"$newRuleName\"." } } private static final RULES = [ HardcodedWindowsRootDirectory: renamedTo('HardCodedWindowsRootDirectory'), AddEmptyString: movedTo(UNNECESSARY_RULESET), AssignCollectionSort: movedTo(GROOVYISM_RULESET), AssignCollectionUnique: movedTo(GROOVYISM_RULESET), BooleanMethodReturnsNull: movedTo(DESIGN_RULESET), CloneableWithoutClone: movedTo(DESIGN_RULESET), ClosureAsLastMethodParameter: movedTo(GROOVYISM_RULESET), CollectAllIsDeprecated: movedTo(GROOVYISM_RULESET), CompareToWithoutComparable: movedTo(DESIGN_RULESET), ConfusingMultipleReturns: movedTo(GROOVYISM_RULESET), ConfusingTernary: movedTo(CONVENTION_RULESET), ConsecutiveLiteralAppends: movedTo(UNNECESSARY_RULESET), ConsecutiveStringConcatenation: movedTo(UNNECESSARY_RULESET), CouldBeElvis: movedTo(CONVENTION_RULESET), ExplicitArrayListInstantiation: movedTo(GROOVYISM_RULESET), ExplicitCallToAndMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToCompareToMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToDivMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToEqualsMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToGetAtMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToLeftShiftMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToMinusMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToModMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToMultiplyMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToOrMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToPlusMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToPowerMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToRightShiftMethod: movedTo(GROOVYISM_RULESET), ExplicitCallToXorMethod: movedTo(GROOVYISM_RULESET), ExplicitHashMapInstantiation: movedTo(GROOVYISM_RULESET), ExplicitHashSetInstantiation: movedTo(GROOVYISM_RULESET), ExplicitLinkedHashMapInstantiation: movedTo(GROOVYISM_RULESET), ExplicitLinkedListInstantiation: movedTo(GROOVYISM_RULESET), ExplicitStackInstantiation: movedTo(GROOVYISM_RULESET), ExplicitTreeSetInstantiation: movedTo(GROOVYISM_RULESET), GStringAsMapKey: movedTo(GROOVYISM_RULESET), GroovyLangImmutable: movedTo(GROOVYISM_RULESET), InvertedIfElse: movedTo(CONVENTION_RULESET), LongLiteralWithLowerCaseL: movedTo(CONVENTION_RULESET), ReturnsNullInsteadOfEmptyArray: movedTo(DESIGN_RULESET), ReturnsNullInsteadOfEmptyCollection: movedTo(DESIGN_RULESET), SimpleDateFormatMissingLocale: movedTo(DESIGN_RULESET), UseCollectMany: movedTo(GROOVYISM_RULESET), UseCollectNested: movedTo(GROOVYISM_RULESET), SerialVersionUID: movedTo(SERIALIZATION_RULESET), // 0.14 SerializableClassMustDefineSerialVersionUID: movedTo(SERIALIZATION_RULESET), // 0.14 StringInstantiation: movedTo(UNNECESSARY_RULESET), // 0.12 BooleanInstantiation: movedTo(UNNECESSARY_RULESET), // 0.12 UnnecessaryBooleanExpression: movedTo(UNNECESSARY_RULESET), // 0.11 UnnecessaryIfStatement: movedTo(UNNECESSARY_RULESET), // 0.11 UnnecessaryTernaryExpression: movedTo(UNNECESSARY_RULESET) // 0.11 ] static String getMovedOrRenamedMessageForRuleName(String name) { def message = RULES[name]?.messageFor(name) return message ?: '' } private static Renamed renamedTo(String newRuleName) { return new Renamed(newRuleName:newRuleName) } private static MovedToRuleSet movedTo(String ruleSetName) { return new MovedToRuleSet(ruleSetName:ruleSetName) } // Private constructor to prevent instantiation. All methods are static. private MovedRules() { } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/RuleSetBuilder.groovy0000644000175000017500000001222112311373552025675 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.Rule import org.codenarc.ruleregistry.RuleRegistryHolder /** * A Builder for RuleSets. Create a RuleSet by calling the ruleset * method, passing in a Closure defining the contents of the RuleSet. * The Closure can contain any combination of the following (as well as * arbitrary Groovy code): *

    *
  • ruleset - to load a RuleSet file. The path specifies either a * Groovy file or an XML file.
  • *
  • rule - to load a single Rule (specify either the rule name or rule class)
  • *
  • description - description of the RuleSet (optional)
  • *
* * @author Chris Mair */ class RuleSetBuilder { private final topLevelDelegate = new TopLevelDelegate() void ruleset(Closure closure) { closure.delegate = topLevelDelegate closure.call() } RuleSet getRuleSet() { topLevelDelegate.ruleSet } } class TopLevelDelegate { private final allRuleSet = new CompositeRuleSet() void ruleset(String path) { def ruleSet = RuleSetUtil.loadRuleSetFile(path) allRuleSet.addRuleSet(ruleSet) } void ruleset(String path, Closure closure) { def ruleSet = RuleSetUtil.loadRuleSetFile(path) def ruleSetConfigurer = new RuleSetDelegate(ruleSet) closure.delegate = ruleSetConfigurer closure.setResolveStrategy(Closure.DELEGATE_FIRST) closure.call() allRuleSet.addRuleSet(ruleSetConfigurer.ruleSet) } void rule(Class ruleClass) { RuleSetUtil.assertClassImplementsRuleInterface(ruleClass) Rule rule = ruleClass.newInstance() allRuleSet.addRule(rule) } void rule(Class ruleClass, Map properties) { RuleSetUtil.assertClassImplementsRuleInterface(ruleClass) // TODO refactor Rule rule = ruleClass.newInstance() properties.each { key, value -> rule[key] = value } allRuleSet.addRule(rule) } void rule(Class ruleClass, Closure closure) { RuleSetUtil.assertClassImplementsRuleInterface(ruleClass) Rule rule = ruleClass.newInstance() closure.delegate = rule closure.resolveStrategy = Closure.DELEGATE_FIRST closure.call() allRuleSet.addRule(rule) } void rule(String path) { def rule = RuleSetUtil.loadRuleScriptFile(path) allRuleSet.addRule(rule) } void rule(String path, Closure closure) { def rule = RuleSetUtil.loadRuleScriptFile(path) closure.delegate = rule closure.resolveStrategy = Closure.DELEGATE_FIRST closure.call() allRuleSet.addRule(rule) } def propertyMissing(String name) { def ruleClass = RuleRegistryHolder.ruleRegistry?.getRuleClass(name) assert ruleClass, "No such rule named [$name]. " + MovedRules.getMovedOrRenamedMessageForRuleName(name) rule(ruleClass) } def methodMissing(String name, args) { def ruleClass = RuleRegistryHolder.ruleRegistry?.getRuleClass(name) assert ruleClass, "No such rule named [$name]. " + MovedRules.getMovedOrRenamedMessageForRuleName(name) if (args.size() > 0) { rule(ruleClass, args[0]) } else { rule(ruleClass) } } @SuppressWarnings(['EmptyMethod', 'UnusedMethodParameter']) void description(String description) { // Do nothing } protected RuleSet getRuleSet() { allRuleSet } } class RuleSetDelegate { RuleSet ruleSet RuleSetDelegate(RuleSet ruleSet) { this.ruleSet = new FilteredRuleSet(ruleSet) } void exclude(String excludeNames) { ruleSet.addExclude(excludeNames) } void include(String includeNames) { ruleSet.addInclude(includeNames) } def methodMissing(String name, args) { def rule = findRule(name) assert rule, "No such rule named [$name]. " + MovedRules.getMovedOrRenamedMessageForRuleName(name) def arg = args[0] if (arg instanceof Closure) { arg.delegate = rule arg.setResolveStrategy(Closure.DELEGATE_FIRST) arg.call() } else { // Assume it is a Map arg.each { key, value -> rule[key] = value } } } private Rule findRule(String name) { ruleSet.rules.find { rule -> rule.name == name } } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/GroovyDslRuleSet.groovy0000644000175000017500000000577412403114530026245 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.apache.log4j.Logger import org.codehaus.groovy.control.MultipleCompilationErrorsException import org.codenarc.util.io.DefaultResourceFactory import org.codenarc.util.io.ResourceFactory /** * A RuleSet implementation that parses a Groovy DSL of RuleSet definitions. * The filename passed into the constructor is interpreted relative to the classpath. * Note that this class attempts to read the file and parse the Groovy from within the constructor. * * @author Chris Mair */ class GroovyDslRuleSet implements RuleSet { private static final LOG = Logger.getLogger(GroovyDslRuleSet) private final ResourceFactory resourceFactory = new DefaultResourceFactory() private final RuleSetBuilder ruleSetBuilder = new RuleSetBuilder() private final String path private final rules /** * Construct a new instance on the specified Groovy DSL RuleSet file path * @param path - the path to the Groovy DSL RuleSet definition file, relative to the classpath; must not be empty or null */ GroovyDslRuleSet(String path) { assert path this.path = path LOG.info("Loading ruleset from [$path]") GroovyShell shell = createGroovyShell() evaluateDsl(shell) rules = ruleSetBuilder.ruleSet.rules } private GroovyShell createGroovyShell() { def callRuleSet = { Closure closure -> closure.resolveStrategy = Closure.DELEGATE_ONLY // fail if access non-existent properties ruleSetBuilder.ruleset(closure) } Binding binding = new Binding(ruleset:callRuleSet) return new GroovyShell(this.class.classLoader, binding) } private void evaluateDsl(GroovyShell shell) { def inputStream = resourceFactory.getResource(path).inputStream inputStream.withReader { reader -> try { shell.evaluate(reader) } catch (MultipleCompilationErrorsException compileError) { LOG.error("An error occurred compiling the configuration file $path", compileError) throw new IllegalStateException("An error occurred compiling the configuration file $path\n${compileError.message}") } } } /** * @return a List of Rule objects */ List getRules() { rules } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/XmlReaderRuleSet.groovy0000644000175000017500000001243212311373552026176 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import groovy.xml.Namespace import org.codenarc.util.PropertyUtil import org.codenarc.util.io.ClassPathResource import javax.xml.transform.stream.StreamSource import javax.xml.validation.SchemaFactory /** * A RuleSet implementation that parses Rule definitions from XML read from a * Reader. Note that this class attempts to read and parse the XML from within * the constructor. * * @author Chris Mair */ @SuppressWarnings('DuplicateLiteral') class XmlReaderRuleSet implements RuleSet { // W3C_XML_SCHEMA_NS_URI constant is not defined in older versions of javax.xml.XMLConstants private static final XML_SCHEMA_URI = 'http://www.w3.org/2001/XMLSchema' private static final NS = new Namespace('http://codenarc.org/ruleset/1.0') private static final RULESET_SCHEMA_FILE = 'ruleset-schema.xsd' private final List rules = [] /** * Construct a new instance on the specified Reader * @param reader - the Reader from which the XML will be read; must not be null */ XmlReaderRuleSet(Reader reader) { assert reader def xml = reader.text validateXml(xml) def ruleset = new XmlParser().parseText(xml) loadRuleSetRefElements(ruleset) loadRuleElements(ruleset) loadRuleScriptElements(ruleset) rules = rules.asImmutable() } /** * @return a List of Rule objects */ List getRules() { rules } //-------------------------------------------------------------------------- // Internal Helper Methods //-------------------------------------------------------------------------- private void loadRuleSetRefElements(ruleset) { ruleset[NS.'ruleset-ref'].each { ruleSetRefNode -> def ruleSetPath = ruleSetRefNode.attribute('path') def refRuleSet = RuleSetUtil.loadRuleSetFile(ruleSetPath) def allRules = refRuleSet.rules def filteredRuleSet = new FilteredRuleSet(refRuleSet) ruleSetRefNode[NS.'include'].each { includeNode -> def includeRuleName = includeNode.attribute('name') filteredRuleSet.addInclude(includeRuleName) } ruleSetRefNode[NS.'exclude'].each { excludeNode -> def excludeRuleName = excludeNode.attribute('name') filteredRuleSet.addExclude(excludeRuleName) } ruleSetRefNode[NS.'rule-config'].each { configNode -> def configRuleName = configNode.attribute('name') def rule = allRules.find { it.name == configRuleName } assert rule, "Rule named [$configRuleName] referenced within was not found. " + MovedRules.getMovedOrRenamedMessageForRuleName(configRuleName) configNode[NS.property].each { p -> def name = p.attribute('name') def value = p.attribute('value') PropertyUtil.setPropertyFromString(rule, name, value) } } rules.addAll(filteredRuleSet.rules) } } private void loadRuleElements(ruleset) { ruleset[NS.rule].each { ruleNode -> def ruleClassName = ruleNode.attribute('class') def ruleClass = getClass().classLoader.loadClass(ruleClassName.toString()) RuleSetUtil.assertClassImplementsRuleInterface(ruleClass) def rule = ruleClass.newInstance() rules << rule setRuleProperties(ruleNode, rule) } } private void loadRuleScriptElements(ruleset) { ruleset[NS.'rule-script'].each { ruleScriptNode -> def ruleScriptPath = ruleScriptNode.attribute('path') def rule = RuleSetUtil.loadRuleScriptFile(ruleScriptPath) rules << rule setRuleProperties(ruleScriptNode, rule) } } private setRuleProperties(ruleNode, rule) { ruleNode[NS.property].each { p -> def name = p.attribute('name') def value = p.attribute('value') PropertyUtil.setPropertyFromString(rule, name, value) } } private void validateXml(String xml) { def factory = SchemaFactory.newInstance(XML_SCHEMA_URI) def schema = factory.newSchema(new StreamSource(getSchemaXmlInputStream())) def validator = schema.newValidator() validator.validate(new StreamSource(new StringReader(xml))) } private InputStream getSchemaXmlInputStream() { ClassPathResource.getInputStream(RULESET_SCHEMA_FILE) } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/PropertiesFileRuleSetConfigurer.groovy0000644000175000017500000001037212311373552031274 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.apache.log4j.Logger import org.codenarc.util.PropertyUtil import org.codenarc.util.io.DefaultResourceFactory import org.codenarc.util.io.ResourceFactory /** * Reads the properties file named "codenarc.properties", if found on the classpath, and applies * the property values to matching Rules within a specified RuleSet. If the * properties file is not found on the classpath, then do nothing. *

* The default name of the properties file ("codenarc.properties") can be overridden by setting * the "codenarc.properties.file" system property to the new filename. Note that the new filename * is still relative to the classpath, and may optionally contain (relative) path components (e.g. * "src/resources/my-codenarc.properties"). *

* For each properties entry of the form [rule-name].[property-name]=[property-value], * the named property for the rule within the RuleSet matching rule-name is set to the * specified property-value. Properties entries not of this form or specifying rule * names not within the specified RuleSet are ignored. * * @author Chris Mair */ class PropertiesFileRuleSetConfigurer { private static final LOG = Logger.getLogger(PropertiesFileRuleSetConfigurer) private static final PROPERTIES_FILE_SYSPROP = 'codenarc.properties.file' private final ResourceFactory resourceFactory = new DefaultResourceFactory() protected defaultPropertiesFilename = 'codenarc.properties' /** * Configure the rules within the RuleSet from the properties file (relative to the classpath). * The default properties filename is "codenarc.properties", but can be overridden by setting the * "codenarc.properties.filename" system property. *

* Each properties entry of the form [rule-name].[property-name]=[property-value] * is used to set the named property of the named rule. Other (non-matching) * property entries are ignored. * @param ruleSet - the RuleSet to configure; must not be null */ void configure(RuleSet ruleSet) { assert ruleSet def propertiesFilename = System.getProperty(PROPERTIES_FILE_SYSPROP) ?: defaultPropertiesFilename try { def inputStream = resourceFactory.getResource(propertiesFilename).inputStream LOG.info("Reading RuleSet configuration from properties file [$propertiesFilename].") inputStream.withStream { input -> def properties = new Properties() properties.load(input) applyProperties(properties, ruleSet) } } catch(IOException e) { LOG.info("RuleSet configuration properties file [$propertiesFilename] not found.") } } private applyProperties(Properties properties, RuleSet ruleSet) { final PATTERN = ~/(\w*)\.(\w*)/ properties.each { k, v -> def matcher = PATTERN.matcher(k) if (matcher.matches()) { def ruleName = matcher[0][1] def propertyName = matcher[0][2] def rule = findRule(ruleSet, ruleName) if (rule) { PropertyUtil.setPropertyFromString(rule, propertyName, v) } else { LOG.warn("No such rule [$ruleName] for property [$k]. " + MovedRules.getMovedOrRenamedMessageForRuleName(ruleName)) } } } } private findRule(RuleSet ruleSet, String name) { ruleSet.rules.find { rule -> rule.name == name } } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleset/ListRuleSet.groovy0000644000175000017500000000263512311373552025232 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.Rule /** * A RuleSet implementation that returns a static List of Rules passed into its constructor. * * @author Chris Mair */ class ListRuleSet implements RuleSet { private final rules /** * Construct a new instance from the specified List of rules. * @param rules - the List of List of Rule objects; must not be null, but may be empty. */ ListRuleSet(List rules) { assert rules != null assert rules.every { it instanceof Rule } def copy = [] copy.addAll(rules) this.rules = Collections.unmodifiableList(copy) } /** * @return a List of Rule objects */ List getRules() { rules } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/0000755000175000017500000000000012623571301021026 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/util/PathUtil.groovy0000644000175000017500000000415712311373553024041 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.util /** * Path-related utility methods. * * @author Chris Mair */ class PathUtil { private static final SEP = '/' static String getName(String path) { if (!path) { return null } int separatorIndex1 = path.lastIndexOf('/') int separatorIndex2 = path.lastIndexOf('\\') int separatorIndex = [separatorIndex1, separatorIndex2].max() (separatorIndex == -1) ? path : path[separatorIndex + 1 .. -1] } static String getParentPath(String filePath) { def normalizedPath = normalizePath(filePath) def partList = normalizedPath ? normalizedPath.tokenize(SEP) : [] if (partList.size() < 2) { return null } def parentList = partList[0..-2] parentList.join(SEP) } static String normalizePath(String path) { path ? path.replaceAll('\\\\', SEP) : path } static String removePathPrefix(String prefix, String path) { def resultPath = path if (prefix && resultPath.startsWith(prefix)) { resultPath = resultPath - prefix return removeLeadingSlash(resultPath) } resultPath } private static String removeLeadingSlash(path) { (path.startsWith('\\') || path.startsWith(SEP)) ? path[1 .. -1] : path } // Private constructor to prevent instantiation. All members are static. private PathUtil() { } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/GroovyVersion.groovy0000644000175000017500000000275512006632016025135 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.util /** * Utility methods to determine the version of Groovy currently executing. * * @author Chris Mair */ class GroovyVersion { static String getVersion() { try { return GroovySystem.getVersion() } catch(MissingMethodException e) { return new org.codehaus.groovy.runtime.InvokerHelper().version } } static boolean isGroovy1_8() { getVersion().startsWith('1.8') } static boolean isGroovy2_x() { getVersion().startsWith('2.') } static boolean isGroovy1_8_OrGreater() { isGroovy1_8() || isGroovy2_x() } static boolean isGroovy1_7() { getVersion().startsWith('1.7') } static boolean isGroovy1_6() { getVersion().startsWith('1.6') } private GroovyVersion() { } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/ConsecutiveUtils.groovy0000644000175000017500000000263012006632016025602 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.util import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.GStringExpression /** * * Utility class for Consecutive* rules. * * @author Hamlet D'Arcy */ class ConsecutiveUtils { static boolean areJoinableConstants(Expression left, Expression right) { if (left.lastLineNumber != right.lineNumber) { return false } if (isJoinableType(left) && isJoinableType(right)) { return true } false } static boolean isJoinableType(Expression expression) { if (expression instanceof ConstantExpression && !AstUtil.isNull(expression)) { return true } return expression instanceof GStringExpression } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/SourceCodeUtil.groovy0000644000175000017500000000555112006632016025170 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.util import org.codehaus.groovy.ast.ASTNode import org.codenarc.source.SourceCode /** * Contains source related static utility methods * * @author Marcin Erdmann */ class SourceCodeUtil { static List nodeSourceLines(SourceCode source, ASTNode node) { sourceLinesBetween(source, node.lineNumber, node.columnNumber, node.lastLineNumber, node.lastColumnNumber) } static List sourceLinesBetweenNodes(SourceCode source, ASTNode startNode, ASTNode endNode) { sourceLinesBetween(source, startNode.lastLineNumber, startNode.lastColumnNumber, endNode.lineNumber, endNode.columnNumber) } /** * Retrieves source lines between the start line and column and end line and column. Lines and columns are counted * starting at one as do the lines and columns describing a beginning and end of ASTNode. * * @param source Source from which the lines are to be extracted * @param startLine has to be greater than zero * @param startColumn has to be greater than zero * @param endLine has to be greater than zero * @param endColumn has to be greater than zero * @return a List of string containing the extracted code * @throws IllegalArgumentException when start is not before end, and any of the start/end parameters is lower than one */ static List sourceLinesBetween(SourceCode source, int startLine, int startColumn, int endLine, int endColumn) { if (startLine < 1 || startColumn < 1 || endLine < 1 || endColumn < 1) { throw new IllegalArgumentException('Start and end indexes are one based and have to be greater than zero') } if (endLine < startLine || (endLine == startLine && endColumn < startColumn)) { throw new IllegalArgumentException('End line/column has to be after start line/column') } def nodeLines = source.lines[(startLine - 1)..(endLine - 1)] as ArrayList if (nodeLines.size() > 1) { nodeLines[0] = startColumn - 1 == nodeLines.first().size() ? '' : nodeLines.first()[(startColumn - 1)..-1] nodeLines[-1] = nodeLines.last()[0..(endColumn - 2)] return nodeLines } return [nodeLines.first()[(startColumn - 1)..(endColumn - 2)]] } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/PropertyUtil.groovy0000644000175000017500000000433512403443524024765 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.util /** * Contains property-related static utility methods * * @author Chris Mair */ class PropertyUtil { /** * Set the value of the named property on the specified Object from a String value. * If the name specifies an int, long or boolean value then trim and parse the provided String value * and convert to the appropriate type. * @param object - the Object whose field should be set * @param name - the property name to set * @param value - the property value as a String * @throws NoSuchFieldException - if the object does not contain the named field */ static void setPropertyFromString(Object object, String propertyName, String propertyValue) { def property = object.metaClass.getMetaProperty(propertyName) if (property == null) { throw new NoSuchFieldException(propertyName) } Object newPropertyValue = propertyValue if (property.type == int) { newPropertyValue = Integer.parseInt(propertyValue.trim()) } if (property.type == long) { newPropertyValue = Long.parseLong(propertyValue.trim()) } if (property.type == boolean) { newPropertyValue = Boolean.parseBoolean(propertyValue.trim()) } if (property.type == BigDecimal) { newPropertyValue = new BigDecimal(propertyValue.trim()) } object[propertyName] = newPropertyValue } /** * Private constructor. All methods are static. */ private PropertyUtil() { } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/ImportUtil.groovy0000644000175000017500000001425312237722336024421 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.util import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ImportNode import org.codenarc.source.SourceCode /** * Contains static utility methods and constants related to Import statements. *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class ImportUtil { /** * Return the package name for the specified import statement or else an empty String * @param importNode - the ImportNode for the import * @return the name package being imported (i.e., the import minus the class name/spec) * or an empty String if the import contains no package component */ static String packageNameForImport(ImportNode importNode) { if (importNode.className) { def importClassName = importNode.className def index = importClassName.lastIndexOf('.') (index == -1) ? '' : importClassName[0..index - 1] } else { def packageName = importNode.packageName packageName.endsWith('.') ? packageName[0..-2] : packageName } } /** * Return the source line and line number for the specified import class name and alias * @param sourceCode - the SourceCode being processed * @param importNode - the ImportNode representing the import * @return an object that has 'sourceLine' and 'lineNumber' fields */ static Map sourceLineAndNumberForImport(SourceCode sourceCode, String className, String alias) { // NOTE: This won't properly handle the case of multiple imports for same class if not all are aliased def index = sourceCode.lines.findIndexOf { line -> if (!line.contains('import')) { return false } if (!line.contains(alias)) { return false } def classNameIndex = line.indexOf(className) if (classNameIndex == -1) { return false } def afterIndex = classNameIndex + className.size() if (afterIndex >= line.size()) { return true } // the className is the last thing on the line if (line[afterIndex..-1].startsWith('.' + alias)) { return true } // className. return line[afterIndex] =~ /[\/\s\;]/ } def lineNumber = index == -1 ? null : index + 1 def sourceLine = lineNumber == null ? "import $className as $alias".toString() : sourceCode.lines[lineNumber - 1].trim() [sourceLine: sourceLine, lineNumber: lineNumber] } /** * Return the source line and line number for the specified import class name and alias * @param sourceCode - the SourceCode being processed * @param importNode - the ImportNode representing the import * @return an object that has 'sourceLine' and 'lineNumber' fields */ static Map sourceLineAndNumberForStarImport(SourceCode sourceCode, ImportNode importNode) { if (!importNode.isStar()) { return [sourceLine: -1, lineNumber: -1] } // NOTE: This won't properly handle the case of multiple imports for same class if not all are aliased def index = sourceCode.lines.findIndexOf { line -> line.contains('import') && (line.contains(importNode.packageName + '*') || (importNode.className && line.contains(importNode.className))) } def lineNumber = index == -1 ? null : index + 1 def sourceLine = lineNumber == null ? "import ${importNode.packageName}*".toString() : sourceCode.lines[lineNumber - 1].trim() [sourceLine: sourceLine, lineNumber: lineNumber] } static Map sourceLineAndNumberForNonStarImport(SourceCode sourceCode, ImportNode importNode) { ClassNode importClassNode = importNode.type if (importClassNode && importClassNode.lineNumber && importClassNode.lineNumber != -1) { int lineNumber = importClassNode.lineNumber String sourceLine = sourceCode.line(lineNumber - 1) ?: importNode.text return [sourceLine: sourceLine, lineNumber: lineNumber] } return sourceLineAndNumberForImport(sourceCode, importNode.className, importNode.alias) } /** * Return the source line and line number for the specified import * @param sourceCode - the SourceCode being processed * @param importNode - the ImportNode representing the import * @return an object that has 'sourceLine' and 'lineNumber' fields */ static Map sourceLineAndNumberForImport(SourceCode sourceCode, ImportNode importNode) { if (importNode.isStar()) { sourceLineAndNumberForStarImport(sourceCode, importNode) } else { sourceLineAndNumberForNonStarImport(sourceCode, importNode) } } static List getImportsSortedByLineNumber(sourceCode) { def staticImports = sourceCode.ast.staticImports.values() + sourceCode.ast.staticStarImports.values() def allImports = sourceCode.ast.imports + sourceCode.ast.starImports + staticImports return sortImportsByLineNumber(allImports, sourceCode) } static List getNonStaticImportsSortedByLineNumber(sourceCode) { def allImports = sourceCode.ast.imports + sourceCode.ast.starImports return sortImportsByLineNumber(allImports, sourceCode) } private static List sortImportsByLineNumber(List imports, sourceCode) { imports.sort { importNode -> def importInfo = ImportUtil.sourceLineAndNumberForImport(sourceCode, importNode) importInfo.lineNumber } } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/io/0000755000175000017500000000000012623571301021435 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/util/io/UrlResource.groovy0000644000175000017500000000347712311373552025173 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.util.io /** * A Resource implementation based on java.net.URL. *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class UrlResource implements Resource { final String path /** * Construct a new FileResource * @param path - the filesystem path to the file. May be absolute or relative. */ UrlResource(String path) { assert path this.path = path } /** * Open a FileInputStream on the file * @throws IOException - if an error occurs opening the InputStream */ InputStream getInputStream() throws IOException { def url = new URL(path) url.openStream() } /** * @return true only if this resource exists and is accessible */ boolean exists() { def inputStream try { def url = new URL(path) inputStream = url.openStream() return inputStream != null } catch (IOException e) { return false } finally { if (inputStream) { inputStream.close() } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/io/Resource.groovy0000644000175000017500000000252112311373552024475 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.util.io /** * Defines the interface for objects that represent a resource (e.g. a file) and * provide access to its InputStream. *

* The design of this (resource) framework is heavily influenced by the Resource classes * within The Spring Framework. *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ interface Resource { /** * Return the InputStream for this resource. * @throws IOException - if an error occurs opening the InputStream */ InputStream getInputStream() throws IOException /** * @return true only if this resource exists and is accessible */ boolean exists() } CodeNarc-0.23/src/main/groovy/org/codenarc/util/io/ClassPathResource.groovy0000644000175000017500000000606212311373552026304 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.util.io /** * A Resource implementation for resources available on the classpath. *

* This class also provides a static InputStream getInputStream(String path) convenience method. *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class ClassPathResource implements Resource { final String path /** * Convenience method to open an InputStream on the specified resource path relative the classpath * @path - the path to the resource (file). The path is relative to the classpath, * by default, but may be optionally prefixed by any of the valid java.net.URL prefixes, such * as "file:" (to load from a relative or absolute path on the filesystem), or "http:". The * path must not be empty or null. * @throws IOException - if an error occurs opening the InputStream */ static InputStream getInputStream(String path) throws IOException { new ClassPathResource(path).getInputStream() } /** * Construct a new ClassPathResource * @path - the path to the resource (file). The path is relative to the classpath, * by default, but may be optionally prefixed by any of the valid java.net.URL prefixes, such * as "file:" (to load from a relative or absolute path on the filesystem), or "http:". The * path must not be empty or null. */ ClassPathResource(String path) { assert path this.path = path } /** * Open an InputStream on the classpath resource path * @throws IOException - if an error occurs opening the InputStream */ InputStream getInputStream() throws IOException { def inputStream = getClass().classLoader.getResourceAsStream(path) if (!inputStream) { throw new FileNotFoundException("File [$path] does not exist or is not accessible") } inputStream } /** * @return true only if this resource exists and is accessible */ boolean exists() { def inputStream try { inputStream = getClass().classLoader.getResourceAsStream(path) return inputStream != null } catch (IOException e) { return false } finally { if (inputStream) { inputStream.close() } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/io/DefaultResourceFactory.groovy0000644000175000017500000000323312311373552027333 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.util.io /** * Default implementation of ResourceFactory. *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class DefaultResourceFactory implements ResourceFactory { private static final String CLASSPATH_PREFIX = 'classpath:' /** * Return a Resource instance suitable for the specified path. * @param path - the path to the resource. Must not be null or empty. This may be * optionally prefixed by "classpath:" or any of the valid java.net.URL prefixes * (e.g., "file:", "http:") * @throws IOException - if an error occurs opening the InputStream */ Resource getResource(String path) throws IOException { assert path if (path.startsWith(CLASSPATH_PREFIX)) { return new ClassPathResource(path - CLASSPATH_PREFIX) } isUrl(path) ? new UrlResource(path) : new ClassPathResource(path) } private isUrl(String path) { path =~ /.*\:.*/ } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/io/ResourceFactory.groovy0000644000175000017500000000225412311373552026030 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.util.io /** * Defines the interface for factory objects that create/return Resource instances. *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ interface ResourceFactory { /** * Return a Resource instance suitable for the specified path. * @param path - the path to the resource. This may be optionally prefixed by * @throws IOException - if an error occurs opening the InputStream */ Resource getResource(String path) throws IOException } CodeNarc-0.23/src/main/groovy/org/codenarc/util/WildcardPattern.groovy0000644000175000017500000001212612311373552025370 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.util /** * Represents a string pattern that may optionally include wildcards ('*', '**' or '?'), and * provides an API to determine whether that pattern matches a specified input string. *

* The wildcard character '*' within the pattern matches a sequence of zero or more characters within a * single file or directory name in the input string. It does not match a sequence of two or more * dir/file names. For instance, 'a*b' matches 'a12345b' and 'ab', but does NOT match 'a/b' or 'a123/b'. *

* The '**' wildcard matches any sequence of zero or more characters in the input string, including * directory names and separators . It matches any part of the directory tree. For instance, 'a**b' * matches 'a12345b', 'ab', 'a/b' and 'a1/a2/a3b'. *

* The wildcard character '?' within the pattern matches exactly one character in the input string, * excluding the normalized file separator character ('/'). *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class WildcardPattern { private final List regexes = [] private final List strings = [] private final defaultMatches /** * Construct a new WildcardPattern instance on a single pattern or a comma-separated list of patterns. * @param patternString - the pattern string, optionally including wildcard characters ('*' or '?'); * may optionally contain more than one pattern, separated by commas; may be null or empty to always match * @param defaultMatches - a boolean indicating whether matches() should * return true if the pattern string is either empty or null. This parameter is * optional and defaults to true. */ WildcardPattern(String patternString, boolean defaultMatches=true) { this.defaultMatches = defaultMatches def patterns = patternString ? patternString.tokenize(',') : [] patterns.each { pattern -> if (containsWildcards(pattern)) { regexes << convertStringWithWildcardsToRegex(pattern.trim()) } else { strings << pattern.trim() } } } /** * Return true if the specified String matches the pattern or if the original * patternString (specified in the constructor) was null or empty and the * value for defaultMatches (also specified in the constructor) was true. * @param string - the String to check * @return true if the String matches the pattern */ boolean matches(String string) { if (regexes.empty && strings.empty) { return defaultMatches } regexes.find { regex -> string ==~ regex } || strings.contains(string) } /** * Return true if the specified String contains one or more wildcard characters ('?' or '*') * @param string - the String to check * @return true if the String contains wildcards */ private static boolean containsWildcards(String string) { string =~ /\*|\?/ } /** * Convert the specified String, optionally containing wildcards (? or *), to a regular expression String * * @param stringWithWildcards - the String to convert, optionally containing wildcards (? or *) * @return an equivalent regex String * * @throws AssertionError - if the stringWithWildcards is null */ @SuppressWarnings('DuplicateLiteral') private static String convertStringWithWildcardsToRegex(String stringWithWildcards) { assert stringWithWildcards != null def result = new StringBuffer() def prevCharWasStar = false stringWithWildcards.each { ch -> switch (ch) { case '*': // Single '*' matches single dir/file; Double '*' matches sequence of zero or more dirs/files result << (prevCharWasStar ? /.*/ : /[^\/]*/) prevCharWasStar = !prevCharWasStar break case '?': // Any character except the normalized file separator ('/') result << /[^\/]/ break case ['$', '|', '[', ']', '(', ')', '.', ':', '{', '}', '\\', '^', '+']: result << '\\' + ch break default: result << ch } } result } } CodeNarc-0.23/src/main/groovy/org/codenarc/util/ModifiersUtil.groovy0000644000175000017500000000737512463441374025100 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.util import org.codehaus.groovy.ast.MethodNode /** * Provide static utility methods for parsing AST member modifiers, e.g. public/protected/private, static, final, etc. * * @author Chris Mair */ class ModifiersUtil { private static final MODIFIERS = [ public:MethodNode.ACC_PUBLIC, protected:MethodNode.ACC_PROTECTED, private:MethodNode.ACC_PRIVATE, static:MethodNode.ACC_STATIC, final:MethodNode.ACC_FINAL, volatile:MethodNode.ACC_VOLATILE, transient:MethodNode.ACC_TRANSIENT ] static boolean matchesAnyModifiers(Integer actualModifiers, List expectedModifiersList) { if (actualModifiers == null) { return true } return expectedModifiersList.any { expectedModifiers -> matchesModifiers(actualModifiers, expectedModifiers) } } /** * Return true only if the actualModifiers int value contains all of the bits (enabled) from the expectedModifiers * @param actualModifiers - the full actual modifiers; an int value of the OR-ed modifiers (values from Opcodes) * @param expectedModifiers - the modifiers to check against; an int value of the OR-ed modifiers (values from Opcodes) * @return true only if the actualModifiers contains all of the bits (enabled) from the expectedModifiers */ static boolean matchesModifiers(Integer actualModifiers, Integer expectedModifiers) { if (actualModifiers && expectedModifiers) { return (actualModifiers & expectedModifiers) == expectedModifiers } return true } /** * Parse comma-separated list of modifier groups * @param modifiersString - comma-separated list of modifier groups; * each group is a list of whitespace-delimited modifier names; * e.g. "public, protected static, protected final" * @return a List of the modifiers, one int value for each group (separated by commas) */ static List parseModifiersList(String modifiersString) { def groups = modifiersString?.tokenize(',') return groups.collect { group -> parseModifiers(group) } } /** * Parse a group of whitespace-delimited modifier names * @param modifiersString - a group of whitespace-delimited modifier names * @return the int value of the OR-ed modifiers (values from Opcodes) */ static int parseModifiers(String modifiersString) { def tokens = modifiersString?.tokenize() def mod = 0 tokens.each { token -> mod = mod | parseSingleModifier(token) } return mod } /** * Parse a single modifier name * @param name - a modifier name; e.g. "public", "private", "static", "final" * @return the int value for the modifier from Opcodes */ private static int parseSingleModifier(String name) { def mod = MODIFIERS[name] assert mod != null, "The modifier $name is not supported" return mod } // Prevent instantiation; all members are static private ModifiersUtil() { } } CodeNarc-0.23/src/main/groovy/org/codenarc/CodeNarc.groovy0000644000175000017500000001733012403723620023001 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc import org.codenarc.analyzer.FilesystemSourceAnalyzer import org.codenarc.analyzer.SourceAnalyzer import org.codenarc.report.HtmlReportWriter import org.codenarc.report.ReportWriterFactory /** * Command-line runner for CodeNarc. *

* The supported command-line parameters are all of the form: "-OPTION=VALUE", where OPTION is one * of the options in the following list. *

    *
  • help - Display the command-line help; If present, this must be the only command-line parameter.
  • *
  • basedir - The base directory for the source code to be analyzed. This is the root of the * directory tree. Defaults to the current directory ('.').
  • *
  • rulesetfiles - The path to the Groovy or XML RuleSet definition files, relative to the classpath. This can be a * single file path, or multiple paths separated by commas. Defaults to "rulesets/basic.xml".
  • *
  • includes - The comma-separated list of Ant file patterns specifying files that must be included; * all files are included when omitted.
  • *
  • excludes - The comma-separated list of Ant file patterns specifying files that must be excluded; * no files are excluded when omitted.
  • *
  • title - The title description for this analysis; used in the output report(s). Optional.
  • *
  • report - The definition of the report to produce. The option value is of the form TYPE[:FILENAME]. * where TYPE is 'html' and FILENAME is the filename (with optional path) of the output report filename. * If the report filename is omitted, the default filename is used ("CodeNarcReport.html"). * If no report option is specified, defaults to a single 'html' report with the default filename. *
  • *
* * @author Chris Mair */ @SuppressWarnings(['Println', 'PrintStackTrace']) class CodeNarc { protected static final HELP = """CodeNarc - static analysis for Groovy', Usage: java org.codenarc.CodeNarc [OPTIONS] where OPTIONS are zero or more command-line options of the form "-NAME[=VALUE]": -basedir= The base (root) directory for the source code to be analyzed. Defaults to the current directory ("."). -includes= The comma-separated list of Ant-style file patterns specifying files that must be included. Defaults to "**/*.groovy". -excludes= The comma-separated list of Ant-style file patterns specifying files that must be excluded. No files are excluded when omitted. -rulesetfiles= The path to the Groovy or XML RuleSet definition files, relative to the classpath. This can be a single file path, or multiple paths separated by commas. Defaults to "rulesets/basic.xml" -title= The title descriptive for this analysis; used in the output report(s). Optional. -report= The definition of the report to produce. The option value is of the form TYPE[:FILENAME], where TYPE is "html", "text", "xml", or "console" and FILENAME is the filename (with optional path) of the output report filename. If the report filename is omitted, the default filename is used for the specified report type ("CodeNarcReport.html" for "html" and "CodeNarcXmlReport.xml" for "xml"). If no report option is specified, default to a single "html" report with the default filename. -help Display the command-line help. If present, this must be the only command-line parameter. Example command-line invocations: java org.codenarc.CodeNarc java org.codenarc.CodeNarc -rulesetfiles="rulesets/basic.xml" title="My Project" java org.codenarc.CodeNarc -report=xml:MyXmlReport.xml -report=html java org.codenarc.CodeNarc -help'""" protected String ruleSetFiles protected String baseDir protected String includes protected String excludes protected String title protected List reports = [] // Abstract creation of the CodeNarcRunner instance to allow substitution of test spy for unit tests protected createCodeNarcRunner = { new CodeNarcRunner() } // Abstract calling System.exit() to allow substitution of test spy for unit tests protected static systemExit = { exitCode -> System.exit(exitCode) } /** * Main command-line entry-point. Run the CodeNarc application. * @param args - the String[] of command-line arguments */ static void main(String[] args) { def codeNarc = new CodeNarc() if (args == ['-help'] as String[]) { println HELP return } try { codeNarc.execute(args) } catch(Throwable t) { println "ERROR: ${t.message}" t.printStackTrace() println HELP systemExit(1) } } protected void execute(String[] args) { parseArgs(args) setDefaultsIfNecessary() def sourceAnalyzer = createSourceAnalyzer() reports.each { reportWriter -> reportWriter.title = title } def codeNarcRunner = createCodeNarcRunner() codeNarcRunner.ruleSetFiles = ruleSetFiles codeNarcRunner.reportWriters = reports codeNarcRunner.sourceAnalyzer = sourceAnalyzer codeNarcRunner.execute() } protected void setDefaultsIfNecessary() { baseDir = baseDir ?: '.' includes = includes ?: '**/*.groovy' ruleSetFiles = ruleSetFiles ?: 'rulesets/basic.xml' if (reports.empty) { reports << new HtmlReportWriter(title:title) } } /** * Create and return the SourceAnalyzer * @return a configured SourceAnalyzer instance */ protected SourceAnalyzer createSourceAnalyzer() { new FilesystemSourceAnalyzer(baseDirectory: baseDir, includes: includes, excludes: excludes) } protected void parseArgs(String[] args) { args.each { arg -> final PATTERN = /\-(.*)\=(.*)/ // -name=value def matcher = arg =~ PATTERN assert matcher, "Invalid argument format: [$arg]" def name = matcher[0][1] def value = matcher[0][2] switch(name) { case 'rulesetfiles': ruleSetFiles = value; break case 'basedir': baseDir = value; break case 'includes': includes = value; break case 'excludes': excludes = value; break case 'title': title = value; break case 'report': parseReport(value); break default: throw new IllegalArgumentException("Invalid option: [$arg]") } } } private parseReport(String argValue) { def parts = argValue.split(':', 2) def type = parts[0] def reportWriter = new ReportWriterFactory().getReportWriter(type) if (parts.size() > 1 && parts[1]) { reportWriter.outputFile = parts[1] } reports << reportWriter } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleregistry/0000755000175000017500000000000012623571301022611 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/ruleregistry/RuleRegistryHolder.groovy0000644000175000017500000000150412006632014027650 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.ruleregistry /** * Holds a reference to the RuleRegistry static singleton * * @author Chris Mair */ class RuleRegistryHolder { static RuleRegistry ruleRegistry } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleregistry/RuleRegistryInitializer.groovy0000644000175000017500000000170012006632016030716 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.ruleregistry /** * Performs initialization (loading) of the RuleRegistry singleton held by RuleRegistryHolder * * @author Chris Mair */ class RuleRegistryInitializer { void initializeRuleRegistry() { RuleRegistryHolder.ruleRegistry = new PropertiesFileRuleRegistry() } } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleregistry/RuleRegistry.groovy0000644000175000017500000000151512006632012026512 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.ruleregistry /** * Represents a registry of rule classes, accessible by rule name * * @author Chris Mair */ interface RuleRegistry { Class getRuleClass(String ruleName) } CodeNarc-0.23/src/main/groovy/org/codenarc/ruleregistry/PropertiesFileRuleRegistry.groovy0000644000175000017500000000425012006632016031372 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.ruleregistry import org.apache.log4j.Logger import org.codenarc.util.io.ClassPathResource /** * Implementation of RuleRegistry that loads the rules from the 'codenarc-base-rules.properties' properties file. * * @see org.codenarc.tool.GenerateCodeNarcRulesProperties * * @author Chris Mair */ class PropertiesFileRuleRegistry implements RuleRegistry { private static final LOG = Logger.getLogger(PropertiesFileRuleRegistry) private static final PROPERTIES_FILENAME = 'codenarc-base-rules.properties' public static final PROPERTIES_FILE = "src/main/resources/$PROPERTIES_FILENAME" private Properties properties PropertiesFileRuleRegistry() { loadRules() } /** * Return the Rule Class for the specified name or else null * @param ruleName - the rule name * @return the associated Rule Class or null if no Rule has been registered for the specified name */ Class getRuleClass(String ruleName) { String className = properties[ruleName] return className ? PropertiesFileRuleRegistry.getClassLoader().loadClass(className) : null } private void loadRules() { def startTime = System.currentTimeMillis() def inputStream = ClassPathResource.getInputStream(PROPERTIES_FILENAME) properties = new Properties() properties.load(inputStream) def elapsedTime = System.currentTimeMillis() - startTime LOG.info("Loaded properties file in ${elapsedTime}ms; ${properties.size()} rules") } } CodeNarc-0.23/src/main/groovy/org/codenarc/test/0000755000175000017500000000000012623571301021030 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/test/TestUtil.groovy0000644000175000017500000001456012041056140024053 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.test import org.apache.log4j.Logger import org.apache.log4j.spi.LoggingEvent /** * Contains common static utility methods for tests * * @author Chris Mair */ class TestUtil { /** * Assert that the specified code throws an exception of the specified type. Return the thrown exception message. * @param expectedExceptionClass - the Class of exception that is expected; may be null * @param code - the Closure containing the code to be executed, which is expected to throw an exception of the specified type * @return the message from the thrown Exception * * @throws AssertionError - if no exception is thrown by the code or if the thrown exception is not of the expected type */ static String shouldFail(Class expectedExceptionClass, Closure code) { def actualException = null try { code.call() } catch (Throwable thrown) { actualException = thrown } assert actualException, "No exception thrown. Expected [${expectedExceptionClass?.getName()}]" if (expectedExceptionClass) { assert expectedExceptionClass.isAssignableFrom(actualException.class), "Expected [${expectedExceptionClass.getName()}] but was [${actualException.class.name}]" } return actualException.getMessage() } /** * Assert that the specified code throws an exception (of any type). Return the thrown exception message. * @param code - the Closure containing the code to be executed, which is expected to throw an exception of the specified type * @return the message from the thrown Exception * * @throws AssertionError - if no exception is thrown by the code or if the thrown exception is not of the expected type */ static String shouldFail(Closure code) { shouldFail(null, code) } /** * Assert that the specified code throws an exception whose message contains the specified text. * @param expectedExceptionClass - the class of the Throwable that is expected to be thrown * @param expectedText - the text expected within the exception message * @param code - the Closure containing the code to be executed, which is expected to throw an exception of the specified type * @return the thrown Exception message * * @throws AssertionError - if no exception is thrown by the code or if the text is not contained in the exception message */ static String shouldFailWithMessageContaining(Class expectedExceptionClass, String expectedText, Closure code) { def msg = shouldFail(expectedExceptionClass, code) assert msg?.contains(expectedText), "Message [$msg] does not contain [$expectedText]" return msg } /** * Assert that the specified closure should throw an exception whose message contains text * @param text - the text expected within the message; may be a single String or a List of Strings * @param closure - the Closure to execute */ static void shouldFailWithMessageContaining(text, Closure closure) { def message = shouldFail(closure) def strings = text instanceof List ? text : [text] strings.each { string -> assert message.contains(string), "[$message] does not contain [$string]" } } /** * Return true if the text contains each of the specified strings * @param text - the text to search * @param strings - the Strings to check for; toString() is invoked on each element */ static boolean containsAll(String text, strings) { strings.every { text.contains(it.toString()) } } /** * Assert that the text contains each of the specified strings * @param text - the text to search * @param strings - the Strings that must be present within text; toString() is invoked on each element */ static void assertContainsAll(String text, strings) { strings.each { assert text.contains(it.toString()), "text does not contain [$it]" } } /** * Assert that the text contains each of the specified strings, in order * @param text - the text to search * @param strings - the Strings that must be present within text, and appear * in the order specified; toString() is applied to each. */ static void assertContainsAllInOrder(String text, strings) { def startIndex = 0 strings.each { string -> def index = text.indexOf(string.toString(), startIndex) assert index > -1, "text does not contain [$string]" startIndex = index + 1 } } /** * Assert that the two collections have equal Sets of elements. In other words, assert that * the two collections are the same, ignoring ordering and duplicates. */ static void assertEqualSets(Collection collection1, Collection collection2) { assert collection1 as Set == collection2 as Set } static String captureSystemOut(Closure closure) { def originalSystemOut = System.out def outputStream = new ByteArrayOutputStream() try { System.out = new PrintStream(outputStream) closure() } finally { System.out = originalSystemOut } outputStream.toString() } static List captureLog4JMessages(Closure closure) { def inMemoryAppender = new InMemoryAppender() def logger = Logger.rootLogger logger.addAppender(inMemoryAppender) try { closure() } finally { logger.removeAppender(inMemoryAppender) } return inMemoryAppender.getLoggingEvents() } } CodeNarc-0.23/src/main/groovy/org/codenarc/test/InMemoryAppender.groovy0000644000175000017500000000272312311373552025523 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.test import org.apache.log4j.AppenderSkeleton import org.apache.log4j.spi.LoggingEvent /** * Log4J Appender that saves all logged loggingEvents in a List. * * @author Chris Mair */ class InMemoryAppender extends AppenderSkeleton implements Closeable { private final List loggingEvents = [] /** * Return the List of LoggingEvents logged to this Appender * @return the List of logged LoggingEvents */ List getLoggingEvents() { return loggingEvents } void clearLoggedMessages() { loggingEvents.clear() } protected void append(LoggingEvent loggingEvent) { loggingEvents.add(loggingEvent) } @Override void close() { // Do nothing } boolean requiresLayout() { return false } } CodeNarc-0.23/src/main/groovy/org/codenarc/test/AbstractTestCase.groovy0000644000175000017500000000417212311373552025504 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.test import org.apache.log4j.Logger import org.junit.Before import org.junit.Rule import org.junit.rules.TestName /** * Abstract superclass for tests * * @author Chris Mair * @author Hamlet D'Arcy */ @SuppressWarnings(['AbstractClassWithoutAbstractMethod', 'ConfusingMethodName']) abstract class AbstractTestCase { protected static final CODENARC_PROPERTIES_FILE_PROP = 'codenarc.properties.file' @SuppressWarnings('FieldName') protected final LOG = Logger.getLogger(getClass()) @SuppressWarnings('PublicInstanceField') @Rule public TestName testName = new TestName() /** * Write out the specified log message, prefixing with the current class name. * @param message - the message to log; toString() is applied first */ protected void log(message) { LOG.info message } protected String getName() { return testName.getMethodName() } private String classNameNoPackage() { def className = getClass().name def index = className.lastIndexOf('.') (index > -1) ? className[index + 1 .. -1] : className } //------------------------------------------------------------------------------------ // Test Setup and Tear Down //------------------------------------------------------------------------------------ @Before void setUpAbstractTestCase() { log "----------[ ${classNameNoPackage()}.${getName()} ]----------" } } CodeNarc-0.23/src/main/groovy/org/codenarc/analyzer/0000755000175000017500000000000012623571301021676 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/analyzer/AbstractSourceAnalyzer.groovy0000644000175000017500000000361712253152040027600 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.analyzer import org.codenarc.rule.Rule import org.codenarc.rule.Violation import org.codenarc.ruleset.RuleSet import org.codenarc.source.CustomCompilerPhaseSourceDecorator import org.codenarc.source.SourceCode /** * Common functionality for SourceAnalyzers. */ @SuppressWarnings('AbstractClassWithoutAbstractMethod') abstract class AbstractSourceAnalyzer implements SourceAnalyzer { protected List collectViolations(SourceCode sourceCode, RuleSet ruleSet) { def allViolations = [] def suppressionService = sourceCode.suppressionAnalyzer def validRules = ruleSet.rules.findAll { !suppressionService.isRuleSuppressed(it) } def sourceAfterPhase = [(SourceCode.DEFAULT_COMPILER_PHASE): sourceCode].withDefault { phase -> new CustomCompilerPhaseSourceDecorator(sourceCode, phase) } for (Rule rule: validRules) { def sourceAfterRequiredPhase = sourceAfterPhase[rule.compilerPhase] def violations = rule.applyTo(sourceAfterRequiredPhase) violations.removeAll { suppressionService.isViolationSuppressed(it) } allViolations.addAll(violations) } allViolations.sort { it.lineNumber } allViolations } } CodeNarc-0.23/src/main/groovy/org/codenarc/analyzer/SourceAnalyzer.groovy0000644000175000017500000000262312311373552026120 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.analyzer import org.codenarc.results.Results import org.codenarc.ruleset.RuleSet /** * The interface for objects that can analyze the source files within one or more directory * trees using a specified RuleSet and produce report results. * * @author Chris Mair */ interface SourceAnalyzer { /** * Analyze all source code using the specified RuleSet and return the report results. * @param ruleset - the RuleSet to apply to each source component; must not be null. * @return the results from applying the RuleSet to all of the source */ Results analyze(RuleSet ruleSet) /** * Return the List of source directories to be analyzed. May be empty; may not be null. */ List getSourceDirectories() } CodeNarc-0.23/src/main/groovy/org/codenarc/analyzer/SuppressionAnalyzer.java0000644000175000017500000001745512006632012026605 0ustar ebourgebourgpackage org.codenarc.analyzer; import org.codehaus.groovy.ast.*; import org.codehaus.groovy.ast.expr.ConstantExpression; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.expr.ListExpression; import org.codenarc.rule.Rule; import org.codenarc.rule.Violation; import org.codenarc.source.SourceCode; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** * This class encapsulates all of the logic for determining if an rule is suppressed or not. */ public class SuppressionAnalyzer { private static final ClassNode SUPPRESS_WARNINGS = ClassHelper.make(SuppressWarnings.class); private final SourceCode source; private boolean initialized = false; private final Object initializationLock = new Object(); private final Set suppressedRuleNames = Collections.synchronizedSet(new HashSet()); private final Map suppressionsByLineNumber = new ConcurrentHashMap(); public SuppressionAnalyzer(SourceCode source) { this.source = source; } public boolean isRuleSuppressed(Rule rule) { init(); return suppressedRuleNames.contains(rule.getName()); } public List filterSuppressedViolations(Iterable violations) { List result = new ArrayList(); if (violations == null) return result; for (Violation v : violations) { if (!isViolationSuppressed(v)) { result.add(v); } } return result; } public boolean isViolationSuppressed(Violation violation) { if (violation == null) return false; if (violation.getRule() == null) return false; if (violation.getRule().getName() == null) return false; if (violation.getLineNumber() == null) return false; if (violation.getLineNumber() < 0) return false; init(); String ruleName = violation.getRule().getName(); int lineNumber = violation.getLineNumber(); BitSet lines = suppressionsByLineNumber.get(ruleName); if (lines != null) { return lines.get(lineNumber); } return false; } private void init() { synchronized (initializationLock) { if (!initialized) { ModuleNode ast = source.getAst(); if (ast != null) { suppressedRuleNames.addAll(getSuppressedRuleNames(ast.getPackage())); suppressedRuleNames.addAll(getSuppressedRuleNames(ast.getImports())); suppressedRuleNames.addAll(getSuppressedRuleNames(ast.getStaticStarImports().values())); suppressedRuleNames.addAll(getSuppressedRuleNames(ast.getStarImports())); // if it is the only class in the file, then a @SuppressWarnings applies to everything if (ast.getClasses() != null && ast.getClasses().size() == 1) { suppressedRuleNames.addAll(getSuppressedRuleNames(ast.getClasses())); } // build up suppressions by line number suppressionsByLineNumber.putAll(getSuppressionsByLineNumber(ast)); } initialized = true; } } } private Map getSuppressionsByLineNumber(ModuleNode ast) { Map result = new HashMap(); int numLines = getLineCount(ast); for (ClassNode classNode : ast.getClasses()) { for (String ruleName : getSuppressedRuleNames(classNode)) { populateLineNumbers(classNode, result, numLines, ruleName); } for (AnnotatedNode fieldNode : from(classNode.getFields())) { for (String ruleName : getSuppressedRuleNames(fieldNode)) { populateLineNumbers(fieldNode, result, numLines, ruleName); } } for (AnnotatedNode methodNode : from(classNode.getMethods())) { for (String ruleName : getSuppressedRuleNames(methodNode)) { populateLineNumbers(methodNode, result, numLines, ruleName); } } } return result; } @SuppressWarnings({"unchecked"}) private static T from(T from) { if (from != null) return from; return (T) Collections.emptyList(); } private static void populateLineNumbers(AnnotatedNode node, Map result, int numLines, String ruleName) { final BitSet bits; if (result.containsKey(ruleName)) { bits = result.get(ruleName); } else { bits = new BitSet(numLines); } bits.set(node.getLineNumber(), node.getLastLineNumber() + 1); result.put(ruleName, bits); } private static int getLineCount(ModuleNode ast) { int highest = 0; for (AnnotatedNode classNode : ast.getClasses()) { if (classNode.getLastLineNumber() > highest) { highest = classNode.getLastLineNumber(); } } return highest; } private static Collection getSuppressedRuleNames(Collection imports) { List result = new ArrayList(); if (imports != null) { for (AnnotatedNode node : imports) { result.addAll(getSuppressedRuleNames(node)); } } return result; } private static Collection getSuppressedRuleNames(AnnotatedNode node) { List result = new ArrayList(); if (node == null) return result; Set annos = getSuppressWarningsAnnotations(node); for (AnnotationNode annotation : annos) { Map members = annotation.getMembers(); if (members != null) { Collection values = members.values(); if (values != null) { for (Expression exp : values) { if (exp instanceof ConstantExpression && ((ConstantExpression) exp).getValue() instanceof String) { result.add((String) ((ConstantExpression) exp).getValue()); } else if (exp instanceof ListExpression) { List expressions = ((ListExpression) exp).getExpressions(); if (expressions != null) { for (Expression entry : expressions) { if (entry instanceof ConstantExpression && ((ConstantExpression) entry).getValue() instanceof String) { result.add((String) ((ConstantExpression) entry).getValue()); } } } } } } } } return result; } private static Set getSuppressWarningsAnnotations(AnnotatedNode node) { Set result = new HashSet(); result.addAll(node.getAnnotations(SUPPRESS_WARNINGS)); List annots = node.getAnnotations(); if (annots != null) { for (AnnotationNode n : annots) { ClassNode classNode = n.getClassNode(); if (classNode != null) { String name = classNode.getName(); if ("SuppressWarnings".equals(name)) { result.add(n); } else if ("java.lang.SuppressWarnings".equals(name)) { result.add(n); } } } } return result; } } CodeNarc-0.23/src/main/groovy/org/codenarc/analyzer/StringSourceAnalyzer.groovy0000644000175000017500000000233612311373552027310 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.analyzer import org.codenarc.results.Results import org.codenarc.results.VirtualResults import org.codenarc.ruleset.RuleSet import org.codenarc.source.SourceString /** * Analyzes Strings. * * @author Hamlet D'Arcy */ class StringSourceAnalyzer extends AbstractSourceAnalyzer { SourceString source StringSourceAnalyzer(String source) { this.source = new SourceString(source) } Results analyze(RuleSet ruleSet) { List allViolations = collectViolations(source, ruleSet) new VirtualResults(allViolations) } List getSourceDirectories() { [] } } CodeNarc-0.23/src/main/groovy/org/codenarc/analyzer/FilesystemSourceAnalyzer.groovy0000644000175000017500000001227412311373552030170 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.analyzer import org.codenarc.results.DirectoryResults import org.codenarc.results.FileResults import org.codenarc.results.Results import org.codenarc.ruleset.RuleSet import org.codenarc.source.SourceCode import org.codenarc.source.SourceFile import org.codenarc.util.WildcardPattern /** * SourceAnalyzer implementation that recursively processes files from the file system. * * @author Chris Mair */ class FilesystemSourceAnalyzer extends AbstractSourceAnalyzer { static final SEP = '/' static final DEFAULT_INCLUDES = '**/*.groovy' /** * The base (root) directory. Must not be null or empty. */ String baseDirectory /** * The ant-style pattern of files to include in the analysis. Defaults to match all * files with names ending with '.groovy'. If null, match all * files/directories. This pattern can optionally contain wildcards: '**', '*' and '?'. * All file separators within paths are normalized to the standard '/' separator, * so use the '/' separator within this pattern where necessary. Example: * "**/*.groovy". If both includes and excludes * are specified, then only files/directories that match at least one of the * includes and none of the excludes are analyzed. */ String includes = DEFAULT_INCLUDES /** * The ant-style pattern of files to exclude from the analysis. If null, exclude no * files/directories. This pattern can optionally contain wildcards: '**', '*' and '?'. * All file separators within paths are normalized to the standard '/' separator, * so use the '/' separator within this pattern where necessary. Example: * "**/*.groovy". If both includes and excludes * are specified, then only files/directories that match at least one of the * includes and none of the excludes are analyzed. */ String excludes private WildcardPattern includesPattern private WildcardPattern excludesPattern /** * Analyze the source with the configured directory tree(s) using the specified RuleSet and return the report results. * @param ruleset - the RuleSet to apply to each of the (applicable) files in the source directories * @return the results from applying the RuleSet to all of the files in the source directories */ Results analyze(RuleSet ruleSet) { assert baseDirectory assert ruleSet initializeWildcardPatterns() def reportResults = new DirectoryResults() def dirResults = processDirectory('', ruleSet) reportResults.addChild(dirResults) reportResults } List getSourceDirectories() { [baseDirectory] } private DirectoryResults processDirectory(String dir, RuleSet ruleSet) { def dirResults = new DirectoryResults(dir) def dirFile = new File((String) baseDirectory, (String) dir) dirFile.eachFile { file -> def dirPrefix = dir ? dir + SEP : dir def filePath = dirPrefix + file.name if (file.directory) { def subdirResults = processDirectory(filePath, ruleSet) // If any of the descendent directories have matching files, then include in final results if (subdirResults.getTotalNumberOfFiles(true)) { dirResults.addChild(subdirResults) } } else { processFile(filePath, dirResults, ruleSet) } } dirResults } private processFile(String filePath, DirectoryResults dirResults, RuleSet ruleSet) { def file = new File((String) baseDirectory, filePath) def sourceFile = new SourceFile(file) if (matches(sourceFile)) { dirResults.numberOfFilesInThisDirectory++ List allViolations = collectViolations(sourceFile, ruleSet) if (allViolations) { def fileResults = new FileResults(filePath, allViolations) dirResults.addChild(fileResults) } } } protected boolean matches(SourceCode sourceFile) { includesPattern.matches(sourceFile.path) && !excludesPattern.matches(sourceFile.path) } protected void initializeWildcardPatterns() { includesPattern = new WildcardPattern(includes) excludesPattern = new WildcardPattern(excludes, false) // do not match by default } } CodeNarc-0.23/src/main/groovy/org/codenarc/analyzer/DirectorySourceAnalyzer.groovy0000644000175000017500000001162212311373552030004 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.analyzer import org.codenarc.results.DirectoryResults import org.codenarc.results.FileResults import org.codenarc.results.Results import org.codenarc.ruleset.RuleSet import org.codenarc.source.SourceCodeCriteria import org.codenarc.source.SourceFile /** * SourceAnalyzer implementation that recursively processes files in the configured source directories. * * @deprecated This is an internal class that will be removed in the future * * @author Chris Mair */ class DirectorySourceAnalyzer extends AbstractSourceAnalyzer { static final SEP = '/' /** * The base directory; the sourceDirectories are relative to this, * if not null. If this value is null, then treat sourceDirectories as full paths. */ String baseDirectory /** * The list of source directories, relative to the baseDirectory * if it is not null. If sourceDirectories is null, then analyze files recursively * from baseDirectory. */ List sourceDirectories /** * Only analyze pathnames matching this regular expression. If null, match all pathnames. * This defaults to matching all pathnames that end with '.groovy'. */ String applyToFilesMatching = /.*\.groovy/ /** * Do NOT analyze pathnames matching this regular expression. If null, then do not exclude any pathnames. */ String doNotApplyToFilesMatching /** * Only analyze filenames matching this value. * The value may optionally be a comma-separated list of names. * The name(s) may optionally include wildcard characters ('*' or '?'). */ String applyToFileNames /** * Do NOT analyze filenames matching this value. * The value may optionally be a comma-separated list of names. * The name(s) may optionally include wildcard characters ('*' or '?'). */ String doNotApplyToFileNames /** * Analyze the source with the configured directory tree(s) using the specified RuleSet and return the report results. * @param ruleset - the RuleSet to apply to each of the (applicable) files in the source directories * @return the results from applying the RuleSet to all of the files in the source directories */ Results analyze(RuleSet ruleSet) { assert baseDirectory || sourceDirectories assert ruleSet def reportResults = new DirectoryResults() def srcDirs = sourceDirectories ?: [''] srcDirs.each { srcDir -> def dirResults = processDirectory(srcDir, ruleSet) reportResults.addChild(dirResults) } reportResults } private DirectoryResults processDirectory(String dir, RuleSet ruleSet) { def dirResults = new DirectoryResults(dir) def dirFile = new File((String)baseDirectory, (String)dir) dirFile.eachFile { file -> def dirPrefix = dir ? dir + SEP : dir def filePath = dirPrefix + file.name if (file.directory) { def subdirResults = processDirectory(filePath, ruleSet) // If any of the descendent directories have matching files, then include in final results if (subdirResults.getTotalNumberOfFiles(true)) { dirResults.addChild(subdirResults) } } else { processFile(filePath, dirResults, ruleSet) } } dirResults } private processFile(String filePath, DirectoryResults dirResults, RuleSet ruleSet) { def file = new File((String)baseDirectory, filePath) def sourceFile = new SourceFile(file) if (new SourceCodeCriteria( applyToFilesMatching:applyToFilesMatching, doNotApplyToFilesMatching:doNotApplyToFilesMatching, applyToFileNames:applyToFileNames, doNotApplyToFileNames:doNotApplyToFileNames).matches(sourceFile)) { dirResults.numberOfFilesInThisDirectory ++ List allViolations = collectViolations(sourceFile, ruleSet) if (allViolations) { def fileResults = new FileResults(filePath, allViolations) dirResults.addChild(fileResults) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/0000755000175000017500000000000012623571301021020 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/0000755000175000017500000000000012623571301023357 5ustar ebourgebourg././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryFinalOnPrivateMethodRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryFinalOnPrivateMethodRule.groo0000644000175000017500000000304312041061502033330 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import java.lang.reflect.Modifier /** * A private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary. * * @author 'Hamlet D'Arcy' */ class UnnecessaryFinalOnPrivateMethodRule extends AbstractAstVisitorRule { String name = 'UnnecessaryFinalOnPrivateMethod' int priority = 3 Class astVisitorClass = UnnecessaryFinalOnPrivateMethodAstVisitor } class UnnecessaryFinalOnPrivateMethodAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (Modifier.isFinal(node.modifiers) && Modifier.isPrivate(node.modifiers)) { addViolation(node, "The '$node.name' method is both private and final") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryGetterRule.groovy0000644000175000017500000000504412311370173031131 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Checks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. * A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). * Getters do not take method arguments. * * @author Hamlet D'Arcy */ class UnnecessaryGetterRule extends AbstractAstVisitorRule { String name = 'UnnecessaryGetter' int priority = 3 Class astVisitorClass = UnnecessaryGetterAstVisitor } class UnnecessaryGetterAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { addViolationsIfGetter(call) } private addViolationsIfGetter(MethodCallExpression call) { if (AstUtil.getMethodArguments(call).size() != 0) { return } if (!(call.method instanceof ConstantExpression)) { return } String name = call.method.value if (name == 'getClass' || name.length() < 4) { return } if (name[0..2] == 'get' && (name[3] as Character).isUpperCase()) { if (name.length() == 4) { addViolation call, "$name() can probably be rewritten as ${name[3].toLowerCase()}" } else if ((name[4] as Character).isLowerCase()) { def propertyName = name[3].toLowerCase() + name[4..-1] addViolation call, "$name() can probably be rewritten as $propertyName" } else { def propertyName = name[3..-1] addViolation call, "$name() can probably be rewritten as $propertyName" } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryTernaryExpressionRule.groovy0000644000175000017500000001231112311373552033402 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * Rule that checks for ternary expressions where the conditional expression always evaluates to * a boolean and the true and false expressions are merely returning true and * false constants. These cases can be replaced by a simple boolean expression. * Examples include: *
    *
  • boolean result = x==99 ? true : false - can be replaced by boolean result = x==99
  • *
  • boolean result = x && y ? true : false - can be replaced by boolean result = x && y
  • *
  • def result = x||y ? false : true - can be replaced by def result = !(x||y)
  • *
  • boolean result = x >= 1 ? true: false - can be replaced by boolean result = x >= 1
  • *
  • boolean result = x < 99 ? Boolean.TRUE : Boolean.FALSE - can be replaced by boolean result = x < 99
  • *
  • def result = !x ? true : false - can be replaced by def result = !x
  • *
* * The rule also checks for ternary expressions where the true and false expressions are the same constant or * variable expression. Examples include: *
    *
  • def result = x ? '123' : '123' - can be replaced by def result = '123'
  • *
  • def result = x ? null : null - can be replaced by def result = null
  • *
  • def result = x ? 23 : 23 - can be replaced by def result = 23
  • *
  • def result = x ? MAX_VALUE : MAX_VALUE - can be replaced by def result = MAX_VALUE
  • *
* * @author Chris Mair */ class UnnecessaryTernaryExpressionRule extends AbstractAstVisitorRule { String name = 'UnnecessaryTernaryExpression' int priority = 3 Class astVisitorClass = UnnecessaryTernaryExpressionAstVisitor } class UnnecessaryTernaryExpressionAstVisitor extends AbstractAstVisitor { private static final BOOLEAN_COMPARISON_OPERATIONS = ['<', '>', '>=', '<=', '==', '!=', '==~'] private static final BOOLEAN_LOGIC_OPERATIONS = ['&&', '||'] void visitTernaryExpression(TernaryExpression ternaryExpression) { if (isFirstVisit(ternaryExpression)) { def trueExpression = ternaryExpression.trueExpression def falseExpression = ternaryExpression.falseExpression def booleanExpression = ternaryExpression.booleanExpression if (areBothTheSame(trueExpression, falseExpression) || (isBooleanConditionalExpression(booleanExpression) && areTrueAndFalse(trueExpression, falseExpression))) { addViolation(ternaryExpression, 'The ternary expression is useless or nonsensical') } } super.visitTernaryExpression(ternaryExpression) } private boolean isBooleanConditionalExpression(BooleanExpression conditionalExpression) { def expression = conditionalExpression.expression if (expression instanceof NotExpression) { return true } if (expression instanceof BinaryExpression && isOperationThatReturnsABoolean(expression)) { return true } false } private boolean isOperationThatReturnsABoolean(expression) { def operationName = expression.operation.text if (operationName in BOOLEAN_COMPARISON_OPERATIONS) { return true } if (operationName in BOOLEAN_LOGIC_OPERATIONS) { return true } false } private boolean areBothTheSame(Expression trueExpression, Expression falseExpression) { if (trueExpression instanceof ConstantExpression && falseExpression instanceof ConstantExpression && trueExpression.getValue() == falseExpression.getValue()) { return true } if (trueExpression instanceof VariableExpression && falseExpression instanceof VariableExpression && trueExpression.getName() == falseExpression.getName()) { return true } false } private boolean areTrueAndFalse(Expression trueExpression, Expression falseExpression) { (AstUtil.isTrue(trueExpression) && AstUtil.isFalse(falseExpression)) || (AstUtil.isFalse(trueExpression) && AstUtil.isTrue(falseExpression)) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryGStringRule.groovy0000644000175000017500000000616212311370173031256 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.GStringExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * String objects should be created with single quotes, and GString objects created with double quotes. Creating normal String objects with double quotes is confusing to readers. * * @author Hamlet D'Arcy */ class UnnecessaryGStringRule extends AbstractAstVisitorRule { String name = 'UnnecessaryGString' int priority = 3 Class astVisitorClass = UnnecessaryGStringAstVisitor } class UnnecessaryGStringAstVisitor extends AbstractAstVisitor { @Override void visitConstantExpression(ConstantExpression expression) { if (isFirstVisit(expression) && expression.value instanceof String && expression.lineNumber > -1) { if (!expressionContainsBannedCharacters(expression)) { suppressException(StringIndexOutOfBoundsException) { addViolationIfDoubleQuoted(expression) } } } super.visitConstantExpression(expression) } private addViolationIfDoubleQuoted(ConstantExpression expression) { def line = getSourceCode().getLines()[expression.lineNumber - 1] def col = line[expression.columnNumber - 1] if (col == '"') { addViolation(expression, "The String '$expression.value' can be wrapped in single quotes instead of double quotes") } } @Override void visitGStringExpression(GStringExpression expression) { // do not visit the string portions of the GString visitListOfExpressions(expression.getValues()) } @SuppressWarnings('CatchThrowable') private static suppressException(Class exceptionType, Closure c) { try { c() } catch (Throwable t) { if (!exceptionType.getClass().isAssignableFrom(t.getClass())) { throw t } } } private boolean expressionContainsBannedCharacters(ConstantExpression expression) { if (expression.value.contains('$')) { return true } if (expression.value.contains("'")) { return true } if (expression.lineNumber == expression.lastLineNumber) { return false } def lines = getSourceCode().getLines() ((expression.lineNumber - 1).. (expression.lastLineNumber - 1)).any { (lines[it].contains('$')) || (lines[it].contains("'")) } } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessarySafeNavigationOperatorRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessarySafeNavigationOperatorRule.gr0000644000175000017500000000505312415361352033400 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.unnecessary import static org.codenarc.util.AstUtil.* import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Check for safe navigation operator (?.) applied to constants and literals, or "this" or * "super", which can never be null. * * @author Chris Mair */ class UnnecessarySafeNavigationOperatorRule extends AbstractAstVisitorRule { String name = 'UnnecessarySafeNavigationOperator' int priority = 3 Class astVisitorClass = UnnecessarySafeNavigationOperatorAstVisitor } class UnnecessarySafeNavigationOperatorAstVisitor extends AbstractAstVisitor { @Override void visitPropertyExpression(PropertyExpression expression) { checkExpression(expression, expression.objectExpression) super.visitPropertyExpression(expression) } @Override void visitMethodCallExpression(MethodCallExpression expression) { checkExpression(expression, expression.objectExpression) super.visitMethodCallExpression(expression) } private void checkExpression(Expression expression, Expression objExpr) { // TODO Could expand this to also check for class expressions, e.g. String?.toString(), but not parsed consistently in Groovy 1.7 if (expression.safe && (isConstantOrLiteral(objExpr) || isThisReference(objExpr) || isSuperReference(objExpr) || isConstructorCall(objExpr))) { def expressionText = '"' + objExpr.text + '"' addViolation(expression, "The safe navigation operator (?.) is unnecessary for $expressionText in class $currentClassName") } } private boolean isConstructorCall(Expression objExpr) { return objExpr instanceof ConstructorCallExpression } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryBigDecimalInstantiationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryBigDecimalInstantiationRule.g0000644000175000017500000000325512006632016033325 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitorRule /** * It is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G. * * @author Hamlet D'Arcy */ class UnnecessaryBigDecimalInstantiationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryBigDecimalInstantiation' int priority = 3 Class astVisitorClass = UnnecessaryBigDecimalInstantiationAstVisitor } class UnnecessaryBigDecimalInstantiationAstVisitor extends UnnecessaryInstantiationAstVisitor { UnnecessaryBigDecimalInstantiationAstVisitor() { super(BigDecimal, [String, Double], 'G') } @Override protected boolean shouldSkipViolation(Object value) { (value instanceof String) && !value.contains('.') } @Override protected boolean isTypeSuffixNecessary(argument) { if (argument.getClass() == String) { return !argument.contains('.') } return argument.getClass() in [Integer, Long] } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryModOneRule.groovy0000644000175000017500000000356612311370173031067 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.Expression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Any expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2). * * @author 'Hamlet D'Arcy' */ class UnnecessaryModOneRule extends AbstractAstVisitorRule { String name = 'UnnecessaryModOne' int priority = 3 Class astVisitorClass = UnnecessaryModOneAstVisitor } class UnnecessaryModOneAstVisitor extends AbstractAstVisitor { @Override void visitBinaryExpression(BinaryExpression expression) { if (AstUtil.isBinaryExpressionType(expression, '%')) { Expression rhs = expression.rightExpression if (rhs instanceof ConstantExpression && rhs.value == 1) { Expression lhs = expression.leftExpression addViolation(expression, "$expression.text is guaranteed to be zero. Did you mean ($lhs.text & 1) or ($lhs.text % 2)") } } super.visitBinaryExpression(expression) } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInFieldDeclarationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInFieldDeclarationRule.gro0000644000175000017500000000620512141066466033250 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil /** * If a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, * 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}. * * @author Hamlet D'Arcy */ class UnnecessaryDefInFieldDeclarationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryDefInFieldDeclaration' int priority = 3 Class astVisitorClass = UnnecessaryDefInFieldDeclarationAstVisitor } class UnnecessaryDefInFieldDeclarationAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { String declaration = AstUtil.getDeclaration(node, sourceCode) def definitionStart = declaration.indexOf('=') if (definitionStart != -1) { declaration = declaration[0 .. definitionStart - 1] } if (contains(declaration, 'def')) { if (contains(declaration, 'private')) { addViolation(node, 'The def keyword is unneeded when a field is marked private') } else if (contains(declaration, 'protected')) { addViolation(node, 'The def keyword is unneeded when a field is marked protected') } else if (contains(declaration, 'public')) { addViolation(node, 'The def keyword is unneeded when a field is marked public') } else if (contains(declaration, 'static')) { addViolation(node, 'The def keyword is unneeded when a field is marked static') } else if (contains(declaration, 'final')) { addViolation(node, 'The def keyword is unneeded when a field is marked final') } else if (contains(declaration, 'strictfp')) { addViolation(node, 'The def keyword is unneeded when a field is marked strictfp') } else if (contains(declaration, 'Object')) { addViolation(node, 'The def keyword is unneeded when a field is specified Object type') } else if (node.type != ClassHelper.DYNAMIC_TYPE) { addViolation(node, 'The def keyword is unneeded when a field type is specified') } } } private static boolean contains(String declaration, String modifier) { declaration?.startsWith(modifier) || declaration?.contains(' ' + modifier + ' ') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/AddEmptyStringRule.groovy0000644000175000017500000000344212006632014030351 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Finds empty string literals which are being added. This is an inefficient way to convert any type to a String. * * @author Hamlet D'Arcy */ class AddEmptyStringRule extends AbstractAstVisitorRule { String name = 'AddEmptyString' int priority = 2 Class astVisitorClass = AddEmptyStringAstVisitor } class AddEmptyStringAstVisitor extends AbstractAstVisitor { @Override void visitBinaryExpression(BinaryExpression expression) { if (isFirstVisit(expression) && AstUtil.isBinaryExpressionType(expression, '+')) { if (expression.leftExpression instanceof ConstantExpression && expression.leftExpression.value == '') { addViolation expression, 'Concatenating an empty string is an inefficient way to convert an object to a String. Consider using toString() or String.valueOf(Object)' } } super.visitBinaryExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryReturnKeywordRule.groovy0000644000175000017500000000474712006632014032530 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * In Groovy, the return keyword is often optional. If a statement is the last line in a method or closure then you do not need to have the return keyword. * * @author Hamlet D'Arcy */ class UnnecessaryReturnKeywordRule extends AbstractAstVisitorRule { String name = 'UnnecessaryReturnKeyword' int priority = 3 Class astVisitorClass = UnnecessaryReturnKeywordAstVisitor } class UnnecessaryReturnKeywordAstVisitor extends AbstractAstVisitor { void visitMethodEx(MethodNode node) { def lastStatement = getLastStatement(node) if (lastStatement instanceof ReturnStatement && !(lastStatement.expression instanceof ClosureExpression)) { addViolation lastStatement, 'The return keyword is not needed and can be removed' } super.visitMethodEx node } void visitClosureExpression(ClosureExpression node) { def lastStatement = getLastStatement(node) if (lastStatement instanceof ReturnStatement && !(lastStatement.expression instanceof ClosureExpression)) { addViolation lastStatement, 'The return keyword is not needed and can be removed' } super.visitClosureExpression node } /** * This is not a good general function for AstUtils. * It is too specific and may not work across different ASTNode subtypes. * @param node * node */ private static getLastStatement(node) { if (node.code instanceof BlockStatement && node.code.statements) { return node.code.statements.last() } null } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryNullCheckBeforeInstanceOfRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryNullCheckBeforeInstanceOfRule0000644000175000017500000000464612006632012033321 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.BinaryExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * There is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument. * * @author Hamlet D'Arcy * @author Chris Mair */ class UnnecessaryNullCheckBeforeInstanceOfRule extends AbstractAstVisitorRule { String name = 'UnnecessaryNullCheckBeforeInstanceOf' int priority = 3 Class astVisitorClass = UnnecessaryNullCheckBeforeInstanceOfAstVisitor } class UnnecessaryNullCheckBeforeInstanceOfAstVisitor extends AbstractAstVisitor { @Override void visitBinaryExpression(BinaryExpression exp) { if (exp.operation.text == '&&') { if (AstUtil.isNotNullCheck(exp.leftExpression) || AstUtil.isNotNullCheck(exp.rightExpression)) { if (AstUtil.isInstanceOfCheck(exp.leftExpression) || AstUtil.isInstanceOfCheck(exp.rightExpression)) { addViolationIfTargetsMatch(exp) } } } super.visitBinaryExpression(exp) } private addViolationIfTargetsMatch(BinaryExpression exp) { def nullTarget = AstUtil.getNullComparisonTarget(exp.leftExpression) ?: AstUtil.getNullComparisonTarget(exp.rightExpression) def instanceofTarget = AstUtil.getInstanceOfTarget(exp.leftExpression) ?: AstUtil.getInstanceOfTarget(exp.rightExpression) if (nullTarget && instanceofTarget && nullTarget == instanceofTarget) { def suggestion = AstUtil.isInstanceOfCheck(exp.leftExpression) ? exp.leftExpression.text : exp.rightExpression.text addViolation(exp, "The condition $exp.text can be safely simplified to $suggestion") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryPackageReferenceRule.groovy0000644000175000017500000001355612314144004033053 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.unnecessary import static org.codenarc.util.AstUtil.AUTO_IMPORTED_CLASSES import static org.codenarc.util.AstUtil.AUTO_IMPORTED_PACKAGES import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.GroovyVersion import org.codenarc.util.ImportUtil import org.codehaus.groovy.ast.expr.* /** * Checks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, * java.util.Map and groovy.lang.Closure, as well as classes that were explicitly imported. * * @author Chris Mair */ class UnnecessaryPackageReferenceRule extends AbstractAstVisitorRule { String name = 'UnnecessaryPackageReference' int priority = 3 Class astVisitorClass = UnnecessaryPackageReferenceAstVisitor } class UnnecessaryPackageReferenceAstVisitor extends AbstractAstVisitor { private static final IGNORE_SUPERCLASS_NAMES = ['java.lang.Object', 'java.lang.Enum', 'groovy.lang.Script'] private final List importedClassNames = [] private final List starImportPackageNames = [] // TODO Only ignore java.util.Object superclass if it was not explicitly specified @Override protected void visitClassEx(ClassNode node) { initializeImportNames() def superClassName = node.superClass.name if (!IGNORE_SUPERCLASS_NAMES.contains(superClassName) && !(GroovyVersion.groovy1_8_OrGreater && node.isScript() && node.name == 'None')) { checkType(superClassName, node) } node.interfaces.each { interfaceNode -> checkType(interfaceNode.name, node) } super.visitClassEx(node) } @Override void visitField(FieldNode node) { checkTypeIfNotDynamicallyTyped(node) super.visitField(node) } @Override void visitConstructorCallExpression(ConstructorCallExpression node) { if (isFirstVisit(node) && !node.superCall && !node.isThisCall()) { checkType(node.type.name, node) } super.visitConstructorCallExpression(node) } @Override void visitVariableExpression(VariableExpression expression) { if (isNotAutoBoxed(expression)) { checkTypeIfNotDynamicallyTyped(expression) } super.visitVariableExpression(expression) } @Override void visitMethodEx(MethodNode node) { if (!node.isDynamicReturnType()) { // ignore 'def' which resolves to java.lang.Object checkType(node.returnType.name, node) } node.parameters.each { parameter -> checkTypeIfNotDynamicallyTyped(parameter) } super.visitMethodEx(node) } @Override void visitClosureExpression(ClosureExpression expression) { expression.parameters.each { parameter -> checkTypeIfNotDynamicallyTyped(parameter) } super.visitClosureExpression(expression) } @Override void visitClassExpression(ClassExpression expression) { checkType(expression.type.name, expression) super.visitClassExpression(expression) } @Override void visitPropertyExpression(PropertyExpression expression) { checkType(expression.text, expression) } @Override void visitCastExpression(CastExpression expression) { if (isFirstVisit(expression)) { checkType(expression.type.name, expression) } super.visitCastExpression(expression) } //-------------------------------------------------------------------------- // Helper Methods //-------------------------------------------------------------------------- private initializeImportNames() { sourceCode.ast.imports.each { importNode -> importedClassNames << importNode.className } sourceCode.ast.starImports.each { importNode -> starImportPackageNames << ImportUtil.packageNameForImport(importNode) } } private void checkTypeIfNotDynamicallyTyped(node) { if (!node.isDynamicTyped()) { // ignore 'def' which resolves to java.lang.Object checkType(node.type.name, node) } } private void checkType(String typeName, node) { if (typeName in AUTO_IMPORTED_CLASSES || parentPackageName(typeName) in AUTO_IMPORTED_PACKAGES) { addViolation(node, "Specifying the package name is not necessary for $typeName") } if (typeName in importedClassNames || parentPackageName(typeName) in starImportPackageNames) { addViolation(node, "The $typeName class was explicitly imported, so specifying the package name is not necessary") } } private String parentPackageName(String typeName) { if (typeName.contains('.')) { def lastPeriod = typeName.lastIndexOf('.') return typeName[0..lastPeriod - 1] } null } private boolean isNotAutoBoxed(VariableExpression expression) { return expression.type.name == expression.originType.name } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDoubleInstantiationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDoubleInstantiationRule.groov0000644000175000017500000000244112006632020033454 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitorRule /** * It is unnecessary to instantiate Double objects. Instead just use the double literal or the 'D' identifier to force the type, such as 123.45d or 0.42d. * * @author Hamlet D'Arcy */ class UnnecessaryDoubleInstantiationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryDoubleInstantiation' int priority = 3 Class astVisitorClass = UnnecessaryDoubleInstantiationAstVisitor } class UnnecessaryDoubleInstantiationAstVisitor extends UnnecessaryInstantiationAstVisitor { UnnecessaryDoubleInstantiationAstVisitor() { super(Double, [String, Double], 'd') } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/ConsecutiveStringConcatenationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/ConsecutiveStringConcatenationRule.groov0000644000175000017500000000713112006632016033447 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.GStringExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Catches concatenation of two string literals on the same line. These can safely by joined. * * @author Hamlet D'Arcy */ class ConsecutiveStringConcatenationRule extends AbstractAstVisitorRule { String name = 'ConsecutiveStringConcatenation' int priority = 3 Class astVisitorClass = ConsecutiveStringConcatenationAstVisitor } class ConsecutiveStringConcatenationAstVisitor extends AbstractAstVisitor { private static final PRIMITIVE_TYPES = [Byte.TYPE, Double.TYPE, Float.TYPE, Integer.TYPE, Long.TYPE, Short.TYPE] @Override void visitBinaryExpression(BinaryExpression expression) { if (AstUtil.isBinaryExpressionType(expression, '+')) { Expression left = expression.leftExpression Expression right = expression.rightExpression if (areJoinableConstants(left, right)) { if (left instanceof GStringExpression || right instanceof GStringExpression) { addViolation(expression, "String concatenation in class $currentClassName can be joined into a single literal") } else { def lvalue = escape(left.value) def rvalue = escape(right.value) addViolation(expression, "String concatenation in class $currentClassName can be joined into the literal '${lvalue}${rvalue}'") } } } super.visitBinaryExpression(expression) } private static String escape(value) { if (value instanceof String) { return value.replaceAll('\n', '\\\\n').replaceAll("'", "\'") } value } private static boolean areJoinableConstants(Expression left, Expression right) { if (left.lastLineNumber != right.lineNumber) { return false } if (isJoinableType(left) && isJoinableType(right)) { // don't join two numbers if (!isNumberLiteral(left) || !isNumberLiteral(right)) { return true } } false } private static boolean isNumberLiteral(Expression node) { if (!(node instanceof ConstantExpression)) { return false } if (AstUtil.isNull(node)) { return false } if (!node.type.isResolved()) { return false } (Number.isAssignableFrom(node.type.typeClass) || node.type.typeClass in PRIMITIVE_TYPES) } private static boolean isJoinableType(Expression node) { if (node instanceof ConstantExpression && !AstUtil.isNull(node)) { return true } return node instanceof GStringExpression } } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInVariableDeclarationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInVariableDeclarationRule.0000644000175000017500000001017412006632016033230 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * If a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. * For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'. * * @author 'René Scheibe' */ class UnnecessaryDefInVariableDeclarationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryDefInVariableDeclaration' int priority = 3 Class astVisitorClass = UnnecessaryDefInVariableDeclarationAstVisitor } class UnnecessaryDefInVariableDeclarationAstVisitor extends AbstractAstVisitor { @Override void visitExpressionStatement(ExpressionStatement statement) { def node = statement.expression if (!(node instanceof DeclarationExpression)) { return } if (!(node.leftExpression instanceof VariableExpression)) { return } String declaration = AstUtil.getDeclaration(node, sourceCode) if (declaration.contains('=')) { declaration = declaration[0..(declaration.indexOf('='))] // ignore everything to the right of equals } if (contains(declaration, 'def')) { if (contains(declaration, 'private')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is marked private") } else if (contains(declaration, 'protected')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is marked protected") } else if (contains(declaration, 'public')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is marked public") } else if (contains(declaration, 'static')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is marked static") } else if (contains(declaration, 'final')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is marked final") } else if (contains(declaration, 'transient')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is marked transient") } else if (contains(declaration, 'volatile')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is marked volatile") } else if (contains(declaration, 'Object')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is of type Object") } else if (node.leftExpression.type != ClassHelper.DYNAMIC_TYPE) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a variable is declared with a type") } } super.visitExpressionStatement(statement) } static private boolean contains(String declaration, String modifier) { return declaration?.startsWith(modifier) || declaration?.contains(' ' + modifier + ' ') } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryStringInstantiationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryStringInstantiationRule.groov0000644000175000017500000000370712006632016033523 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractConstructorCallAstVisitor /** * Rule that checks for direct call to the String constructor that accepts a String literal. * In almost all cases, this is unnecessary - use a String literal instead. * * @author Chris Mair */ class UnnecessaryStringInstantiationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryStringInstantiation' int priority = 3 Class astVisitorClass = UnnecessaryStringInstantiationAstVisitor } class UnnecessaryStringInstantiationAstVisitor extends AbstractConstructorCallAstVisitor { static final NEW_STRING = /new +(java\.lang\.)?String\(/ @SuppressWarnings('ExplicitCallToGetAtMethod') protected isConstructorCallAViolation(ConstructorCallExpression constructorCall) { def firstArgExpression = constructorCall.arguments?.expressions?.getAt(0) constructorCall.text =~ NEW_STRING && (firstArgExpression instanceof ConstantExpression) } @Override protected String getViolationMessage(ConstructorCallExpression call) { 'There is typically no need to call the String constructor' } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryOverridingMethodRule.groovy0000644000175000017500000000446412006632014033151 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * The overriding method merely calls the same method defined in a superclass. * * @author Sven Lange * @author Hamlet D'Arcy */ class UnnecessaryOverridingMethodRule extends AbstractAstVisitorRule { String name = 'UnnecessaryOverridingMethod' int priority = 3 Class astVisitorClass = UnnecessaryOverridingMethodAstVisitor } class UnnecessaryOverridingMethodAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (isSingleLineMethod(node) && node.code.statements[0]?.expression instanceof MethodCallExpression) { MethodCallExpression methodCall = node.code.statements[0].expression if (AstUtil.isMethodCall(methodCall, 'super', node.name, node.parameters.length)) { if (AstUtil.getParameterNames(node) == AstUtil.getArgumentNames(methodCall)) { addViolation node, "The method $node.name contains no logic and can be safely deleted" } } } } private static boolean isSingleLineMethod(MethodNode node) { if (node?.code instanceof BlockStatement) { if (node.code.statements?.size() == 1) { if (node.code.statements[0] instanceof ExpressionStatement) { return true } } } false } } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryIntegerInstantiationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryIntegerInstantiationRule.groo0000644000175000017500000000260012006632016033453 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitorRule /** * It is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i. * * @author Hamlet D'Arcy */ class UnnecessaryIntegerInstantiationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryIntegerInstantiation' int priority = 3 Class astVisitorClass = UnnecessaryIntegerInstantiationAstVisitor } class UnnecessaryIntegerInstantiationAstVisitor extends UnnecessaryInstantiationAstVisitor { UnnecessaryIntegerInstantiationAstVisitor() { super(Integer, [String, Integer], 'i') } @Override protected boolean isTypeSuffixNecessary(argument) { return false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryElseStatementRule.groovy0000644000175000017500000000575712050576634032501 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.IfStatement import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codehaus.groovy.ast.stmt.Statement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * When an if statement block ends with a return statement the else is unnecessary * * @author Victor Savkin */ class UnnecessaryElseStatementRule extends AbstractAstVisitorRule { String name = 'UnnecessaryElseStatement' int priority = 3 Class astVisitorClass = UnnecessaryElseStatementAstVisitor } class UnnecessaryElseStatementAstVisitor extends AbstractAstVisitor { @Override void visitIfElse(IfStatement node) { if (isFirstVisit(node)) { def (allIfBlocks, theElseBlock) = collectIfsAndElses(node) if (isValidElseBlock(theElseBlock)) { if (allIfBlocks && allIfBlocks.every { allBranchesReturn(it.ifBlock) }) { addViolation theElseBlock, 'When an if statement block ends with a return statement the else is unnecessary' } } visited.addAll allIfBlocks visited.add theElseBlock } super.visitIfElse node } private static collectIfsAndElses(IfStatement ifStatement) { def ifs = [] def theElse = null def node = ifStatement while (theElse == null) { ifs.add node if (node.elseBlock instanceof IfStatement) { node = node.elseBlock } else { theElse = node.elseBlock } } [ifs, theElse] } private static isValidElseBlock(Statement elseBlock) { elseBlock != null && !elseBlock.empty && !(elseBlock instanceof IfStatement) } private static allBranchesReturn(Statement expr) { if(expr instanceof BlockStatement) { expr.statements.any { allBranchesReturn(it) } } else if (expr instanceof IfStatement) { allBranchesReturn(expr.ifBlock) && allBranchesReturn(expr.elseBlock) } else { isReturn expr } } private static isReturn(statement) { statement instanceof ReturnStatement } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstanceOfCheckRule.groovy0000644000175000017500000000412312006632020032654 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.NotExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * This rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean. * * @author Hamlet D'Arcy */ class UnnecessaryInstanceOfCheckRule extends AbstractAstVisitorRule { String name = 'UnnecessaryInstanceOfCheck' int priority = 3 Class astVisitorClass = UnnecessaryInstanceOfCheckAstVisitor } class UnnecessaryInstanceOfCheckAstVisitor extends AbstractAstVisitor { @Override void visitBinaryExpression(BinaryExpression expression) { if (isFirstVisit(expression)) { if (AstUtil.isBinaryExpressionType(expression, 'instanceof') && expression.leftExpression instanceof NotExpression) { if (expression.rightExpression.text == 'Boolean') { addViolation(expression, "The result of '!($expression.leftExpression.text)' will always be a Boolean") } else { addViolation(expression, "The result of '!($expression.leftExpression.text)' will never be a $expression.rightExpression.text") } } super.visitBinaryExpression(expression) } } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInMethodDeclarationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInMethodDeclarationRule.gr0000644000175000017500000001137412304647570033273 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * If a method has a visibility modifier or a type declaration, then the def keyword is unneeded. * For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'. * * @author Hamlet D'Arcy */ class UnnecessaryDefInMethodDeclarationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryDefInMethodDeclaration' int priority = 3 Class astVisitorClass = UnnecessaryDefInMethodDeclarationAstVisitor } class UnnecessaryDefInMethodDeclarationAstVisitor extends AbstractAstVisitor { private static final PATTERNS_OF_DISTRACTING_DECLARATION_PARTS = [ "'", // method name with single quotes, e.g.: def 'some method'() { ... } '"', // method name with double quotes, e.g.: def "some method"() { ... } '(', // method with parameters, e.g.: def method(def x) { ... } ] @Override protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { String declaration = removeDistractingParts(AstUtil.getDeclaration(node, sourceCode)) if (contains(declaration, 'def') && !declaration.contains('<')) { if (isConstructor) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded on constructors") } else if (contains(declaration, 'private')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method is marked private") } else if (contains(declaration, 'protected')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method is marked protected") } else if (contains(declaration, 'public')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method is marked public") } else if (contains(declaration, 'static')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method is marked static") } else if (contains(declaration, 'final')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method is marked final") } else if (contains(declaration, 'synchronized')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method is marked synchronized") } else if (contains(declaration, 'abstract')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method is marked abstract") } else if (contains(declaration, 'strictfp')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method is marked strictfp") } else if (contains(declaration, 'Object')) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method returns the Object type") } else if (node.returnType != ClassHelper.DYNAMIC_TYPE) { addViolation(node, "Violation in class $currentClassName. The def keyword is unneeded when a method specifies a return type") } } super.visitConstructorOrMethod(node, isConstructor) } private static removeDistractingParts(declaration) { def resultDeclaration = declaration for (pattern in PATTERNS_OF_DISTRACTING_DECLARATION_PARTS) { if (resultDeclaration.contains(pattern)) { resultDeclaration = resultDeclaration[0.. getViolationsForSource(SourceCode sourceCode) { def result = [] List lines = sourceCode.lines if (!lines) { return result } int lineNumber = 1 for (String line : lines) { if (line.trim().endsWith(';') && !line.matches(excludePattern)) { result.add( new Violation( rule: this, lineNumber: lineNumber, sourceLine: line, message: 'Semi-colons as line endings can be removed safely' ) ) } lineNumber++ } result } } class UnnecessarySemicolonAstVisitor extends AbstractAstVisitor { @Override void visitConstantExpression(ConstantExpression node) { // search inside multiline strings if (node.value instanceof String && node.lineNumber != node.lastLineNumber) { removeViolationsInRange(node.lineNumber, node.lastLineNumber - 1) } super.visitConstantExpression(node) } private removeViolationsInRange(start, end) { rule.temporaryViolations.get().removeAll { Violation v -> v.lineNumber >= start && v.lineNumber <= end } } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryBigIntegerInstantiationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryBigIntegerInstantiationRule.g0000644000175000017500000000245112006632012033355 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitorRule /** * It is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G. * * @author Hamlet D'Arcy */ class UnnecessaryBigIntegerInstantiationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryBigIntegerInstantiation' int priority = 3 Class astVisitorClass = UnnecessaryBigIntegerInstantiationAstVisitor } class UnnecessaryBigIntegerInstantiationAstVisitor extends UnnecessaryInstantiationAstVisitor { UnnecessaryBigIntegerInstantiationAstVisitor() { super(BigInteger, [String], 'G') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryCollectCallRule.groovy0000644000175000017500000001113212006632014032047 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * Some method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect { it.multiply(2) } can be replaced by list*.multiply(2). * * @author Hamlet D'Arcy */ class UnnecessaryCollectCallRule extends AbstractAstVisitorRule { String name = 'UnnecessaryCollectCall' int priority = 3 Class astVisitorClass = UnnecessaryCollectCallAstVisitor } class UnnecessaryCollectCallAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'collect', 1)) { def args = AstUtil.getMethodArguments(call) whenOneStatementClosureFound(args) { exp, parmName -> if (isPossibleViolation(exp, parmName)) { addViolationWithMessage(call, exp) } } } } private whenOneStatementClosureFound(List args, Closure callback) { // do we have one closure parameter? if (args[0] instanceof ClosureExpression && args[0].parameters?.length < 2) { ClosureExpression c = args[0] // do we have one statement in the closure? if (c.code instanceof BlockStatement && c.code.statements?.size() == 1) { def parmName = 'it' if (c.parameters?.length == 1) { parmName = c.parameters[0].name } if (c.code.statements[0] instanceof ExpressionStatement) { def exp = c.code.statements[0].expression callback(exp, parmName) } } } } private static boolean isPossibleViolation(Expression exp, String parmName) { if (!(exp instanceof MethodCallExpression) && !(exp instanceof PropertyExpression)) { return false } if (!(exp.objectExpression instanceof VariableExpression)) { return false } if (exp.objectExpression.name != parmName) { return false } def finder = new VariableUsageFinder(targetVariable: parmName) if (exp instanceof MethodCallExpression) { exp.method.visit finder exp.arguments.visit finder } else if (exp instanceof PropertyExpression) { exp.property.visit finder } !finder.found } @SuppressWarnings('CatchThrowable') private addViolationWithMessage(MethodCallExpression call, MethodCallExpression exp) { try { addViolation(call, "The call to collect could probably be rewritten as a spread expression: ${call.objectExpression.text}*.${exp.method.text}${exp.arguments.text}") } catch (Throwable t) { addViolation(call, 'The call to collect could probably be rewritten as a spread expression. ') } } @SuppressWarnings('CatchThrowable') private addViolationWithMessage(MethodCallExpression call, PropertyExpression exp) { try { addViolation(call, "The call to collect could probably be rewritten as a spread expression: ${call.objectExpression.text}*.${exp.property.text}") } catch (Throwable t) { addViolation(call, 'The call to collect could probably be rewritten as a spread expression. ') } } } class VariableUsageFinder extends AbstractAstVisitor { String targetVariable boolean found = false @Override void visitVariableExpression(VariableExpression expression) { if (expression.name == targetVariable) { found = true } else { super.visitVariableExpression expression } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryTransientModifierRule.groovy0000644000175000017500000000325112311373552033327 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * The field is marked as transient, but the class isn't Serializable, so marking it as transient should have no effect. * * @author Hamlet D'Arcy */ class UnnecessaryTransientModifierRule extends AbstractAstVisitorRule { String name = 'UnnecessaryTransientModifier' int priority = 3 Class astVisitorClass = UnnecessaryTransientModifierAstVisitor } class UnnecessaryTransientModifierAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (Modifier.isTransient(node.modifiers)) { if (!AstUtil.classNodeImplementsType(node.owner, Serializable)) { addViolation(node, "The field '$node.name' is marked transient, but $node.owner.name does not implement Serializable") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryToStringRule.groovy0000644000175000017500000000575212325340351031456 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Checks for unnecessary calls to toString(). * * Only check for calls to toString() for the value assigned to a String field or variable * if checkAssignments is true. * * @author Chris Mair */ class UnnecessaryToStringRule extends AbstractAstVisitorRule { String name = 'UnnecessaryToString' int priority = 2 Class astVisitorClass = UnnecessaryToStringAstVisitor // If true, then check for calls to toString() for the value assigned to a String field or variable. boolean checkAssignments = true } class UnnecessaryToStringAstVisitor extends AbstractAstVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (isFirstVisit(call) && AstUtil.isMethodCall(call, 'toString', 0) && isStringType(call.objectExpression)) { addViolation(call, "Calling toString() on the String expression in class $currentClassName is unnecessary") } super.visitMethodCallExpression(call) } @Override void visitField(FieldNode node) { if (isStringType(node) && AstUtil.isMethodCall(node.initialExpression, 'toString', 0) && rule.checkAssignments) { addViolation(node, "Calling toString() when assigning to String field \"${node.name}\" in class $currentClassName is unnecessary") } super.visitField(node) } @Override void visitDeclarationExpression(DeclarationExpression expression) { if (expression.leftExpression instanceof VariableExpression && isStringType(expression.leftExpression)) { if (AstUtil.isMethodCall(expression.rightExpression, 'toString', 0) && rule.checkAssignments) { def varName = expression.leftExpression.name addViolation(expression, "Calling toString() when assigning to String variable \"$varName\" in class $currentClassName is unnecessary") } } super.visitDeclarationExpression(expression) } private boolean isStringType(node) { node.type.name in ['String', 'java.lang.String'] } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstantiationAstVisitor.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstantiationAstVisitor.groov0000644000175000017500000000531012006632012033520 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.TupleExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.util.AstUtil /** * Base visitor for unnecessary constructor calls. * @author Hamlet D'Arcy */ class UnnecessaryInstantiationAstVisitor extends AbstractAstVisitor { Class targetType List parameterTypes String suffix UnnecessaryInstantiationAstVisitor(Class targetType, List parameterTypes, String suffix) { this.targetType = targetType this.parameterTypes = parameterTypes this.suffix = suffix } @SuppressWarnings('UnusedMethodParameter') protected boolean isTypeSuffixNecessary(argument) { return true } @Override final void visitConstructorCallExpression(ConstructorCallExpression call) { if (!isFirstVisit(call)) { return } if (AstUtil.classNodeImplementsType(call.type, targetType) && call.arguments instanceof TupleExpression && call.arguments.expressions.size() == 1) { Expression argument = call.arguments.expressions.head() parameterTypes.each { Class clazz -> if (argument instanceof ConstantExpression && argument.value.getClass() == clazz && !shouldSkipViolation(argument.value)) { boolean isSuffixNecessary = isTypeSuffixNecessary(argument.value) def replacementOptions = isSuffixNecessary ? "${argument.value}$suffix" : "${argument.value} or ${argument.value}$suffix" addViolation call, "Can be rewritten as $replacementOptions" } } } super.visitConstructorCallExpression call } @SuppressWarnings('UnusedMethodParameter') protected boolean shouldSkipViolation(Object value) { false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryDotClassRule.groovy0000644000175000017500000000407412322572174031424 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * To make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String. * * @author 'Dean Del Ponte' * @author Chris Mair */ class UnnecessaryDotClassRule extends AbstractAstVisitorRule { String name = 'UnnecessaryDotClass' int priority = 3 Class astVisitorClass = UnnecessaryDotClassAstVisitor } class UnnecessaryDotClassAstVisitor extends AbstractAstVisitor { @Override void visitPropertyExpression(PropertyExpression expression) { if (isFirstVisit(expression) && AstUtil.isConstant(expression.property, 'class')) { def object = expression.objectExpression boolean isClassPropertyExpression = object instanceof PropertyExpression && object.property instanceof ConstantExpression && Character.isUpperCase(object.property.value.toCharacter()) if (isClassPropertyExpression || AstUtil.isVariable(object, /[A-Z].*/)) { def exprText = object.text addViolation(expression, "${exprText}.class can be rewritten as $exprText") } } super.visitPropertyExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryPublicModifierRule.groovy0000644000175000017500000000572712006632014032600 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.apache.log4j.Logger import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * The 'public' modifier is not required on methods, constructors or classes. * * @author Hamlet D'Arcy */ class UnnecessaryPublicModifierRule extends AbstractAstVisitorRule { String name = 'UnnecessaryPublicModifier' int priority = 3 Class astVisitorClass = UnnecessaryPublicModifierAstVisitor } class UnnecessaryPublicModifierAstVisitor extends AbstractAstVisitor { private static final LOG = Logger.getLogger(UnnecessaryPublicModifierAstVisitor) @Override protected void visitClassEx(ClassNode node) { if (!node.isScript()) { checkDeclaration(node, 'classes') } super.visitClassEx(node) } @Override void visitMethodEx(MethodNode node) { checkDeclaration(node, 'methods') super.visitMethodEx(node) } @Override void visitConstructor(ConstructorNode node) { checkDeclaration(node, 'constructors') super.visitConstructor(node) } private void checkDeclaration(node, String nodeType) { String declaration = getDeclaration(node) if (getDeclaration(node)?.startsWith('public ')) { addViolation(node, "The public keyword is unnecessary for $nodeType") } else if (declaration?.contains(' public ')) { addViolation(node, "The public keyword is unnecessary for $nodeType") } } private String getDeclaration(ASTNode node) { if (node.lineNumber < 0) { return '' } def current = node.lineNumber - 1 String acc = '' while (current <= node.lastLineNumber) { def line = sourceCode.line(current) if (line == null) { LOG.warn("${rule.name} cannot find source code line $current in ${sourceCode.name}. Scanning lines ${node.lineNumber} to ${node.lastLineNumber}.") return '' } else if (line.contains('{')) { return acc + line[0..(line.indexOf('{'))] } acc = acc + line + ' ' current++ } acc } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryFloatInstantiationRule.groovy0000644000175000017500000000244112006632016033505 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitorRule /** * It is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f. * * @author Hamlet D'Arcy */ class UnnecessaryFloatInstantiationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryFloatInstantiation' int priority = 3 Class astVisitorClass = UnnecessaryFloatInstantiationAstVisitor } class UnnecessaryFloatInstantiationAstVisitor extends UnnecessaryInstantiationAstVisitor { UnnecessaryFloatInstantiationAstVisitor() { super(Float, [String, Double, Float], 'f') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessarySelfAssignmentRule.groovy0000644000175000017500000000602512006632014032615 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Method contains a pointless self-assignment to a variable or property. * * @author Hamlet D'Arcy */ class UnnecessarySelfAssignmentRule extends AbstractAstVisitorRule { String name = 'UnnecessarySelfAssignment' int priority = 3 Class astVisitorClass = UnnecessarySelfAssignmentAstVisitor } class UnnecessarySelfAssignmentAstVisitor extends AbstractAstVisitor { @Override void visitBinaryExpression(BinaryExpression expression) { if (AstUtil.isBinaryExpressionType(expression, '=')) { Expression left = expression.leftExpression Expression right = expression.rightExpression if (left instanceof VariableExpression && right instanceof VariableExpression) { if (left.name == right.name) { addViolation(expression, 'Assignment a variable to itself should be unnecessary. Remove this dead code') } } else if (propertyExpressionsAreEqual(left, right)) { if (left.text == right.text) { addViolation(expression, 'Assignment a variable to itself should be unnecessary. Remove this dead code') } } } super.visitBinaryExpression(expression) } private static boolean propertyExpressionsAreEqual(Expression left, Expression right) { def stack = [[left, right]] as Stack while (stack) { (left, right) = stack.pop() if (!(left instanceof PropertyExpression) || !(right instanceof PropertyExpression)) { return false } if (left.text != right.text) { return false } if (left.spreadSafe != right.spreadSafe || left.safe != right.safe) { return false } if (left.objectExpression instanceof PropertyExpression && right.objectExpression instanceof PropertyExpression) { // recursive alternative stack << [left.objectExpression, right.objectExpression] } } true } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryCastRule.groovy0000644000175000017500000000363212462042133030571 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.CastExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor /** * Checks for unnecessary cast operations * * @author Chris Mair */ class UnnecessaryCastRule extends AbstractAstVisitorRule { String name = 'UnnecessaryCast' int priority = 2 Class astVisitorClass = UnnecessaryCastAstVisitor } class UnnecessaryCastAstVisitor extends AbstractAstVisitor { // Map of Cast type -> Cast expression type (both as Strings) private static final CAST_TYPE_MAP = [ int:'java.lang.Integer', long:'java.lang.Long', BigDecimal:'java.math.BigDecimal', String:'java.lang.String', List:'java.util.List', Map:'java.util.Map', ] @Override void visitCastExpression(CastExpression expression) { if (isUnnecessaryCast(expression)) { addViolation(expression, "The cast ${expression.text} in class $currentClassName is unnecessary") } super.visitCastExpression(expression) } private boolean isUnnecessaryCast(CastExpression expression) { CAST_TYPE_MAP[expression.type.name] == expression.expression.type.name || expression.type.name == expression.expression.type.name } } ././@LongLink0000644000000000000000000000016600000000000011606 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryParenthesesForMethodCallWithClosureRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryParenthesesForMethodCallWithC0000644000175000017500000000433212006632012033340 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil import org.codenarc.util.SourceCodeUtil /** * If a method is called and the only parameter to that method is an inline closure then the brackets of the method call can be omitted. * * @author Marcin Erdmann */ class UnnecessaryParenthesesForMethodCallWithClosureRule extends AbstractAstVisitorRule { String name = 'UnnecessaryParenthesesForMethodCallWithClosure' int priority = 3 Class astVisitorClass = UnnecessaryParenthesesForMethodCallWithClosureAstVisitor } class UnnecessaryParenthesesForMethodCallWithClosureAstVisitor extends AbstractMethodCallExpressionVisitor { private final static EMPTY_BRACKETS_PATTERN = /\s*\(\s*\)\s*/ @Override void visitMethodCallExpression(MethodCallExpression call) { if (!AstUtil.isFromGeneratedSourceCode(call.method)) { def arguments = AstUtil.getMethodArguments(call) if (arguments.size() == 1 && arguments.first() instanceof ClosureExpression) { def sourceBetweenMethodAndClosure = SourceCodeUtil.sourceLinesBetweenNodes(sourceCode, call.method, arguments.first()).join() if (sourceBetweenMethodAndClosure ==~ EMPTY_BRACKETS_PATTERN) { addViolation(call, "Parentheses in the '$call.methodAsString' method call are unnecessary and can be removed.") } } } } } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryBooleanInstantiationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryBooleanInstantiationRule.groo0000644000175000017500000000473412311373552033455 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractConstructorCallAstVisitor import org.codenarc.util.AstUtil /** * Rule that checks for direct call to Boolean constructor - use Boolean.valueOf() instead. * Also checks for Boolean.valueOf(true) or Boolean.valueOf(false) - use Boolean.TRUE or * Boolean.FALSE instead. * * @author Chris Mair */ class UnnecessaryBooleanInstantiationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryBooleanInstantiation' int priority = 3 Class astVisitorClass = UnnecessaryBooleanInstantiationAstVisitor } class UnnecessaryBooleanInstantiationAstVisitor extends AbstractConstructorCallAstVisitor { static final NEW_BOOLEAN = /new +(java\.lang\.)?Boolean\(/ protected isConstructorCallAViolation(ConstructorCallExpression constructorCall) { constructorCall.text =~ NEW_BOOLEAN } void visitMethodCallExpression(MethodCallExpression methodCall) { if (isFirstVisit(methodCall)) { def args = AstUtil.getMethodArguments(methodCall) def isMatch = AstUtil.isMethodCall(methodCall, 'Boolean', 'valueOf', 1) && args[0] instanceof ConstantExpression && args[0].value in [true, false] if (isMatch) { addViolation(methodCall, "Call to $methodCall.text is unnecessary and can probably be replaced with simply ${args[0].value}") } } super.visitMethodCallExpression(methodCall) } @Override protected String getViolationMessage(ConstructorCallExpression call) { 'There is typically no need to instantiate Boolean instances.' } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryCollectionCallRule.groovy0000644000175000017500000000372512006632014032566 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.TupleExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor /** * Useless call to collections. This call doesn't make sense. For any collection c, calling c.containsAll(c) should * always be true, and c.retainAll(c) should have no effect. * * @author Hamlet D'Arcy */ class UnnecessaryCollectionCallRule extends AbstractAstVisitorRule { String name = 'UnnecessaryCollectionCall' int priority = 3 Class astVisitorClass = UnnecessaryCollectionCallAstVisitor } class UnnecessaryCollectionCallAstVisitor extends AbstractMethodCallExpressionVisitor { private static final List USELESS_METHOD_NAMES = ['retainAll', 'containsAll'] void visitMethodCallExpression(MethodCallExpression call) { if (USELESS_METHOD_NAMES.contains(call.method.text)) { String variableName = call.objectExpression.text if (call.arguments instanceof TupleExpression && call.arguments.expressions.size() == 1) { def argName = call.arguments.expressions[0].text if (argName == variableName) { addViolation call, "The call to $call.method.text has no effect" } } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryCallToSubstringRule.groovy0000644000175000017500000000325412006632012032751 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Calling String.substring(0) always returns the original string. This code is meaningless. * * @author Hamlet D'Arcy */ class UnnecessaryCallToSubstringRule extends AbstractAstVisitorRule { String name = 'UnnecessaryCallToSubstring' int priority = 3 Class astVisitorClass = UnnecessaryCallToSubstringAstVisitor } class UnnecessaryCallToSubstringAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'substring', 1)) { def arg = AstUtil.getMethodArguments(call)[0] if (AstUtil.isConstant(arg, 0)) { addViolation(call, 'Invoking the String method substring(0) always returns the original value. Method possibly missing 2nd parameter') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryObjectReferencesRule.groovy0000644000175000017500000000637112006632014033107 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codehaus.groovy.ast.stmt.Statement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Violations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block. * * @author Hamlet D'Arcy */ class UnnecessaryObjectReferencesRule extends AbstractAstVisitorRule { String name = 'UnnecessaryObjectReferences' int priority = 3 int maxReferencesAllowed = 5 Class astVisitorClass = UnnecessaryObjectReferencesAstVisitor } class UnnecessaryObjectReferencesAstVisitor extends AbstractAstVisitor { private final runCollector = [variable: null, count: 0, clear: { this.variable = null; this.count = 0 }] @Override void visitBlockStatement(BlockStatement block) { // search for runs of methods or runs of properties block.statements.each { Statement statement -> if (!(statement instanceof ExpressionStatement)) { runCollector.clear() return } def exp = statement.expression if (exp instanceof MethodCallExpression && exp.objectExpression instanceof VariableExpression) { accumulateOrError(exp.objectExpression.variable, statement) } else if (exp instanceof BinaryExpression && exp.leftExpression instanceof PropertyExpression && exp.leftExpression.objectExpression instanceof VariableExpression ) { accumulateOrError(exp.leftExpression.objectExpression.variable, statement) } else { runCollector.clear() } } runCollector.clear() super.visitBlockStatement block } private void accumulateOrError(String variable, ExpressionStatement statement) { if (variable == runCollector.variable) { if (runCollector.count == rule.maxReferencesAllowed) { addViolation statement.expression, 'The code could be more concise by using a with() or identity() block' } else { runCollector.count = runCollector.count + 1 } } else if (variable != 'this') { runCollector.variable = variable runCollector.count = 1 } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryIfStatementRule.groovy0000644000175000017500000001751512311373553032135 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.stmt.* /** * Rule that checks for unnecessary if statements. If/else statements are considered unnecessary for * the four scenarios described below. *

* (1) When the if and else blocks contain only an explicit return of true and false * constants. These cases can be replaced by a simple return statement. Examples include: *

    *
  • if (someExpression) return true else return false - can be replaced by return someExpression
  • *
  • if (someExpression) { return true } else { return false } - can be replaced by return someExpression
  • *
  • if (someExpression) { return Boolean.TRUE } else { return Boolean.FALSE } - can be replaced by return someExpression
  • *
* * (2) When the if statement is the last statement in a block and the if and else blocks contain only * true and false expressions. This is an implicit return of true/false. * For example, the if statement in the following code can be replaced by someExpression: * * boolean myMethod() { * doSomething() * if (someExpression) true; else false * } * * * (3) When the second-to-last statement in a block is an if statement with no else, where the block contains a single * return statement, and the last statement in the block is a return statement, and one return statement returns a * true expression and the other returns a false expression. * For example, the if statement in the following code can be replaced by return expression1: * * if (expression1) { * return true * } * return false * * * NOTE: This check is disabled by setting checkLastStatementImplicitElse to false. * * (4) When either the if block or else block of an if statement that is not the last statement in a * block contain only a single constant or literal expression * For example, the if statement in the following code has no effect and can be removed: * * def myMethod() { * if (someExpression) { 123 } * doSomething() * } * * * @author Chris Mair */ class UnnecessaryIfStatementRule extends AbstractAstVisitorRule { String name = 'UnnecessaryIfStatement' int priority = 3 Class astVisitorClass = UnnecessaryIfStatementAstVisitor boolean checkLastStatementImplicitElse = true } class UnnecessaryIfStatementAstVisitor extends AbstractAstVisitor { @Override void visitIfElse(IfStatement ifStatement) { if (isFirstVisit(ifStatement) && hasElseBlock(ifStatement)) { if (areReturningTrueAndFalse(ifStatement.ifBlock, ifStatement.elseBlock)) { addViolation(ifStatement, 'The if and else blocks merely return true/false') } } super.visitIfElse(ifStatement) } @Override void visitBlockStatement(BlockStatement block) { def allStatements = block.statements def allExceptLastStatement = allExceptLastElement(allStatements) allExceptLastStatement.each { statement -> if (statement instanceof IfStatement) { visitIfElseThatIsNotTheLastStatementInABlock(statement) } } if (allStatements && allStatements.last() instanceof IfStatement) { visitIfElseThatIsTheLastStatementInABlock(allStatements.last()) } if (allStatements.size() > 1 && rule.checkLastStatementImplicitElse) { def nextToLastStatement = allStatements[-2] if (nextToLastStatement instanceof IfStatement && hasNoElseBlock(nextToLastStatement)) { def lastStatement = allStatements[-1] if (areReturningTrueAndFalse(nextToLastStatement.ifBlock, lastStatement)) { addViolation(nextToLastStatement, 'The if block and the subsequent fall-through statement merely return true/false') } } } super.visitBlockStatement(block) } private void visitIfElseThatIsNotTheLastStatementInABlock(IfStatement ifStatement) { if (isOnlyAConstantOrLiteralExpression(ifStatement.ifBlock)) { addViolation(ifStatement, 'The if block is a constant or literal') } if (isOnlyAConstantOrLiteralExpression(ifStatement.elseBlock)) { addViolation(ifStatement.elseBlock, 'The else block is a constant or literal') } } private void visitIfElseThatIsTheLastStatementInABlock(IfStatement ifStatement) { if (isFirstVisit([CHECK_FOR_CONSTANT:ifStatement]) && hasElseBlock(ifStatement)) { if (areTrueAndFalseExpressions(ifStatement.ifBlock, ifStatement.elseBlock)) { addViolation(ifStatement, 'The if and else blocks implicitly return true/false') } } } private boolean areReturningTrueAndFalse(Statement ifBlock, Statement elseBlock) { (isReturnTrue(ifBlock) && isReturnFalse(elseBlock)) || (isReturnFalse(ifBlock) && isReturnTrue(elseBlock)) } private boolean isReturnTrue(Statement blockStatement) { def statement = getStatement(blockStatement) statement instanceof ReturnStatement && AstUtil.isTrue(statement.expression) } private boolean isReturnFalse(Statement blockStatement) { def statement = getStatement(blockStatement) statement instanceof ReturnStatement && AstUtil.isFalse(statement.expression) } private boolean areTrueAndFalseExpressions(Statement ifBlock, Statement elseBlock) { (isTrueExpression(ifBlock) && isFalseExpression(elseBlock)) || (isFalseExpression(ifBlock) && isTrueExpression(elseBlock)) } private boolean isTrueExpression(Statement blockStatement) { def statement = getStatement(blockStatement) statement instanceof ExpressionStatement && AstUtil.isTrue(statement.expression) } private boolean isFalseExpression(Statement blockStatement) { def statement = getStatement(blockStatement) statement instanceof ExpressionStatement && AstUtil.isFalse(statement.expression) } private boolean hasElseBlock(IfStatement ifStatement) { !ifStatement.elseBlock.empty } private boolean hasNoElseBlock(IfStatement ifStatement) { ifStatement.elseBlock.empty } private boolean isOnlyAConstantOrLiteralExpression(Statement blockStatement) { def statement = getStatement(blockStatement) statement instanceof ExpressionStatement && AstUtil.isConstantOrLiteral(statement.expression) } private Statement getStatement(Statement statement) { isSingleStatementBlock(statement) ? statement.statements.get(0) : statement } private boolean isSingleStatementBlock(Statement statement) { statement instanceof BlockStatement && statement.statements.size() == 1 } private allExceptLastElement(list) { def lastElement = list.empty ? null : list.last() list - lastElement } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/ConsecutiveLiteralAppendsRule.groovy0000644000175000017500000000511212311370173032572 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.GStringExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil import org.codenarc.util.ConsecutiveUtils /** * Violations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation. * * @author 'Hamlet D'Arcy' */ class ConsecutiveLiteralAppendsRule extends AbstractAstVisitorRule { String name = 'ConsecutiveLiteralAppends' int priority = 2 Class astVisitorClass = ConsecutiveLiteralAppendsAstVisitor } class ConsecutiveLiteralAppendsAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (isChainedAppend(call)) { def arg1 = AstUtil.getMethodArguments(call.objectExpression)[0] def arg2 = AstUtil.getMethodArguments(call)[0] if (ConsecutiveUtils.areJoinableConstants(arg1, arg2) && !AstUtil.isNull(arg1) && !AstUtil.isNull(arg2)) { if (arg1 instanceof GStringExpression || arg2 instanceof GStringExpression) { addViolation(call, 'Consecutive calls to append method with literal parameters can be joined into one append() call') } else { addViolation(call, "Consecutive calls to append method with literal parameters can be joined into append('${arg1.value}${arg2.value}')") } } } } static private boolean isChainedAppend(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'append', 1)) { if (call.objectExpression instanceof MethodCallExpression && AstUtil.isMethodNamed(call.objectExpression, 'append', 1)) { return true } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryBooleanExpressionRule.groovy0000644000175000017500000000632712311373552033347 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.NotExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks unnecessary boolean expressions, including ANDing (&&) or ORing (||) with * true, false, null, or a Map/List/String/Number literal. * * This rule also checks for negation (!) of true, false, * null, or a Map/List/String/Number literal. * Examples include: *
    *
  • def result = value && true
  • *
  • if (false || value) { .. }
  • *
  • return value && Boolean.FALSE
  • *
  • result = value && "abc"
  • *
  • result = null && value
  • *
  • result = value && 123
  • *
  • result = 678.123 || true
  • *
  • result = value && [x, y]
  • *
  • def result = [a:123] && value
  • * *
  • result = !true
  • *
  • result = !false
  • *
  • result = !Boolean.TRUE
  • *
  • result = !null
  • *
  • result = !"abc"
  • *
  • result = ![a:123]
  • *
  • result = ![a,b]
  • *
* * @author Chris Mair */ class UnnecessaryBooleanExpressionRule extends AbstractAstVisitorRule { String name = 'UnnecessaryBooleanExpression' int priority = 3 Class astVisitorClass = UnnecessaryBooleanExpressionAstVisitor } class UnnecessaryBooleanExpressionAstVisitor extends AbstractAstVisitor { private static final BOOLEAN_LOGIC_OPERATIONS = ['&&', '||'] void visitBinaryExpression(BinaryExpression expression) { def operationName = expression.operation.text if (operationName in BOOLEAN_LOGIC_OPERATIONS && (AstUtil.isConstantOrLiteral(expression.rightExpression) || AstUtil.isConstantOrLiteral(expression.leftExpression))) { addViolation(expression, "The expression using $operationName is compared to a constant") } super.visitBinaryExpression(expression) } void visitNotExpression(NotExpression expression) { if (AstUtil.isConstantOrLiteral(expression.expression)) { addViolation(expression, 'The Not expression contains a literal or contant. ') } super.visitNotExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryConstructorRule.groovy0000644000175000017500000000512412041061502032214 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * UnnecessaryConstructor * * @author Tomasz Bujok * @author Hamlet D'Arcy * @author Chris Mair */ class UnnecessaryConstructorRule extends AbstractAstVisitorRule { String name = 'UnnecessaryConstructor' int priority = 3 Class astVisitorClass = UnnecessaryConstructorAstVisitor } class UnnecessaryConstructorAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode node) { if (node.declaredConstructors?.size() == 1) { analyzeConstructor node.declaredConstructors[0] } super.visitClassEx(node) } private void analyzeConstructor(ConstructorNode node) { if(isEmptyOrJustCallsSuper(node) && !Modifier.isPrivate(node.modifiers) && node.parameters?.size() == 0) { addViolation node, 'The constructor can be safely deleted' } } private boolean isEmptyOrJustCallsSuper(ConstructorNode node) { isEmptyConstructor(node) || containsOnlyCallToSuper(node) } private boolean isEmptyConstructor(ConstructorNode node) { node.code?.isEmpty() } private boolean containsOnlyCallToSuper(ConstructorNode node) { if (!AstUtil.isOneLiner(node.code)) { return false } def onlyStatement = node.code.statements[0] return onlyStatement instanceof ExpressionStatement && onlyStatement.expression instanceof ConstructorCallExpression && onlyStatement.expression.superCall && onlyStatement.expression.arguments.expressions.empty } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryCallForLastElementRule.groovy0000644000175000017500000000760512311370173033364 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * This rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, * it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is * simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a * get, getAt, or array-style access is used with an object size check. * * @author Hamlet D'Arcy */ class UnnecessaryCallForLastElementRule extends AbstractAstVisitorRule { String name = 'UnnecessaryCallForLastElement' int priority = 3 Class astVisitorClass = UnnecessaryCallForLastElementAstVisitor } class UnnecessaryCallForLastElementAstVisitor extends AbstractAstVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'get', 1) || AstUtil.isMethodNamed(call, 'getAt', 1)) { def methodObjectText = call.objectExpression.text if (call.arguments instanceof ArgumentListExpression) { Expression exp = call.arguments?.expressions?.first() if (isSubtractOneOnObject(methodObjectText, exp)) { addViolation call, "Unnecessarily complex access of last element. This can be simplified to ${methodObjectText}.last() or ${methodObjectText}[-1]" } } } super.visitMethodCallExpression call } @Override void visitBinaryExpression(BinaryExpression expression) { if (expression.operation.getText() == '[') { def methodObjectText = expression.leftExpression.text if (isSubtractOneOnObject(methodObjectText, expression.rightExpression)) { addViolation expression, "Unnecessarily complex access of last element. This can be simplified to ${methodObjectText}.last() or ${methodObjectText}[-1]" } } super.visitBinaryExpression expression } private static isSubtractOneOnObject(String methodObjectText, Expression exp) { if (!(exp instanceof BinaryExpression)) { return false } if (exp.operation.text != '-') { return false } if (!(exp.rightExpression instanceof ConstantExpression)) { return false } if (exp.rightExpression.value != 1) { return false } if (exp.leftExpression instanceof MethodCallExpression) { if (AstUtil.isMethodCall(exp.leftExpression, methodObjectText, 'size', 0)) { return true } } if (exp.leftExpression instanceof PropertyExpression) { PropertyExpression property = exp.leftExpression if (property.objectExpression.text != methodObjectText) { return false } if (!(property.property instanceof ConstantExpression)) { return false } if (property.property.value == 'length') { return true } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryNullCheckRule.groovy0000644000175000017500000001361312006632016031546 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * Groovy contains the safe dereference operator, which can be used in boolean conditional statements to safely * replace explicit "x == null" tests. * * @author Hamlet D'Arcy */ class UnnecessaryNullCheckRule extends AbstractAstVisitorRule { String name = 'UnnecessaryNullCheck' int priority = 3 Class astVisitorClass = UnnecessaryNullCheckAstVisitor } class UnnecessaryNullCheckAstVisitor extends AbstractAstVisitor { @SuppressWarnings('NestedBlockDepth') @Override void visitBooleanExpression(BooleanExpression expression) { if (isFirstVisit(expression)) { def exp = expression.expression if (exp instanceof BinaryExpression && exp.operation.text == '&&') { if (AstUtil.isNotNullCheck(exp.leftExpression)) { // perform should use null-safe dereference test def nullTarget = AstUtil.getNullComparisonTarget(exp.leftExpression) if (isPropertyInvocation(exp.rightExpression, nullTarget)) { def suggestion = "$nullTarget?.$exp.rightExpression.property.text" addViolation(expression, "The expression $expression.text can be simplified to ($suggestion)") } else if (isMethodInvocation(exp.rightExpression, nullTarget)) { def suggestion = "$nullTarget?.${exp.rightExpression.method.text}${exp.rightExpression.arguments.text}" addViolation(expression, "The expression $expression.text can be simplified to ($suggestion)") } } else if (AstUtil.isNotNullCheck(exp.rightExpression)) { def nullTarget = AstUtil.getNullComparisonTarget(exp.rightExpression) // perform pointless null check test if (isPropertyInvocation(exp.leftExpression, nullTarget) || isMethodInvocation(exp.leftExpression, nullTarget)) { def suggestion = exp.leftExpression.text addViolation(expression, "The expression $expression.text can be simplified to ($suggestion)") } } } else if (isNotNullCheckAgainstThisReference(exp)) { addViolation(expression, 'Testing the this reference for not null will always return true') } else if (isNullCheckAgainstThisReference(exp)) { addViolation(expression, 'Testing the this reference for null will always return false') } else if (isNotNullCheckAgainstSuperReference(exp)) { addViolation(expression, 'Testing the super reference for not null will always return true') } else if (isNullCheckAgainstSuperReference(exp)) { addViolation(expression, 'Testing the super reference for null will always return false') } super.visitBooleanExpression(expression) } } private static boolean isSuperReference(Expression expression) { expression instanceof VariableExpression && expression.variable == 'super' } private static boolean isNotNullCheckAgainstThisReference(Expression exp) { if (exp instanceof BinaryExpression && AstUtil.isNotNullCheck(exp)) { if (AstUtil.isThisReference(exp.leftExpression) || AstUtil.isThisReference(exp.rightExpression)) { return true } } false } private static boolean isNotNullCheckAgainstSuperReference(Expression exp) { if (exp instanceof BinaryExpression && AstUtil.isNotNullCheck(exp)) { if (isSuperReference(exp.leftExpression) || isSuperReference(exp.rightExpression)) { return true } } false } private static boolean isNullCheckAgainstThisReference(Expression exp) { if (exp instanceof BinaryExpression && AstUtil.isNullCheck(exp)) { if (AstUtil.isThisReference(exp.leftExpression) || AstUtil.isThisReference(exp.rightExpression)) { return true } } false } private static boolean isNullCheckAgainstSuperReference(Expression exp) { if (exp instanceof BinaryExpression && AstUtil.isNullCheck(exp)) { if (isSuperReference(exp.leftExpression) || isSuperReference(exp.rightExpression)) { return true } } false } private static boolean isPropertyInvocation(expression, String targetName) { if (expression instanceof PropertyExpression) { if (expression.objectExpression instanceof VariableExpression) { if (expression.objectExpression.variable == targetName) { return true } } } false } private static boolean isMethodInvocation(expression, String targetName) { if (expression instanceof MethodCallExpression) { if (expression.objectExpression instanceof VariableExpression) { if (expression.objectExpression.variable == targetName) { return true } } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryCatchBlockRule.groovy0000644000175000017500000000463012311370173031674 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.CatchStatement import org.codehaus.groovy.ast.stmt.ThrowStatement import org.codehaus.groovy.ast.stmt.TryCatchStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Violations are triggered when a catch block does nothing but throw the original exception. In this scenario there is * usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently * occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out. * * @author Hamlet D'Arcy */ class UnnecessaryCatchBlockRule extends AbstractAstVisitorRule { String name = 'UnnecessaryCatchBlock' int priority = 3 Class astVisitorClass = UnnecessaryCatchBlockAstVisitor } class UnnecessaryCatchBlockAstVisitor extends AbstractAstVisitor { @Override void visitTryCatchFinally(TryCatchStatement statement) { def badNodes = statement.catchStatements?.findAll { CatchStatement it -> def paramName = it.variable.name if (it.code instanceof BlockStatement && it.code.statements.size() == 1) { def throwStatement = it.code.statements[0] if (throwStatement instanceof ThrowStatement && AstUtil.isVariable(throwStatement.expression, paramName)) { return true } } false } if (badNodes.size() == statement.catchStatements?.size()) { badNodes.each { addViolation it, 'Catch statement can probably be removed.' } } super.visitTryCatchFinally statement } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryLongInstantiationRule.groovy0000644000175000017500000000240412006632014033334 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractAstVisitorRule /** * It is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L. * * @author Hamlet D'Arcy */ class UnnecessaryLongInstantiationRule extends AbstractAstVisitorRule { String name = 'UnnecessaryLongInstantiation' int priority = 3 Class astVisitorClass = UnnecessaryLongInstantiationAstVisitor } class UnnecessaryLongInstantiationAstVisitor extends UnnecessaryInstantiationAstVisitor { UnnecessaryLongInstantiationAstVisitor() { super(Long, [String, Long], 'L') } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstantiationToGetClassRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstantiationToGetClassRule.g0000644000175000017500000000343012006632014033346 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unnecessary import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Avoid instantiating an object just to call getClass() on it; use the .class public member instead. * * @author Hamlet D'Arcy */ class UnnecessaryInstantiationToGetClassRule extends AbstractAstVisitorRule { String name = 'UnnecessaryInstantiationToGetClass' int priority = 3 Class astVisitorClass = UnnecessaryInstantiationToGetClassAstVisitor } class UnnecessaryInstantiationToGetClassAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'getClass', 0)) { if (call.objectExpression instanceof ConstructorCallExpression) { def typeName = call.objectExpression.type.name addViolation(call, "$typeName instantiation with getClass() should be simplified to ${typeName}.class") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/0000755000175000017500000000000012623571301023172 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/BracesForForLoopRule.groovy0000644000175000017500000000363612052041522030441 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.stmt.ForStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Checks the location of the opening brace ({) for for loops. By default, requires them on the same line, * but the sameLine property can be set to false to override this. * * @author Hamlet D'Arcy */ class BracesForForLoopRule extends AbstractAstVisitorRule { String name = 'BracesForForLoop' int priority = 2 boolean sameLine = true Class astVisitorClass = BracesForForLoopAstVisitor } class BracesForForLoopAstVisitor extends AbstractAstVisitor { @Override void visitForLoop(ForStatement node) { if (AstUtil.isBlock(node.loopBlock)) { if (rule.sameLine) { if(!lastSourceLineTrimmed(node.collectionExpression)?.contains('{')) { addViolation(node, 'Braces should start on the same line') } } else { if(lastSourceLineTrimmed(node.collectionExpression)?.contains('{')) { addViolation(node, 'Braces should start on a new line') } } } super.visitForLoop(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/LineLengthRule.groovy0000644000175000017500000000531312311373552027326 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.source.SourceCode /** * Checks the maximum length for each line of source code. It checks for number of characters, so lines that include * tabs may appear longer than the allowed number when viewing the file. The maximum line length can be configured by * setting the length property, which defaults to 120. * * @author Hamlet D'Arcy * @author Geli Crick */ class LineLengthRule extends AbstractAstVisitorRule { String name = 'LineLength' int priority = 2 int length = 120 // The default max line length. Can be overridden boolean ignoreImportStatements = true // import statements can be longer than the max line legnth boolean ignorePackageStatements = true // import statements can be longer than the max line legnth @Override void applyTo(SourceCode sourceCode, List violations) { int lineNumber = 0 for (line in sourceCode.getLines()) { lineNumber++ if (sourceViolatesLineLengthRule(line)) { violations << createViolation(lineNumber, line, "The line exceeds $length characters. The line is ${line.length()} characters.") } } } private Boolean sourceViolatesLineLengthRule(String line) { lineExceedsMaxLength(line) && (flagIfImport(line) || flagIfPackage(line) || flagIfRegularLine(line)) } private Boolean flagIfImport(String line) { (sourceLineIsImport(line) && !ignoreImportStatements) } private Boolean flagIfPackage(String line) { (sourceLineIsPackage(line) && !ignorePackageStatements) } private Boolean flagIfRegularLine(String line) { !sourceLineIsImport(line) && !sourceLineIsPackage(line) } private Boolean sourceLineIsImport(String line) { line.trim().startsWith('import ') } private Boolean sourceLineIsPackage(String line) { line.trim().startsWith('package ') } private Boolean lineExceedsMaxLength(String line) { line.length() > length } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/ClassJavadocRule.groovy0000644000175000017500000000517212311373552027635 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Makes sure each class and interface definition is preceded by javadoc. Enum definitions are not checked, * due to strange behavior in the Groovy AST. * * @author Hamlet D'Arcy * @author Geli Crick */ class ClassJavadocRule extends AbstractRule { String name = 'ClassJavadoc' int priority = 2 boolean applyToNonMainClasses = false /** * Apply the rule to the given source, writing violations to the given list. * @param sourceCode The source to check * @param violations A list of Violations that may be added to. It can be an empty list */ @Override @SuppressWarnings('EmptyWhileStatement') void applyTo(SourceCode sourceCode, List violations) { def lines = sourceCode.getLines() sourceCode.ast?.classes?.each { classNode -> if (!applyToNonMainClasses && sourceCodeNameWithoutExtension(sourceCode) != classNode.nameWithoutPackage) { return // only apply to classes that have same name as the source unit. } if (classNode.isPrimaryClassNode() && classNode.superClass.name != 'java.lang.Enum') { def index = classNode.lineNumber - 1 while (lines[--index].trim().startsWith('*') || lines[index].trim().isEmpty()) { /* Do nothing, to simulate an until loop */ } if (!lines[index].trim().startsWith('/**')) { violations.add(createViolation(sourceCode, classNode, "Class $classNode.name missing JavaDoc")) } } } } protected String sourceCodeNameWithoutExtension(SourceCode sourceCode) { def indexOfPeriod = sourceCode.name?.lastIndexOf('.') if (indexOfPeriod && indexOfPeriod != -1) { return sourceCode.name[0..indexOfPeriod - 1] } return sourceCode.getName() } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceBeforeClosingBraceRule.groovy0000644000175000017500000001230212414277432031727 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.stmt.BlockStatement import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.MapEntryExpression import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.MethodNode /** * Check that there is at least one space (blank) or whitespace before each closing brace ("}"). * This checks method/class/interface declarations, closure expressions and block statements. * * @author Chris Mair */ class SpaceBeforeClosingBraceRule extends AbstractAstVisitorRule { String name = 'SpaceBeforeClosingBrace' int priority = 3 Class astVisitorClass = SpaceBeforeClosingBraceAstVisitor boolean checkClosureMapEntryValue = true boolean ignoreEmptyBlock = false } class SpaceBeforeClosingBraceAstVisitor extends AbstractSpaceAroundBraceAstVisitor { @Override protected void visitClassEx(ClassNode node) { def line = lastSourceLineOrEmpty(node) def indexOfBrace = line.indexOf('}') if (indexOfBrace > 1) { if (isNotWhitespace(line, indexOfBrace) && checkIsEmptyBlock(line, indexOfBrace)) { def typeName = node.isInterface() ? 'interface' : (node.isEnum() ? 'enum' : 'class') addViolation(node, "The closing brace for $typeName $currentClassName is not preceded by a space or whitespace") } } super.visitClassEx(node) } @Override protected void visitMethodEx(MethodNode node) { processMethodNode(node) super.visitMethodEx(node) } @Override void visitConstructor(ConstructorNode node) { processMethodNode(node) super.visitConstructor(node) } private void processMethodNode(MethodNode node) { if (isFirstVisit(node.code) && node.code && !AstUtil.isFromGeneratedSourceCode(node)) { def line = lastSourceLineOrEmpty(node.code) def lastCol = node.code.lastColumnNumber if (line.size() >= lastCol && isNotWhitespace(line, lastCol - 1) && line[lastCol - 1] == '}' && checkIsEmptyBlock(line, lastCol - 1)) { addOpeningBraceViolation(node.code, 'block') } } } @Override void visitBlockStatement(BlockStatement block) { if (isFirstVisit(block) && !AstUtil.isFromGeneratedSourceCode(block)) { def startLine = sourceLineOrEmpty(block) def line = lastSourceLineOrEmpty(block) def lastCol = block.lastColumnNumber def startCol = block.columnNumber if (startLine[startCol - 1] == '{') { int lastIndex = indexOfClosingBrace(line, lastCol) if (isNotWhitespace(line, lastIndex) && checkIsEmptyBlock(line, lastIndex)) { addOpeningBraceViolation(block, 'block') } } } super.visitBlockStatement(block) } @Override void visitClosureExpression(ClosureExpression expression) { isFirstVisit(expression.code) // Register the code block so that it will be ignored in visitBlockStatement() if (isFirstVisit(expression)) { def line = lastSourceLineOrEmpty(expression) def lastCol = expression.lastColumnNumber int lastIndex = indexOfClosingBrace(line, lastCol) if (isNotWhitespace(line, lastIndex) && checkIsEmptyBlock(line, lastIndex)) { addOpeningBraceViolation(expression, 'closure') } } super.visitClosureExpression(expression) } @Override void visitMapEntryExpression(MapEntryExpression expression) { if (!rule.checkClosureMapEntryValue && expression.valueExpression instanceof ClosureExpression) { isFirstVisit(expression.valueExpression) // Register the closure so that it will be ignored in visitClosureExpression() } super.visitMapEntryExpression(expression) } private void addOpeningBraceViolation(ASTNode node, String keyword) { addViolation(node, "The closing brace for the $keyword in class $currentClassName is not preceded by a space or whitespace") } private boolean checkIsEmptyBlock(String line, int indexOfBrace) { if (rule.ignoreEmptyBlock ) { return isNotCharacter(line, '{' as char, indexOfBrace) } return true } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAroundClosureArrowRule.groovy0000644000175000017500000000330512170246030032041 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.expr.ClosureExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor /** * Checks that there is whitespace around the closure arrow (->) symbol * * @author Chris Mair */ class SpaceAroundClosureArrowRule extends AbstractAstVisitorRule { String name = 'SpaceAroundClosureArrow' int priority = 3 Class astVisitorClass = SpaceAroundClosureArrowAstVisitor } class SpaceAroundClosureArrowAstVisitor extends AbstractAstVisitor { @Override void visitClosureExpression(ClosureExpression expression) { def line = sourceLine(expression) + ' ' // add trailing space in case -> is at end of line if (line.contains('->') && !(line =~ /\s\-\>\s/)) { addViolation(expression, "The closure arrow (->) within class $currentClassName is not surrounded by a space or whitespace") //"The operator \"?\" within class $currentClassName is not followed by a space or whitespace") } super.visitClosureExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterOpeningBraceRule.groovy0000644000175000017500000001173012414277432031573 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.MapEntryExpression import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.MethodNode /** * Check that there is at least one space (blank) or whitespace after each opening brace ("{"). * This checks method/class/interface declarations, closure expressions and block statements. * * @author Chris Mair */ class SpaceAfterOpeningBraceRule extends AbstractAstVisitorRule { String name = 'SpaceAfterOpeningBrace' int priority = 3 Class astVisitorClass = SpaceAfterOpeningBraceAstVisitor boolean checkClosureMapEntryValue = true boolean ignoreEmptyBlock = false } class SpaceAfterOpeningBraceAstVisitor extends AbstractSpaceAroundBraceAstVisitor { @Override protected void visitClassEx(ClassNode node) { def line = sourceLineOrEmpty(node) def indexOfBrace = line.indexOf('{') if (indexOfBrace != -1 && isNotWhitespace(line, indexOfBrace + 2) && checkIsEmptyBlock(line, indexOfBrace + 2)) { def typeName = node.isInterface() ? 'interface' : (node.isEnum() ? 'enum' : 'class') addViolation(node, "The opening brace for $typeName $currentClassName is not followed by a space or whitespace") } super.visitClassEx(node) } @Override void visitConstructor(ConstructorNode node) { // The AST for constructors is "special". The BlockStatement begins on the line following the // opening brace if it is a multi-line method. Bug? isFirstVisit(node.code) // Register the code block so that it will be ignored in visitBlockStatement() def line = sourceLineOrEmpty(node) if (line =~ /\{\S/) { addOpeningBraceViolation(node, 'block') } super.visitConstructor(node) } @Override void visitBlockStatement(BlockStatement block) { if (isFirstVisit(block) && !AstUtil.isFromGeneratedSourceCode(block)) { def line = sourceLineOrEmpty(block) def startCol = block.columnNumber if (line[startCol - 1] == '{' && isNotWhitespace(line, startCol + 1) && checkIsEmptyBlock(line, startCol + 1)) { addOpeningBraceViolation(block, 'block') } } super.visitBlockStatement(block) } @Override void visitClosureExpression(ClosureExpression expression) { isFirstVisit(expression.code) // Register the code block so that it will be ignored in visitBlockStatement() if (isFirstVisit(expression)) { def line = sourceLineOrEmpty(expression) def startCol = expression.columnNumber if (isNotWhitespace(line, startCol + 1) && checkIsEmptyBlock(line, startCol + 1)) { addOpeningBraceViolation(expression, 'closure') } } super.visitClosureExpression(expression) } @Override protected void visitMethodEx(MethodNode node) { if (node.code) { def line = sourceLineOrEmpty(node.code) def startCol = node.code.columnNumber if (startCol > 1 && line[startCol - 2] == '{') { addOpeningBraceViolation(node.code, 'block') } } } @Override void visitMapEntryExpression(MapEntryExpression expression) { if (!rule.checkClosureMapEntryValue && expression.valueExpression instanceof ClosureExpression) { isFirstVisit(expression.valueExpression) // Register the closure so that it will be ignored in visitClosureExpression() } super.visitMapEntryExpression(expression) } private void addOpeningBraceViolation(ASTNode node, String keyword) { addViolation(node, "The opening brace for the $keyword in class $currentClassName is not followed by a space or whitespace") } private boolean checkIsEmptyBlock(String line, int indexOfBrace) { if (rule.ignoreEmptyBlock ) { return isNotCharacter(line, '}' as char, indexOfBrace) } return true } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterIfRule.groovy0000644000175000017500000000247712311373552027601 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.stmt.IfStatement import org.codenarc.rule.AbstractAstVisitorRule /** * Check that there is exactly one space (blank) after the if keyword and before the opening parenthesis. * * @author Chris Mair */ class SpaceAfterIfRule extends AbstractAstVisitorRule { String name = 'SpaceAfterIf' int priority = 3 Class astVisitorClass = SpaceAfterIfAstVisitor } class SpaceAfterIfAstVisitor extends AbstractSingleSpaceAfterKeywordAstVisitor { @Override void visitIfElse(IfStatement ifElse) { checkForSingleSpaceAndOpeningParenthesis(ifElse, 'if') super.visitIfElse(ifElse) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterCatchRule.groovy0000644000175000017500000000256112054251720030253 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.stmt.CatchStatement /** * Check that there is exactly one space (blank) after the catch keyword and before the opening parenthesis. * * @author Chris Mair */ class SpaceAfterCatchRule extends AbstractAstVisitorRule { String name = 'SpaceAfterCatch' int priority = 3 Class astVisitorClass = SpaceAfterElseAstVisitor } class SpaceAfterElseAstVisitor extends AbstractSingleSpaceAfterKeywordAstVisitor { @Override void visitCatchStatement(CatchStatement statement) { checkForSingleSpaceAndOpeningParenthesis(statement, 'catch') super.visitCatchStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/FileEndsWithoutNewlineRule.groovy0000644000175000017500000000272012312152270031664 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Makes sure the source code file ends with a newline character. * * @author Joe Sondow */ class FileEndsWithoutNewlineRule extends AbstractRule { String name = 'FileEndsWithoutNewline' int priority = 3 /** * Apply the rule to the given source, writing violations to the given list. * @param sourceCode The source to check * @param violations A list of Violations that may be added to. It can be an empty list */ @Override void applyTo(SourceCode sourceCode, List violations) { if (!sourceCode.text.endsWith('\n')) { violations.add(createViolation(sourceCode.lines.size() - 1, sourceCode.lines[-1], "File $sourceCode.name does not end with a newline")) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/BracesForTryCatchFinallyRule.groovy0000644000175000017500000001427312050064304032121 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.stmt.CatchStatement import org.codehaus.groovy.ast.stmt.TryCatchStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Checks the location of the opening brace ({) for try statements, the location * of the 'catch' keyword and corresponding opening braces, and the location of the 'finally' * keyword and the corresponding opening braces. By default, requires opening braces on the * same line, but the sameLine property can be set to false to override this. * * By default does not validate catch and finally clauses, to turn this on set properties * validateCatch and validateFinally to true respectively. The catch and finally handling * defaults to using the sameLine value so if sameLine is true, we expect "} catch(x) {" * and "} finally {". For fine grained control, use boolean properties catchOnSameLineAsClosingBrace, * catchOnSameLineAsOpeningBrace, finallyOnSameLineAsClosingBrace, finallyOnSameLineAsOpeningBrace * * @author Geli Crick * @author Hamlet D'Arcy * @author Matias Bjarland */ class BracesForTryCatchFinallyRule extends AbstractAstVisitorRule { String name = 'BracesForTryCatchFinally' int priority = 2 Class astVisitorClass = BracesForTryCatchFinallyAstVisitor boolean sameLine = true boolean validateCatch = false Boolean catchOnSameLineAsClosingBrace Boolean catchOnSameLineAsOpeningBrace boolean validateFinally = false Boolean finallyOnSameLineAsClosingBrace Boolean finallyOnSameLineAsOpeningBrace } class BracesForTryCatchFinallyAstVisitor extends AbstractAstVisitor { @Override void visitTryCatchFinally(TryCatchStatement node) { BracesForTryCatchFinallyRule myRule = rule as BracesForTryCatchFinallyRule if (myRule.sameLine) { if(!sourceLineTrimmed(node)?.contains('{')) { addViolation(node, "Opening brace should be on the same line as 'try'") } } else { if(sourceLineTrimmed(node)?.contains('{')) { addViolation(node, "Opening brace should not be on the same line as 'try'") } } visitCatch(myRule, node) visitFinally(myRule, node) super.visitTryCatchFinally(node) } void visitCatch(BracesForTryCatchFinallyRule myRule, TryCatchStatement node) { //TODO: Understand AstUtil.isBlock and isFirstVisit and apply them as appropriate to the below block if (myRule.validateCatch && node.catchStatements) { //if user has not explicitly set the catch brace settings, 'inherit' them from sameLine if (myRule.catchOnSameLineAsClosingBrace == null) { myRule.catchOnSameLineAsClosingBrace = myRule.sameLine } if (myRule.catchOnSameLineAsOpeningBrace == null) { myRule.catchOnSameLineAsOpeningBrace = myRule.sameLine } node.catchStatements.each { CatchStatement stmt -> def srcLine = sourceLineTrimmed(stmt) if (myRule.catchOnSameLineAsClosingBrace && !srcLine?.contains('}')) { addViolation(stmt, "'catch' should be on the same line as the closing brace") } else if (!myRule.catchOnSameLineAsClosingBrace && srcLine?.contains('}')) { addViolation(stmt, "'catch' should not be on the same line as the closing brace") } if (myRule.catchOnSameLineAsOpeningBrace && !srcLine?.contains('{')) { addViolation(stmt, "Opening brace should be on the same line as 'catch'") } else if (!myRule.catchOnSameLineAsOpeningBrace && srcLine?.contains('}')) { addViolation(stmt, "Opening brace should not be on the same line as 'catch'") } } } } void visitFinally(BracesForTryCatchFinallyRule myRule, TryCatchStatement node) { //TODO: Understand AstUtil.isBlock and isFirstVisit and apply them as appropriate to the below block //if user has not explicitly set the finally brace settings, 'inherit' them from sameLine if (myRule.finallyOnSameLineAsClosingBrace == null) { myRule.finallyOnSameLineAsClosingBrace = myRule.sameLine } if (myRule.finallyOnSameLineAsOpeningBrace == null) { myRule.finallyOnSameLineAsOpeningBrace = myRule.sameLine } if (myRule.validateFinally && node.finallyStatement) { def stmt = node.finallyStatement def srcLine = sourceLineTrimmed(stmt) if (myRule.finallyOnSameLineAsClosingBrace && srcLine && !srcLine?.contains('}')) { addViolation(stmt, "'finally' should be on the same line as the closing brace") } else if (!myRule.finallyOnSameLineAsClosingBrace && srcLine?.contains('}')) { addViolation(stmt, "'finally' should not be on the same line as the closing brace") } if (myRule.finallyOnSameLineAsOpeningBrace && srcLine && !srcLine?.contains('{')) { addViolation(stmt, "Opening brace should be on the same line as 'finally'") } else if (!myRule.catchOnSameLineAsOpeningBrace && srcLine?.contains('}')) { addViolation(stmt, "Opening brace should not be on the same line as 'finally'") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/BracesForMethodRule.groovy0000644000175000017500000000503512461207021030276 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Checks the location of the opening brace ({) for constructors and methods. By default, requires them on the same line, but the sameLine property can be set to false to override this. * * @author Geli Crick * @author Hamlet D'Arcy */ class BracesForMethodRule extends AbstractAstVisitorRule { String name = 'BracesForMethod' int priority = 2 Class astVisitorClass = BracesForMethodAstVisitor boolean sameLine = true } class BracesForMethodAstVisitor extends AbstractAstVisitor { @Override void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { if (node.declaringClass?.isInterface() || node.isAbstract()) { return } String lastLine if (node.exceptions) { lastLine = lastSourceLineTrimmed(node.exceptions[-1]) } else if (node.parameters) { lastLine = lastSourceLineTrimmed(node.parameters[-1]) } else { lastLine = sourceLineTrimmed(node) } if (rule.sameLine) { if(!(containsOpeningBraceAfterParenthesis(lastLine))) { addViolation(node, "Opening brace for the method $node.name should start on the same line") } } else { if (containsOpeningBraceAfterParenthesis(lastLine)) { addViolation(node, "Opening brace for the method $node.name should start on a new line") } } super.visitConstructorOrMethod(node, isConstructor) } private containsOpeningBraceAfterParenthesis(String lastLine) { int parenthesisIndex = lastLine?.indexOf(')') ?: 0 lastLine?.indexOf('{', parenthesisIndex) >= 0 } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/MissingBlankLineAfterPackageRule.groovy0000644000175000017500000000266312312152270032722 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.PackageNode import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Makes sure there is a blank line after the package statement of a source code file. * * @author Joe Sondow */ class MissingBlankLineAfterPackageRule extends AbstractRule { String name = 'MissingBlankLineAfterPackage' int priority = 3 @Override void applyTo(SourceCode sourceCode, List violations) { PackageNode packageNode = sourceCode.ast?.package if (packageNode && !sourceCode.line(packageNode.lineNumber).isEmpty()) { violations.add(createViolation(packageNode.lineNumber, sourceCode.line(packageNode.lineNumber), "Missing blank line after package statement in file $sourceCode.name")) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterSemicolonRule.groovy0000644000175000017500000000556512311373552031174 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codehaus.groovy.ast.stmt.BlockStatement import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.stmt.ForStatement import org.codehaus.groovy.ast.expr.ClosureListExpression /** * Check that there is at least one space (blank) or whitespace following a semicolon that separates: * - multiple statements on a single line * - the clauses within a classic for loop, e.g. for (i=0;i<10;i++) * * @author Chris Mair */ class SpaceAfterSemicolonRule extends AbstractAstVisitorRule { String name = 'SpaceAfterSemicolon' int priority = 3 Class astVisitorClass = SpaceAfterSemicolonAstVisitor } class SpaceAfterSemicolonAstVisitor extends AbstractAstVisitor { @Override void visitBlockStatement(BlockStatement block) { def lastLine def lastColumn block.statements.each { statementExpression -> if (lastLine && statementExpression.lineNumber == lastLine && statementExpression.columnNumber == lastColumn + 1) { def stmtText = AstUtil.getNodeText(statementExpression, sourceCode) addViolation(statementExpression, "The statement \"${stmtText}\" within class $currentClassName is not preceded by a space or whitespace") } lastLine = statementExpression.lineNumber lastColumn = statementExpression.lastColumnNumber } super.visitBlockStatement(block) } @Override void visitForLoop(ForStatement forLoop) { if (forLoop.collectionExpression instanceof ClosureListExpression) { def lastColumn forLoop.collectionExpression.expressions.each { expression -> if (lastColumn && expression.columnNumber == lastColumn + 1) { def exprText = AstUtil.getNodeText(expression, sourceCode) addViolation(forLoop, "The for loop expression \"$exprText\" within class $currentClassName is not preceded by a space or whitespace") } lastColumn = expression.lastColumnNumber } } super.visitForLoop(forLoop) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterWhileRule.groovy0000644000175000017500000000252512311373552030305 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.stmt.WhileStatement import org.codenarc.rule.AbstractAstVisitorRule /** * Check that there is exactly one space (blank) after the while keyword and before the opening parenthesis. * * @author Chris Mair */ class SpaceAfterWhileRule extends AbstractAstVisitorRule { String name = 'SpaceAfterWhile' int priority = 3 Class astVisitorClass = SpaceAfterWhileAstVisitor } class SpaceAfterWhileAstVisitor extends AbstractSingleSpaceAfterKeywordAstVisitor { @Override void visitWhileLoop(WhileStatement loop) { checkForSingleSpaceAndOpeningParenthesis(loop, 'while') super.visitWhileLoop(loop) } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/AbstractSingleSpaceAfterKeywordAstVisitor.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/AbstractSingleSpaceAfterKeywordAstVisitor0000644000175000017500000000313412461172524033362 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.ASTNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.util.AstUtil /** * Abstract superclass for AstVisitor classes that checks that there is exactly one space (blank) after a keyword * and before the opening parenthesis. * * @author Chris Mair */ class AbstractSingleSpaceAfterKeywordAstVisitor extends AbstractAstVisitor { protected void checkForSingleSpaceAndOpeningParenthesis(ASTNode node, String keyword) { if (AstUtil.isFromGeneratedSourceCode(node)) { return } def line = sourceLine(node) int col = node.columnNumber int keywordSize = keyword.size() if (line[col + keywordSize - 1] != ' ' || line.size() < col + keywordSize || line[col + keywordSize] != '(') { addViolation(node, "The $keyword keyword within class $currentClassName is not followed by a single space") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/BracesForIfElseRule.groovy0000644000175000017500000001227012051601044030222 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.stmt.IfStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Checks the location of the opening brace ({) for if statements and optionally closing and opening braces * for else statements. By default, requires them on the same line, but the sameLine property can be set to * false to override this. To enable else checking, set the validateElse property to true. For more fine grained * control, use boolean properties elseOnSameLineAsClosingBrace and elseOnSameLineAsOpeningBrace * * Example: * *
 * if (x) {     //A
 *
 * } else if (y) { //B
 *
 * } else {    //C
 *
 * }
 * 
* * A - checked and defaults to no errors since the brace is on the same line
* B - checked if option validateElse is set to true. Validation result controlled by boolean * options elseOnSameLineAsClosingBrace and elseOnSameLineAsOpeningBrace * C - same as B * * @author Hamlet D'Arcy * @author Geli Crick * @author Matias Bjarland */ class BracesForIfElseRule extends AbstractAstVisitorRule { String name = 'BracesForIfElse' int priority = 2 Class astVisitorClass = BracesForIfElseAstVisitor boolean sameLine = true boolean validateElse = false Boolean elseOnSameLineAsClosingBrace Boolean elseOnSameLineAsOpeningBrace } class BracesForIfElseAstVisitor extends AbstractAstVisitor { @Override void visitIfElse(IfStatement node) { BracesForIfElseRule myRule = rule as BracesForIfElseRule if (isFirstVisit(node) && AstUtil.isBlock(node.ifBlock)) { if (myRule.sameLine) { if(!lastSourceLineTrimmed(node.booleanExpression)?.contains('{')) { addViolation(node, "Opening brace should be on the same line as 'if'") } } else { if(lastSourceLineTrimmed(node.booleanExpression)?.contains('{')) { addViolation(node, "Opening brace should not be on the same line as 'if'") } } } visitElse(myRule, node) super.visitIfElse(node) } void visitElse(BracesForIfElseRule myRule, IfStatement node) { //TODO: Understand isFirstVisit and apply them as appropriate to the below block if (myRule.validateElse && node.elseBlock) { //if user has not explicitly set the else brace settings, 'inherit' them from sameLine if (myRule.elseOnSameLineAsClosingBrace == null) { myRule.elseOnSameLineAsClosingBrace = myRule.sameLine } if (myRule.elseOnSameLineAsOpeningBrace == null) { myRule.elseOnSameLineAsOpeningBrace = myRule.sameLine } def srcLine = sourceLineTrimmed(node.elseBlock) visitElseClosingBrace(myRule, node, srcLine) visitElseOpeningBrace(myRule, node, srcLine) } } void visitElseClosingBrace(BracesForIfElseRule myRule, IfStatement node, String srcLine) { //only test for else closing curlies if the if statement has curlies to test for (i.e. is not one-line) if (AstUtil.isBlock(node.ifBlock)) { if (myRule.elseOnSameLineAsClosingBrace && srcLine && !(srcLine?.contains('else') && srcLine?.contains('}'))) { addViolation(node.elseBlock, "'else' should be on the same line as the closing brace") } else if (!myRule.elseOnSameLineAsClosingBrace && srcLine?.contains('else') && srcLine?.contains('}')) { addViolation(node.elseBlock, "'else' should not be on the same line as the closing brace") } } } void visitElseOpeningBrace(BracesForIfElseRule myRule, IfStatement node, String srcLine) { //only test for else opening curlies if the else statement has curlies to test for (i.e. is not one-line) if (AstUtil.isBlock(node.elseBlock)) { if (myRule.elseOnSameLineAsOpeningBrace && srcLine && !(srcLine?.contains('else') && srcLine?.contains('{'))) { addViolation(node.elseBlock, "Opening brace should be on the same line as 'else'") } else if (!myRule.elseOnSameLineAsOpeningBrace && srcLine?.contains('else') && srcLine?.contains('{')) { addViolation(node.elseBlock, "Opening brace should not be on the same line as 'else'") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/BracesForClassRule.groovy0000644000175000017500000000635212313644537030143 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode import org.codenarc.util.AstUtil /** * Checks the location of the opening brace ({) for classes. By default, requires them on the same line, but the sameLine property can be set to false to override this. * * @author Hamlet D'Arcy * @author Geli Crick */ class BracesForClassRule extends AbstractRule { String name = 'BracesForClass' int priority = 2 boolean sameLine = true @Override void applyTo(SourceCode sourceCode, List violations) { sourceCode?.ast?.classes?.each { ClassNode classNode -> def (lineNumber, sourceLine) = findOpeningBraceLine(sourceCode, classNode) // Groovy 1.7 returns -1 as line number for a ClassNode representing an enum. // In this case we ignore the rule if (lineNumber != -1) { applyToClassNode(classNode, lineNumber, sourceLine, violations) } } } private applyToClassNode(ClassNode classNode, int lineNumber, String sourceLine, List violations) { if (sameLine) { if (sourceLine?.startsWith('{')) { violations.add(new Violation( rule: this, lineNumber: lineNumber, sourceLine: sourceLine, message: "Opening brace for the ${classNode.isInterface() ? 'interface' : 'class'} $classNode.name should start on the same line")) } } else { if (!sourceLine?.startsWith('{') && !definesAnnotationType(sourceLine)) { violations.add(new Violation( rule: this, lineNumber: lineNumber, sourceLine: sourceLine, message: "Opening brace for the ${classNode.isInterface() ? 'interface' : 'class'} $classNode.name should start on a new line")) } } } private definesAnnotationType(String sourceLine) { sourceLine?.contains('@interface') } private findOpeningBraceLine(SourceCode sourceCode, ASTNode node) { int line = AstUtil.findFirstNonAnnotationLine(node, sourceCode) def sourceLine = sourceCode.line(line - 1) while (sourceLine != null) { if (sourceLine?.contains('{')) { return [line, sourceLine] } line++ sourceLine = sourceCode.line(line - 1) } return [line, null] } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterSwitchRule.groovy0000644000175000017500000000255312054251646030502 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.stmt.SwitchStatement /** * Check that there is exactly one space (blank) after the switch keyword and before the opening parenthesis. * * @author Chris Mair */ class SpaceAfterSwitchRule extends AbstractAstVisitorRule { String name = 'SpaceAfterSwitch' int priority = 3 Class astVisitorClass = SpaceAfterSwitchAstVisitor } class SpaceAfterSwitchAstVisitor extends AbstractSingleSpaceAfterKeywordAstVisitor { @Override void visitSwitch(SwitchStatement statement) { checkForSingleSpaceAndOpeningParenthesis(statement, 'switch') super.visitSwitch(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAroundMapEntryColonRule.groovy0000644000175000017500000000517012407150242032150 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.expr.MapEntryExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Check for configured formatting of whitespace around colons for literal Map entries * * @author Chris Mair */ class SpaceAroundMapEntryColonRule extends AbstractAstVisitorRule { String name = 'SpaceAroundMapEntryColon' int priority = 3 String characterBeforeColonRegex = /\S/ String characterAfterColonRegex = /\S/ Class astVisitorClass = SpaceAroundMapEntryColonAstVisitor } class SpaceAroundMapEntryColonAstVisitor extends AbstractAstVisitor { @Override void visitMapEntryExpression(MapEntryExpression expression) { if (expression.lineNumber != -1) { handleMapExpression(expression) } super.visitMapEntryExpression(expression) } private void handleMapExpression(MapEntryExpression expression) { def line = sourceLine(expression) def colonIndex = expression.lastColumnNumber - 1 def charBeforeColon = line[colonIndex - 2] // Handle special case of colon as the last char of the line def charAfterColon = colonIndex >= line.size() ? '\n' : line[colonIndex] if (!(charBeforeColon ==~ rule.characterBeforeColonRegex)) { String keyName = expression.keyExpression.text addViolation(expression, violationMessage(keyName, 'preceded', rule.characterBeforeColonRegex)) } if (!(charAfterColon ==~ rule.characterAfterColonRegex)) { String keyName = expression.keyExpression.text addViolation(expression, violationMessage(keyName, 'followed', rule.characterAfterColonRegex)) } } private String violationMessage(String keyName, String precededOrFollowed, String regex) { return "The colon for the literal Map entry for key [$keyName] within class $currentClassName" + " is not $precededOrFollowed by a match for regular expression [$regex]" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/MissingBlankLineAfterImportsRule.groovy0000644000175000017500000000325512311450700033020 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Makes sure there is a blank line after the imports of a source code file. */ class MissingBlankLineAfterImportsRule extends AbstractRule { String name = 'MissingBlankLineAfterImports' int priority = 3 @Override void applyTo(SourceCode sourceCode, List violations) { if (sourceCode.ast?.imports) { // Before Groovy 2.1.3 some ImportNode objects lack a way to get the line number, so just parse the text. // https://jira.codehaus.org/browse/GROOVY-6094 List lines = sourceCode.lines int lastImportLineNumber = lines.findLastIndexOf { it.trim().startsWith('import ') } if (lastImportLineNumber > -1 && !lines[lastImportLineNumber + 1].trim().isEmpty()) { violations.add(createViolation(lastImportLineNumber + 1, lines[lastImportLineNumber + 1], "Missing blank line after imports in file $sourceCode.name")) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/AbstractSpaceAroundBraceAstVisitor.groovy0000644000175000017500000000521112461202660033314 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.expr.GStringExpression import org.codenarc.rule.AbstractAstVisitor /** * Abstract superclass for AstVisitor classes dealing with space around braces * * @author Chris Mair */ abstract class AbstractSpaceAroundBraceAstVisitor extends AbstractAstVisitor { private final Stack gStringExpressionsStack = [] as Stack @Override void visitGStringExpression(GStringExpression expression) { gStringExpressionsStack.push(expression) super.visitGStringExpression(expression) gStringExpressionsStack.pop() } protected boolean isNotInsideGString() { return gStringExpressionsStack.empty() } protected String sourceLineOrEmpty(node) { (node.lineNumber == -1 || (node instanceof ClassNode && node.script)) ? '' : sourceLine(node) } protected String lastSourceLineOrEmpty(node) { (node.lineNumber == -1 || (node instanceof ClassNode && node.script)) ? '' : lastSourceLine(node) } /** * Return true if the specified (1-based) index is valid and the character at that index is not a whitespace character * @param line - the source line to be checked * @param index - the 1-based index of the character to be checked * @return true only if the character is not a whitespace character */ protected boolean isNotWhitespace(String line, int index) { index in 1..line.size() && !Character.isWhitespace(line[index - 1] as char) } protected boolean isNotCharacter(String line, char c, int index) { index in 1..line.size() && line[index - 1] as char != c } protected int indexOfClosingBrace(String line, int blockLastColumn) { int index = blockLastColumn - 2 while(index >= 0) { if (line[index] == '}') { return index } index-- } return index } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/BlankLineBeforePackageRule.groovy0000644000175000017500000000300512311371417031525 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.PackageNode import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Makes sure there are no blank lines before the package declaration of a source code file. * * @author Joe Sondow */ class BlankLineBeforePackageRule extends AbstractRule { String name = 'BlankLineBeforePackage' int priority = 3 @Override void applyTo(SourceCode sourceCode, List violations) { PackageNode packageNode = sourceCode.ast?.package if (packageNode) { for (int index = 0; index < packageNode.lineNumber; index++) { if (sourceCode.line(index).isEmpty()) { violations.add(createViolation(index, sourceCode.line(index), "Blank line precedes package declaration in file $sourceCode.name")) } } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/ConsecutiveBlankLinesRule.groovy0000644000175000017500000000317512311370173031527 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Makes sure there are no consecutive lines that are either blank or whitespace only. * * @author Joe Sondow */ class ConsecutiveBlankLinesRule extends AbstractRule { String name = 'ConsecutiveBlankLines' int priority = 3 /** * Apply the rule to the given source, writing violations to the given list. * * @param sourceCode the source to check * @param violations a list of Violations that may be added to. It can be an empty list */ @Override void applyTo(SourceCode sourceCode, List violations) { List lines = sourceCode.getLines() for (int index = 1; index < lines.size(); index++) { String line = lines[index] if (line.trim().isEmpty() && lines[index - 1].trim().isEmpty()) { violations.add(createViolation(index, line, "File $sourceCode.name has consecutive blank lines")) } } } } ././@LongLink0000644000000000000000000000017100000000000011602 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/ClosureStatementOnOpeningLineOfMultipleLineClosureRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/ClosureStatementOnOpeningLineOfMultipleLi0000644000175000017500000000405412325017373033337 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.expr.ClosureExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Checks for closure logic on first line (after ->) for a multi-line closure * * @author Chris Mair */ class ClosureStatementOnOpeningLineOfMultipleLineClosureRule extends AbstractAstVisitorRule { String name = 'ClosureStatementOnOpeningLineOfMultipleLineClosure' int priority = 3 Class astVisitorClass = ClosureStatementOnOpeningLineOfMultipleLineClosureAstVisitor } class ClosureStatementOnOpeningLineOfMultipleLineClosureAstVisitor extends AbstractAstVisitor { @Override void visitClosureExpression(ClosureExpression expression) { def block = expression.code boolean hasAtLeastOneStatement = !block.isEmpty() if (hasAtLeastOneStatement) { int closureStartLineNumber = expression.lineNumber def lastStatement = block.statements[-1] boolean isMultiLineClosure = lastStatement.lastLineNumber > block.lineNumber boolean hasCodeOnStartingLine = closureStartLineNumber == block.lineNumber if (isMultiLineClosure && hasCodeOnStartingLine) { addViolation(expression, "The multi-line closure within class $currentClassName contains a statement on the opening line of the closure.") } } super.visitClosureExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterCommaRule.groovy0000644000175000017500000001260712466525534030305 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.ListExpression import org.codehaus.groovy.ast.expr.MapExpression import org.codehaus.groovy.ast.expr.Expression /** * Check that there is at least one space (blank) or whitespace following each comma. That includes checks * for method and closure declaration parameter lists, method call parameter lists, Map literals and List literals. * * @author Chris Mair */ class SpaceAfterCommaRule extends AbstractAstVisitorRule { // Initialize displayed text for AST ClosureExpression { ClosureExpression.metaClass.getText = { return CLOSURE_TEXT } } String name = 'SpaceAfterComma' int priority = 3 Class astVisitorClass = SpaceAfterCommaAstVisitor } class SpaceAfterCommaAstVisitor extends AbstractAstVisitor { @Override protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { def lastColumn node.parameters.each { parameter -> if (lastColumn && parameter.columnNumber == lastColumn + 1) { addViolation(node, "The parameter ${parameter.name} of method ${node.name} within class $currentClassName is not preceded by a space or whitespace") } lastColumn = parameter.lastColumnNumber } super.visitConstructorOrMethod(node, isConstructor) } @Override void visitClosureExpression(ClosureExpression expression) { if (isFirstVisit(expression)) { def lastColumn expression.parameters.each { parameter -> if (lastColumn && parameter.columnNumber == lastColumn + 1) { addViolation(expression, "The closure parameter ${parameter.name} within class $currentClassName is not preceded by a space or whitespace") } lastColumn = parameter.lastColumnNumber } } super.visitClosureExpression(expression) } @Override void visitMethodCallExpression(MethodCallExpression call) { processMethodOrConstructorCall(call) super.visitMethodCallExpression(call) } @Override void visitConstructorCallExpression(ConstructorCallExpression call) { processMethodOrConstructorCall(call) super.visitConstructorCallExpression(call) } private void processMethodOrConstructorCall(Expression call) { if (isFirstVisit(call)) { def arguments = call.arguments def parameterExpressions = arguments.expressions def lastColumn parameterExpressions.each { e -> if (lastColumn && e.columnNumber == lastColumn + 1 && !isClosureParameterOutsideParentheses(e, arguments)) { addViolation(call, "The parameter ${e.text} in the call to method ${call.methodAsString} within class $currentClassName is not preceded by a space or whitespace") } lastColumn = e.lastColumnNumber } } } private boolean isClosureParameterOutsideParentheses(Expression e, arguments) { e instanceof ClosureExpression && e.columnNumber > arguments.lastColumnNumber } @Override void visitListExpression(ListExpression listExpression) { if (isFirstVisit(listExpression)) { def lastColumn listExpression.expressions.each { e -> if (lastColumn && e.columnNumber == lastColumn + 1) { addViolation(listExpression, "The list element ${e.text} within class $currentClassName is not preceded by a space or whitespace") } lastColumn = e.lastColumnNumber } } super.visitListExpression(listExpression) } @Override void visitMapExpression(MapExpression mapExpression) { if (isFirstVisit(mapExpression)) { def lastColumn mapExpression.mapEntryExpressions.each { e -> if (lastColumn && e.keyExpression.columnNumber == lastColumn + 1) { def mapEntryAsString = e.keyExpression.text + ':' + e.valueExpression.text addViolation(mapExpression, "The map entry $mapEntryAsString within class $currentClassName is not preceded by a space or whitespace") } lastColumn = e.valueExpression.lastColumnNumber } } super.visitMapExpression(mapExpression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceBeforeOpeningBraceRule.groovy0000644000175000017500000001277212443420675031744 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.SwitchStatement import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.MapEntryExpression import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.MethodNode /** * Check that there is at least one space (blank) or whitespace before each opening brace ("{"). * This checks method/class/interface declarations, as well as try/for/while/if statements. * * @author Chris Mair */ class SpaceBeforeOpeningBraceRule extends AbstractAstVisitorRule { String name = 'SpaceBeforeOpeningBrace' int priority = 3 Class astVisitorClass = SpaceBeforeOpeningBraceAstVisitor boolean checkClosureMapEntryValue = true } class SpaceBeforeOpeningBraceAstVisitor extends AbstractSpaceAroundBraceAstVisitor { @Override protected void visitClassEx(ClassNode node) { def line = sourceLineOrEmpty(node) def indexOfBrace = line.indexOf('{') if (indexOfBrace > 1) { if (isNotWhitespace(line, indexOfBrace)) { def typeName = node.isInterface() ? 'interface' : (node.isEnum() ? 'enum' : 'class') addViolation(node, "The opening brace for $typeName $currentClassName is not preceded by a space or whitespace") } } super.visitClassEx(node) } @Override protected void visitMethodEx(MethodNode node) { processMethodNode(node, 'method') super.visitMethodEx(node) } @Override void visitConstructor(ConstructorNode node) { processMethodNode(node, 'constructor') super.visitConstructor(node) } private void processMethodNode(MethodNode node, String keyword) { if (isFirstVisit(node.code) && node.code && !AstUtil.isFromGeneratedSourceCode(node)) { def line = sourceLineOrEmpty(node) if (line.contains('){')) { addOpeningBraceViolation(node, keyword) } } } @Override void visitBlockStatement(BlockStatement block) { if (isFirstVisit(block) && !AstUtil.isFromGeneratedSourceCode(block)) { def line = sourceLineOrEmpty(block) def startCol = block.columnNumber if (isNotWhitespace(line, startCol - 1)) { addOpeningBraceViolation(block, 'block') } } super.visitBlockStatement(block) } @Override void visitClosureExpression(ClosureExpression expression) { isFirstVisit(expression.code) // Register the code block so that it will be ignored in visitBlockStatement() if (isFirstVisit(expression)) { if (isCharacterPrecedingClosureInvalid(expression)) { addOpeningBraceViolation(expression, 'closure') } } super.visitClosureExpression(expression) } @Override void visitMapEntryExpression(MapEntryExpression expression) { if (!rule.checkClosureMapEntryValue && expression.valueExpression instanceof ClosureExpression) { isFirstVisit(expression.valueExpression) // Register the closure so that it will be ignored in visitClosureExpression() } super.visitMapEntryExpression(expression) } @Override void visitSwitch(SwitchStatement statement) { if (isFirstVisit(statement)) { def line = sourceLineOrEmpty(statement) if (line.contains('){')) { addOpeningBraceViolation(statement, 'switch statement') } } super.visitSwitch(statement) } private boolean isCharacterPrecedingClosureInvalid(ClosureExpression expression) { String line = sourceLineOrEmpty(expression) int investigatedIndex = expression.columnNumber - 1 return isNotWhitespace(line, investigatedIndex) && isNotOpeningParenthesis(line, investigatedIndex) && isNotDollarInsideGString(line, investigatedIndex) } private boolean isNotDollarInsideGString(String line, int index) { if (isNotDollar(line, index)) { return true } return isNotInsideGString() } private boolean isNotDollar(String line, int index) { return isNotCharacter(line, '$' as char, index) } private boolean isNotOpeningParenthesis(String line, int index) { return isNotCharacter(line, '(' as char, index) } private void addOpeningBraceViolation(ASTNode node, String keyword) { addViolation(node, "The opening brace for the $keyword in class $currentClassName is not preceded by a space or whitespace") } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterForRule.groovy0000644000175000017500000000251512054252376027766 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.stmt.ForStatement /** * Check that there is exactly one space (blank) after the for keyword and before the opening parenthesis. * * @author Chris Mair */ class SpaceAfterForRule extends AbstractAstVisitorRule { String name = 'SpaceAfterFor' int priority = 3 Class astVisitorClass = SpaceAfterForAstVisitor } class SpaceAfterForAstVisitor extends AbstractSingleSpaceAfterKeywordAstVisitor { @Override void visitForLoop(ForStatement forLoop) { checkForSingleSpaceAndOpeningParenthesis(forLoop, 'for') super.visitForLoop(forLoop) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/TrailingWhitespaceRule.groovy0000644000175000017500000000247212407277244031075 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Checks that no lines of source code end with whitespace characters. * * @author Joe Sondow */ class TrailingWhitespaceRule extends AbstractRule { String name = 'TrailingWhitespace' int priority = 3 @Override void applyTo(SourceCode sourceCode, List violations) { def matcher = sourceCode.getText() =~ /[^\n]*[ \t]+\n/ while (matcher.find()) { def lineNumber = sourceCode.getLineNumberForCharacterIndex(matcher.start()) violations.add(createViolation(lineNumber, matcher.group(), 'Line ends with whitespace characters')) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAfterClosingBraceRule.groovy0000644000175000017500000001317112461206554031572 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.ConstructorNode import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.MapEntryExpression import org.codehaus.groovy.ast.ASTNode /** * Check that there is at least one space (blank) or whitespace after each closing brace ("}"). * This checks method/class/interface declarations, closure expressions and block statements. * * A closure expression followed by a dot operator (.), a comma, a closing parenthesis, the * spread-dot operator (*.), a semicolon or the null-safe operator (?.) does not cause a violation. * * @author Chris Mair */ class SpaceAfterClosingBraceRule extends AbstractAstVisitorRule { String name = 'SpaceAfterClosingBrace' int priority = 3 Class astVisitorClass = SpaceAfterClosingBraceAstVisitor boolean checkClosureMapEntryValue = true } class SpaceAfterClosingBraceAstVisitor extends AbstractSpaceAroundBraceAstVisitor { @Override protected void visitClassEx(ClassNode node) { def line = lastSourceLineOrEmpty(node) def startColumn = node.columnNumber >= 0 ? node.columnNumber : 0 def indexOfBrace = line.indexOf('}', startColumn) if (indexOfBrace > 1) { if (isNotWhitespace(line, indexOfBrace + 2) && isNotAllowedCharacterAfterClass(line, indexOfBrace + 2)) { def typeName = node.isInterface() ? 'interface' : (node.isEnum() ? 'enum' : 'class') addViolation(node, "The closing brace for $typeName $currentClassName is not followed by a space or whitespace") } } super.visitClassEx(node) } @Override protected void visitMethodEx(MethodNode node) { processMethodNode(node) super.visitMethodEx(node) } @Override void visitConstructor(ConstructorNode node) { processMethodNode(node) super.visitConstructor(node) } private void processMethodNode(MethodNode node) { if (isFirstVisit(node.code) && node.code && !AstUtil.isFromGeneratedSourceCode(node)) { def line = lastSourceLineOrEmpty(node.code) def lastCol = node.code.lastColumnNumber if (line.size() >= lastCol && isNotWhitespace(line, lastCol + 1) && line[lastCol - 1] == '}' ) { addOpeningBraceViolation(node.code, 'block') } } } @Override void visitBlockStatement(BlockStatement block) { if (isFirstVisit(block) && !AstUtil.isFromGeneratedSourceCode(block)) { def startLine = sourceLineOrEmpty(block) def line = lastSourceLineOrEmpty(block) def lastCol = block.lastColumnNumber def startCol = block.columnNumber if (startLine[startCol - 1] == '{') { int lastIndex = indexOfClosingBrace(line, lastCol) if (isNotWhitespace(line, lastIndex + 2)) { addOpeningBraceViolation(block, 'block') } } } super.visitBlockStatement(block) } @Override void visitClosureExpression(ClosureExpression expression) { isFirstVisit(expression.code) // Register the code block so that it will be ignored in visitBlockStatement() if (isFirstVisit(expression)) { String line = lastSourceLineOrEmpty(expression) int lastCol = expression.lastColumnNumber int investigatedIndex = indexOfClosingBrace(line, lastCol) + 2 if (isNotWhitespace(line, investigatedIndex) && isNotAllowedCharacterAfterClosure(line, investigatedIndex) && isNotInsideGString()) { addOpeningBraceViolation(expression, 'closure') } } super.visitClosureExpression(expression) } @Override void visitMapEntryExpression(MapEntryExpression expression) { if (!rule.checkClosureMapEntryValue && expression.valueExpression instanceof ClosureExpression) { isFirstVisit(expression.valueExpression) // Register the closure so that it will be ignored in visitClosureExpression() } super.visitMapEntryExpression(expression) } private boolean isNotAllowedCharacterAfterClosure(String line, int index) { return index in 1..line.size() && !(line[index - 1] in ['.', ',', ')', '*', '?', ';']) } private boolean isNotAllowedCharacterAfterClass(String line, int index) { return index in 1..line.size() && !(line[index - 1] in ['.', ')', ';']) } private void addOpeningBraceViolation(ASTNode node, String keyword) { addViolation(node, "The closing brace for the $keyword in class $currentClassName is not followed by a space or whitespace") } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/formatting/SpaceAroundOperatorRule.groovy0000644000175000017500000001766612325341275031235 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.CastExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.expr.TernaryExpression import org.codehaus.groovy.ast.expr.ElvisOperatorExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.BooleanExpression /** * Check that there is at least one space (blank) or whitespace around each binary operator, * including: +, -, *, /, >>, <<, &&, ||, &, |, ?:, =, as. * * Do not check dot ('.') operator. Do not check unary operators (!, +, -, ++, --, ?.). * Do not check array ('[') operator. * * Known limitation: Does not catch violations of missing space around equals operator (=) within a * declaration expression, e.g. def x=23 * * Known limitation: Does not catch violations of certain ternary expressions. * * @author Chris Mair */ class SpaceAroundOperatorRule extends AbstractAstVisitorRule { String name = 'SpaceAroundOperator' int priority = 3 Class astVisitorClass = SpaceAroundOperatorAstVisitor } class SpaceAroundOperatorAstVisitor extends AbstractAstVisitor { private boolean withinDeclarationExpression @Override void visitDeclarationExpression(DeclarationExpression expression) { withinDeclarationExpression = true super.visitDeclarationExpression(expression) withinDeclarationExpression = false } @Override void visitTernaryExpression(TernaryExpression expression) { if (isFirstVisit(expression)) { if (expression instanceof ElvisOperatorExpression) { processElvisExpression(expression) } else { processTernaryExpression(expression) } } super.visitTernaryExpression(expression) } private void processTernaryExpression(TernaryExpression expression) { def opColumn = expression.columnNumber def line = sourceLine(expression) def beforeChar = line[opColumn - 2] as char // Known limitation: Ternary expression column does not always indicate column of '?' if (opColumn <= leftMostColumn(expression.booleanExpression)) { checkForSpaceAroundTernaryOperator(expression, line) return } if (!Character.isWhitespace(beforeChar)) { addViolation(expression, "The operator \"?\" within class $currentClassName is not preceded by a space or whitespace") } if (opColumn < line.size() && !Character.isWhitespace(line[opColumn] as char)) { addViolation(expression, "The operator \"?\" within class $currentClassName is not followed by a space or whitespace") } if (rightMostColumn(expression.trueExpression) + 1 == leftMostColumn(expression.falseExpression)) { addViolation(expression, "The operator \":\" within class $currentClassName is not surrounded by a space or whitespace") } } private checkForSpaceAroundTernaryOperator(TernaryExpression expression, String line) { if (expression.lineNumber == expression.lastLineNumber) { def hasWhitespaceAroundQuestionMark = (line =~ /\s\?\s/) if (!hasWhitespaceAroundQuestionMark) { addViolation(expression, "The operator \"?\" within class $currentClassName is not surrounded by a space or whitespace") } def hasWhitespaceAroundColon = (line =~ /\s\:\s/) if (!hasWhitespaceAroundColon) { addViolation(expression, "The operator \":\" within class $currentClassName is not surrounded by a space or whitespace") } } } private void processElvisExpression(ElvisOperatorExpression expression) { def line = sourceCode.lines[expression.lineNumber - 1] if (line.contains('?:')) { if (!(line =~ /\s\?\:/)) { addViolation(expression, "The operator \"?:\" within class $currentClassName is not preceded by a space or whitespace") } if (!(line =~ /\?\:\s/)) { addViolation(expression, "The operator \"?:\" within class $currentClassName is not followed by a space or whitespace") } } } @Override void visitBinaryExpression(BinaryExpression expression) { if (!isFirstVisit(expression)) { return } def op = expression.operation def opText = op.text def opEndColumn = op.startColumn + opText.size() - 1 def line = sourceCode.lines[op.startLine - 1] boolean assignmentWithinDeclaration = (opText == '=') && withinDeclarationExpression boolean arrayOperator = opText == '[' boolean isOperatorAtIndex = op.startColumn != -1 && (line[op.startColumn - 1] == opText[0]) boolean ignore = assignmentWithinDeclaration || arrayOperator || !isOperatorAtIndex if (!ignore && op.startColumn > 1) { def beforeChar = line[op.startColumn - 2] as char if (!Character.isWhitespace(beforeChar)) { addViolation(expression, "The operator \"${expression.operation.text}\" within class $currentClassName is not preceded by a space or whitespace") } } if (!ignore && opEndColumn != -1 && opEndColumn < line.size()) { def afterChar = line[opEndColumn] as char if (!Character.isWhitespace(afterChar)) { addViolation(expression, "The operator \"${expression.operation.text}\" within class $currentClassName is not followed by a space or whitespace") } } super.visitBinaryExpression(expression) } @Override void visitCastExpression(CastExpression expression) { if (expression.coerce && expression.lineNumber != -1) { boolean containsAsWithSpaces = (expression.lineNumber..expression.lastLineNumber).find { lineNumber -> String line = sourceCode.lines[lineNumber - 1] return line.find(/\sas\s/) } if (!containsAsWithSpaces) { addViolation(expression, "The operator \"as\" within class $currentClassName is not surrounded by a space or whitespace") } } super.visitCastExpression(expression) } private int rightMostColumn(expression) { if (expression instanceof BinaryExpression) { return rightMostColumn(expression.rightExpression) } if (expression instanceof MethodCallExpression) { return expression.arguments.lastColumnNumber } if (expression instanceof PropertyExpression) { return expression.property.lastColumnNumber } if (expression instanceof BooleanExpression) { return rightMostColumn(expression.expression) } expression.lastColumnNumber } private int leftMostColumn(expression) { return expression instanceof BinaryExpression ? leftMostColumn(expression.leftExpression) : expression.columnNumber } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/Violation.groovy0000644000175000017500000000173512311373552024243 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule /** * Represents a single instance of a rule violation * * @author Chris Mair */ class Violation { Rule rule Integer lineNumber String sourceLine String message String toString() { "Violation[rule=$rule, lineNumber=$lineNumber, sourceLine=$sourceLine, message=$message]" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/0000755000175000017500000000000012623571301022151 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/SpockIgnoreRestUsedRule.groovy0000644000175000017500000000443112407347720030162 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.WildcardPattern /** * If Spock's @IgnoreRest on any method, all non-annotated test methods are not executed. This behaviour is almost always * unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed. * * @author Jan Ahrens * @author Stefan Armbruster * @author Chris Mair */ class SpockIgnoreRestUsedRule extends AbstractAstVisitorRule { String name = 'SpockIgnoreRestUsed' int priority = 2 String specificationSuperclassNames = '*Specification' String specificationClassNames = null Class astVisitorClass = SpockIgnoreRestUsedAstVisitor } class SpockIgnoreRestUsedAstVisitor extends AbstractMethodVisitor { @Override void visitClass(ClassNode node) { def superClassPattern = new WildcardPattern(rule.specificationSuperclassNames) def classNamePattern = new WildcardPattern(rule.specificationClassNames, false) if (superClassPattern.matches(node.superClass.name) || classNamePattern.matches(node.name)) { super.visitClass(node) } } @Override void visitMethod(MethodNode node) { def hasIgnoreRest = node.annotations.any { it.classNode.nameWithoutPackage == 'IgnoreRest' } if (hasIgnoreRest) { addViolation(node, "The method '$node.name' in class $node.declaringClass.name uses @IgnoreRest") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitLostTestRule.groovy0000644000175000017500000000500512311373552027005 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codehaus.groovy.ast.MethodNode import java.lang.reflect.Modifier import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.ClassNode /** * Rule that checks if a JUnit 4 test class contains public, instance, void, no-arg methods * named test*() that are NOT annotated with @Test. *

* This rule sets the default value of applyToFilesMatching to only match source code file * paths ending in 'Test.groovy' or 'Tests.groovy'. * * @author Chris Mair */ class JUnitLostTestRule extends AbstractAstVisitorRule { String name = 'JUnitLostTest' int priority = 2 Class astVisitorClass = JUnitLostTestAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitLostTestAstVisitor extends AbstractMethodVisitor { @Override void visitClass(ClassNode node) { def imports = sourceCode.ast.imports + sourceCode.ast.starImports def junit4TestClass = imports.find { importNode -> def importName = importNode.className ?: importNode.packageName importName.startsWith('org.junit.') } if (junit4TestClass) { super.visitClass(node) } } @Override void visitMethod(MethodNode methodNode) { if (Modifier.isPublic(methodNode.modifiers) && (methodNode.isVoidMethod()) && (methodNode.parameters?.length == 0) && (methodNode.name?.startsWith('test')) && !(Modifier.isStatic(methodNode.modifiers)) && !AstUtil.hasAnnotation(methodNode, 'Test') ) { addViolation(methodNode, "The method ${methodNode.name} is a public, instance, void, no-arg method named test*() that is not annotated with @Test.") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/CoupledTestCaseRule.groovy0000644000175000017500000000504712311373552027307 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * This rule finds test cases that are coupled to other test cases, either by invoking static methods on another test * case or by creating instances of another test case. If you require shared logic in test cases then extract that logic * to a new class where it can properly be reused. Static references to methods on the current test class are ignored. * * @author Hamlet D'Arcy * @author Chris Mair */ class CoupledTestCaseRule extends AbstractAstVisitorRule { String name = 'CoupledTestCase' int priority = 2 Class astVisitorClass = CoupledTestCaseAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class CoupledTestCaseAstVisitor extends AbstractAstVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, '[A-Z].*Test', '.*') && !isMethodCallOnSameClass(call)) { addViolation(call, "$call.text invokes a method on another test case. Test cases should not be coupled. Move this method to a helper object") } super.visitMethodCallExpression(call) } @Override void visitConstructorCallExpression(ConstructorCallExpression call) { if (call.type.name.matches('[A-Z].*Test')) { addViolation(call, "$call.text creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object") } super.visitConstructorCallExpression(call) } private boolean isMethodCallOnSameClass(MethodCallExpression call) { AstUtil.isMethodCallOnObject(call, getCurrentClassName()) || AstUtil.isMethodCallOnObject(call, getCurrentClassNode().nameWithoutPackage) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitFailWithoutMessageRule.groovy0000644000175000017500000000313112006632012030754 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * This rule detects JUnit calling the fail() method without an argument. For better error reporting you should always provide a message. * * @author Hamlet D'Arcy */ class JUnitFailWithoutMessageRule extends AbstractAstVisitorRule { String name = 'JUnitFailWithoutMessage' int priority = 2 Class astVisitorClass = JUnitFailWithoutMessageRuleAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitFailWithoutMessageRuleAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, ['this', 'Assert'], ['fail'], 0)) { addViolation call, 'Pass a String parameter to the fail method' } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/UseAssertSameInsteadOfAssertTrueRule.groovy0000644000175000017500000000413312053435560032617 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * This rule detects JUnit calling assertTrue where the first or second parameter is an Object#is() call testing for reference equality. These assertion should be made against the assertSame method instead. * * @author Hamlet D'Arcy */ class UseAssertSameInsteadOfAssertTrueRule extends AbstractAstVisitorRule { String name = 'UseAssertSameInsteadOfAssertTrue' int priority = 3 String applyToClassNames = DEFAULT_TEST_CLASS_NAMES Class astVisitorClass = UseAssertSameInsteadOfAssertTrueAstVisitor } class UseAssertSameInsteadOfAssertTrueAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { List args = AstUtil.getMethodArguments(call) if (AstUtil.isMethodCall(call, ['this', 'Assert'], ['assertTrue', 'assertFalse'])) { if (args.size() == 1 && AstUtil.isMethodCall(args[0], 'is', 1)) { addViolation call, 'assert method can be simplified using the assertSame method' } else if (args.size() == 2 && AstUtil.isMethodCall(args[1], 'is', 1)) { addViolation call, 'assert method can be simplified using the assertSame method' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitUnnecessaryTearDownRule.groovy0000644000175000017500000000357012311373552031174 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * Rule that checks for a JUnit tearDown() method that only contains a call to * super.tearDown(). *

* This rule sets the default value of applyToFilesMatching to only match source code file * paths ending in 'Test.groovy' or 'Tests.groovy'. * * @author Chris Mair * @author Hamlet D'Arcy */ class JUnitUnnecessaryTearDownRule extends AbstractAstVisitorRule { String name = 'JUnitUnnecessaryTearDown' int priority = 3 Class astVisitorClass = JUnitUnnecessaryTearDownAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitUnnecessaryTearDownAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode methodNode) { if (JUnitUtil.isTearDownMethod(methodNode)) { def statements = methodNode.code.statements if (statements.size() == 1 && AstUtil.isMethodCall(statements[0], 'super', 'tearDown', 0)) { addViolation(methodNode, 'The tearDown() method contains no logic and can be removed') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitUnnecessaryThrowsExceptionRule.groovy0000644000175000017500000000452212056263614032617 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codehaus.groovy.ast.MethodNode import org.codenarc.util.AstUtil /** * Check for throws clauses on JUnit test methods. That is not necessary in Groovy. * * This rule sets the default value of the property to only match class names * ending in 'Test', 'Tests' or 'TestCase'. * * @author Chris Mair */ class JUnitUnnecessaryThrowsExceptionRule extends AbstractAstVisitorRule { String name = 'JUnitUnnecessaryThrowsException' int priority = 3 Class astVisitorClass = JUnitUnnecessaryThrowsExceptionAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitUnnecessaryThrowsExceptionAstVisitor extends AbstractAstVisitor { private static final JUNIT4_ANNOTATIONS = ['Test', 'Before', 'BeforeClass', 'AfterClass', 'After', 'Ignore'] @Override protected void visitMethodEx(MethodNode node) { if (node.exceptions && node.parameters.size() == 0 && node.isPublic() && !node.isStatic() && node.isVoidMethod() && (isJUnit3MatchingMethod(node) || hasJUnit4Annotation(node)) ) { addViolation(node, "The ${node.name} method in class $currentClassName declares thrown exceptions, which is not necessary") } super.visitMethodEx(node) } private boolean isJUnit3MatchingMethod(MethodNode node) { return node.name.startsWith('test') || node.name in ['setUp', 'tearDown'] } private boolean hasJUnit4Annotation(MethodNode node) { return JUNIT4_ANNOTATIONS.find { annotation -> AstUtil.hasAnnotation(node, annotation) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitAssertAlwaysFailsRule.groovy0000644000175000017500000000567612311373552030643 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor /** * Rule that checks for JUnit assert() method calls with constant arguments * such that the assertion always fails. This includes: *

    *
  • assertTrue(false).
  • *
  • assertTrue(0).
  • *
  • assertTrue('').
  • *
  • assertTrue([123]).
  • *
  • assertTrue([a:123]).
  • *
  • assertFalse(true).
  • *
  • assertFalse(99).
  • *
  • assertFalse([123]).
  • *
  • assertFalse([a:123]).
  • *
  • assertNull(CONSTANT).
  • *
  • assertNull([]).
  • *
  • assertNull([123]).
  • *
  • assertNull([a:123]).
  • *
  • assertNull([:]).
  • *
* This rule sets the default value of applyToFilesMatching to only match source code file * paths ending in 'Test.groovy' or 'Tests.groovy'. * * @author Chris Mair */ class JUnitAssertAlwaysFailsRule extends AbstractAstVisitorRule { String name = 'JUnitAssertAlwaysFails' int priority = 2 Class astVisitorClass = JUnitAssertAlwaysFailsAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitAssertAlwaysFailsAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression methodCall) { def isMatch = JUnitUtil.isAssertCallWithLiteralValue(methodCall, 'assertTrue', false) || JUnitUtil.isAssertCallWithLiteralValue(methodCall, 'assertFalse', true) || JUnitUtil.isAssertCallWithNonNullConstantValue(methodCall, 'assertNull') || JUnitUtil.isAssertCallWithLiteralValue(methodCall, 'assertNull', true) || JUnitUtil.isAssertCallWithLiteralValue(methodCall, 'assertNull', false) || JUnitUtil.isAssertCallWithConstantValue(methodCall, 'assertNotNull', null) if (isMatch) { addViolation(methodCall, "The assertion $methodCall.text will always fail. Replace with a call to the fail(String) method") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/UnnecessaryFailRule.groovy0000644000175000017500000000434312006632014027341 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.CatchStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * In a unit test, catching an exception and immedietly calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all. * * @author Hamlet D'Arcy */ class UnnecessaryFailRule extends AbstractAstVisitorRule { String name = 'UnnecessaryFail' int priority = 2 Class astVisitorClass = UnnecessaryFailAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class UnnecessaryFailAstVisitor extends AbstractAstVisitor { @Override void visitCatchStatement(CatchStatement statement) { if (statement.code instanceof BlockStatement && statement.code.statements) { statement.code.statements.each { addViolationIfFail(it) } } super.visitCatchStatement(statement) } private addViolationIfFail(ASTNode it) { if (it instanceof ExpressionStatement && it.expression instanceof MethodCallExpression) { if (AstUtil.isMethodCall(it.expression, ['this', 'Assert'], ['fail'], 0)) { addViolation it.expression, 'Catching an exception and failing will hide the stack trace. It is better to rethrow the exception' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/UseAssertEqualsInsteadOfAssertTrueRule.groovy0000644000175000017500000000431112006632016033153 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * This rule detects JUnit assertions in object equality. These assertions should be made by more specific * methods, like assertEquals. * * @author Per Junel * @author Hamlet D'Arcy */ class UseAssertEqualsInsteadOfAssertTrueRule extends AbstractAstVisitorRule { String name = 'UseAssertEqualsInsteadOfAssertTrue' int priority = 3 String applyToClassNames = DEFAULT_TEST_CLASS_NAMES Class astVisitorClass = UseAssertEqualsInsteadOfAssertTrueAstVisitor } class UseAssertEqualsInsteadOfAssertTrueAstVisitor extends AbstractMethodCallExpressionVisitor { @SuppressWarnings('DuplicateLiteral') void visitMethodCallExpression(MethodCallExpression call) { List args = AstUtil.getMethodArguments(call) if (args.size() < 3 && args.size() > 0) { def arg = args.last() if (AstUtil.isMethodCall(call, ['this', 'Assert'], ['assertTrue']) && AstUtil.isBinaryExpressionType(arg, '==')) { addViolation call, "Replace $call.methodAsString with a call to assertEquals()" } if (AstUtil.isMethodCall(call, ['this', 'Assert'], ['assertFalse']) && AstUtil.isBinaryExpressionType(arg, '!=') && call.methodAsString == 'assertFalse') { addViolation call, "Replace $call.methodAsString with a call to assertEquals()" } } } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitAssertEqualsConstantActualValueRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitAssertEqualsConstantActualValueRule.groov0000644000175000017500000000755512142570714033325 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.StaticMethodCallExpression import org.codehaus.groovy.control.Phases import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.junit.Assert /** * Reports usages of org.junit.Assert.assertEquals([message,] expected, actual) where the 'actual' parameter * is a constant or a literal. Most likely it was intended to be the 'expected' value. * * @author Artur Gajowy */ class JUnitAssertEqualsConstantActualValueRule extends AbstractAstVisitorRule { String name = 'JUnitAssertEqualsConstantActualValue' int priority = 2 Class astVisitorClass = JUnitAssertEqualsConstantActualValueAstVisitor String applyToFilesMatching = DEFAULT_TEST_FILES int compilerPhase = Phases.SEMANTIC_ANALYSIS } class JUnitAssertEqualsConstantActualValueAstVisitor extends AbstractAstVisitor { private static final ClassNode ASSERT_TYPE = ClassHelper.make(Assert) private static final String ASSERT_EQUALS = 'assertEquals' @Override void visitMethodCallExpression(MethodCallExpression call) { if (call.objectExpression.type == ASSERT_TYPE && AstUtil.isMethodNamed(call, ASSERT_EQUALS)) { findViolations(call) } } @Override void visitStaticMethodCallExpression(StaticMethodCallExpression call) { if (call.ownerType == ASSERT_TYPE && call.method == ASSERT_EQUALS) { findViolations(call) } } private void findViolations(def methodCall) { Expression actualArgument = getActualArgument(methodCall) if (actualArgument && AstUtil.isConstantOrConstantLiteral(actualArgument)) { addViolation(methodCall, VIOLATION_MESSAGE) } } private Expression getActualArgument(def methodCall) { List arguments = AstUtil.getMethodArguments(methodCall) int actualArgumentIndex = getActualArgumentIndex(arguments) return actualArgumentIndex == -1 ? null : arguments[actualArgumentIndex] } //see org.junit.Assert.assertEquals methods' signatures private int getActualArgumentIndex(List arguments) { def actualArgumentIndex = -1 if (arguments.size() == 2) { actualArgumentIndex = 1 } else if (arguments.size() == 4) { actualArgumentIndex = 2 } else if (arguments.size() == 3) { if (arguments.first().type == ClassHelper.make(String)) { actualArgumentIndex = 2 } else if (isConvertibleToDouble(arguments.first().type)) { actualArgumentIndex = 1 } } actualArgumentIndex } private boolean isConvertibleToDouble(ClassNode classNode) { return classNode.typeClass in [int, Integer, long, Long, float, Float, double, Double, BigInteger, BigDecimal] } private static final String VIOLATION_MESSAGE = 'Found `assertEquals` with literal or constant `actual` parameter. ' + 'Most likely it was intended to be the `expected` value.' } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitPublicFieldRule.groovy0000644000175000017500000000360112251104076027402 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil /** * Checks for public field on a JUnit test class. Ignores fields with the @Rule annotation. *

* This rule ignores interfaces. *

* This rule sets the default value of applyToFilesMatching to only match source code file * paths ending in 'Test.groovy' or 'Tests.groovy'. * * @author Chris Mair */ class JUnitPublicFieldRule extends AbstractAstVisitorRule { String name = 'JUnitPublicField' int priority = 3 Class astVisitorClass = JUnitPublicFieldAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitPublicFieldAstVisitor extends AbstractFieldVisitor { @Override void visitClass(ClassNode node) { if (!node.isInterface()) { super.visitClass(node) } } @Override void visitField(FieldNode node) { if (node.isPublic() && !AstUtil.hasAnnotation(node, 'Rule') ) { addViolation(node, "The field $node.name is public. There is usually no reason to have a public field (even a constant) on a test class.") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitUnnecessarySetUpRule.groovy0000644000175000017500000000353612311373552030513 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * Rule that checks for a JUnit setUp() method that only contains a call to * super.setUp(). *

* This rule sets the default value of applyToFilesMatching to only match source code file * paths ending in 'Test.groovy' or 'Tests.groovy'. * * @author Chris Mair * @author Hamlet D'Arcy */ class JUnitUnnecessarySetUpRule extends AbstractAstVisitorRule { String name = 'JUnitUnnecessarySetUp' int priority = 3 Class astVisitorClass = JUnitUnnecessarySetUpAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitUnnecessarySetUpAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode methodNode) { if (JUnitUtil.isSetUpMethod(methodNode)) { def statements = methodNode.code.statements if (statements.size() == 1 && AstUtil.isMethodCall(statements[0], 'super', 'setUp', 0)) { addViolation(methodNode, 'The setUp() method contains no logic and can be removed') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitAssertAlwaysSucceedsRule.groovy0000644000175000017500000000545112311373552031332 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor /** * Rule that checks for JUnit assert() method calls with constant arguments * such that the assertion always succeeds. This includes: *

    *
  • assertTrue(true).
  • *
  • assertTrue('abc').
  • *
  • assertTrue(99).
  • *
  • assertTrue([123]).
  • *
  • assertTrue([a:123]).
  • *
  • assertFalse(false).
  • *
  • assertFalse(0).
  • *
  • assertFalse('').
  • *
  • assertFalse([]).
  • *
  • assertFalse([:]).
  • *
  • assertNull(null).
  • *
* This rule sets the default value of applyToFilesMatching to only match source code file * paths ending in 'Test.groovy' or 'Tests.groovy'. * * @author Chris Mair */ class JUnitAssertAlwaysSucceedsRule extends AbstractAstVisitorRule { String name = 'JUnitAssertAlwaysSucceeds' int priority = 2 Class astVisitorClass = JUnitAssertAlwaysSucceedsAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitAssertAlwaysSucceedsAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression methodCall) { def isMatch = JUnitUtil.isAssertCallWithLiteralValue(methodCall, 'assertTrue', true) || JUnitUtil.isAssertCallWithLiteralValue(methodCall, 'assertFalse', false) || JUnitUtil.isAssertCallWithConstantValue(methodCall, 'assertNull', null) || JUnitUtil.isAssertCallWithNonNullConstantValue(methodCall, 'assertNotNull') || JUnitUtil.isAssertCallWithLiteralValue(methodCall, 'assertNotNull', true) || JUnitUtil.isAssertCallWithLiteralValue(methodCall, 'assertNotNull', false) if (isMatch) { addViolation(methodCall, "The assertion $methodCall.text will always pass and is therefore pointless") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitTestMethodWithoutAssertRule.groovy0000644000175000017500000001025712443420675032064 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.AssertStatement import org.codehaus.groovy.ast.stmt.Statement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.rule.AstVisitor import org.codenarc.util.AstUtil /** * This rule searches for test methods that do not contain assert statements. Either the test method is missing assert * statements, which is an error, or the test method contains custom assert statements that do not follow a proper * assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test * annotation. By default this rule applies to the default test class names, but this can be changed using the rule's * applyToClassNames property. * * @author Hamlet D'Arcy */ class JUnitTestMethodWithoutAssertRule extends AbstractAstVisitorRule { String name = 'JUnitTestMethodWithoutAssert' int priority = 2 String assertMethodPatterns = 'assert.*,should.*,fail.*,verify.*,expect.*' String applyToClassNames = DEFAULT_TEST_CLASS_NAMES @Override AstVisitor getAstVisitor() { def strings = assertMethodPatterns ? assertMethodPatterns.tokenize(',') : [] new JUnitTestMethodWithoutAssertAstVisitor(assertMethodPatterns: strings as Set) } } class JUnitTestMethodWithoutAssertAstVisitor extends AbstractMethodVisitor { Set assertMethodPatterns @Override void visitMethod(MethodNode node) { if (JUnitUtil.isTestMethod(node)) { if (!statementContainsAssertions(node.code) && !checksException(node) && !checksTimeout(node)) { addViolation node, "Test method '$node.name' makes no assertions" } } } private boolean statementContainsAssertions(Statement code) { if (!code) { return false } def assertionTrap = new AssertionTrap(assertMethodPatterns: assertMethodPatterns) code.visit assertionTrap assertionTrap.assertionFound } private boolean checksException(ASTNode node) { hasTestAnnotationWithMember(node, 'expected') } private boolean checksTimeout(ASTNode node) { hasTestAnnotationWithMember(node, 'timeout') } private boolean hasTestAnnotationWithMember(ASTNode node, String memberName) { def testAnnotation = AstUtil.getAnnotation(node, 'Test') ?: AstUtil.getAnnotation(node, 'org.junit.Test') testAnnotation?.getMember(memberName) } } /** * Visits code searching for assert statements or assert.* method calls. */ class AssertionTrap extends AbstractAstVisitor { Set assertMethodPatterns def assertionFound = false @Override void visitAssertStatement(AssertStatement statement) { assertionFound = true } @Override void visitMethodCallExpression(MethodCallExpression call) { if (call.method instanceof ConstantExpression && methodNamesCountsAsAssertion(call.method.value)) { assertionFound = true } else { super.visitMethodCallExpression call } } private boolean methodNamesCountsAsAssertion(methodName) { if (methodName instanceof String) { return assertMethodPatterns.any { pattern -> methodName.matches(pattern) } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitPublicNonTestMethodRule.groovy0000644000175000017500000000601712311373552031122 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * Rule that checks if a JUnit test class contains public methods other than: *
    *
  • Zero-argument methods with names starting with "test"
  • *
  • The setUp() and tearDown() methods
  • *
  • Methods annotated with @Test
  • *
  • Methods annotated with @Before and @After
  • *
  • Methods annotated with @BeforeClass and @AfterClass
  • *
* Public, non-test methods on a test class violate conventional usage of test classes, * and can be confusing. *

* Public, non-test methods may also hide unintentional 'Lost Tests'. For instance, the test method * declaration may accidentally include methods parameters, and thus be ignored by JUnit. Or the * method may accidentally not follow the "test.." naming convention and not have the @Test annotation, * and thus be ignored by JUnit. *

* This rule sets the default value of the property to only match class names * ending in 'Test', 'Tests' or 'TestCase'. * * @author Chris Mair * @author Hamlet D'Arcy */ class JUnitPublicNonTestMethodRule extends AbstractAstVisitorRule { String name = 'JUnitPublicNonTestMethod' int priority = 2 Class astVisitorClass = JUnitPublicNonTestMethodAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitPublicNonTestMethodAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode methodNode) { if (Modifier.isPublic(methodNode.modifiers) && !(Modifier.isStatic(methodNode.modifiers)) && !JUnitUtil.isTestMethod(methodNode) && !AstUtil.isMethodNode(methodNode, 'setUp|tearDown', 0) && !AstUtil.getAnnotation(methodNode, 'Override') && !AstUtil.getAnnotation(methodNode, 'Test') && !AstUtil.getAnnotation(methodNode, 'Before') && !AstUtil.getAnnotation(methodNode, 'After') && !AstUtil.getAnnotation(methodNode, 'BeforeClass') && !AstUtil.getAnnotation(methodNode, 'AfterClass') ) { addViolation(methodNode, "The method $methodNode.name is public but not a test method") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitStyleAssertionsRule.groovy0000644000175000017500000000413612006632016030375 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * This rule detects calling JUnit style assertions like assertEquals, assertTrue, assertFalse, assertNull, * assertNotNull. Groovy 1.7 ships with a feature called the "power assert", which is an assert statement with * better error reporting. This is preferable to the JUnit assertions. * * @author Hamlet D'Arcy */ class JUnitStyleAssertionsRule extends AbstractAstVisitorRule { String name = 'JUnitStyleAssertions' int priority = 3 Class astVisitorClass = JUnitStyleAssertionsAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitStyleAssertionsAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { // TODO better suggestions def objects = ['Assert', 'this'] (1..2).each { if (AstUtil.isMethodCall(call, objects, ['assertTrue', 'assertFalse', 'assertNull', 'assertNotNull'], it)) { addViolation call, "Replace $call.methodAsString with an assert statement" } } (2..3).each { if (AstUtil.isMethodCall(call, objects, ['assertEquals'], it)) { addViolation call, "Replace $call.methodAsString with an assert statement" } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/UseAssertTrueInsteadOfNegationRule.groovy0000644000175000017500000000427212006632014032307 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.NotExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * In unit tests, if a condition is expected to be true then there is no sense using assertFalse with the negation operator. For instance, assertFalse(!condition) can always be simplified to assertTrue(condition) * * @author 'Hamlet D'Arcy' */ class UseAssertTrueInsteadOfNegationRule extends AbstractAstVisitorRule { String name = 'UseAssertTrueInsteadOfNegation' int priority = 2 Class astVisitorClass = UseAssertTrueInsteadOfNegationAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class UseAssertTrueInsteadOfNegationAstVisitor extends AbstractMethodCallExpressionVisitor { @SuppressWarnings('DuplicateLiteral') void visitMethodCallExpression(MethodCallExpression call) { List args = AstUtil.getMethodArguments(call) if (AstUtil.isMethodCall(call, ['this', 'Assert'], ['assertFalse'])) { if (args.size() < 3 && args.size() > 0) { def arg = args.last() if (arg instanceof NotExpression) { def left = call.objectExpression.text == 'this' ? '' : call.objectExpression.text + '.' def right = arg.expression.text addViolation call, "${left}assertFalse(!${right}) can be simplified to ${left}assertTrue($right)" } } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitPublicPropertyRule.groovy0000644000175000017500000000347012323246316030213 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.PropertyNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.WildcardPattern /** * Checks for public properties defined on JUnit test classes. There should typically be no need to * expose a public property on a test class. * * @author Chris Mair */ class JUnitPublicPropertyRule extends AbstractAstVisitorRule { String name = 'JUnitPublicProperty' int priority = 2 Class astVisitorClass = JUnitPublicPropertyAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES String ignorePropertyNames } class JUnitPublicPropertyAstVisitor extends AbstractAstVisitor { @Override void visitProperty(PropertyNode node) { if (!isIgnoredPropertyName(node)) { addViolation(node, "The test class $currentClassName contains a public property ${node.name}. There is usually no reason to have a public property (even a constant) on a test class.") } super.visitProperty(node) } private boolean isIgnoredPropertyName(PropertyNode node) { new WildcardPattern(rule.ignorePropertyNames, false).matches(node.name) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/ChainedTestRule.groovy0000644000175000017500000000324012006632016026436 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * A test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be atomic, and not be dependent on one another. * * @author Hamlet D'Arcy */ class ChainedTestRule extends AbstractAstVisitorRule { String name = 'ChainedTest' int priority = 2 Class astVisitorClass = ChainedTestAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class ChainedTestAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, 'this', 'test.*', 0)) { addViolation(call, "The test method $call.methodAsString() is being invoked explicitly from within a unit test. Tests should be isolated and not dependent on one another") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/UseAssertNullInsteadOfAssertEqualsRule.groovy0000644000175000017500000000375412006632012033154 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * This rule detects JUnit calling assertEquals where the first or second parameter is null. These assertion should be made against the assertNull method instead. * * @author Hamlet D'Arcy */ class UseAssertNullInsteadOfAssertEqualsRule extends AbstractAstVisitorRule { String name = 'UseAssertNullInsteadOfAssertEquals' int priority = 3 Class astVisitorClass = UseAssertNullInsteadOfAssertEqualsAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class UseAssertNullInsteadOfAssertEqualsAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { List args = AstUtil.getMethodArguments(call) if (AstUtil.isMethodCall(call, 'this', 'assertEquals')) { if (args.size() == 2 && (AstUtil.isNull(args[0]) || AstUtil.isNull(args[1]))) { addViolation call, 'assertEquals can be simplified using assertNull' } else if (args.size() == 3 && (AstUtil.isNull(args[1]) || AstUtil.isNull(args[2]))) { addViolation call, 'assertEquals can be simplified using assertNull' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitSetUpCallsSuperRule.groovy0000644000175000017500000000362412311373552030267 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * Rule that checks that if the JUnit setUp() method is defined, that it includes a call to * super.setUp(). *

* This rule sets the default value of applyToFilesMatching to only match source code file * paths ending in 'Test.groovy' or 'Tests.groovy'. * * @author Chris Mair * @author Hamlet D'Arcy */ class JUnitSetUpCallsSuperRule extends AbstractAstVisitorRule { String name = 'JUnitSetUpCallsSuper' int priority = 2 Class astVisitorClass = JUnitSetUpCallsSuperAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitSetUpCallsSuperAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode methodNode) { if (JUnitUtil.isSetUpMethod(methodNode)) { def statements = methodNode.code.statements def found = statements.find { stmt -> AstUtil.isMethodCall(stmt, 'super', 'setUp', 0) } if (!found) { addViolation(methodNode, 'The method setUp() does not call super.setUp()') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/UseAssertFalseInsteadOfNegationRule.groovy0000644000175000017500000000427312006632012032421 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.NotExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * In unit tests, if a condition is expected to be false then there is no sense using assertTrue with the negation operator. For instance, assertTrue(!condition) can always be simplified to assertFalse(condition) * * @author Hamlet D'Arcy */ class UseAssertFalseInsteadOfNegationRule extends AbstractAstVisitorRule { String name = 'UseAssertFalseInsteadOfNegation' int priority = 2 Class astVisitorClass = UseAssertFalseInsteadOfNegationAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class UseAssertFalseInsteadOfNegationAstVisitor extends AbstractMethodCallExpressionVisitor { @SuppressWarnings('DuplicateLiteral') void visitMethodCallExpression(MethodCallExpression call) { List args = AstUtil.getMethodArguments(call) if (AstUtil.isMethodCall(call, ['this', 'Assert'], ['assertTrue'])) { if (args.size() < 3 && args.size() > 0) { def arg = args.last() if (arg instanceof NotExpression) { def left = call.objectExpression.text == 'this' ? '' : call.objectExpression.text + '.' def right = arg.expression.text addViolation call, "${left}assertTrue(!${right}) can be simplified to ${left}assertFalse($right)" } } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/UseAssertTrueInsteadOfAssertEqualsRule.groovy0000644000175000017500000000654512467726544033213 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.AssertStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * This rule detects JUnit calling assertEquals where the first parameter is a boolean. These assertions * should be made by more specific methods, like assertTrue or assertFalse. * * If the checkAssertStatements property is true, then it also checks for assert statements, e.g. assert x == true. * * @author Hamlet D'Arcy */ class UseAssertTrueInsteadOfAssertEqualsRule extends AbstractAstVisitorRule { String name = 'UseAssertTrueInsteadOfAssertEquals' int priority = 3 String applyToClassNames = DEFAULT_TEST_CLASS_NAMES boolean checkAssertStatements = false Class astVisitorClass = UseAssertTrueInsteadOfAssertEqualsAstVisitor } class UseAssertTrueInsteadOfAssertEqualsAstVisitor extends AbstractAstVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { List args = AstUtil.getMethodArguments(call) if (AstUtil.isMethodCall(call, 'this', 'assertEquals')) { if (args.size() == 2 && (AstUtil.isBoolean(args[0]) || AstUtil.isBoolean(args[1]))) { addViolation call, 'assertEquals can be simplified using assertTrue or assertFalse' } else if (args.size() == 3 && (AstUtil.isBoolean(args[1]) || AstUtil.isBoolean(args[2]))) { addViolation call, 'assertEquals can be simplified using assertTrue or assertFalse' } } super.visitMethodCallExpression call } @Override void visitAssertStatement(AssertStatement statement) { if (rule.checkAssertStatements && AstUtil.isBinaryExpressionType(statement.booleanExpression.expression, '==')) { BinaryExpression exp = statement.booleanExpression.expression if (AstUtil.isTrue(exp.leftExpression)) { addViolation(statement, "The expression '$exp.text' can be simplified to '$exp.rightExpression.text'") } else if (AstUtil.isTrue(exp.rightExpression)) { addViolation(statement, "The expression '$exp.text' can be simplified to '$exp.leftExpression.text'") } else if (AstUtil.isFalse(exp.leftExpression)) { addViolation(statement, "The expression '$exp.text' can be simplified to '!$exp.rightExpression.text'") } else if (AstUtil.isFalse(exp.rightExpression)) { addViolation(statement, "The expression '$exp.text' can be simplified to '!$exp.leftExpression.text'") } } super.visitAssertStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitTearDownCallsSuperRule.groovy0000644000175000017500000000366212311373552030754 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * Rule that checks that if the JUnit tearDown() method is defined, that it includes a call to * super.tearDown(). *

* This rule sets the default value of applyToFilesMatching to only match source code file * paths ending in 'Test.groovy' or 'Tests.groovy'. * * @author Chris Mair * @author Hamlet D'Arcy */ class JUnitTearDownCallsSuperRule extends AbstractAstVisitorRule { String name = 'JUnitTearDownCallsSuper' int priority = 2 Class astVisitorClass = JUnitTearDownCallsSuperAstVisitor String applyToClassNames = DEFAULT_TEST_CLASS_NAMES } class JUnitTearDownCallsSuperAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode methodNode) { if (JUnitUtil.isTearDownMethod(methodNode)) { def statements = methodNode.code.statements def found = statements.find { stmt -> AstUtil.isMethodCall(stmt, 'super', 'tearDown', 0) } if (!found) { addViolation(methodNode, 'The method tearDown() does not call super.tearDown()') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/junit/JUnitUtil.groovy0000644000175000017500000001332212461316616025316 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.ListExpression import org.codehaus.groovy.ast.expr.MapExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codenarc.util.AstUtil /** * Utility methods for JUnit rule classes. This class is not intended for general use. * * @author Chris Mair */ class JUnitUtil { /** * Return true if the MethodCallExpression represents a JUnit assert method call with the specified * method name and constant argument value. This handles either single-argument assert calls or * 2-argument assert methods where the first parameter is the assertion message. * @param methodCall - the MethodCallExpression of the method call * @param methodName - the name of the method * @param value - the argument value */ protected static boolean isAssertCallWithConstantValue(MethodCallExpression methodCall, String methodName, Object value) { return isAssertCallWithValueMatching(methodCall, methodName) { v -> v == value } } protected static boolean isAssertCallWithNonNullConstantValue(MethodCallExpression methodCall, String methodName) { return isAssertCallWithValueMatching(methodCall, methodName) { v -> v != null } } private static boolean isAssertCallWithValueMatching(MethodCallExpression methodCall, String methodName, Closure closure) { def isMatch = false if (AstUtil.isMethodCall(methodCall, 'this', methodName)) { def args = methodCall.arguments.expressions def valueExpression = args.last() isMatch = args.size() in 1..2 && valueExpression instanceof ConstantExpression && closure(valueExpression.value) } isMatch } /** * Return true if the MethodCallExpression represents a JUnit assert method call with the specified * method name and constant argument value. This handles either single-argument assert calls or * 2-argument assert methods where the first parameter is the assertion message. * @param methodCall - the MethodCallExpression of the method call * @param methodName - the name of the method * @param literalEvaluatesToTrue - true if the argument value must evaluate to true using Groovy truth */ protected static boolean isAssertCallWithLiteralValue(MethodCallExpression methodCall, String methodName, boolean literalEvaluatesToTrue) { def isMatch = false if (AstUtil.isMethodCall(methodCall, 'this', methodName)) { def args = methodCall.arguments.expressions isMatch = args.size() in 1..2 && isLiteralWithValueThatEvaluatesTo(args.last(), literalEvaluatesToTrue) } isMatch } private static boolean isLiteralWithValueThatEvaluatesTo(Expression expression, boolean literalEvaluatesToTrue) { if (expression instanceof ConstantExpression) { def value = expression.properties['value'] return value != null && (value as boolean) == literalEvaluatesToTrue } if (expression instanceof ListExpression) { return expression.expressions.isEmpty() == !literalEvaluatesToTrue } if (expression instanceof MapExpression) { return expression.mapEntryExpressions.isEmpty() == !literalEvaluatesToTrue } } protected static boolean isSetUpMethod(MethodNode methodNode) { (methodNode.name == 'setUp' && methodNode.parameters.size() == 0 && !AstUtil.getAnnotation(methodNode, 'Before') && methodNode.code instanceof BlockStatement) } protected static boolean isTearDownMethod(MethodNode methodNode) { (methodNode.name == 'tearDown' && methodNode.parameters.size() == 0 && !AstUtil.getAnnotation(methodNode, 'After') && methodNode.code instanceof BlockStatement) } /** * Tells you if an ASTNode is a test MethodNode. A method node is a MethodNode and is named test.* or is annotated * with @Test or @org.junit.Test, * @param node * the node to analyze * @return * true if the node is a test method */ static boolean isTestMethod(ASTNode node) { if (!AstUtil.isPublic(node)) { return false } if (!(node instanceof MethodNode)) { return false } if (!node.isVoidMethod()) { return false } if (node.parameters?.length > 0) { return false } if (node.name?.startsWith('test')) { return true } node.properties['annotations']?.any { annotation -> def name = annotation?.properties['classNode']?.name name == 'Test' || name == 'org.junit.Test' } } /** * Private constructor. All members are static. */ private JUnitUtil() { } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/0000755000175000017500000000000012623571301023201 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchNullPointerExceptionRule.groovy0000644000175000017500000000211512006632014032366 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for catching a NullPointerException * * @author Chris Mair */ class CatchNullPointerExceptionRule extends AbstractAstVisitorRule { String name = 'CatchNullPointerException' int priority = 2 AstVisitor getAstVisitor() { new CommonCatchAstVisitor('NullPointerException') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchIndexOutOfBoundsExceptionRule.groovy0000644000175000017500000000214112006632012033307 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for catching a IndexOutOfBoundsException * * @author Chris Mair */ class CatchIndexOutOfBoundsExceptionRule extends AbstractAstVisitorRule { String name = 'CatchIndexOutOfBoundsException' int priority = 2 AstVisitor getAstVisitor() { new CommonCatchAstVisitor('IndexOutOfBoundsException') } } ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchArrayIndexOutOfBoundsExceptionRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchArrayIndexOutOfBoundsExceptionRule.g0000644000175000017500000000216512006632014033217 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for catching a ArrayIndexOutOfBoundsException * * @author Chris Mair */ class CatchArrayIndexOutOfBoundsExceptionRule extends AbstractAstVisitorRule { String name = 'CatchArrayIndexOutOfBoundsException' int priority = 2 AstVisitor getAstVisitor() { new CommonCatchAstVisitor('ArrayIndexOutOfBoundsException') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchErrorRule.groovy0000644000175000017500000000202112006632016027323 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for catching a Error * * @author Chris Mair */ class CatchErrorRule extends AbstractAstVisitorRule { String name = 'CatchError' int priority = 2 AstVisitor getAstVisitor() { new CommonCatchAstVisitor('Error') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ThrowNullPointerExceptionRule.groovy0000644000175000017500000000220712311373552032461 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for throwing an instance of java.lang.NullPointerException * * @author Chris Mair */ class ThrowNullPointerExceptionRule extends AbstractAstVisitorRule { String name = 'ThrowNullPointerException' int priority = 2 AstVisitor getAstVisitor() { new CommonThrowAstVisitor(['NullPointerException', 'java.lang.NullPointerException']) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ExceptionExtendsThrowableRule.groovy0000644000175000017500000000306412316050647032450 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.exceptions import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codenarc.util.AstUtil /** * Checks for classes that extend Throwable. Custom exception classes should subclass Exception or one of its descendants. * * @author Chris Mair */ class ExceptionExtendsThrowableRule extends AbstractAstVisitorRule { String name = 'ExceptionExtendsThrowable' int priority = 2 Class astVisitorClass = ExceptionExtendsThrowableAstVisitor } class ExceptionExtendsThrowableAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { if (AstUtil.classNodeImplementsType(node, Throwable)) { addViolation(node, "The class $node.name extends Throwable. Custom exception classes should subclass Exception or one of its descendants.") } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ConfusingClassNamedExceptionRule.groovy0000644000175000017500000000314712006632012033042 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * This rule traps classes named exception that do not inherit from exception. * * @author Hamlet D'Arcy */ class ConfusingClassNamedExceptionRule extends AbstractAstVisitorRule { String name = 'ConfusingClassNamedException' int priority = 2 Class astVisitorClass = ConfusingClassNamedExceptionAstVisitor } class ConfusingClassNamedExceptionAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode node) { if (node.name.endsWith('Exception') && !AstUtil.classNodeImplementsType(node, Exception)) { if (!(node.superClass.name == 'Throwable') && !node.superClass.name.endsWith('Exception')) { addViolation node, "Found a class named $node.name that does not extend Exception." } } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ReturnNullFromCatchBlockRule.groovy0000644000175000017500000000457312410141717032163 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.CatchStatement import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Returning null from a catch block often masks errors and requires the client to handle error codes. * In some coding styles this is discouraged. This rule ignores methods with void return type. * * @author Hamlet D'Arcy * @author Chris Mair */ class ReturnNullFromCatchBlockRule extends AbstractAstVisitorRule { String name = 'ReturnNullFromCatchBlock' int priority = 2 Class astVisitorClass = ReturnNullFromCatchBlockAstVisitor } class ReturnNullFromCatchBlockAstVisitor extends AbstractAstVisitor { @Override protected boolean shouldVisitMethod(MethodNode node) { // Ignore void methods return node.returnType.toString() != 'void' } void visitCatchStatement(CatchStatement node) { def lastStatement = getLastStatement(node) if (lastStatement instanceof ReturnStatement) { if (AstUtil.isNull(lastStatement.expression)) { addViolation lastStatement, 'Do not return null from a catch block' } } super.visitCatchStatement node } /** * This is not a good general function for AstUtils. * It is too specific and may not work across different ASTNode subtypes. * @param node * node */ private static getLastStatement(node) { if (node.code instanceof BlockStatement && node.code.statements) { return node.code.statements.last() } null } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CommonThrowAstVisitor.groovy0000644000175000017500000000362712311373552030766 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.stmt.ThrowStatement import org.codenarc.rule.AbstractAstVisitor /** * AstVisitor implementation that checks for throwing one of the exception type names specified in the constructor *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class CommonThrowAstVisitor extends AbstractAstVisitor { private final List exceptionTypeNames /** * Construct a new instance, specifying the exception type names * @param exceptionTypeNames - the names of the exception class; typically including class name * with and without package */ CommonThrowAstVisitor(List exceptionTypeNames) { this.exceptionTypeNames = exceptionTypeNames } void visitThrowStatement(ThrowStatement throwStatement) { def throwExpression = throwStatement.expression if (isFirstVisit(throwStatement) && throwExpression instanceof ConstructorCallExpression && throwExpression.type.name in exceptionTypeNames) { addViolation(throwStatement, "The type $throwExpression.type.name should not be thrown") } super.visitThrowStatement(throwStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ThrowErrorRule.groovy0000644000175000017500000000207412311373552027422 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for throwing an instance of java.lang.Error * * @author Chris Mair */ class ThrowErrorRule extends AbstractAstVisitorRule { String name = 'ThrowError' int priority = 2 AstVisitor getAstVisitor() { new CommonThrowAstVisitor(['Error', 'java.lang.Error']) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ExceptionExtendsErrorRule.groovy0000644000175000017500000000267712322751146031622 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Errors are system exceptions. Do not extend them. * * @author Hamlet D'Arcy */ class ExceptionExtendsErrorRule extends AbstractAstVisitorRule { String name = 'ExceptionExtendsError' int priority = 2 Class astVisitorClass = ExceptionExtendsErrorAstVisitor } class ExceptionExtendsErrorAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { if (AstUtil.classNodeImplementsType(node, Error)) { addViolation(node, "The class $node.name extends Error, which is meant to be used only as a system exception") } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ThrowExceptionRule.groovy0000644000175000017500000000212012311373552030257 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for throwing an instance of java.lang.Exception * * @author Chris Mair */ class ThrowExceptionRule extends AbstractAstVisitorRule { String name = 'ThrowException' int priority = 2 AstVisitor getAstVisitor() { new CommonThrowAstVisitor(['Exception', 'java.lang.Exception']) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/MissingNewInThrowStatementRule.groovy0000644000175000017500000000560512047331630032570 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.ThrowStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * A common Groovy mistake when throwing exceptions is to forget the new keyword. For instance, "throw RuntimeException()" * instead of "throw new RuntimeException()". If the error path is not unit tested then the production system will throw * a Method Missing exception and hide the root cause. This rule finds constructs like "throw RuntimeException()" that * look like a new keyword was meant to be used but forgotten. * * @author Hamlet D'Arcy */ class MissingNewInThrowStatementRule extends AbstractAstVisitorRule { String name = 'MissingNewInThrowStatement' int priority = 2 Class astVisitorClass = MissingNewInThrowStatementAstVisitor } class MissingNewInThrowStatementAstVisitor extends AbstractAstVisitor { @Override void visitThrowStatement(ThrowStatement statement) { if (statement.expression instanceof MethodCallExpression) { String name = statement?.expression?.method?.properties['value'] if (looksLikeAnExceptionType(name)) { addViolation (statement, "The throw statement appears to be throwing the class literal $name instead of a new instance") } } else if (statement.expression instanceof VariableExpression) { String name = statement.expression.variable if (looksLikeAnExceptionType(name)) { addViolation (statement, "The throw statement appears to be throwing the class literal $name instead of a new instance") } } super.visitThrowStatement(statement) } private static boolean looksLikeAnExceptionType(String name) { if (isFirstLetterUpperCase(name)) { if (name.endsWith('Exception') || name.endsWith('Failure') || name.endsWith('Fault')) { return true } } false } private static boolean isFirstLetterUpperCase(String name) { return name && (name[0] as Character).isUpperCase() } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ThrowRuntimeExceptionRule.groovy0000644000175000017500000000216312311373552031632 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for throwing an instance of java.lang.RuntimeException * * @author Chris Mair */ class ThrowRuntimeExceptionRule extends AbstractAstVisitorRule { String name = 'ThrowRuntimeException' int priority = 2 AstVisitor getAstVisitor() { new CommonThrowAstVisitor(['RuntimeException', 'java.lang.RuntimeException']) } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchIllegalMonitorStateExceptionRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchIllegalMonitorStateExceptionRule.gro0000644000175000017500000000212212006632014033275 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule to trap when IllegalMonitorStateException is being caught. * * @author Hamlet D'Arcy */ class CatchIllegalMonitorStateExceptionRule extends AbstractAstVisitorRule { String name = 'CatchIllegalMonitorStateException' int priority = 2 AstVisitor getAstVisitor() { new CommonCatchAstVisitor('IllegalMonitorStateException') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ExceptionNotThrownRule.groovy0000644000175000017500000000453012060741510031117 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codehaus.groovy.ast.stmt.CatchStatement import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.stmt.Statement import org.codehaus.groovy.ast.stmt.ExpressionStatement /** * Checks for an exception constructor call as the last statement within a catch block. * * @author Chris Mair */ class ExceptionNotThrownRule extends AbstractAstVisitorRule { String name = 'ExceptionNotThrown' int priority = 2 Class astVisitorClass = ExceptionNotThrownAstVisitor } class ExceptionNotThrownAstVisitor extends AbstractAstVisitor { @Override void visitCatchStatement(CatchStatement statement) { def lastStatement = getLastStatement(statement.code) if (isLastStatementAnExceptionConstructorCall(lastStatement)) { def typeName = lastStatement.expression.type.name addViolation(lastStatement, "The catch statement within class $currentClassName constructs a [$typeName] but does not throw it") } super.visitCatchStatement(statement) } private Statement getLastStatement(BlockStatement block) { return block.statements.size() > 0 ? block.statements[-1] : null } private boolean isLastStatementAnExceptionConstructorCall(Statement lastStatement) { return lastStatement && lastStatement instanceof ExpressionStatement && lastStatement.expression instanceof ConstructorCallExpression && lastStatement.expression.type.name.endsWith('Exception') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchRuntimeExceptionRule.groovy0000644000175000017500000000207512006632014031543 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for catching a RuntimeException * * @author Chris Mair */ class CatchRuntimeExceptionRule extends AbstractAstVisitorRule { String name = 'CatchRuntimeException' int priority = 2 AstVisitor getAstVisitor() { new CommonCatchAstVisitor('RuntimeException') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchThrowableRule.groovy0000644000175000017500000000204112006632014030161 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for catching a Throwable * * @author Chris Mair */ class CatchThrowableRule extends AbstractAstVisitorRule { String name = 'CatchThrowable' int priority = 2 AstVisitor getAstVisitor() { new CommonCatchAstVisitor('Throwable') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/SwallowThreadDeathRule.groovy0000644000175000017500000000521612311370173031030 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.exceptions import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.CatchStatement import org.codehaus.groovy.ast.stmt.ThrowStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Detects code that catches java.lang.ThreadDeath without re-throwing it. If ThreadDeath is caught by a method, it is important that it be rethrown so that the thread actually dies. * * @author Rob Fletcher * @author Klaus Baumecker */ class SwallowThreadDeathRule extends AbstractAstVisitorRule { String name = 'SwallowThreadDeath' int priority = 2 Class astVisitorClass = SwallowThreadDeathAstVisitor } class SwallowThreadDeathAstVisitor extends AbstractAstVisitor { private boolean withinCatchThreadDeath = false private String caughtVariableName = null private boolean foundThrow = false @Override void visitCatchStatement(CatchStatement statement) { if (statement.exceptionType.name == ThreadDeath.simpleName) { withinCatchThreadDeath = true foundThrow = false caughtVariableName = statement.variable.name super.visitCatchStatement(statement) withinCatchThreadDeath = false if (!foundThrow) { addViolation statement, 'ThreadDeath caught without being re-thrown. If ThreadDeath is caught by a method, it is important that it be rethrown so that the thread actually dies.' } } } @Override void visitThrowStatement(ThrowStatement statement) { if (withinCatchThreadDeath) { def expression = statement.expression if (expression instanceof VariableExpression && expression.name == caughtVariableName) { foundThrow = true } else if (expression instanceof ConstructorCallExpression && expression.type.name == ThreadDeath.simpleName) { foundThrow = true } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CommonCatchAstVisitor.groovy0000644000175000017500000000340512311373552030677 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codehaus.groovy.ast.stmt.CatchStatement import org.codenarc.rule.AbstractAstVisitor /** * AstVisitor implementation that checks for catching an exception type specified in the constructor *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class CommonCatchAstVisitor extends AbstractAstVisitor { private final exceptionClassNameWithoutPackage /** * Construct a new instance, specifying the exception class name * @param exceptionClassNameWithoutPackage - the name of the exception class to check for, without the package */ CommonCatchAstVisitor(String exceptionClassNameWithoutPackage) { this.exceptionClassNameWithoutPackage = exceptionClassNameWithoutPackage } void visitCatchStatement(CatchStatement catchStatement) { if (isFirstVisit(catchStatement) && catchStatement.exceptionType.nameWithoutPackage == exceptionClassNameWithoutPackage) { addViolation(catchStatement, "The type $exceptionClassNameWithoutPackage should not be caught") } super.visitCatchStatement(catchStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/CatchExceptionRule.groovy0000644000175000017500000000204112006632016030172 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for catching a Exception * * @author Chris Mair */ class CatchExceptionRule extends AbstractAstVisitorRule { String name = 'CatchException' int priority = 2 AstVisitor getAstVisitor() { new CommonCatchAstVisitor('Exception') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/exceptions/ThrowThrowableRule.groovy0000644000175000017500000000212012311373552030250 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Rule that checks for throwing an instance of java.lang.Throwable * * @author Chris Mair */ class ThrowThrowableRule extends AbstractAstVisitorRule { String name = 'ThrowThrowable' int priority = 2 AstVisitor getAstVisitor() { new CommonThrowAstVisitor(['Throwable', 'java.lang.Throwable']) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/NullReturnTracker.groovy0000644000175000017500000000447212407310774025731 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.TernaryExpression import org.codehaus.groovy.ast.stmt.ReturnStatement /** * Helper AST visitor that adds rule violation if a return statement is encountered that returns a null constant. * * @author Hamlet D'Arcy */ class NullReturnTracker extends AbstractAstVisitor { // NOTE: The provided parent must be a subclass of AbstractAstVisitor and // implement the void handleClosure(ClosureExpression expression) method def parent def errorMessage void visitReturnStatement(ReturnStatement statement) { def expression = statement.expression if (expressionReturnsNull(expression)) { parent.addViolation(statement, errorMessage) } super.visitReturnStatement(statement) } private expressionReturnsNull(Expression expression) { def stack = [expression] as Stack // alternative to recursion while (stack) { def expr = stack.pop() if (expr == ConstantExpression.NULL) { return true } else if (expr instanceof ConstantExpression && expr.value == null) { return true } else if (expr instanceof TernaryExpression) { stack.push(expr.trueExpression) stack.push(expr.falseExpression) } } false } void visitClosureExpression(ClosureExpression expression) { parent.handleClosure(expression) // do not keep walking, let the parent start a new walk for this new scope } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/0000755000175000017500000000000012623571301022301 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsMassAssignmentRule.groovy0000644000175000017500000000545512275777054030527 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.grails import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codehaus.groovy.ast.expr.PropertyExpression import org.codehaus.groovy.ast.expr.AttributeExpression import org.codehaus.groovy.ast.expr.VariableExpression /** * Untrusted input should not be allowed to set arbitrary object fields without restriction. * * TODO: Switch from name-based detection to type based detection when Grails domain object interfaces are detectable * @author Brian Soby */ class GrailsMassAssignmentRule extends AbstractAstVisitorRule { String name = 'GrailsMassAssignment' int priority = 2 Class astVisitorClass = GrailsMassAssignmentAstVisitor } @SuppressWarnings('NestedBlockDepth') class GrailsMassAssignmentAstVisitor extends AbstractAstVisitor { @Override void visitConstructorCallExpression(ConstructorCallExpression call) { if (isFirstVisit(call)) { if (call.arguments && call.arguments.expressions) { def exp = call.arguments.expressions.first() if (exp instanceof VariableExpression) { if (exp.variable == 'params') { addViolation(call, 'Restrict mass attribute assignment') } } } } super.visitConstructorCallExpression(call) } @Override void visitBinaryExpression(BinaryExpression expression) { if (isFirstVisit(expression)) { if (expression.leftExpression instanceof PropertyExpression && !(expression.leftExpression instanceof AttributeExpression) ) { if (expression.leftExpression.property.hasProperty('value') && expression.leftExpression.property.value == 'properties') { if (expression.rightExpression instanceof VariableExpression && expression.rightExpression.variable == 'params') { addViolation(expression, 'Restrict mass attribute assignment') } } } } super.visitBinaryExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsServletContextReferenceRule.groovy0000644000175000017500000000527312465006116032362 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.grails import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that checks for references to the servletContext object from within Grails controller and * taglib classes. *

* This rule is intended as a "governance" rule to enable monitoring and controlling access to the * servletContext from within application source code. Storing objects in the servletContext may * inhibit scalability and/or performance and should be carefully considered. Furthermore, access * to the servletContext is not synchronized, so reading/writing objects from the servletConext must * be manually synchronized, as described in The Definitive Guide to Grails (2nd edition). *

* Enabling this rule may make most sense in a team environment where team members exhibit a broad * range of skill and experience levels. Appropriate servletContext access can be configured as * exceptions to this rule by configuring either the doNotApplyToFilenames or * doNotApplyToFilesMatching property of the rule. *

* This rule sets the default value of applyToFilesMatching to only match files * under the 'grails-app/controllers' or 'grails-app/taglib' folders. You can override this * with a different regular expression value if appropriate. * * @author Chris Mair */ class GrailsServletContextReferenceRule extends AbstractAstVisitorRule { String name = 'GrailsServletContextReference' int priority = 2 Class astVisitorClass = GrailsServletContextReferenceAstVisitor String applyToFilesMatching = GrailsUtil.CONTROLLERS_AND_TAGLIB_FILES } class GrailsServletContextReferenceAstVisitor extends AbstractAstVisitor { void visitVariableExpression(VariableExpression expression) { if (isFirstVisit(expression) && expression.variable == 'servletContext') { addViolation(expression, 'Storing objects in the servletContext can limit scalability') } super.visitVariableExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsDomainReservedSqlKeywordNameRule.groovy0000644000175000017500000002166112311373552033307 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.ListExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Forbids usage of SQL reserved keywords as class or field names in Grails domain classes. * Naming a domain class (or its field) with such a keyword causes SQL schema creation errors and/or redundant * table/column name mappings.
* * Note: due to limited type information available during CodeNarc's operation, this rule will report fields * of type {@link java.io.Serializable}, but not of its implementations. Please specify any implementations * used as domain properties in {@code #additionalHibernateBasicTypes}. * * @author Artur Gajowy */ class GrailsDomainReservedSqlKeywordNameRule extends AbstractAstVisitorRule { String name = 'GrailsDomainReservedSqlKeywordName' int priority = 2 Class astVisitorClass = GrailsDomainReservedSqlKeywordNameAstVisitor String applyToFilesMatching = GrailsUtil.DOMAIN_FILES //based on http://developer.mimer.com/validator/sql-reserved-words.tml private final reservedSqlKeywords = ['ABSOLUTE', 'ACTION', 'ADD', 'AFTER', 'ALL', 'ALLOCATE', 'ALTER', 'AND', 'ANY', 'ARE', 'ARRAY', 'AS', 'ASC', 'ASENSITIVE', 'ASSERTION', 'ASYMMETRIC', 'AT', 'ATOMIC', 'AUTHORIZATION', 'AVG', 'BEFORE', 'BEGIN', 'BETWEEN', 'BIGINT', 'BINARY', 'BIT', 'BIT_LENGTH', 'BLOB', 'BOOLEAN', 'BOTH', 'BREADTH', 'BY', 'CALL', 'CALLED', 'CASCADE', 'CASCADED', 'CASE', 'CAST', 'CATALOG', 'CHAR', 'CHARACTER', 'CHARACTER_LENGTH', 'CHAR_LENGTH', 'CHECK', 'CLOB', 'CLOSE', 'COALESCE', 'COLLATE', 'COLLATION', 'COLUMN', 'COMMIT', 'CONDITION', 'CONNECT', 'CONNECTION', 'CONSTRAINT', 'CONSTRAINTS', 'CONSTRUCTOR', 'CONTAINS', 'CONTINUE', 'CONVERT', 'CORRESPONDING', 'COUNT', 'CREATE', 'CROSS', 'CUBE', 'CURRENT', 'CURRENT_DATE', 'CURRENT_DEFAULT_TRANSFORM_GROUP', 'CURRENT_PATH', 'CURRENT_ROLE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_TRANSFORM_GROUP_FOR_TYPE', 'CURRENT_USER', 'CURSOR', 'CYCLE', 'DATA', 'DATE', 'DAY', 'DEALLOCATE', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DEFERRABLE', 'DEFERRED', 'DELETE', 'DEPTH', 'DEREF', 'DESC', 'DESCRIBE', 'DESCRIPTOR', 'DETERMINISTIC', 'DIAGNOSTICS', 'DISCONNECT', 'DISTINCT', 'DO', 'DOMAIN', 'DOUBLE', 'DROP', 'DYNAMIC', 'EACH', 'ELEMENT', 'ELSE', 'ELSEIF', 'END', 'EQUALS', 'ESCAPE', 'EXCEPT', 'EXCEPTION', 'EXEC', 'EXECUTE', 'EXISTS', 'EXIT', 'EXTERNAL', 'EXTRACT', 'FALSE', 'FETCH', 'FILTER', 'FIRST', 'FLOAT', 'FOR', 'FOREIGN', 'FOUND', 'FREE', 'FROM', 'FULL', 'FUNCTION', 'GENERAL', 'GET', 'GLOBAL', 'GO', 'GOTO', 'GRANT', 'GROUP', 'GROUPING', 'HANDLER', 'HAVING', 'HOLD', 'HOUR', 'IDENTITY', 'IF', 'IMMEDIATE', 'IN', 'INDICATOR', 'INITIALLY', 'INNER', 'INOUT', 'INPUT', 'INSENSITIVE', 'INSERT', 'INT', 'INTEGER', 'INTERSECT', 'INTERVAL', 'INTO', 'IS', 'ISOLATION', 'ITERATE', 'JOIN', 'KEY', 'LANGUAGE', 'LARGE', 'LAST', 'LATERAL', 'LEADING', 'LEAVE', 'LEFT', 'LEVEL', 'LIKE', 'LOCAL', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCATOR', 'LOOP', 'LOWER', 'MAP', 'MATCH', 'MAX', 'MEMBER', 'MERGE', 'METHOD', 'MIN', 'MINUTE', 'MODIFIES', 'MODULE', 'MONTH', 'MULTISET', 'NAMES', 'NATIONAL', 'NATURAL', 'NCHAR', 'NCLOB', 'NEW', 'NEXT', 'NO', 'NONE', 'NOT', 'NULL', 'NULLIF', 'NUMERIC', 'OBJECT', 'OCTET_LENGTH', 'OF', 'OLD', 'ON', 'ONLY', 'OPEN', 'OPTION', 'OR', 'ORDER', 'ORDINALITY', 'OUT', 'OUTER', 'OUTPUT', 'OVER', 'OVERLAPS', 'PAD', 'PARAMETER', 'PARTIAL', 'PARTITION', 'PATH', 'POSITION', 'PRECISION', 'PREPARE', 'PRESERVE', 'PRIMARY', 'PRIOR', 'PRIVILEGES', 'PROCEDURE', 'PUBLIC', 'RANGE', 'READ', 'READS', 'REAL', 'RECURSIVE', 'REF', 'REFERENCES', 'REFERENCING', 'RELATIVE', 'RELEASE', 'REPEAT', 'RESIGNAL', 'RESTRICT', 'RESULT', 'RETURN', 'RETURNS', 'REVOKE', 'RIGHT', 'ROLE', 'ROLLBACK', 'ROLLUP', 'ROUTINE', 'ROW', 'ROWS', 'SAVEPOINT', 'SCHEMA', 'SCOPE', 'SCROLL', 'SEARCH', 'SECOND', 'SECTION', 'SELECT', 'SENSITIVE', 'SESSION', 'SESSION_USER', 'SET', 'SETS', 'SIGNAL', 'SIMILAR', 'SIZE', 'SMALLINT', 'SOME', 'SPACE', 'SPECIFIC', 'SPECIFICTYPE', 'SQL', 'SQLCODE', 'SQLERROR', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'START', 'STATE', 'STATIC', 'SUBMULTISET', 'SUBSTRING', 'SUM', 'SYMMETRIC', 'SYSTEM', 'SYSTEM_USER', 'TABLE', 'TABLESAMPLE', 'TEMPORARY', 'THEN', 'TIME', 'TIMESTAMP', 'TIMEZONE_HOUR', 'TIMEZONE_MINUTE', 'TO', 'TRAILING', 'TRANSACTION', 'TRANSLATE', 'TRANSLATION', 'TREAT', 'TRIGGER', 'TRIM', 'TRUE', 'UNDER', 'UNDO', 'UNION', 'UNIQUE', 'UNKNOWN', 'UNNEST', 'UNTIL', 'UPDATE', 'UPPER', 'USAGE', 'USER', 'USING', 'VALUE', 'VALUES', 'VARCHAR', 'VARYING', 'VIEW', 'WHEN', 'WHENEVER', 'WHERE', 'WHILE', 'WINDOW', 'WITH', 'WITHIN', 'WITHOUT', 'WORK', 'WRITE', 'YEAR', 'ZONE' ] as Set //based on http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/types.html#types-value-basic private final hibernateBasicTypes = ['String', 'Character', 'boolean', 'Boolean', 'byte', 'Byte', 'short', 'Short', 'int', 'Integer', 'long', 'Long', 'float', 'Float', 'double', 'Double', 'BigInteger', 'BigDecimal', 'Timestamp', 'Time', 'Date', 'Calendar', 'Currency', 'Locale', 'TimeZone', 'URL', 'Class', 'Blob', 'Clob', '[B', 'Byte[]', '[C', 'Character[]', 'UUID', 'Serializable' ] as Set String additionalReservedSqlKeywords = '' String additionalHibernateBasicTypes = '' @Override AstVisitor getAstVisitor() { return new GrailsDomainReservedSqlKeywordNameAstVisitor( reservedSqlKeywords + toSet(additionalReservedSqlKeywords), hibernateBasicTypes + toSet(additionalHibernateBasicTypes) ) } private Set toSet(String listInString) { listInString.split(/,\s*/).findAll { !it.isEmpty() } as Set } } class GrailsDomainReservedSqlKeywordNameAstVisitor extends AbstractAstVisitor { private final reservedSqlKeywords private final hibernateBasicTypes private final instanceFields = [] private transients = [] GrailsDomainReservedSqlKeywordNameAstVisitor(Set reservedSqlKeywords, Set hibernateBasicTypes) { this.reservedSqlKeywords = reservedSqlKeywords*.toUpperCase() this.hibernateBasicTypes = hibernateBasicTypes } @Override protected void visitClassEx(ClassNode node) { if (node.name.toUpperCase() in reservedSqlKeywords) { addViolation(node, violationMessage(node.name, 'domain class name')) } } @Override protected void visitClassComplete(ClassNode node) { addViolationsForInstanceFields() } @Override void visitField(FieldNode node) { if (node.inStaticContext) { if (node.name == 'transients') { extractTransients(node) } } else { instanceFields << node } } @SuppressWarnings('EmptyCatchBlock') private void extractTransients(FieldNode transientsNode) { try { assert transientsNode.initialExpression instanceof ListExpression def listExpression = transientsNode.initialExpression as ListExpression assert listExpression.expressions.every { it instanceof ConstantExpression } def expressions = listExpression.expressions as List assert expressions.every { it.type.name == String.name } transients = expressions*.value } catch (AssertionError e) { } } private addViolationsForInstanceFields() { instanceFields.each { FieldNode field -> if (hibernateWouldCreateColumnFor(field) && field.name.toUpperCase() in reservedSqlKeywords) { addViolation(field, violationMessage(field.name, 'domain class\' field name')) } } } private boolean hibernateWouldCreateColumnFor(FieldNode field) { !(field.dynamicTyped || field.name in transients) && field.type.name in hibernateBasicTypes } private String violationMessage(String identifier, String kindOfName) { "'$identifier' is a reserved SQL keyword and - as such - a problematic $kindOfName." } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsPublicControllerMethodRule.groovy0000644000175000017500000000650212311373552032172 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.grails import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.WildcardPattern import java.lang.reflect.Modifier /** * Rule that checks for public methods on Grails controller classes. Static methods are ignored. *

* NOTE: This rule is DISABLED by default (i.e., by setting its enabled property to false). * Given that Grails 2.x allows and encourages controller actions to be defined as methods instead of closures, * this rule makes no more sense (for Grails 2.x projects). *

* Grails controller actions and interceptors are defined as properties on the controller class. * Public methods on a controller class are unnecessary. They break encapsulation and can * be confusing. *

* The ignoreMethodNames property optionally specifies one or more * (comma-separated) method names that should be ignored (i.e., that should not cause a * rule violation). The name(s) may optionally include wildcard characters ('*' or '?'). *

* This rule sets the default value of applyToFilesMatching to only match files * under the 'grails-app/controllers' folder. You can override this with a different regular * expression value if appropriate. *

* This rule also sets the default value of applyToClassNames to only match class * names ending in 'Controller'. You can override this with a different class name pattern * (String) if appropriate. * * @author Chris Mair * @author Hamlet D'Arcy */ class GrailsPublicControllerMethodRule extends AbstractAstVisitorRule { String name = 'GrailsPublicControllerMethod' int priority = 2 String ignoreMethodNames Class astVisitorClass = GrailsPublicControllerMethodAstVisitor String applyToFilesMatching = GrailsUtil.CONTROLLERS_FILES String applyToClassNames = GrailsUtil.CONTROLLERS_CLASSES GrailsPublicControllerMethodRule() { this.enabled = false // disabled by default } } class GrailsPublicControllerMethodAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode methodNode) { if (Modifier.isPublic(methodNode.modifiers) && !(methodNode.modifiers & MethodNode.ACC_STATIC) && !isIgnoredMethodName(methodNode)) { addViolation(methodNode, "The Grails controller has a public method $methodNode.name. This should be a closure property or moved") } } private boolean isIgnoredMethodName(MethodNode node) { new WildcardPattern(rule.ignoreMethodNames, false).matches(node.name) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsUtil.groovy0000644000175000017500000000254412311373552025636 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.grails /** * Utility methods and constants for Grails rule classes. This class is not intended for general use. * * @author Chris Mair */ class GrailsUtil { protected static final SERVICE_FILES = /.*grails-app\/services\/.*/ protected static final DOMAIN_FILES = /.*grails-app\/domain\/.*/ protected static final CONTROLLERS_FILES = /.*grails-app\/controllers\/.*/ protected static final CONTROLLERS_AND_TAGLIB_FILES = /.*grails-app\/(controllers|taglib)\/.*/ protected static final CONTROLLERS_CLASSES = '*Controller' protected static final SERVICE_CLASSES = '*Service' /** * Private constructor. All members are static. */ private GrailsUtil() { } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsStatelessServiceRule.groovy0000644000175000017500000001061012311370173031026 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.grails import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.generic.StatelessClassRule /** * Rule that checks for non-final fields on a Grails service class. Grails service * classes are, by default, singletons, and so they should be reentrant. In most cases, this implies * (or at least encourages) that they should be stateless. *

* This rule ignores final fields (either instance or static). Fields that are * static and non-final, however, do cause a violation. *

* This rule ignores non-static properties (i.e., no visibility modifier specified) declared with "def". *

* This rule also ignores fields annotated with the @Inject annotation. *

* You can configure this rule to ignore certain fields either by name or by type. This can be * useful to ignore fields that hold references to (static) dependencies (such as DAOs or * Service objects) or static configuration. *

* The ignoreFieldNames property specifies one or more (comma-separated) field names * that should be ignored (i.e., that should not cause a rule violation). The name(s) may optionally * include wildcard characters ('*' or '?'). You can add to the field names to be ignored by setting * the (write-only) addIgnoreFieldNames property. This is a "special" property -- each * call to setAddIgnoreFieldNames() adds to the existing ignoreFieldNames * property value. *

* The ignoreFieldTypes property specifies one or more (comma-separated) field type names * that should be ignored (i.e., that should not cause a rule violation). The type name(s) may optionally * include wildcard characters ('*' or '?'). *

* Note: The ignoreFieldTypes property matches the field type name as indicated * in the field declaration, only including a full package specification IF it is included in * the source code. For example, the field declaration BigDecimal value matches * an ignoreFieldTypes value of BigDecimal, but not * java.lang.BigDecimal. *

* There is one exception for the ignoreFieldTypes property: if the field is declared * with a modifier/type of def, then the type resolves to java.lang.Object. *

* The ignoreFieldNames property of this rule is preconfigured to ignore the standard * Grails service configuration field names ('scope', 'transactional') and injected bean names * ('dataSource', 'sessionFactory'), as well as all other field names ending with 'Service'. *

* This rule sets the default value of applyToFilesMatching to only match files * under the 'grails-app/services' folder. You can override this with a different regular * expression value if appropriate. *

* This rule also sets the default value of applyToClassNames to only match class * names ending in 'Service'. You can override this with a different class name pattern * (String) if appropriate. * * @author Chris Mair */ class GrailsStatelessServiceRule extends StatelessClassRule { String name = 'GrailsStatelessService' int priority = 2 String applyToFilesMatching = GrailsUtil.SERVICE_FILES String applyToClassNames = GrailsUtil.SERVICE_CLASSES GrailsStatelessServiceRule() { ignoreFieldNames = 'dataSource,scope,sessionFactory,transactional,*Service' } @Override protected boolean shouldIgnoreField(FieldNode fieldNode) { return super.shouldIgnoreField(fieldNode) || fieldNode.isDynamicTyped() && !fieldNode.static && fieldNode.synthetic } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsDuplicateConstraintRule.groovy0000644000175000017500000000640712414042204031521 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.expr.MethodCallExpression /** * Check for duplicate constraints entry * * @author Chris Mair */ class GrailsDuplicateConstraintRule extends AbstractAstVisitorRule { String name = 'GrailsDuplicateConstraint' int priority = 2 Class astVisitorClass = GrailsDuplicateConstraintAstVisitor String applyToFilesMatching = GrailsUtil.DOMAIN_FILES } class GrailsDuplicateConstraintAstVisitor extends AbstractAstVisitor { private final Set constraintNames = [] private boolean withinConstraint @Override void visitField(FieldNode node) { if (node.name == 'constraints') { withinConstraint = true super.visitField(node) withinConstraint = false } } @Override void visitMethodCallExpression(MethodCallExpression call) { if (withinConstraint && isFirstVisit(call)) { String methodName = call.methodAsString if (methodName == 'importFrom') { Collection importedConstraintNames = extractImportedConstraints(call.text) constraintNames.intersect(importedConstraintNames).each { addViolation(call, "The constraint for $it in domain class $currentClassName has already been specified") } constraintNames.addAll(importedConstraintNames) } else if (methodName in constraintNames) { addViolation(call, "The constraint for $methodName in domain class $currentClassName has already been specified") } else { constraintNames << methodName } } } /** * Extract the properties included in an importFrom constraint definition. So far this just handles included properties. * It doesn't currently support extracting all the properties from the given class, so no exclude: support either. * @param text - e.g. "this.importFrom([include:[firstName]], Entity)" * @return the collection of properties specifically included */ private static Collection extractImportedConstraints(String text) { Collection importedConstraintNames = [] if (text.indexOf('include:') > 0) { String collectionString = text[(text.lastIndexOf('[') + 1)..(text.indexOf(']') - 1)] importedConstraintNames = collectionString.split(',') } importedConstraintNames } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsSessionReferenceRule.groovy0000644000175000017500000000515112465006037031011 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.grails import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that checks for references to the session object from within Grails controller and * taglib classes. *

* This rule is intended as a "governance" rule to enable monitoring and controlling access to the * session from within application source code. Storing objects in the session may inhibit scalability * and/or performance and should be carefully considered. *

* Enabling this rule may make most sense in a team environment where team members exhibit a broad * range of skill and experience levels. Appropriate session access can be configured as exceptions * to this rule by configuring either the doNotApplyToFilenames or * doNotApplyToFilesMatching property of the rule. *

* This rule sets the default value of applyToFilesMatching to only match files * under the 'grails-app/controllers' or 'grails-app/taglib' folders. You can override this * with a different regular expression value if appropriate. * * @deprecated This rule is deprecated and disabled (enabled=false) by default * * @author Chris Mair */ class GrailsSessionReferenceRule extends AbstractAstVisitorRule { String name = 'GrailsSessionReference' int priority = 2 Class astVisitorClass = GrailsSessionReferenceAstVisitor String applyToFilesMatching = GrailsUtil.CONTROLLERS_AND_TAGLIB_FILES GrailsSessionReferenceRule() { this.enabled = false // deprecated; disabled by default } } class GrailsSessionReferenceAstVisitor extends AbstractAstVisitor { void visitVariableExpression(VariableExpression expression) { if (isFirstVisit(expression) && expression.variable == 'session') { addViolation(expression, 'Interacting with the Grails session object can limit scalability') } super.visitVariableExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsDomainWithServiceReferenceRule.groovy0000644000175000017500000000311112111536264032742 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.grails import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor /** * Checks that Grails Domain classes do not have Service classes injected. * * @author Artur Gajowy */ class GrailsDomainWithServiceReferenceRule extends AbstractAstVisitorRule { String name = 'GrailsDomainWithServiceReference' int priority = 2 Class astVisitorClass = GrailsDomainCantReferenceServiceAstVisitor String applyToFilesMatching = GrailsUtil.DOMAIN_FILES } class GrailsDomainCantReferenceServiceAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (node.name.endsWith('Service')) { def domainName = node.declaringClass.nameWithoutPackage addViolation(node, "Domain class $domainName should not reference services (offending field: ${node.name})") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsDuplicateMappingRule.groovy0000644000175000017500000000424112056540656031002 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.FieldNode /** * Check for duplicate entry in a domain class mapping * * @author Chris Mair */ class GrailsDuplicateMappingRule extends AbstractAstVisitorRule { String name = 'GrailsDuplicateMapping' int priority = 2 Class astVisitorClass = GrailsDuplicateMappingAstVisitor String applyToFilesMatching = GrailsUtil.DOMAIN_FILES } class GrailsDuplicateMappingAstVisitor extends AbstractAstVisitor { private final Set mappingNames = [] private boolean withinMapping @Override void visitField(FieldNode node) { if (node.name == 'mapping') { withinMapping = true super.visitField(node) withinMapping = false } } @Override void visitMethodCallExpression(MethodCallExpression call) { if (withinMapping && isFirstVisit(call)) { def name = call.methodAsString if (name in mappingNames) { addViolation(call, "The mapping for $name in domain class $currentClassName has already been specified") } else { mappingNames << name } // Process optional nested columns closure if (name == 'columns') { super.visitMethodCallExpression(call) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsDomainHasToStringRule.groovy0000644000175000017500000000346012041642132031075 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import static org.codenarc.util.AstUtil.hasAnnotation import static org.codenarc.util.AstUtil.isMethodNode import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Checks that Grails domain classes redefine toString() * * @author Geli Crick * @author Hamlet D'Arcy * @author Chris Mair */ class GrailsDomainHasToStringRule extends AbstractAstVisitorRule { String name = 'GrailsDomainHasToString' int priority = 2 Class astVisitorClass = GrailsDomainHasToStringAstVisitor String applyToFilesMatching = GrailsUtil.DOMAIN_FILES } class GrailsDomainHasToStringAstVisitor extends AbstractAstVisitor { void visitClassComplete(ClassNode classNode) { if (isFirstVisit(classNode) && !hasAnnotation(classNode, 'ToString') && !hasAnnotation(classNode, 'Canonical')) { if (!classNode.methods.any { isMethodNode(it, 'toString', 0) }) { addViolation(classNode, "The domain class $classNode.name should define a toString() method") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/grails/GrailsDomainHasEqualsRule.groovy0000644000175000017500000000346112275775574030611 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import static org.codenarc.util.AstUtil.hasAnnotation import static org.codenarc.util.AstUtil.isMethodNode import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Checks that Grails domain classes redefine equals(). * * @author Geli Crick * @author Hamlet D'Arcy * @author Chris Mair */ class GrailsDomainHasEqualsRule extends AbstractAstVisitorRule { String name = 'GrailsDomainHasEquals' int priority = 2 Class astVisitorClass = GrailsDomainHasEqualsAstVisitor String applyToFilesMatching = GrailsUtil.DOMAIN_FILES } class GrailsDomainHasEqualsAstVisitor extends AbstractAstVisitor { void visitClassComplete(ClassNode classNode) { if (isFirstVisit(classNode) && !hasAnnotation(classNode, 'EqualsAndHashCode') && !hasAnnotation(classNode, 'Canonical')) { if (!classNode.methods.any { isMethodNode(it, 'equals', 1) }) { addViolation(classNode, "The domain class $classNode.name should define an equals(Object) method") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/AstVisitor.groovy0000644000175000017500000000254612311373552024407 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule import org.codehaus.groovy.ast.GroovyClassVisitor import org.codenarc.source.SourceCode /** * Interface for Groovy AST Visitors used with Rules * * @author Chris Mair */ interface AstVisitor extends GroovyClassVisitor { /** * Set the Rule associated with this visitor * @param rule - the Rule */ void setRule(Rule rule) /** * Set the SourceCode associated with this visitor * @param sourceCode - the SourceCode */ void setSourceCode(SourceCode sourceCode) /** * Retrieve the List of Violations resulting from applying this visitor * @return the List of Violations; may be empty */ List getViolations() } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/StubRule.groovy0000644000175000017500000000204512311373552024037 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule import org.codenarc.source.SourceCode /** * Stub implementation of the Rule interface for testing * * @author Chris Mair */ class StubRule extends AbstractRule { int priority String name StubRule() { } StubRule(int priority) { this.priority = priority } @Override void applyTo(SourceCode sourceCode, List violations) { } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/0000755000175000017500000000000012623571301023202 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/VectorIsObsoleteRule.groovy0000644000175000017500000000253712006632014030535 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.ClassReferenceAstVisitor /** * Check for direct use of Vector or java.util.Vector. * * Known limitation: Does not catch references as Anonymous Inner class: def x = new java.util.Vector() { .. } * * @author Chris Mair */ class VectorIsObsoleteRule extends AbstractAstVisitorRule { String name = 'VectorIsObsolete' int priority = 2 @Override AstVisitor getAstVisitor() { new ClassReferenceAstVisitor('Vector, java.util.Vector', 'The {0} class is obsolete. Use classes from the Java Collections Framework instead, including ArrayList or Collections.synchronizedList().') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/IfStatementCouldBeTernaryRule.groovy0000644000175000017500000001074712311373552032342 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codehaus.groovy.ast.stmt.IfStatement import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codehaus.groovy.ast.ASTNode import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.GStringExpression /** * Checks for: * * (1) An if statements where both the if and else blocks contain only a single return statement with a constant or * literal value. * * (2) When the second-to-last statement in a block is an if statement with no else, where the block contains a single * return statement, and the last statement in the block is a return statement, and both return statements return a * constant or literal value. This checks can be disabled by setting checkLastStatementImplicitElse to false. * * @author Chris Mair */ class IfStatementCouldBeTernaryRule extends AbstractAstVisitorRule { String name = 'IfStatementCouldBeTernary' int priority = 2 Class astVisitorClass = IfStatementCouldBeTernaryAstVisitor boolean checkLastStatementImplicitElse = true } class IfStatementCouldBeTernaryAstVisitor extends AbstractAstVisitor { @Override void visitIfElse(IfStatement ifElse) { if (isFirstVisit(ifElse) && isOnlyReturnStatement(ifElse.ifBlock) && isOnlyReturnStatement(ifElse.elseBlock)) { def ternaryExpression = "return ${ifElse.booleanExpression.text} ? ${getReturnValue(ifElse.ifBlock)} : ${getReturnValue(ifElse.elseBlock)}" addViolation(ifElse, "The if statement in class $currentClassName can be rewritten using the ternary operator: $ternaryExpression") } super.visitIfElse(ifElse) } @Override void visitBlockStatement(BlockStatement block) { def allStatements = block.statements if (allStatements.size() > 1 && rule.checkLastStatementImplicitElse) { def nextToLastStatement = allStatements[-2] if (nextToLastStatement instanceof IfStatement && hasNoElseBlock(nextToLastStatement)) { def lastStatement = allStatements[-1] IfStatement ifStatement = nextToLastStatement if (isOnlyReturnStatement(ifStatement.ifBlock) && isReturnStatementWithConstantOrLiteralValue(lastStatement)) { def elseReturnExpression = AstUtil.createPrettyExpression(lastStatement.expression) def ternaryExpression = "return ${ifStatement.booleanExpression.text} ? ${getReturnValue(ifStatement.ifBlock)} : ${elseReturnExpression}" addViolation(ifStatement, "The if statement in class $currentClassName can be rewritten using the ternary operator: $ternaryExpression") } } } super.visitBlockStatement(block) } private boolean hasNoElseBlock(IfStatement ifStatement) { ifStatement.elseBlock.empty } private boolean isOnlyReturnStatement(ASTNode node) { isBlockWithSingleReturnStatement(node) || isReturnStatementWithConstantOrLiteralValue(node) } private boolean isBlockWithSingleReturnStatement(ASTNode node) { return node instanceof BlockStatement && node.statements.size() == 1 && isReturnStatementWithConstantOrLiteralValue(node.statements[0]) } private boolean isReturnStatementWithConstantOrLiteralValue(ASTNode node) { return node instanceof ReturnStatement && (AstUtil.isConstantOrLiteral(node.expression) || node.expression instanceof GStringExpression) } private String getReturnValue(ASTNode node) { def expr = node instanceof BlockStatement ? node.statements[0].expression : node.expression return AstUtil.createPrettyExpression(expr) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/HashtableIsObsoleteRule.groovy0000644000175000017500000000253712006632014031166 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.ClassReferenceAstVisitor /** * Check for direct use of Vector or java.util.Hashtable. * * Known limitation: Does not catch references as Anonymous Inner class: def x = new java.util.Vector() { .. } * * @author Chris Mair */ class HashtableIsObsoleteRule extends AbstractAstVisitorRule { String name = 'HashtableIsObsolete' int priority = 2 @Override AstVisitor getAstVisitor() { new ClassReferenceAstVisitor('Hashtable, java.util.Hashtable', 'The {0} class is obsolete. Use classes from the Java Collections Framework instead, including HashMap or ConcurrentHashMap.') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/InvertedIfElseRule.groovy0000644000175000017500000000443412141451554030160 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.convention import org.codehaus.groovy.ast.expr.NotExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.IfStatement import org.codehaus.groovy.ast.stmt.Statement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * An inverted if-else statement is one in which there is a single if statement with a single else branch and the * boolean test of the if is negated. For instance "if (!x) false else true". It is usually clearer to write this as * "if (x) true else false". * * @author Hamlet D'Arcy */ class InvertedIfElseRule extends AbstractAstVisitorRule { String name = 'InvertedIfElse' int priority = 3 Class astVisitorClass = InvertedIfElseAstVisitor } class InvertedIfElseAstVisitor extends AbstractAstVisitor { void visitIfElse(IfStatement ifElse) { if (ifElse.booleanExpression.expression instanceof NotExpression) { if (ifElse.elseBlock instanceof BlockStatement) { addViolation ifElse.booleanExpression, 'Testing the negative condition first can make an if statement confusing' } } dispatchToIfWithoutSuper ifElse } private void dispatchToIfWithoutSuper(IfStatement ifElse) { // no need to visit boolean expression // if block might have another instance of this error ifElse.ifBlock.visit(this) Statement elseBlock = ifElse.elseBlock if (elseBlock instanceof IfStatement) { // uh-oh found an if-elseif-else dispatchToIfWithoutSuper elseBlock } else { elseBlock.visit(this) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/TernaryCouldBeElvisRule.groovy0000644000175000017500000000452712311373552031200 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.expr.* /** * Rule that checks for ternary expressions where the boolean and true expressions are the same. * These can be simplified to an Elvis expression. * * @author Chris Mair */ class TernaryCouldBeElvisRule extends AbstractAstVisitorRule { String name = 'TernaryCouldBeElvis' int priority = 3 Class astVisitorClass = TernaryCouldBeElvisAstVisitor } class TernaryCouldBeElvisAstVisitor extends AbstractAstVisitor { @Override void visitTernaryExpression(TernaryExpression expression) { if (isNotElvis(expression) && areTheSame(expression.booleanExpression.expression, expression.trueExpression)) { def asElvis = "${expression.trueExpression.text} ?: ${expression.falseExpression.text}" addViolation(expression, "${expression.text} in class $currentClassName can be simplified to $asElvis") } super.visitTernaryExpression(expression) } private boolean isNotElvis(TernaryExpression expression) { return !(expression instanceof ElvisOperatorExpression) } private boolean areTheSame(Expression booleanExpression, Expression trueExpression) { if (booleanExpression.class != trueExpression.class) { return false } if (booleanExpression instanceof VariableExpression) { return booleanExpression.name == trueExpression.name } if (booleanExpression instanceof MethodCallExpression) { return booleanExpression.text == trueExpression.text } return false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/NoDefRule.groovy0000644000175000017500000000321212414302312026262 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode import java.util.regex.Pattern /** * Def keyword is overused and should be replaced with specific type. *

* The excludeRegex property optionally specifies regex * to find text which could occur immediately after def. * * @author Dominik Przybysz */ class NoDefRule extends AbstractRule { String name = 'NoDef' int priority = 3 protected static final String MESSAGE = 'def should not be used' String excludeRegex @Override void applyTo(SourceCode sourceCode, List violations) { Pattern excludeFilter = excludeRegex ? ~/.*def\s+$excludeRegex.*/ : null sourceCode.lines.eachWithIndex { String line, int idx -> if (line.contains('def ') && (!excludeFilter || !(line ==~ excludeFilter))) { violations << createViolation(idx + 1, line.trim(), MESSAGE) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/ParameterReassignmentRule.groovy0000644000175000017500000000603012041061500031565 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Checks for a method or closure parameter being reassigned to a new value within the body of the * method/closure, which is a confusing, questionable practice. Use a temporary variable instead. * * @author Chris Mair */ class ParameterReassignmentRule extends AbstractAstVisitorRule { String name = 'ParameterReassignment' int priority = 3 Class astVisitorClass = ParameterReassignmentAstVisitor } class ParameterReassignmentAstVisitor extends AbstractAstVisitor { private currentMethodParameterNames private final currentClosureParameterNames = [] @Override protected void visitMethodEx(MethodNode node) { currentMethodParameterNames = node.parameters.name super.visitMethodEx(node) } @Override protected void visitMethodComplete(MethodNode node) { super.visitMethodComplete(node) currentMethodParameterNames = [] } @Override void visitClosureExpression(ClosureExpression expression) { def parameterNames = expression.parameters?.name ?: [] currentClosureParameterNames.addAll(parameterNames) super.visitClosureExpression(expression) currentClosureParameterNames.removeAll(parameterNames) } @Override void visitBinaryExpression(BinaryExpression expression) { if (isFirstVisit(expression) && isReassigningAParameter(expression)) { def name = expression.leftExpression.name addViolation(expression, "The method parameter [$name] in class $currentClassName was reassigned. Use a temporary variable instead.") } super.visitBinaryExpression(expression) } private boolean isReassigningAParameter(BinaryExpression expression) { expression.operation.text == '=' && expression.leftExpression instanceof VariableExpression && isCurrentParameterName(expression.leftExpression.name) } private boolean isCurrentParameterName(String name) { name in currentMethodParameterNames || name in currentClosureParameterNames } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/ConfusingTernaryRule.groovy0000644000175000017500000000602212311370173030577 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.convention import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.NotExpression import org.codehaus.groovy.ast.expr.TernaryExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * In an "if" expression with an "else" clause, avoid negation in the test. For example, rephrase: * if (x != y) diff(); else same(); * as: * if (x == y) same(); else diff(); * Most "if (x != y)" cases without an "else" are often return cases, so consistent use of this rule makes the code * easier to read. Also, this resolves trivial ordering problems, such as "does the error case go first?" or "does * the common case go first?". * * @author Hamlet D'Arcy */ class ConfusingTernaryRule extends AbstractAstVisitorRule { String name = 'ConfusingTernary' int priority = 3 Class astVisitorClass = ConfusingTernaryAstVisitor } class ConfusingTernaryAstVisitor extends AbstractAstVisitor { @Override void visitTernaryExpression(TernaryExpression expression) { if (expression.booleanExpression.expression instanceof BinaryExpression) { addViolationForBinaryExpression(expression.booleanExpression.expression, expression) } else if (expression.booleanExpression.expression instanceof NotExpression) { addViolationForNotExpression(expression, expression.booleanExpression.expression) } super.visitTernaryExpression(expression) } private addViolationForNotExpression(TernaryExpression expression, NotExpression exp) { addViolation(expression, "(!$exp.text) is a confusing negation in a ternary expression. Rewrite as ($exp.expression.text) and invert the conditions.") } private addViolationForBinaryExpression(BinaryExpression exp, TernaryExpression expression) { if (exp.operation.text == '!=') { if (AstUtil.isNull(exp.leftExpression) || AstUtil.isNull(exp.rightExpression)) { return } if (AstUtil.isBoolean(exp.leftExpression) || AstUtil.isBoolean(exp.rightExpression)) { return } def suggestion = "($exp.leftExpression.text == $exp.rightExpression.text)" addViolation(expression, "$exp.text is a confusing negation in a ternary expression. Rewrite as $suggestion and invert the conditions.") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/LongLiteralWithLowerCaseLRule.groovy0000644000175000017500000000411012461172330032265 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.convention import org.codehaus.groovy.ast.expr.ConstantExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * In Java and Groovy, you can specify long literals with the L or l character, for instance 55L or * 24l. It is best practice to always use an uppercase L and never a lowercase l. This is * because 11l rendered in some fonts may look like 111 instead of 11L. * * @author Hamlet D'Arcy */ class LongLiteralWithLowerCaseLRule extends AbstractAstVisitorRule { String name = 'LongLiteralWithLowerCaseL' int priority = 2 Class astVisitorClass = LongLiteralWithLowerCaseLAstVisitor } class LongLiteralWithLowerCaseLAstVisitor extends AbstractAstVisitor { @Override void visitConstantExpression(ConstantExpression expression) { if (!isFirstVisit(expression)) { return } if (expression.type.name in ['long', 'java.lang.Long']) { def line = getSourceCode().lines[expression.lineNumber - 1] if (line?.length() <= expression.lastColumnNumber) { def definition = line[expression.lastColumnNumber - 2] if (definition == 'l') { addViolation(expression, "The literal ${expression.value}l should be rewritten ${expression.value}L") } } } super.visitConstantExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/convention/CouldBeElvisRule.groovy0000644000175000017500000000541412311373552027627 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.convention import org.codehaus.groovy.ast.expr.NotExpression import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codehaus.groovy.ast.stmt.IfStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Catch an if block that could be written as an elvis expression. * * @author GUM * @author Chris Mair */ class CouldBeElvisRule extends AbstractAstVisitorRule { String name = 'CouldBeElvis' int priority = 3 Class astVisitorClass = CouldBeElvisAstVisitor } class CouldBeElvisAstVisitor extends AbstractAstVisitor { @Override void visitIfElse(IfStatement node) { addViolationCouldBeElvis(node) super.visitIfElse(node) } private addViolationCouldBeElvis(IfStatement node) { def conditionalCheck = node.booleanExpression?.expression if (conditionalCheck instanceof NotExpression) { def bodyOfIfStatement = getSingleStatementExpressionOrNull(node.ifBlock) if (AstUtil.isBinaryExpressionType(bodyOfIfStatement, '=')) { def conditionalText = conditionalCheck.expression.text def leftAssignText = bodyOfIfStatement.leftExpression.text // space check is a safe guard against crazy ass AST getText() implementations if (conditionalText == leftAssignText && !conditionalText.contains(' ')) { def rightText = AstUtil.createPrettyExpression(bodyOfIfStatement.rightExpression) def rewrite = "$leftAssignText = $leftAssignText ?: $rightText " addViolation(node, "Code could use elvis operator: $rewrite") } } } } private getSingleStatementExpressionOrNull(ifBlock) { if (AstUtil.isOneLiner(ifBlock) && AstUtil.respondsTo(ifBlock.statements[0], 'expression') ) { return ifBlock.statements[0].expression } if (ifBlock instanceof ExpressionStatement) { return ifBlock.expression } return null } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/ClassReferenceAstVisitor.groovy0000644000175000017500000001235512041061502027200 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.ModuleNode import org.codenarc.util.WildcardPattern import java.text.MessageFormat import org.codehaus.groovy.ast.expr.* /** * AstVisitor that check for references for a named class * * @author Chris Mair */ class ClassReferenceAstVisitor extends AbstractAstVisitor { private final classNamePattern private final String violationMessagePattern /** * Constructor * @param classNames - one or more comma-separated class name patterns. Can contain wildcards (*,?) */ ClassReferenceAstVisitor(String classNames) { this(classNames, 'Found reference to {0}') } /** * Constructor * @param classNames - one or more comma-separated class name patterns. Can contain wildcards (*,?) * @param violationMessagePattern - the MessageFormat String pattern used to build the violation message. * The class name is passed as the single argument to the pattern. e.g. "Found reference to {0}" */ ClassReferenceAstVisitor(String classNames, String violationMessagePattern) { this.classNamePattern = new WildcardPattern(classNames) this.violationMessagePattern = violationMessagePattern } @Override void visitImports(ModuleNode node) { def allImports = node.imports + node.staticStarImports.values() allImports?.each { importNode -> if (classNamePattern.matches(importNode.className)) { def violationMessage = formatViolationMessage(importNode.className) addViolation(rule.createViolationForImport(sourceCode, importNode, violationMessage)) } } super.visitImports(node) } @Override void visitField(FieldNode node) { checkNodeType(node) super.visitField(node) } @Override void visitPropertyExpression(PropertyExpression expression) { checkType(expression.text, expression) super.visitPropertyExpression(expression) } @Override void visitClassExpression(ClassExpression expression) { checkNodeType(expression) super.visitClassExpression(expression) } @Override void visitConstructorCallExpression(ConstructorCallExpression node) { if (isFirstVisit(node)) { checkNodeType(node) } super.visitConstructorCallExpression(node) } @Override void visitVariableExpression(VariableExpression expression) { checkNodeType(expression) checkType(expression.name, expression) super.visitVariableExpression(expression) } @Override void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { checkType(node.returnType.name, node) node.parameters.each { parameter -> checkNodeType(parameter) } super.visitConstructorOrMethod(node, isConstructor) } @Override void visitClosureExpression(ClosureExpression expression) { expression.parameters.each { parameter -> checkNodeType(parameter) } super.visitClosureExpression(expression) } @Override void visitCastExpression(CastExpression expression) { checkNodeType(expression) super.visitCastExpression(expression) } @Override protected void visitClassEx(ClassNode node) { def superClassName = node.superClass.name if (superClassName != 'java.lang.Object') { checkType(superClassName, node) } node.interfaces.each { interfaceNode -> checkType(interfaceNode.name, node) } super.visitClassEx(node) } //-------------------------------------------------------------------------- // Helper Methods //-------------------------------------------------------------------------- private void checkType(String type, node) { if (classNamePattern.matches(type)) { def violationMessage = formatViolationMessage(type) addViolation(node, violationMessage) } } private void checkNodeType(node) { if (classNamePattern.matches(node.type.name)) { def violationMessage = formatViolationMessage(node.type.name) addViolation(node, violationMessage) } } private String formatViolationMessage(String typeName) { MessageFormat.format(violationMessagePattern, typeName) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/serialization/0000755000175000017500000000000012623571301023675 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/serialization/SerialPersistentFieldsRule.groovy0000644000175000017500000000453712041061502032423 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.serialization import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * To use a Serializable object's serialPersistentFields correctly, it must be declared private, static, and final. * * @author 'Hamlet D'Arcy' */ class SerialPersistentFieldsRule extends AbstractAstVisitorRule { String name = 'SerialPersistentFields' int priority = 2 Class astVisitorClass = SerialPersistentFieldsAstVisitor } class SerialPersistentFieldsAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (AstUtil.classNodeImplementsType(node.owner, Serializable)) { if (node.name == 'serialPersistentFields') { if (!AstUtil.classNodeImplementsType(node.type, ObjectStreamField[].class)) { addViolation(node, "The class is Serializable and defines a field named serialPersistentFields of type $node.type.name. The field should be declared as a ObjectStreamField[] instead") } else if (!Modifier.isFinal(node.modifiers) || !Modifier.isStatic(node.modifiers) || !Modifier.isPrivate(node.modifiers)) { addViolation(node, 'The class is Serializable and defines a field named serialPersistentFields which is not private, static, and final') } } else if (node.name?.toLowerCase() == 'serialpersistentfields') { addViolation(node, "The class is Serializable and defines a field named $node.name. This should be named serialPersistentFields instead") } } } } ././@LongLink0000644000000000000000000000016500000000000011605 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/serialization/SerializableClassMustDefineSerialVersionUIDRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/serialization/SerializableClassMustDefineSerialVersi0000644000175000017500000000321512311370173033350 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.serialization import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Classes that implement Serializable should define a serialVersionUID. * * @author 'Hamlet D'Arcy' */ class SerializableClassMustDefineSerialVersionUIDRule extends AbstractAstVisitorRule { String name = 'SerializableClassMustDefineSerialVersionUID' int priority = 2 Class astVisitorClass = SerializableClassMustDefineSerialVersionUIDAstVisitor } class SerializableClassMustDefineSerialVersionUIDAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { if (AstUtil.classNodeImplementsType(node, Serializable)) { if (!node.fields.find { it.name == 'serialVersionUID' }) { addViolation(node, "The class $node.name implements Serializable but does not define a serialVersionUID") } } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/serialization/SerialVersionUIDRule.groovy0000644000175000017500000000441712311373552031133 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.serialization import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.PropertyNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import java.lang.reflect.Modifier /** * Rule that checks that serialVersionUID field is static final and type long, and is not a property. * * @author Hamlet D'Arcy */ class SerialVersionUIDRule extends AbstractAstVisitorRule { String name = 'SerialVersionUID' int priority = 2 Class astVisitorClass = SerialVersionUIDAstVisitor } class SerialVersionUIDAstVisitor extends AbstractAstVisitor { private final static SERIAL_ID = 'serialVersionUID' void visitField(FieldNode node) { if (node?.name == SERIAL_ID) { if (!Modifier.isPrivate(node?.modifiers)) { addViolation node, 'serialVersionUID found that is not private.' } if (!Modifier.isStatic(node?.modifiers)) { addViolation node, 'serialVersionUID found that is not static.' } if (!Modifier.isFinal(node?.modifiers)) { addViolation node, 'serialVersionUID found that is not final.' } if (node?.type?.name != 'long') { addViolation node, 'serialVersionUID found that is not long. Found: ' + node?.type?.name } } super.visitField node } void visitProperty(PropertyNode node) { if (node?.name == SERIAL_ID) { addViolation node, 'serialVersionUID found that is a property. ' } super.visitProperty(node) } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/serialization/EnumCustomSerializationIgnoredRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/serialization/EnumCustomSerializationIgnoredRule.gro0000644000175000017500000000511012311373552033402 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.serialization import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import java.lang.reflect.Modifier /** * Checks for enums that define writeObject() or writeReplace() methods, or declare * serialPersistentFields or serialVersionUID fields, all of which are ignored for enums. * * @author Chris Mair */ class EnumCustomSerializationIgnoredRule extends AbstractAstVisitorRule { String name = 'EnumCustomSerializationIgnored' int priority = 2 Class astVisitorClass = EnumCustomSerializationIgnoredAstVisitor } class EnumCustomSerializationIgnoredAstVisitor extends AbstractAstVisitor { @Override void visitField(FieldNode node) { if (currentClassNode.isEnum()) { if (isPrivateStaticFinalField(node, 'serialVersionUID') || isPrivateStaticFinalField(node, 'serialPersistentFields')) { addViolation(node, "Field ${node.name} in class $currentClassName is ignored for enums") } } } @Override protected void visitMethodComplete(MethodNode node) { if (currentClassNode.isEnum()) { if (isWriteReplaceMethod(node) || isWriteObjectMethod(node)) { addViolation(node, "Method ${node.name}() in class $currentClassName is ignored for enums") } } } private isWriteObjectMethod(MethodNode node) { node.name == 'writeObject' && node?.parameters.size() == 1 && node.parameters[0].type.name == 'ObjectOutputStream' } private isWriteReplaceMethod(MethodNode node) { node.name == 'writeReplace' && !node.parameters } private boolean isPrivateStaticFinalField(FieldNode node, String name) { return node?.name == name && Modifier.isPrivate(node?.modifiers) && Modifier.isStatic(node?.modifiers) && Modifier.isFinal(node?.modifiers) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/0000755000175000017500000000000012623571301023056 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToGetAtMethodRule.groovy0000644000175000017500000000306212141456400032121 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the getAt(Object) method is called directly in code instead of using the [] index operator. A groovier way to express this: a.getAt(b) is this: a[b] * * @author Hamlet D'Arcy */ class ExplicitCallToGetAtMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToGetAtMethod' int priority = 2 Class astVisitorClass = ExplicitCallToGetAtMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToGetAtMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToGetAtMethodAstVisitor() { super('getAt') } @Override protected String getViolationMessage(MethodCallExpression call) { "Explicit call to ${call.text} method can be rewritten as ${call.objectExpression.text}[${call.arguments.text}]" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToAndMethodRule.groovy0000644000175000017500000000303012141456440031616 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the and(Object) method is called directly in code instead of using the & operator. A groovier way to express this: a.and(b) is this: a & b * * @author Hamlet D'Arcy */ class ExplicitCallToAndMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToAndMethod' int priority = 2 Class astVisitorClass = ExplicitCallToAndMethodAstVisitor boolean ignoreThisReference = true } class ExplicitCallToAndMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToAndMethodAstVisitor() { super('and') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} & ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitArrayListInstantiationRule.groovy0000644000175000017500000000262712141456634033353 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * This rule checks for the explicit instantiation of an ArrayList using the no-arg constructor. * In Groovy, it is best to write "new ArrayList()" as "[]", which creates the same object. * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitArrayListInstantiationRule extends AbstractAstVisitorRule { String name = 'ExplicitArrayListInstantiation' int priority = 2 @Override AstVisitor getAstVisitor() { new ExplicitTypeInstantiationAstVisitor('ArrayList') { @Override protected String createErrorMessage() { 'ArrayList objects are better instantiated using the form "[]"' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitTreeSetInstantiationRule.groovy0000644000175000017500000000264412141456644033014 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * This rule checks for the explicit instantiation of a TreeSet using the no-arg constructor. * In Groovy, it is best to write "new TreeSet()" as "[] as SortedSet", which creates the same object. * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitTreeSetInstantiationRule extends AbstractAstVisitorRule { String name = 'ExplicitTreeSetInstantiation' int priority = 2 @Override AstVisitor getAstVisitor() { new ExplicitTypeInstantiationAstVisitor('TreeSet') { @Override protected String createErrorMessage() { 'TreeSet objects are better instantiated using the form "[] as SortedSet"' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitHashSetInstantiationRule.groovy0000644000175000017500000000265112311373552032771 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * This rule checks for the explicit instantiation of a HashSet using the no-arg constructor. * In Groovy, it is best to write "new HashSet()" as "[] as Set", which creates the same object. * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitHashSetInstantiationRule extends AbstractAstVisitorRule { String name = 'ExplicitHashSetInstantiation' int priority = 2 @Override AstVisitor getAstVisitor() { new ExplicitTypeInstantiationAstVisitor('HashSet') { @Override protected String createErrorMessage() { 'HashSet objects are better instantiated using the form "[] as Set"' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ConfusingMultipleReturnsRule.groovy0000644000175000017500000001022412462775514032223 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.EmptyExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Multiple return values can be used to set several variables at once. To use multiple return values, the left hand * side of the assignment must be enclosed in parenthesis. If not, then you are not using multiple return values, * you're only assigning the last element. * * @author Hamlet D'Arcy */ class ConfusingMultipleReturnsRule extends AbstractAstVisitorRule { String name = 'ConfusingMultipleReturns' int priority = 2 Class astVisitorClass = ConfusingMultipleReturnsAstVisitor } class ConfusingMultipleReturnsAstVisitor extends AbstractAstVisitor { Set declarations = [] as Set @Override void visitDeclarationExpression(DeclarationExpression expression) { declarations << expression super.visitDeclarationExpression(expression) } @Override protected void visitClassEx(ClassNode node) { declarations.clear() // clear it out for next iteration def fields = node.fields. groupBy { FieldNode f -> f.lineNumber }. values(). findAll { Collection c -> c.size() > 1 } for (Collection nodes : fields) { nodes.sort { it.columnNumber } addViolationsForMultipleFieldDeclarations(nodes) } super.visitClassEx(node) } @Override protected void visitClassComplete(ClassNode node) { def declarationsOnSingleLine = declarations. groupBy { DeclarationExpression d -> d.lineNumber }. values(). findAll { Collection c -> c.size() > 1 } for (Collection groupedNodes : declarationsOnSingleLine) { groupedNodes.sort { it.columnNumber } addViolationForMultipleDeclarations(groupedNodes) } declarations.clear() super.visitClassComplete(node) } private addViolationsForMultipleFieldDeclarations(Collection nodes) { // all the declarations are on the same line... does the last one have an initial expression and the others do not? if (nodes[-1].initialExpression != null) { nodes.remove(nodes[-1]) // remove last node if (nodes.every { FieldNode f -> f.initialExpression == null }) { for (def v: nodes) { addViolation(v, "Confusing declaration in class $currentClassName. The field '$v.name' is initialized to null") } } } } private addViolationForMultipleDeclarations(Collection groupedNodes) { // all the declarations are on the same line... does the last one have an initial expression and the others do not? def lastExpression = groupedNodes[-1] if (!(lastExpression.rightExpression instanceof EmptyExpression)) { groupedNodes.remove(lastExpression) // remove last node b/c it has an expression for (def declaration: groupedNodes) { def rhs = declaration.rightExpression if (rhs instanceof EmptyExpression) { addViolation(declaration, "Confusing declaration in class $currentClassName. The variable '$declaration.leftExpression.text' is initialized to null") } } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToOrMethodRule.groovy0000644000175000017500000000303012141456300031467 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the or(Object) method is called directly in code instead of using the | operator. A groovier way to express this: a.or(b) is this: a | b * * @author Hamlet D'Arcy */ class ExplicitCallToOrMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToOrMethod' int priority = 2 Class astVisitorClass = ExplicitCallToOrMethodAstVisitor boolean ignoreThisReference = true } class ExplicitCallToOrMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToOrMethodAstVisitor() { super('or') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} | ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitHashMapInstantiationRule.groovy0000644000175000017500000000261612141456710032753 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * This rule checks for the explicit instantiation of a HashMap using the no-arg constructor. * In Groovy, it is best to write "new HashMap()" as "[:]", which creates the same object. * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitHashMapInstantiationRule extends AbstractAstVisitorRule { String name = 'ExplicitHashMapInstantiation' int priority = 2 @Override AstVisitor getAstVisitor() { new ExplicitTypeInstantiationAstVisitor('HashMap') { @Override protected String createErrorMessage() { 'HashMap objects are normally instantiated using the form "[:]"' } } } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitLinkedHashMapInstantiationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitLinkedHashMapInstantiationRule.gro0000644000175000017500000000263212141456674033353 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * This rule checks for the explicit instantiation of a LinkedHashMap using the no-arg constructor. * In Groovy, it is best to write "new LinkedHashMap()" as "[:]", which creates the same object. * * @author René Scheibe */ class ExplicitLinkedHashMapInstantiationRule extends AbstractAstVisitorRule { String name = 'ExplicitLinkedHashMapInstantiation' int priority = 2 @Override AstVisitor getAstVisitor() { new ExplicitTypeInstantiationAstVisitor('LinkedHashMap') { @Override protected String createErrorMessage() { 'LinkedHashMap objects are better instantiated using the form "[:]"' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ClosureAsLastMethodParameterRule.groovy0000644000175000017500000000501512006632016032700 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * If a method is called and the last parameter is an inline closure it can be declared outside of the method call brackets. * * @author Marcin Erdmann * @Chris Mair */ class ClosureAsLastMethodParameterRule extends AbstractAstVisitorRule { String name = 'ClosureAsLastMethodParameter' int priority = 3 Class astVisitorClass = ClosureAsLastMethodParameterAstVisitor } class ClosureAsLastMethodParameterAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { def arguments = AstUtil.getMethodArguments(call) if (arguments && arguments.last() instanceof ClosureExpression) { def lastArgument = arguments.last() def sourceLine = sourceCode.lines[call.lineNumber - 1] def firstChar = sourceLine[call.columnNumber - 1] // If a method call is surrounded by parentheses (possibly unnecessary), then the AST includes those in the // MethodCall start/end column indexes. In that case, it gets too complicated. Just bail. if (firstChar == '(') { super.visitMethodCallExpression(call) return } def isViolation = call.lastLineNumber > lastArgument.lastLineNumber || (call.lastLineNumber == lastArgument.lastLineNumber && call.lastColumnNumber > lastArgument.lastColumnNumber) if (isViolation) { addViolation(call, "The last parameter to the '$call.methodAsString' method call is a closure an can appear outside the parenthesis") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToMethodAstVisitor.groovy0000644000175000017500000000426612311371417032406 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Parent Visitor for "ExplicitCallToX" Rules. * * @author Hamlet D'Arcy * @author René Scheibe */ abstract class ExplicitCallToMethodAstVisitor extends AbstractMethodCallExpressionVisitor { final String methodName /** * @param methodName The method name to watch for. */ protected ExplicitCallToMethodAstVisitor(String methodName) { this.methodName = methodName } void visitMethodCallExpression(MethodCallExpression call) { if (!AstUtil.isSafe(call) && !AstUtil.isSpreadSafe(call) && AstUtil.isMethodNamed(call, methodName, 1)) { boolean isAllowedCallOnThis = rule.ignoreThisReference && AstUtil.isMethodCallOnObject(call, 'this') boolean isAllowedCallOnSuper = AstUtil.isMethodCallOnObject(call, 'super') if (!isAllowedCallOnThis && !isAllowedCallOnSuper) { if (!AstUtil.isSafe(call.objectExpression)) { safelyAddViolation(call) } } } } @SuppressWarnings('CatchThrowable') private safelyAddViolation(MethodCallExpression call) { try { addViolation call, getViolationMessage(call) } catch (Throwable t) { addViolation call, "Explicit call to $methodName can be simplified using Groovy operator overloading." } } abstract protected String getViolationMessage(MethodCallExpression exp) } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToLeftShiftMethodRule.groovy0000644000175000017500000000312412141456370033012 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the leftShift(Object) method is called directly in code instead of using the << operator. A groovier way to express this: a.leftShift(b) is this: a << b * * @author Hamlet D'Arcy */ class ExplicitCallToLeftShiftMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToLeftShiftMethod' int priority = 2 Class astVisitorClass = ExplicitCallToLeftShiftMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToLeftShiftMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToLeftShiftMethodAstVisitor() { super('leftShift') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} << ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/CollectAllIsDeprecatedRule.groovy0000644000175000017500000000343412006632014031446 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * collectAll is deprecated since Groovy 1.8.1. Use collectNested instead * * @author Joachim Baumann */ class CollectAllIsDeprecatedRule extends AbstractAstVisitorRule { String name = 'CollectAllIsDeprecated' int priority = 2 Class astVisitorClass = CollectAllIsDeprecatedAstVisitor protected static final String MESSAGE = 'collectAll{} is deprecated since Groovy 1.8.1. Use collectNested instead{}.' } class CollectAllIsDeprecatedAstVisitor extends AbstractAstVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { /* The structure of the AST for this violation is as follows: MethodCallExpression name collectAll(), one or two parameterStack */ if(AstUtil.isMethodCall(call, 'collectAll', 1..2)) { addViolation(call, CollectAllIsDeprecatedRule.MESSAGE) } super.visitMethodCallExpression(call) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitStackInstantiationRule.groovy0000644000175000017500000000262012141456652032477 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * This rule checks for the explicit instantiation of a Stack using the no-arg constructor. * In Groovy, it is best to write "new Stack()" as "[] as Stack", which creates the same object. * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitStackInstantiationRule extends AbstractAstVisitorRule { String name = 'ExplicitStackInstantiation' int priority = 2 @Override AstVisitor getAstVisitor() { new ExplicitTypeInstantiationAstVisitor('Stack') { @Override protected String createErrorMessage() { 'Stack objects are better instantiated using the form "[] as Stack"' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToCompareToMethodRule.groovy0000644000175000017500000000320512141456430033010 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the compareTo(Object) method is called directly in code instead of using the <=>, >, >=, <, and <= operators. A groovier way to express this: a.compareTo(b) is this: a <=> b, or using the other operators. * * @author Hamlet D'Arcy */ class ExplicitCallToCompareToMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToCompareToMethod' int priority = 2 Class astVisitorClass = ExplicitCallToCompareToMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToCompareToMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToCompareToMethodAstVisitor() { super('compareTo') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten using the compareTo operators such as >, <, <=, >=, and <=>" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/UseCollectNestedRule.groovy0000644000175000017500000001126212041054176030364 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.groovyism import org.apache.log4j.Logger import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.Parameter import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Instead of nested collect{}-calls use collectNested{} * * @author Joachim Baumann * @author Chris Mair */ class UseCollectNestedRule extends AbstractAstVisitorRule { String name = 'UseCollectNested' int priority = 2 Class astVisitorClass = UseCollectNestedAstVisitor protected static final String MESSAGE = 'Instead of nested collect{}-calls use collectNested{}' } class UseCollectNestedAstVisitor extends AbstractAstVisitor { private static final LOG = Logger.getLogger(UseCollectNestedAstVisitor) private final Stack parameterStack = [] @Override protected void visitClassComplete(ClassNode cn) { if (parameterStack.size() != 0) { LOG.warn("Internal Error for ${cn.name}: Visits are unbalanced") } } @Override void visitMethodCallExpression(MethodCallExpression call) { boolean isCollectCall = false Parameter parameter Parameter it = new Parameter(ClassHelper.OBJECT_TYPE, 'it') /* The idea for this rule is to add the parameter of the closure used in the collect call to the stack of parameters, and check for each collect expression whether it is called on the parameter on the top of the stack */ if(AstUtil.isMethodCall(call, 'collect', 1..2)) { Expression expression = getMethodCallParameterThatIsAClosure(call) isCollectCall = expression instanceof ClosureExpression if (isCollectCall) { parameter = getClosureParameter(expression, it) checkForCallToClosureParameter(call) } } addArgumentList(isCollectCall, parameter) super.visitMethodCallExpression(call) removeArgumentList(isCollectCall) } private Parameter getClosureParameter(ClosureExpression expression, Parameter it) { Parameter param if (expression.parameters.size() != 0) { // we assume correct syntax and thus only one parameter param = expression.parameters[0] } else { // implicit parameter, we use our own parameter object as placeholder param = it } return param } private Expression getMethodCallParameterThatIsAClosure(MethodCallExpression call) { int arity = AstUtil.getMethodArguments(call).size() Expression expression if (arity == 1) { // closure is the first parameter expression = call.arguments.expressions[0] } else { // closure is second parameter expression = call.arguments.expressions[1] } return expression } private void checkForCallToClosureParameter(MethodCallExpression call) { // Now if the call is to the parameter of the closure then the node on // which collect is called has to be a VariableExpression if (call.objectExpression instanceof VariableExpression && !parameterStack.empty() && parameterStack.peek().name == call.objectExpression.name) { addViolation(call, UseCollectNestedRule.MESSAGE) } } private void addArgumentList(boolean isCollectCall, Parameter param) { if (isCollectCall) { parameterStack.push(param) } } private void removeArgumentList(boolean isCollectCall) { if (isCollectCall) { parameterStack.pop() } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/GroovyLangImmutableRule.groovy0000644000175000017500000000512412311370173031104 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ModuleNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * The groovy.lang.Immutable annotation has been deprecated and replaced by groovy.transform.Immutable. Do not use the * Immutable in groovy.lang. * * @author Hamlet D'Arcy */ class GroovyLangImmutableRule extends AbstractAstVisitorRule { String name = 'GroovyLangImmutable' int priority = 2 Class astVisitorClass = GroovyLangImmutableAstVisitor } class GroovyLangImmutableAstVisitor extends AbstractAstVisitor { boolean groovyTransformIsStarImported = false boolean groovyTransformIsImported = false List aliases = [] @Override void visitImports(ModuleNode node) { groovyTransformIsImported = node.imports.any { it.type.name == 'groovy.transform.Immutable' } groovyTransformIsStarImported = node.starImports.any { it.packageName == 'groovy.transform.' } aliases = node.imports.findAll { it.type.name == 'groovy.lang.Immutable' && it.alias }*.alias super.visitImports(node) } @Override protected void visitClassComplete(ClassNode node) { node?.annotations?.each { AnnotationNode anno -> if (anno?.classNode?.name == 'groovy.lang.Immutable') { addViolation(anno, 'groovy.lang.Immutable is deprecated in favor of groovy.transform.Immutable') } else if (anno?.classNode?.name == 'Immutable' && !groovyTransformIsStarImported && !groovyTransformIsImported ) { addViolation(anno, 'groovy.lang.Immutable is deprecated in favor of groovy.transform.Immutable') } else if (aliases.contains(anno?.classNode?.name)) { addViolation(anno, 'groovy.lang.Immutable is deprecated in favor of groovy.transform.Immutable') } } super.visitClassComplete(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/AssignCollectionSortRule.groovy0000644000175000017500000000502212106561212031260 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * The Collections.sort() method mutates the list and returns the list as a value. If you are assigning the result of * sort() to a variable, then you probably don't realize that you're also modifying the original list as well. This is * frequently the cause of subtle bugs. * * @author Hamlet D'Arcy */ class AssignCollectionSortRule extends AbstractAstVisitorRule { String name = 'AssignCollectionSort' int priority = 2 Class astVisitorClass = AssignCollectionSortAstVisitor } class AssignCollectionSortAstVisitor extends AbstractAstVisitor { @Override void visitDeclarationExpression(DeclarationExpression expression) { Expression right = expression.rightExpression if (right instanceof MethodCallExpression) { if (isChainedSort(right) || (isChainedSort(right.objectExpression))) { addViolation(expression, 'Violation in $currentClassName. sort() mutates the original list, but the return value is being assigned') } } super.visitDeclarationExpression expression } private static boolean isChainedSort(Expression expression) { if (AstUtil.isMethodCall(expression, 'sort', 0..2)) { def arguments = AstUtil.getMethodArguments(expression) def isMutateFalse = arguments && AstUtil.isFalse(arguments[0]) if (expression.objectExpression instanceof VariableExpression && !isMutateFalse) { return true } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToModMethodRule.groovy0000644000175000017500000000303112141456346031641 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the mod(Object) method is called directly in code instead of using the % operator. A groovier way to express this: a.mod(b) is this: a % b * * @author Hamlet D'Arcy */ class ExplicitCallToModMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToModMethod' int priority = 2 Class astVisitorClass = ExplicitCallToModMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToModMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToModMethodAstVisitor() { super('mod') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} % ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToDivMethodRule.groovy0000644000175000017500000000303112141456422031637 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the div(Object) method is called directly in code instead of using the / operator. A groovier way to express this: a.div(b) is this: a / b * * @author Hamlet D'Arcy */ class ExplicitCallToDivMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToDivMethod' int priority = 2 Class astVisitorClass = ExplicitCallToDivMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToDivMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToDivMethodAstVisitor() { super('div') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} / ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/GetterMethodCouldBePropertyRule.groovy0000644000175000017500000001065712311373552032566 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.ClassExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * If a class defines a public method that follows the Java getter notation and returns a constant, * then it is cleaner to provide a Groovy property for the value rather than a Groovy method. * * @author Hamlet D'Arcy * @author Chris Mair */ class GetterMethodCouldBePropertyRule extends AbstractAstVisitorRule { String name = 'GetterMethodCouldBeProperty' int priority = 3 Class astVisitorClass = GetterMethodCouldBePropertyAstVisitor } class GetterMethodCouldBePropertyAstVisitor extends AbstractAstVisitor { private final staticFieldNames = [] @Override protected void visitClassEx(ClassNode node) { staticFieldNames.addAll(node.fields.findAll { it.isStatic() }*.name) super.visitClassEx(node) } @Override protected void visitClassComplete(ClassNode node) { staticFieldNames.clear() super.visitClassComplete(node) } @Override protected void visitMethodEx(MethodNode node) { if (AstUtil.isMethodNode(node, 'get[A-Z].*', 0) && node.isPublic() && AstUtil.isOneLiner(node.code)) { def statement = node.code.statements[0] if (statement instanceof ExpressionStatement) { if (statement.expression instanceof ConstantExpression) { addViolation(node, createMessage(node)) } else if (statement.expression instanceof VariableExpression && statement.expression.variable ==~ /[A-Z].*/) { addViolation(node, createMessage(node)) } else if (statement.expression instanceof VariableExpression && staticFieldNames.contains(statement.expression.name)) { addViolation(node, createMessage(node)) } } else if (statement instanceof ReturnStatement) { if (statement.expression instanceof ConstantExpression) { addViolation(node, createMessage(node)) } else if (statement.expression instanceof ClassExpression) { addViolation(node, createMessage(node)) } else if (statement.expression instanceof VariableExpression && staticFieldNames.contains(statement.expression.name)) { addViolation(node, createMessage(node)) } } } super.visitMethodEx(node) } private String createMessage(MethodNode node) { def constant = node.code.statements[0].expression def methodName = node.name def methodType = node.returnType.nameWithoutPackage def staticModifier = node.isStatic() ? 'static ' : '' def propertyName = node.name[3].toLowerCase() + (node.name.length() == 4 ? '' : node.name[4..-1]) def constantValue if (constant instanceof ConstantExpression) { constantValue = constant.value instanceof String ? "'" + constant.value + "'" : constant.value } else if (constant instanceof ClassExpression) { constantValue = constant.text } else if (constant instanceof VariableExpression) { constantValue = constant.name } else { constantValue = '' } "The method '$methodName ' in class $currentClassName can be expressed more simply as the field declaration\n" + "${staticModifier}final $methodType $propertyName = $constantValue" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToPowerMethodRule.groovy0000644000175000017500000000305512141456262032221 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the power(Object) method is called directly in code instead of using the ** operator. A groovier way to express this: a.power(b) is this: a ** b * * @author Hamlet D'Arcy */ class ExplicitCallToPowerMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToPowerMethod' int priority = 2 Class astVisitorClass = ExplicitCallToPowerMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToPowerMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToPowerMethodAstVisitor() { super('power') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} ** ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToMinusMethodRule.groovy0000644000175000017500000000306112141456356032221 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the minus(Object) method is called directly in code instead of using the - operator. A groovier way to express this: a.minus(b) is this: a - b * * @author Hamlet D'Arcy */ class ExplicitCallToMinusMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToMinusMethod' int priority = 2 Class astVisitorClass = ExplicitCallToMinusMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToMinusMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToMinusMethodAstVisitor() { super('minus') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} - ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/GStringExpressionWithinStringRule.groovy0000644000175000017500000001061012465005511033161 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.AnnotatedNode import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.expr.AnnotationConstantExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.ListExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import java.util.regex.Matcher /** * Check for regular (single quote) strings containing a GString-type expression (${..}). * * @author Chris Mair */ class GStringExpressionWithinStringRule extends AbstractAstVisitorRule { String name = 'GStringExpressionWithinString' int priority = 2 Class astVisitorClass = GStringExpressionWithinStringAstVisitor } class GStringExpressionWithinStringAstVisitor extends AbstractAstVisitor { private static final GSTRING_EXPRESSION_REGEX = /\$\{.*\}/ private AnnotatedNode currentAnnotatedNode @Override void visitConstantExpression(ConstantExpression expression) { if (isFirstVisit(expression) && expression.value instanceof String && expression.lineNumber > -1) { Matcher matcher = expression.value =~ GSTRING_EXPRESSION_REGEX boolean matchesGStringExpressionPattern = matcher as boolean if (matchesGStringExpressionPattern && isNotElementOfAnnotation(expression)) { addViolation(expression, "The String '$expression.value' contains a GString-type expression: '${matcher[0]}'") } } super.visitConstantExpression(expression) } @Override void visitAnnotations(AnnotatedNode node) { saveCurrentAnnotatedNode(node) super.visitAnnotations(node) resetCurrentAnnotatedNode() } private boolean isNotElementOfAnnotation(ConstantExpression expression) { return !isProcessingAnnotatedNode() || !isUsedInAnyAnnotationOnCurrentAnnotatedNode(expression) } private boolean isUsedInAnyAnnotationOnCurrentAnnotatedNode(ConstantExpression constantExpression) { return currentAnnotatedNode.annotations.any { AnnotationNode annotationNode -> isExpressionUsedInAnnotation(constantExpression, annotationNode) } } private static boolean isExpressionUsedInAnnotation(ConstantExpression expression, AnnotationNode annotationNode) { List constantExpressions = new ConstantExpressionExtractor().extractFrom(annotationNode) return constantExpressions.any { it.is(expression) } } private boolean isProcessingAnnotatedNode() { return this.currentAnnotatedNode != null } private void resetCurrentAnnotatedNode() { this.currentAnnotatedNode = null } private void saveCurrentAnnotatedNode(AnnotatedNode annotatedNode) { this.currentAnnotatedNode = annotatedNode } } class ConstantExpressionExtractor { @SuppressWarnings('UseCollectMany') //collectMany is not available in Groovy 1.7.5 List extractFrom(AnnotationNode annotationNode) { return annotationNode.members.values().collect { Expression expression -> extractFromExpression(expression) }.flatten() } private List extractFromExpression(ListExpression listExpression) { return listExpression.expressions.collect { Expression expression -> extractFromExpression(expression) } } private List extractFromExpression(ConstantExpression expression) { return [expression] } private List extractFromExpression(AnnotationConstantExpression expression) { AnnotationNode annotationNode = expression.value as AnnotationNode return extractFrom(annotationNode) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitLinkedListInstantiationRule.groovy0000644000175000017500000000265612311373552033501 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * This rule checks for the explicit instantiation of a LinkedList using the no-arg constructor. * In Groovy, it is best to write "new LinkedList()" as "[] as Queue", which creates the same object. * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitLinkedListInstantiationRule extends AbstractAstVisitorRule { String name = 'ExplicitLinkedListInstantiation' int priority = 2 @Override AstVisitor getAstVisitor() { new ExplicitTypeInstantiationAstVisitor('LinkedList') { @Override protected String createErrorMessage() { 'LinkedList objects are better instantiated using the form "[] as Queue"' } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/AssignCollectionUniqueRule.groovy0000644000175000017500000000421512006632012031576 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * the unique method mutates the original list. If a user is using the result of this method then they probably don't understand thiss * * @author Nick Larson * @author Juan Vazquez * @author Jon DeJong */ class AssignCollectionUniqueRule extends AbstractAstVisitorRule { String name = 'AssignCollectionUnique' int priority = 2 Class astVisitorClass = AssignCollectionUniqueAstVisitor } class AssignCollectionUniqueAstVisitor extends AbstractAstVisitor { @Override void visitDeclarationExpression(DeclarationExpression expression) { Expression right = expression.rightExpression if (right instanceof MethodCallExpression) { if (isChainedUnique(right) || (isChainedUnique(right.objectExpression))) { addViolation(expression, 'unique() mutates the original list.') } } super.visitDeclarationExpression expression } private static boolean isChainedUnique(Expression right) { if (AstUtil.isMethodCall(right, 'unique', 0..1)) { if (right.objectExpression instanceof VariableExpression) { return true } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToPlusMethodRule.groovy0000644000175000017500000000304212141456270032043 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the plus(Object) method is called directly in code instead of using the + operator. A groovier way to express this: a.plus(b) is this: a + b * * @author Hamlet D'Arcy */ class ExplicitCallToPlusMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToPlusMethod' int priority = 2 Class astVisitorClass = ExplicitCallToPlusMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToPlusMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToPlusMethodAstVisitor() { super('plus') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} + ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToXorMethodRule.groovy0000644000175000017500000000304212141456242031667 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the xor(Object) method is called directly in code instead of using the ^ operator. A groovier way to express this: a.xor(b) is this: a ^ b * * @author Hamlet D'Arcy */ class ExplicitCallToXorMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToXorMethod' int priority = 2 Class astVisitorClass = ExplicitCallToXorMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToXorMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToXorMethodAstVisitor() { super('xor') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} ^ ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToRightShiftMethodRule.groovy0000644000175000017500000000313512141456252033176 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the rightShift(Object) method is called directly in code instead of using the >> operator. A groovier way to express this: a.rightShift(b) is this: a >> b * * @author Hamlet D'Arcy */ class ExplicitCallToRightShiftMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToRightShiftMethod' int priority = 2 Class astVisitorClass = ExplicitCallToRightShiftMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToRightShiftMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToRightShiftMethodAstVisitor() { super('rightShift') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} >> ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/GStringAsMapKeyRule.groovy0000644000175000017500000000316012006632014030117 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MapEntryExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * A rule that disallows GStrings as map keys as they might change * their hashcode over time. * The map keys and values are recursively checked. * * @author @Hackergarten */ class GStringAsMapKeyRule extends AbstractAstVisitorRule { String name = 'GStringAsMapKey' int priority = 2 Class astVisitorClass = GStringAsMapKeyAstVisitor } class GStringAsMapKeyAstVisitor extends AbstractAstVisitor { void visitMapEntryExpression(MapEntryExpression expression) { if (AstUtil.classNodeImplementsType(expression?.keyExpression?.type, GString)) { addViolation expression, 'GString as a key in a map is unsafe' } super.visitMapEntryExpression expression // needed for GStrings in nested keys and values } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitTypeInstantiationAstVisitor.groovy0000644000175000017500000000274712141456624033564 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codenarc.rule.AbstractAstVisitor /** * AstVisitor that checks for no-arg constructor calls for the type specified in the constructor. * Used by the ExplicitXxxInstantiation rules. * * @author Chris Mair */ abstract class ExplicitTypeInstantiationAstVisitor extends AbstractAstVisitor { private final String typeName protected ExplicitTypeInstantiationAstVisitor(String typeName) { this.typeName = typeName } void visitConstructorCallExpression(ConstructorCallExpression call) { if (isFirstVisit(call) && call?.type?.name == typeName && call.arguments.expressions.empty) { addViolation call, createErrorMessage() } super.visitConstructorCallExpression call } abstract protected String createErrorMessage() } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToEqualsMethodRule.groovy0000644000175000017500000000316512141456412032356 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the equals(Object) method is called directly in code instead of using the == or != operator. A groovier way to express this: a.equals(b) is this: a == b and a groovier way to express : !a.equals(b) is : a != b * * @author Hamlet D'Arcy */ class ExplicitCallToEqualsMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToEqualsMethod' int priority = 2 Class astVisitorClass = ExplicitCallToEqualsMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToEqualsMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToEqualsMethodAstVisitor() { super('equals') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as (${exp.objectExpression.text} == ${exp.arguments.text})" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/ExplicitCallToMultiplyMethodRule.groovy0000644000175000017500000000311112141456334032735 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule /** * This rule detects when the multiply(Object) method is called directly in code instead of using the * operator. A groovier way to express this: a.multiply(b) is this: a * b * * @author Hamlet D'Arcy */ class ExplicitCallToMultiplyMethodRule extends AbstractAstVisitorRule { String name = 'ExplicitCallToMultiplyMethod' int priority = 2 Class astVisitorClass = ExplicitCallToMultiplyMethodAstVisitor boolean ignoreThisReference = false } class ExplicitCallToMultiplyMethodAstVisitor extends ExplicitCallToMethodAstVisitor { ExplicitCallToMultiplyMethodAstVisitor() { super('multiply') } @Override protected String getViolationMessage(MethodCallExpression exp) { "Explicit call to ${exp.text} method can be rewritten as ${exp.objectExpression.text} * ${exp.arguments.text}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/groovyism/UseCollectManyRule.groovy0000644000175000017500000000437212006632016030046 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * In many case collectMany() yields the same result as collect{}.flatten. It is easier to * understand and more clearly transports the purpose. * * @author Joachim Baumann */ class UseCollectManyRule extends AbstractAstVisitorRule { protected static final String MESSAGE = 'collect{}.flatten() can be collectMany{}' String name = 'UseCollectMany' int priority = 2 Class astVisitorClass = UseCollectManyAstVisitor } class UseCollectManyAstVisitor extends AbstractAstVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { /* The structure of the AST for this violation is as follows: MethodCallExpression name flatten(), no arguments - objectExpression contains as first element - MethodCallExpression name collect(), one argument (closure) Nota Bene: This does not detect assignment to a variable and subsequent call to flatten() */ if(AstUtil.isMethodCall(call, 'flatten', 0)) { // found flatten, now we try to find the previous collect()-call Expression expression = call.objectExpression if(AstUtil.isMethodCall(expression, 'collect', 1)) { addViolation(call, UseCollectManyRule.MESSAGE) } } super.visitMethodCallExpression(call) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/0000755000175000017500000000000012623571301022667 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/InsecureRandomRule.groovy0000644000175000017500000000572412006632014027706 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Reports usages of java.util.Random, which can produce very predictable results. If two instances of Random are * created with the same seed and sequence of method calls, they will generate the exact same results. Use * java.security.SecureRandom instead, which provides a cryptographically strong random number generator. * SecureRandom uses PRNG, which means they are using a deterministic algorithm to produce a pseudo-random number * from a true random seed. SecureRandom produces non-deterministic output. * * By default, this rule does not apply to test files. * * @author Hamlet D'Arcy */ class InsecureRandomRule extends AbstractAstVisitorRule { String name = 'InsecureRandom' int priority = 2 Class astVisitorClass = InsecureRandomAstVisitor String doNotApplyToFilesMatching = DEFAULT_TEST_FILES } class InsecureRandomAstVisitor extends AbstractAstVisitor { @Override void visitConstructorCallExpression(ConstructorCallExpression call) { if (AstUtil.classNodeImplementsType(call.type, Random)) { addViolation(call, 'Using Random is insecure. Use SecureRandom instead') } super.visitConstructorCallExpression(call) } @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, 'Math', 'random', 0)) { addViolation(call, 'Using Math.random() is insecure. Use SecureRandom instead') } else if (AstUtil.isMethodNamed(call, 'random', 0) && isJavaLangMathCall(call)) { addViolation(call, 'Using Math.random() is insecure. Use SecureRandom instead') } super.visitMethodCallExpression(call) } private static boolean isJavaLangMathCall(MethodCallExpression call) { if (AstUtil.isPropertyNamed(call.objectExpression, 'Math')) { if (AstUtil.isPropertyNamed(call.objectExpression.objectExpression, 'lang')) { if (AstUtil.isVariable(call.objectExpression.objectExpression.objectExpression, 'java')) { return true } } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/NonFinalPublicFieldRule.groovy0000644000175000017500000000264312006632016030576 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor /** * Finds code that violates secure coding principles for mobile code by declaring a member variable public but not final. * * @author Hamlet D'Arcy */ class NonFinalPublicFieldRule extends AbstractAstVisitorRule { String name = 'NonFinalPublicField' int priority = 2 Class astVisitorClass = NonFinalPublicFieldAstVisitor } class NonFinalPublicFieldAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (node.isPublic() && !node.isFinal()) { addViolation(node, "The field $node.name is public but not final, which violates secure coding principles") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/FileCreateTempFileRule.groovy0000644000175000017500000000344712006632020030416 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * The File.createTempFile() method is insecure, and has been deprecated by the ESAPI secure coding library. * It has been replaced by the ESAPI Randomizer.getRandomFilename(String) method. * * By default, this rule does not apply to test files. * * @author Hamlet D'Arcy */ class FileCreateTempFileRule extends AbstractAstVisitorRule { String name = 'FileCreateTempFile' int priority = 2 Class astVisitorClass = FileCreateTempFileAstVisitor String doNotApplyToFilesMatching = DEFAULT_TEST_FILES } class FileCreateTempFileAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, 'File', 'createTempFile', 2) || AstUtil.isMethodCall(call, 'File', 'createTempFile', 3)) { addViolation(call, 'The method File.createTempFile is insecure. Use a secure API such as that provided by ESAPI') } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/ObjectFinalizeRule.groovy0000644000175000017500000000277512006632020027660 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * The finalize() method should only be called by the JVM after the object has been garbage collected. * * @author 'Hamlet D'Arcy' */ class ObjectFinalizeRule extends AbstractAstVisitorRule { String name = 'ObjectFinalize' int priority = 2 Class astVisitorClass = ObjectFinalizeAstVisitor } class ObjectFinalizeAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'finalize', 0)) { addViolation(call, 'The finalize() method should only be called by the JVM after the object has been garbage collected') } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/SystemExitRule.groovy0000644000175000017500000000302712006632012027076 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Web applications should never call System.exit(). A call to System.exit() is probably part of leftover debug code or code imported from a non-J2EE application. * * @author 'Hamlet D'Arcy' */ class SystemExitRule extends AbstractAstVisitorRule { String name = 'SystemExit' int priority = 2 Class astVisitorClass = SystemExitAstVisitor } class SystemExitAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, 'System', 'exit', 1)) { addViolation(call, 'Calling System.exit() is insecure and can expose a denial of service attack') } } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/NonFinalSubclassOfSensitiveInterfaceRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/NonFinalSubclassOfSensitiveInterfaceRule.gr0000644000175000017500000000561312311370173033260 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import java.lang.reflect.Modifier import java.security.BasicPermission import java.security.Permission import java.security.PrivilegedAction import java.security.PrivilegedActionException /** * The permissions classes such as java.security.Permission and java.security.BasicPermission are designed to be extended. * Classes that derive from these permissions classes, however, must prohibit extension. This prohibition ensures that * malicious subclasses cannot change the properties of the derived class. Classes that implement sensitive interfaces * such as java.security.PrivilegedAction and java.security.PrivilegedActionException must also be declared final for * analogous reasons. * * @author Hamlet D'Arcy */ class NonFinalSubclassOfSensitiveInterfaceRule extends AbstractAstVisitorRule { String name = 'NonFinalSubclassOfSensitiveInterface' int priority = 2 Class astVisitorClass = NonFinalSubclassOfSensitiveInterfaceAstVisitor } class NonFinalSubclassOfSensitiveInterfaceAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { if (!Modifier.isFinal(node.modifiers)) { if (AstUtil.classNodeImplementsType(node, Permission)) { addViolation(node, "The class $node.nameWithoutPackage extends java.security.Permission but is not final") } else if (AstUtil.classNodeImplementsType(node, BasicPermission)) { addViolation(node, "The class $node.nameWithoutPackage extends java.security.BasicPermission but is not final") } else if (AstUtil.classNodeImplementsType(node, PrivilegedAction)) { addViolation(node, "The class $node.nameWithoutPackage implements java.security.PrivilegedAction but is not final") } else if (AstUtil.classNodeImplementsType(node, PrivilegedActionException)) { addViolation(node, "The class $node.nameWithoutPackage extends java.security.PrivilegedActionException but is not final") } } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/UnsafeArrayDeclarationRule.groovy0000644000175000017500000000371312311370173031356 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * Triggers a violation when an array is declared public, final, and static. Secure coding principles state that, in most cases, an array declared public, final and static is a bug because arrays are mutable objects. * * @author 'Hamlet D'Arcy' */ class UnsafeArrayDeclarationRule extends AbstractAstVisitorRule { String name = 'UnsafeArrayDeclaration' int priority = 2 Class astVisitorClass = UnsafeArrayDeclarationAstVisitor } class UnsafeArrayDeclarationAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (isPublicStaticFinal(node) && isArray(node)) { addViolation(node, "The Array field $node.name is public, static, and final but still mutable") } } private static boolean isArray(FieldNode node) { AstUtil.getFieldType(node)?.isArray() } private static boolean isPublicStaticFinal(FieldNode node) { Modifier.isFinal(node.modifiers) && Modifier.isStatic(node.modifiers) && Modifier.isPublic(node.modifiers) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/PublicFinalizeMethodRule.groovy0000644000175000017500000000306712041061502031024 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * Creates a violation when the program violates secure coding principles by declaring a finalize() method public. * * @author Hamlet D'Arcy */ class PublicFinalizeMethodRule extends AbstractAstVisitorRule { String name = 'PublicFinalizeMethod' int priority = 2 Class astVisitorClass = PublicFinalizeMethodAstVisitor } class PublicFinalizeMethodAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (AstUtil.isMethodNode(node, 'finalize', 0) && !Modifier.isProtected(node.modifiers)) { addViolation(node, 'The finalize() method should only be declared with protected visibility') } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/JavaIoPackageAccessRule.groovy0000644000175000017500000000713412311370173030540 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * This rule reports violations of the Enterprise JavaBeans specification by using the java.io package to access files or the file system. * * @author 'Hamlet D'Arcy' */ class JavaIoPackageAccessRule extends AbstractAstVisitorRule { String name = 'JavaIoPackageAccess' int priority = 2 Class astVisitorClass = JavaIoPackageAccessAstVisitor String doNotApplyToFilesMatching = DEFAULT_TEST_FILES } class JavaIoPackageAccessAstVisitor extends AbstractAstVisitor { @Override void visitConstructorCallExpression(ConstructorCallExpression call) { if (AstUtil.classNodeImplementsType(call.type, File)) { def argCount = AstUtil.getMethodArguments(call).size() if (argCount == 1 || argCount == 2) { addViolation(call, 'The use of java.io.File violates the Enterprise Java Bean specification') } } else if (AstUtil.classNodeImplementsType(call.type, FileOutputStream)) { def argCount = AstUtil.getMethodArguments(call).size() if (argCount == 1 || argCount == 2) { addViolation(call, 'The use of java.io.FileOutputStream violates the Enterprise Java Bean specification') } } else if (AstUtil.classNodeImplementsType(call.type, FileReader)) { def argCount = AstUtil.getMethodArguments(call).size() if (argCount == 1) { addViolation(call, 'The use of java.io.FileReader violates the Enterprise Java Bean specification') } } else if (AstUtil.classNodeImplementsType(call.type, RandomAccessFile)) { def argCount = AstUtil.getMethodArguments(call).size() if (argCount == 2) { addViolation(call, 'The use of java.io.RandomAccessFile violates the Enterprise Java Bean specification') } } super.visitConstructorCallExpression(call) } @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCallOnObject(call, 'FileSystem')) { addViolation(call, 'The use of java.io.FileSystem violates the Enterprise Java Bean specification') } super.visitMethodCallExpression(call) } @Override void visitPropertyExpression(PropertyExpression expression) { if (expression.objectExpression instanceof VariableExpression) { if (expression.objectExpression.variable == 'FileSystem') { addViolation(expression, 'The use of java.io.FileSystem violates the Enterprise Java Bean specification') } } super.visitPropertyExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/security/UnsafeImplementationAsMapRule.groovy0000644000175000017500000000540112225130172032032 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.security import org.codehaus.groovy.ast.expr.CastExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.MapExpression import org.codehaus.groovy.control.Phases import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor /** * Reports incomplete interface implementations created by map-to-interface coercions. * * Example: * [hasNext: { ... }] as Iterator * (Not all Iterator methods are implemented. An UnsupportedOperationException will be thrown upon call to e.g. next().) * * By default, this rule does not apply to test files. * * @author Artur Gajowy */ class UnsafeImplementationAsMapRule extends AbstractAstVisitorRule { String name = 'UnsafeImplementationAsMap' int priority = 2 Class astVisitorClass = UnsafeImplementationAsMapAstVisitor int compilerPhase = Phases.SEMANTIC_ANALYSIS String doNotApplyToFilesMatching = DEFAULT_TEST_FILES } class UnsafeImplementationAsMapAstVisitor extends AbstractAstVisitor { @Override void visitCastExpression(CastExpression cast) { if (isFirstVisit(cast) && cast.type.isInterface() && cast.expression instanceof MapExpression) { def interfaceMethods = cast.type.abstractMethods*.name as Set def implementedMethods = getMethodsImplementedByCoercion(cast.expression) def unimplementedMethods = (interfaceMethods - implementedMethods).sort() if (unimplementedMethods) { addViolation(cast, "Incomplete interface implementation. The following methods of $cast.type.name" + " are not implemented by this map-to-interface coercion: $unimplementedMethods. Please note that" + ' calling any of these methods on this implementation will cause' + ' an UnsupportedOperationException, which is likely not intended.') } } } private List getMethodsImplementedByCoercion(MapExpression methodMap) { List methodNames = methodMap.mapEntryExpressions*.keyExpression.grep(ConstantExpression) methodNames*.value } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/braces/0000755000175000017500000000000012623571301022257 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/braces/WhileStatementBracesRule.groovy0000644000175000017500000000277412311373552030447 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.braces import org.codehaus.groovy.ast.stmt.WhileStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks that while statements use braces rather than a single statement. * * @author Chris Mair */ class WhileStatementBracesRule extends AbstractAstVisitorRule { String name = 'WhileStatementBraces' int priority = 2 Class astVisitorClass = WhileStatementBracesAstVisitor } class WhileStatementBracesAstVisitor extends AbstractAstVisitor { void visitWhileLoop(WhileStatement whileStatement) { if (isFirstVisit(whileStatement) && !AstUtil.isBlock(whileStatement.loopBlock)) { addViolation(whileStatement, 'The while statement lacks braces') } super.visitWhileLoop(whileStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/braces/IfStatementBracesRule.groovy0000644000175000017500000000271512311373552027730 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.braces import org.codehaus.groovy.ast.stmt.IfStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks that if statements use braces rather than a single statement. * * @author Chris Mair */ class IfStatementBracesRule extends AbstractAstVisitorRule { String name = 'IfStatementBraces' int priority = 2 Class astVisitorClass = IfStatementBracesAstVisitor } class IfStatementBracesAstVisitor extends AbstractAstVisitor { void visitIfElse(IfStatement ifStatement) { if (isFirstVisit(ifStatement) && !AstUtil.isBlock(ifStatement.ifBlock)) { addViolation(ifStatement, 'The if statement lacks braces') } super.visitIfElse(ifStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/braces/ElseBlockBracesRule.groovy0000644000175000017500000000364312311373552027351 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.braces import org.codehaus.groovy.ast.stmt.EmptyStatement import org.codehaus.groovy.ast.stmt.IfStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks that else blocks use braces rather than a single statement. *

* By default, braces are not required for an else if it is followed immediately * by an if. Set the bracesRequiredForElseIf property to true to * require braces is that situation as well. * * @author Chris Mair */ class ElseBlockBracesRule extends AbstractAstVisitorRule { String name = 'ElseBlockBraces' int priority = 2 boolean bracesRequiredForElseIf = false Class astVisitorClass = ElseBlockBracesAstVisitor } class ElseBlockBracesAstVisitor extends AbstractAstVisitor { void visitIfElse(IfStatement ifStatement) { if (isFirstVisit(ifStatement) && !(ifStatement.elseBlock instanceof EmptyStatement) && !AstUtil.isBlock(ifStatement.elseBlock)) { if (!(ifStatement.elseBlock instanceof IfStatement) || rule.bracesRequiredForElseIf) { addViolation(ifStatement, 'The else block lacks braces') } } super.visitIfElse(ifStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/braces/ForStatementBracesRule.groovy0000644000175000017500000000273412311373552030121 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.braces import org.codehaus.groovy.ast.stmt.ForStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks that for statements use braces rather than a single statement. * * @author Chris Mair */ class ForStatementBracesRule extends AbstractAstVisitorRule { String name = 'ForStatementBraces' int priority = 2 Class astVisitorClass = ForStatementBracesAstVisitor } class ForStatementBracesAstVisitor extends AbstractAstVisitor { void visitForLoop(ForStatement forStatement) { if (isFirstVisit(forStatement) && !AstUtil.isBlock(forStatement.loopBlock)) { addViolation(forStatement, 'The for statement lacks braces') } super.visitForLoop(forStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/InlineViolationsParser.groovy0000644000175000017500000000466312236327370026750 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule /** * Parser for inline violation metadata within Rule test classes * * @author Artur Gajowy */ class InlineViolationsParser { protected static String inlineViolation(String violationMessage) { '#' + violationMessage.replaceAll(~/\Q#\E/, /\\#/) + PREVENT_ACCIDENTAL_ESCAPING_OF_NEXT_MARKER } private static final String PREVENT_ACCIDENTAL_ESCAPING_OF_NEXT_MARKER = ' ' def result = new ParseResult() ParseResult parse(String annotatedSource) { annotatedSource.eachLine(1, this.&parseLine) result.source = result.source.replaceFirst(~/\n$/, '') result } private void parseLine(String lineWithInlineViolations, int lineNumber) { def splitByViolationMarkerPattern = lineNumber == 1 ? HASH_NOT_ESCAPED_NOT_PART_OF_SHEBANG : HASH_NOT_ESCAPED def splitByMarker = lineWithInlineViolations.split(splitByViolationMarkerPattern, KEEP_EMPTY_STRINGS) def (sourceLine, violationMessages) = [splitByMarker.head(), splitByMarker.tail()] result.source += sourceLine.replaceAll(~/\s+$/, '') + '\n' result.violations += violationMessages.collect { createViolation(lineNumber, sourceLine.trim(), unescape(it.trim())) } } private static final String HASH_NOT_ESCAPED = /(? violations = [] } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/jdbc/0000755000175000017500000000000012623571301021722 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/jdbc/DirectConnectionManagementRule.groovy0000644000175000017500000000510112006632014031237 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * The J2EE standard requires that applications use the container's resource management facilities to obtain * connections to resources. Every major web application container provides pooled database connection management as * part of its resource management framework. Duplicating this functionality in an application is difficult and * error prone, which is part of the reason it is forbidden under the J2EE standard. * * @author 'Hamlet D'Arcy' */ class DirectConnectionManagementRule extends AbstractAstVisitorRule { String name = 'DirectConnectionManagement' int priority = 2 Class astVisitorClass = DirectConnectionManagementAstVisitor } class DirectConnectionManagementAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, 'DriverManager', 'getConnection')) { addViolation(call, 'Using DriverManager.getConnection() violates the J2EE standards. Use the connection from the context instead') } else if (AstUtil.isMethodNamed(call, 'getConnection') && isJavaSQLDriverManagerCall(call)) { addViolation(call, 'Using DriverManager.getConnection() violates the J2EE standards. Use the connection from the context instead') } } private static boolean isJavaSQLDriverManagerCall(MethodCallExpression call) { if (AstUtil.isPropertyNamed(call.objectExpression, 'DriverManager')) { if (AstUtil.isPropertyNamed(call.objectExpression.objectExpression, 'sql')) { if (AstUtil.isVariable(call.objectExpression.objectExpression.objectExpression, 'java')) { return true } } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/jdbc/JdbcConnectionReferenceRule.groovy0000644000175000017500000000232012006632014030511 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.ClassReferenceAstVisitor /** * Check for direct use of java.sql.Connection. * * Known limitation: Does not catch references as Anonymous Inner class: def x = new java.sql.Connection() { .. } * * @author Chris Mair */ class JdbcConnectionReferenceRule extends AbstractAstVisitorRule { String name = 'JdbcConnectionReference' int priority = 2 @Override AstVisitor getAstVisitor() { new ClassReferenceAstVisitor('java.sql.Connection') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/jdbc/JdbcResultSetReferenceRule.groovy0000644000175000017500000000245512006632016030357 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.ClassReferenceAstVisitor /** * Check for direct use of java.sql.ResultSet, which is not necessary if using the Groovy Sql facility or an * ORM framework such as Hibernate. * * Known limitation: Does not catch references as Anonymous Inner class: def x = new java.sql.ResultSet() { .. } * * @author Chris Mair */ class JdbcResultSetReferenceRule extends AbstractAstVisitorRule { String name = 'JdbcResultSetReference' int priority = 2 @Override AstVisitor getAstVisitor() { new ClassReferenceAstVisitor('java.sql.ResultSet') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/jdbc/JdbcStatementReferenceRule.groovy0000644000175000017500000000261612006632016030370 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.ClassReferenceAstVisitor /** * Check for direct use of java.sql.Statement, PreparedStatement, or CallableStatement, which is not necessary if * using the Groovy Sql facility or an ORM framework such as Hibernate. * * Known limitation: Does not catch references as Anonymous Inner class: def x = new java.sql.Statement() { .. } * * @author Chris Mair */ class JdbcStatementReferenceRule extends AbstractAstVisitorRule { String name = 'JdbcStatementReference' int priority = 2 @Override AstVisitor getAstVisitor() { new ClassReferenceAstVisitor('java.sql.Statement, java.sql.PreparedStatement, java.sql.CallableStatement') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/0000755000175000017500000000000012623571301022446 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/SystemErrPrintRule.groovy0000644000175000017500000000302512311373552027521 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor /** * Rule that checks for calls to System.err.print(), System.err.println() * or System.err.printf(). * * @author Chris Mair */ class SystemErrPrintRule extends AbstractAstVisitorRule { String name = 'SystemErrPrint' int priority = 2 Class astVisitorClass = SystemErrPrintAstVisitor } class SystemErrPrintAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression methodCall) { if (methodCall.text.startsWith('System.err.print')) { addViolation(methodCall, "System.err.$methodCall.methodAsString should be replaced with something more robust") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/PrintStackTraceRule.groovy0000644000175000017500000000331612311373552027613 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Rule that checks for calls to printStackTrace(). * * @author Chris Mair * @author Hamlet D'Arcy */ class PrintStackTraceRule extends AbstractAstVisitorRule { String name = 'PrintStackTrace' int priority = 2 Class astVisitorClass = PrintStackTraceAstVisitor } class PrintStackTraceAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression methodCall) { if (AstUtil.isMethodNamed(methodCall, 'printStackTrace', 0)) { addViolation(methodCall, 'printStackTrace() should be replaced with something more robust') } if (AstUtil.isMethodNamed(methodCall, 'printSanitizedStackTrace', 1)) { addViolation(methodCall, 'printSanitizedStackTrace() should be replaced with something more robust') } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/LoggerForDifferentClassRule.groovy0000644000175000017500000001151112311373552031251 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.logging import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.InnerClassNode import org.codehaus.groovy.ast.expr.Expression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor /** * Rule that checks for instantiating a logger for a class other than the current class. Supports logger * instantiations for Log4J, Logback, SLF4J, Apache Commons Logging, Java Logging API (java.util.logging). * * Limitations: *

    *
  • Only checks Loggers instantiated within a class field or property (not variables or expressions within a method)
  • *
  • For Log4J: Does not catch Logger instantiations if you specify the full package name for the Logger class: * e.g. org.apache.log4.Logger.getLogger(..)
  • *
  • For SLF4J and Logback: Does not catch Log instantiations if you specify the full package name for the LoggerFactory * class: e.g. org.slf4j.LoggerFactory.getLogger(..)
  • *
  • For Commons Logging: Does not catch Log instantiations if you specify the full package name for the LogFactory * class: e.g. org.apache.commons.logging.LogFactory.getLog(..)
  • *
  • For Java Logging API: Does not catch Logger instantiations if you specify the full package name for the Logger * class: e.g. java.util.logging.Logger.getLogger(..)
  • *
* * @author Chris Mair */ class LoggerForDifferentClassRule extends AbstractAstVisitorRule { String name = 'LoggerForDifferentClass' int priority = 2 boolean allowDerivedClasses = false Class astVisitorClass = LoggerForDifferentClassAstVisitor } class LoggerForDifferentClassAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode fieldNode) { def expression = fieldNode.getInitialExpression() if (LogUtil.isMatchingLoggerDefinition(expression)) { def firstArg = expression.arguments?.expressions?.get(0) def argText = firstArg.text final CLASSNAME_WITHOUT_PACKAGE if (fieldNode.owner instanceof InnerClassNode) { CLASSNAME_WITHOUT_PACKAGE = fieldNode.owner.nameWithoutPackage - "$fieldNode.owner.outerClass.nameWithoutPackage\$" } else { CLASSNAME_WITHOUT_PACKAGE = fieldNode.declaringClass.nameWithoutPackage } if (!rule.allowDerivedClasses && isCapitalized(argText) && !isEqualToCurrentClassOrClassName(argText, CLASSNAME_WITHOUT_PACKAGE)) { addViolation(fieldNode, "Logger is defined in $CLASSNAME_WITHOUT_PACKAGE but initialized with $argText") } else if (rule.allowDerivedClasses && !isLoggerForDerivedClass(fieldNode)) { addViolation(fieldNode, "Logger is defined in $CLASSNAME_WITHOUT_PACKAGE but initialized with $argText") } } } private static boolean isEqualToCurrentClassOrClassName(String argText, classNameWithoutPackage) { return isEqualToCurrentClass(argText, classNameWithoutPackage) || isEqualToCurrentClassName(argText, classNameWithoutPackage) } private static boolean isEqualToCurrentClass(String argText, classNameWithoutPackage) { return (argText == classNameWithoutPackage) || (argText == classNameWithoutPackage + '.class') } private static boolean isLoggerForDerivedClass(FieldNode fieldNode) { Expression methodArgument = fieldNode.getInitialValueExpression().arguments.expressions.first() methodArgument.text in ['this.class', 'this.getClass()', 'getClass()'] } private static boolean isEqualToCurrentClassName(String argText, classNameWithoutPackage) { def classNameOptions = [ classNameWithoutPackage + '.getClass().getName()', classNameWithoutPackage + '.getClass().name', classNameWithoutPackage + '.class.getName()', classNameWithoutPackage + '.class.name', classNameWithoutPackage + '.name', ] return argText in classNameOptions } private static boolean isCapitalized(String text) { def firstCharacter = text[0] return firstCharacter.toUpperCase() == firstCharacter } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/MultipleLoggersRule.groovy0000644000175000017500000000345612006632014027665 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor /** * This rule catches classes that have more than one logger object defined. Typically, a class has zero or one logger objects. * * @author 'Hamlet D'Arcy' */ class MultipleLoggersRule extends AbstractAstVisitorRule { String name = 'MultipleLoggers' int priority = 2 Class astVisitorClass = MultipleLoggersAstVisitor } class MultipleLoggersAstVisitor extends AbstractFieldVisitor { Map> classNodeToFieldNames = [:] @Override void visitField(FieldNode fieldNode) { if (LogUtil.isMatchingLoggerDefinition(fieldNode.getInitialExpression())) { List logFields = classNodeToFieldNames[fieldNode.declaringClass] if (logFields) { logFields.add(fieldNode.name) addViolation(fieldNode, 'The class defines multiple loggers: ' + logFields.join(', ')) } else { classNodeToFieldNames[fieldNode.declaringClass] = [fieldNode.name] } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/LoggerWithWrongModifiersRule.groovy0000644000175000017500000000561412041061504031476 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import java.lang.reflect.Modifier /** * Logger objects should be declared private, static and final. * The exception is, when derived classes should use logger objects. Then they should be declared protected, non-static and final. * This rule find loggers that are not declared with these modifiers. * * @author Hamlet D'Arcy * @author René Scheibe */ class LoggerWithWrongModifiersRule extends AbstractAstVisitorRule { String name = 'LoggerWithWrongModifiers' int priority = 2 boolean allowProtectedLogger = false boolean allowNonStaticLogger = false Class astVisitorClass = LoggerWithWrongModifiersAstVisitor } class LoggerWithWrongModifiersAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode fieldNode) { if (LogUtil.isMatchingLoggerDefinition(fieldNode.getInitialExpression())) { int modifiers = fieldNode.modifiers boolean isPrivate = Modifier.isPrivate(modifiers) boolean isProtected = Modifier.isProtected(modifiers) boolean isFinal = Modifier.isFinal(modifiers) boolean isStatic = Modifier.isStatic(modifiers) if (!isPrivate && !rule.allowProtectedLogger) { addViolationForField(fieldNode) } else if ((!isPrivate && !isProtected) && rule.allowProtectedLogger) { addViolationForField(fieldNode) } else if (!isFinal) { addViolationForField(fieldNode) } else if (!isStatic && !rule.allowNonStaticLogger) { addViolationForField(fieldNode) } else if ((!isPrivate && !isProtected) && rule.allowProtectedLogger) { addViolationForField(fieldNode) } } } private addViolationForField(FieldNode fieldNode) { def visibility = rule.allowProtectedLogger ? 'private (or protected)' : 'private' def staticness = rule.allowNonStaticLogger ? '' : ', static' addViolation(fieldNode, "The Logger field $fieldNode.name should be ${visibility}${staticness} and final") } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/LogUtil.groovy0000644000175000017500000000205512006632016025272 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.logging import org.codenarc.util.AstUtil /** * Utility methods for Logging rules * @author Hamlet D'Arcy */ class LogUtil { static boolean isMatchingLoggerDefinition(expression) { return AstUtil.isMethodCall(expression, 'Logger', 'getLogger', 1) || AstUtil.isMethodCall(expression, 'LogFactory', 'getLog', 1) || AstUtil.isMethodCall(expression, 'LoggerFactory', 'getLogger', 1) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/LoggingSwallowsStacktraceRule.groovy0000644000175000017500000000555612006632020031676 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.CatchStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * If you are logging an exception then the proper API is to call error(Object, Throwable), which will log the message * and the exception stack trace. If you call error(Object) then the stacktrace may not be logged. * * @author Hamlet D'Arcy */ class LoggingSwallowsStacktraceRule extends AbstractAstVisitorRule { String name = 'LoggingSwallowsStacktrace' int priority = 2 Class astVisitorClass = LoggingSwallowsStacktraceAstVisitor } class LoggingSwallowsStacktraceAstVisitor extends AbstractAstVisitor { Map> classNodeToLoggerNames = [:] @Override void visitField(FieldNode fieldNode) { if (LogUtil.isMatchingLoggerDefinition(fieldNode.getInitialExpression())) { List logFields = classNodeToLoggerNames[fieldNode.declaringClass] if (logFields) { logFields.add(fieldNode.name) } else { classNodeToLoggerNames[fieldNode.declaringClass] = [fieldNode.name] } } super.visitField(fieldNode) } @Override void visitCatchStatement(CatchStatement statement) { if (currentClassNode && statement.code instanceof BlockStatement) { List loggerNames = classNodeToLoggerNames[currentClassNode] def expressions = statement.code.statements.findAll { it instanceof ExpressionStatement && it.expression instanceof MethodCallExpression } expressions*.expression.each { MethodCallExpression it -> if (AstUtil.isMethodCall(it, loggerNames, ['error'], 1)) { addViolation(it, 'The error logging may hide the stacktrace from the exception named ' + statement.variable.name) } } } super.visitCatchStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/SystemOutPrintRule.groovy0000644000175000017500000000275512311373552027551 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor /** * Rule that checks for calls to System.out.print(), System.out.println() * or System.out.printf(). * * @author Chris Mair */ class SystemOutPrintRule extends AbstractAstVisitorRule { String name = 'SystemOutPrint' int priority = 2 Class astVisitorClass = SystemOutPrintAstVisitor } class SystemOutPrintAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression methodCall) { if (methodCall.text.startsWith('System.out.print')) { addViolation(methodCall, "System.out.$methodCall.methodAsString should be replaced with something more robust") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/logging/PrintlnRule.groovy0000644000175000017500000000545412311373552026205 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for calls to this.print(), this.println() * or this.printf(). * * @author Chris Mair * @author Hamlet D'Arcy */ class PrintlnRule extends AbstractAstVisitorRule { String name = 'Println' int priority = 2 Class astVisitorClass = PrintlnAstVisitor } class PrintlnAstVisitor extends AbstractAstVisitor { boolean printlnMethodDefined = false boolean printlnClosureDefined = false @Override protected void visitClassEx(ClassNode node) { printlnMethodDefined = node?.methods?.any { MethodNode it -> it.name == 'println' || it.name == 'print' } printlnClosureDefined = node?.fields?.any { FieldNode it -> AstUtil.isClosureDeclaration(it) && (it.name == 'println' || it.name == 'print') } } @Override protected void visitClassComplete(ClassNode node) { printlnMethodDefined = false printlnClosureDefined = false } @SuppressWarnings('DuplicateLiteral') void visitMethodCallExpression(MethodCallExpression methodCall) { if (printlnMethodDefined || printlnClosureDefined) { return } if (isFirstVisit(methodCall)) { def isMatch = AstUtil.isMethodCall(methodCall, 'this', 'println', 0) || AstUtil.isMethodCall(methodCall, 'this', 'println', 1) || AstUtil.isMethodCall(methodCall, 'this', 'print', 1) || (AstUtil.isMethodCall(methodCall, 'this', 'printf') && AstUtil.getMethodArguments(methodCall).size() > 1) if (isMatch) { addViolation(methodCall, 'println should be replaced with something more robust') } } super.visitMethodCallExpression(methodCall) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/0000755000175000017500000000000012623571301021772 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/CrapMetricRule.groovy0000644000175000017500000001513012311373552026124 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.size import org.apache.log4j.Logger import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.util.io.DefaultResourceFactory import org.gmetrics.metric.coverage.CoberturaLineCoverageMetric import org.gmetrics.metric.crap.CrapMetric /** * Rule that calculates the CRAP Metric for methods/classes and checks against * configured threshold values. *

* Note that this rule requires the GMetrics 0.5 (or later) jar on the classpath, as well as * a Cobertura XML coverage file. If either of these prerequisites is not available, this rule * logs a warning messages and exits (i.e., does nothing). *

* The coberturaXmlFile property must be set to the path to the Cobertura XML coverage file * for the Groovy code being analyzed. By default, the path is relative to the classpath. But the path * may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from * a relative or absolute path on the filesystem), or "http:". This property is REQUIRED. *

* The maxMethodCrapScore property holds the threshold value for the CRAP crapMetric * value for each method. If this value is non-zero, a method with a CRAP score value greater than * this value is considered a violation. The maxMethodCrapScore property defaults to 30. *

* The maxClassAverageCrapScore property holds the threshold value for the average CRAP * crapMetric value for each class. If this value is non-zero, a class with an average CRAP score * value greater than this value is considered a violation. The maxMethodAverageCrapScore property * defaults to 30. *

* The maxClassCrapScore property holds the threshold value for the total CRAP * crapMetric value for each class. If this value is non-zero, a class with a total CRAP score * value greater than this value is considered a violation. The maxClassCrapScore property * defaults to 0. *

* The ignoreMethodNames property optionally specifies one or more (comma-separated) method * names that should be ignored (i.e., that should not cause a rule violation). The name(s) may optionally * include wildcard characters ('*' or '?'). Note that the ignored methods still contribute to the class * complexity value. *

* This rule does NOT treat "closure fields" as methods (unlike some of the other size/complexity rules). * * @see The original 2007 blog post that defined the CRAP crapMetric. * @see A 2011 blog post from Alberto Savoia, describing the formula, the motivation, and the CRAP4J tool. * @see GMetrics CRAP crapMetric. * * @author Chris Mair */ class CrapMetricRule extends AbstractAstVisitorRule { private static final LOG = Logger.getLogger(CrapMetricRule) String name = 'CrapMetric' int priority = 2 BigDecimal maxMethodCrapScore = 30 BigDecimal maxClassAverageMethodCrapScore = 30 BigDecimal maxClassCrapScore = 0 String coberturaXmlFile String ignoreMethodNames protected String crapMetricClassName = 'org.gmetrics.metric.crap.CrapMetric' private Boolean ready private crapMetric // omit CrapMetric type; it may not be on the classpath private final readyLock = new Object() private final createMetricLock = new Object() private final resourceFactory = new DefaultResourceFactory() @Override AstVisitor getAstVisitor() { return new CrapMetricAstVisitor(createCrapMetric()) } @Override boolean isReady() { synchronized(readyLock) { if (ready == null) { ready = true if (!doesCoberturaXmlFileExist()) { LOG.warn("The Cobertura XML file [$coberturaXmlFile] is not accessible; skipping this rule") ready = false } if (!isCrapMetricClassOnClasspath()) { LOG.warn('The GMetrics CrapMetric class is not on the classpath; skipping this rule') ready = false } } } return ready } private boolean doesCoberturaXmlFileExist() { if (!coberturaXmlFile) { return false } def resource = resourceFactory.getResource(coberturaXmlFile) return resource.exists() } private createCrapMetric() { // omit CrapMetric type; it may not be on the classpath synchronized(createMetricLock) { if (!crapMetric) { def coverageMetric = new CoberturaLineCoverageMetric(coberturaFile:coberturaXmlFile) crapMetric = new CrapMetric(coverageMetric:coverageMetric) } } return crapMetric } private boolean isCrapMetricClassOnClasspath() { try { getClass().classLoader.loadClass(crapMetricClassName) return true } catch (ClassNotFoundException e) { return false } } } class CrapMetricAstVisitor extends AbstractMethodMetricAstVisitor { final String metricShortDescription = 'CRAP score' private final CrapMetric crapMetric protected CrapMetricAstVisitor(CrapMetric crapMetric) { this.crapMetric = crapMetric } @Override protected Object createMetric() { return crapMetric } @Override protected Object getMaxMethodMetricValue() { rule.maxMethodCrapScore } @Override protected Object getMaxClassAverageMethodMetricValue() { rule.maxClassAverageMethodCrapScore } protected Object getMaxClassMetricValue() { rule.maxClassCrapScore } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/AbcComplexityRule.groovy0000644000175000017500000000775012311373552026647 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractAstVisitorRule import org.gmetrics.metric.abc.AbcMetric /** * Rule that calculates the ABC Complexity for methods/classes and checks against * configured threshold values. *

* The maxMethodComplexity property holds the threshold value for the ABC complexity value * (magnitude) for each method. If this value is non-zero, a method with a cyclomatic complexity value greater than * this value is considered a violation. The value does not have to be an integer (i.e., 1.7 is allowed). The * maxMethodComplexity property defaults to 60. *

* The maxClassAverageMethodComplexity property holds the threshold value for the average ABC * complexity value for each class. If this value is non-zero, a class with an average ABC complexity * value greater than this value is considered a violation. The value does not have to be an integer * (i.e., 1.7 is allowed). The maxClassAverageMethodComplexity property defaults to 60. *

* The maxClassComplexity property holds the threshold value for the total ABC * complexity value for each class. If this value is non-zero, a class with a total ABC complexity * value greater than this value is considered a violation. The value does not have to be an integer * (i.e., 1.7 is allowed). The maxClassComplexity property defaults to 0. *

* The ignoreMethodNames property optionally specifies one or more (comma-separated) method * names that should be ignored (i.e., that should not cause a rule violation). The name(s) may optionally * include wildcard characters ('*' or '?'). Note that the ignored methods still contribute to the class * complexity value. *

* This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), * then that Closure is analyzed and checked just like a method. * * @see ABC Metric specification. * @see Blog post describing guidelines for interpreting an ABC score. * @see GMetrics ABC metric. * * @deprecated This rule is deprecated and disabled (enabled=false) by default. Use AbcMetric rule instead. * * @author Chris Mair */ class AbcComplexityRule extends AbstractAstVisitorRule { String name = 'AbcComplexity' int priority = 2 Class astVisitorClass = AbcComplexityAstVisitor int maxMethodComplexity = 60 int maxClassAverageMethodComplexity = 60 int maxClassComplexity = 0 String ignoreMethodNames AbcComplexityRule() { this.enabled = false // deprecated; disabled by default } } class AbcComplexityAstVisitor extends AbstractMethodMetricAstVisitor { final String metricShortDescription = 'ABC score' protected Object createMetric() { new AbcMetric() } protected Object getMaxMethodMetricValue() { rule.maxMethodComplexity } protected Object getMaxClassAverageMethodMetricValue() { rule.maxClassAverageMethodComplexity } protected Object getMaxClassMetricValue() { rule.maxClassComplexity } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/MethodCountRule.groovy0000644000175000017500000000271612006632012026320 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.size import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * A class with too many methods is probably a good suspect for refactoring, in order to reduce its complexity and find * a way to have more fine-grained objects. * * @author Tomasz Bujok * @author Hamlet D'Arcy */ class MethodCountRule extends AbstractAstVisitorRule { String name = 'MethodCount' int priority = 2 Class astVisitorClass = MethodCountAstVisitor int maxMethods = 30 } class MethodCountAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode node) { if (node.methods?.size() > rule.maxMethods) { addViolation(node, "Class $node.name has ${node.methods?.size()} methods") } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/NestedBlockDepthRule.groovy0000644000175000017500000001204512311373553027260 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.size import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.stmt.* /** * Rule that checks for blocks or closures nested more than a configured maximum number. * Blocks include if, for, while, switch, try, catch, finally and synchronized * blocks/statements, as well as closures. *

* The maxNestedBlockDepth property holds the threshold value for the maximum number of * nesting levels. A block or closures nested deeper than that number of levels is considered a * violation. The maxNestedBlockDepth property defaults to 3. * * @author Chris Mair * @author Hamlet D'Arcy */ class NestedBlockDepthRule extends AbstractAstVisitorRule { String name = 'NestedBlockDepth' int priority = 2 int maxNestedBlockDepth = 5 String ignoreRegex = '.*(b|B)uilder' Class astVisitorClass = NestedBlockDepthAstVisitor } class NestedBlockDepthAstVisitor extends AbstractAstVisitor { private final Set blocksToProcess = [] private Set closureFieldExpressions private nestedBlockDepth = 0 void visitClassEx(ClassNode classNode) { addClosureFields(classNode) super.visitClassEx(classNode) } private void addClosureFields(ClassNode classNode) { closureFieldExpressions = [] classNode.fields.each { fieldNode -> if (!AstUtil.isFromGeneratedSourceCode(fieldNode) && fieldNode.initialExpression instanceof ClosureExpression) { closureFieldExpressions << fieldNode.initialExpression } } } void visitBlockStatement(BlockStatement block) { if (isFirstVisit(block) && block in blocksToProcess) { handleNestedNode(block) { super.visitBlockStatement(block) } } else { super.visitBlockStatement(block) } } void visitTryCatchFinally(TryCatchStatement tryCatchStatement) { addBlockIfNotEmpty(tryCatchStatement.tryStatement) addBlockIfNotEmpty(tryCatchStatement.finallyStatement) super.visitTryCatchFinally(tryCatchStatement) } void visitCatchStatement(CatchStatement statement) { handleNestedNode(statement) { super.visitCatchStatement(statement) } } private void addBlockIfNotEmpty(block) { if (!(block instanceof EmptyStatement)) { blocksToProcess << block } } void visitIfElse(IfStatement ifStatement) { if (isFirstVisit(ifStatement)) { addBlockIfNotEmpty(ifStatement.ifBlock) addBlockIfNotEmpty(ifStatement.elseBlock) } super.visitIfElse(ifStatement) } void visitWhileLoop(WhileStatement whileStatement) { handleNestedNode(whileStatement) { super.visitWhileLoop(whileStatement) } } void visitForLoop(ForStatement forStatement) { handleNestedNode(forStatement) { super.visitForLoop(forStatement) } } void visitCaseStatement(CaseStatement statement) { handleNestedNode(statement) { super.visitCaseStatement(statement) } } void visitSynchronizedStatement(SynchronizedStatement statement) { handleNestedNode(statement) { super.visitSynchronizedStatement(statement) } } void visitClosureExpression(ClosureExpression expression) { if (closureFieldExpressions.contains(expression)) { super.visitClosureExpression(expression) } else { handleNestedNode(expression) { super.visitClosureExpression(expression) } } } @Override void visitMethodCallExpression(MethodCallExpression call) { if (!AstUtil.isMethodCallOnObject(call, rule.ignoreRegex) && !AstUtil.isConstructorCall(call.objectExpression, rule.ignoreRegex)) { super.visitMethodCallExpression(call) } } private void handleNestedNode(node, Closure callVisitorMethod) { nestedBlockDepth++ if (nestedBlockDepth > rule.maxNestedBlockDepth) { addViolation(node, "The nested block depth is $nestedBlockDepth") } callVisitorMethod() nestedBlockDepth-- } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/ClassSizeRule.groovy0000644000175000017500000000407112467526132026003 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.size import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.Violation import org.codenarc.util.AstUtil /** * Rule that checks the size of a class. *

* The maxLines property holds the threshold value for the maximum number of lines. A * class length (number of lines) greater than that value is considered a violation. The * maxLines property defaults to 1000. * * @author Chris Mair * @author Hamlet D'Arcy */ class ClassSizeRule extends AbstractAstVisitorRule { String name = 'ClassSize' int priority = 3 Class astVisitorClass = ClassSizeAstVisitor int maxLines = 1000 } class ClassSizeAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode classNode) { if (!AstUtil.isFromGeneratedSourceCode(classNode)) { def numLines = classNode.lastLineNumber - classNode.lineNumber + 1 if (numLines > rule.maxLines) { def className = classNode.name def classNameNoPackage = className[(className.lastIndexOf('.') + 1) .. -1] violations.add(new Violation(rule:rule, lineNumber:classNode.lineNumber, message:"""Class "$classNameNoPackage" is $numLines lines""")) } } super.visitClassEx(classNode) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/ParameterCountRule.groovy0000644000175000017500000000434112444433061027025 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.size import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor /** * Checks if the number of parameters in method/constructor exceeds the number of parameters * specified by the maxParameters property. * * @author Maciej Ziarko */ class ParameterCountRule extends AbstractAstVisitorRule { private static final DEFAULT_MAX_PARAMETER = 5 String name = 'ParameterCount' int priority = 2 Class astVisitorClass = ParameterCountAstVisitor int maxParameters = DEFAULT_MAX_PARAMETER void setMaxParameters(int maxParameters) { if (maxParameters < 1) { throw new IllegalArgumentException("maxParameters property of $name rule must be a positive integer!") } this.maxParameters = maxParameters } } class ParameterCountAstVisitor extends AbstractAstVisitor { @Override protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { checkParametersCount(node) } private void checkParametersCount(MethodNode node) { if (node.parameters.size() > rule.maxParameters) { addViolation(node, "Number of parameters in ${getName(node)} exceeds maximum allowed (${rule.maxParameters}).") } } private String getName(MethodNode methodNode) { return "method ${methodNode.declaringClass.name}.${methodNode.name}" } private String getName(ConstructorNode constructorNode) { return "constructor of class ${constructorNode.declaringClass.name}" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/MethodSizeRule.groovy0000644000175000017500000000473512413643352026160 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.size import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.Violation import org.codenarc.util.WildcardPattern /** * Rule that checks the size of a method. *

* The maxLines property holds the threshold value for the maximum number of lines. A * method length (number of lines) greater than that value is considered a violation. The * maxLines property defaults to 100. *

* The ignoreMethodNames property optionally specifies one or more * (comma-separated) method names that should be ignored (i.e., that should not cause a * rule violation). The name(s) may optionally include wildcard characters ('*' or '?'). * * @author Chris Mair * @author Hamlet D'Arcy */ class MethodSizeRule extends AbstractAstVisitorRule { String name = 'MethodSize' int priority = 3 Class astVisitorClass = MethodSizeAstVisitor int maxLines = 100 String ignoreMethodNames } class MethodSizeAstVisitor extends AbstractAstVisitor { void visitConstructorOrMethod(MethodNode methodNode, boolean isConstructor) { if (methodNode.lineNumber >= 0) { def numLines = methodNode.lastLineNumber - methodNode.lineNumber + 1 if (numLines > rule.maxLines && !isIgnoredMethodName(methodNode)) { def methodName = methodNode.name violations.add(new Violation(rule:rule, lineNumber:methodNode.lineNumber, message:"""Method "$methodName" is $numLines lines""")) } } super.visitConstructorOrMethod(methodNode, isConstructor) } private boolean isIgnoredMethodName(MethodNode node) { new WildcardPattern(rule.ignoreMethodNames, false).matches(node.name) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/GMetricsSourceCodeAdapter.groovy0000644000175000017500000000325012006632016030227 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.size import org.codehaus.groovy.ast.ModuleNode import org.gmetrics.source.SourceCode /** * Adapter that adapts from a GMetrics SourceCode object to a CodeNarc SourceCode object. * * @author Chris Mair */ class GMetricsSourceCodeAdapter implements SourceCode { private final codeNarcSourceCode GMetricsSourceCodeAdapter(org.codenarc.source.SourceCode sourceCode) { assert sourceCode codeNarcSourceCode = sourceCode } String getName() { codeNarcSourceCode.name } String getPath() { codeNarcSourceCode.path } String getText() { codeNarcSourceCode.text } List getLines() { codeNarcSourceCode.lines } String line(int lineNumber) { codeNarcSourceCode.line(lineNumber) } ModuleNode getAst() { codeNarcSourceCode.ast } int getLineNumberForCharacterIndex(int charIndex) { codeNarcSourceCode.getLineNumberForCharacterIndex(charIndex) } boolean isValid() { return codeNarcSourceCode.isValid() } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/AbstractMethodMetricAstVisitor.groovy0000644000175000017500000001210112311373552031336 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.size import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.Violation import org.codenarc.util.AstUtil import org.codenarc.util.WildcardPattern import org.gmetrics.metric.Metric /** * Abstract superclass for AstVisitor classes that use method-level GMetrics Metrics. * * Subclasses must: *

    *
  • Implement the abstract createMetric() method
  • *
  • Implement the abstract getMetricShortDescription() method
  • *
  • Implement the abstract getMaxMethodMetricValue() method
  • *
  • Implement the abstract getMaxClassAverageMethodMetricValue() method
  • *
  • The owning Rule class must have the ignoreMethodNames property
  • *
* * @author Chris Mair * @author Hamlet D'Arcy */ @SuppressWarnings('DuplicateLiteral') abstract class AbstractMethodMetricAstVisitor extends AbstractAstVisitor { protected Metric metric private final metricLock = new Object() protected abstract createMetric() protected abstract String getMetricShortDescription() protected abstract Object getMaxMethodMetricValue() protected abstract Object getMaxClassMetricValue() protected abstract Object getMaxClassAverageMethodMetricValue() private Metric getMetric() { synchronized(metricLock) { if (metric == null) { metric = createMetric() } return metric } } void visitClassEx(ClassNode classNode) { def gmetricsSourceCode = new GMetricsSourceCodeAdapter(this.sourceCode) def classMetricResult = getMetric().applyToClass(classNode, gmetricsSourceCode) if (classMetricResult == null) { // no methods or closure fields return } checkMethods(classMetricResult) if (!AstUtil.isFromGeneratedSourceCode(classNode)) { if (!(classNode.isScript() && classNode.name == 'None')) { checkClass(classMetricResult, classNode) } } super.visitClassEx(classNode) } private void checkMethods(classMetricResult) { def methodResults = classMetricResult.methodMetricResults methodResults.each { method, results -> String methodName = extractMethodName(method) if (results['total'] > getMaxMethodMetricValue() && !isIgnoredMethodName(methodName)) { def message = "Violation in class $currentClassName. The ${getMetricShortDescription()} for method [$methodName] is [${results['total']}]" addViolation(results, message) } } } protected String extractMethodName(method) { // For GMetrics 0.4, it is a String; For GMetrics 0.5 it is a MethodKey method instanceof String ? method : method.methodName } private void checkClass(classMetricResult, classNode) { def className = classNode.name def classResults = classMetricResult.classMetricResult if (getMaxClassAverageMethodMetricValue() && classResults['average'] > getMaxClassAverageMethodMetricValue()) { def message = "The average method ${getMetricShortDescription()} for class [$className] is [${classResults['average']}]" addViolation(classResults, message) } if (getMaxClassMetricValue() && classResults['total'] > getMaxClassMetricValue()) { def message = "The total class ${getMetricShortDescription()} for class [$className] is [${classResults['total']}]" addViolation(classResults, message) } } protected void addViolation(classResults, String message) { def lineNumber = getLineNumber(classResults) def sourceLine = getSourceLine(lineNumber) violations.add(new Violation(rule:rule, lineNumber:lineNumber, sourceLine:sourceLine, message:message)) } protected getLineNumber(methodResults) { def lineNumber = AstUtil.respondsTo(methodResults, 'getLineNumber') ? methodResults.getLineNumber() : null (lineNumber == -1) ? null : lineNumber } protected String getSourceLine(lineNumber) { lineNumber == null ?: this.sourceCode.line(lineNumber - 1) } protected boolean isIgnoredMethodName(String methodName) { new WildcardPattern(rule.ignoreMethodNames, false).matches(methodName) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/AbcMetricRule.groovy0000644000175000017500000000724712055544272025742 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractAstVisitorRule import org.gmetrics.metric.abc.AbcMetric /** * Rule that calculates the ABC metric score for methods/classes and checks against * configured threshold values. *

* The maxMethodAbcScore property holds the threshold value for the ABC score * (magnitude) for each method. If this value is non-zero, a method with an ABC score greater than * this value is considered a violation. The value does not have to be an integer (i.e., 1.7 is allowed). The * maxMethodAbcScore property defaults to 60. *

* The maxClassAverageMethodAbcScore property holds the threshold value for the average ABC * score for each class. If this value is non-zero, a class with an average ABC score * greater than this value is considered a violation. The value does not have to be an integer * (i.e., 1.7 is allowed). The maxClassAverageMethodAbcScore property defaults to 60. *

* The maxClassAbcScore property holds the threshold value for the total ABC * score value for each class. If this value is non-zero, a class with a total ABC score * greater than this value is considered a violation. The value does not have to be an integer * (i.e., 1.7 is allowed). The maxClassAbcScore property defaults to 0. *

* The ignoreMethodNames property optionally specifies one or more (comma-separated) method * names that should be ignored (i.e., that should not cause a rule violation). The name(s) may optionally * include wildcard characters ('*' or '?'). Note that the ignored methods still contribute to the class * complexity value. *

* This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), * then that Closure is analyzed and checked just like a method. * * @see ABC Metric specification. * @see Blog post describing guidelines for interpreting an ABC score. * @see GMetrics ABC metric. * * @author Chris Mair */ class AbcMetricRule extends AbstractAstVisitorRule { String name = 'AbcMetric' int priority = 2 Class astVisitorClass = AbcMetricAstVisitor int maxMethodAbcScore = 60 int maxClassAverageMethodAbcScore = 60 int maxClassAbcScore = 0 String ignoreMethodNames } class AbcMetricAstVisitor extends AbstractMethodMetricAstVisitor { final String metricShortDescription = 'ABC score' protected Object createMetric() { new AbcMetric() } protected Object getMaxMethodMetricValue() { rule.maxMethodAbcScore } protected Object getMaxClassAverageMethodMetricValue() { rule.maxClassAverageMethodAbcScore } protected Object getMaxClassMetricValue() { rule.maxClassAbcScore } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/size/CyclomaticComplexityRule.groovy0000644000175000017500000000731012311373552030241 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractAstVisitorRule import org.gmetrics.metric.cyclomatic.CyclomaticComplexityMetric /** * Rule that calculates the Cyclomatic Complexity for methods/classes and checks against * configured threshold values. *

* The maxMethodComplexity property holds the threshold value for the cyclomatic complexity * value for each method. If this value is non-zero, a method with a cyclomatic complexity value greater than * this value is considered a violation. The maxMethodComplexity property defaults to 20. *

* The maxClassAverageMethodComplexity property holds the threshold value for the average cyclomatic * complexity value for each class. If this value is non-zero, a class with an average cyclomatic complexity * value greater than this value is considered a violation. The maxClassAverageMethodComplexity property * defaults to 20. *

* The maxClassComplexity property holds the threshold value for the total cyclomatic * complexity value for each class. If this value is non-zero, a class with a total cyclomatic complexity * value greater than this value is considered a violation. The maxClassComplexity property * defaults to 0. *

* The ignoreMethodNames property optionally specifies one or more (comma-separated) method * names that should be ignored (i.e., that should not cause a rule violation). The name(s) may optionally * include wildcard characters ('*' or '?'). Note that the ignored methods still contribute to the class * complexity value. *

* This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), * then that Closure is analyzed and checked just like a method. * * @see Cyclomatic Complexity Wikipedia entry. * @see The original paper describing Cyclomatic Complexity. * @see GMetrics Cyclomatic Complexity metric. * * @author Chris Mair */ class CyclomaticComplexityRule extends AbstractAstVisitorRule { String name = 'CyclomaticComplexity' int priority = 2 Class astVisitorClass = CyclomaticComplexityAstVisitor int maxMethodComplexity = 20 int maxClassComplexity = 0 int maxClassAverageMethodComplexity = 20 String ignoreMethodNames } class CyclomaticComplexityAstVisitor extends AbstractMethodMetricAstVisitor { final String metricShortDescription = 'cyclomatic complexity' protected Object createMetric() { new CyclomaticComplexityMetric() } protected Object getMaxMethodMetricValue() { rule.maxMethodComplexity } protected Object getMaxClassAverageMethodMetricValue() { rule.maxClassAverageMethodComplexity } protected Object getMaxClassMetricValue() { rule.maxClassComplexity } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/0000755000175000017500000000000012623571301022515 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/UnusedImportRule.groovy0000644000175000017500000000621212277665572027276 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.imports import org.codehaus.groovy.ast.ImportNode import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode import org.codenarc.util.GroovyVersion /** * Rule that checks for an unreferenced import * * @author Chris Mair */ class UnusedImportRule extends AbstractRule { String name = 'UnusedImport' int priority = 3 void applyTo(SourceCode sourceCode, List violations) { processImports(sourceCode, violations) processStaticImports(sourceCode, violations) } private void processImports(SourceCode sourceCode, List violations) { sourceCode.ast?.imports?.each { importNode -> if (!findReference(sourceCode, importNode.alias, importNode.className)) { violations.add(createViolationForImport(sourceCode, importNode, "The [${importNode.className}] import is never referenced")) } } } private void processStaticImports(SourceCode sourceCode, List violations) { if (GroovyVersion.isGroovy1_8_OrGreater()) { sourceCode.ast?.staticImports?.each { alias, ImportNode classNode -> if (!findReference(sourceCode, alias)) { violations.add(createViolationForImport(sourceCode, classNode.className, alias, "The [${classNode.className}] import is never referenced")) } } } else { sourceCode.ast?.staticImportAliases?.each { alias, classNode -> if (!findReference(sourceCode, alias)) { violations.add(createViolationForImport(sourceCode, classNode.name, alias, "The [${classNode.name}] import is never referenced")) } } } } private findReference(SourceCode sourceCode, String alias, String className = null) { def aliasSameAsNonQualifiedClassName = className && className.endsWith(alias) sourceCode.lines.find { line -> if (!isImportStatementForAlias(line, alias)) { def aliasCount = countUsage(line, alias) return aliasSameAsNonQualifiedClassName ? aliasCount && aliasCount > countUsage(line, className) : aliasCount } } } private isImportStatementForAlias(String line, String alias) { final IMPORT_PATTERN = /import\s+.*/ + alias line =~ IMPORT_PATTERN } private countUsage(String line, String pattern) { (line =~ /\b${pattern}\b/).count } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/NoWildcardImportsRule.groovy0000644000175000017500000000233512311373552030225 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Wildcard imports, static or otherwise, are not used. * * @author Kyle Boon */ class NoWildcardImportsRule extends AbstractImportRule { String name = 'NoWildcardImports' int priority = 3 void applyTo(SourceCode sourceCode, List violations) { eachImportLine(sourceCode) { int lineNumber, String line -> if (line.trim().endsWith('.*')) { violations.add(new Violation(rule: this, sourceLine: line.trim(), lineNumber: lineNumber)) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/UnnecessaryGroovyImportRule.groovy0000644000175000017500000000405412311373552031521 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode import org.codenarc.util.AstUtil import org.codenarc.util.ImportUtil /** * Rule that checks for non-static imports from any packages that are * automatically imported by Groovy, including: *

    *
  • java.io
  • *
  • java.lang
  • *
  • java.net
  • *
  • java.util
  • *
  • java.math.BigDecimal
  • *
  • java.math.BigInteger
  • *
  • groovy.lang
  • *
  • groovy.util
  • *
* * @author Chris Mair */ class UnnecessaryGroovyImportRule extends AbstractRule { String name = 'UnnecessaryGroovyImport' int priority = 3 void applyTo(SourceCode sourceCode, List violations) { if (sourceCode.ast?.imports || sourceCode.ast?.starImports) { ImportUtil.getNonStaticImportsSortedByLineNumber(sourceCode).each { importNode -> def importClassName = importNode.className def importPackageName = ImportUtil.packageNameForImport(importNode) if ((!importNode.alias || importClassName.endsWith(".$importNode.alias")) && (importPackageName in AstUtil.AUTO_IMPORTED_PACKAGES || importClassName in AstUtil.AUTO_IMPORTED_CLASSES)) { violations.add(createViolationForImport(sourceCode, importNode)) } } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/MisorderedStaticImportsRule.groovy0000644000175000017500000000421112006632014031427 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Static imports should be before nonstatic imports * * @author Erik Pragt * @author Marcin Erdmann * @author Hamlet D'Arcy */ class MisorderedStaticImportsRule extends AbstractImportRule { private static final String COMES_BEFORE_MESSAGE = 'Static imports should appear before normal imports' private static final String COMES_AFTER_MESSAGE = 'Normal imports should appear before static imports' String name = 'MisorderedStaticImports' int priority = 3 boolean comesBefore = true void applyTo(SourceCode sourceCode, List violations) { if (comesBefore) { violations.addAll addOrderingViolations(sourceCode, NON_STATIC_IMPORT_PATTERN, STATIC_IMPORT_PATTERN, COMES_BEFORE_MESSAGE) } else { violations.addAll addOrderingViolations(sourceCode, STATIC_IMPORT_PATTERN, NON_STATIC_IMPORT_PATTERN, COMES_AFTER_MESSAGE) } } private addOrderingViolations(SourceCode sourceCode, String earlyPattern, String latePattern, String message) { List violations = [] boolean nonStaticFound = false eachImportLine(sourceCode) { int lineNumber, String line -> nonStaticFound = nonStaticFound || line =~ earlyPattern if (nonStaticFound && line =~ latePattern) { violations << new Violation(rule: this, sourceLine: line.trim(), lineNumber: lineNumber, message: message) } } violations } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/ImportFromSamePackageRule.groovy0000644000175000017500000000423312311373552031000 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode import org.codenarc.util.ImportUtil /** * Checks for an import of a class that is within the same package as the importing class. * * @author Chris Mair */ @SuppressWarnings('DuplicateLiteral') class ImportFromSamePackageRule extends AbstractRule { String name = 'ImportFromSamePackage' int priority = 3 void applyTo(SourceCode sourceCode, List violations) { def hasImports = sourceCode.ast?.imports || sourceCode.ast?.starImports if (hasImports && sourceCode.ast.packageName) { def rawPackage = sourceCode.ast.packageName def filePackageName = rawPackage.endsWith('.') ? rawPackage[0..-2] : rawPackage ImportUtil.getNonStaticImportsSortedByLineNumber(sourceCode).each { importNode -> def importPackageName = ImportUtil.packageNameForImport(importNode) if (importPackageName == filePackageName && !hasAlias(importNode)) { violations.add(createViolationForImport(sourceCode, importNode)) } } } } private boolean hasAlias(importNode) { importNode.className && importNode.alias != getClassNameNoPackage(importNode.className) } private String getClassNameNoPackage(String className) { def indexOfLastPeriod = className.lastIndexOf('.') (indexOfLastPeriod == -1) ? className : className[indexOfLastPeriod + 1..-1] } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/ImportFromSunPackagesRule.groovy0000644000175000017500000000406412006632012031033 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.imports import org.codehaus.groovy.ast.ImportNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.source.SourceCode /** * Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change. * * @author 'Hamlet D'Arcy' */ class ImportFromSunPackagesRule extends AbstractAstVisitorRule { String name = 'ImportFromSunPackages' int priority = 2 void applyTo(SourceCode sourceCode, List violations) { sourceCode.ast?.imports?.each { importNode -> addViolationForSunImport(importNode, sourceCode, violations) } sourceCode.ast?.starImports?.each { importNode -> addViolationForSunImport(importNode, sourceCode, violations) } } def addViolationForSunImport(ImportNode importNode, SourceCode sourceCode, List violations) { def className = importNode.className def packageName = importNode.packageName if (className?.startsWith('sun.')) { String message = "The file imports $className, which is not portable and likely to change" violations.add(createViolationForImport(sourceCode, importNode, message)) } else if (packageName?.startsWith('sun.')) { String message = "The file imports ${packageName}*, which is not portable and likely to change" violations.add(createViolationForImport(sourceCode, importNode, message)) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/AbstractImportRule.groovy0000644000175000017500000000372212006632016027552 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Abstract class with common functionalities for import-related rules. * * @author Erik Pragt * @author Marcin Erdmann */ abstract class AbstractImportRule extends AbstractRule { public static final NON_STATIC_IMPORT_PATTERN = /^\s*import(?!\s+static)\s+(\w+(\.\w+)*)\b.*/ public static final STATIC_IMPORT_PATTERN = /^\s*import\s+static\s+(\w+(\.\w+)*)\b.*/ /** * Optimization: Stop checking lines for imports once a class/interface has been declared */ protected findLineNumberOfFirstClassDeclaration(SourceCode sourceCode) { int firstLineNumber = sourceCode.lines.size() def ast = sourceCode.ast ast?.classes.each { classNode -> if (classNode.lineNumber >= 0 && classNode.lineNumber < firstLineNumber) { firstLineNumber = classNode.lineNumber } } firstLineNumber } protected void eachImportLine(SourceCode sourceCode, Closure closure) { int firstClassDeclarationLine = findLineNumberOfFirstClassDeclaration(sourceCode) for(int index=0; index < firstClassDeclarationLine; index++) { def line = sourceCode.lines[index] def lineNumber = index + 1 closure.call(lineNumber, line) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/imports/DuplicateImportRule.groovy0000644000175000017500000000477012311373552027733 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Rule that checks for a duplicate import * * NOTE: Does not distinguish between multiple duplicate imports of the same class. * Thus, it may produce multiple violations with the same line number in that case. * * @author Chris Mair * @author Hamlet D'Arcy */ class DuplicateImportRule extends AbstractImportRule { String name = 'DuplicateImport' int priority = 3 void applyTo(SourceCode sourceCode, List violations) { def importNames = [] as Set def staticImportNames = [] as Set eachImportLine(sourceCode) { int lineNumber, String line -> checkImport(line, lineNumber, importNames, violations) checkStaticImport(line, lineNumber, staticImportNames, violations) } } private void checkImport(line, lineNumber, importNames, violations) { def importMatcher = line =~ NON_STATIC_IMPORT_PATTERN if (importMatcher) { def importName = importMatcher[0][1] if (importNames.contains(importName)) { violations.add(new Violation(rule: this, sourceLine: line.trim(), lineNumber: lineNumber)) } else { importNames.add(importName) } } } private void checkStaticImport(line, lineNumber, staticImportNames, violations) { def importMatcher = line =~ STATIC_IMPORT_PATTERN if (importMatcher) { def staticImportName = importMatcher[0][1] if (staticImportNames.contains(staticImportName)) { violations.add(new Violation(rule: this, sourceLine: line.trim(), lineNumber: lineNumber)) } else { staticImportNames.add(staticImportName) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/AbstractConstructorCallAstVisitor.groovy0000644000175000017500000000351412311373552031131 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule import org.codehaus.groovy.ast.expr.ConstructorCallExpression /** * Abstract superclass for AST Visitor classes that deal with constructor calls * * @author Chris Mair */ abstract class AbstractConstructorCallAstVisitor extends AbstractAstVisitor { /** * Subclasses must implement to return true if the visited constructor call causes a rule violation */ protected abstract isConstructorCallAViolation(ConstructorCallExpression constructorCall) protected abstract String getViolationMessage(ConstructorCallExpression call) @SuppressWarnings('CatchThrowable') @Override void visitConstructorCallExpression(ConstructorCallExpression constructorCall) { if (isFirstVisit(constructorCall) && isConstructorCallAViolation(constructorCall)) { try { addViolation(constructorCall, getViolationMessage(constructorCall)) } catch (Throwable t) { addViolation(constructorCall, "Violation in class $currentClassName. The type $constructorCall.type.name can be instantiated with a literal") } } super.visitConstructorCallExpression(constructorCall) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/0000755000175000017500000000000012623571301023352 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/SynchronizedOnGetClassRule.groovy0000644000175000017500000000355212006632020032047 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Synchronized on getClass rather than class literal. This instance method synchronizes on this.getClass(). If this * class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended. * * @author Hamlet D'Arcy */ class SynchronizedOnGetClassRule extends AbstractAstVisitorRule { String name = 'SynchronizedOnGetClass' int priority = 2 Class astVisitorClass = SynchronizedOnGetClassAstVisitor } class SynchronizedOnGetClassAstVisitor extends AbstractAstVisitor { void visitSynchronizedStatement(SynchronizedStatement statement) { if (!isFirstVisit(statement)) { return } if (statement.expression instanceof MethodCallExpression && AstUtil.isMethodNamed(statement.expression, 'getClass', 0)) { addViolation statement, 'Synchronizing on getClass() should be replaced with a class literal' } super.visitSynchronizedStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/SynchronizedReadObjectMethodRule.groovy0000644000175000017500000000655412311373552033230 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.Parameter import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.Statement import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * Catches Serializable classes that define a synchronized readObject method. By definition, an object created by * deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. * If the readObject() method itself is causing the object to become visible to another thread, that is an example of * very dubious coding style. * * @author Hamlet D'Arcy */ class SynchronizedReadObjectMethodRule extends AbstractAstVisitorRule { String name = 'SynchronizedReadObjectMethod' int priority = 2 Class astVisitorClass = SynchronizedReadObjectMethodAstVisitor } class SynchronizedReadObjectMethodAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { def classNode = getCurrentClassNode() if (isSerializable(classNode) && AstUtil.isMethodNode(node, 'readObject', 1) && Modifier.isPrivate(node.modifiers)) { Parameter parm = node.parameters[0] if (node?.returnType?.name == 'void' && AstUtil.classNodeImplementsType(parm.type, ObjectInputStream)) { if (Modifier.isSynchronized(node.modifiers)) { addViolation(node, "The Serializable class $classNode.name has a synchronized readObject method. It is normally unnecesary to synchronize within deserializable") } else if (isSynchronizedBlock(node.code)) { addViolation(node.code, "The Serializable class $classNode.name has a synchronized readObject method. It is normally unnecesary to synchronize within deserializable") } } } } private static isSerializable(ClassNode node) { boolean isSerializable = false node.interfaces?.each { if (AstUtil.classNodeImplementsType(it, Serializable)) { isSerializable = true } } isSerializable } private static boolean isSynchronizedBlock(Statement statement) { if (!(statement instanceof BlockStatement)) { return false } if (statement.statements.size() != 1) { return false } statement.statements[0] instanceof SynchronizedStatement } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/BusyWaitRule.groovy0000644000175000017500000000460212006632016027216 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codehaus.groovy.ast.stmt.ForStatement import org.codehaus.groovy.ast.stmt.WhileStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Busy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package. * * @author Hamlet D'Arcy */ class BusyWaitRule extends AbstractAstVisitorRule { String name = 'BusyWait' int priority = 2 Class astVisitorClass = BusyWaitAstVisitor } class BusyWaitAstVisitor extends AbstractAstVisitor { @Override void visitWhileLoop(WhileStatement node) { addViolationIfBusyWait(node) super.visitWhileLoop(node) } @Override void visitForLoop(ForStatement node) { // -1 is line number for a for-each loop if (node.variable.lineNumber == -1) { addViolationIfBusyWait(node) } super.visitForLoop(node) } private addViolationIfBusyWait(node) { if (node.loopBlock instanceof BlockStatement && node.loopBlock.statements?.size() == 1 && node.loopBlock.statements[0] instanceof ExpressionStatement) { Expression expression = node.loopBlock.statements[0].expression if (AstUtil.isMethodCall(expression, 'sleep', 1) || AstUtil.isMethodCall(expression, 'sleep', 2)) { addViolation(expression, 'Busy wait detected. Switch the usage of Thread.sleep() to a lock or gate from java.util.concurrent') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/InconsistentPropertyLockingRule.groovy0000644000175000017500000001025712141451430033205 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * Class contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all. * * @author 'Hamlet D'Arcy' */ class InconsistentPropertyLockingRule extends AbstractAstVisitorRule { String name = 'InconsistentPropertyLocking' int priority = 2 Class astVisitorClass = InconsistentPropertyLockingAstVisitor } class InconsistentPropertyLockingAstVisitor extends AbstractMethodVisitor { private final Map guardedMethods = [:] private final Map unguardedMethods = [:] @Override void visitMethod(MethodNode node) { if (node.name.startsWith('get') && node.name.size() > 3 && AstUtil.getParameterNames(node).isEmpty()) { // is a getter def propName = node.name[3..-1] saveMethodInfo(node) addViolationOnMismatch(node.name, "set$propName") } if (node.name.startsWith('is') && node.name.size() > 2 && AstUtil.getParameterNames(node).isEmpty()) { // is a getter def propName = node.name[2..-1] saveMethodInfo(node) addViolationOnMismatch(node.name, "set$propName") } if (node.name.startsWith('set') && node.name.size() > 3 && AstUtil.getParameterNames(node).size() == 1) { // is a setter def propName = node.name[3..-1] saveMethodInfo(node) addViolationOnMismatch("get$propName", node.name) addViolationOnMismatch("is$propName", node.name) } } private saveMethodInfo(MethodNode node) { if (isWriteLocked(node) || isReadLocked(node)) { guardedMethods.put(node.name, node) } else { unguardedMethods.put(node.name, node) } } private void addViolationOnMismatch(String getterName, String setterName) { if (guardedMethods.containsKey(getterName) && unguardedMethods.containsKey(setterName)) { MethodNode unguardedNode = unguardedMethods.get(setterName) MethodNode guardedNode = guardedMethods.get(getterName) def lockType = getGuardName(guardedNode) addViolation(unguardedNode, "The getter method $getterName is marked @$lockType but the setter method $setterName is not locked") } if (unguardedMethods.containsKey(getterName) && guardedMethods.containsKey(setterName)) { MethodNode unguardedNode = unguardedMethods.get(getterName) MethodNode guardedNode = guardedMethods.get(setterName) def lockType = getGuardName(guardedNode) addViolation(unguardedNode, "The setter method $setterName is marked @$lockType but the getter method $getterName is not locked") } } private static String getGuardName(MethodNode guardedNode) { if (isWriteLocked(guardedNode)) { return 'WithWriteLock' } if (isReadLocked(guardedNode)) { return 'WithReadLock' } '' } private static boolean isWriteLocked(MethodNode node) { AstUtil.getAnnotation(node, 'WithWriteLock') || AstUtil.getAnnotation(node, 'groovy.transform.WithWriteLock') } private static boolean isReadLocked(MethodNode node) { AstUtil.getAnnotation(node, 'WithReadLock') || AstUtil.getAnnotation(node, 'groovy.transform.WithReadLock') } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/SynchronizedOnStringRule.groovy0000644000175000017500000000341712006632016031615 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Synchronization on a String field can lead to deadlock because Strings are interned by the JVM and can be shared. * * @author Hamlet D'Arcy */ class SynchronizedOnStringRule extends AbstractAstVisitorRule { String name = 'SynchronizedOnString' int priority = 2 Class astVisitorClass = SynchronizedOnStringAstVisitor } class SynchronizedOnStringAstVisitor extends AbstractAstVisitor { @Override void visitSynchronizedStatement(SynchronizedStatement statement) { if (statement.expression instanceof VariableExpression) { if (AstUtil.getFieldType(currentClassNode, statement.expression.variable) == String) { addViolation(statement, "Synchronizing on the constant String field $statement.expression.variable is unsafe. Do not synchronize on interned strings") } } super.visitSynchronizedStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/SynchronizedOnReentrantLockRule.groovy0000644000175000017500000000400412041061500033104 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import java.util.concurrent.locks.ReentrantLock /** * Synchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method. * * @author 'Hamlet D'Arcy' */ class SynchronizedOnReentrantLockRule extends AbstractAstVisitorRule { String name = 'SynchronizedOnReentrantLock' int priority = 2 Class astVisitorClass = SynchronizedOnReentrantLockAstVisitor } class SynchronizedOnReentrantLockAstVisitor extends AbstractAstVisitor { @Override void visitSynchronizedStatement(SynchronizedStatement statement) { if (statement.expression instanceof VariableExpression) { if (AstUtil.getFieldType(currentClassNode, statement.expression.variable) == ReentrantLock) { addViolation(statement, "Synchronizing on a ReentrantLock field $statement.expression.variable. This is almost never the intended usage; use the lock() and unlock() methods instead") } } super.visitSynchronizedStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/NestedSynchronizationRule.groovy0000644000175000017500000000450612006632012032012 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.Violation /** * Rule to detect nested synchronization blocks. * * @author Hamlet D'Arcy */ class NestedSynchronizationRule extends AbstractAstVisitorRule { String name = 'NestedSynchronization' int priority = 2 Class astVisitorClass = NestedSynchronizationAstVisitor } class NestedSynchronizationAstVisitor extends AbstractAstVisitor { private int visitCount = 0 void visitSynchronizedStatement(SynchronizedStatement statement) { if (isFirstVisit(statement)) { if (visitCount > 0) { addViolation(statement, 'Nested synchronized statements are confusing and may lead to deadlock') } visitCount++ super.visitSynchronizedStatement(statement) visitCount-- } else { super.visitSynchronizedStatement(statement) } } void visitClosureExpression(ClosureExpression expression) { if (isFirstVisit(expression)) { // dispatch to a new instance b/c we have a new scope AbstractAstVisitor newVisitor = new NestedSynchronizationAstVisitor(sourceCode: this.sourceCode, rule: this.rule, visited: this.visited) expression.getCode().visit(newVisitor) newVisitor.getViolations().each { Violation it -> addViolation(it) } } else { super.visitClosureExpression(expression) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/StaticConnectionRule.groovy0000644000175000017500000000335512311370173030724 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier import java.sql.Connection /** * Creates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions. * * @author 'Hamlet D'Arcy' */ class StaticConnectionRule extends AbstractAstVisitorRule { String name = 'StaticConnection' int priority = 2 Class astVisitorClass = StaticConnectionAstVisitor } class StaticConnectionAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (AstUtil.classNodeImplementsType(node.type, Connection) && Modifier.isStatic(node.modifiers)) { addViolation(node, "The field $node.name is marked static, meaning the Connection will be shared between threads and will possibly experience race conditions") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/UseOfNotifyMethodRule.groovy0000644000175000017500000000322112006632020031011 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * This code calls notify() rather than notifyAll(). Java monitors are often used for multiple conditions. Calling * notify() only wakes up one thread, meaning that the thread woken up might not be the one waiting for the condition * that the caller just satisfied. * * @author Hamlet D'Arcy */ class UseOfNotifyMethodRule extends AbstractAstVisitorRule { String name = 'UseOfNotifyMethod' int priority = 2 Class astVisitorClass = UseOfNotifyMethodAstVisitor } class UseOfNotifyMethodAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'notify', 0)) { addViolation call, "The method $call.text should be replaced with ${call.objectExpression.text}.notifyAll()" } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/ThreadYieldRule.groovy0000644000175000017500000000303012311371417027643 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Method calls to Thread.yield() should not be allowed. * This method has no useful guaranteed semantics, and is often used by inexperienced * programmers to mask race conditions. * * @author Hamlet D'Arcy */ class ThreadYieldRule extends AbstractAstVisitorRule { String name = 'ThreadYield' int priority = 2 Class astVisitorClass = ThreadYieldAstVisitor } class ThreadYieldAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, 'Thread', 'yield', 0)) { addViolation(call, 'Thread.yield() has not useful guaranteed semantics') } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/SystemRunFinalizersOnExitRule.groovy0000644000175000017500000000350212006632016032574 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Method calls to System.runFinalizersOnExit() should not be allowed. This method is inherently * non-thread-safe, may result in data corruption, deadlock, and may effect parts of the program * far removed from it's call point. It is deprecated, and it's use strongly discouraged. * * @author Hamlet D'Arcy */ class SystemRunFinalizersOnExitRule extends AbstractAstVisitorRule { String name = 'SystemRunFinalizersOnExit' int priority = 2 Class astVisitorClass = SystemRunFinalizersOnExitAstVisitor } class SystemRunFinalizersOnExitAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression call) { if (call.objectExpression instanceof VariableExpression) { if (AstUtil.isMethodCall(call, 'System', 'runFinalizersOnExit', 1)) { addViolation(call, 'System.runFinalizersOnExit() should not be invoked') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/VolatileArrayFieldRule.groovy0000644000175000017500000000331312311370173031171 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * Volatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not. * * @author Hamlet D'Arcy */ class VolatileArrayFieldRule extends AbstractAstVisitorRule { String name = 'VolatileArrayField' int priority = 2 Class astVisitorClass = VolatileArrayFieldAstVisitor } class VolatileArrayFieldAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (Modifier.isVolatile(node.modifiers) && AstUtil.getFieldType(node)?.isArray()) { addViolation(node, "The array field $node.name is marked volatile, but the contents of the array will not share the same volatile semantics. Use a different data type") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/StaticSimpleDateFormatFieldRule.groovy0000644000175000017500000000463612041061500032763 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier import java.text.SimpleDateFormat /** * SimpleDateFormat objects should not be used as static fields. SimpleDateFormat are inherently unsafe for * multi-threaded use. Sharing a single instance across thread boundaries without proper synchronization will * result in erratic behavior of the application. * * @author Chris Mair */ class StaticSimpleDateFormatFieldRule extends AbstractAstVisitorRule { String name = 'StaticSimpleDateFormatField' int priority = 2 Class astVisitorClass = StaticSimpleDateFormatFieldAstVisitor } class StaticSimpleDateFormatFieldAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (Modifier.isStatic(node.modifiers) && AstUtil.classNodeImplementsType(node.type, SimpleDateFormat)) { addSimpleDateFormatViolation(node, node.name) } else { if (Modifier.isStatic(node.modifiers) && node.initialValueExpression && isSimpleDateFormatConstructorCall(node.initialValueExpression)) { addSimpleDateFormatViolation(node, node.name) } } } private static boolean isSimpleDateFormatConstructorCall(expression) { AstUtil.isConstructorCall(expression, ['SimpleDateFormat', 'java.text.SimpleDateFormat']) } private void addSimpleDateFormatViolation(node, String fieldName) { addViolation(node, "SimpleDateFormat instances are not thread safe. Wrap the SimpleDateFormat field $fieldName in a ThreadLocal or make it an instance field") } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/ThreadLocalNotStaticFinalRule.groovy0000644000175000017500000000365012041054200032426 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import java.lang.reflect.Modifier /** * ThreadLocal fields should be static and final. In the most common case a java.lang.ThreadLocal * instance associates state with a thread. A non-static non-final java.lang.ThreadLocal field * associates state with an instance-thread combination. This is seldom necessary and often a * bug which can cause memory leaks and possibly incorrect behavior. * * @author Hamlet D'Arcy */ class ThreadLocalNotStaticFinalRule extends AbstractAstVisitorRule { String name = 'ThreadLocalNotStaticFinal' int priority = 2 Class astVisitorClass = ThreadLocalNotStaticFinalAstVisitor } class ThreadLocalNotStaticFinalAstVisitor extends AbstractFieldVisitor { void visitField(FieldNode node) { if (node?.type?.name == 'ThreadLocal') { if (!Modifier.isStatic(node.modifiers)) { addViolation(node, "The ThreadLocal field $node.name is not static") } if (!Modifier.isFinal(node.modifiers)) { addViolation(node, "The ThreadLocal field $node.name is not final") } } } } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/InconsistentPropertySynchronizationRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/InconsistentPropertySynchronizationRule.0000644000175000017500000001454412462775475033605 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * Class contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not. * * @author 'Hamlet D'Arcy' */ class InconsistentPropertySynchronizationRule extends AbstractAstVisitorRule { String name = 'InconsistentPropertySynchronization' int priority = 2 Class astVisitorClass = InconsistentPropertySynchronizationAstVisitor } class InconsistentPropertySynchronizationAstVisitor extends AbstractMethodVisitor { private final Map synchronizedMethods = [:] private final Map unsynchronizedMethods = [:] @Override void visitMethod(MethodNode node) { if (node.name.startsWith('get') && node.name.size() > 3 && AstUtil.getParameterNames(node).isEmpty()) { // is a getter def propName = node.name[3..-1] saveMethodInfo(node) // does the enclosing class have this property? if (AstUtil.classNodeHasProperty(currentClassNode, extractPropertyName(node))) { addViolationOnMismatch([node.name], "set$propName") } } if (node.name.startsWith('is') && node.name.size() > 2 && AstUtil.getParameterNames(node).isEmpty()) { // is a getter def propName = node.name[2..-1] saveMethodInfo(node) if (AstUtil.classNodeHasProperty(currentClassNode, extractPropertyName(node))) { addViolationOnMismatch([node.name], "set$propName") } } if (node.name.startsWith('set') && node.name.size() > 3 && AstUtil.getParameterNames(node).size() == 1) { // is a setter def propName = node.name[3..-1] saveMethodInfo(node) if (AstUtil.classNodeHasProperty(currentClassNode, extractPropertyName(node))) { addViolationOnMismatch(["get$propName", "is$propName"], node.name) } } } private static String extractPropertyName(MethodNode node) { if (node.name.startsWith('get') || node.name.startsWith('set')) { if (node.name.length() == 4) { return node.name[3..-1].toLowerCase() } return node.name[3].toLowerCase() + node.name[4..-1] } else if (node.name.startsWith('is')) { if (node.name.length() == 3) { return node.name[2..-1].toLowerCase() } return node.name[2].toLowerCase() + node.name[3..-1] } throw new IllegalArgumentException("MethodNode $node.name is not a getter/setter/izzer") } private saveMethodInfo(MethodNode node) { if (Modifier.isSynchronized(node.modifiers)) { synchronizedMethods.put(node.name, node) } else if (AstUtil.getAnnotation(node, 'Synchronized')) { synchronizedMethods.put(node.name, node) } else if (AstUtil.getAnnotation(node, 'groovy.transform.Synchronized')) { synchronizedMethods.put(node.name, node) } else { unsynchronizedMethods.put(node.name, node) } } @SuppressWarnings('CyclomaticComplexity') private void addViolationOnMismatch(List rawGetterNames, String setterName) { def getterNames = rawGetterNames*.toString() // force GString into strings if (containsKey(synchronizedMethods, getterNames) && unsynchronizedMethods.containsKey(setterName)) { def getterName = getFirstValue(synchronizedMethods, getterNames).name MethodNode node = unsynchronizedMethods.get(setterName) addViolation(node, "The getter method $getterName is synchronized but the setter method $setterName is not") } else if (containsKey(unsynchronizedMethods, getterNames) && synchronizedMethods.containsKey(setterName)) { def getterName = getFirstValue(unsynchronizedMethods, getterNames).name MethodNode node = unsynchronizedMethods.get(getterName) addViolation(node, "The setter method $setterName is synchronized but the getter method $getterName is not") } else if (containsKey(synchronizedMethods, getterNames)) { // perhaps the owner didn't define the method def getterName = getFirstValue(synchronizedMethods, getterNames).name MethodNode node = synchronizedMethods.get(getterName) if (!currentClassNode?.methods?.find { it?.name == setterName && it?.parameters?.length == 1 }) { addViolation(node, "The getter method $getterName is synchronized but the setter method $setterName is not") } } else if (synchronizedMethods.containsKey(setterName)) { // the setter is synchronized, perhaps the getter was never defined? if (!currentClassNode?.methods?.find { getterNames.contains(it?.name) && it?.parameters?.length == 0 }) { MethodNode node = synchronizedMethods.get(setterName) addViolation(node, "The setter method $setterName is synchronized but the getter method ${getterNames.size() == 1 ? getterNames[0] : getterNames} is not") } } } private static boolean containsKey(Map methodList, List keys) { methodList.find { it.key in keys } != null } private static MethodNode getFirstValue(Map methodList, List keys) { methodList.find { it.key in keys }.value } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/StaticDateFormatFieldRule.groovy0000644000175000017500000000500412041061500031577 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier import java.text.DateFormat /** * DateFormat objects should not be used as static fields. DateFormat are inherently unsafe for multithreaded use. Sharing a * single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. * * @author 'Hamlet D'Arcy' * @author Chris Mair */ class StaticDateFormatFieldRule extends AbstractAstVisitorRule { String name = 'StaticDateFormatField' int priority = 2 Class astVisitorClass = StaticDateFormatFieldAstVisitor } class StaticDateFormatFieldAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (Modifier.isStatic(node.modifiers) && AstUtil.classNodeImplementsType(node.type, DateFormat)) { addDateFormatViolation(node, node.name) } else { if (Modifier.isStatic(node.modifiers) && node.initialValueExpression && isDateFormatFactoryMethodCall(node.initialValueExpression)) { addDateFormatViolation(node, node.name) } } } private static boolean isDateFormatFactoryMethodCall(expression) { expression instanceof MethodCallExpression && AstUtil.isMethodCall(expression, ['DateFormat', /java\.text\.DateFormat/], ['getDateInstance', 'getDateTimeInstance', 'getTimeInstance']) } private void addDateFormatViolation(node, String fieldName) { addViolation(node, "DateFormat instances are not thread safe. Wrap the DateFormat field $fieldName in a ThreadLocal or make it an instance field") } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/StaticCalendarFieldRule.groovy0000644000175000017500000000440512041061500031266 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * Calendar objects should not be used as static fields. Calendars are inherently unsafe for multithreaded use. Sharing * a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. * * @author Hamlet D'Arcy * @author Chris Mair */ class StaticCalendarFieldRule extends AbstractAstVisitorRule { String name = 'StaticCalendarField' int priority = 2 Class astVisitorClass = StaticCalendarFieldAstVisitor } class StaticCalendarFieldAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (Modifier.isStatic(node.modifiers) && AstUtil.classNodeImplementsType(node.type, Calendar)) { addCalendarViolation(node, node.name) } else { if (Modifier.isStatic(node.modifiers) && node.initialValueExpression && isCalendarFactoryMethodCall(node.initialValueExpression)) { addCalendarViolation(node, node.name) } } } private static boolean isCalendarFactoryMethodCall(expression) { AstUtil.isMethodCall(expression, 'Calendar', 'getInstance') } private void addCalendarViolation(node, String fieldName) { addViolation(node, "Calendar instances are not thread safe. Wrap the Calendar field $fieldName in a ThreadLocal or make it an instance field") } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/StaticMatcherFieldRule.groovy0000644000175000017500000000341112041061500031134 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier import java.util.regex.Matcher /** * Matcher objects should not be used as static fields. Calendars are inherently unsafe for multithreaded use. Sharing a * single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. * * @author Hamlet D'Arcy */ class StaticMatcherFieldRule extends AbstractAstVisitorRule { String name = 'StaticMatcherField' int priority = 2 Class astVisitorClass = StaticMatcherFieldAstVisitor } class StaticMatcherFieldAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (Modifier.isStatic(node.modifiers) && AstUtil.classNodeImplementsType(node.type, Matcher)) { addViolation(node, "Matcher instances are not thread safe. Wrap the Matcher field $node.name in a ThreadLocal or make it an instance field") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/VolatileLongOrDoubleFieldRule.groovy0000644000175000017500000000373512041054202032446 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import java.lang.reflect.Modifier /** * This rule reports long or double fields which are declared as volatile. Java * specifies that reads and writes from such fields are atomic, but many JVM's * have violated this specification. Unless you are certain of your JVM, it is * better to synchronize access to such fields rather than declare them volatile. * * @author Hamlet D'Arcy */ class VolatileLongOrDoubleFieldRule extends AbstractAstVisitorRule { String name = 'VolatileLongOrDoubleField' int priority = 2 Class astVisitorClass = VolatileLongOrDoubleFieldVisitor } class VolatileLongOrDoubleFieldVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if (node?.type == ClassHelper.double_TYPE || node?.type == ClassHelper.long_TYPE || node?.type?.name == 'Long' || node?.type?.name == 'Double') { if (Modifier.isVolatile(node.modifiers)) { addViolation(node, 'Operations on volatile long and double fields are not guaranteed atomic on all JVMs') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/SynchronizedOnThisRule.groovy0000644000175000017500000000365612006632016031263 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Synchronized On This Rule - This rule reports uses of the synchronized blocks where * the synchronization reference is 'this'. Doing this effectively makes your * synchronization policy public and modifiable by other objects. To avoid possibilities * of deadlock, it is better to synchronize on internal objects. * * @author Hamlet D'Arcy */ class SynchronizedOnThisRule extends AbstractAstVisitorRule { String name = 'SynchronizedOnThis' int priority = 2 Class astVisitorClass = SynchronizedOnThisAstVisitor } class SynchronizedOnThisAstVisitor extends AbstractAstVisitor { void visitSynchronizedStatement(SynchronizedStatement statement) { if (isFirstVisit(statement)) { if (statement.getExpression() instanceof VariableExpression) { if (statement.expression?.variable == 'this') { addViolation(statement, "The synchronized statement uses the 'this' reference") } } } super.visitSynchronizedStatement(statement) } } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/ThisReferenceEscapesConstructorRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/ThisReferenceEscapesConstructorRule.groo0000644000175000017500000000655612137611550033407 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.NamedArgumentListExpression import org.codehaus.groovy.ast.expr.TupleExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor /** * Reports constructors passing the 'this' reference to other methods. * This equals exposing a half-baked objects and can lead to race conditions during initialization. * For reference, see * Java Concurrency Gotchas by Alex Miller and * Java theory and practice: Safe construction techniques by Brian Goetz. * * @author Artur Gajowy */ class ThisReferenceEscapesConstructorRule extends AbstractAstVisitorRule { String name = 'ThisReferenceEscapesConstructor' int priority = 2 Class astVisitorClass = ThisReferenceEscapesConstructorAstVisitor } class ThisReferenceEscapesConstructorAstVisitor extends AbstractAstVisitor { private boolean withinConstructor = false @Override void visitConstructor(ConstructorNode node) { withinConstructor = true super.visitConstructor(node) withinConstructor = false } @Override void visitMethodCallExpression(MethodCallExpression call) { findViolations(call) super.visitMethodCallExpression(call) } @Override void visitConstructorCallExpression(ConstructorCallExpression call) { findViolations(call) } private void findViolations(Expression methodOrConstructorCall) { if (withinConstructor && argumentsContainThis(methodOrConstructorCall.arguments)) { addViolation(methodOrConstructorCall, 'The `this` reference escapes constructor. ' + 'This equals exposing a half-baked object and can lead to race conditions.') } } private boolean argumentsContainThis(TupleExpression argumentsTuple) { argumentsTuple.expressions.any { isThisExpression(it) || isNamedArgumentsListContainingThis(it) } } private boolean isThisExpression(Expression expression) { expression instanceof VariableExpression && expression.isThisExpression() } private boolean isNamedArgumentsListContainingThis(Expression expression) { expression instanceof NamedArgumentListExpression && expression.mapEntryExpressions*.valueExpression.any { isThisExpression(it) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/SynchronizedMethodRule.groovy0000644000175000017500000000327712041061500031267 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import java.lang.reflect.Modifier /** * Synchronized Method Rule - This rule reports uses of the synchronized keyword on * methods. Synchronized methods are the same as synchronizing on 'this', which * effectively make your synchronization policy public and modifiable by other objects. * To avoid possibilities of deadlock, it is better to synchronize on internal objects. * * @author Hamlet D'Arcy */ class SynchronizedMethodRule extends AbstractAstVisitorRule { String name = 'SynchronizedMethod' int priority = 2 Class astVisitorClass = SynchronizedMethodAstVisitor } class SynchronizedMethodAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (Modifier.isSynchronized(node.getModifiers())) { addViolation(node, "The method $node.name is synchronized at the method level") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/WaitOutsideOfWhileLoopRule.groovy0000644000175000017500000000403012006632014032011 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.WhileStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Checks for calls to wait() that are not within a while loop. * * See Joshua Bloch's Effective Java: chapter 50 (1st edition) is entitled "Never invoke wait outside a loop." * See https://www.securecoding.cert.org/confluence/display/java/THI03-J.+Always+invoke+wait()+and+await()+methods+inside+a+loop * * @author Chris Mair */ class WaitOutsideOfWhileLoopRule extends AbstractAstVisitorRule { String name = 'WaitOutsideOfWhileLoop' int priority = 2 Class astVisitorClass = WaitOutsideOfWhileLoopAstVisitor } class WaitOutsideOfWhileLoopAstVisitor extends AbstractAstVisitor { private boolean withinWhileLoop = false void visitWhileLoop(WhileStatement whileStatement) { withinWhileLoop = true super.visitWhileLoop(whileStatement) withinWhileLoop = false } void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'wait', 0) && !withinWhileLoop) { addViolation call, 'Only call the wait() method within a while loop. Or better yet, prefer the Java concurrency utilities to wait() and notify()' } super.visitMethodCallExpression(call) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/ThreadGroupRule.groovy0000644000175000017500000000400312311370173027670 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Avoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe. * * @author 'Hamlet D'Arcy' */ class ThreadGroupRule extends AbstractAstVisitorRule { String name = 'ThreadGroup' int priority = 2 Class astVisitorClass = ThreadGroupAstVisitor } class ThreadGroupAstVisitor extends AbstractAstVisitor { @Override void visitConstructorCallExpression(ConstructorCallExpression call) { if (isConstructorNamed(call, ThreadGroup)) { addViolation(call, 'Avoid using java.lang.ThreadGroup; it is unsafe') } super.visitConstructorCallExpression(call) } @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodNamed(call, 'getThreadGroup', 0)) { addViolation(call, 'Avoid using java.lang.ThreadGroup; it is unsafe') } super.visitMethodCallExpression(call) } private static boolean isConstructorNamed(ConstructorCallExpression call, Class clazz) { call.type.name == clazz.name || call.type.name == clazz.simpleName } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/DoubleCheckedLockingRule.groovy0000644000175000017500000000770212311370173031445 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.expr.BooleanExpression import org.codehaus.groovy.ast.expr.NotExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.IfStatement import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * This rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern. * * @author Hamlet D'Arcy */ class DoubleCheckedLockingRule extends AbstractAstVisitorRule { String name = 'DoubleCheckedLocking' int priority = 2 Class astVisitorClass = DoubleCheckedLockingAstVisitor } class DoubleCheckedLockingAstVisitor extends AbstractAstVisitor { @Override void visitIfElse(IfStatement node) { addViolationOnDoubleLocking(node) super.visitIfElse(node) } private addViolationOnDoubleLocking(IfStatement node) { if (!AstUtil.expressionIsNullCheck(node)) { return } SynchronizedStatement syncStatement = getSynchronizedStatement(node.ifBlock) if (!syncStatement) { return } if (!AstUtil.isOneLiner(syncStatement.code)) { return } def synchContents = syncStatement.code.statements[0] if (AstUtil.expressionIsNullCheck(synchContents)) { def varName1 = getNullCheckVariableName(node.booleanExpression) def varName2 = getNullCheckVariableName(synchContents.booleanExpression) if (varName1 == varName2) { if (AstUtil.isOneLiner(synchContents.ifBlock) && AstUtil.expressionIsAssignment(synchContents.ifBlock.statements[0], varName2)) { addViolation(synchContents.ifBlock.statements[0], "Double checked locking detected for variable ${varName1}. replace with more robust lazy initialization") } } } } private static SynchronizedStatement getSynchronizedStatement(ASTNode statement) { if (statement instanceof BlockStatement && statement.statements?.size() == 1) { if (statement.statements[0] instanceof SynchronizedStatement) { return statement.statements[0] } } null } private static String getNullCheckVariableName(ASTNode node) { if (!(node instanceof BooleanExpression)) { return null } if (AstUtil.isBinaryExpressionType(node.expression, '==')) { if (AstUtil.isNull(node.expression.leftExpression) && node.expression.rightExpression instanceof VariableExpression) { return node.expression.rightExpression.variable } else if (AstUtil.isNull(node.expression.rightExpression) && node.expression.leftExpression instanceof VariableExpression) { return node.expression.leftExpression.variable } } else if (node.expression instanceof NotExpression && node.expression.expression instanceof VariableExpression) { return node.expression.expression.variable } null } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/concurrency/SynchronizedOnBoxedPrimitiveRule.groovy0000644000175000017500000000402012006632014033266 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.concurrency import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * The code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and * shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and * possible deadlock * * @author 'Hamlet D'Arcy' */ class SynchronizedOnBoxedPrimitiveRule extends AbstractAstVisitorRule { String name = 'SynchronizedOnBoxedPrimitive' int priority = 2 Class astVisitorClass = SynchronizedOnBoxedPrimitiveAstVisitor } class SynchronizedOnBoxedPrimitiveAstVisitor extends AbstractAstVisitor { @Override void visitSynchronizedStatement(SynchronizedStatement statement) { if (statement.expression instanceof VariableExpression) { Class type = AstUtil.getFieldType(currentClassNode, statement.expression.variable) if (type in [Byte, Short, Double, Integer, Long, Float, Character, Boolean]) { addViolation(statement, "Synchronizing on the $type.simpleName field $statement.expression.variable is unsafe. Do not synchronize on boxed types") } } super.visitSynchronizedStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/FieldReferenceAstVisitor.groovy0000644000175000017500000001077712465006222027174 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.PropertyNode import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.util.AstUtil /** * AST Visitor that searches for references to the fields specified on the constructor * * @author Chris Mair */ class FieldReferenceAstVisitor extends AbstractAstVisitor { private final Map unreferencedFieldMap = [:] FieldReferenceAstVisitor(Collection fields) { fields.each { fieldNode -> // Cannot use map syntax here because the name might be a property on Map, such as "metaClass" unreferencedFieldMap.put(fieldNode.name, fieldNode) } } Collection getUnreferencedFields() { return unreferencedFieldMap.values() } void visitVariableExpression(VariableExpression expression) { unreferencedFieldMap.remove(expression.name) super.visitVariableExpression(expression) } void visitProperty(PropertyNode node) { unreferencedFieldMap.remove(node.name) super.visitProperty(node) } void visitPropertyExpression(PropertyExpression expression) { if (expression.objectExpression instanceof VariableExpression && expression.objectExpression.name in ['this', currentClassNode.nameWithoutPackage] && expression.property instanceof ConstantExpression) { unreferencedFieldMap.remove(expression.property.value) } else if (expression.objectExpression instanceof PropertyExpression && expression.objectExpression.objectExpression instanceof VariableExpression && expression.objectExpression.property instanceof ConstantExpression && expression.objectExpression.objectExpression.name == currentClassNode.outerClass?.name && expression.objectExpression.property.value == 'this' ) { unreferencedFieldMap.remove(expression.property.value) } super.visitPropertyExpression(expression) } void visitMethodEx(MethodNode node) { if (node.parameters) { node.parameters.each { parameter -> def initialExpression = parameter.initialExpression if (initialExpression && AstUtil.respondsTo(initialExpression, 'getName')) { unreferencedFieldMap.remove(initialExpression.name) } } } super.visitMethodEx(node) } void visitMethodCallExpression(MethodCallExpression call) { // If there happens to be a method call on a method with the same name as the field. // This handles the case of defining a closure and then executing it, e.g.: // private myClosure = { println 'ok' } // ... // myClosure() // But this could potentially "hide" some unused fields (i.e. false negatives). if (AstUtil.isMethodCallOnObject(call, 'this') && call.method instanceof ConstantExpression) { unreferencedFieldMap.remove(call.method.value) } else if (call.objectExpression instanceof PropertyExpression && call.objectExpression.objectExpression instanceof VariableExpression && call.objectExpression.property instanceof ConstantExpression && call.method instanceof ConstantExpression && call.objectExpression.objectExpression.name == currentClassNode.outerClass?.name && call.objectExpression.property.value == 'this') { unreferencedFieldMap.remove(call.method.value) } super.visitMethodCallExpression(call) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/0000755000175000017500000000000012623571301022323 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/UnusedPrivateMethodParameterRule.groovy0000644000175000017500000000451512051045102032215 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.InnerClassNode import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import java.lang.reflect.Modifier /** * Rule that checks for parameters to private methods that are not referenced within the method body. * * @author Chris Mair * @author Hamlet D'Arcy */ class UnusedPrivateMethodParameterRule extends AbstractAstVisitorRule { String name = 'UnusedPrivateMethodParameter' int priority = 2 String ignoreRegex = 'ignore|ignored' Class astVisitorClass = UnusedPrivateMethodParameterAstVisitor } class UnusedPrivateMethodParameterAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (Modifier.isPrivate(node.modifiers)) { def unusedParameterNames = node.parameters*.name def collector = new ReferenceCollector() collector.visitMethod(node) getAnonymousClasses().each { ClassNode it -> it.visitContents(collector) } unusedParameterNames.removeAll(collector.references) unusedParameterNames.removeAll { it =~ rule.ignoreRegex } unusedParameterNames.each { parameterName -> addViolation(node, "Method parameter [$parameterName] is never referenced in the method $node.name of class $currentClassName") } } } private List getAnonymousClasses() { sourceCode.ast.classes.findAll { it instanceof InnerClassNode && it.anonymous } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/UnusedVariableRule.groovy0000644000175000017500000001322312465005702027335 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.InnerClassNode import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.source.SourceCode import org.codenarc.util.AstUtil import org.codenarc.util.WildcardPattern import org.codehaus.groovy.ast.stmt.ForStatement /** * Rule that checks for variables that are not referenced. * * @author Chris Mair * @author Hamlet D'Arcy */ class UnusedVariableRule extends AbstractAstVisitorRule { String name = 'UnusedVariable' int priority = 2 String ignoreVariableNames @Override void applyTo(SourceCode sourceCode, List violations) { // If AST is null, skip this source code def ast = sourceCode.ast if (ast && ast.classes) { def anonymousClasses = getAnonymousClasses(ast.classes) def collector = new ReferenceCollector() anonymousClasses.each { collector.visitClass(it) } def anonymousReferences = collector.references ast.classes.each { classNode -> if (shouldApplyThisRuleTo(classNode)) { def visitor = new UnusedVariableAstVisitor(anonymousReferences: anonymousReferences) visitor.rule = this visitor.sourceCode = sourceCode visitor.visitClass(classNode) violations.addAll(visitor.violations) } } } } private static List getAnonymousClasses(List classes) { classes.findAll { it instanceof InnerClassNode && it.anonymous } } } class UnusedVariableAstVisitor extends AbstractAstVisitor { private final variablesByBlockScope = [] as Stack private variablesInCurrentBlockScope private anonymousReferences void visitDeclarationExpression(DeclarationExpression declarationExpression) { if (isFirstVisit(declarationExpression)) { def varExpressions = AstUtil.getVariableExpressions(declarationExpression) varExpressions.each { varExpression -> variablesInCurrentBlockScope[varExpression] = false } } super.visitDeclarationExpression(declarationExpression) } void visitBlockStatement(BlockStatement block) { beforeBlock() super.visitBlockStatement(block) afterBlock() } @Override void visitForLoop(ForStatement forLoop) { beforeBlock() super.visitForLoop(forLoop) afterBlock() } private beforeBlock() { variablesInCurrentBlockScope = [:] variablesByBlockScope.push(variablesInCurrentBlockScope) } private afterBlock() { variablesInCurrentBlockScope.each { varExpression, isUsed -> if (!isIgnoredVariable(varExpression) && !isUsed && !anonymousReferences.contains(varExpression.name)) { addViolation(varExpression, "The variable [${varExpression.name}] in class $currentClassName is not used") } } variablesByBlockScope.pop() variablesInCurrentBlockScope = variablesByBlockScope.empty() ? null : variablesByBlockScope.peek() } void visitVariableExpression(VariableExpression expression) { markVariableAsReferenced(expression.name, expression) super.visitVariableExpression(expression) } void visitMethodCallExpression(MethodCallExpression call) { // If there happens to be a method call on a method with the same name as the variable. // This handles the case of defining a closure and then executing it, e.g.: // def myClosure = { println 'ok' } // myClosure() // But this could potentially "hide" some unused variables (i.e. false negatives). if (call.isImplicitThis() && call.method instanceof ConstantExpression) { markVariableAsReferenced(call.method.value, null) } super.visitMethodCallExpression(call) } @SuppressWarnings('NestedForLoop') private void markVariableAsReferenced(String varName, VariableExpression varExpression) { for(blockVariables in variablesByBlockScope) { for(var in blockVariables.keySet()) { if (var.name == varName && var != varExpression) { blockVariables[var] = true return } } } } private boolean isIgnoredVariable(VariableExpression expression) { new WildcardPattern(rule.ignoreVariableNames, false).matches(expression.name) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/UnusedObjectRule.groovy0000644000175000017500000000360212006632014027007 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitorRule /** * Checks for object constructions that are not assigned or used (i.e., ignored). * Ignores unassigned objects if the construction is the last statement within a block, * because it may be the intentional return value. * * By default, this rule does not apply to test files. * * @author Chris Mair */ class UnusedObjectRule extends AbstractAstVisitorRule { String name = 'UnusedObject' int priority = 2 Class astVisitorClass = UnusedObjectAstVisitor String doNotApplyToFilesMatching = DEFAULT_TEST_FILES } class UnusedObjectAstVisitor extends AbstractLastStatementInBlockAstVisitor { void visitExpressionStatement(ExpressionStatement statement) { if (isFirstVisit(statement) && statement.expression instanceof ConstructorCallExpression && !statement.expression.isSuperCall() && !statement.expression.isThisCall() && !isLastStatementInBlock(statement)) { addViolation(statement, 'The instantiated object is not used') } super.visitExpressionStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/UnusedPrivateFieldRule.groovy0000644000175000017500000000556412006632014030170 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractSharedAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.FieldReferenceAstVisitor import org.codenarc.rule.Violation import org.codenarc.source.SourceCode import org.codenarc.util.WildcardPattern /** * Rule that checks for private fields that are not referenced within the same class. *

* The ignoreFieldNames property optionally specifies one or more * (comma-separated) field names that should be ignored (i.e., that should not cause a * rule violation). The name(s) may optionally include wildcard characters ('*' or '?'). * * @author Chris Mair * @author Hamlet D'Arcy */ class UnusedPrivateFieldRule extends AbstractSharedAstVisitorRule { String name = 'UnusedPrivateField' int priority = 2 String ignoreFieldNames = 'serialVersionUID' @Override protected AstVisitor getAstVisitor(SourceCode sourceCode) { def allPrivateFields = collectAllPrivateFields(sourceCode.ast) return new FieldReferenceAstVisitor(allPrivateFields) } @Override protected List getViolations(AstVisitor visitor, SourceCode sourceCode) { visitor.unreferencedFields.each { FieldNode fieldNode -> visitor.addViolation(fieldNode, "The field ${fieldNode.name} is not used within the class ${fieldNode.owner?.name}") } return visitor.violations } @SuppressWarnings('NestedBlockDepth') private collectAllPrivateFields(ast) { def allPrivateFields = [] ast.classes.each { classNode -> if (shouldApplyThisRuleTo(classNode)) { classNode.fields.inject(allPrivateFields) { acc, fieldNode -> def wildcardPattern = new WildcardPattern(ignoreFieldNames, false) def isPrivate = fieldNode.modifiers & FieldNode.ACC_PRIVATE def isNotGenerated = fieldNode.lineNumber != -1 def isIgnored = wildcardPattern.matches(fieldNode.name) if (isPrivate && isNotGenerated && !isIgnored) { acc << fieldNode } acc } } } allPrivateFields } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/AbstractLastStatementInBlockAstVisitor.groovy0000644000175000017500000000260212006632014033332 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.Statement import org.codenarc.rule.AbstractAstVisitor /** * Abstract superclass for AstVisitor classes that need to determine whether a Statement is * the last statement within a block. * * @author Chris Mair */ abstract class AbstractLastStatementInBlockAstVisitor extends AbstractAstVisitor { private final lastStatements = [] as Set protected boolean isLastStatementInBlock(Statement statement) { lastStatements.contains(statement) } void visitBlockStatement(BlockStatement block) { if (block.statements) { lastStatements << block.statements.last() } super.visitBlockStatement(block) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/UnusedPrivateMethodRule.groovy0000644000175000017500000001540612311373553030372 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractSharedAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.Violation import org.codenarc.source.SourceCode import org.codenarc.util.AstUtil import java.lang.reflect.Modifier import org.codehaus.groovy.ast.expr.* /** * Rule that checks for private methods that are not referenced within the same class. * * Known limitations: *

    *
  • Does not handle method reference through property access: getName() accessed as x.name
  • *
  • Does not handle method invocations when method name is a GString (e.g. this."${methodName}"
  • *
  • Does not handle invoking private method of another instance (i.e. other than 'this')
  • *
  • Does not differentiate between multiple private methods with the same name but different parameters (i.e., overloaded)
  • *
  • Does not check constructors
  • *
* * @author Chris Mair * @author Hamlet D'Arcy */ class UnusedPrivateMethodRule extends AbstractSharedAstVisitorRule { String name = 'UnusedPrivateMethod' int priority = 2 @Override protected AstVisitor getAstVisitor(SourceCode sourceCode) { def allPrivateMethods = collectAllPrivateMethods(sourceCode.ast) return new UnusedPrivateMethodAstVisitor(allPrivateMethods, sourceCode.ast.classes*.name) } @Override protected List getViolations(AstVisitor visitor, SourceCode sourceCode) { visitor.unusedPrivateMethods.each { key, value -> visitor.addViolation(value, "The method $key is not used within ${sourceCode.name ?: 'the class'}") } return visitor.violations } @SuppressWarnings('NestedBlockDepth') private collectAllPrivateMethods(ast) { def allPrivateMethods = [:] ast.classes.each { classNode -> if (shouldApplyThisRuleTo(classNode)) { classNode.methods.inject(allPrivateMethods) { acc, methodNode -> if ((Modifier.isPrivate(methodNode.modifiers)) && !allPrivateMethods.containsKey(methodNode.name)) { allPrivateMethods.put(methodNode.name, methodNode) } } } } allPrivateMethods } } @SuppressWarnings('DuplicateLiteral') class UnusedPrivateMethodAstVisitor extends AbstractAstVisitor { private final Map unusedPrivateMethods private final List classNames UnusedPrivateMethodAstVisitor(Map unusedPrivateMethods, List classNames) { this.classNames = classNames.inject(['this']) { acc, value -> acc.add value if (value.contains('$') && !value.endsWith('$')) { acc.add value[value.lastIndexOf('$') + 1..-1] } else if (value.contains('.') && !value.endsWith('.')) { acc.add value[value.lastIndexOf('.') + 1..-1] } acc } this.unusedPrivateMethods = unusedPrivateMethods } void visitMethodCallExpression(MethodCallExpression expression) { classNames.each { if (isMethodCall(expression, it)) { unusedPrivateMethods.remove(expression.method.value) } } // Static invocation through current class name if (isMethodCall(expression, currentClassNode.nameWithoutPackage)) { unusedPrivateMethods.remove(expression.method.value) } super.visitMethodCallExpression(expression) } void visitMethodPointerExpression(MethodPointerExpression methodPointerExpression) { if (methodPointerExpression.expression instanceof VariableExpression && classNames.contains(methodPointerExpression.expression.name) && methodPointerExpression.methodName instanceof ConstantExpression) { unusedPrivateMethods.remove(methodPointerExpression.methodName.value) } super.visitMethodPointerExpression(methodPointerExpression) } @Override void visitVariableExpression(VariableExpression expression) { if (expression.name.size() == 1) { unusedPrivateMethods.remove('get' + expression.name.toUpperCase()) unusedPrivateMethods.remove('is' + expression.name.toUpperCase()) unusedPrivateMethods.remove('set' + expression.name.toUpperCase()) } else { unusedPrivateMethods.remove('get' + expression.name[0].toUpperCase() + expression.name[1..-1]) unusedPrivateMethods.remove('is' + expression.name[0].toUpperCase() + expression.name[1..-1]) unusedPrivateMethods.remove('set' + expression.name[0].toUpperCase() + expression.name[1..-1]) } super.visitVariableExpression expression } @Override void visitPropertyExpression(PropertyExpression expression) { if (isConstantString(expression.property)) { def propertyName = expression.property.value if (propertyName.size() == 1) { def propertyNameUpperCase = expression.property.value.toUpperCase() unusedPrivateMethods.remove('get' + propertyNameUpperCase) unusedPrivateMethods.remove('set' + propertyNameUpperCase) } else { if (propertyName) { unusedPrivateMethods.remove('get' + propertyName[0].toUpperCase() + propertyName[1..-1]) unusedPrivateMethods.remove('set' + propertyName[0].toUpperCase() + propertyName[1..-1]) } } } super.visitPropertyExpression expression } private static boolean isConstantString(Expression expression) { expression instanceof ConstantExpression && expression.value instanceof String } private static boolean isMethodCall(MethodCallExpression expression, String targetName) { AstUtil.isMethodCallOnObject(expression, targetName) && expression.method instanceof ConstantExpression } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/UnusedArrayRule.groovy0000644000175000017500000000313312006632016026660 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.expr.ArrayExpression import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitorRule /** * Checks for array allocations that are not assigned or used (i.e., it is ignored). * Ignores unassigned arrays if the construction is the last statement within a block, * because it may be the intentional return value. * * @author Chris Mair */ class UnusedArrayRule extends AbstractAstVisitorRule { String name = 'UnusedArray' int priority = 2 Class astVisitorClass = UnusedArrayAstVisitor } class UnusedArrayAstVisitor extends AbstractLastStatementInBlockAstVisitor { void visitExpressionStatement(ExpressionStatement statement) { if (statement.expression instanceof ArrayExpression && !isLastStatementInBlock(statement)) { addViolation(statement, 'The result of the array expression is ignored') } super.visitExpressionStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/UnusedMethodParameterRule.groovy0000644000175000017500000000577412051271130030674 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.InnerClassNode import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * This rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override. * * @author Hamlet D'Arcy * @author Chris Mair */ class UnusedMethodParameterRule extends AbstractAstVisitorRule { String name = 'UnusedMethodParameter' int priority = 2 String ignoreRegex = 'ignore|ignored' String ignoreClassRegex = '.*Category' Class astVisitorClass = UnusedMethodParameterAstVisitor } class UnusedMethodParameterAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (!currentClassNode.isInterface() && !node.isAbstract() && !(currentClassName ==~ rule.ignoreClassRegex) && !Modifier.isPrivate(node.modifiers) && AstUtil.getAnnotation(node, 'Override') == null && !isMainMethod(node)) { def unusedParameterNames = node.parameters*.name def collector = new ReferenceCollector() collector.visitMethod(node) getAnonymousClasses().each { ClassNode it -> it.visitContents(collector) } unusedParameterNames.removeAll(collector.references) unusedParameterNames.removeAll { it =~ rule.ignoreRegex } unusedParameterNames.each { parameterName -> addViolation(node, "Method parameter [$parameterName] is never referenced in the method $node.name of class $currentClassName") } } } private static boolean isMainMethod(MethodNode node) { AstUtil.isMethodNode(node, 'main', 1) && (node.parameters[0].dynamicTyped || node.parameters[0].type.name in ['String[]', '[Ljava.lang.String;']) && (node.isVoidMethod() || node.dynamicReturnType) && node.isStatic() } private List getAnonymousClasses() { sourceCode.ast.classes.findAll { it instanceof InnerClassNode && it.anonymous } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/unused/ReferenceCollector.groovy0000644000175000017500000000352412465654155027360 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.unused import org.codehaus.groovy.ast.ClassCodeVisitorSupport import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.control.SourceUnit import org.codenarc.util.AstUtil /** * * @author Hamlet D'Arcy */ class ReferenceCollector extends ClassCodeVisitorSupport { def references = [] as Set void visitVariableExpression(VariableExpression expression) { references.add(expression.name) } void visitMethodCallExpression(MethodCallExpression call) { // Check for method call on a method with the same name as the parameter. // This handles the case of a parameter being a closure that is then invoked within the method, e.g.: // private myMethod1(Closure closure) { // println closure() // } if (AstUtil.isMethodCallOnObject(call, 'this') && call.method instanceof ConstantExpression) { references.add(call.method.value) } super.visitMethodCallExpression(call) } @Override SourceUnit getSourceUnit() { throw new UnsupportedOperationException() } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/dry/0000755000175000017500000000000012623571301021616 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/dry/DryUtil.groovy0000644000175000017500000001357312014546114024470 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.dry import org.codehaus.groovy.ast.expr.* /** * Utility methods for the DRY rule classes * * @author Chris Mair */ class DryUtil { /** * @return true only if both MapExpressions have the same set of constant or literal keys and values, in the same order. */ static boolean areTheSameConstantOrLiteralMaps(MapExpression mapExpression1, MapExpression mapExpression2) { def mapEntryExpressions1 = mapExpression1.mapEntryExpressions def mapEntryExpressions2 = mapExpression2.mapEntryExpressions if (mapEntryExpressions1.size() == mapEntryExpressions2.size()) { for (int index = 0; index < mapEntryExpressions1.size(); index++) { // may be empty if (!areTheSameConstantOrLiteralMapEntryExpression(mapEntryExpressions1[index], mapEntryExpressions2[index])) { return false } } return true // all entries matched } return false } /** * @return true only if both MapEntryExpressions have the same constant or literal key and value */ static boolean areTheSameConstantOrLiteralMapEntryExpression(MapEntryExpression mapEntryExpression1, MapEntryExpression mapEntryExpression2) { if (mapEntryExpression1 == null || mapEntryExpression2 == null) { return mapEntryExpression1 == mapEntryExpression2 } return haveTheSameConstantOrLiteralValue(mapEntryExpression1.keyExpression, mapEntryExpression2.keyExpression) && haveTheSameConstantOrLiteralValue(mapEntryExpression1.valueExpression, mapEntryExpression2.valueExpression) } /** * @return true only if both Expressions have the same constant or literal value */ static boolean haveTheSameConstantOrLiteralValue(Expression expression1, Expression expression2) { if (expression1.class != expression2.class) { return false } boolean isTheSameValue = haveTheSameConstantValue(expression1, expression2) || haveTheSameConstantPropertyExpression(expression1, expression2) || haveTheSameMapLiteralValue(expression1, expression2) || haveTheSameListLiteralValue(expression1, expression2) return isTheSameValue } /** * @return true only if both Expressions are MapExpressions and both have the same set of constant or * literal keys and values, in the same order. */ static boolean haveTheSameMapLiteralValue(Expression expression1, Expression expression2) { if (!(expression1 instanceof MapExpression && expression2 instanceof MapExpression)) { return false } return areTheSameConstantOrLiteralMaps(expression1, expression2) } /** * @return true only if both Expressions are ListExpressions and both have the same set of constant or literal values, in the same order. */ static boolean haveTheSameListLiteralValue(Expression expression1, Expression expression2) { if (!(expression1 instanceof ListExpression && expression2 instanceof ListExpression)) { return false } return areTheSameConstantOrLiteralLists(expression1, expression2) } /** * @return true only if both ListExpressions have the same set of constant or literal values, in the same order. */ static boolean areTheSameConstantOrLiteralLists(ListExpression listExpression1, ListExpression listExpression2) { def expressions1 = listExpression1.expressions def expressions2 = listExpression2.expressions if (expressions1.size() == expressions2.size()) { for (int index = 0; index < expressions1.size(); index++) { // may be empty if (!haveTheSameConstantOrLiteralValue(expressions1[index], expressions2[index])) { return false } } return true // all entries matched } return false } /** * @return true only if both Expressions have the same constant or literal values */ static boolean haveTheSameConstantValue(Expression expression1, Expression expression2) { if (!(expression1 instanceof ConstantExpression && expression2 instanceof ConstantExpression)) { return false } return expression1.value == expression2.value } /** * @return true only if both Expressions have the same constant property expression (e.g., Object.Property) */ static boolean haveTheSameConstantPropertyExpression(Expression expression1, Expression expression2) { if (!(expression1 instanceof PropertyExpression && expression2 instanceof PropertyExpression)) { return false } Expression object1 = ((PropertyExpression) expression1).getObjectExpression() Expression property1 = ((PropertyExpression) expression1).getProperty() Expression object2 = ((PropertyExpression) expression2).getObjectExpression() Expression property2 = ((PropertyExpression) expression2).getProperty() boolean isTheSame = false if (object1 instanceof VariableExpression) { isTheSame = object1.getName() == object2.getName() && property1.getText() == property2.getText() } return isTheSame } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/dry/DuplicateMapLiteral.groovy0000644000175000017500000000404012311373552026752 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.dry import org.codehaus.groovy.ast.expr.MapExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Check for multiple instances of the same Map literal, limited to Maps where the keys * and values are all constants or literals. * * @author Chris Mair */ class DuplicateMapLiteralRule extends AbstractAstVisitorRule { String name = 'DuplicateMapLiteral' int priority = 3 String doNotApplyToFilesMatching = DEFAULT_TEST_FILES Class astVisitorClass = DuplicateMapLiteralAstVisitor } class DuplicateMapLiteralAstVisitor extends AbstractAstVisitor { private final Collection mapLiterals = [] @Override void visitMapExpression(MapExpression expression) { if (expression.mapEntryExpressions.isEmpty()) { return } if(isFirstVisit(expression)) { if (AstUtil.isMapLiteralWithOnlyConstantValues(expression)) { def isDuplicate = mapLiterals.find { mapLiteral -> DryUtil.areTheSameConstantOrLiteralMaps(mapLiteral, expression) } if (isDuplicate) { addViolation(expression, "Map ${expression.text} is duplicated.") return // Ignore duplicate sub-Maps } mapLiterals.add(expression) } super.visitMapExpression(expression) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/dry/DuplicateStringLiteralRule.groovy0000644000175000017500000000346512311373552030345 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.dry import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Code containing duplicate String literals can usually be improved by declaring the String as a constant field. *

* Set the optional ignoreStrings property to a comma-separated list (String) of * the strings that should be ignored by this rule (i.e., not cause a violation). This property * defaults to "" to ignore empty strings. * * By default, this rule does not apply to test files. * * @author Hamlet D'Arcy * @author Chris Mair */ class DuplicateStringLiteralRule extends AbstractAstVisitorRule { String name = 'DuplicateStringLiteral' int priority = 2 String doNotApplyToFilesMatching = DEFAULT_TEST_FILES String ignoreStrings = '' @Override AstVisitor getAstVisitor() { def ignoreValuesSet = parseIgnoreValues() new DuplicateLiteralAstVisitor(String, ignoreValuesSet) } private Set parseIgnoreValues() { if (ignoreStrings == null) { return Collections.EMPTY_SET } def strings = ignoreStrings.contains(',') ? ignoreStrings.split(',') : [ignoreStrings] strings as Set } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/dry/DuplicateListLiteral.groovy0000644000175000017500000000404112311373552027151 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.dry import org.codehaus.groovy.ast.expr.ListExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Check for multiple instances of the same List literal, limited to Lists where the * values are all constants or literals. * * @author Chris Mair */ class DuplicateListLiteralRule extends AbstractAstVisitorRule { String name = 'DuplicateListLiteral' int priority = 3 String doNotApplyToFilesMatching = DEFAULT_TEST_FILES Class astVisitorClass = DuplicateListLiteralAstVisitor } class DuplicateListLiteralAstVisitor extends AbstractAstVisitor { private final Collection listLiterals = [] @Override void visitListExpression(ListExpression expression) { if (expression.expressions.isEmpty()) { return } if(isFirstVisit(expression)) { if (AstUtil.isListLiteralWithOnlyConstantValues(expression)) { def isDuplicate = listLiterals.find { listLiteral -> DryUtil.areTheSameConstantOrLiteralLists(listLiteral, expression) } if (isDuplicate) { addViolation(expression, "List ${expression.text} is duplicated.") return // Ignore duplicate sub-Lists } listLiterals.add(expression) } super.visitListExpression(expression) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/dry/DuplicateNumberLiteralRule.groovy0000644000175000017500000000357312311373552030327 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.dry import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor /** * Checks for duplication of constant number literal values. *

* Set the optional ignoreNumbers property to a comma-separated list (String) of * the numbers that should be ignored by this rule (i.e., not cause a violation). This property * defaults to "0,1" to ignore the constants zero and one. * * By default, this rule does not apply to test files. * * @author Chris Mair */ class DuplicateNumberLiteralRule extends AbstractAstVisitorRule { String name = 'DuplicateNumberLiteral' int priority = 2 String doNotApplyToFilesMatching = DEFAULT_TEST_FILES String ignoreNumbers = '0,1' private static final NUMBER_TYPES = [Number, Byte.TYPE, Double.TYPE, Float.TYPE, Integer.TYPE, Long.TYPE, Short.TYPE] @Override AstVisitor getAstVisitor() { def ignoreValuesSet = parseIgnoreValues() new DuplicateLiteralAstVisitor(NUMBER_TYPES, ignoreValuesSet) } private Set parseIgnoreValues() { def strings = ignoreNumbers ? ignoreNumbers.tokenize(',') : [] def numbers = strings*.trim() numbers as Set } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/dry/DuplicateLiteralAstVisitor.groovy0000644000175000017500000001054112311373552030347 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.dry import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitor import org.codehaus.groovy.ast.expr.* /** * Abstract superclass for rule AstVisitor classes that detect duplicate literal constants * * @author Hamlet D'Arcy * @author Chris Mair */ class DuplicateLiteralAstVisitor extends AbstractAstVisitor { List constants = [] private final List constantTypes private final Set ignoreValuesSet DuplicateLiteralAstVisitor(Class constantType, Set ignoreValuesSet) { assert constantType this.constantTypes = [constantType] this.ignoreValuesSet = ignoreValuesSet } DuplicateLiteralAstVisitor(List constantTypes, Set ignoreValuesSet) { assert constantTypes this.constantTypes = constantTypes this.ignoreValuesSet = ignoreValuesSet } @Override void visitClassEx(ClassNode node) { constants.clear() } void visitArgumentlistExpression(ArgumentListExpression expression) { expression.expressions.each { addViolationIfDuplicate(it) } super.visitArgumentlistExpression expression } void visitMethodCallExpression(MethodCallExpression call) { addViolationIfDuplicate(call.objectExpression) super.visitMethodCallExpression call } void visitListExpression(ListExpression expression) { expression.expressions.findAll { addViolationIfDuplicate it } super.visitListExpression expression } void visitField(FieldNode node) { if (node.type == node.owner) { ignoreValuesSet.add node.name } addViolationIfDuplicate(node.initialValueExpression, node.isStatic()) super.visitField node } void visitBinaryExpression(BinaryExpression expression) { addViolationIfDuplicate expression.leftExpression addViolationIfDuplicate expression.rightExpression super.visitBinaryExpression expression } void visitShortTernaryExpression(ElvisOperatorExpression expression) { addViolationIfDuplicate expression.booleanExpression addViolationIfDuplicate expression.trueExpression addViolationIfDuplicate expression.falseExpression super.visitShortTernaryExpression expression } void visitReturnStatement(ReturnStatement statement) { addViolationIfDuplicate(statement.expression) super.visitReturnStatement statement } void visitStaticMethodCallExpression(StaticMethodCallExpression call) { call.arguments.each { addViolationIfDuplicate(it) } super.visitStaticMethodCallExpression call } void visitMapEntryExpression(MapEntryExpression expression) { addViolationIfDuplicate expression.valueExpression super.visitMapEntryExpression expression } private addViolationIfDuplicate(node, boolean isStatic = false) { if (!isFirstVisit(node)) { return } if (!(node instanceof ConstantExpression)) { return } if (node.value == null) { return } if (!node.type.isResolved()) { return } def literal = String.valueOf(node.value) for (Class constantType: constantTypes) { if ((constantType.isAssignableFrom(node.value.class) || node.value.class == constantType || node.type.typeClass == constantType)) { if (constants.contains(literal) && !isStatic && !ignoreValuesSet.contains(literal)) { addViolation node, "Duplicate ${constantType.simpleName} Literal: $literal" return } } } constants.add literal } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/0000755000175000017500000000000012623571301022271 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/ConstantsOnlyInterfaceRule.groovy0000644000175000017500000000274412006632016031032 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * An interface should be used only to model a behaviour of a class: using an interface as a container of constants is a poor usage pattern. * * @author 'Hamlet D'Arcy' */ class ConstantsOnlyInterfaceRule extends AbstractAstVisitorRule { String name = 'ConstantsOnlyInterface' int priority = 2 Class astVisitorClass = ConstantsOnlyInterfaceAstVisitor } class ConstantsOnlyInterfaceAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { if (node.isInterface() && node.fields && !node.methods) { addViolation(node, "The interface $node.name has only fields and no methods defined") } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/EmptyMethodInAbstractClassRule.groovy0000644000175000017500000000553312311370173031574 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * An empty method in an abstract class should be abstract instead, as developer may rely on this empty implementation rather than code the appropriate one. * * @author Hamlet D'Arcy */ class EmptyMethodInAbstractClassRule extends AbstractAstVisitorRule { String name = 'EmptyMethodInAbstractClass' int priority = 2 Class astVisitorClass = EmptyMethodInAbstractClassAstVisitor } class EmptyMethodInAbstractClassAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (isAbstract(node.declaringClass) && !isAbstract(node) && !node.isPrivate()) { if (node.returnType.name == 'void') { // check for empty statement if (node.code instanceof BlockStatement && !node.code.statements) { addViolation (node, "The method $node.name in abstract class $node.declaringClass.name is empty. Consider making it abstract") } } else if (node.code instanceof BlockStatement && node.code.statements.size() == 1) { // check for 'return null' statement def code = node.code.statements[0] if (code instanceof ExpressionStatement && AstUtil.isNull(code.expression)) { addViolation (node, "The method $node.name in abstract class $node.declaringClass.name contains no logic. Consider making it abstract") } else if (code instanceof ReturnStatement && AstUtil.isNull(code.expression)) { addViolation (node, "The method $node.name in abstract class $node.declaringClass.name contains no logic. Consider making it abstract") } } } } private static boolean isAbstract(node) { return Modifier.isAbstract(node.modifiers) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/PublicInstanceFieldRule.groovy0000644000175000017500000000276412050576634030260 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor /** * Using public fields is considered to be a bad design. Use properties instead. * * @author Victor Savkin */ class PublicInstanceFieldRule extends AbstractAstVisitorRule { String name = 'PublicInstanceField' int priority = 2 Class astVisitorClass = PublicInstanceFieldAstVisitor } class PublicInstanceFieldAstVisitor extends AbstractFieldVisitor { @Override void visitField(FieldNode node) { if(node.public && !node.static) { addViolation node, createErrorMessage(node) } } private static createErrorMessage(node) { "Using public fields is considered bad design. Create property '$node.name' instead." } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/AbstractClassWithoutAbstractMethodRule.groovy0000644000175000017500000000377112041061500033327 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import java.lang.reflect.Modifier /** * The abstract class does not contain any abstract methods. An abstract class suggests an incomplete implementation, * which is to be completed by subclasses implementing the abstract methods. If the class is intended to be used as a * base class only (not to be instantiated direcly) a protected constructor can be provided prevent direct instantiation. * * @author 'Hamlet D'Arcy' */ class AbstractClassWithoutAbstractMethodRule extends AbstractAstVisitorRule { String name = 'AbstractClassWithoutAbstractMethod' int priority = 2 Class astVisitorClass = AbstractClassWithoutAbstractMethodAstVisitor } class AbstractClassWithoutAbstractMethodAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { if (!node.isInterface() && Modifier.isAbstract(node.modifiers) && !node.superClass.name.startsWith('Abstract') && !node.superClass.name.startsWith('Base')) { if (!node.methods.any { Modifier.isAbstract(it.modifiers) }) { addViolation(node, "The abstract class $node.name contains no abstract methods") } } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/CloseWithoutCloseableRule.groovy0000644000175000017500000000330212041061500030616 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * If a class defines a "void close()" then that class should implement java.io.Closeable. * * @author Hamlet D'Arcy */ class CloseWithoutCloseableRule extends AbstractAstVisitorRule { String name = 'CloseWithoutCloseable' int priority = 2 Class astVisitorClass = CloseWithoutCloseableAstVisitor } class CloseWithoutCloseableAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (AstUtil.isMethodNode(node, 'close', 0, Void.TYPE) && !Modifier.isPrivate(node.modifiers)) { if (!AstUtil.classNodeImplementsType(node.declaringClass, Closeable) && !AstUtil.classNodeImplementsType(node.declaringClass, Script)) { addViolation(node, 'void close() method defined without implementing Closeable') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/FinalClassWithProtectedMemberRule.groovy0000644000175000017500000000473612311370173032255 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * This rule finds classes marked final that contain protected methods and fields. If a class is final then it may not be subclassed, * and there is therefore no point in having a member with protected visibility. Either the class should not be final or * the member should be private or protected. * * @author Hamlet D'Arcy */ class FinalClassWithProtectedMemberRule extends AbstractAstVisitorRule { String name = 'FinalClassWithProtectedMember' int priority = 2 Class astVisitorClass = FinalClassWithProtectedMemberAstVisitor } class FinalClassWithProtectedMemberAstVisitor extends AbstractAstVisitor { @Override void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { if (node.isProtected()) { if (Modifier.isFinal(node.declaringClass.modifiers) && !AstUtil.getAnnotation(node, 'Override')) { addViolation node, "The method $node.name has protected visibility but the enclosing class $node.declaringClass.name is marked final" } } super.visitConstructorOrMethod(node, isConstructor) } @Override void visitField(FieldNode node) { if (isProtected(node)) { if (Modifier.isFinal(node.declaringClass.modifiers)) { addViolation node, "The field $node.name has protected visibility but the enclosing class $node.declaringClass.name is marked final" } } super.visitField(node) } private static boolean isProtected(node) { Modifier.isProtected(node.modifiers) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/AbstractClassWithPublicConstructorRule.groovy0000644000175000017500000000332512041061500033352 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import java.lang.reflect.Modifier /** * An abstract class cannot be instantiated, therefore a public constructor is useless and confusing. * * @author Chris Mair */ class AbstractClassWithPublicConstructorRule extends AbstractAstVisitorRule { String name = 'AbstractClassWithPublicConstructor' int priority = 2 Class astVisitorClass = AbstractClassWithPublicConstructorAstVisitor } class AbstractClassWithPublicConstructorAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { if (Modifier.isAbstract(node.modifiers)) { node.declaredConstructors.each { constructor -> if (Modifier.isPublic(constructor.modifiers)) { addViolation(constructor, "The abstract class $node.name contains a public constructor") } } } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/LocaleSetDefaultRule.groovy0000644000175000017500000000455112231044226027551 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.PropertyExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codenarc.util.AstUtil /** * Checks for calls to Locale.setDefault(), which sets the Locale across the entire JVM. * * @author mingzhi.huang, rob.patrick * @author Chris Mair */ class LocaleSetDefaultRule extends AbstractAstVisitorRule { String name = 'LocaleSetDefault' int priority = 2 Class astVisitorClass = LocaleSetDefaultAstVisitor } class LocaleSetDefaultAstVisitor extends AbstractAstVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, ['Locale', /java\.util\.Locale/], ['setDefault'])) { addViolation(call, 'Avoid explicit calls to Locale.setDefault, which sets the Locale across the entire JVM') } super.visitMethodCallExpression(call) } @Override void visitBinaryExpression(BinaryExpression expression) { if (expression.operation.text == '=') { def leftExpression = expression.leftExpression if (leftExpression instanceof PropertyExpression && (AstUtil.isVariable(leftExpression.objectExpression, /Locale/) || leftExpression.objectExpression.text == 'java.util.Locale') && AstUtil.isConstant(leftExpression.property, 'default') ) { addViolation(expression, 'Avoid explicit assignment to Locale.default, which sets the Locale across the entire JVM') } } super.visitBinaryExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/CompareToWithoutComparableRule.groovy0000644000175000017500000000350412006632014031627 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * If you implement a compareTo method then you should also implement the Comparable interface. If you don't then you * could possibly get an exception if the Groovy == operator is invoked on your object. This is an issue fixed in * Groovy 1.8 but present in previous versions. * * @author Hamlet D'Arcy */ class CompareToWithoutComparableRule extends AbstractAstVisitorRule { String name = 'CompareToWithoutComparable' int priority = 2 Class astVisitorClass = CompareToWithoutComparableAstVisitor } class CompareToWithoutComparableAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (AstUtil.isMethodNode(node, 'compareTo', 1, Integer.TYPE)) { if (!AstUtil.classNodeImplementsType(node.declaringClass, Comparable)) { addViolation(node.declaringClass, "compareTo method at line $node.lineNumber would implement Comparable.compareTo(Object) but the enclosing class does not implement Comparable.") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/InstanceofRule.groovy0000644000175000017500000000404112415113071026453 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.expr.BinaryExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codenarc.util.WildcardPattern /** * Checks for use of the instanceof operator. Use ignoreTypeNames property to configure ignored type names. * * @author Chris Mair */ class InstanceofRule extends AbstractAstVisitorRule { String name = 'Instanceof' int priority = 2 String doNotApplyToFilesMatching = DEFAULT_TEST_FILES String ignoreTypeNames = '*Exception' Class astVisitorClass = InstanceofAstVisitor } class InstanceofAstVisitor extends AbstractAstVisitor { private wildcardPattern @Override protected void visitClassEx(ClassNode node) { wildcardPattern = new WildcardPattern(rule.ignoreTypeNames, false) } @Override void visitBinaryExpression(BinaryExpression expression) { def wildcardPattern = new WildcardPattern(rule.ignoreTypeNames, false) if (isFirstVisit(expression)) { def op = expression.operation String typeName = expression.rightExpression.type.name if (op.text == 'instanceof' && !wildcardPattern.matches(typeName)) { addViolation(expression, "The instanceof operator is used in class $currentClassName") } } super.visitBinaryExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/NestedForLoopRule.groovy0000644000175000017500000000277212440206243027120 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.stmt.ForStatement import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor /** * Reports classes with nested for loops. * * @author Maciej Ziarko */ class NestedForLoopRule extends AbstractAstVisitorRule { String name = 'NestedForLoop' int priority = 3 Class astVisitorClass = NestedForLoopAstVisitor } class NestedForLoopAstVisitor extends AbstractAstVisitor { private final Stack forStatementsStack = [] as Stack @Override void visitForLoop(ForStatement forLoop) { forStatementsStack.push(forLoop) if (isForNested()) { addViolation(forLoop, 'Nested for loop') } super.visitForLoop(forLoop) forStatementsStack.pop() } private boolean isForNested() { return forStatementsStack.size() >= 2 } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/PrivateFieldCouldBeFinalRule.groovy0000644000175000017500000001675112427743540031200 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.expr.* import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractSharedAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.Violation import org.codenarc.source.SourceCode import org.codenarc.util.AstUtil import org.codenarc.util.WildcardPattern /** * Rule that checks for private fields that are only set within a constructor or field initializer. * Such fields can safely be made final. * * @author Chris Mair */ class PrivateFieldCouldBeFinalRule extends AbstractSharedAstVisitorRule { String name = 'PrivateFieldCouldBeFinal' int priority = 3 String ignoreFieldNames boolean ignoreJpaEntities = false Class astVisitorClass = PrivateFieldCouldBeFinalAstVisitor @Override protected List getViolations(AstVisitor visitor, SourceCode sourceCode) { def wildcardPattern = new WildcardPattern(ignoreFieldNames, false) visitor.initializedFields.each { FieldNode fieldNode -> boolean isIgnoredBecauseMatchesPattern = wildcardPattern.matches(fieldNode.name) boolean isIgnoredBecauseDefinedInJpaEntity = ignoreJpaEntities && isDefinedInJpaEntity(fieldNode) boolean isIgnored = isIgnoredBecauseMatchesPattern || isIgnoredBecauseDefinedInJpaEntity if (!isIgnored) { def className = fieldNode.owner.name def violationMessage = "Private field [${fieldNode.name}] in class $className is only set within the field initializer or a constructor, and so it can be made final." visitor.addViolation(fieldNode, violationMessage) } } return visitor.violations } boolean isDefinedInJpaEntity(FieldNode fieldNode) { return AstUtil.hasAnyAnnotation(fieldNode.owner, 'Entity', 'MappedSuperclass', 'javax.persistence.Entity', 'javax.persistence.MappedSuperclass') } } class PrivateFieldCouldBeFinalAstVisitor extends AbstractAstVisitor { private final Collection initializedFields = [] private final Collection allFields = [] private boolean withinConstructor private ClassNode currentClassNode @Override protected void visitClassEx(ClassNode node) { currentClassNode = node def allClassFields = node.fields.findAll { field -> isPrivate(field) && !field.isFinal() && !field.synthetic } allFields.addAll(allClassFields) def initializedClassFields = allClassFields.findAll { field -> field.initialExpression } initializedFields.addAll(initializedClassFields) super.visitClassEx(node) } @Override void visitConstructor(ConstructorNode node) { withinConstructor = true super.visitConstructor(node) withinConstructor = false } @Override void visitBinaryExpression(BinaryExpression expression) { def matchingFieldName = extractVariableOrFieldName(expression) boolean isAssignment = expression.operation.text.endsWith('=') && expression.operation.text != '==' if (isAssignment && matchingFieldName) { if (withinConstructor) { addInitializedField(matchingFieldName) } else { removeInitializedField(matchingFieldName) } } super.visitBinaryExpression(expression) } @Override void visitClosureExpression(ClosureExpression expression) { def originalWithinConstructor = withinConstructor // Closures within constructor cannot set final fields, so turn off constructor context for closures withinConstructor = false super.visitClosureExpression(expression) withinConstructor = originalWithinConstructor } @Override void visitPostfixExpression(PostfixExpression expression) { removeExpressionVariableName(expression) super.visitPostfixExpression(expression) } @Override void visitPrefixExpression(PrefixExpression expression) { removeExpressionVariableName(expression) super.visitPrefixExpression(expression) } //------------------------------------------------------------------------------------ // Helper Methods //------------------------------------------------------------------------------------ private void removeExpressionVariableName(expression) { if (expression.expression instanceof VariableExpression) { def varName = expression.expression.name removeInitializedField(varName) } } private String extractVariableOrFieldName(BinaryExpression expression) { def matchingFieldName if (expression.leftExpression instanceof VariableExpression) { matchingFieldName = expression.leftExpression.name } if (expression.leftExpression instanceof PropertyExpression) { def propertyExpression = expression.leftExpression boolean isMatchingPropertyExpression = propertyExpression.objectExpression instanceof VariableExpression && propertyExpression.objectExpression.name == 'this' && propertyExpression.property instanceof ConstantExpression if (isMatchingPropertyExpression) { matchingFieldName = propertyExpression.property.value } } return matchingFieldName } private void addInitializedField(varName) { def fieldNode = allFields.find { field -> isMatchingField(field, varName) } def alreadyInitializedFieldNode = initializedFields.find { field -> isMatchingField(field, varName) } if (fieldNode && !alreadyInitializedFieldNode) { initializedFields << fieldNode } } private void removeInitializedField(String varName) { if (varName in initializedFields.name) { initializedFields.removeAll { field -> isMatchingField(field, varName) } } } private Number isPrivate(FieldNode field) { return field.modifiers & FieldNode.ACC_PRIVATE } private boolean isMatchingField(FieldNode field, String name) { field.name == name && isOwnedByClassOrItsOuterClass(field, currentClassNode) } private boolean isOwnedByClassOrItsOuterClass(FieldNode field, ClassNode classNode) { if (classNode == null) { return false } field.owner == classNode || isOwnedByClassOrItsOuterClass(field, classNode.outerClass) } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootCodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/ReturnsNullInsteadOfEmptyCollectionRule.groovyCodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/ReturnsNullInsteadOfEmptyCollectionRule.groov0000644000175000017500000001103712311373552033330 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.NullReturnTracker import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * This rule detects when null is returned from a method that might return a * collection. Instead of null, return a zero length array. * * @author Hamlet D'Arcy */ class ReturnsNullInsteadOfEmptyCollectionRule extends AbstractAstVisitorRule { String name = 'ReturnsNullInsteadOfEmptyCollection' int priority = 2 Class astVisitorClass = ReturnsNullInsteadOfEmptyCollectionRuleAstVisitor } class ReturnsNullInsteadOfEmptyCollectionRuleAstVisitor extends AbstractAstVisitor { private static final String ERROR_MSG = 'Returning null from a method that might return a Collection or Map' void visitMethodEx(MethodNode node) { if (methodReturnsCollection(node)) { // does this method ever return null? node.code?.visit(new NullReturnTracker(parent: this, errorMessage: ERROR_MSG)) } super.visitMethodEx(node) } void handleClosure(ClosureExpression expression) { if (closureReturnsCollection(expression)) { // does this closure ever return null? expression.code?.visit(new NullReturnTracker(parent: this, errorMessage: ERROR_MSG)) } super.visitClosureExpression(expression) } private static boolean methodReturnsCollection(MethodNode node) { if (AstUtil.classNodeImplementsType(node.returnType, Iterable)) { return true } if (AstUtil.classNodeImplementsType(node.returnType, Map)) { return true } if (AstUtil.classNodeImplementsType(node.returnType, List)) { return true } if (AstUtil.classNodeImplementsType(node.returnType, Collection)) { return true } if (AstUtil.classNodeImplementsType(node.returnType, ArrayList)) { return true } if (AstUtil.classNodeImplementsType(node.returnType, Set)) { return true } if (AstUtil.classNodeImplementsType(node.returnType, HashSet)) { return true } boolean returnsCollection = false node.code?.visit(new CollectionReturnTracker(callbackFunction: { returnsCollection = true })) returnsCollection } private static boolean closureReturnsCollection(ClosureExpression node) { boolean returnsArray = false node.code?.visit(new CollectionReturnTracker(callbackFunction: { returnsArray = true })) returnsArray } } class CollectionReturnTracker extends AbstractAstVisitor { def callbackFunction void visitReturnStatement(ReturnStatement statement) { expressionReturnsList(statement.expression) super.visitReturnStatement(statement) } private expressionReturnsList(Expression expression) { def stack = [expression] as Stack // as alternative to recursion while (stack) { def expr = stack.pop() if (expr instanceof ListExpression || expr instanceof MapExpression) { callbackFunction() } if (expr instanceof ConstructorCallExpression || expr instanceof CastExpression) { [Map, Iterable, List, Collection, ArrayList, Set, HashSet].findAll { AstUtil.classNodeImplementsType(expr.type, it) }.each { callbackFunction() } } if (expr instanceof TernaryExpression) { stack.push(expr.trueExpression) stack.push(expr.falseExpression) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/SimpleDateFormatMissingLocaleRule.groovy0000644000175000017500000000443512311373552032252 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Be sure to specify a Locale when creating a new instance of SimpleDateFormat; the class is locale-sensitive. If you * instantiate SimpleDateFormat without a Locale parameter, it will format the date and time according to the default * Locale. Both the pattern and the Locale determine the format. For the same pattern, SimpleDateFormat may format a date * and time differently if the Locale varies. * * @author Hamlet D'Arcy */ class SimpleDateFormatMissingLocaleRule extends AbstractAstVisitorRule { String name = 'SimpleDateFormatMissingLocale' int priority = 2 Class astVisitorClass = SimpleDateFormatMissingLocaleAstVisitor } class SimpleDateFormatMissingLocaleAstVisitor extends AbstractAstVisitor { @Override void visitConstructorCallExpression(ConstructorCallExpression call) { if (isFirstVisit(call) && call.type.name in ['SimpleDateFormat', 'java.text.SimpleDateFormat']) { if (!hasMinimumParameterCount(call, 2)) { addViolation(call, 'Created an instance of SimpleDateFormat without specifying a Locale') } } super.visitConstructorCallExpression(call) } private static boolean hasMinimumParameterCount(ConstructorCallExpression call, int minimum) { def argumentsExpression = call.arguments if (AstUtil.respondsTo(argumentsExpression, 'getExpressions')) { return argumentsExpression.expressions.size() >= minimum } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/BuilderMethodWithSideEffectsRule.groovy0000644000175000017500000000313712006632016032060 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor /** * A builder method is defined as one that creates objects. As such, they should never be of void return type. If a method is named build, create, or make, then it should always return a value. * * @author Hamlet D'Arcy */ class BuilderMethodWithSideEffectsRule extends AbstractAstVisitorRule { String name = 'BuilderMethodWithSideEffects' int priority = 2 Class astVisitorClass = BuilderMethodWithSideEffectsAstVisitor String methodNameRegex = '(create.*|make.*|build.*)' } class BuilderMethodWithSideEffectsAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (node.name ==~ rule.methodNameRegex && node.isVoidMethod()) { addViolation(node, "The method '$node.name' is named like a builder method but has a void return type") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/BooleanMethodReturnsNullRule.groovy0000644000175000017500000001067212467644410031344 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codehaus.groovy.ast.stmt.Statement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.NullReturnTracker import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * Method with Boolean return type returns explicit null. A method that returns either Boolean.TRUE, Boolean.FALSE or * null is an accident waiting to happen. This method can be invoked as though it returned a value of type boolean, * and the compiler will insert automatic unboxing of the Boolean value. If a null value is returned, this will * result in a NullPointerException. * * @author Hamlet D'Arcy */ class BooleanMethodReturnsNullRule extends AbstractAstVisitorRule { String name = 'BooleanMethodReturnsNull' int priority = 2 Class astVisitorClass = BooleanMethodReturnsNullAstVisitor } class BooleanMethodReturnsNullAstVisitor extends AbstractAstVisitor { private static final String ERROR_MSG = 'Returning null from a method that might return a Boolean' void visitMethodEx(MethodNode node) { if (methodReturnsBoolean(node)) { // does this method ever return null? node.code?.visit(new NullReturnTracker(parent: this, errorMessage: ERROR_MSG)) } super.visitMethodEx(node) } void handleClosure(ClosureExpression expression) { if (closureReturnsBoolean(expression)) { // does this closure ever return null? expression.code?.visit(new NullReturnTracker(parent: this, errorMessage: ERROR_MSG)) } super.visitClosureExpression(expression) } private static boolean methodReturnsBoolean(MethodNode node) { if (AstUtil.classNodeImplementsType(node.returnType, Boolean) || AstUtil.classNodeImplementsType(node.returnType, Boolean.TYPE)) { return true } return codeReturnsBoolean(node.code) } private static boolean closureReturnsBoolean(ClosureExpression node) { return codeReturnsBoolean(node.code) } private static boolean codeReturnsBoolean(Statement statement) { boolean returnsBoolean = false if (statement) { def booleanTracker = new BooleanReturnTracker() statement.visit(booleanTracker) returnsBoolean = booleanTracker.returnsBoolean && !booleanTracker.returnsNonBoolean } returnsBoolean } } class BooleanReturnTracker extends AbstractAstVisitor { boolean returnsNonBoolean = false boolean returnsBoolean = false void visitReturnStatement(ReturnStatement statement) { checkReturnValues(statement.expression) super.visitReturnStatement(statement) } private checkReturnValues(Expression expression) { def stack = [expression] as Stack while (stack) { def expr = stack.pop() if (AstUtil.isBoolean(expr)) { returnsBoolean = true } else if (expr instanceof BooleanExpression) { returnsBoolean = true } else if (expr instanceof CastExpression && AstUtil.classNodeImplementsType(expr.type, Boolean)) { returnsBoolean = true } else if (expr instanceof TernaryExpression) { stack.push(expr.trueExpression) stack.push(expr.falseExpression) } else if (!isNull(expr)) { returnsNonBoolean = true } } } private boolean isNull(Expression expression) { return expression == ConstantExpression.NULL || (expression instanceof ConstantExpression && expression.value == null) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/CloneableWithoutCloneRule.groovy0000644000175000017500000000357112311370173030625 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.Parameter import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * A class that implements Cloneable should define a clone() method. * * @author Hamlet D'Arcy & Rene Groeschke */ class CloneableWithoutCloneRule extends AbstractAstVisitorRule { String name = 'CloneableWithoutClone' int priority = 2 Class astVisitorClass = CloneableWithoutCloneAstVisitor } class CloneableWithoutCloneAstVisitor extends AbstractAstVisitor { @Override void visitClassEx(ClassNode node) { // is this class a Cloneable? def cloneableClassNode = ClassHelper.make(Cloneable) def isCloneable = node.interfaces.find { it == cloneableClassNode || it.name == 'Cloneable' } if (isCloneable) { if (!hasCloneMethod(node)) { addViolation(node, "The class $node.name implements Cloneable but does not define a proper clone() method") } } super.visitClassEx(node) } private boolean hasCloneMethod(ClassNode classNode) { classNode.getDeclaredMethod('clone', [] as Parameter[]) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/StatelessSingletonRule.groovy0000644000175000017500000000517212311371417030227 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * There is no benefit in creating a stateless Singleton. Make a new instance with the new keyword instead. * * @author 'Victor Savkin' */ class StatelessSingletonRule extends AbstractAstVisitorRule { String name = 'StatelessSingleton' int priority = 2 Class astVisitorClass = StatelessSingletonAstVisitor String instanceRegex = 'instance|_instance' } class StatelessSingletonAstVisitor extends AbstractAstVisitor { @Override protected void visitClassComplete(ClassNode node) { if (isSingleton(node) && !doesExtendClass(node) && !hasState(node)) { addViolation node, 'There is no point in creating a stateless Singleton. ' + "Make a new instance of '${node.nameWithoutPackage}' with the new keyword instead." } super.visitClassComplete node } private isSingleton(classNode) { hasSingletonAnnotation(classNode) || hasOneStaticFieldOfItself(classNode) || hasOneStaticFieldNamedInstance(classNode) } private static doesExtendClass(classNode) { classNode.superClass.name != Object.name } private hasState(classNode) { classNode.fields.any { it.type.name != classNode.name && !(it.name ==~ rule.instanceRegex) } } private static hasOneStaticFieldOfItself(classNode) { classNode.fields.findAll { it.static && it.type.name == classNode.name }.size() == 1 } private hasOneStaticFieldNamedInstance(classNode) { classNode.fields.findAll { it.static && it.type.name == Object.name && it.name ==~ rule.instanceRegex }.size() == 1 } private static hasSingletonAnnotation(classNode) { classNode?.annotations?.any { it.classNode.name == Singleton.name } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/ReturnsNullInsteadOfEmptyArrayRule.groovy0000644000175000017500000000705312141453056032506 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.CastExpression import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.TernaryExpression import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.NullReturnTracker /** * This rule detects when null is returned from a method that might return an * array. Instead of null, return a zero length array. * * @author Hamlet D'Arcy */ class ReturnsNullInsteadOfEmptyArrayRule extends AbstractAstVisitorRule { String name = 'ReturnsNullInsteadOfEmptyArray' int priority = 2 Class astVisitorClass = ReturnsNullInsteadOfEmptyArrayAstVisitor } class ReturnsNullInsteadOfEmptyArrayAstVisitor extends AbstractAstVisitor { private static final String ERROR_MSG = 'Returning null from a method that might return an Array' void visitMethodEx(MethodNode node) { if (methodReturnsArray(node)) { // does this method ever return null? node.code?.visit(new NullReturnTracker(parent: this, errorMessage: ERROR_MSG)) } super.visitMethodEx(node) } void handleClosure(ClosureExpression expression) { if (closureReturnsArray(expression)) { // does this closure ever return null? expression.code?.visit(new NullReturnTracker(parent: this, errorMessage: ERROR_MSG)) } super.visitClosureExpression(expression) } private static boolean methodReturnsArray(MethodNode node) { if (node.returnType.isArray()) { return true } boolean returnsArray = false node.code?.visit(new ArrayReturnTracker(callbackFunction: { returnsArray = true })) returnsArray } private static boolean closureReturnsArray(ClosureExpression node) { boolean returnsArray = false node.code?.visit(new ArrayReturnTracker(callbackFunction: { returnsArray = true })) returnsArray } } class ArrayReturnTracker extends AbstractAstVisitor { def callbackFunction void visitReturnStatement(ReturnStatement statement) { callBackForArrayReturns(statement.expression) super.visitReturnStatement(statement) } private callBackForArrayReturns(Expression expression) { def stack = [expression] as Stack while (stack) { def expr = stack.pop() if (expr instanceof CastExpression) { if (expr.type.isArray()) { callbackFunction() } } else if (expr instanceof TernaryExpression) { stack.push(expr.trueExpression) stack.push(expr.falseExpression) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/ImplementationAsTypeRule.groovy0000644000175000017500000001313212006632016030477 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Checks for use of the following concrete classes when specifying the type of a method * parameter, closure parameter, constructor parameter, method return type or field * type (the associated interfaces should be used to specify the type instead): *

    *
  • java.util.ArrayList
  • *
  • java.util.GregorianCalendar
  • *
  • java.util.HashMap
  • *
  • java.util.HashSet
  • *
  • java.util.Hashtable
  • *
  • java.util.LinkedHashMap
  • *
  • java.util.LinkedHashSet
  • *
  • java.util.LinkedList
  • *
  • java.util.TreeMap
  • *
  • java.util.TreeSet
  • *
  • java.util.Vector
  • *
  • java.util.concurrent.ArrayBlockingQueue
  • *
  • java.util.concurrent.ConcurrentHashMap
  • *
  • java.util.concurrent.ConcurrentLinkedQueue
  • *
  • java.util.concurrent.CopyOnWriteArrayList
  • *
  • java.util.concurrent.CopyOnWriteArraySet
  • *
  • java.util.concurrent.DelayQueue
  • *
  • java.util.concurrent.LinkedBlockingQueue
  • *
  • java.util.concurrent.PriorityBlockingQueue
  • *
  • java.util.concurrent.PriorityQueue
  • *
  • java.util.concurrent.SynchronousQueue
  • *
* @author Chris Mair * @author Hamlet D'Arcy */ class ImplementationAsTypeRule extends AbstractAstVisitorRule { String name = 'ImplementationAsType' int priority = 2 Class astVisitorClass = ImplementationAsTypeAstVisitor } class ImplementationAsTypeAstVisitor extends AbstractAstVisitor { private static final TYPES = [ 'ArrayList', 'java.util.ArrayList', 'GregorianCalendar', 'java.util.GregorianCalendar', 'HashMap', 'java.util.HashMap', 'HashSet', 'java.util.HashSet', 'Hashtable', 'java.util.Hashtable', 'LinkedHashMap', 'java.util.LinkedHashMap', 'LinkedHashSet', 'java.util.LinkedHashSet', 'LinkedList', 'java.util.LinkedList', 'TreeMap', 'java.util.TreeMap', 'TreeSet', 'java.util.TreeSet', 'Vector', 'java.util.Vector', 'CopyOnWriteArrayList', 'java.util.concurrent.CopyOnWriteArrayList', 'CopyOnWriteArraySet', 'java.util.concurrent.CopyOnWriteArraySet', 'ConcurrentHashMap', 'java.util.concurrent.ConcurrentHashMap', 'ArrayBlockingQueue', 'java.util.concurrent.ArrayBlockingQueue', 'ConcurrentLinkedQueue', 'java.util.concurrent.ConcurrentLinkedQueue', 'DelayQueue', 'java.util.concurrent.DelayQueue', 'LinkedBlockingQueue', 'java.util.concurrent.LinkedBlockingQueue', 'PriorityBlockingQueue', 'java.util.concurrent.PriorityBlockingQueue', 'PriorityQueue', 'java.util.concurrent.PriorityQueue', 'SynchronousQueue', 'java.util.concurrent.SynchronousQueue', ] void visitMethodEx(MethodNode methodNode) { processParameters(methodNode.parameters) processType(methodNode.returnType, "The return type $methodNode.returnType.name should be replaced with an interface or more general parent class") super.visitMethodEx(methodNode) } @Override void visitConstructor(ConstructorNode constructorNode) { processParameters(constructorNode.parameters) super.visitConstructor(constructorNode) } void visitClosureExpression(ClosureExpression closureExpression) { if (isFirstVisit(closureExpression)) { processParameters(closureExpression.parameters) } super.visitClosureExpression(closureExpression) } void visitDeclarationExpression(DeclarationExpression declarationExpression) { if (isFirstVisit(declarationExpression)) { def varExpressions = AstUtil.getVariableExpressions(declarationExpression) varExpressions.each { varExpression -> def msg = varExpressions.size() > 1 ? "Variable type: [$varExpression.type]" : null processType(varExpression.type, msg) } } super.visitDeclarationExpression(declarationExpression) } void visitField(FieldNode fieldNode) { processType(fieldNode.type, "The type $fieldNode.type.name should be replaced with an interface or more general parent class") super.visitField(fieldNode) } private void processParameters(parameters) { parameters.each { parameter -> processType(parameter.type, "The type $parameter.type.name should be replaced with an interface or more general parent class") } } private void processType(typeNode, String message) { String typeName = typeNode.name if (typeNode.lineNumber >= 0 && (TYPES.contains(typeName))) { addViolation(typeNode, message) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/ToStringReturnsNullRule.groovy0000644000175000017500000000462612407311525030367 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.ClosureExpression import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.NullReturnTracker import org.codenarc.util.AstUtil /** * Checks for toString() methods that return null. * * @author Chris Mair */ class ToStringReturnsNullRule extends AbstractAstVisitorRule { String name = 'ToStringReturnsNull' int priority = 2 Class astVisitorClass = ToStringReturnsNullAstVisitor } class ToStringReturnsNullAstVisitor extends AbstractAstVisitor { private static final String ERROR_MESSAGE = 'The toString() method within class %s returns null' @Override protected void visitMethodEx(MethodNode node) { if (AstUtil.isMethodNode(node, 'toString', 0)) { def errorMessage = String.format(ERROR_MESSAGE, currentClassName) // This will find all of the explicit return statements node.code?.visit(new NullReturnTracker(parent:this, errorMessage:errorMessage)) checkForImplicitNullReturns(node, errorMessage) } super.visitMethodEx(node) } void handleClosure(ClosureExpression expression) { super.visitClosureExpression(expression) } private void checkForImplicitNullReturns(MethodNode node, String errorMessage) { def statements = node.code.statements if (statements.empty) { addViolation(node, errorMessage) return } def lastStatement = statements[-1] if (lastStatement instanceof ExpressionStatement && AstUtil.isNull(lastStatement.expression)) { addViolation(lastStatement, errorMessage) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/design/CloneWithoutCloneableRule.groovy0000644000175000017500000000364012142570620030623 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.design import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.Parameter import org.codehaus.groovy.control.Phases import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor import org.codenarc.util.AstUtil /** * The method clone() should only be declared if the class implements the Cloneable interface. * * @author ArturGajowy */ class CloneWithoutCloneableRule extends AbstractAstVisitorRule { String name = 'CloneWithoutCloneable' int priority = 2 Class astVisitorClass = CloneWithoutCloneableAstVisitor int compilerPhase = Phases.SEMANTIC_ANALYSIS } class CloneWithoutCloneableAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { def cloneMethod = cloneMethod(node) if (cloneMethod && !isCloneable(node)) { addViolation(cloneMethod, "Class $node.name declares a clone() method, but does not implement java.lang.Cloneable interface") } } private MethodNode cloneMethod(ClassNode classNode) { classNode.getDeclaredMethod('clone', [] as Parameter[]) } private boolean isCloneable(ClassNode classNode) { AstUtil.classNodeImplementsType(classNode, Cloneable) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/0000755000175000017500000000000012623571301022271 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/ObjectOverrideMisspelledMethodNameRule.groovy0000644000175000017500000000502112006632016033254 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor /** * Rule that checks that the names of the most commonly overridden methods: equals, * hashCode and toString, are correct. * * @author @Hackergarten * @author Hamlet D'Arcy */ class ObjectOverrideMisspelledMethodNameRule extends AbstractAstVisitorRule { String name = 'ObjectOverrideMisspelledMethodName' int priority = 2 Class astVisitorClass = ObjectOverrideMisspelledMethodNameAstVisitor } class ObjectOverrideMisspelledMethodNameAstVisitor extends AbstractMethodVisitor { @Override @SuppressWarnings('DuplicateLiteral') void visitMethod(MethodNode node) { checkForExactMethodName(node, 'equal', ['Object'], 'equals') checkForMethodNameWithIncorrectCase(node, 'equals', ['Object']) checkForMethodNameWithIncorrectCase(node, 'hashCode', []) checkForMethodNameWithIncorrectCase(node, 'toString', []) } private void checkForMethodNameWithIncorrectCase(MethodNode node, String targetMethodName, List parameterTypes) { def actualMethodName = node?.name if (actualMethodName?.toLowerCase() == targetMethodName.toLowerCase() && actualMethodName != targetMethodName && node?.parameters*.type.name == parameterTypes) { addViolation node, "Trying to override the $targetMethodName method using the name [$actualMethodName]" } } private void checkForExactMethodName(MethodNode node, String targetMethodName, List parameterTypes, String overridingMethodName) { def actualMethodName = node?.name if (actualMethodName == targetMethodName && node?.parameters*.type.name == parameterTypes) { addViolation node, "Trying to override the $overridingMethodName method using the name [$actualMethodName]" } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/MethodNameRule.groovy0000644000175000017500000000435212311373552026417 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.WildcardPattern /** * Rule that verifies that the name of each method matches a regular expression. By default it checks that the * method name starts with a lowercase letter. Implicit method names are ignored (i.e., 'main' and 'run' * methods automatically created for Groovy scripts). *

* The regex property specifies the regular expression to check the method name against. It is * required and cannot be null or empty. It defaults to '[a-z]\w*'. *

* The ignoreMethodNames property optionally specifies one or more * (comma-separated) method names that should be ignored (i.e., that should not cause a * rule violation). The name(s) may optionally include wildcard characters ('*' or '?'). * * @author Chris Mair * @author Hamlet D'Arcy */ class MethodNameRule extends AbstractAstVisitorRule { String name = 'MethodName' int priority = 2 Class astVisitorClass = MethodNameAstVisitor String regex = /[a-z]\w*/ String ignoreMethodNames } class MethodNameAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode methodNode) { assert rule.regex if (!new WildcardPattern(rule.ignoreMethodNames, false).matches(methodNode.name)) { if (!(methodNode.name ==~ rule.regex)) { addViolation(methodNode, "The method name $methodNode.name in class $currentClassName does not match $rule.regex") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/FactoryMethodNameRule.groovy0000644000175000017500000000365412006632014027743 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * A factory method is a method that creates objects, and they are typically named either buildFoo(), makeFoo(), or * createFoo(). This rule enforces that only one naming convention is used. It defaults to makeFoo(), but that can * be changed using the property 'regex'. * * @author Hamlet D'Arcy */ class FactoryMethodNameRule extends AbstractAstVisitorRule { String name = 'FactoryMethodName' int priority = 2 Class astVisitorClass = FactoryMethodNameAstVisitor String regex = /(build.*|create.*)/ } class FactoryMethodNameAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (!AstUtil.getAnnotation(node, 'Override') && node.name ==~ rule.regex) { if (!(currentClassName ==~ /.*Builder/)) { addViolation(node, "The method '$node.name' matches the regular expression /$rule.regex/ and does not appear in a class matching /*.Builder/") } else if (!(node.name ==~ /build.*/)) { addViolation(node, "The method '$node.name' matches the regular expression /$rule.regex/") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/InterfaceNameRule.groovy0000644000175000017500000000303312311373552027072 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that verifies that the name of an interface matches a regular expression specified in * the regex property. If that property is null or empty, then this rule is not applied * (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. * * @see ClassNameRule * * @author Chris Mair */ class InterfaceNameRule extends AbstractAstVisitorRule { String name = 'InterfaceName' int priority = 2 Class astVisitorClass = InterfaceNameAstVisitor String regex boolean isReady() { regex } } class InterfaceNameAstVisitor extends AbstractTypeNameAstVisitor { protected boolean shouldVisit(ClassNode classNode) { classNode.modifiers & classNode.ACC_INTERFACE } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/AbstractTypeNameAstVisitor.groovy0000644000175000017500000000377212311373552031011 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.InnerClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.util.GroovyVersion /** * Abstract superclass for AstVisitor classes dealing with class/type names, e.g. classes, * interfaces and abstract classes. * * @author Chris Mair * @author Hamlet D'Arcy */ abstract class AbstractTypeNameAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode classNode) { assert rule.regex if (GroovyVersion.isGroovy1_8_OrGreater() && classNode instanceof InnerClassNode && classNode.anonymous) { // do nothing for anonymous inner classes super.visitClassEx(classNode) } else if (GroovyVersion.isGroovy1_8_OrGreater() && classNode.isScript()) { // do nothing for script classes super.visitClassEx(classNode) } else { if (shouldVisit(classNode) && !(classNode.getNameWithoutPackage() ==~ rule.regex)) { addViolation(classNode, "The name ${classNode.getNameWithoutPackage()} failed to match the pattern ${rule.regex.toString()}") } super.visitClassEx(classNode) } } /** * @return true only if this visitor should be applied to (visit) the specified ClassNode. */ protected abstract boolean shouldVisit(ClassNode classNode) } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/ClassNameSameAsFilenameRule.groovy0000644000175000017500000000430612311373552030776 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Reports files containing only one top level class / enum / interface which is named differently than the file. * * @author Artur Gajowy * @author Chris Mair */ class ClassNameSameAsFilenameRule extends AbstractRule { String name = 'ClassNameSameAsFilename' int priority = 2 @Override void applyTo(SourceCode sourceCode, List violations) { if (!sourceCode.name) { return } List classes = sourceCode?.ast?.classes List topLevelClasses = classes?.findAll { !it.outerClass } ClassNode onlyTopLevelClass = topLevelClasses?.size() == 1 ? topLevelClasses.first() : null if (onlyTopLevelClass && onlyTopLevelClass.superClass != ClassHelper.make(Script)) { String className = onlyTopLevelClass.nameWithoutPackage if (className != sourceCode.name - '.groovy') { violations << createViolation(sourceCode, onlyTopLevelClass, "${classNodeType(onlyTopLevelClass)} `$className` is the only class in `${sourceCode.name}`. " + 'In such a case the file and the class should have the same name.') } } } String classNodeType(ClassNode classNode) { return classNode.isInterface() ? 'Interface' : classNode.isEnum() ? 'Enum' : 'Class' } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/PackageNameRule.groovy0000644000175000017500000000437112407624465026543 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.Violation /** * Rule that verifies that the package name of a class matches a regular expression. By default it checks that the * package name consists of only lowercase letters and numbers, separated by periods. *

* The regex property specifies the regular expression to check the package name against. It is * required and cannot be null or empty. It defaults to '[a-z]+[a-z0-9]*(\.[a-z0-9]+)*'. *

* The packageNameRequired property indicates whether a package name declaration is required for * all classes. It defaults to false. * * @author Chris Mair * @author Hamlet D'Arcy */ class PackageNameRule extends AbstractAstVisitorRule { String name = 'PackageName' int priority = 2 Class astVisitorClass = PackageNameAstVisitor String regex = /[a-z]+[a-z0-9]*(\.[a-z0-9]+)*/ boolean packageNameRequired = false } class PackageNameAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode classNode) { assert rule.regex if (classNode.packageName != null && !(classNode.packageName ==~ rule.regex)) { violations.add(new Violation(rule:rule, message:"package=$classNode.packageName")) } if (rule.packageNameRequired && classNode.packageName == null) { addViolation(classNode, 'Required package declaration is missing for class') } super.visitClassEx(classNode) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/PackageNameMatchesFilePathRule.groovy0000644000175000017500000000552712410134515031453 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.PackageNode import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode import org.codenarc.util.PathUtil import java.util.regex.Pattern /** * A package source file's path should match the package declaration. *

* To find the package-relevant sub-path in the file path the groupId needs to be configured. * It is expected to appear in every package declaration. * * @author Simon Tost */ class PackageNameMatchesFilePathRule extends AbstractRule { String groupId String name = 'PackageNameMatchesFilePath' int priority = 2 @Override boolean isReady() { return groupId } @Override void applyTo(SourceCode sourceCode, List violations) { PackageNode packageNode = sourceCode.ast?.package if (!packageNode || !sourceCode.path) { return } def normalizedPath = PathUtil.normalizePath(sourceCode.path - sourceCode.name) def dotSeparatedFolders = normalizedPath.replace('/', '.') dotSeparatedFolders = removeTrailingPeriod(dotSeparatedFolders) def packageName = removeTrailingPeriod(packageNode.name) if (!dotSeparatedFolders.find(groupId) || !packageName.find(groupId)) { violations << createViolation(sourceCode, packageNode, "Could not find groupId '$groupId' in package ($packageName) or file's path ($sourceCode.path)") } else { def groupPattern = Pattern.quote(groupId) def subfolders = dotSeparatedFolders.split(groupPattern, 2)[1] def subpackages = packageName.split(groupPattern, 2)[1] if (subfolders != subpackages) { violations << createViolation(sourceCode, packageNode, mismatchMessage(subfolders)) } } } private String removeTrailingPeriod(String str) { return (str.endsWith('.')) ? str[0..-2] : str } private mismatchMessage(String subfolders) { def dotSeparatedPath = groupId + subfolders def subpath = dotSeparatedPath.replace('.', File.separator) "The package source file's path ($subpath) should match the package declaration" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/FieldNameRule.groovy0000644000175000017500000001257512403117552026226 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.PropertyNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.WildcardPattern import java.lang.reflect.Modifier /** * Rule that verifies that the name of each field matches a regular expression. By default it checks that * non-final field names start with a lowercase letter and contains only letters or numbers. * By default, final field names start with an uppercase letter and contain only uppercase * letters, numbers and underscores. *

* NOTE: This rule checks only regular fields of a class, not properties. In Groovy, * properties are fields declared with no access modifier (public, protected, private). Thus, * this rule only checks fields that specify an access modifier. For naming of regular * properties, see PropertyNameRule. *

* The regex property specifies the default regular expression to validate a field name. * It is required and cannot be null or empty. It defaults to '[a-z][a-zA-Z0-9]*'. *

* The finalRegex property specifies the regular expression to validate final * field names. It is optional and defaults to null, so that final fields that are not * static will be validated using regex. *

* The staticRegex property specifies the regular expression to validate static * field names. It is optional and defaults to null, so that static fields that are * non-final will be validated using regex. *

* The staticFinalRegex property specifies the regular expression to validate static final * field names. It is optional, but defaults to '[A-Z][A-Z0-9_]*'. *

* The privateStaticFinalRegex property specifies the regular expression to validate private static final * field names. It is optional, but defaults to '[A-Z][A-Z0-9_]*'. *

* The order of precedence for the regular expression properties is: privateStaticFinalRegex, staticFinalRegex, * finalRegex, staticRegex and finally regex. In other words, the first * regex in that list matching the modifiers for the field is the one that is applied for the field name validation. *

* The ignoreFieldNames property optionally specifies one or more * (comma-separated) field names that should be ignored (i.e., that should not cause a * rule violation). The name(s) may optionally include wildcard characters ('*' or '?'). * * @author Chris Mair * @author Hamlet D'Arcy */ class FieldNameRule extends AbstractAstVisitorRule { String name = 'FieldName' int priority = 2 String regex = DEFAULT_FIELD_NAME String staticRegex String finalRegex String staticFinalRegex = DEFAULT_CONST_NAME String privateStaticFinalRegex String ignoreFieldNames = 'serialVersionUID' Class astVisitorClass = FieldNameAstVisitor void validate() { assert regex } } class FieldNameAstVisitor extends AbstractAstVisitor { private final Set propertyNames = [] void visitField(FieldNode fieldNode) { if (!isProperty(fieldNode) && !isIgnoredPropertyName(fieldNode)) { def mod = fieldNode.modifiers def re = rule.regex if (Modifier.isStatic(mod)) { re = rule.staticRegex ?: re } if (Modifier.isFinal(mod)) { re = rule.finalRegex ?: re } if ((Modifier.isFinal(mod)) && (Modifier.isStatic(mod))) { re = rule.staticFinalRegex ?: re } if ((Modifier.isFinal(mod)) && Modifier.isStatic(mod) && Modifier.isPrivate(mod)) { re = rule.privateStaticFinalRegex ?: re } if (!(fieldNode.name ==~ re)) { addViolation(fieldNode, "The fieldname $fieldNode.name in class ${fieldNode.owner?.name} does not match ${re.toString()}") } } super.visitField(fieldNode) } void visitProperty(PropertyNode node) { propertyNames << node.name super.visitProperty(node) } private boolean isIgnoredPropertyName(FieldNode node) { new WildcardPattern(rule.ignoreFieldNames, false).matches(node.name) } private boolean isProperty(FieldNode node) { // This assumes that the property node is visited before the (regular) field node propertyNames.contains(node.name) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/VariableNameRule.groovy0000644000175000017500000000641212311373552026723 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codenarc.util.WildcardPattern /** * Rule that verifies that the name of each variable matches a regular expression. By default it checks that * non-final variable names start with a lowercase letter and contains only letters or numbers. * By default, final variable names start with an uppercase letter and contain only uppercase * letters, numbers and underscores. *

* The regex property specifies the default regular expression to validate a variable name. * It is required and cannot be null or empty. It defaults to '[a-z][a-zA-Z0-9]*'. *

* The finalRegex property specifies the regular expression to validate final * variable names. It is optional but defaults to '[A-Z][A-Z0-9_]*'. If not set, then regex is * used to validate final variables. *

* The ignoreVariableNames property optionally specifies one or more * (comma-separated) variable names that should be ignored (i.e., that should not cause a * rule violation). The name(s) may optionally include wildcard characters ('*' or '?'). * * @author Chris Mair */ class VariableNameRule extends AbstractAstVisitorRule { String name = 'VariableName' int priority = 2 String regex = DEFAULT_VAR_NAME String finalRegex = DEFAULT_CONST_NAME String ignoreVariableNames Class astVisitorClass = VariableNameAstVisitor } class VariableNameAstVisitor extends AbstractAstVisitor { void visitDeclarationExpression(DeclarationExpression declarationExpression) { assert rule.regex if (isFirstVisit(declarationExpression)) { def varExpressions = AstUtil.getVariableExpressions(declarationExpression) def re = rule.finalRegex && AstUtil.isFinalVariable(declarationExpression, sourceCode) ? rule.finalRegex : rule.regex varExpressions.each { varExpression -> if (!new WildcardPattern(rule.ignoreVariableNames, false).matches(varExpression.name) && !(varExpression.name ==~ re)) { def msg = "Variable named $varExpression.name in class $currentClassName does not match the pattern ${re.toString()}" addViolation(declarationExpression, msg) } } } super.visitDeclarationExpression(declarationExpression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/PropertyNameRule.groovy0000644000175000017500000001057212311373552027024 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.PropertyNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.WildcardPattern import java.lang.reflect.Modifier /** * Rule that verifies that the name of each property matches a regular expression. By default it checks that * property names (other than static final) start with a lowercase letter and contains only letters * or numbers. By default, static final property names start with an uppercase letter and contain * only uppercase letters, numbers and underscores. *

* NOTE: This rule checks only properties of a class, not regular fields. In Groovy, * properties are fields declared with no access modifier (public, protected, private). * For naming of regular fields, see FieldNameRule. *

* The regex property specifies the default regular expression to validate a property name. * It is required and cannot be null or empty. It defaults to '[a-z][a-zA-Z0-9]*'. *

* The finalRegex property specifies the regular expression to validate final * property names. It is optional and defaults to null, so that final properties that are * non-static will be validated using regex. *

* The staticRegex property specifies the regular expression to validate static * property names. It is optional and defaults to null, so that static properties that are * non-final will be validated using regex. *

* The staticFinalRegex property specifies the regular expression to validate static final * property names. It is optional but defaults to '[A-Z][A-Z0-9_]*'. *

* The order of precedence for the regular expression properties is: staticFinalRegex, * finalRegex, staticRegex and finally regex. In other words, the first * regex in that list matching the modifiers for the property is the one that is applied for the property * name validation. *

* The ignorePropertyNames property optionally specifies one or more * (comma-separated) property names that should be ignored (i.e., that should not cause a * rule violation). The name(s) may optionally include wildcard characters ('*' or '?'). * * @author Chris Mair * @author Hamlet D'Arcy */ class PropertyNameRule extends AbstractAstVisitorRule { String name = 'PropertyName' int priority = 2 String regex = DEFAULT_FIELD_NAME String staticRegex String finalRegex String staticFinalRegex = DEFAULT_CONST_NAME String ignorePropertyNames Class astVisitorClass = PropertyNameAstVisitor void validate() { assert regex } } class PropertyNameAstVisitor extends AbstractAstVisitor { void visitProperty(PropertyNode node) { if (!new WildcardPattern(rule.ignorePropertyNames, false).matches(node.name)) { def re = rule.regex def mod = node.modifiers if (Modifier.isStatic(mod)) { re = rule.staticRegex ?: re } if (Modifier.isFinal(mod)) { re = rule.finalRegex ?: re } if ((Modifier.isFinal(mod)) && (Modifier.isStatic(mod))) { re = rule.staticFinalRegex ?: re } if (!(node.name ==~ re)) { addViolation(node, "The property name $node.name in class ${node.field?.owner?.name} does not match the pattern $re") } } super.visitProperty(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/ConfusingMethodNameRule.groovy0000644000175000017500000000734712277665572030323 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.Parameter import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * This rule traps the condition where two methods or closures differ only by their capitalization. * * @author Hamlet D'Arcy * @author Hubert 'Mr. Haki' Klein Ikkink */ class ConfusingMethodNameRule extends AbstractAstVisitorRule { String name = 'ConfusingMethodName' int priority = 2 Class astVisitorClass = ConfusingMethodNameAstVisitor } class ConfusingMethodNameAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode node) { node.visitContents(new ScopedConfusingMethodNameAstVisitor(this)) } } class ScopedConfusingMethodNameAstVisitor extends AbstractAstVisitor { def lowercaseMethodNames = [] as Set def lowercaseMethodNamesWithParameterTypes = [] as Set def lowercaseClosureNames = [] as Set def lowercaseFieldNames = [:] def parent ScopedConfusingMethodNameAstVisitor(AbstractAstVisitor parent) { this.parent = parent this.rule = parent.rule } void visitMethodEx(MethodNode node) { String methodName = node.getName().toLowerCase() String parameterInfo = getParameterDefinitionAsString(node) String methodNameWithParameters = node.name.toLowerCase() + parameterInfo if (lowercaseClosureNames.contains(methodName)) { parent.addViolation(node, 'Found very confusing method name. ' + 'Conflicts with a similar closure name. ' + "Found method : $node.name $parameterInfo") } else if (lowercaseMethodNamesWithParameterTypes.contains(methodNameWithParameters)) { parent.addViolation(node, "Found very confusing method name: $node.name $parameterInfo") } else if (lowercaseFieldNames.any { it.key == methodName }) { parent.addViolation(node, "The method name $node.name is similar to the field name ${lowercaseFieldNames[methodName]}") } lowercaseMethodNames.add(methodName) lowercaseMethodNamesWithParameterTypes.add(methodNameWithParameters) super.visitMethodEx node } void visitField(FieldNode node) { if (AstUtil.isClosureDeclaration(node)) { String methodName = node.name.toLowerCase() if (lowercaseClosureNames.contains(methodName)) { parent.addViolation(node, "Found very confusing closure name: $node.name") } lowercaseClosureNames.add(methodName) } else { String fieldName = node.name.toLowerCase() lowercaseFieldNames[fieldName] = node.name } super.visitField(node) } void visitClassEx(ClassNode node) { parent.visitClassEx(node) } private static String getParameterDefinitionAsString(MethodNode node) { Parameter[] parameters = node?.getParameters() '(' + parameters?.collect { it?.type?.toString() }?.join(', ') + ')' } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/AbstractClassNameRule.groovy0000644000175000017500000000335212311373552027727 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that verifies that the name of an abstract class matches a regular expression specified in * the regex property. If that property is null or empty, then this rule is not applied * (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. * This rule ignores interfaces. * * @see ClassNameRule * @see InterfaceNameRule * * @author Chris Mair */ class AbstractClassNameRule extends AbstractAstVisitorRule { String name = 'AbstractClassName' int priority = 2 Class astVisitorClass = AbstractClassNameAstVisitor String regex boolean isReady() { regex } } class AbstractClassNameAstVisitor extends AbstractTypeNameAstVisitor { protected boolean shouldVisit(ClassNode classNode) { def isAbstract = classNode.modifiers & classNode.ACC_ABSTRACT def isInterface = classNode.modifiers & classNode.ACC_INTERFACE isAbstract && !isInterface } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/ClassNameRule.groovy0000644000175000017500000000345512311373552026247 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that verifies that the name of a class matches a regular expression. By default it checks that the * class name starts with an uppercase letter and is followed by zero or more word characters * (letters, numbers or underscores). Implicit classes (i.e. Groovy scripts) are ignored. This rule applies * to all classes, including abstract classes and interfaces. *

* The regex property specifies the regular expression to check the class name against. It is * required and cannot be null or empty. It defaults to '[A-Z]\w*'. * * @see AbstractClassNameRule * @see InterfaceNameRule * * @author Chris Mair */ class ClassNameRule extends AbstractAstVisitorRule { String name = 'ClassName' int priority = 2 String regex = /([A-Z]\w*\$?)*/ Class astVisitorClass = ClassNameAstVisitor void validate() { assert regex } } class ClassNameAstVisitor extends AbstractTypeNameAstVisitor { @Override protected boolean shouldVisit(ClassNode classNode) { true } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/naming/ParameterNameRule.groovy0000644000175000017500000000634712311373552027125 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codehaus.groovy.ast.ConstructorNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.ClosureExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.WildcardPattern /** * Rule that verifies that the name of each parameter matches a regular expression. This rule applies * to method parameters, constructor parameters and closure parameters. By default it checks that * parameter names start with a lowercase letter and contains only letters or numbers. *

* The regex property specifies the default regular expression used to validate the * parameter name. It is required and cannot be null or empty. It defaults to '[a-z][a-zA-Z0-9]*'. *

* The ignoreParameterNames property optionally specifies one or more * (comma-separated) parameter names that should be ignored (i.e., that should not cause a * rule violation). The name(s) may optionally include wildcard characters ('*' or '?'). * * @author Chris Mair * @author Hamlet D'Arcy */ class ParameterNameRule extends AbstractAstVisitorRule { String name = 'ParameterName' int priority = 2 String regex = DEFAULT_VAR_NAME String ignoreParameterNames Class astVisitorClass = ParameterNameAstVisitor void validate() { assert regex } } class ParameterNameAstVisitor extends AbstractAstVisitor { void visitMethodEx(MethodNode methodNode) { processParameters(methodNode.parameters, methodNode.name) super.visitMethodEx(methodNode) } @Override void visitConstructor(ConstructorNode constructorNode) { processParameters(constructorNode.parameters, '') super.visitConstructor(constructorNode) } void visitClosureExpression(ClosureExpression closureExpression) { if (isFirstVisit(closureExpression)) { processParameters(closureExpression.parameters, '') } super.visitClosureExpression(closureExpression) } private void processParameters(parameters, methodName) { parameters.each { parameter -> if (!new WildcardPattern(rule.ignoreParameterNames, false).matches(parameter.name)) { if (parameter.lineNumber >= 0 && !(parameter.name ==~ rule.regex)) { addViolation(parameter, "The parameter named $parameter.name in method $methodName of class $currentClassName does not match ${rule.regex.toString()}") } } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/AbstractRuleTestCase.groovy0000644000175000017500000003707612444433061026334 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule import org.codenarc.analyzer.StringSourceAnalyzer import org.codenarc.ruleset.ListRuleSet import org.codenarc.source.CustomCompilerPhaseSourceDecorator import org.codenarc.source.SourceCode import org.codenarc.source.SourceString import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import java.util.regex.Pattern import java.util.regex.PatternSyntaxException import static org.codenarc.test.TestUtil.assertContainsAll /** * Abstract superclass for tests of Rule classes * * @author Chris Mair * @author Hamlet D'Arcy */ @SuppressWarnings('DuplicateLiteral') abstract class AbstractRuleTestCase extends AbstractTestCase { protected static final CONSTRUCTOR_METHOD_NAME = '' protected static final DEFAULT_TEST_FILES = AbstractAstVisitorRule.DEFAULT_TEST_FILES protected static final DEFAULT_TEST_CLASS_NAMES = AbstractAstVisitorRule.DEFAULT_TEST_CLASS_NAMES protected Rule rule // Subclasses can optionally set these to set the name or path of the SourceCode object created protected String sourceCodeName protected String sourceCodePath //-------------------------------------------------------------------------- // Common Tests - Run for all concrete subclasses //-------------------------------------------------------------------------- /** * Make sure that code unrelated to the rule under test causes no violations. * Subclasses can skip this rule by defining a property named 'skipTestThatUnrelatedCodeHasNoViolations'. */ @Test void testThatUnrelatedCodeHasNoViolations() { final SOURCE = 'class MyClass { }' if (!getProperties().keySet().contains('skipTestThatUnrelatedCodeHasNoViolations')) { assertNoViolations(SOURCE) } } @Test void testThatInvalidCodeHasNoViolations() { final SOURCE = ''' @will not compile@ &^%$# ''' if (!getProperties().keySet().contains('skipTestThatInvalidCodeHasNoViolations')) { // Verify no errors/exceptions def sourceCode = prepareSourceCode(SOURCE) assert rule.applyTo(sourceCode).empty } } @Test void testThatApplyToFilesMatchingValuesAreValidRegex() { assertValidRegex(rule.applyToFilesMatching, 'applyToFilesMatching') assertValidRegex(rule.doNotApplyToFilesMatching, 'doNotApplyToFilesMatching') } private void assertValidRegex(String regex, String name) { if (regex) { try { Pattern.compile(regex) } catch(PatternSyntaxException e) { fail("The $name value [$regex] is not a valid regular expression: $e") } } } //-------------------------------------------------------------------------- // Abstract Method Declarations - Must be implemented by concrete subclasses //-------------------------------------------------------------------------- /** * Create and return a new instance of the Rule class to be tested. * @return a new Rule instance */ protected abstract Rule createRule() /** * Apply the current Rule to the specified source (String) and assert that it results * in two violations with the specified line numbers and containing the specified source text values. * @param source - the full source code to which the rule is applied, as a String * @param lineNumber1 - the expected line number in the first violation * @param sourceLineText1 - the text expected within the sourceLine of the first violation * @param lineNumber2 - the expected line number in the second violation * @param sourceLineText2 - the text expected within the sourceLine of the second violation */ protected void assertTwoViolations(String source, Integer lineNumber1, String sourceLineText1, Integer lineNumber2, String sourceLineText2) { def violations = applyRuleTo(source) violations.sort { it.lineNumber } assert violations.size() == 2, "Expected 2 violations\nFound ${violations.size()}: \n${violations.join('\n')}\n" assertViolation(violations[0], lineNumber1, sourceLineText1) assertViolation(violations[1], lineNumber2, sourceLineText2) } /** * Apply the current Rule to the specified source (String) and assert that it results * in the violations specified inline within the source.

* * Inline violations can be specified either by using the {@link #inlineViolation(java.lang.String)} method * or simply by prefixing a violation message with a '#'. Multiple inline violations per line are allowed.

* * One can prevent a '#' character from starting a violation message by escaping it with a '\' character * (keep in mind that most of Groovy's string literal syntax demands the '\' to be escaped itself, * as a '\\' sequence).

* * For every source line all text after the first non-escaped '#' character is part of some inline violation message * (with the sole exception of the first line of a Groovy script beginning with a shebang). * More precisely, every '#' character that is neither escaped nor part of a shebang starts an inline violation that * spans to the end of its line or until next non-escaped '#' character.

* * See the {@link #inlineViolation(java.lang.String)} method.
* See the {@link #removeInlineViolations(java.lang.String)} method.
* * @param source - the full source code to which the rule is applied annotated with inline violations, as a String */ protected void assertInlineViolations(String annotatedSource) { def parseResult = new InlineViolationsParser().parse(annotatedSource) def violationsMap = parseResult.violations as Map[] assertViolations(parseResult.source, violationsMap) assert violationsMap, 'There must be at least one inline violation specified. If no violations are intended, then use assertNoViolations() instead' } /** * Prepares an inline violation with a given message, escaping all '#' characters and preventing accidental * escaping of next inline violation's start when the message ends with a '\' character. * * @param violationMessage message for the inline violation * @return a String that will be interpreted as an inline violation by the * {@link #assertInlineViolations(java.lang.String)} method */ protected static String inlineViolation(String violationMessage) { return InlineViolationsParser.inlineViolation(violationMessage) } /** * Removes all inline violations from a source. * * @param annotatedSource source possibly containing inline violations * @return the given source with inline violations removed */ protected static String removeInlineViolations(String annotatedSource) { return new InlineViolationsParser().parse(annotatedSource).source } /** * Apply the current Rule to the specified source (String) and assert that it results * in the violations specified in violationMaps. * @param source - the full source code to which the rule is applied, as a String * @param violationMaps - a list (array) of Maps, each describing a single violation. * Each element in the map can contain a lineNumber, sourceLineText and messageText entries. */ protected void assertViolations(String source, Map[] violationMaps) { def rawViolations = applyRuleTo(source) rawViolations.sort { v -> v.lineNumber } assert rawViolations.size() == violationMaps.size(), "Expected ${violationMaps.size()} violations\nFound ${rawViolations.size()}: \n ${rawViolations.join('\n ')}\n" violationMaps.eachWithIndex { violationMap, index -> assert violationMap.keySet().every { key -> key in ['lineNumber', 'sourceLineText', 'messageText'] }, "violationMap keys must be 'lineNumber', 'sourceLineText' and/or 'messageText'" assertViolation(rawViolations[index], violationMap.lineNumber, violationMap.sourceLineText, violationMap.messageText) } } /** * Apply the current Rule to the specified source (String) and assert that it results * in two violations with the specified line numbers and containing the specified source text values. * @param source - the full source code to which the rule is applied, as a String * @param lineNumber1 - the expected line number in the first violation * @param sourceLineText1 - the text expected within the sourceLine of the first violation * @param msg1 - the text expected within the message of the first violation; May be a String or List of Strings; Defaults to null; * @param lineNumber2 - the expected line number in the second violation * @param sourceLineText2 - the text expected within the sourceLine of the second violation * @param msg2 - the text expected within the message of the second violation; May be a String or List of Strings; Defaults to null; */ @SuppressWarnings('ParameterCount') protected void assertTwoViolations(String source, Integer lineNumber1, String sourceLineText1, msg1, Integer lineNumber2, String sourceLineText2, msg2) { def violations = applyRuleTo(source) assert violations.size() == 2, "Expected 2 violations\nFound ${violations.size()}: \n${violations.join('\n')}\n" assertViolation(violations[0], lineNumber1, sourceLineText1, msg1) assertViolation(violations[1], lineNumber2, sourceLineText2, msg2) } /** * Apply the current Rule to the specified source (String) and assert that it results * in a single violation with the specified line number and containing the specified source text. * @param source - the full source code to which the rule is applied, as a String * @param lineNumber - the expected line number in the resulting violation; defaults to null * @param sourceLineText - the text expected within the sourceLine of the resulting violation; defaults to null * @param messageText - the text expected within the message of the resulting violation; May be a String or List of Strings; Defaults to null; */ protected void assertSingleViolation(String source, Integer lineNumber=null, String sourceLineText=null, messageText=null) { def violations = applyRuleTo(source) assert violations.size() == 1, "Expected 1 violation\nFound ${violations.size()}: \n${violations.join('\n')}\n for sourceLineText: [$sourceLineText]" assertViolation(violations[0], lineNumber, sourceLineText, messageText) } /** * Apply the current Rule to the specified source (String) and assert that it results * in a single violation and that the specified closure returns true. * @param source - the full source code to which the rule is applied, as a String; defaults to null * @param closure - the closure to apply to the violation; takes a single Violation parameter */ protected void assertSingleViolation(String source, Closure closure) { def violations = applyRuleTo(source) assert violations.size() == 1, "Expected 1 violation\nFound ${violations.size()}: \n${violations.join('\n')}\n" assert closure(violations[0]), "Closure failed for ${violations[0]}" } /** * Apply the current Rule to the specified source (String) and assert that it results * in no violations. * @param source - the full source code to which the rule is applied, as a String */ protected void assertNoViolations(String source) { def violations = applyRuleTo(source) assert violations.empty, "Expected no violations, but got ${violations.size()}: \n${violations.join('\n')}\n" } /** * Assert that the specified violation is for the current rule, and has expected line number * and contains the specified source text and message text. * @param violation - the Violation * @param lineNumber - the expected line number in the resulting violation * @param sourceLineText - the text expected within the sourceLine of the resulting violation; may be null * @param messageText - the text expected within the message of the resulting violation; May be a String or List of Strings; Defaults to null; */ protected void assertViolation( Violation violation, Integer lineNumber, String sourceLineText, messageText=null) { assert violation.rule == rule assert violation.lineNumber == lineNumber : "Wrong line number for violation: \n$violation\nExpected: $lineNumber\nFound: $violation.lineNumber\n" if (sourceLineText) { assert violation.sourceLine assert violation.sourceLine.contains(sourceLineText), """Problem with source text: expected to contain: $sourceLineText actual: $violation.sourceLine """ } if (messageText) { assert violation.message, 'The violation message was null' if (messageText instanceof Collection) { assertContainsAll(violation.message, messageText) } else { assert violation.message.contains(messageText), "\nExpected message text: [$messageText]\nFound message text: [$violation.message]\n" } } } /** * Apply the current Rule to the specified source (String) and return the resulting List of Violations. * @param source - the full source code to which the rule is applied, as a String */ protected List applyRuleTo(String source) { def sourceCode = prepareSourceCode(source) assert sourceCode.valid def violations = rule.applyTo(sourceCode) log("violations=$violations") violations } private SourceCode prepareSourceCode(String source) { def sourceCode = new SourceString(source, sourceCodePath, sourceCodeName) if (rule.compilerPhase != SourceCode.DEFAULT_COMPILER_PHASE) { sourceCode = new CustomCompilerPhaseSourceDecorator(sourceCode, rule.compilerPhase) } sourceCode } /** * Apply the current Rule to the specified source (String) and return the resulting List of Violations. * @param source - the full source code to which the rule is applied, as a String */ protected List manuallyApplyRule(String source) { def analyzer = new StringSourceAnalyzer(source) assert analyzer.source.valid def results = analyzer.analyze(new ListRuleSet([rule])) results.violations } @Before void setUpAbstractRuleTestCase() { this.rule = createRule() } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/0000755000175000017500000000000012623571301022101 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EqualsAndHashCodeRule.groovy0000644000175000017500000000421512052037536027461 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that checks that if either the boolean equals(Object) or * the int hashCode() methods are overridden within a class, then both must be overridden. * * @author Chris Mair * @author Hamlet D'Arcy */ class EqualsAndHashCodeRule extends AbstractAstVisitorRule { String name = 'EqualsAndHashCode' int priority = 2 Class astVisitorClass = EqualsAndHashCodeAstVisitor } class EqualsAndHashCodeAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode classNode) { def methods = classNode.methods def equalsMethod = methods.find { m -> m.name == 'equals' && m.parameters.size() == 1 && m.parameters[0].type.name in ['Object', 'java.lang.Object'] } def hashCodeMethod = methods.find { m -> m.name == 'hashCode' && m.parameters.size() == 0 } def oneButNotBoth = (equalsMethod || hashCodeMethod) && !(equalsMethod && hashCodeMethod) if (oneButNotBoth) { if (equalsMethod) { addViolation(classNode, "The class $classNode.name defines equals(Object) but not hashCode()") } else { addViolation(classNode, "The class $classNode.name defines hashCode() but not equals(Object)") } } super.visitClassEx(classNode) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/AbstractFinallyAstVisitor.groovy0000644000175000017500000000336012311373552030466 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.Statement import org.codehaus.groovy.ast.stmt.TryCatchStatement import org.codenarc.rule.AbstractAstVisitor /** * Abstract superclass for AST Visitor classes that check for conditions within a finally block * * @author Chris Mair */ abstract class AbstractFinallyAstVisitor extends AbstractAstVisitor { private final finallyLineRanges = [] // Known pathology: if there is another statement on the same line as the beginning or // end of the finally block, but outside the block. void visitTryCatchFinally(TryCatchStatement tryCatchStatement) { if (tryCatchStatement.finallyStatement) { def f = tryCatchStatement.finallyStatement finallyLineRanges.add(f.lineNumber..f.lastLineNumber) } super.visitTryCatchFinally(tryCatchStatement) } /** * @return true if the specified statement is within a finally block */ protected boolean isStatementWithinFinally(Statement statement) { finallyLineRanges.find { statement.lineNumber in it } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyInstanceInitializerRule.groovy0000644000175000017500000000331212006632012031156 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * The class has an empty instance initializer. It can safely by removed. * * @author 'Hamlet D'Arcy' */ class EmptyInstanceInitializerRule extends AbstractAstVisitorRule { String name = 'EmptyInstanceInitializer' int priority = 2 Class astVisitorClass = EmptyInstanceInitializerAstVisitor } class EmptyInstanceInitializerAstVisitor extends AbstractAstVisitor { @Override protected void visitObjectInitializerStatements(ClassNode node) { if (node.objectInitializerStatements.size() == 1 && AstUtil.isEmptyBlock(node.objectInitializerStatements[0])) { def emptyBlock = AstUtil.getEmptyBlock(node.objectInitializerStatements[0]) if (emptyBlock) { addViolation(emptyBlock, "The class $node.name defines an empty instance initializer. It is safe to delete it") } } super.visitObjectInitializerStatements(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ForLoopShouldBeWhileLoopRule.groovy0000644000175000017500000000440012006632014031021 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.EmptyExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codehaus.groovy.ast.stmt.ForStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * For loops where init and update statements are empty can be simplified to while loops. * Ignores For-Each Loops (for (Plan p : plans) { .. }) and Groovy For Loops (for (p in plans) { .. }). * * @author Victor Savkin */ class ForLoopShouldBeWhileLoopRule extends AbstractAstVisitorRule { String name = 'ForLoopShouldBeWhileLoop' int priority = 3 Class astVisitorClass = ForLoopShouldBeWhileLoopAstVisitor } class ForLoopShouldBeWhileLoopAstVisitor extends AbstractAstVisitor { @Override void visitForLoop(ForStatement node) { if(!isForEachLoop(node) && hasOnlyConditionExpr(node)) { addViolation node, 'The for loop can be simplified to a while loop' } super.visitForLoop node } private hasOnlyConditionExpr(ForStatement forStatement) { if (AstUtil.respondsTo(forStatement.collectionExpression, 'expressions')) { def (init, condition, update) = forStatement.collectionExpression.expressions return isEmptyExpression(init) && isEmptyExpression(update) && !isEmptyExpression(condition) } false } private static isEmptyExpression(expr) { expr instanceof EmptyExpression } private boolean isForEachLoop(ForStatement forStatement) { return forStatement.collectionExpression instanceof VariableExpression } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/MultipleUnaryOperatorsRule.groovy0000644000175000017500000000606712323627301030721 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.BitwiseNegationExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.NotExpression import org.codehaus.groovy.ast.expr.UnaryMinusExpression import org.codehaus.groovy.ast.expr.UnaryPlusExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractAstVisitor /** * Checks for multiple consecutive unary operators. These are confusing, and are likely typos and bugs. * * @author Chris Mair */ class MultipleUnaryOperatorsRule extends AbstractAstVisitorRule { String name = 'MultipleUnaryOperators' int priority = 2 Class astVisitorClass = MultipleUnaryOperatorsAstVisitor } class MultipleUnaryOperatorsAstVisitor extends AbstractAstVisitor { private static final UNARY_OPERATORS = [ (BitwiseNegationExpression):'~', (NotExpression):'!', (UnaryMinusExpression):'-', (UnaryPlusExpression):'+' ] private static final UNARY_OPERATOR_CLASSES = UNARY_OPERATORS.keySet() private static final ERROR_MESSAGE = 'The expression (%s) in class %s contains confusing multiple consecutive unary operators' @Override void visitBitwiseNegationExpression(BitwiseNegationExpression expression) { checkForSecondUnaryOperator(expression, BitwiseNegationExpression) super.visitBitwiseNegationExpression(expression) } @Override void visitNotExpression(NotExpression expression) { checkForSecondUnaryOperator(expression, NotExpression) super.visitNotExpression(expression) } @Override void visitUnaryMinusExpression(UnaryMinusExpression expression) { checkForSecondUnaryOperator(expression, UnaryMinusExpression) super.visitUnaryMinusExpression(expression) } @Override void visitUnaryPlusExpression(UnaryPlusExpression expression) { checkForSecondUnaryOperator(expression, UnaryPlusExpression) super.visitUnaryPlusExpression(expression) } private void checkForSecondUnaryOperator(Expression expression, Class firstOperatorClass) { if (expression.expression.class in UNARY_OPERATOR_CLASSES) { String operators = UNARY_OPERATORS[firstOperatorClass] + UNARY_OPERATORS[expression.expression.class] String expressionText = operators + expression.text addViolation(expression, String.format(ERROR_MESSAGE, expressionText, currentClassName)) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyCatchBlockRule.groovy0000644000175000017500000000334412311373552027222 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.CatchStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for empty catch blocks * * @author Chris Mair */ class EmptyCatchBlockRule extends AbstractAstVisitorRule { String name = 'EmptyCatchBlock' int priority = 2 Class astVisitorClass = EmptyCatchBlockAstVisitor String ignoreRegex = 'ignore|ignored' } class EmptyCatchBlockAstVisitor extends AbstractAstVisitor { void visitCatchStatement(CatchStatement catchStatement) { if (isFirstVisit(catchStatement) && isExceptionIgnored(catchStatement)) { addViolation(catchStatement, 'The catch block is empty') } super.visitCatchStatement(catchStatement) } private isExceptionIgnored(catchStatement) { AstUtil.isEmptyBlock(catchStatement.code) && !doesContainIgnoreWord(catchStatement.variable?.name) } private doesContainIgnoreWord(String name) { name ==~ rule.ignoreRegex } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/BigDecimalInstantiationRule.groovy0000644000175000017500000000415312461171646030740 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.ConstructorCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractConstructorCallAstVisitor /** * Rule that checks for calls to the BigDecimal constructor with a double or float literal. * The String literal should be used instead. * * @author Chris Mair */ class BigDecimalInstantiationRule extends AbstractAstVisitorRule { String name = 'BigDecimalInstantiation' int priority = 2 Class astVisitorClass = BigDecimalInstantiationAstVisitor } class BigDecimalInstantiationAstVisitor extends AbstractConstructorCallAstVisitor { static final NEW_BIG_DECIMAL = /new +(java\.math\.)?BigDecimal\(/ @SuppressWarnings('ExplicitCallToGetAtMethod') protected isConstructorCallAViolation(ConstructorCallExpression constructorCall) { def firstArgExpression = constructorCall.arguments?.expressions?.getAt(0) constructorCall.text =~ NEW_BIG_DECIMAL && (firstArgExpression instanceof ConstantExpression) && (firstArgExpression.type.name in ['java.math.BigDecimal', 'java.lang.Double', 'double']) } @Override protected String getViolationMessage(ConstructorCallExpression call) { """Call to $call.text uses the double constructor and should probably be replaced with new ${call.type.name}("${call.arguments?.expressions?.first().text}")""" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/DoubleNegativeRule.groovy0000644000175000017500000000272612323542260027103 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.NotExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * There is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well. * * @author Hamlet D'Arcy */ class DoubleNegativeRule extends AbstractAstVisitorRule { String name = 'DoubleNegative' int priority = 2 Class astVisitorClass = DoubleNegativeAstVisitor } class DoubleNegativeAstVisitor extends AbstractAstVisitor { void visitNotExpression(NotExpression expression) { if (expression.expression instanceof NotExpression) { addViolation expression, "The expression (!!$expression.text) is a confusing double negative" } super.visitNotExpression expression } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/AssignmentInConditionalRule.groovy0000644000175000017500000000543512041061502030761 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ElvisOperatorExpression import org.codehaus.groovy.ast.expr.TernaryExpression import org.codehaus.groovy.ast.stmt.IfStatement import org.codehaus.groovy.ast.stmt.WhileStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * An assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended. * * @author 'Hamlet D'Arcy' * @author Chris Mair */ class AssignmentInConditionalRule extends AbstractAstVisitorRule { String name = 'AssignmentInConditional' int priority = 2 Class astVisitorClass = AssignmentInConditionalAstVisitor } class AssignmentInConditionalAstVisitor extends AbstractAstVisitor { @Override void visitIfElse(IfStatement node) { addViolationIfAssignment(node.booleanExpression.expression) super.visitIfElse(node) } @Override void visitWhileLoop(WhileStatement node) { addViolationIfAssignment(node.booleanExpression.expression) super.visitWhileLoop(node) } @Override void visitTernaryExpression(TernaryExpression node) { addViolationIfAssignment(node.booleanExpression.expression) super.visitTernaryExpression(node) } @Override void visitShortTernaryExpression(ElvisOperatorExpression node) { addViolationIfAssignment(node.booleanExpression.expression) super.visitShortTernaryExpression(node) } private addViolationIfAssignment(node) { if (isFirstVisit(node) && node instanceof BinaryExpression) { if (node.operation.text == '=') { addViolation(node, 'Assignment used as conditional value, which always results in true. Use the == operator instead') } else { if (node.operation.text in ['&&', '||']) { addViolationIfAssignment(node.leftExpression) addViolationIfAssignment(node.rightExpression) } } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/DeadCodeRule.groovy0000644000175000017500000000451412311370173025632 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.TernaryExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.stmt.* /** * Dead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted. * * @author Hamlet D'Arcy */ class DeadCodeRule extends AbstractAstVisitorRule { String name = 'DeadCode' int priority = 2 Class astVisitorClass = DeadCodeAstVisitor } class DeadCodeAstVisitor extends AbstractAstVisitor { void visitBlockStatement(BlockStatement block) { if (block.statements && block.statements.size() >= 2) { (block.statements.size() - 1).times { def statement = block.statements[it] if (statementForcesMethodReturn(statement)) { addViolation (block.statements[it + 1], 'This code cannot be reached') } } } super.visitBlockStatement block } private boolean statementForcesMethodReturn(Statement statement) { if (statement instanceof ReturnStatement ) { return true } if (statement instanceof ThrowStatement ) { return true } if (statement instanceof IfStatement) { return statementForcesMethodReturn(statement.ifBlock) && statementForcesMethodReturn(statement.elseBlock) } if (statement instanceof TernaryExpression) { return statementForcesMethodReturn(statement.trueExpression) && statementForcesMethodReturn(statement.falseExpression) } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyStaticInitializerRule.groovy0000644000175000017500000000306212006632016030647 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * An empty static initializer was found. It is safe to remove it. * * @author Hamlet D'Arcy */ class EmptyStaticInitializerRule extends AbstractAstVisitorRule { String name = 'EmptyStaticInitializer' int priority = 2 Class astVisitorClass = EmptyStaticInitializerAstVisitor } class EmptyStaticInitializerAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (node.name == '' && AstUtil.isEmptyBlock(node.code)) { def emptyBlock = AstUtil.getEmptyBlock(node.code) if (emptyBlock) { addViolation(emptyBlock, "The class ${node?.declaringClass?.name} has an empty static initializer. It is safe to delete it") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/HardCodedWindowsFileSeparatorRule.groovy0000644000175000017500000000450412141451332032050 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * This rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant. * * @author Hamlet D'Arcy */ class HardCodedWindowsFileSeparatorRule extends AbstractAstVisitorRule { String name = 'HardCodedWindowsFileSeparator' int priority = 2 Class astVisitorClass = HardCodedWindowsFileSeparatorAstVisitor } class HardCodedWindowsFileSeparatorAstVisitor extends AbstractAstVisitor { @Override void visitConstructorCallExpression(ConstructorCallExpression call) { if (isFirstVisit(call)) { if (AstUtil.isConstructorCall(call, 'File') && call.arguments instanceof ArgumentListExpression) { for (Expression exp : call.arguments.expressions) { addViolationForWindowsSeparator(exp) } } super.visitConstructorCallExpression(call) } } private void addViolationForWindowsSeparator(Expression expression) { if (expression instanceof ConstantExpression && expression.value instanceof String) { if (expression.value.contains('\\')) { addViolation(expression, 'The windows file separator is not portable') } } else if (expression instanceof GStringExpression) { if (expression.strings && expression.strings[0].value.contains('\\')) { addViolation(expression, 'The windows file separator is not portable') } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptySynchronizedStatementRule.groovy0000644000175000017500000000307612311373552031573 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.SynchronizedStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for empty synchronized statement * * @author Chris Mair */ class EmptySynchronizedStatementRule extends AbstractAstVisitorRule { String name = 'EmptySynchronizedStatement' int priority = 2 Class astVisitorClass = EmptySynchronizedStatementAstVisitor } class EmptySynchronizedStatementAstVisitor extends AbstractAstVisitor { void visitSynchronizedStatement(SynchronizedStatement synchronizedStatement) { if (isFirstVisit(synchronizedStatement) && AstUtil.isEmptyBlock(synchronizedStatement.code)) { addViolation(synchronizedStatement, 'The synchronized statement is empty') } super.visitSynchronizedStatement(synchronizedStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/RemoveAllOnSelfRule.groovy0000644000175000017500000000374712006632014027202 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.TupleExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor /** * This rule catches calling the method removeAll with yourself as a parameter. * * @author Hamlet D'Arcy */ class RemoveAllOnSelfRule extends AbstractAstVisitorRule { String name = 'RemoveAllOnSelf' int priority = 2 Class astVisitorClass = RemoveAllOnSelfAstVisitor } class RemoveAllOnSelfAstVisitor extends AbstractMethodCallExpressionVisitor { void visitMethodCallExpression(MethodCallExpression call) { if (isMethodNamed(call, 'removeAll') && getArity(call) == 1) { String variableName = call.objectExpression.text def argumentName = call.arguments.expressions[0].text if (argumentName == variableName) { addViolation call, "A call to $call.text can be replaced with ${call.objectExpression.text}.clear()" } } } private static boolean isMethodNamed(MethodCallExpression call, target) { call?.method?.text == target } private static int getArity(MethodCallExpression call) { if (call?.arguments instanceof TupleExpression) { return call?.arguments?.expressions?.size() } 0 } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ExplicitGarbageCollectionRule.groovy0000644000175000017500000000541512006632014031245 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * Calls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the * same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, * "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks * develop within an application, it should be dealt with JVM options rather than within the code itself. * * @author 'Hamlet D'Arcy' */ class ExplicitGarbageCollectionRule extends AbstractAstVisitorRule { String name = 'ExplicitGarbageCollection' int priority = 2 Class astVisitorClass = ExplicitGarbageCollectionAstVisitor } class ExplicitGarbageCollectionAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, ['System'], ['gc', 'runFinalization'], 0)) { addViolation call, 'Garbage collection should not be explicitly forced' } else if (AstUtil.isMethodNamed(call, 'gc', 0)) { if (isPropertyExpression(call.objectExpression, 'Runtime', 'runtime')) { addViolation call, 'Garbage collection should not be explicitly forced' } else if (AstUtil.isMethodCall(call.objectExpression, 'Runtime', 'getRuntime', 0)) { addViolation call, 'Garbage collection should not be explicitly forced' } } } private static boolean isPropertyExpression(Expression expression, String object, String propertyName) { if (!(expression instanceof PropertyExpression)) { return false } if (expression.property instanceof ConstantExpression && expression.property.value == propertyName) { if (expression.objectExpression instanceof VariableExpression && expression.objectExpression.variable == object) { return true } } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/DuplicateMapKeyRule.groovy0000644000175000017500000000356012006632016027221 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.MapExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * A map literal is created with duplicated key. The map entry will be overwritten. * * @author 'Łukasz Indykiewicz' */ class DuplicateMapKeyRule extends AbstractAstVisitorRule { String name = 'DuplicateMapKey' int priority = 2 Class astVisitorClass = DuplicateMapKeyAstVisitor } class DuplicateMapKeyAstVisitor extends AbstractAstVisitor { @Override @SuppressWarnings('UnnecessaryCollectCall') void visitMapExpression(MapExpression expression) { if(isFirstVisit(expression)) { def a = expression.mapEntryExpressions .findAll { it.keyExpression instanceof ConstantExpression } .collect { it.keyExpression } a.inject([]) { result, it -> if (result.contains(it.value)) { addViolation(it, "Key '${it.value}' is duplicated.") } else { result.add(it.value) } result } super.visitMapExpression(expression) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/DuplicateCaseStatementRule.groovy0000644000175000017500000000360612006632014030572 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.stmt.CaseStatement import org.codehaus.groovy.ast.stmt.SwitchStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that checks for duplicate case statements in a switch block, such as two * equal integers or strings. * * @author Hamlet D'Arcy */ class DuplicateCaseStatementRule extends AbstractAstVisitorRule { String name = 'DuplicateCaseStatement' int priority = 2 Class astVisitorClass = DuplicateCaseStatementAstVisitor } class DuplicateCaseStatementAstVisitor extends AbstractAstVisitor { void visitSwitch(SwitchStatement statement) { def allElements = statement?.caseStatements?.findAll { it?.expression instanceof ConstantExpression } allElements.inject([]) { list, CaseStatement item -> if (list.contains(item?.expression?.value)) { addViolation(item, "Duplicate case statements found in switch. $item?.expression?.value appears twice") } else { list.add item.expression?.value } list } super.visitSwitch(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/AssertWithinFinallyBlockRule.groovy0000644000175000017500000000303512311373552031121 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.AssertStatement import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that checks for assert statements within a finally block. * * @author Chris Mair */ class AssertWithinFinallyBlockRule extends AbstractAstVisitorRule { String name = 'AssertWithinFinallyBlock' int priority = 2 Class astVisitorClass = AssertWithinFinallyBlockAstVisitor } class AssertWithinFinallyBlockAstVisitor extends AbstractFinallyAstVisitor { @Override void visitAssertStatement(AssertStatement statement) { if (isFirstVisit(statement) && isStatementWithinFinally(statement)) { addViolation(statement, "A finally block within class $currentClassName contains an assert statement, potentially hiding the original exception, if there is one") } super.visitAssertStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ConstantTernaryExpressionRule.groovy0000644000175000017500000000520712311373552031424 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.TernaryExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for ternary expressions with a constant value for the boolean expression, such as: *

    *
  • true ? x : y
  • *
  • false ? x : y
  • *
  • Boolean.TRUE ? x : y
  • *
  • Boolean.FALSE ? x : y
  • *
  • null ? x : y
  • *
  • 0 ? x : y
  • *
  • 99.7 ? x : y
  • *
  • "" ? x : y
  • *
  • "abc" ? x : y
  • *
  • [:] ? x : y
  • *
  • [a:123, b:456] ? x : y
  • *
  • [a, b, c] ? x : y
  • *
* * Also checks for the same types of constant values for the boolean expressions within the "short" * ternary expressions, also known as the "Elvis" operator, e.g.: *
    *
  • true ?: y
  • *
  • null ?: y
  • *
  • 99.7 ?: y
  • *
  • "abc" ?: y
  • *
  • [a:123] ?: y
  • *
* * @author Chris Mair */ class ConstantTernaryExpressionRule extends AbstractAstVisitorRule { String name = 'ConstantTernaryExpression' int priority = 2 Class astVisitorClass = ConstantTernaryExpressionAstVisitor } class ConstantTernaryExpressionAstVisitor extends AbstractAstVisitor { void visitTernaryExpression(TernaryExpression ternaryExpression) { if (isFirstVisit(ternaryExpression)) { def booleanExpression = ternaryExpression.booleanExpression if (AstUtil.isConstantOrLiteral(booleanExpression.expression)) { addViolation(ternaryExpression, "The ternary expression contains the constant $booleanExpression.expression") } } super.visitTernaryExpression(ternaryExpression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyWhileStatementRule.groovy0000644000175000017500000000272112311373552030160 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.WhileStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for empty while statements * * @author Chris Mair */ class EmptyWhileStatementRule extends AbstractAstVisitorRule { String name = 'EmptyWhileStatement' int priority = 2 Class astVisitorClass = EmptyWhileStatementAstVisitor } class EmptyWhileStatementAstVisitor extends AbstractAstVisitor { void visitWhileLoop(WhileStatement whileStatement) { if (isFirstVisit(whileStatement) && AstUtil.isEmptyBlock(whileStatement.loopBlock)) { addViolation(whileStatement, 'The while statement is empty') } super.visitWhileLoop(whileStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ComparisonOfTwoConstantsRule.groovy0000644000175000017500000000530612006632014031164 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * CodeNarc Rule. Checks for using a comparison operator or equals() or compareTo() to compare two * constants to each other or two literal that contain only constant values, e.g.: * 23 == 67, [3,2] != [1,2] * Boolean.FALSE != false * 23 < 88, 0.17 <= 0.99, "abc" > "ddd", [a] >= [x], * [a:1] <=> [a:99.87] * [1,2].equals([17,true]) * [a:1].compareTo([a:3]) * * @author Chris Mair */ class ComparisonOfTwoConstantsRule extends AbstractAstVisitorRule { String name = 'ComparisonOfTwoConstants' int priority = 2 Class astVisitorClass = ComparisonOfTwoConstantsAstVisitor } class ComparisonOfTwoConstantsAstVisitor extends AbstractAstVisitor { @Override void visitBinaryExpression(BinaryExpression expression) { if (isFirstVisit(expression) && AstUtil.isBinaryExpressionType(expression, AstUtil.COMPARISON_OPERATORS)) { def left = expression.leftExpression def right = expression.rightExpression addViolationIfBothAreConstantsOrLiterals(expression, left, right) } super.visitBinaryExpression(expression) } @Override void visitMethodCallExpression(MethodCallExpression call) { if (isFirstVisit(call) && (AstUtil.isMethodCall(call, 'equals', 1) || AstUtil.isMethodCall(call, 'compareTo', 1))) { def left = call.objectExpression def right = call.arguments.getExpression(0) addViolationIfBothAreConstantsOrLiterals(call, left, right) } super.visitMethodCallExpression(call) } private void addViolationIfBothAreConstantsOrLiterals(node, left, right) { if (AstUtil.isConstantOrConstantLiteral(left) && AstUtil.isConstantOrConstantLiteral(right)) { addViolation(node, "Comparing two constants or constant literals is useless and may indicate a bug: ${node.text}") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/IntegerGetIntegerRule.groovy0000644000175000017500000000373012006632020027545 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * This rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. * It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API * to use; replace it with System.properties['prop']. * * @author 'Hamlet D'Arcy' */ class IntegerGetIntegerRule extends AbstractAstVisitorRule { String name = 'IntegerGetInteger' int priority = 2 Class astVisitorClass = IntegerGetIntegerAstVisitor } class IntegerGetIntegerAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, 'Integer', 'getInteger', 1)) { addViolation call, 'Integer.getInteger(String) is a confusing API for reading System properties. Prefer the System.getProperty(String) API.' } else if (AstUtil.isMethodCall(call, 'Integer', 'getInteger', 2)) { addViolation call, 'Integer.getInteger(String, Integer) is a confusing API for reading System properties. Prefer the System.getProperty(String) API.' } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyClassRule.groovy0000644000175000017500000000467512170526114026277 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.InnerClassNode import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Reports classes without methods, fields or properties. * * Ignores interfaces, Enums, anonymous inner classes, subclasses (extends), and classes with annotations. * * @author Artur Gajowy */ class EmptyClassRule extends AbstractRule { String name = 'EmptyClass' int priority = 2 @Override void applyTo(SourceCode sourceCode, List violations) { sourceCode.ast?.classes?.each { classNode -> if ( !classNode.isInterface() && !classNode.isEnum() && !isAnonymousInnerClass(classNode) && !isSubclass(classNode) && !hasAnnotation(classNode) && isEmpty(classNode)) { violations << createViolation(sourceCode, classNode, violationMessage(classNode)) } } } private boolean isSubclass(ClassNode classNode) { return classNode.superClass.name != 'java.lang.Object' } private boolean hasAnnotation(ClassNode classNode) { return classNode.getAnnotations() } private boolean isAnonymousInnerClass(ClassNode classNode) { return classNode instanceof InnerClassNode && classNode.isAnonymous() } private boolean isEmpty(ClassNode classNode) { classNode.with { [methods, declaredConstructors, fields].every { it.isEmpty() } } } private String violationMessage(ClassNode classNode) { def name = classNode.nameWithoutPackage "Class '$name' is empty (has no methods, fields or properties). Why would you need a class like this?" } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/HardCodedWindowsRootDirectoryRule.groovy0000644000175000017500000000454712141451376032137 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil import org.codehaus.groovy.ast.expr.* /** * This rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative. * * @author Hamlet D'Arcy */ class HardCodedWindowsRootDirectoryRule extends AbstractAstVisitorRule { String name = 'HardCodedWindowsRootDirectory' int priority = 2 Class astVisitorClass = HardcodedWindowsRootDirectoryAstVisitor } class HardcodedWindowsRootDirectoryAstVisitor extends AbstractAstVisitor { @Override void visitConstructorCallExpression(ConstructorCallExpression call) { if (isFirstVisit(call)) { if (AstUtil.isConstructorCall(call, 'File') && call.arguments instanceof ArgumentListExpression) { for (Expression exp : call.arguments.expressions) { addViolationForWindowsPath(exp) } } super.visitConstructorCallExpression(call) } } private void addViolationForWindowsPath(Expression expression) { if (expression instanceof ConstantExpression && expression.value instanceof String) { if (expression.value ==~ /[a-zA-Z]:\\.*/) { addViolation(expression, "The file location ${expression.value[0..2]} is not portable") } } else if (expression instanceof GStringExpression) { if (expression.strings && expression.strings[0].value ==~ /[a-zA-Z]:\\.*/) { addViolation(expression, "The file location ${expression.strings[0].value[0..2]} is not portable") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyForStatementRule.groovy0000644000175000017500000000266312311373552027643 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.ForStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for empty for statements * * @author Chris Mair */ class EmptyForStatementRule extends AbstractAstVisitorRule { String name = 'EmptyForStatement' int priority = 2 Class astVisitorClass = EmptyForStatementAstVisitor } class EmptyForStatementAstVisitor extends AbstractAstVisitor { void visitForLoop(ForStatement forStatement) { if (isFirstVisit(forStatement) && AstUtil.isEmptyBlock(forStatement.loopBlock)) { addViolation(forStatement, 'The for statement is empty') } super.visitForLoop(forStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EqualsOverloadedRule.groovy0000644000175000017500000000426512311370173027444 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil /** * The class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it. * * @author Hamlet D'Arcy, * @author Artur Gajowy * @author Marcin Smialek * */ class EqualsOverloadedRule extends AbstractAstVisitorRule { String name = 'EqualsOverloaded' int priority = 2 Class astVisitorClass = EqualsOverloadedAstVisitor } class EqualsOverloadedAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (AstUtil.isMethodNode(node, 'equals')) { addViolationIfOverloaded(node) } } private void addViolationIfOverloaded(MethodNode method) { if (!(isEqualsMethodWithOneArgument(method) && onlyArgumentHasTypeObject(method))) { addViolation(method, "The class $method.declaringClass.name overloads the equals method, it does not override it.") } } private static boolean isEqualsMethodWithOneArgument(MethodNode method) { AstUtil.isMethodNode(method, 'equals', 1) } private static boolean onlyArgumentHasTypeObject(MethodNode method) { if (method.parameters[0].type.name == 'Object') { return true } if (method.parameters[0].type.name == 'java.lang.Object') { return true } false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyIfStatementRule.groovy0000644000175000017500000000264212311373552027450 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.IfStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for empty if statements * * @author Chris Mair */ class EmptyIfStatementRule extends AbstractAstVisitorRule { String name = 'EmptyIfStatement' int priority = 2 Class astVisitorClass = EmptyIfStatementAstVisitor } class EmptyIfStatementAstVisitor extends AbstractAstVisitor { void visitIfElse(IfStatement ifStatement) { if (isFirstVisit(ifStatement) && AstUtil.isEmptyBlock(ifStatement.ifBlock)) { addViolation(ifStatement, 'The if statement is empty') } super.visitIfElse(ifStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyTryBlockRule.groovy0000644000175000017500000000272112311373552026754 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.TryCatchStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for empty try blocks * * @author Chris Mair */ class EmptyTryBlockRule extends AbstractAstVisitorRule { String name = 'EmptyTryBlock' int priority = 2 Class astVisitorClass = EmptyTryBlockAstVisitor } class EmptyTryBlockAstVisitor extends AbstractAstVisitor { void visitTryCatchFinally(TryCatchStatement tryCatchStatement) { if (isFirstVisit(tryCatchStatement) && AstUtil.isEmptyBlock(tryCatchStatement.tryStatement)) { addViolation(tryCatchStatement, 'The try block is empty') } super.visitTryCatchFinally(tryCatchStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ReturnFromFinallyRule.groovy0000644000175000017500000000267412311373552027635 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that checks for a return from within a finally block * * @author Chris Mair */ class ReturnFromFinallyBlockRule extends AbstractAstVisitorRule { String name = 'ReturnFromFinallyBlock' int priority = 2 Class astVisitorClass = ReturnFromFinallyBlockAstVisitor } class ReturnFromFinallyBlockAstVisitor extends AbstractFinallyAstVisitor { void visitReturnStatement(ReturnStatement returnStatement) { if (isFirstVisit(returnStatement) && isStatementWithinFinally(returnStatement)) { addViolation(returnStatement, 'finally statements cannot return a value') } super.visitReturnStatement(returnStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/BrokenOddnessCheckRule.groovy0000644000175000017500000000546712006632012027702 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.BinaryExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * The code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). * If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0. * * @author 'Hamlet D'Arcy' */ class BrokenOddnessCheckRule extends AbstractAstVisitorRule { String name = 'BrokenOddnessCheck' int priority = 2 Class astVisitorClass = BrokenOddnessCheckAstVisitor } class BrokenOddnessCheckAstVisitor extends AbstractAstVisitor { @SuppressWarnings('NestedBlockDepth') // this code isn't that bad @Override void visitBinaryExpression(BinaryExpression expression) { if (AstUtil.isBinaryExpressionType(expression, '==')) { if (AstUtil.isBinaryExpressionType(expression.leftExpression, '%')) { if (AstUtil.isConstant(expression.rightExpression, 1)) { BinaryExpression modExp = expression.leftExpression if (AstUtil.isConstant(modExp.rightExpression, 2)) { def variable = modExp.leftExpression.text addViolation(expression, "The code uses '($variable % 2 == 1)' to check for oddness, which does not work for negative numbers. Use ($variable & 1 == 1) or ($variable % 2 != 0) instead") } } } else if (AstUtil.isBinaryExpressionType(expression.rightExpression, '%')) { if (AstUtil.isConstant(expression.leftExpression, 1)) { BinaryExpression modExp = expression.rightExpression if (AstUtil.isConstant(modExp.rightExpression, 2)) { def variable = modExp.leftExpression.text addViolation(expression, "The code uses '(1 == $variable % 2)' to check for oddness, which does not work for negative numbers. Use ($variable & 1 == 1) or ($variable % 2 != 0) instead") } } } } super.visitBinaryExpression(expression) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyElseBlockRule.groovy0000644000175000017500000000264212311373552027070 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.IfStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for empty else blocks * * @author Chris Mair */ class EmptyElseBlockRule extends AbstractAstVisitorRule { String name = 'EmptyElseBlock' int priority = 2 Class astVisitorClass = EmptyElseBlockAstVisitor } class EmptyElseBlockAstVisitor extends AbstractAstVisitor { void visitIfElse(IfStatement ifStatement) { if (isFirstVisit(ifStatement) && AstUtil.isEmptyBlock(ifStatement.elseBlock)) { addViolation(ifStatement.elseBlock, 'The else block is empty') } super.visitIfElse(ifStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/RandomDoubleCoercedToZeroRule.groovy0000644000175000017500000001070012006632012031171 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.CastExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.TernaryExpression import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * The Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this * result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int * field is probably a bug. * * @author Hamlet D'Arcy */ class RandomDoubleCoercedToZeroRule extends AbstractAstVisitorRule { String name = 'RandomDoubleCoercedToZero' int priority = 2 Class astVisitorClass = RandomDoubleCoercedToZeroAstVisitor } class RandomDoubleCoercedToZeroAstVisitor extends AbstractAstVisitor { @Override void visitCastExpression(CastExpression expression) { if (isFirstVisit(expression)) { if (AstUtil.isMethodCall(expression.expression, 'Math', 'random', 0)) { if (expression.type?.name == 'long' || expression.type?.name == 'Long') { addViolation(expression, "Casting the result of Math.random() to a ${expression.type.name} always results in 0") } else if (expression.type?.name == 'int' || expression.type?.name == 'Integer') { addViolation(expression, "Casting the result of Math.random() to an ${expression.type.name} always results in 0") } } } super.visitCastExpression(expression) } @Override void visitField(FieldNode node) { if (isFirstVisit(node)) { if (node.initialExpression && AstUtil.isMethodCall(node.initialExpression, 'Math', 'random', 0)) { if (node.type?.name == 'long' || node.type?.name == 'Long') { addViolation(node, "Assigning the result of Math.random() to a ${node.type.name} always results in 0") } else if (node.type?.name == 'int' || node.type?.name == 'Integer') { addViolation(node, "Assigning the result of Math.random() to an ${node.type.name} always results in 0") } } } super.visitField(node) } @Override void visitMethodEx(MethodNode node) { if (isFirstVisit(node)) { if (node.returnType.name in ['int', 'Integer']) { node.code?.visit(new MathRandomTracker(callbackFunction: { addViolation(it, "Returning the result of Math.random() from an ${node.returnType.name}-returning method always returns 0") })) } if (node.returnType.name in ['long', 'Long']) { node.code?.visit(new MathRandomTracker(callbackFunction: { addViolation(it, "Returning the result of Math.random() from a ${node.returnType.name}-returning method always returns 0") })) } } } } class MathRandomTracker extends AbstractAstVisitor { def callbackFunction void visitReturnStatement(ReturnStatement statement) { callBackForMathRandomReturns(statement.expression) super.visitReturnStatement(statement) } private callBackForMathRandomReturns(Expression exp) { def stack = [exp] as Stack while (stack) { def expression = stack.pop() if (AstUtil.isMethodCall(expression, 'Math', 'random', 0)) { callbackFunction(expression) } else if (expression instanceof TernaryExpression) { stack.push(expression.trueExpression) stack.push(expression.falseExpression) } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptySwitchStatementRule.groovy0000644000175000017500000000265312311373552030355 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.SwitchStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that checks for empty switch statements * * @author Chris Mair */ class EmptySwitchStatementRule extends AbstractAstVisitorRule { String name = 'EmptySwitchStatement' int priority = 2 Class astVisitorClass = EmptySwitchStatementAstVisitor } class EmptySwitchStatementAstVisitor extends AbstractAstVisitor { void visitSwitch(SwitchStatement switchStatement) { if (isFirstVisit(switchStatement) && switchStatement.caseStatements.empty) { addViolation(switchStatement, 'The switch statement is empty') } super.visitSwitch(switchStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ClassForNameRule.groovy0000644000175000017500000000330612006632016026513 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * Using Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time. * * @author 'Hamlet D'Arcy' */ class ClassForNameRule extends AbstractAstVisitorRule { String name = 'ClassForName' int priority = 2 Class astVisitorClass = ClassForNameAstVisitor } class ClassForNameAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression node) { if (AstUtil.isMethodCall(node, 'Class', 'forName', 1) || AstUtil.isMethodCall(node, 'Class', 'forName', 3)) { addViolation(node, 'Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)') } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/BrokenNullCheckRule.groovy0000644000175000017500000001163212041642016027210 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.basic import static org.codenarc.util.AstUtil.isNull import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.expr.* /** * Looks for faulty checks for null in boolean conditions, e.g. * if (name != null || name.length > 0) { } * if (name != null || name.size() > 0) { } * if (string == null && string.equals("")) { } * * @author Chris Mair */ class BrokenNullCheckRule extends AbstractAstVisitorRule { String name = 'BrokenNullCheck' int priority = 2 Class astVisitorClass = BrokenNullCheckAstVisitor } class BrokenNullCheckAstVisitor extends AbstractAstVisitor { @Override void visitBinaryExpression(BinaryExpression expression) { if (isFirstVisit(expression)) { if (expression.leftExpression instanceof BinaryExpression) { if (isBrokenNullCheck(expression, '||', '!=') || isBrokenNullCheck(expression, '&&', '==')) { addViolation(expression, "The expression ${expression.text} within class $currentClassName incorrectly checks for null, and can throw a NullPointerException.") } } } super.visitBinaryExpression(expression) } private boolean isBrokenNullCheck(BinaryExpression expression, String andOrOperator, String comparisonWithNullOperator) { if (expression.operation.text == andOrOperator) { def leftBinary = expression.leftExpression def rightBinary = expression.rightExpression if (isComparisonWithNull(leftBinary, comparisonWithNullOperator)) { def varName = leftBinary.leftExpression.name if (isExpressionAccessingMemberNamed(rightBinary, varName)) { return true } } } return false } private boolean isExpressionAccessingMemberNamed(Expression rightBinary, varName) { return isPropertyAccessForName(rightBinary, varName) || isMethodCallOnName(rightBinary, varName) } private boolean isComparisonWithNull(BinaryExpression expression, String operation) { return expression.leftExpression instanceof VariableExpression && expression.operation.text == operation && isNull(expression.rightExpression) } private boolean isPropertyAccessForName(Expression expression, String varName) { boolean isDirectPropertyAccess = expression instanceof PropertyExpression && expression.objectExpression instanceof VariableExpression && expression.objectExpression.name == varName return isDirectPropertyAccess || isBinaryExpressionWithPropertyAccessForName(expression, varName) || isNotExpressionWithPropertyAccessForName(expression, varName) } private boolean isBinaryExpressionWithPropertyAccessForName(Expression expression, String varName) { return expression instanceof BinaryExpression && isPropertyAccessForName(expression.leftExpression, varName) } private boolean isNotExpressionWithPropertyAccessForName(Expression expression, String varName) { return expression instanceof NotExpression && isPropertyAccessForName(expression.expression, varName) } private boolean isMethodCallOnName(Expression expression, String varName) { boolean isDirectMethodCall = expression instanceof MethodCallExpression && expression.objectExpression instanceof VariableExpression && expression.objectExpression.name == varName return isDirectMethodCall || isBinaryExpressionWithMethodCallOnName(expression, varName) || isNotExpressionWithMethodCallOnName(expression, varName) } private boolean isBinaryExpressionWithMethodCallOnName(Expression expression, String varName) { return expression instanceof BinaryExpression && isMethodCallOnName(expression.leftExpression, varName) } private boolean isNotExpressionWithMethodCallOnName(Expression expression, String varName) { return expression instanceof NotExpression && isMethodCallOnName(expression.expression, varName) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/DuplicateSetValueRule.groovy0000644000175000017500000000526412311370173027570 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.expr.CastExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.ListExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule /** * A Set literal is created with duplicate constant value. A set cannot contain two elements with the same value. * * @author Hamlet D'Arcy */ class DuplicateSetValueRule extends AbstractAstVisitorRule { String name = 'DuplicateSetValue' int priority = 2 Class astVisitorClass = DuplicateSetValueAstVisitor } class DuplicateSetValueAstVisitor extends AbstractAstVisitor { @Override void visitCastExpression(CastExpression expression) { if (isSetLiteral(expression)) { expression.expression.expressions?.inject([]) { acc, value -> if (isDuplicate(value, acc)) { addViolationForDuplicate(value) } acc } } super.visitCastExpression(expression) } private static boolean isDuplicate(ASTNode expression, previousValues) { if ((expression instanceof ConstantExpression)) { if (previousValues.contains(expression.value)) { return true } previousValues.add(expression.value) } false } private addViolationForDuplicate(ConstantExpression constant) { if (constant.value == null) { addViolation(constant, 'The constant value null is duplicated in the Set literal') } else if (constant.value instanceof String) { addViolation(constant, "The constant value '$constant.value' is duplicated in the Set literal") } else { addViolation(constant, "The constant value $constant.value is duplicated in the Set literal") } } private static boolean isSetLiteral(CastExpression expression) { return expression.type?.name?.endsWith('Set') && expression.expression instanceof ListExpression } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ThrowExceptionFromFinallyRule.groovy0000644000175000017500000000277712311373552031344 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.ThrowStatement import org.codenarc.rule.AbstractAstVisitorRule /** * Rule that checks for throwing an exception from within a finally block * * @author Chris Mair */ class ThrowExceptionFromFinallyBlockRule extends AbstractAstVisitorRule { String name = 'ThrowExceptionFromFinallyBlock' int priority = 2 Class astVisitorClass = ThrowExceptionFromFinallyBlockAstVisitor } class ThrowExceptionFromFinallyBlockAstVisitor extends AbstractFinallyAstVisitor { void visitThrowStatement(ThrowStatement throwStatement) { if (isFirstVisit(throwStatement) && isStatementWithinFinally(throwStatement)) { addViolation(throwStatement, 'Throwing an exception from a finally block can hide an underlying error') } super.visitThrowStatement(throwStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ConstantAssertExpressionRule.groovy0000644000175000017500000000442512311373552031242 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.AssertStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for assert statements where the assert condition expressions is a constant value or literal value, such as: *
    *
  • assert true
  • *
  • assert false
  • *
  • assert Boolean.TRUE
  • *
  • assert Boolean.FALSE
  • *
  • assert null
  • *
  • assert 0
  • *
  • assert 99.7
  • *
  • assert ""
  • *
  • assert "abc"
  • *
  • assert [:]
  • *
  • assert [a:123, b:456]
  • *
  • assert [a, b, c]
  • *
* * @author Chris Mair */ class ConstantAssertExpressionRule extends AbstractAstVisitorRule { String name = 'ConstantAssertExpression' int priority = 3 Class astVisitorClass = ConstantAssertExpressionAstVisitor } class ConstantAssertExpressionAstVisitor extends AbstractAstVisitor { @Override void visitAssertStatement(AssertStatement statement) { if (isFirstVisit(statement)) { def booleanExpression = statement.booleanExpression if (AstUtil.isConstantOrLiteral(booleanExpression.expression)) { addViolation(statement, "The assert statement within class $currentClassName has a constant boolean expression [$booleanExpression.text]") } } super.visitAssertStatement(statement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/BitwiseOperatorInConditionalRule.groovy0000644000175000017500000000647712006632014032005 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ElvisOperatorExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.TernaryExpression import org.codehaus.groovy.ast.stmt.IfStatement import org.codehaus.groovy.ast.stmt.WhileStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Checks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable. * * @author Jeff Beck */ class BitwiseOperatorInConditionalRule extends AbstractAstVisitorRule { String name = 'BitwiseOperatorInConditional' int priority = 2 Class astVisitorClass = BitwiseOperatorInConditionalAstVisitor } class BitwiseOperatorInConditionalAstVisitor extends AbstractAstVisitor { private addViolationBitwiseConditional(Expression expression) { if (!isFirstVisit(expression)) { return } def parms = [expression] as Stack while (parms) { def node = parms.pop() if (node instanceof BinaryExpression) { if (AstUtil.isBinaryExpressionType(node, '|')) { addViolation(node, 'Use of a bitwise or (|) operator in a conditional') } else if (AstUtil.isBinaryExpressionType(node, '&')) { addViolation(node, 'Use of a bitwise and (&) operator in a conditional') } else { parms.addAll(collectChildren(node)) } } } } private collectChildren(BinaryExpression node) { def results = [] if (node.leftExpression instanceof BinaryExpression) { results.add(node.leftExpression) } if (node.rightExpression instanceof BinaryExpression) { results.add(node.rightExpression) } results } @Override void visitIfElse(IfStatement node) { addViolationBitwiseConditional(node.booleanExpression.expression) super.visitIfElse(node) } @Override void visitWhileLoop(WhileStatement node) { addViolationBitwiseConditional(node.booleanExpression.expression) super.visitWhileLoop(node) } @Override void visitTernaryExpression(TernaryExpression node) { addViolationBitwiseConditional(node.booleanExpression.expression) super.visitTernaryExpression(node) } @Override void visitShortTernaryExpression(ElvisOperatorExpression node) { addViolationBitwiseConditional(node.booleanExpression.expression) super.visitShortTernaryExpression(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyMethodRule.groovy0000644000175000017500000000325612052037512026442 0ustar ebourgebourg/*AbstractMethodVisitor * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.MethodNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodVisitor import org.codenarc.util.AstUtil import java.lang.reflect.Modifier /** * A method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation. * * @author Hamlet D'Arcy */ class EmptyMethodRule extends AbstractAstVisitorRule { String name = 'EmptyMethod' int priority = 2 Class astVisitorClass = EmptyMethodAstVisitor } class EmptyMethodAstVisitor extends AbstractMethodVisitor { @Override void visitMethod(MethodNode node) { if (AstUtil.isEmptyBlock(node.code) && !Modifier.isAbstract(node.declaringClass.modifiers)) { if (!node.annotations.find { it?.classNode?.name == 'Override' }) { addViolation(node, "The method $node.name is both empty and not marked with @Override") } } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/BooleanGetBooleanRule.groovy0000644000175000017500000000334312006632014027514 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractMethodCallExpressionVisitor import org.codenarc.util.AstUtil /** * This rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. * It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API * to use; replace it with System.properties['prop̈́']. * * @author Hamlet D'Arcy */ class BooleanGetBooleanRule extends AbstractAstVisitorRule { String name = 'BooleanGetBoolean' int priority = 2 Class astVisitorClass = BooleanGetBooleanAstVisitor } class BooleanGetBooleanAstVisitor extends AbstractMethodCallExpressionVisitor { @Override void visitMethodCallExpression(MethodCallExpression call) { if (AstUtil.isMethodCall(call, 'Boolean', 'getBoolean', 1)) { addViolation(call, 'Boolean.getBoolean(String) is a confusing API for reading System properties. Prefer the System.getProperty(String) API.') } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ComparisonWithSelfRule.groovy0000644000175000017500000000513512006632014027756 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.VariableExpression import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * CodeNarc Rule. Checks for using a comparison operator or equals() or compareTo() to compare a * variable to itself, e.g.: * x == x, x != x, x <=> x, * x < x, x > x, x <= x, x >= x, * x.equals(x), x.compareTo(x) * where x is a variable * * @author Chris Mair */ class ComparisonWithSelfRule extends AbstractAstVisitorRule { String name = 'ComparisonWithSelf' int priority = 2 Class astVisitorClass = ComparisonWithSelfAstVisitor } class ComparisonWithSelfAstVisitor extends AbstractAstVisitor { @Override void visitBinaryExpression(BinaryExpression expression) { if (isFirstVisit(expression) && AstUtil.isBinaryExpressionType(expression, AstUtil.COMPARISON_OPERATORS)) { def left = expression.leftExpression def right = expression.rightExpression addViolationIfBothAreTheSameVariable(expression, left, right) } super.visitBinaryExpression(expression) } @Override void visitMethodCallExpression(MethodCallExpression call) { if (isFirstVisit(call) && (AstUtil.isMethodCall(call, 'equals', 1) || AstUtil.isMethodCall(call, 'compareTo', 1))) { def left = call.objectExpression def right = call.arguments.getExpression(0) addViolationIfBothAreTheSameVariable(call, left, right) } super.visitMethodCallExpression(call) } private void addViolationIfBothAreTheSameVariable(node, left, right) { if (left instanceof VariableExpression && right instanceof VariableExpression && left.name == right.name) { addViolation(node, "Comparing an object to itself is useless and may indicate a bug: ${node.text}") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/ConstantIfExpressionRule.groovy0000644000175000017500000000424512311373552030337 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.IfStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for if statement with a constant value for the if expression, such as: *
    *
  • if (true) { .. }
  • *
  • if (false) { .. }
  • *
  • if (Boolean.TRUE) { .. }
  • *
  • if (Boolean.FALSE) { .. }
  • *
  • if (null) { .. }
  • *
  • if (0) { .. }
  • *
  • if (99.7) { .. }
  • *
  • if ("") { .. }
  • *
  • if ("abc") { .. }
  • *
  • if ([a:123, b:456]) { .. }
  • *
  • if ([a, b]) { .. }
  • *
* * @author Chris Mair */ class ConstantIfExpressionRule extends AbstractAstVisitorRule { String name = 'ConstantIfExpression' int priority = 2 Class astVisitorClass = ConstantIfExpressionAstVisitor } class ConstantIfExpressionAstVisitor extends AbstractAstVisitor { void visitIfElse(IfStatement ifStatement) { if (isFirstVisit(ifStatement)) { def booleanExpression = ifStatement.booleanExpression if (AstUtil.isConstantOrLiteral(booleanExpression.expression)) { addViolation(ifStatement, "The if statement condition ($booleanExpression.text) contains a constant") } } super.visitIfElse(ifStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/basic/EmptyFinallyBlockRule.groovy0000644000175000017500000000277612311373552027606 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codehaus.groovy.ast.stmt.TryCatchStatement import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.AstUtil /** * Rule that checks for empty finally blocks * * @author Chris Mair */ class EmptyFinallyBlockRule extends AbstractAstVisitorRule { String name = 'EmptyFinallyBlock' int priority = 2 Class astVisitorClass = EmptyFinallyBlockAstVisitor } class EmptyFinallyBlockAstVisitor extends AbstractAstVisitor { void visitTryCatchFinally(TryCatchStatement tryCatchStatement) { if (isFirstVisit(tryCatchStatement) && AstUtil.isEmptyBlock(tryCatchStatement.finallyStatement)) { addViolation(tryCatchStatement.finallyStatement, 'The finally block is empty') } super.visitTryCatchFinally(tryCatchStatement) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/0000755000175000017500000000000012623571301022434 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/IllegalPackageReferenceRule.groovy0000644000175000017500000001336112311370173031201 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.generic import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.ModuleNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.ImportUtil import org.codenarc.util.WildcardPattern import org.codehaus.groovy.ast.expr.* /** * Checks for reference to any of the named packages. *

* The packageNames property specifies the comma-separated list of package names to check for. * The package name(s) may optionally include wildcard characters ('*' or '?'). Note that the '*' wildcard * matches any sequence of zero or more characters in the package name, e.g. 'a.*' matches 'a.b' as well as * 'a.b.c.d'. If packageNames is null or empty, do nothing. * * Known limitation: Does not catch references as Anonymous Inner class: def x = new org.bad.Handler() { .. } * * @author Chris Mair */ class IllegalPackageReferenceRule extends AbstractAstVisitorRule { String name = 'IllegalPackageReference' int priority = 2 String packageNames = null Class astVisitorClass = IllegalPackageReferenceAstVisitor boolean isReady() { packageNames } } class IllegalPackageReferenceAstVisitor extends AbstractAstVisitor { private wildcard @Override protected void visitClassEx(ClassNode node) { wildcard = new WildcardPattern(rule.packageNames) def superClassName = node.superClass.name if (superClassName != 'java.lang.Object') { checkType(superClassName, node) } node.interfaces.each { interfaceNode -> checkType(interfaceNode.name, node) } super.visitClassEx(node) } @Override void visitField(FieldNode node) { checkTypeIfNotDynamicallyTyped(node) } @Override void visitConstructorCallExpression(ConstructorCallExpression node) { if (isFirstVisit(node) && !node.superCall) { checkType(node.type.name, node) } super.visitConstructorCallExpression(node) } @Override void visitVariableExpression(VariableExpression expression) { checkTypeIfNotDynamicallyTyped(expression) super.visitVariableExpression(expression) } @Override void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { if (!node.isDynamicReturnType()) { // ignore 'def' which resolves to java.lang.Object checkType(node.returnType.name, node) } node.parameters.each { parameter -> checkTypeIfNotDynamicallyTyped(parameter) } super.visitConstructorOrMethod(node, isConstructor) } @Override void visitClosureExpression(ClosureExpression expression) { expression.parameters.each { parameter -> checkTypeIfNotDynamicallyTyped(parameter) } super.visitClosureExpression(expression) } @Override void visitCastExpression(CastExpression expression) { checkType(expression.type.name, expression) super.visitCastExpression(expression) } @Override void visitClassExpression(ClassExpression expression) { checkType(expression.type.name, expression) super.visitClassExpression(expression) } @Override void visitPropertyExpression(PropertyExpression expression) { checkType(expression.text, expression) } @Override void visitImports(ModuleNode node) { def allImports = node.imports + node.starImports + node.staticImports.values() + node.staticStarImports.values() allImports?.each { importNode -> def parentPackage = ImportUtil.packageNameForImport(importNode) if (wildcard.matches(parentPackage)) { addViolation(rule.createViolationForImport(sourceCode, importNode, "Found reference to illegal package name $parentPackage")) } } super.visitImports(node) } //-------------------------------------------------------------------------- // Helper Methods //-------------------------------------------------------------------------- private void checkTypeIfNotDynamicallyTyped(node) { if (!node.isDynamicTyped()) { // ignore 'def' which resolves to java.lang.Object checkType(node.type.name, node) } } private void checkType(String typeName, node) { def parentPackage = parentPackageName(typeName) checkPackageName(parentPackage, node) } private void checkPackageName(String parentPackage, node) { if (wildcard.matches(parentPackage)) { addViolation(node, "Found reference to illegal package name $parentPackage") } } private String parentPackageName(String typeName) { if (typeName.contains('.')) { def lastPeriod = typeName.lastIndexOf('.') return typeName[0..lastPeriod - 1] } null } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/IllegalRegexRule.groovy0000644000175000017500000000337712311373552027113 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Checks for a specified illegal regular expression within the source code. *

* The regex property specifies the regular expression to check for. If null or empty, do nothing. *

* A RuleSet can contain any number of instances of this rule, but each should be configured * with a unique rule name, regex, violationMessage and (optionally) customized priority. * * @author Chris Mair */ class IllegalRegexRule extends AbstractRule { String name = 'IllegalRegex' int priority = 3 String regex boolean isReady() { regex } void applyTo(SourceCode sourceCode, List violations) { def matcher = sourceCode.getText() =~ regex while (matcher.find()) { def lineNumber = sourceCode.getLineNumberForCharacterIndex(matcher.start()) violations.add(new Violation(rule:this, lineNumber:lineNumber, sourceLine:matcher.group(), message:"Match found for illegal regular expression \"$regex\"")) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/RequiredStringRule.groovy0000644000175000017500000000315112311373552027504 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Checks for a specified String that must exist within the source code. *

* The string property specifies the String of text to check for. If null or empty, do nothing. *

* A RuleSet can contain any number of instances of this rule, but each should be configured * with a unique rule name, string, violationMessage and (optionally) customized priority. * * @author Chris Mair */ class RequiredStringRule extends AbstractRule { String name = 'RequiredString' int priority = 3 String string boolean isReady() { string } void applyTo(SourceCode sourceCode, List violations) { if (!(sourceCode.getText().contains(string))) { violations.add(new Violation(rule:this, message:"Match not found for required string [$string]")) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/IllegalClassMemberRule.groovy0000644000175000017500000001604712311373552030234 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.generic import static org.codenarc.util.ModifiersUtil.matchesAnyModifiers import static org.codenarc.util.ModifiersUtil.parseModifiersList import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.FieldNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.PropertyNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.WildcardPattern /** * Checks for classes containing fields/properties/methods matching configured illegal member modifiers. * * @author Chris Mair */ class IllegalClassMemberRule extends AbstractAstVisitorRule { String name = 'IllegalClassMember' int priority = 2 Class astVisitorClass = IllegalClassMemberAstVisitor String ignoreMethodNames String ignoreMethodsWithAnnotationNames protected Collection illegalFieldModifiersList = [] protected String illegalFieldModifiersString protected Collection allowedFieldModifiersList = [] protected String allowedFieldModifiersString protected Collection illegalPropertyModifiersList = [] protected String illegalPropertyModifiersString protected Collection allowedPropertyModifiersList = [] protected String allowedPropertyModifiersString protected Collection illegalMethodModifiersList = [] protected String illegalMethodModifiersString protected Collection allowedMethodModifiersList = [] protected String allowedMethodModifiersString void setIllegalFieldModifiers(String illegalFieldModifiers) { this.illegalFieldModifiersString = illegalFieldModifiers this.illegalFieldModifiersList = parseModifiersList(illegalFieldModifiers) } void setAllowedFieldModifiers(String allowedFieldModifiers) { this.allowedFieldModifiersString = allowedFieldModifiers this.allowedFieldModifiersList = parseModifiersList(allowedFieldModifiers) } void setIllegalPropertyModifiers(String illegalPropertyModifiers) { this.illegalPropertyModifiersString = illegalPropertyModifiers this.illegalPropertyModifiersList = parseModifiersList(illegalPropertyModifiers) } void setAllowedPropertyModifiers(String allowedPropertyModifiers) { this.allowedPropertyModifiersString = allowedPropertyModifiers this.allowedPropertyModifiersList = parseModifiersList(allowedPropertyModifiers) } void setIllegalMethodModifiers(String illegalMethodModifiers) { this.illegalMethodModifiersString = illegalMethodModifiers this.illegalMethodModifiersList = parseModifiersList(illegalMethodModifiers) } void setAllowedMethodModifiers(String allowedMethodModifiers) { this.allowedMethodModifiersString = allowedMethodModifiers this.allowedMethodModifiersList = parseModifiersList(allowedMethodModifiers) } @Override boolean isReady() { (illegalFieldModifiersList || allowedFieldModifiersList || illegalMethodModifiersList || allowedMethodModifiersList || illegalPropertyModifiersList || allowedPropertyModifiersList) && (applyToClassNames || applyToFileNames || applyToFilesMatching) } } class IllegalClassMemberAstVisitor extends AbstractAstVisitor { @Override void visitField(FieldNode node) { boolean matchesIllegal = matchesAnyModifiers(node.modifiers, rule.illegalFieldModifiersList) if (matchesIllegal) { addViolation(node, "Field \"${node.name}\" has modifiers matching one of the configured illegalFieldModifiers: \"${rule.illegalFieldModifiersString}\"") } if (rule.allowedFieldModifiersList) { boolean matchesAllowed = matchesAnyModifiers(node.modifiers, rule.allowedFieldModifiersList) if (!matchesAllowed) { addViolation(node, "Field \"${node.name}\" does not have modifiers matching one of the configured allowedFieldModifiers: \"${rule.allowedFieldModifiersString}\"") } } super.visitField(node) } @Override void visitProperty(PropertyNode node) { boolean matchesIllegal = matchesAnyModifiers(node.modifiers, rule.illegalPropertyModifiersList) if (matchesIllegal) { addViolation(node, "Property \"${node.name}\" has modifiers matching one of the configured illegalPropertyModifiers: \"${rule.illegalPropertyModifiersString}\"") } if (rule.allowedPropertyModifiersList) { boolean matchesAllowed = matchesAnyModifiers(node.modifiers, rule.allowedPropertyModifiersList) if (!matchesAllowed) { addViolation(node, "Property \"${node.name}\" does not have modifiers matching one of the configured allowedPropertyModifiers: \"${rule.allowedPropertyModifiersString}\"") } } super.visitProperty(node) } @Override protected void visitMethodEx(MethodNode node) { boolean matchesIllegal = matchesAnyModifiers(node.modifiers, rule.illegalMethodModifiersList) if (matchesIllegal && !matchesIgnoreMethodNames(node) && !matchesIgnoreMethodsWithAnnotationNames(node)) { addViolation(node, "Method \"${node.name}\" has modifiers matching one of the configured illegalMethodModifiers: \"${rule.illegalMethodModifiersString}\"") } if (rule.allowedMethodModifiersList) { boolean matchesAllowed = matchesAnyModifiers(node.modifiers, rule.allowedMethodModifiersList) if (!matchesAllowed && !matchesIgnoreMethodNames(node) && !matchesIgnoreMethodsWithAnnotationNames(node)) { addViolation(node, "Method \"${node.name}\" does not have modifiers matching one of the configured allowedMethodModifiers: \"${rule.allowedMethodModifiersString}\"") } } } private boolean matchesIgnoreMethodNames(MethodNode methodNode) { return new WildcardPattern(rule.ignoreMethodNames, false).matches(methodNode.name) } private boolean matchesIgnoreMethodsWithAnnotationNames(MethodNode methodNode) { def wildcardPattern = new WildcardPattern(rule.ignoreMethodsWithAnnotationNames, false) List annotations = methodNode.getAnnotations() for (AnnotationNode annotation : annotations) { def annotationName = annotation.getClassNode().getName() if (wildcardPattern.matches(annotationName)) { return true } } return false } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/StatelessClassRule.groovy0000644000175000017500000001264612311373552027503 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.generic import static org.codenarc.util.AstUtil.hasAnnotation import org.codehaus.groovy.ast.FieldNode import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AbstractFieldVisitor import org.codenarc.util.WildcardPattern /** * Rule that checks for non-final fields on a class. The intent of this rule is * to check a configured set of classes that should remain "stateless" and reentrant. One * example might be Grails service classes, which are, by default, a singleton, and so they * should be reentrant. DAO classes are also often kept stateless. *

* This rule ignores final fields (either instance or static). Fields that are * static and non-final, however, do cause a violation. *

* This rule also ignores all classes annotated with the @Immutable transformation. * See http://groovy.codehaus.org/Immutable+transformation. *

* This rule also ignores fields annotated with the @Inject annotation. *

* You can configure this rule to ignore certain fields either by name or by type. This can be * useful to ignore fields that hold references to (static) dependencies (such as DAOs or * Service objects) or static configuration. *

* The ignoreFieldNames property specifies one or more (comma-separated) field names * that should be ignored (i.e., that should not cause a rule violation). The name(s) may optionally * include wildcard characters ('*' or '?'). You can add to the field names to be ignored by setting * the (write-only) addIgnoreFieldNames property. This is a "special" property -- each * call to setAddIgnoreFieldNames() adds to the existing ignoreFieldNames * property value. *

* The ignoreFieldTypes property specifies one or more (comma-separated) field type names * that should be ignored (i.e., that should not cause a rule violation). The type name(s) may optionally * include wildcard characters ('*' or '?'). *

* Note: The ignoreFieldTypes property matches the field type name as indicated * in the field declaration, only including a full package specification IF it is included in * the source code. For example, the field declaration BigDecimal value matches * an ignoreFieldTypes value of BigDecimal, but not * java.lang.BigDecimal. *

* There is one exception for the ignoreFieldTypes property: if the field is declared * with a modifier/type of def, then the type resolves to java.lang.Object. * * @author Chris Mair * @author Hamlet D'Arcy */ class StatelessClassRule extends AbstractAstVisitorRule { String name = 'StatelessClass' int priority = 2 String ignoreFieldNames String ignoreFieldTypes Class astVisitorClass = StatelessClassAstVisitor boolean isReady() { applyToClassNames || applyToFileNames || applyToFilesMatching } /** * Add more field names to the existing ignoreFieldNames property value. * @param moreFieldNames - specifies one or more (comma-separated) field names that should be * ignored (i.e., that should not cause a rule violation). The name(s) may optionally * include wildcard characters ('*' or '?'). Any names specified here are joined to * the existing ignoreFieldNames property value. */ void setAddToIgnoreFieldNames(String moreFieldNames) { this.ignoreFieldNames = this.ignoreFieldNames ? this.ignoreFieldNames + ',' + moreFieldNames : moreFieldNames } /** * Subclasses can optionally override to provide more specific filtering of fields */ protected boolean shouldIgnoreField(FieldNode fieldNode) { return hasAnnotation(fieldNode.owner, 'Immutable') || hasAnnotation(fieldNode, 'Inject') || fieldNode.isFinal() || matchesIgnoreFieldNames(fieldNode) || matchesIgnoreFieldTypes(fieldNode) } private boolean matchesIgnoreFieldNames(FieldNode fieldNode) { ignoreFieldNames && new WildcardPattern(ignoreFieldNames).matches(fieldNode.name) } private boolean matchesIgnoreFieldTypes(FieldNode fieldNode) { ignoreFieldTypes && new WildcardPattern(ignoreFieldTypes).matches(fieldNode.type.name) } } class StatelessClassAstVisitor extends AbstractFieldVisitor { void visitField(FieldNode fieldNode) { boolean ignore = rule.shouldIgnoreField(fieldNode) if (!ignore) { addViolation(fieldNode, "The class is marked as stateless but contains the non-final field '$fieldNode.name'") } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/RequiredRegexRule.groovy0000644000175000017500000000311212311373552027305 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Checks for a specified regular expression that must exist within the source code. *

* The regex property specifies the regular expression to check for. If null or empty, do nothing. *

* A RuleSet can contain any number of instances of this rule, but each should be configured * with a unique rule name, regex, violationMessage and (optionally) customized priority. * * @author Chris Mair */ class RequiredRegexRule extends AbstractRule { String name = 'RequiredRegex' int priority = 3 String regex boolean isReady() { regex } void applyTo(SourceCode sourceCode, List violations) { if (!(sourceCode.getText() =~ regex)) { violations.add(new Violation(rule:this, message:"Match not found for required regular expression \"$regex\"")) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/IllegalSubclassRule.groovy0000644000175000017500000000316212322755034027611 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.rule.generic import org.codehaus.groovy.ast.ClassNode import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.util.WildcardPattern /** * Checks for classes that extend one of the specified set of illegal superclasses. * * @author Chris Mair */ class IllegalSubclassRule extends AbstractAstVisitorRule { String name = 'IllegalSubclass' int priority = 2 Class astVisitorClass = IllegalSubclassAstVisitor String superclassNames boolean isReady() { superclassNames } } class IllegalSubclassAstVisitor extends AbstractAstVisitor { @Override protected void visitClassEx(ClassNode node) { def wildcard = new WildcardPattern(rule.superclassNames) def superclassName = node.superClass?.name if (wildcard.matches(superclassName)) { addViolation(node, "The class $node.name extends from the illegal superclass $superclassName") } super.visitClassEx(node) } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/IllegalStringRule.groovy0000644000175000017500000000305012311373552027273 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRule import org.codenarc.rule.Violation import org.codenarc.source.SourceCode /** * Checks for a specified illegal string within the source code. *

* The string property specifies the String of text to check for. If null or empty, do nothing. *

* A RuleSet can contain any number of instances of this rule, but each should be configured * with a unique rule name, string, violationMessage and (optionally) customized priority. * * @author Chris Mair */ class IllegalStringRule extends AbstractRule { String name = 'IllegalString' int priority = 2 String string boolean isReady() { string } void applyTo(SourceCode sourceCode, List violations) { if (sourceCode.getText().contains(string)) { violations.add(new Violation(rule:this, message:"Match found for illegal string [$string]")) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/rule/generic/IllegalClassReferenceRule.groovy0000644000175000017500000000333612006632012030706 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractAstVisitorRule import org.codenarc.rule.AstVisitor import org.codenarc.rule.ClassReferenceAstVisitor /** * Checks for reference to any of the named classes. *

* The classNames property specifies the comma-separated list of (fully-qualified) class names to check for. * The class name(s) may optionally include wildcard characters ('*' or '?'). Note that the '*' wildcard * matches any sequence of zero or more characters in the class/package name, e.g. 'a.*.MyClass' matches * 'a.b.MyClass' as well as 'a.b.c.d.MyClass'. If classNames is null or empty, do nothing. * * Known limitation: Does not catch references as Anonymous Inner class: def x = new org.bad.Handler() { .. } * * @author Chris Mair */ class IllegalClassReferenceRule extends AbstractAstVisitorRule { String name = 'IllegalClassReference' int priority = 2 String classNames = null @Override AstVisitor getAstVisitor() { new ClassReferenceAstVisitor(classNames) } @Override boolean isReady() { classNames } } CodeNarc-0.23/src/main/groovy/org/codenarc/report/0000755000175000017500000000000012623571301021364 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/report/AbstractReportWriter.groovy0000644000175000017500000001430112311373554026772 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.report import groovy.text.SimpleTemplateEngine import org.apache.log4j.Logger import org.codenarc.AnalysisContext import org.codenarc.results.Results import org.codenarc.rule.Rule import org.codenarc.util.AstUtil import org.codenarc.util.io.ClassPathResource /** * Abstract superclass for ReportWriter implementation classes. *

* Subclasses must implement the writeReport(ResultsNode, MetricSet, Writer) method * and define a defaultOutputFile property. * * @author Chris Mair */ abstract class AbstractReportWriter implements ReportWriter { protected static final BASE_MESSAGES_BUNDLE = 'codenarc-base-messages' protected static final CUSTOM_MESSAGES_BUNDLE = 'codenarc-messages' protected static final VERSION_FILE = 'codenarc-version.txt' protected static final CODENARC_URL = 'http://www.codenarc.org' String outputFile Object writeToStandardOut private static final LOG = Logger.getLogger(AbstractReportWriter) protected getTimestamp = { new Date() } protected customMessagesBundleName = CUSTOM_MESSAGES_BUNDLE protected resourceBundle private final templateEngine = new SimpleTemplateEngine() // Allow tests to override this protected initializeResourceBundle = { initializeDefaultResourceBundle() } abstract void writeReport(Writer writer, AnalysisContext analysisContext, Results results) /** * Write out a report for the specified analysis results * @param analysisContext - the AnalysisContext containing the analysis configuration information * @param results - the analysis results */ void writeReport(AnalysisContext analysisContext, Results results) { assert analysisContext assert results if (isWriteToStandardOut()) { writeReportToStandardOut(analysisContext, results) } else { writeReportToFile(analysisContext, results) } } private void writeReportToStandardOut(AnalysisContext analysisContext, Results results) { def writer = new OutputStreamWriter(System.out) writeReport(writer, analysisContext, results) } private void writeReportToFile(AnalysisContext analysisContext, Results results) { def outputFilename = outputFile ?: getProperty('defaultOutputFile') def outputFile = new File(outputFilename) outputFile.getParentFile()?.mkdirs() outputFile.withWriter { writer -> writeReport(writer, analysisContext, results) } LOG.info("Report file [$outputFilename] created.") } protected void initializeDefaultResourceBundle() { def baseBundle = ResourceBundle.getBundle(BASE_MESSAGES_BUNDLE) resourceBundle = baseBundle try { resourceBundle = ResourceBundle.getBundle(customMessagesBundleName) LOG.info("Using custom message bundle [$customMessagesBundleName]") resourceBundle.setParent(baseBundle) } catch(MissingResourceException) { LOG.info("No custom message bundle found for [$customMessagesBundleName]. Using default messages.") } } protected String getHtmlDescriptionForRule(Rule rule) { def rawMessageText = getDescriptionProperty(rule) ?: getHtmlRuleDescription(rule) ?: getRuleDescriptionOrDefaultMessage(rule) return substituteMessageParametersIfPresent(rule, rawMessageText) } protected String getDescriptionForRule(Rule rule) { def rawMessageText = getDescriptionProperty(rule) ?: getRuleDescriptionOrDefaultMessage(rule) return substituteMessageParametersIfPresent(rule, rawMessageText) } private String substituteMessageParametersIfPresent(Rule rule, String rawMessageText) { if (rawMessageText.contains('${')) { def template = templateEngine.createTemplate(rawMessageText) def binding = [rule:rule] return template.make(binding) } rawMessageText } private String getHtmlRuleDescription(Rule rule) { def resourceKey = rule.name + '.description.html' getResourceBundleString(resourceKey, null, false) } private String getRuleDescriptionOrDefaultMessage(Rule rule) { def resourceKey = rule.name + '.description' getResourceBundleString(resourceKey, "No description provided for rule named [$rule.name]") } private String getDescriptionProperty(Rule rule) { AstUtil.respondsTo(rule, 'getDescription') ? rule.description : null } protected String getResourceBundleString(String resourceKey, String defaultString='?', boolean logWarning=true) { def string = defaultString try { string = resourceBundle.getString(resourceKey) } catch (MissingResourceException e) { if (logWarning) { LOG.warn("No string found for resourceKey=[$resourceKey]") } } string } protected String getFormattedTimestamp() { def dateFormat = java.text.DateFormat.getDateTimeInstance() dateFormat.format(getTimestamp()) } protected List getSortedRules(AnalysisContext analysisContext) { def rules = analysisContext.ruleSet.rules.findAll { rule -> isEnabled(rule) } rules.toList().sort { rule -> rule.name } } protected boolean isEnabled(Rule rule) { (!AstUtil.respondsTo(rule, 'isEnabled') || rule.enabled) } protected String getCodeNarcVersion() { ClassPathResource.getInputStream(VERSION_FILE).text } private boolean isWriteToStandardOut() { writeToStandardOut == true || writeToStandardOut == 'true' } } CodeNarc-0.23/src/main/groovy/org/codenarc/report/XmlReportWriter.groovy0000644000175000017500000001321512451074641025772 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.report import groovy.xml.StreamingMarkupBuilder import org.codenarc.AnalysisContext import org.codenarc.results.FileResults import org.codenarc.results.Results import org.codenarc.rule.Violation import org.codenarc.util.PathUtil /** * ReportWriter that generates an XML report. * * @author Chris Mair */ @SuppressWarnings(['UnnecessaryReturnKeyword', 'FactoryMethodName']) class XmlReportWriter extends AbstractReportWriter { String title String defaultOutputFile = 'CodeNarcXmlReport.xml' void writeReport(Writer writer, AnalysisContext analysisContext, Results results) { assert analysisContext assert results initializeResourceBundle() def builder = new StreamingMarkupBuilder() def xml = builder.bind { mkp.xmlDeclaration() CodeNarc(url:CODENARC_URL, version:getCodeNarcVersion()) { out << buildReportElement() out << buildProjectElement(analysisContext) out << buildPackageElements(results) out << buildRulesElement(analysisContext) } } writer << xml } //-------------------------------------------------------------------------- // Internal Helper Methods //-------------------------------------------------------------------------- protected buildReportElement() { return { Report(timestamp:getFormattedTimestamp()) } } protected buildProjectElement(AnalysisContext analysisContext) { return { Project(title:title) { analysisContext.sourceDirectories.each { sourceDirectory -> SourceDirectory(sourceDirectory) } } } } protected buildPackageElements(results) { return buildPackageElement(results) } protected buildPackageElement(results) { def elementName = isRoot(results) ? 'PackageSummary' : 'Package' return { "$elementName"(buildPackageAttributeMap(results)) { results.children.each { child -> if (child.isFile()) { out << buildFileElement(child) } } } results.children.each { child -> if (!child.isFile()) { out << buildPackageElement(child) } } } } protected Map buildPackageAttributeMap(results) { def attributeMap = [ totalFiles: results.getTotalNumberOfFiles(), filesWithViolations: results.getNumberOfFilesWithViolations(3), priority1:results.getNumberOfViolationsWithPriority(1), priority2:results.getNumberOfViolationsWithPriority(2), priority3:results.getNumberOfViolationsWithPriority(3) ] if (!isRoot(results)) { attributeMap = [path:results.path] + attributeMap } return attributeMap } protected boolean isRoot(results) { results.path == null } protected buildFileElement(FileResults results) { return { def name = PathUtil.getName(results.path) File(name: name) { results.violations.each { violation -> out << buildViolationElement(violation) } } } } protected buildViolationElement(Violation violation) { def rule = violation.rule return { Violation(ruleName:rule.name, priority:rule.priority, lineNumber:violation.lineNumber) { out << buildSourceLineElement(violation) out << buildMessageElement(violation) } } } protected buildSourceLineElement(Violation violation) { return (violation.sourceLine) ? { SourceLine(cdata(removeIllegalCharacters(violation.sourceLine))) } : null } protected buildMessageElement(Violation violation) { return (violation.message) ? { Message(cdata(removeIllegalCharacters(violation.message))) } : null } protected buildRulesElement(AnalysisContext analysisContext) { def sortedRules = getSortedRules(analysisContext) return { Rules { sortedRules.each { rule -> def description = this.getDescriptionForRule(rule) Rule(name:rule.name) { Description(cdata(description)) } } } } } protected cdata(String text) { return { unescaped << '' } } protected String removeIllegalCharacters(String string) { // See http://www.w3.org/TR/xml/#charsets // See http://stackoverflow.com/questions/730133/invalid-characters-in-xml // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] final REGEX = /[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]/ return string.replaceAll(REGEX, '') } } CodeNarc-0.23/src/main/groovy/org/codenarc/report/IdeTextReportWriter.groovy0000644000175000017500000000274512445626230026606 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.report import org.codenarc.rule.Violation import org.codenarc.util.PathUtil /** * ReportWriter that generates an simple ASCII text report, and includes IDE-compatible * (Eclipse, Idea) hyperlinks to source code for violations. * * Set the maxPriority property to control the maximum priority level for violations in * the report. For instance, setting maxPriority to 2 will result in the report containing * only priority 1 and 2 violations (and omitting violations with priority 3). The * maxPriority property defaults to 3. * * @author Chris Mair */ class IdeTextReportWriter extends TextReportWriter { @Override protected String getViolationLocationString(Violation violation, String path) { def fileName = PathUtil.getName(path) return "Loc=.($fileName:${violation.lineNumber})" } } CodeNarc-0.23/src/main/groovy/org/codenarc/report/ReportWriter.groovy0000644000175000017500000000223512311373552025307 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.report import org.codenarc.AnalysisContext import org.codenarc.results.Results /** * Represents the interface of an object that can write out a report * * @author Chris Mair */ interface ReportWriter { /** * Write out a report for the specified analysis results * @param analysisContext - the AnalysisContext containing the analysis configuration information * @param results - the analysis results */ void writeReport(AnalysisContext analysisContext, Results results) } CodeNarc-0.23/src/main/groovy/org/codenarc/report/TextReportWriter.groovy0000644000175000017500000001001512405332375026151 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.report import org.codenarc.AnalysisContext import org.codenarc.results.FileResults import org.codenarc.results.Results import org.codenarc.rule.Violation /** * ReportWriter that generates an simple ASCII text report. * * Set the maxPriority property to control the maximum priority level for violations in * the report. For instance, setting maxPriority to 2 will result in the report containing * only priority 1 and 2 violations (and omitting violations with priority 3). The * maxPriority property defaults to 3. * * @author Chris Mair */ class TextReportWriter extends AbstractReportWriter { String title String defaultOutputFile = 'CodeNarcReport.txt' int maxPriority = 3 @Override void writeReport(Writer writer, AnalysisContext analysisContext, Results results) { initializeResourceBundle() def printWriter = new PrintWriter(writer) writeTitle(printWriter) writeSummary(printWriter, results) writePackageViolations(printWriter, results) writeFooter(printWriter) printWriter.flush() } protected void writeTitle(Writer writer) { def titleString = 'CodeNarc Report' + (title ? ': ' + title : '') + ' - ' + getFormattedTimestamp() writer.println(titleString) } protected void writeSummary(Writer writer, Results results) { def summary = "Summary: TotalFiles=${results.totalNumberOfFiles} " + "FilesWithViolations=${results.getNumberOfFilesWithViolations(maxPriority)}" (1..maxPriority).each { p -> summary += " P$p=${results.getNumberOfViolationsWithPriority(p)}" } writer.println() writer.println(summary) } protected void writePackageViolations(Writer writer, Results results) { results.children.each { child -> if (child.isFile()) { writeFileViolations(writer, child) } else { writePackageViolations(writer, child) } } } protected void writeFileViolations(Writer writer, FileResults results) { if (results.violations.find { v -> v.rule.priority <= maxPriority }) { writer.println() writer.println('File: ' + results.path) def violations = results.violations.findAll { v -> v.rule.priority <= maxPriority } violations.sort { violation -> violation.rule.priority }.each { violation -> writeViolation(writer, violation, results.path) } } } protected void writeViolation(Writer writer, Violation violation, String path) { def rule = violation.rule def locationString = getViolationLocationString(violation, path) def message = violation.message ? " Msg=[${violation.message}]" : '' def sourceLine = violation.sourceLine ? " Src=[${violation.sourceLine}]" : '' writer.println " Violation: Rule=${rule.name} P=${rule.priority} ${locationString}$message$sourceLine" } @SuppressWarnings('UnusedMethodParameter') protected String getViolationLocationString(Violation violation, String path) { return "Line=${violation.lineNumber}" } protected void writeFooter(Writer writer) { writer.println() writer.println("[CodeNarc ($CODENARC_URL) v" + getCodeNarcVersion() + ']') } } CodeNarc-0.23/src/main/groovy/org/codenarc/report/HtmlReportWriter.groovy0000644000175000017500000003470212450013112026123 0ustar ebourgebourg/* * Copyright 2014 the original author or 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 org.codenarc.report import groovy.xml.StreamingMarkupBuilder import org.codenarc.AnalysisContext import org.codenarc.results.Results import org.codenarc.rule.Rule import org.codenarc.rule.Violation import org.codenarc.util.io.ClassPathResource /** * ReportWriter that generates an HTML report. *

* The default localized messages, including rule descriptions, are read from the "codenarc-base-messages" * ResourceBundle. You can override these messages using the normal ResourceBundle mechanisms (i.e. * creating a locale-specific resource bundle file on the classpath, such as "codenarc-base-messages_de"). * You can optionally add rule descriptions for custom rules by placing them within a "codenarc-messages.properties" * file on the classpath, with entries of the form: {rule-name}.description=..." *

* Set the includeSummaryByPackage property to false to exclude the violation summary for each package * within the "Summary" section of the report. It defaults to true. *

* Set the maxPriority property to control the maximum priority level for violations in * the report. For instance, setting maxPriority to 2 will result in the report containing * only priority 1 and 2 violations (and omitting violations with priority 3). The * maxPriority property defaults to 3. * * @author Chris Mair */ @SuppressWarnings(['DuplicateMapLiteral', 'UnnecessaryReturnKeyword', 'FactoryMethodName']) class HtmlReportWriter extends AbstractReportWriter { public static final DEFAULT_OUTPUT_FILE = 'CodeNarcReport.html' private static final CSS_FILE = 'codenarc-htmlreport.css' private static final ROOT_PACKAGE_NAME = '' private static final MAX_SOURCE_LINE_LENGTH = 70 private static final SOURCE_LINE_LAST_SEGMENT_LENGTH = 12 String title String defaultOutputFile = DEFAULT_OUTPUT_FILE boolean includeSummaryByPackage = true int maxPriority = 3 /** * Write out a report to the specified Writer for the analysis results * @param analysisContext - the AnalysisContext containing the analysis configuration information * @param results - the analysis results */ void writeReport(Writer writer, AnalysisContext analysisContext, Results results) { assert analysisContext assert results initializeResourceBundle() def builder = new StreamingMarkupBuilder() def html = builder.bind { html { out << buildHeaderSection() out << buildBodySection(analysisContext, results) } } writer << html } String toString() { "HtmlReportWriter[outputFile=$outputFile, title=$title]" } //-------------------------------------------------------------------------- // Internal Helper Methods //-------------------------------------------------------------------------- private buildCSS() { return { def cssInputStream = ClassPathResource.getInputStream(CSS_FILE) assert cssInputStream, "CSS File [$CSS_FILE] not found" def css = cssInputStream.text style(type: 'text/css') { unescaped << css } } } private buildHeaderSection() { return { head { title(buildTitle()) out << buildCSS() } } } private buildBodySection(AnalysisContext analysisContext, results) { return { body { // TODO: copy the image or inline it in the css out << buildLogo() h1(getResourceBundleString('htmlReport.titlePrefix')) out << buildReportMetadata() out << buildSummaryByPackage(results) out << buildAllPackageSections(results) out << buildRuleDescriptions(analysisContext) } } } private buildReportMetadata() { return { div(class: 'metadata') { table { tr { td(class: 'em', getResourceBundleString('htmlReport.reportTitle.title')) td title } tr { td(class: 'em', getResourceBundleString('htmlReport.reportTimestamp.label')) td getFormattedTimestamp() } tr { td(class: 'em', getResourceBundleString('htmlReport.reportVersion.label')) td { a("CodeNarc v${getCodeNarcVersion()}", href:CODENARC_URL) } } } } } } private buildLogo() { return { img(class: 'logo', src: 'http://codenarc.sourceforge.net/images/codenarc-logo.png', alt: 'CodeNarc', align: 'right') } } private buildSummaryByPackage(results) { return { div(class: 'summary') { h2(getResourceBundleString('htmlReport.summary.title')) table { tr(class:'tableHeader') { th(getResourceBundleString('htmlReport.summary.packageHeading')) th(getResourceBundleString('htmlReport.summary.totalFilesHeading')) th(getResourceBundleString('htmlReport.summary.filesWithViolationsHeading')) (1..maxPriority).each { p -> th(getResourceBundleString("htmlReport.summary.priority${p}Heading")) } } out << buildSummaryByPackageRow(results, true) if (includeSummaryByPackage) { out << buildAllSummaryByPackageRowsRecursively(results) } } } } } private buildAllSummaryByPackageRowsRecursively(results) { return { results.children.each { child -> if (isDirectoryContainingFiles(child)) { out << buildSummaryByPackageRow(child, false) } if (!child.isFile()) { out << buildAllSummaryByPackageRowsRecursively(child) } } } } private buildSummaryByPackageRow(results, boolean allPackages) { def recursive = allPackages return { tr { if (allPackages) { td(getResourceBundleString('htmlReport.summary.allPackages'), class:'allPackages') } else { def pathName = results.path ?: ROOT_PACKAGE_NAME if (isDirectoryContainingFilesWithViolations(results)) { td { a(pathName, href:"#${pathName}") } } else { td(pathName) } } td(results.getTotalNumberOfFiles(recursive), class:'number') td(results.getNumberOfFilesWithViolations(maxPriority, recursive) ?: '-', class:'number') (1..maxPriority).each { p -> td(results.getNumberOfViolationsWithPriority(p, recursive) ?: '-', class:'priority' + p) } } } } private buildAllPackageSections(results) { return { results.children.each { child -> out << buildPackageSection(child) } } } private buildPackageSection(results) { return { def pathName = results.path ?: ROOT_PACKAGE_NAME if (isDirectoryContainingFilesWithViolations(results)) { div(class: 'summary') { a(' ', name: pathName) h2("Package: ${pathName.replaceAll('/', '.')}", class:'packageHeader') } } results.children.each { child -> if (child.isFile() && child.violations.find { v -> v.rule.priority <= maxPriority }) { div(class: 'summary') { h3(class:'fileHeader') { mkp.yieldUnescaped '➥ ' + (child.path - "$pathName/") } out << buildFileSection(child) } } else { out << buildPackageSection(child) } } } } private buildFileSection(results) { assert results.isFile() return { table(border:'1') { tr(class:'tableHeader') { th(getResourceBundleString('htmlReport.violations.ruleName')) th(getResourceBundleString('htmlReport.violations.priority')) th(getResourceBundleString('htmlReport.violations.lineNumber')) th(getResourceBundleString('htmlReport.violations.sourceLine')) } def violations = results.violations.findAll { v -> v.rule.priority <= maxPriority } // def violations = results.violations violations.sort { v -> v.rule.priority } violations.each { Violation violation -> def moreInfo = violation.message ? violation.message : '' tr { td { a(violation.rule.name, href:"#${violation.rule.name}") } td(class: "priority${violation.rule.priority}", violation.rule.priority) td(violation.lineNumber, class:'number') td { if (violation.sourceLine) { def formattedSourceLine = formatSourceLine(violation.sourceLine) p(class:'violationInfo') { span('[SRC]', class:'violationInfoPrefix') span(formattedSourceLine, class:'sourceCode') } } if (moreInfo) { p(class:'violationInfo') { span('[MSG]', class:'violationInfoPrefix') span(moreInfo, class:'violationMessage') } } } } } } } } private buildRuleDescriptions(AnalysisContext analysisContext) { def sortedRules = getSortedRules(analysisContext) return { div(class: 'summary') { h2(getResourceBundleString('htmlReport.ruleDescriptions.title')) table(border:'1') { tr(class:'tableHeader') { th('#', class:'ruleDescriptions') th(getResourceBundleString('htmlReport.ruleDescriptions.ruleNameHeading'), class:'ruleDescriptions') th(getResourceBundleString('htmlReport.ruleDescriptions.descriptionHeading'), class:'ruleDescriptions') } sortedRules.eachWithIndex { Rule rule, index -> def ruleName = rule.name def priority = rule.priority tr(class:'ruleDescriptions') { td { a(name:ruleName) { } span(index + 1,class:'ruleIndex') } td(ruleName, class:"ruleName priority${priority}") td { unescaped << getHtmlDescriptionForRule(rule) } } } } } } } /** * Format and trim the source line. If the whole line fits, then include the whole line (trimmed). * Otherwise, remove characters from the middle to truncate to the max length. * @param sourceLine - the source line to format * @param startColumn - the starting column index; used to truncate the line if it's too long; defaults to 0 * @return the formatted and trimmed source line */ protected String formatSourceLine(String sourceLine, int startColumn=0) { def source = sourceLine ? sourceLine.trim() : null if (source && source.size() > MAX_SOURCE_LINE_LENGTH) { source = startColumn ? sourceLine[startColumn..-1] : sourceLine.trim() def lengthOfFirstSegment = MAX_SOURCE_LINE_LENGTH - SOURCE_LINE_LAST_SEGMENT_LENGTH - 2 def firstSegment = source[0..lengthOfFirstSegment - 1] def lastSegment = source[-SOURCE_LINE_LAST_SEGMENT_LENGTH..-1] source = firstSegment + '..' + lastSegment } return source } /** * Return true if the Results represents a directory that contains at least one file with one * or more violations. * @param results - the Results */ protected boolean isDirectoryContainingFilesWithViolations(Results results) { return !results.isFile() && results.getNumberOfFilesWithViolations(maxPriority, false) } /** * Return true if the Results represents a directory that contains at least one file * @param results - the Results */ protected boolean isDirectoryContainingFiles(Results results) { return !results.isFile() && results.getTotalNumberOfFiles(false) } private String buildTitle() { getResourceBundleString('htmlReport.titlePrefix') + (title ? ": $title" : '') } } CodeNarc-0.23/src/main/groovy/org/codenarc/report/InlineXmlReportWriter.groovy0000644000175000017500000000363412311370173027127 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.report import org.codenarc.AnalysisContext import org.codenarc.rule.Violation /** * ReportWriter that generates an XML report with inline rule descriptions. * This makes it easy for Hudson to parse * * @author Robin Bramley */ @SuppressWarnings('UnnecessaryReturnKeyword') class InlineXmlReportWriter extends XmlReportWriter { //-------------------------------------------------------------------------- // Internal Helper Methods //-------------------------------------------------------------------------- @Override protected buildViolationElement(Violation violation) { def rule = violation.rule return { Violation(ruleName:rule.name, priority:rule.priority, lineNumber:violation.lineNumber) { out << buildSourceLineElement(violation) out << buildMessageElement(violation) out << buildDescriptionElement(rule) // put inline } } } @Override protected buildRulesElement(AnalysisContext analysisContext) { // No-op as we have inline rule descriptions } @SuppressWarnings('FactoryMethodName') private buildDescriptionElement(rule) { def description = this.getDescriptionForRule(rule) return { Description(cdata(description)) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/report/ReportWriterFactory.groovy0000644000175000017500000000403612415111506026632 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.report import org.codenarc.util.PropertyUtil /** * Factory for ReportWriter objects based on the report type (name). *

* The passed in type can either be one of the predefined type names: "html", "xml", "console", * "ide", "inlineXml", or else it can specify the fully-qualified class name of a class (accessible on the * classpath) that implements the org.codenarc.report.ReportWriter interface. * * @author Chris Mair */ class ReportWriterFactory { ReportWriter getReportWriter(String type) { assert type switch(type) { case 'html': return new HtmlReportWriter() case 'xml': return new XmlReportWriter() case 'text': return new TextReportWriter() case 'console': def w = new TextReportWriter(); w.writeToStandardOut = true; return w case 'ide': def w = new IdeTextReportWriter(); w.writeToStandardOut = true; return w case 'inlineXml' : return new InlineXmlReportWriter() } def reportClass = getClass().classLoader.loadClass(type) reportClass.newInstance() } ReportWriter getReportWriter(String type, Map options) { def reportWriter = getReportWriter(type) options.each { name, value -> PropertyUtil.setPropertyFromString(reportWriter, name, value) } reportWriter } } CodeNarc-0.23/src/main/groovy/org/codenarc/tool/0000755000175000017500000000000012623571301021026 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/tool/GenerateCodeNarcRulesProperties.groovy0000644000175000017500000000375012311370173030521 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import org.apache.log4j.Logger import org.codenarc.ruleregistry.PropertiesFileRuleRegistry /** * Java application (main() method) that generates the 'codenarc-base-rules.properties' properties file. * This properties file contains = properties for all CodeNarc rules. * * @see org.codenarc.ruleregistry.PropertiesFileRuleRegistry * * @author Chris Mair */ class GenerateCodeNarcRulesProperties { protected static final PROPERTIES_FILE = PropertiesFileRuleRegistry.PROPERTIES_FILE private static final LOG = Logger.getLogger(GenerateCodeNarcRulesProperties) protected static propertiesFile = PROPERTIES_FILE /** * Write out all current rules to the 'codenarc-base-rules.properties' properties file * @param args - command-line args (not used) */ static void main(String[] args) { def sortedRules = GenerateUtil.createSortedListOfAllRules() LOG.debug("sortedRules=$sortedRules") def propertiesFile = new File(propertiesFile) propertiesFile.withWriter { writer -> writer.println '# CodeNarc Rules (see PropertiesFileRuleRegistry): ' + new Date() sortedRules.each { rule -> writer.println "${rule.name} = ${rule.class.name}" } } LOG.info("Finished writing ${sortedRules.size()} rules to $propertiesFile") } } CodeNarc-0.23/src/main/groovy/org/codenarc/tool/GenerateAll.groovy0000644000175000017500000000232612311370173024461 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import org.apache.log4j.BasicConfigurator /** * Java application (main() method) that invokes all of the Generate* scripts. * * @author Chris Mair */ class GenerateAll { /** * Invoke all generation scripts * @param args - command-line args (not used) */ static void main(String[] args) { BasicConfigurator.configure() GenerateCodeNarcRulesProperties.main(null) GenerateRuleSetAllRules.main(null) GenerateRuleSetAllRulesByCategory.main(null) GenerateRuleIndexPage.main(null) } } CodeNarc-0.23/src/main/groovy/org/codenarc/tool/GenerateUtil.groovy0000644000175000017500000000355312166016544024700 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import org.codenarc.ruleset.CompositeRuleSet import org.codenarc.ruleset.RuleSets import org.codenarc.ruleset.XmlFileRuleSet import org.codenarc.util.io.ClassPathResource /** * Contains static utility methods related to the Generate* tools. * * @author Chris Mair */ class GenerateUtil { private static final RULE_EXTRA_INFO_FILE = 'codenarc-rule-extrainfo.properties' private static Properties ruleExtraInformation static Properties getRuleExtraInformation() { if (ruleExtraInformation) { return ruleExtraInformation } ruleExtraInformation = new Properties() ruleExtraInformation.load(ClassPathResource.getInputStream(RULE_EXTRA_INFO_FILE)) ruleExtraInformation } static List createSortedListOfAllRules() { def allRuleSet = new CompositeRuleSet() RuleSets.ALL_RULESET_FILES.each { ruleSetPath -> def ruleSet = new XmlFileRuleSet(ruleSetPath) allRuleSet.addRuleSet(ruleSet) } sortRules(allRuleSet.rules) } static List sortRules(List rules) { def allRules = [] allRules.addAll(rules) allRules.sort { rule -> rule.name } } } CodeNarc-0.23/src/main/groovy/org/codenarc/tool/GenerateRuleSetAllRulesByCategory.groovy0000644000175000017500000000475512311370173031001 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import groovy.text.SimpleTemplateEngine import org.apache.log4j.Logger import org.codenarc.ruleset.RuleSets import org.codenarc.ruleset.XmlFileRuleSet /** * Java application (main() method) that generates the "StarterRuleSet-AllRulesByCategory.groovy.txt.template" file. * This file is a valid CodeNarc ruleset file that includes ALL rules distributed with CodeNarc, grouped by the * category. * * @author Chris Mair */ class GenerateRuleSetAllRulesByCategory { protected static final RULESET_FILE = 'src/site/resources/StarterRuleSet-AllRulesByCategory.groovy.txt' private static final TEMPLATE_FILE = 'src/main/resources/templates/StarterRuleSet-AllRulesByCategory.groovy.template' private static final LOG = Logger.getLogger(GenerateRuleSetAllRulesByCategory) protected static ruleSetFile = RULESET_FILE /** * Write out all current rules to the 'codenarc-base-rules.properties' properties file * @param args - command-line args (not used) */ static void main(String[] args) { def rulesByRuleSet = [:] RuleSets.ALL_RULESET_FILES.each { ruleSetPath -> def ruleSet = new XmlFileRuleSet(ruleSetPath) rulesByRuleSet[ruleSetPath] = GenerateUtil.sortRules(ruleSet.rules) } LOG.info("rulesByCategory=$rulesByRuleSet") Properties ruleExtraInformation = GenerateUtil.getRuleExtraInformation() def binding = [ruleSets:rulesByRuleSet, ruleExtraInformation:ruleExtraInformation] def ruleSetTemplateFile = new File(TEMPLATE_FILE) def engine = new SimpleTemplateEngine() def ruleSetText = engine.createTemplate(ruleSetTemplateFile).make(binding) def outputFile = new File(ruleSetFile) outputFile.text = ruleSetText LOG.info("Finished writing $ruleSetFile") } } CodeNarc-0.23/src/main/groovy/org/codenarc/tool/GenerateRuleIndexPage.groovy0000644000175000017500000000475112311370173026451 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import groovy.text.SimpleTemplateEngine import org.apache.log4j.Logger import org.codenarc.ruleset.RuleSets import org.codenarc.ruleset.XmlFileRuleSet /** * Java application (main() method) that generates the "codenarc-rule-index.apt.template" file. * which is the APT file for the Rule Index page of the project web site. * * @author Chris Mair */ class GenerateRuleIndexPage { protected static final RULE_INDEX_FILE = 'src/site/apt/codenarc-rule-index.apt' private static final TEMPLATE_FILE = 'src/main/resources/templates/codenarc-rule-index.apt.template' private static final LOG = Logger.getLogger(GenerateRuleIndexPage) protected static ruleIndexFile = RULE_INDEX_FILE /** * Write out all current rule index to the 'codenarc-rule-index.apt' APT file * @param args - command-line args (not used) */ static void main(String[] args) { def rulesByRuleSet = [:] def numberOfRules = 0 RuleSets.ALL_RULESET_FILES.each { ruleSetPath -> def ruleSet = new XmlFileRuleSet(ruleSetPath) def ruleSetName = ruleSetPath - 'rulesets/' - '.xml' rulesByRuleSet[ruleSetName] = GenerateUtil.sortRules(ruleSet.rules) numberOfRules += rulesByRuleSet[ruleSetName].size() } Properties ruleExtraInformation = GenerateUtil.getRuleExtraInformation() def binding = [ruleSets:rulesByRuleSet, numberOfRules:numberOfRules, ruleExtraInformation:ruleExtraInformation] def ruleSetTemplateFile = new File(TEMPLATE_FILE) def engine = new SimpleTemplateEngine() def ruleSetText = engine.createTemplate(ruleSetTemplateFile).make(binding) def outputFile = new File(ruleIndexFile) outputFile.text = ruleSetText LOG.info("Finished writing $ruleIndexFile") } } CodeNarc-0.23/src/main/groovy/org/codenarc/tool/GenerateRuleSetAllRules.groovy0000644000175000017500000000425512311370173027003 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import groovy.text.SimpleTemplateEngine import org.apache.log4j.Logger /** * Java application (main() method) that generates the "StarterRuleSet-AllRules.groovy.txt.template" file. * This file is a valid CodeNarc ruleset file that includes ALL rules distributed with CodeNarc. * * @author Chris Mair */ class GenerateRuleSetAllRules { protected static final RULESET_FILE = 'src/site/resources/StarterRuleSet-AllRules.groovy.txt' private static final TEMPLATE_FILE = 'src/main/resources/templates/StarterRuleSet-AllRules.groovy.template' private static final LOG = Logger.getLogger(GenerateRuleSetAllRules) protected static ruleSetFile = RULESET_FILE /** * Write out all current rules to the 'codenarc-base-rules.properties' properties file * @param args - command-line args (not used) */ static void main(String[] args) { def sortedRules = GenerateUtil.createSortedListOfAllRules() LOG.debug("sortedRules=$sortedRules") Properties ruleExtraInformation = GenerateUtil.getRuleExtraInformation() def binding = [rules:sortedRules, ruleExtraInformation:ruleExtraInformation] def ruleSetTemplateFile = new File(TEMPLATE_FILE) def engine = new SimpleTemplateEngine() def ruleSetText = engine.createTemplate(ruleSetTemplateFile).make(binding) def outputFile = new File(ruleSetFile) outputFile.text = ruleSetText LOG.info("Finished writing ${sortedRules.size()} rules to $ruleSetFile") } } CodeNarc-0.23/src/main/groovy/org/codenarc/CodeNarcRunner.groovy0000644000175000017500000001061012311373552024170 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc import org.apache.log4j.Logger import org.codenarc.analyzer.SourceAnalyzer import org.codenarc.results.Results import org.codenarc.ruleregistry.RuleRegistryInitializer import org.codenarc.ruleset.CompositeRuleSet import org.codenarc.ruleset.PropertiesFileRuleSetConfigurer import org.codenarc.ruleset.RuleSet import org.codenarc.ruleset.RuleSetUtil /** * Helper class to run CodeNarc. *

* The following properties must be configured before invoking the execute() method: *

    *
  • rulesetfiles - The path to the Groovy or XML RuleSet definition files, relative to the classpath. This can be a * single file path, or multiple paths separated by commas.
  • *
  • sourceAnalyzer - An instance of a org.codenarc.analyzer.SourceAnalyzer implementation.
  • *
  • reportWriters - The list of ReportWriter instances. A report is generated * for each element in this list. At least one ReportWriter must be configured.
  • *
* * NOTE: This is an internal class. Its API is subject to change. * * @author Chris Mair */ class CodeNarcRunner { private static final LOG = Logger.getLogger(CodeNarcRunner) String ruleSetFiles SourceAnalyzer sourceAnalyzer List reportWriters = [] /** * The main entry point for this class. Runs CodeNarc and returns the results. Processing steps include: *
    *
  1. Parse the ruleSetFiles property to create a RuleSet.
  2. *
  3. Configure the RuleSet from the "codenarc.properties" file, if that file is found on the classpath.
  4. *
  5. Apply the configured SourceAnalyzer.
  6. *
  7. Generate a report for each configured ReportWriter.
  8. *
  9. Return the Results object representing the analysis results.
  10. *
* @returns the Results object containing the results of the CodeNarc analysis. */ Results execute() { assert ruleSetFiles, 'The ruleSetFiles property must be set' assert sourceAnalyzer, 'The sourceAnalyzer property must be set to a valid SourceAnalayzer' def startTime = System.currentTimeMillis() new RuleRegistryInitializer().initializeRuleRegistry() def ruleSet = createRuleSet() new PropertiesFileRuleSetConfigurer().configure(ruleSet) def results = sourceAnalyzer.analyze(ruleSet) def p1 = results.getNumberOfViolationsWithPriority(1, true) def p2 = results.getNumberOfViolationsWithPriority(2, true) def p3 = results.getNumberOfViolationsWithPriority(3, true) def countsText = "(p1=$p1; p2=$p2; p3=$p3)" def elapsedTime = System.currentTimeMillis() - startTime LOG.debug("results=$results") def analysisContext = new AnalysisContext(ruleSet:ruleSet, sourceDirectories:sourceAnalyzer.sourceDirectories) reportWriters.each { reportWriter -> reportWriter.writeReport(analysisContext, results) } def resultsMessage = 'CodeNarc completed: ' + countsText + " ${elapsedTime}ms" println resultsMessage results } /** * Create and return the RuleSet that provides the source of Rules to be applied. * The returned RuleSet may aggregate multiple underlying RuleSets. * @return a single RuleSet */ protected RuleSet createRuleSet() { def paths = ruleSetFiles.tokenize(',') def newRuleSet = new CompositeRuleSet() paths.each { path -> def ruleSet = RuleSetUtil.loadRuleSetFile(path.trim()) newRuleSet.addRuleSet(ruleSet) } newRuleSet } } CodeNarc-0.23/src/main/groovy/org/codenarc/source/0000755000175000017500000000000012623571301021351 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/source/SourceCodeCriteria.groovy0000644000175000017500000000753112311373553026347 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.source import org.codenarc.util.WildcardPattern /** * Represents the set of criteria used to filter source code (files). Provides an API * to determine whether a particular source code file matches the criteria. *

* This is an internal class and its API is subject to change. * * @author Chris Mair */ class SourceCodeCriteria { /** * Apply only to source code (file) pathnames matching this regular expression. * If null, then all SourceCode instances match this part of the criteria (i.e., this property is ignored). */ String applyToFilesMatching /** * Do NOT apply to source code (file) pathnames matching this regular expression. * If null, then all SourceCode instances match this part of the criteria (i.e., this property is ignored). */ String doNotApplyToFilesMatching /** * Only apply to source code (file) names matching this value. The name may optionally contain a path. * If a path is specified, then the source code path must match it. If no path is specified, then only * the source code (file) name is compared (i.e., its path is ignored). * The value may optionally be a comma-separated list of names, in which case one of the names must match. * The name(s) may optionally include wildcard characters ('*' or '?'). * If null, then all SourceCode instances match this part of the criteria (i.e., this property is ignored). */ String applyToFileNames /** * Do NOT apply to source code (file) names matching this value. The name may optionally contain a path. * If a path is specified, then the source code path must match it. If no path is specified, then only * the source code (file) name is compared (i.e., its path is ignored). * The value may optionally be a comma-separated list of names, in which case any one of the names can match. * The name(s) may optionally include wildcard characters ('*' or '?'). * If null, then all SourceCode instances match this part of the criteria (i.e., this property is ignored). */ String doNotApplyToFileNames /** * Return true if all of the criteria specified in this object apply to thw SourceCode. * @param sourceCode - the SourceCode * @return true only if all of the (specified, i.e. non-null) criteria match the SourceCode */ boolean matches(SourceCode sourceCode) { boolean apply = (applyToFilesMatching) ? sourceCode.path ==~ applyToFilesMatching : true if (apply && doNotApplyToFilesMatching) { apply = !(sourceCode.path ==~ doNotApplyToFilesMatching) } if (apply && applyToFileNames) { def target = includesPath(applyToFileNames) ? sourceCode.path : sourceCode.name apply = new WildcardPattern(applyToFileNames).matches(target) } if (apply && doNotApplyToFileNames) { def target = includesPath(doNotApplyToFileNames) ? sourceCode.path : sourceCode.name apply = !new WildcardPattern(doNotApplyToFileNames).matches(target) } apply } private boolean includesPath(String value) { value.contains('/') } } CodeNarc-0.23/src/main/groovy/org/codenarc/source/SourceString.groovy0000644000175000017500000000343312311373552025254 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.source import org.codenarc.analyzer.SuppressionAnalyzer /** * SourceCode implementation that uses source from a pre-defined String. * Note that the path is normalized: file separator chars are normalized to standard '/'. * * @author Chris Mair */ class SourceString extends AbstractSourceCode { String path String name private final String source /** * Construct a new instance for the file at the specified path * @param source - the source; must not be null or empty * @param path - the path for the source code; may be null; defaults to null * @param name - the name for the source code; may be null; defaults to null */ SourceString(String source, String path=null, String name=null) { assert source this.source = source setPath(path) this.name = name setSuppressionAnalyzer(new SuppressionAnalyzer(this)) } /** * @return the full text of the source code */ String getText() { source } void setPath(String path) { this.path = path ? normalizePath(path) : path } String toString() { "SourceString[$source]" } } CodeNarc-0.23/src/main/groovy/org/codenarc/source/SourceCode.groovy0000644000175000017500000000660712324227505024666 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.source import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ModuleNode import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.control.Phases import org.codenarc.analyzer.SuppressionAnalyzer /** * Represents a unit of source code to be analyzed * * @author Chris Mair */ interface SourceCode { public static final int DEFAULT_COMPILER_PHASE = Phases.CONVERSION /** * Returns information about this classes' suppressed warnings. * @return suppression analyzer */ SuppressionAnalyzer getSuppressionAnalyzer() /** * Get the logical name for this source code. If this object is a file, then the name * is the filename, without a path. * @return the name for this source; may be null */ String getName() /** * Get the logical path for this source code. If this object is a file, then the name * is the full path in the filesystem. File separators are normalized to forward slash (/). * @return the name for this source; may be null */ String getPath() /** * @return the full text of the source code */ String getText() /** * @return the List of lines of the source code (with line terminators removed) */ List getLines() /** * Get the trimmed line at the specified index * @param lineNumber - the zero-based line number; may be negative * @return the trimmed line at the specified index, or null if lineNumber is not valid */ String line(int lineNumber) /** * Return the Groovy AST (Abstract Syntax Tree) for this source file * @return the ModuleNode representing the AST for this source file */ ModuleNode getAst() /** * @return compiler phase (as in {@link org.codehaus.groovy.control.Phases}) up to which the AST will be processed */ int getAstCompilerPhase() /** * Return the line index for the line containing the character at the specified index within the source code. * @param charIndex - the index of the character within the source code (zero-based) * @return the line number (one-based) containing the specified character; Return -1 if charIndex is not valid. */ int getLineNumberForCharacterIndex(int charIndex) /** * Return true if and only if the source code can be successfully compiled * @return true only if the source code is valid */ boolean isValid() /** * This method gives you all of the MethodCallExpressions defined in the AST without forcing you to walk the * entire tree on every request. They are cached for the lifespan of the SourceCode. * @return */ Map> getMethodCallExpressions() } CodeNarc-0.23/src/main/groovy/org/codenarc/source/SourceFile.groovy0000644000175000017500000000347012311373552024666 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.source import org.codenarc.analyzer.SuppressionAnalyzer /** * The SourceCode implementation for a single file. * Note that the path is normalized: file separator chars are normalized to standard '/'. * * @author Chris Mair */ class SourceFile extends AbstractSourceCode { private final File file private final path private String text /** * Construct a new instance for the file at the specified path * @param path - the path of the file; must not be null or empty */ SourceFile(File file) { assert file this.file = file this.path = normalizePath(file.path) setSuppressionAnalyzer(new SuppressionAnalyzer(this)) } /** * @return the filename for this source file, excluding path */ String getName() { file.name } /** * @return the normalized path for this source file, including filename */ String getPath() { path } /** * @return the full text of the source code */ String getText() { if (text == null) { text = file.text } text } String toString() { "SourceFile[$file.absolutePath]" } } CodeNarc-0.23/src/main/groovy/org/codenarc/source/AbstractSourceCode.groovy0000644000175000017500000001434712407277435026363 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.source import groovy.grape.GrabAnnotationTransformation import org.apache.log4j.Logger import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ModuleNode import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.control.CompilationFailedException import org.codehaus.groovy.control.CompilationUnit import org.codehaus.groovy.control.SourceUnit import org.codehaus.groovy.transform.ASTTransformation import org.codenarc.analyzer.SuppressionAnalyzer /** * Abstract superclass for SourceCode implementations * * @author Chris Mair * @author Hamlet D'Arcy */ @SuppressWarnings('AbstractClassWithoutAbstractMethod') abstract class AbstractSourceCode implements SourceCode { static final LOG = Logger.getLogger(AbstractSourceCode) static final SEPARATOR_PROP = 'file.separator' private ModuleNode ast private List lines private astParsed = false private final initLock = new Object() private Map> methodCallExpressions SuppressionAnalyzer suppressionAnalyzer /** * Setter exists to avoid circular dependency. * @param suppressionAnalyzer suppression analyzer */ protected void setSuppressionAnalyzer(SuppressionAnalyzer suppressionAnalyzer) { this.suppressionAnalyzer = suppressionAnalyzer } /** * @return the List of lines of the source code (with line terminators removed) */ List getLines() { if (lines == null) { lines = new StringReader(getText()).readLines() } return lines } /** * Get the trimmed line at the specified index * @param lineNumber - the zero-based line number; may be negative * @return the trimmed line at the specified index, or null if lineNumber is not valid */ String line(int lineNumber) { def allLines = getLines() (lineNumber >= 0) && lineNumber < allLines.size() ? allLines[lineNumber].trim() : null } /** * Return the Groovy AST (Abstract Syntax Tree) for this source file * @return the ModuleNode representing the AST for this source file */ ModuleNode getAst() { init() ast } private void init() { synchronized (initLock) { if (!astParsed) { SourceUnit unit = SourceUnit.create('None', getText()) CompilationUnit compUnit = new CompilationUnit() compUnit.addSource(unit) try { removeGrabTransformation(compUnit) compUnit.compile(getAstCompilerPhase()) ast = unit.getAST() } catch (CompilationFailedException e) { logCompilationError(e) } catch (NoClassDefFoundError e) { logCompilationError(e) LOG.info("Most likely, a lib containing $e.message is missing from CodeNarc's runtime classpath.") } methodCallExpressions = new ExpressionCollector().getMethodCalls(ast) astParsed = true } } } private void logCompilationError(Throwable e) { LOG.warn("Compilation failed for [${toString()}].") if (getAstCompilerPhase() <= DEFAULT_COMPILER_PHASE) { LOG.info("Compilation failed because of [${e.class.name}] with message: [$e.message]") } } /** * @return compiler phase (as in {@link org.codehaus.groovy.control.Phases}) up to which the AST will be processed */ @SuppressWarnings('GetterMethodCouldBeProperty') int getAstCompilerPhase() { DEFAULT_COMPILER_PHASE } Map> getMethodCallExpressions() { init() methodCallExpressions.asImmutable() } private removeGrabTransformation(CompilationUnit compUnit) { compUnit.phaseOperations?.each { List xforms -> xforms?.removeAll { entry -> entry.getClass().declaredFields.any { it.name == 'val$instance' && it.type == ASTTransformation } && entry.val$instance instanceof GrabAnnotationTransformation } } } /** * Return the line index for the line containing the character at the specified index within the source code. * @param charIndex - the index of the character within the source code (zero-based) * @return the line number (one-based) containing the specified character; Return -1 if charIndex is not valid. */ int getLineNumberForCharacterIndex(int charIndex) { int lineCount = 1 def source = getText() if (charIndex >= source.size() || charIndex < 0) { return -1 } if (charIndex > 0) { (charIndex - 1..0).each { index -> def ch = source[index] if (ch == '\n') { lineCount++ } } } lineCount } /** * Return true if and only if the source code can be successfully compiled * @return true only if the source code is valid */ boolean isValid() { return getAst() } /** * Return the normalized value of the specified path. Convert file separator chars to standard '/'. * @param path - the path to normalize * @return the normalized value */ protected String normalizePath(String path) { final SEP = '/' as char char separatorChar = System.getProperty(SEPARATOR_PROP).charAt(0) (separatorChar == SEP) ? path : path.replace(separatorChar, SEP) } } CodeNarc-0.23/src/main/groovy/org/codenarc/source/CustomCompilerPhaseSourceDecorator.groovy0000644000175000017500000000343512140600454031573 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.source import org.codehaus.groovy.control.Phases import org.codenarc.analyzer.SuppressionAnalyzer /** * A {@link SourceCode} decorator overriding the decorated source's returned AST * so that it meets the user's compilerPhase requirements. * * Ensures that the compiler phase is before classes are output to disk. * * @author Artur Gajowy */ class CustomCompilerPhaseSourceDecorator extends AbstractSourceCode { private final SourceCode delegate private final int compilerPhase CustomCompilerPhaseSourceDecorator(SourceCode delegate, int compilerPhase) { assert delegate this.delegate = delegate assert compilerPhase < Phases.OUTPUT this.compilerPhase = compilerPhase } @Override int getAstCompilerPhase() { compilerPhase } String getName() { delegate.name } String getPath() { delegate.path } String getText() { delegate.text } @Override SuppressionAnalyzer getSuppressionAnalyzer() { delegate.suppressionAnalyzer } String toString() { "CustomCompilerPhaseSourceDecorator[${delegate.toString()}]" } } CodeNarc-0.23/src/main/groovy/org/codenarc/results/0000755000175000017500000000000012623571301021552 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/results/DirectoryResults.groovy0000644000175000017500000001053612311373552026356 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.results /** * Represents the results for a directory * * @author Chris Mair */ class DirectoryResults implements Results { private final String path private final List children = [] int numberOfFilesInThisDirectory = 0 /** * Create a new uninitialized instance */ DirectoryResults() { } /** * Create a new instance with the specified path * @param path - the path */ DirectoryResults(String path) { this.path = path } /** * Create a new instance with the specified path and number of files in the directory */ DirectoryResults(String path, int numberOfFilesInThisDirectory) { this.path = path this.numberOfFilesInThisDirectory = numberOfFilesInThisDirectory } /** * @return the path to the file or directory associated with these results */ String getPath() { path } void addChild(Results child) { children.add(child) } /** * @return the List of child Results objects; may be empty */ List getChildren() { children } /** * @return the List of all violations; may be empty */ List getViolations() { children.inject([]) { violations, child -> violations.addAll(child.getViolations()); violations } } /** * Return the number of violations with the specified priority * @param recursive - true if the returned count should include subdirectories as well; defaults to true * @return the number of violations with the specified priority */ int getNumberOfViolationsWithPriority(int priority, boolean recursive=true) { children.sum(0) { child -> (recursive || child.isFile()) ? child.getNumberOfViolationsWithPriority(priority) : 0 } } /** * Return the number of files with violations * @param maxPriority - the maximum priority level; ignore violations with priority greater than this * @param recursive - true if the returned count should include subdirectories as well; defaults to true * @return the number of files containing violations */ int getNumberOfFilesWithViolations(int maxPriority, boolean recursive=true) { children.sum(0) { child -> (recursive || child.isFile()) ? child.getNumberOfFilesWithViolations(maxPriority) : 0 } } /** * Return the total number of (Groovy) files analyzed * @param recursive - true if the returned count should include subdirectories as well * @return the total number of files (with or without violations) */ int getTotalNumberOfFiles(boolean recursive=true) { def total = numberOfFilesInThisDirectory if (recursive) { total += children.sum(0) { child -> child.isFile() ? 0 : child.getTotalNumberOfFiles(true) } } total } /** * @return false (this object does not represents the results for a single file) */ boolean isFile() { false } /** * Return the Results object with the specified path within this directory or its descendents. * @param path - the path to search for * @return this Results object if a match is found, otherwise null */ Results findResultsForPath(String path) { if (this.path == path) { return this } for(child in this.children) { def foundResults = child.findResultsForPath(path) if (foundResults) { return foundResults } } null } String toString() { "DirectoryResults($path) $children" } } CodeNarc-0.23/src/main/groovy/org/codenarc/results/VirtualResults.groovy0000644000175000017500000000366112145021324026031 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.results /** * This is a Results object for something that has no real file system, such as a string. * * @author Hamlet D'Arcy */ class VirtualResults implements Results { private final List violations VirtualResults(List violations) { this.violations = violations } List getViolations() { return new ArrayList(violations) } String getPath() { throw new UnsupportedOperationException('Not supported on virtual results') } List getChildren() { throw new UnsupportedOperationException('Not supported on virtual results') } @Override int getNumberOfViolationsWithPriority(int priority, boolean recursive) { throw new UnsupportedOperationException('Not supported on virtual results') } @Override int getTotalNumberOfFiles(boolean recursive) { throw new UnsupportedOperationException('Not supported on virtual results') } @Override int getNumberOfFilesWithViolations(int maxPriority, boolean recursive) { throw new UnsupportedOperationException('Not supported on virtual results') } @Override boolean isFile() { false } @Override Results findResultsForPath(String path) { throw new UnsupportedOperationException('Not supported on virtual results') } } CodeNarc-0.23/src/main/groovy/org/codenarc/results/Results.groovy0000644000175000017500000000507012311373552024466 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.results /** * Represents the results of applying rules to one or more source files/directories * * @author Chris Mair */ interface Results { /** * @return the path to the file or directory associated with these results */ String getPath() /** * @return the List of child Results objects; may be empty */ List getChildren() /** * @return the List of all violations; may be empty */ List getViolations() /** * Return the number of violations with the specified priority * @param priority - the priority * @param recursive - true if the returned count should include subdirectories as well * @return the number of violations with the specified priority */ int getNumberOfViolationsWithPriority(int priority, boolean recursive) /** * Return the total number of (Groovy) files analyzed * @param recursive - true if the returned count should include subdirectories as well * @return the total number of files (with or without violations) */ int getTotalNumberOfFiles(boolean recursive) /** * Return the number of files with violations * @param maxPriority - the maximum priority level; ignore violations with priority greater than this * @param recursive - true if the returned count should include subdirectories as well * @return the number of files containing violations */ int getNumberOfFilesWithViolations(int maxPriority, boolean recursive) /** * @return true only if this object represents the results for a single file */ boolean isFile() /** * Return the Results object with the specified path within this results object or its descendents. * @param path - the path to search for * @return this Results object if a match is found, otherwise null */ Results findResultsForPath(String path) } CodeNarc-0.23/src/main/groovy/org/codenarc/results/FileResults.groovy0000644000175000017500000000620412463037530025267 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.results /** * Represents the results of applying a set of rules against a single sourcefile * * @author Chris Mair */ @SuppressWarnings('UnusedMethodParameter') class FileResults implements Results { private final String path private final List violations FileResults(String path, List violations) { this.path = path this.violations = violations } /** * @return the path to the file or directory associated with these results */ String getPath() { path } /** * @return true (this object represents the results for a single file) */ boolean isFile() { true } /** * Return an empty List * @return the List of child Results objects; may be empty */ List getChildren() { Collections.EMPTY_LIST } /** * @return the List of all violations */ List getViolations() { new ArrayList(violations) } /** * @param recursive - ignored * @return the number of violations with the specified priority */ //@Override - causes compile error in Groovy 2.4.0 int getNumberOfViolationsWithPriority(int priority, boolean recursive=true) { violations.sum(0) { violation -> violation.rule.priority == priority ? 1 : 0 } } /** * Return the total number of (Groovy) files analyzed * @param recursive - ignored * @return the total number of files (with or without violations) */ //@Override - causes compile error in Groovy 2.4.0 int getTotalNumberOfFiles(boolean recursive=true) { 1 } /** * Return 1 if these results include at least one violation * @param maxPriority - the maximum priority level; ignore violations with priority greater than this * @param recursive - ignored * @return the number of files containing violations */ //@Override - causes compile error in Groovy 2.4.0 int getNumberOfFilesWithViolations(int maxPriority, boolean recursive=true) { violations.find { v -> v.rule.priority <= maxPriority } ? 1 : 0 } /** * Return the Results object with the specified path. * @param path - the path to search for * @return this Results object if the path matches, otherwise null */ Results findResultsForPath(String path) { this.path == path ? this : null } String toString() { "FileResults($path) $violations" } } CodeNarc-0.23/src/main/groovy/org/codenarc/AnalysisContext.groovy0000644000175000017500000000206612311373552024456 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc import org.codenarc.ruleset.RuleSet /** * Holds information related to the configuration and context for the source code analysis. * * @author Chris Mair */ class AnalysisContext { /** * The List of source directories being analyzed. May be null or empty. */ List sourceDirectories /** * The RuleSet containing the rules being applied. */ RuleSet ruleSet } CodeNarc-0.23/src/main/groovy/org/codenarc/ant/0000755000175000017500000000000012623571301020633 5ustar ebourgebourgCodeNarc-0.23/src/main/groovy/org/codenarc/ant/Report.groovy0000644000175000017500000000216012311373552023356 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.ant /** * JavaBean class holding the properties for a element with the CodeNarc Ant Task. * * @see CodeNarcTask * * @author Chris Mair */ class Report { String type /** @deprecated Use option elements instead */ String title /** @deprecated Use option elements instead */ String toFile final Map options = [:] void addConfiguredOption(ReportOption option) { options[option.name] = option.value } } CodeNarc-0.23/src/main/groovy/org/codenarc/ant/CodeNarcTask.groovy0000644000175000017500000001224312311373552024407 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.ant import org.apache.log4j.Logger import org.apache.tools.ant.BuildException import org.apache.tools.ant.Task import org.apache.tools.ant.types.FileSet import org.codenarc.CodeNarcRunner import org.codenarc.analyzer.SourceAnalyzer import org.codenarc.report.ReportWriterFactory import org.codenarc.results.Results /** * Ant Task for running CodeNarc. *

* The ruleSetFiles property specifies the path to the Groovy or XML RuleSet * definition files, relative to the classpath. This can be a single file path, or multiple * paths separated by commas. It is required. *

* The maxPriority1Violations property specifies the maximum number of priority 1 * violations allowed before failing the build (throwing a BuildException). Likewise, * maxPriority2Violations and maxPriority3Violations specifiy the * thresholds for violations of priority 2 and 3. *

* At least one nested fileset element is required, and is used to specify the source files * to be analyzed. This is the standard Ant FileSet, and is quite powerful and flexible. * See the Apache Ant Manual for more information on FileSets. *

* The report nested element defines the format and output file for the analysis report. * Currently, HTML (type="html") and XML (type="xml") are the only supported formats. Each report * is configured using nested option elements, with name, and * value attributes. * * @see "http://ant.apache.org/manual/index.html" * * @author Chris Mair */ class CodeNarcTask extends Task { private static final LOG = Logger.getLogger(CodeNarcTask) /** * The path to the Groovy or XML RuleSet definition files, relative to the classpath. This can be a * single file path, or multiple paths separated by commas. */ String ruleSetFiles int maxPriority1Violations = Integer.MAX_VALUE int maxPriority2Violations = Integer.MAX_VALUE int maxPriority3Violations = Integer.MAX_VALUE protected List reportWriters = [] protected List fileSets = [] protected ruleSet // Abstract creation of the CodeNarcRunner instance to allow substitution of test spy for unit tests protected createCodeNarcRunner = { new CodeNarcRunner() } /** * Execute this Ant Task */ void execute() throws BuildException { assert ruleSetFiles assert fileSets def sourceAnalyzer = createSourceAnalyzer() def codeNarcRunner = createCodeNarcRunner() codeNarcRunner.ruleSetFiles = ruleSetFiles codeNarcRunner.reportWriters = reportWriters codeNarcRunner.sourceAnalyzer = sourceAnalyzer def results = codeNarcRunner.execute() checkMaxViolations(results) } void addFileset(FileSet fileSet) { assert fileSet this.fileSets << fileSet } /** * Ant-defined method (by convention), called with each instance of a nested * element within this task. */ void addConfiguredReport(Report report) { def reportWriter = new ReportWriterFactory().getReportWriter(report.type, report.options) if (report.title) { reportWriter.title = report.title } if (report.toFile) { reportWriter.outputFile = report.toFile } LOG.debug("Adding report: $reportWriter") reportWriters << reportWriter } /** * Create and return the SourceAnalyzer * @return a configured SourceAnalyzer instance */ protected SourceAnalyzer createSourceAnalyzer() { new AntFileSetSourceAnalyzer(getProject(), fileSets) } private void checkMaxViolations(Results results) { def p1 = results.getNumberOfViolationsWithPriority(1, true) def p2 = results.getNumberOfViolationsWithPriority(2, true) def p3 = results.getNumberOfViolationsWithPriority(3, true) def countsText = "(p1=$p1; p2=$p2; p3=$p3)" checkMaxViolationForPriority(1, p1, countsText) checkMaxViolationForPriority(2, p2, countsText) checkMaxViolationForPriority(3, p3, countsText) } private void checkMaxViolationForPriority(int priority, int count, String countsText) { if (count > this."maxPriority${priority}Violations") { throw new BuildException("Exceeded maximum number of priority ${priority} violations: " + countsText) } } } CodeNarc-0.23/src/main/groovy/org/codenarc/ant/ReportOption.groovy0000644000175000017500000000162112311373552024550 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.ant /** * JavaBean class holding the properties for a

* This is an internal class and its API is subject to change. * * @author Chris Mair * @author Hamlet D'Arcy */ @SuppressWarnings("PMD.CollapsibleIfStatements") public class AstUtil { private static final Logger LOG = Logger.getLogger(AstUtil.class); public static final List AUTO_IMPORTED_PACKAGES = asList("java.lang", "java.io", "java.net", "java.util", "groovy.lang", "groovy.util"); public static final List AUTO_IMPORTED_CLASSES = asList("java.math.BigDecimal", "java.math.BigInteger"); public static final List COMPARISON_OPERATORS = asList("==", "!=", "<", "<=", ">", ">=", "<=>"); private static final Map> PREDEFINED_CONSTANTS = new HashMap>(); static { PREDEFINED_CONSTANTS.put("Boolean", asList("FALSE", "TRUE")); } /** * Private constructor. All methods are static. */ private AstUtil() { } /** * Tells you if an expression is a constant or literal. Basically, is it a map, list, constant, or a predefined * constant like true/false. * @param expression * any expression * @return * as described */ public static boolean isConstantOrLiteral(Expression expression) { if (expression instanceof ConstantExpression) return true; if (expression instanceof ListExpression) return true; if (expression instanceof MapExpression) return true; return isPredefinedConstant(expression); } /** * Tells you if the expression is a predefined constant like TRUE or FALSE. * @param expression * any expression * @return * as described */ private static boolean isPredefinedConstant(Expression expression) { if (expression instanceof PropertyExpression) { Expression object = ((PropertyExpression) expression).getObjectExpression(); Expression property = ((PropertyExpression) expression).getProperty(); if (object instanceof VariableExpression) { List predefinedConstantNames = PREDEFINED_CONSTANTS.get(((VariableExpression) object).getName()); if (predefinedConstantNames != null && predefinedConstantNames.contains(property.getText())) { return true; } } } return false; } /** * Returns true if an expression is a constant or else a literal that contains only constant values. * Basically, is it a constant, or else a map like [a:1, b:99, c:true], or a list like ['abc', 99.0, false] * @param expression - any expression */ public static boolean isConstantOrConstantLiteral(Expression expression) { return expression instanceof ConstantExpression || isPredefinedConstant(expression) || isMapLiteralWithOnlyConstantValues(expression) || isListLiteralWithOnlyConstantValues(expression); } /** * Returns true if a Map literal that contains only entries where both key and value are constants. * @param expression - any expression */ public static boolean isMapLiteralWithOnlyConstantValues(Expression expression) { if (expression instanceof MapExpression) { List entries = ((MapExpression) expression).getMapEntryExpressions(); for (MapEntryExpression entry : entries) { if (!isConstantOrConstantLiteral(entry.getKeyExpression()) || !isConstantOrConstantLiteral(entry.getValueExpression())) { return false; } } return true; } return false; } /** * Returns true if a List literal that contains only entries that are constants. * @param expression - any expression */ public static boolean isListLiteralWithOnlyConstantValues(Expression expression) { if (expression instanceof ListExpression) { List expressions = ((ListExpression) expression).getExpressions(); for (Expression e : expressions) { if (!isConstantOrConstantLiteral(e)) { return false; } } return true; } return false; } /** * Tells you if an expression is the expected constant. * @param expression * any expression * @param expected * the expected int or String * @return * as described */ public static boolean isConstant(Expression expression, Object expected) { return expression instanceof ConstantExpression && expected.equals(((ConstantExpression) expression).getValue()); } public static boolean isPropertyNamed(Expression property, Object expectedName) { return (property instanceof PropertyExpression && isConstant(((PropertyExpression) property).getProperty(), expectedName)); } /** * Return true if the Statement is a block * @param statement - the Statement to check * @return true if the Statement is a block */ public static boolean isBlock(Statement statement) { return statement instanceof BlockStatement; } /** * Return true if the Statement is a block and it is empty (contains no "meaningful" statements). * This implementation also addresses some "weirdness" around some statement types (specifically finally) * where the BlockStatement answered false to isEmpty() even if it was. * @param origStatement - the Statement to check * @return true if the BlockStatement is empty */ public static boolean isEmptyBlock(Statement origStatement) { Stack stack = new Stack(); stack.push(origStatement); while (!stack.isEmpty()) { ASTNode statement = stack.pop(); if (!(statement instanceof BlockStatement)) { return false; } if (((BlockStatement) statement).isEmpty()) { return true; } if (((BlockStatement) statement).getStatements().size() != 1) { return false; } stack.push(((BlockStatement) statement).getStatements().get(0)); } return false; } public static ASTNode getEmptyBlock(Statement origStatement) { Stack stack = new Stack(); stack.push(origStatement); while (!stack.isEmpty()) { ASTNode statement = stack.pop(); if (!(statement instanceof BlockStatement)) { return null; } if (((BlockStatement) statement).isEmpty()) { return statement; } if (((BlockStatement) statement).getStatements().size() != 1) { return null; } stack.push(((BlockStatement) statement).getStatements().get(0)); } return null; } /** * Return the List of Arguments for the specified MethodCallExpression or a ConstructorCallExpression. * The returned List contains either ConstantExpression or MapEntryExpression objects. * @param methodCall - the AST MethodCallExpression or ConstructorCalLExpression * @return the List of argument objects */ public static List getMethodArguments(ASTNode methodCall) { if (methodCall instanceof ConstructorCallExpression) { return extractExpressions(((ConstructorCallExpression) methodCall).getArguments()); } else if (methodCall instanceof MethodCallExpression) { return extractExpressions(((MethodCallExpression) methodCall).getArguments()); } else if (methodCall instanceof StaticMethodCallExpression) { return extractExpressions(((StaticMethodCallExpression) methodCall).getArguments()); } else if (respondsTo(methodCall, "getArguments")) { throw new RuntimeException(); // TODO: remove, should never happen } return new ArrayList(); } private static List extractExpressions(Expression argumentsExpression ) { if (argumentsExpression instanceof ArrayExpression) { return ((ArrayExpression) argumentsExpression).getExpressions(); } else if (argumentsExpression instanceof ListExpression) { return ((ListExpression) argumentsExpression).getExpressions(); } else if (argumentsExpression instanceof TupleExpression) { return ((TupleExpression) argumentsExpression).getExpressions(); } else if (argumentsExpression instanceof MapExpression) { return ((MapExpression) argumentsExpression).getMapEntryExpressions(); } else if (respondsTo(argumentsExpression, "getExpressions")) { throw new RuntimeException(); // TODO: add warning } else if (respondsTo(argumentsExpression, "getMapEntryExpressions")) { throw new RuntimeException(); // TODO: add warning } return new ArrayList(); } /** * Tells you if the expression is a method call on a particular object (which is represented as a String). * For instance, you may ask isMethodCallOnObject(e, 'this') to find a this reference. * @param expression - the expression * @param methodObjectPattern - the name of the method object (receiver) such as 'this' * @return * as described */ public static boolean isMethodCallOnObject(Expression expression, String methodObjectPattern) { if (expression instanceof MethodCallExpression) { Expression objectExpression = ((MethodCallExpression) expression).getObjectExpression(); if (objectExpression instanceof VariableExpression) { String name = ((VariableExpression) objectExpression).getName(); if (name != null && name.matches(methodObjectPattern)) { return true; } } if (objectExpression instanceof PropertyExpression && objectExpression.getText() != null && objectExpression.getText().matches(methodObjectPattern)) { return true; } if (objectExpression instanceof MethodCallExpression && isMethodNamed((MethodCallExpression) objectExpression, methodObjectPattern)) { return true; } } return false; } /** * Return true only if the Statement represents a method call for the specified method object (receiver), * method name, and with the specified number of arguments. * @param stmt - the AST Statement * @param methodObject - the name of the method object (receiver) * @param methodName - the name of the method being called * @param numArguments - the number of arguments passed into the method * @return true only if the Statement is a method call matching the specified criteria */ public static boolean isMethodCall(Statement stmt, String methodObject, String methodName, int numArguments) { if (stmt instanceof ExpressionStatement) { Expression expression = ((ExpressionStatement) stmt).getExpression(); if (expression instanceof MethodCallExpression) { return isMethodCall(expression, methodObject, methodName, numArguments); } } return false; } /** * Return true only if the MethodCallExpression represents a method call for the specified method object (receiver), * method name, and with the specified number of arguments. * @param methodCall - the AST MethodCallExpression * @param methodObjectPattern - the name of the method object (receiver) * @param methodPattern - the name of the method being called * @param numArguments - the number of arguments passed into the method * @return true only if the method call matches the specified criteria */ public static boolean isMethodCall(MethodCallExpression methodCall, String methodObjectPattern, String methodPattern, int numArguments) { return (isMethodCall(methodCall, methodObjectPattern, methodPattern) && AstUtil.getMethodArguments(methodCall).size() == numArguments); } /** * Return true only if the expression is a MethodCallExpression representing a method call for the specified * method object (receiver), method name, and with the specified number of arguments. * @param expression - the AST expression * @param methodObject - the name of the method object (receiver) * @param methodName - the name of the method being called * @param numArguments - the number of arguments passed into the method * @return true only if the method call matches the specified criteria */ public static boolean isMethodCall(Expression expression, String methodObject, String methodName, int numArguments) { return expression instanceof MethodCallExpression && isMethodCall((MethodCallExpression) expression, methodObject, methodName, numArguments); } /** * Return true only if the expression represents a method call (MethodCallExpression) for the specified * method object (receiver) and method name. * * @param expression - the AST expression to be checked * @param methodObjectPattern - the name of the method object (receiver) * @param methodNamePattern - the name of the method being called * @return true only if the expression is a method call that matches the specified criteria */ public static boolean isMethodCall(Expression expression, String methodObjectPattern, String methodNamePattern) { return isMethodCallOnObject(expression, methodObjectPattern) && isMethodNamed((MethodCallExpression) expression, methodNamePattern); } /** * Return true only if the MethodCallExpression represents a method call for any one of the specified method * objects (receivers) and any one of the method names. Optionally, you can restrict it to a method call with * a certain number of arguments. * @param methodCall * the method call object * @param methodObjects * a list of receivers, such as ['this', 'super'] * @param methodNames * a list of method names * @param numArguments * optionally, require a certain number of arguments * @return * as described */ public static boolean isMethodCall(MethodCallExpression methodCall, List methodObjects, List methodNames, Integer numArguments) { if (methodNames != null) { for (String name: methodNames) { if (methodObjects != null) { for (String objectName: methodObjects) { boolean match = isMethodCallOnObject(methodCall, objectName) && isMethodNamed(methodCall, name); if (match && numArguments == null) { return true; } else if (match && getMethodArguments(methodCall).size() == numArguments) { return true; } } } } } return false; } public static boolean isMethodCall(MethodCallExpression methodCall, List methodObjects, List methodNames) { return isMethodCall(methodCall, methodObjects, methodNames, null); } /** * Tells you if the expression is a method call for a certain method name with a certain * number of arguments. * @param expression * the (potentially) method call * @param methodName * the name of the method expected * @param numArguments * number of expected arguments * @return * as described */ public static boolean isMethodCall(Expression expression, String methodName, int numArguments) { return expression instanceof MethodCallExpression && isMethodNamed((MethodCallExpression) expression, methodName) && getMethodArguments(expression).size() == numArguments; } /** * Tells you if the expression is a method call for a certain method name with a certain * number of arguments. * @param expression * the (potentially) method call * @param methodName * the name of the method expected * @param numArguments * number of expected arguments * @return * as described */ public static boolean isMethodCall(Expression expression, String methodName, Range numArguments) { if (expression instanceof MethodCallExpression && AstUtil.isMethodNamed((MethodCallExpression) expression, methodName)) { int arity = AstUtil.getMethodArguments(expression).size(); if (arity >= (Integer)numArguments.getFrom() && arity <= (Integer)numArguments.getTo()) { return true; } } return false; } /** * Return true only if the MethodCallExpression represents a method call for the specified method name * @param methodCall - the AST MethodCallExpression * @param methodNamePattern - the expected name of the method being called * @param numArguments - The number of expected arguments * @return true only if the method call name matches */ public static boolean isMethodNamed(MethodCallExpression methodCall, String methodNamePattern, Integer numArguments) { Expression method = methodCall.getMethod(); // !important: performance enhancement boolean IS_NAME_MATCH = false; if (method instanceof ConstantExpression) { if (((ConstantExpression) method).getValue() instanceof String) { IS_NAME_MATCH = ((String)((ConstantExpression) method).getValue()).matches(methodNamePattern); } } if (IS_NAME_MATCH && numArguments != null) { return AstUtil.getMethodArguments(methodCall).size() == numArguments; } return IS_NAME_MATCH; } public static boolean isMethodNamed(MethodCallExpression methodCall, String methodNamePattern) { return isMethodNamed(methodCall, methodNamePattern, null); } /** * Return true if the expression is a constructor call on any of the named classes, with any number of parameters. * @param expression - the expression * @param classNames - the possible List of class names * @return as described */ public static boolean isConstructorCall(Expression expression, List classNames) { return expression instanceof ConstructorCallExpression && classNames.contains(expression.getType().getName()); } /** * Return true if the expression is a constructor call on a class that matches the supplied. * @param expression - the expression * @param classNamePattern - the possible List of class names * @return as described */ public static boolean isConstructorCall(Expression expression, String classNamePattern) { return expression instanceof ConstructorCallExpression && expression.getType().getName().matches(classNamePattern); } /** * Return the AnnotationNode for the named annotation, or else null. * Supports Groovy 1.5 and Groovy 1.6. * @param node - the AnnotatedNode * @param name - the name of the annotation * @return the AnnotationNode or else null */ public static AnnotationNode getAnnotation(AnnotatedNode node, String name) { List annotations = node.getAnnotations(); for (AnnotationNode annot : annotations) { if (annot.getClassNode().getName().equals(name)) { return annot; } } return null; } /** * Return true only if the node has the named annotation * @param node - the AST Node to check * @param name - the name of the annotation * @return true only if the node has the named annotation */ public static boolean hasAnnotation(AnnotatedNode node, String name) { return AstUtil.getAnnotation(node, name) != null; } /** * Return true only if the node has any of the named annotations * @param node - the AST Node to check * @param names - the names of the annotations * @return true only if the node has any of the named annotations */ public static boolean hasAnyAnnotation(AnnotatedNode node, String... names) { for (String name : names) { if (hasAnnotation(node, name)) { return true; } } return false; } /** * Return the List of VariableExpression objects referenced by the specified DeclarationExpression. * @param declarationExpression - the DeclarationExpression * @return the List of VariableExpression objects */ public static List getVariableExpressions(DeclarationExpression declarationExpression) { Expression leftExpression = declarationExpression.getLeftExpression(); // !important: performance enhancement if (leftExpression instanceof ArrayExpression) { List expressions = ((ArrayExpression) leftExpression).getExpressions(); return expressions.isEmpty() ? Arrays.asList(leftExpression) : expressions; } else if (leftExpression instanceof ListExpression) { List expressions = ((ListExpression) leftExpression).getExpressions(); return expressions.isEmpty() ? Arrays.asList(leftExpression) : expressions; } else if (leftExpression instanceof TupleExpression) { List expressions = ((TupleExpression) leftExpression).getExpressions(); return expressions.isEmpty() ? Arrays.asList(leftExpression) : expressions; } else if (leftExpression instanceof VariableExpression) { return Arrays.asList(leftExpression); } // todo: write warning return Collections.emptyList(); } /** * Return true if the DeclarationExpression represents a 'final' variable declaration. * * NOTE: THIS IS A WORKAROUND. * * There does not seem to be an easy way to determine whether the 'final' modifier has been * specified for a variable declaration. Return true if the 'final' is present before the variable name. */ public static boolean isFinalVariable(DeclarationExpression declarationExpression, SourceCode sourceCode) { if (isFromGeneratedSourceCode(declarationExpression)) { return false; } List variableExpressions = getVariableExpressions(declarationExpression); if (!variableExpressions.isEmpty()) { Expression variableExpression = variableExpressions.get(0); int startOfDeclaration = declarationExpression.getColumnNumber(); int startOfVariableName = variableExpression.getColumnNumber(); String sourceLine = sourceCode.getLines().get(declarationExpression.getLineNumber() - 1); String modifiers = (startOfDeclaration >= 0 && startOfVariableName >= 0) ? sourceLine.substring(startOfDeclaration - 1, startOfVariableName - 1) : ""; return modifiers.contains("final"); } return false; } /** * @return true if the ASTNode was generated (synthetic) rather than from the "real" input source code. */ public static boolean isFromGeneratedSourceCode(ASTNode node) { return node.getLineNumber() < 0 || (node instanceof ClassNode && ((ClassNode)node).isScript()); } /** * Tells you if the expression is true, which can be true or Boolean.TRUE. * @param expression * expression * @return * as described */ public static boolean isTrue(Expression expression) { if (expression == null) { return false; } if (expression instanceof PropertyExpression && classNodeImplementsType(((PropertyExpression) expression).getObjectExpression().getType(), Boolean.class)) { if (((PropertyExpression) expression).getProperty() instanceof ConstantExpression && "TRUE".equals(((ConstantExpression) ((PropertyExpression) expression).getProperty()).getValue())) { return true; } } return ((expression instanceof ConstantExpression) && ((ConstantExpression) expression).isTrueExpression()) || "Boolean.TRUE".equals(expression.getText()); } /** * Tells you if the expression is either the true or false literal. * @param expression * expression * @return * as described */ public static boolean isBoolean(Expression expression) { return isTrue(expression) || isFalse(expression); } /** * Tells you if the expression is the null literal. * @param expression * expression. * @return * as described */ public static boolean isNull(ASTNode expression) { return expression instanceof ConstantExpression && ((ConstantExpression)expression).isNullExpression(); } /** * Tells you if the expression is the false expression, either literal or contant. * @param expression * expression * @return * as described */ public static boolean isFalse(Expression expression) { if (expression == null) { return false; } if (expression instanceof PropertyExpression && classNodeImplementsType(((PropertyExpression) expression).getObjectExpression().getType(), Boolean.class)) { if (((PropertyExpression) expression).getProperty() instanceof ConstantExpression && "FALSE".equals(((ConstantExpression) ((PropertyExpression) expression).getProperty()).getValue())) { return true; } } return ((expression instanceof ConstantExpression) && ((ConstantExpression) expression).isFalseExpression()) || "Boolean.FALSE".equals(expression.getText()); } /** * Return true only if the specified object responds to the named method * @param object - the object to check * @param methodName - the name of the method * @return true if the object responds to the named method */ public static boolean respondsTo(Object object, String methodName) { MetaClass metaClass = DefaultGroovyMethods.getMetaClass(object); if (!metaClass.respondsTo(object, methodName).isEmpty()) { return true; } Map properties = DefaultGroovyMethods.getProperties(object); return properties.containsKey(methodName); } /** * This method tells you if a ClassNode implements or extends a certain class. * @param node * the node * @param target * the class * @return * true if the class node 'is a' target */ public static boolean classNodeImplementsType(ClassNode node, Class target) { ClassNode targetNode = ClassHelper.make(target); if (node.implementsInterface(targetNode)) { return true; } if (node.isDerivedFrom(targetNode)) { return true; } if (node.getName().equals(target.getName())) { return true; } if (node.getName().equals(target.getSimpleName())) { return true; } if (node.getSuperClass() != null && node.getSuperClass().getName().equals(target.getName())) { return true; } if (node.getSuperClass() != null && node.getSuperClass().getName().equals(target.getSimpleName())) { return true; } if (node.getInterfaces() != null) { for (ClassNode declaredInterface : node.getInterfaces()) { if (classNodeImplementsType(declaredInterface, target)) { return true; } } } return false; } /** * Returns true if the ASTNode is a declaration of a closure, either as a declaration * or a field. * @param expression * the target expression * @return * as described */ public static boolean isClosureDeclaration(ASTNode expression) { if (expression instanceof DeclarationExpression) { if (((DeclarationExpression) expression).getRightExpression() instanceof ClosureExpression) { return true; } } if (expression instanceof FieldNode) { ClassNode type = ((FieldNode) expression).getType(); if (AstUtil.classNodeImplementsType(type, Closure.class)) { return true; } else if (((FieldNode) expression).getInitialValueExpression() instanceof ClosureExpression) { return true; } } return false; } /** * Gets the parameter names of a method node. * @param node * the node to search parameter names on * @return * argument names, never null */ public static List getParameterNames(MethodNode node) { ArrayList result = new ArrayList(); if (node.getParameters() != null) { for (Parameter parameter : node.getParameters()) { result.add(parameter.getName()); } } return result; } /** * Gets the argument names of a method call. If the arguments are not VariableExpressions then a null * will be returned. * @param methodCall * the method call to search * @return * a list of strings, never null, but some elements may be null */ public static List getArgumentNames(MethodCallExpression methodCall) { ArrayList result = new ArrayList(); Expression arguments = methodCall.getArguments(); List argExpressions = null; if (arguments instanceof ArrayExpression) { argExpressions = ((ArrayExpression) arguments).getExpressions(); } else if (arguments instanceof ListExpression) { argExpressions = ((ListExpression) arguments).getExpressions(); } else if (arguments instanceof TupleExpression) { argExpressions = ((TupleExpression) arguments).getExpressions(); } else { LOG.warn("getArgumentNames arguments is not an expected type"); } if (argExpressions != null) { for (Expression exp : argExpressions) { if (exp instanceof VariableExpression) { result.add(((VariableExpression) exp).getName()); } } } return result; } /** * Returns true if the expression is a binary expression with the specified token. * @param expression * expression * @param token * token * @return * as described */ public static boolean isBinaryExpressionType(Expression expression, String token) { if (expression instanceof BinaryExpression) { if (token.equals(((BinaryExpression) expression).getOperation().getText())) { return true; } } return false; } /** * Returns true if the expression is a binary expression with the specified token. * @param expression - the expression node * @param tokens - the List of allowable (operator) tokens * @return as described */ public static boolean isBinaryExpressionType(Expression expression, List tokens) { if (expression instanceof BinaryExpression) { if (tokens.contains(((BinaryExpression) expression).getOperation().getText())) { return true; } } return false; } /** * Tells you if the expression is a null safe dereference. * @param expression * expression * @return * true if is null safe dereference. */ public static boolean isSafe(Expression expression) { if (expression instanceof MethodCallExpression) { return ((MethodCallExpression) expression).isSafe(); } if (expression instanceof PropertyExpression) { return ((PropertyExpression) expression).isSafe(); } return false; } /** * Tells you if the expression is a spread operator call * @param expression * expression * @return * true if is spread expression */ public static boolean isSpreadSafe(Expression expression) { if (expression instanceof MethodCallExpression) { return ((MethodCallExpression) expression).isSpreadSafe(); } if (expression instanceof PropertyExpression) { return ((PropertyExpression) expression).isSpreadSafe(); } return false; } /** * Tells you if the ASTNode is a method node for the given name, arity, and return type. * @param node * the node to inspect * @param methodNamePattern * the expected name of the method * @param numArguments * the expected number of arguments, optional * @param returnType * the expected return type, optional * @return * true if this node is a MethodNode meeting the parameters. false otherwise */ public static boolean isMethodNode(ASTNode node, String methodNamePattern, Integer numArguments, Class returnType) { if (!(node instanceof MethodNode)) { return false; } if (!(((MethodNode) node).getName().matches(methodNamePattern))) { return false; } if (numArguments != null && ((MethodNode)node).getParameters() != null && ((MethodNode)node).getParameters().length != numArguments) { return false; } if (returnType != null && !AstUtil.classNodeImplementsType(((MethodNode) node).getReturnType(), returnType)) { return false; } return true; } public static boolean isMethodNode(ASTNode node, String methodNamePattern, Integer numArguments) { return isMethodNode(node, methodNamePattern, numArguments, null); } public static boolean isMethodNode(ASTNode node, String methodNamePattern) { return isMethodNode(node, methodNamePattern, null, null); } /** * Tells you if the given ASTNode is a VariableExpression with the given name. * @param expression * any AST Node * @param pattern * a string pattern to match * @return * true if the node is a variable with the specified name */ public static boolean isVariable(ASTNode expression, String pattern) { return (expression instanceof VariableExpression && ((VariableExpression) expression).getName().matches(pattern)); } /** * Tells you if the ASTNode has a public modifier on it. If the node does not have modifiers at all (like * a variable expression) then false is returned. * @param node * node to query * @return * true if definitely public, false if not public or unknown */ public static boolean isPublic(ASTNode node) { Integer modifiers = null; // !important - Performance improvement if (node instanceof ClassNode) { modifiers = ((ClassNode) node).getModifiers(); } else if (node instanceof FieldNode) { modifiers = ((FieldNode) node).getModifiers(); }else if (node instanceof MethodNode) { modifiers = ((MethodNode) node).getModifiers(); }else if (node instanceof PropertyNode) { modifiers = ((PropertyNode) node).getModifiers(); } else { LOG.warn("isPublic node is not an expected type"); } if (modifiers != null) { return Modifier.isPublic(modifiers); } return false; } public static boolean isNotNullCheck(Object expression) { if (expression instanceof BinaryExpression) { if ("!=".equals(((BinaryExpression) expression).getOperation().getText())) { if (isNull(((BinaryExpression) expression).getLeftExpression()) || isNull(((BinaryExpression) expression).getRightExpression())) { return true; } } } return false; } public static boolean isNullCheck(Object expression) { if (expression instanceof BinaryExpression) { if ("==".equals(((BinaryExpression) expression).getOperation().getText())) { if (isNull(((BinaryExpression) expression).getLeftExpression()) || isNull(((BinaryExpression) expression).getRightExpression())) { return true; } } } return false; } public static String getNullComparisonTarget(Object expression) { if (expression instanceof BinaryExpression && "!=".equals(((BinaryExpression) expression).getOperation().getText())) { if (isNull(((BinaryExpression) expression).getLeftExpression())) { return ((BinaryExpression) expression).getRightExpression().getText(); } else if (isNull(((BinaryExpression) expression).getRightExpression())) { return ((BinaryExpression) expression).getLeftExpression().getText(); } } return null; } public static boolean isInstanceOfCheck(Object expression) { return (expression instanceof BinaryExpression && "instanceof".equals(((BinaryExpression) expression).getOperation().getText())); } public static String getInstanceOfTarget(Object expression) { if (isInstanceOfCheck(expression)) { return ((BinaryExpression)expression).getLeftExpression().getText(); } return null; } /** * Supports discovering many common JDK types, but not all. */ public static Class getFieldType(ClassNode node, String fieldName) { while (node != null) { for (FieldNode field: node.getFields()) { if (field.getName().equals(fieldName)) { return getFieldType(field); } } node = node.getOuterClass(); } return null; } /** * Supports discovering many common JDK types, but not all. */ public static Class getFieldType(FieldNode field) { // Step 1: Analyze the field's declared type Class declaredType = getClassForClassNode(field.getType()); if (declaredType != null) { return declaredType; } // Step 2: Analyze the cast type of the initial expression if (field.getInitialExpression() != null) { Class castType = getClassForClassNode(field.getInitialExpression().getType()); if (castType != null) { return castType; } } // Step 3: Look at the literal within the constant if (field.getInitialExpression() instanceof ConstantExpression) { Object constantValue = ((ConstantExpression) field.getInitialExpression()).getValue(); if (constantValue instanceof String) { return String.class; } else if (isBoolean(field.getInitialExpression())) { return Boolean.class; } else if (constantValue.getClass() == Integer.class || constantValue.getClass() == Integer.TYPE) { return Integer.class; } else if (constantValue.getClass() == Long.class || constantValue.getClass() == Long.TYPE) { return Long.class; } else if (constantValue.getClass() == Double.class || constantValue.getClass() == Double.TYPE) { return Double.class; } else if (constantValue.getClass() == Float.class || constantValue.getClass() == Float.TYPE) { return Float.class; } } return null; } /** * This is private. It is a helper function for the utils. */ private static Class getClassForClassNode(ClassNode type) { // todo hamlet - move to a different "InferenceUtil" object Class primitiveType = getPrimitiveType(type); if (primitiveType != null) { return primitiveType; } else if (classNodeImplementsType(type, String.class)) { return String.class; } else if (classNodeImplementsType(type, ReentrantLock.class)) { return ReentrantLock.class; } else if (type.getName() != null && type.getName().endsWith("[]")) { return Object[].class; // better type inference could be done, but oh well } return null; } private static Class getPrimitiveType(ClassNode type) { if (classNodeImplementsType(type, Boolean.class) || classNodeImplementsType(type, Boolean.TYPE)) { return Boolean.class; } else if (classNodeImplementsType(type, Long.class) || classNodeImplementsType(type, Long.TYPE)) { return Long.class; } else if (classNodeImplementsType(type, Short.class) || classNodeImplementsType(type, Short.TYPE)) { return Short.class; } else if (classNodeImplementsType(type, Double.class) || classNodeImplementsType(type, Double.TYPE)) { return Double.class; } else if (classNodeImplementsType(type, Float.class) || classNodeImplementsType(type, Float.TYPE)) { return Float.class; } else if (classNodeImplementsType(type, Character.class) || classNodeImplementsType(type, Character.TYPE)) { return Character.class; } else if (classNodeImplementsType(type, Integer.class) || classNodeImplementsType(type, Integer.TYPE)) { return Integer.class; } else if (classNodeImplementsType(type, Long.class) || classNodeImplementsType(type, Long.TYPE)) { return Long.class; } else if (classNodeImplementsType(type, Byte.class) || classNodeImplementsType(type, Byte.TYPE)) { return Byte.class; } return null; } public static boolean isThisReference(Expression expression) { return expression instanceof VariableExpression && "this".equals(((VariableExpression) expression).getName()); } public static boolean isSuperReference(Expression expression) { return expression instanceof VariableExpression && "super".equals(((VariableExpression) expression).getName()); } public static boolean classNodeHasProperty(ClassNode classNode, String propertyName) { if (classNode.getFields() != null) { for (FieldNode field : classNode.getFields()) { if (propertyName.equals(field.getName())) { return true; } } } if (classNode.getProperties() != null) { for (PropertyNode property : classNode.getProperties()) { if (propertyName.equals(property.getName())) { return true; } } } return false; } /** * gets the first non annotation line number of a node, taking into account annotations. */ public static int findFirstNonAnnotationLine(ASTNode node, SourceCode sourceCode) { if (node instanceof AnnotatedNode && !((AnnotatedNode) node).getAnnotations().isEmpty()) { // HACK: Groovy line numbers are broken when annotations have a parameter :( // so we must look at the lineNumber, not the lastLineNumber AnnotationNode lastAnnotation = null; for (AnnotationNode annotation : ((AnnotatedNode) node).getAnnotations()) { if (lastAnnotation == null) lastAnnotation = annotation; else if (lastAnnotation.getLineNumber() < annotation.getLineNumber()) lastAnnotation = annotation; } String rawLine = getRawLine(sourceCode, lastAnnotation.getLastLineNumber()-1); // is the annotation the last thing on the line? if (rawLine.length() > lastAnnotation.getLastColumnNumber()) { // no it is not return lastAnnotation.getLastLineNumber(); } // yes it is the last thing, return the next thing return lastAnnotation.getLastLineNumber() + 1; } return node.getLineNumber(); } public static String getRawLine(SourceCode sourceCode, int lineNumber) { List allLines = sourceCode.getLines(); return (lineNumber >= 0) && lineNumber < allLines.size() ? allLines.get(lineNumber) : null; } public static boolean isOneLiner(Object statement) { if (statement instanceof BlockStatement && ((BlockStatement) statement).getStatements() != null) { if (((BlockStatement) statement).getStatements().size() == 1) { return true; } } return false; } public static boolean expressionIsNullCheck(ASTNode node) { if (!(node instanceof IfStatement)) { return false; } if (!(((IfStatement) node).getBooleanExpression() != null)) { return false; } BooleanExpression booleanExp = ((IfStatement) node).getBooleanExpression(); if (isBinaryExpressionType(booleanExp.getExpression(), "==")) { if (isNull(((BinaryExpression)booleanExp.getExpression()).getLeftExpression()) && ((BinaryExpression) booleanExp.getExpression()).getRightExpression() instanceof VariableExpression) { return true; } else if (isNull(((BinaryExpression) booleanExp.getExpression()).getRightExpression()) && ((BinaryExpression) booleanExp.getExpression()).getLeftExpression() instanceof VariableExpression) { return true; } } else if (booleanExp.getExpression() instanceof NotExpression && ((NotExpression) booleanExp.getExpression()).getExpression() instanceof VariableExpression) { return true; } return false; } public static boolean expressionIsAssignment(ASTNode node, String variableName) { if (node instanceof Expression && isBinaryExpressionType((Expression) node, "=")) { if (isVariable(((BinaryExpression) node).getLeftExpression(), variableName)) { return true; } } else if (node instanceof ExpressionStatement && isBinaryExpressionType(((ExpressionStatement) node).getExpression(), "=")) { if (AstUtil.isVariable(((BinaryExpression)((ExpressionStatement) node).getExpression()).getLeftExpression(), variableName)) { return true; } } return false; } private static String repeat(char c, int count) { String result = ""; for (int x = 0; x <= count; x++) { result = result + c; } return result; } public static String getNodeText(ASTNode expression, SourceCode sourceCode) { String line = sourceCode.getLines().get(expression.getLineNumber() - 1); // If multi-line, only include rest of first line int endColumn = expression.getLineNumber() == expression.getLastLineNumber() ? expression.getLastColumnNumber() - 1 : line.length(); return line.substring(expression.getColumnNumber() - 1, endColumn); } public static String getDeclaration(ASTNode node, SourceCode sourceCode) { if (node.getLineNumber() < 1) return ""; if (node.getLastLineNumber() < 1) return ""; if (node.getColumnNumber() < 1) return ""; if (node.getLastColumnNumber() < 1) return ""; String acc = ""; for (int lineIndex = node.getLineNumber() - 1; lineIndex <= node.getLastLineNumber() -1; lineIndex++) { // the raw line is required to apply columnNumber and lastColumnNumber String line = getRawLine(sourceCode, lineIndex); // extract the relevant part of the first line if (lineIndex == node.getLineNumber() - 1) { int nonRelevantColumns = node.getColumnNumber() - 1; line = line.replaceFirst(".{" + nonRelevantColumns + "}", repeat(' ', nonRelevantColumns)); // retain the line length as it's important when using lastColumnNumber } // extract the relevant part of the last line if (lineIndex == node.getLastLineNumber() - 1) { int stopIndex = node.getLastColumnNumber() < line.length() ? node.getLastColumnNumber() - 2 : line.length() - 1; line = line.substring(0, stopIndex); } if (line.contains("{")) { acc += line.substring(0, line.indexOf("{")); break; } else { acc += line + " "; } } return acc; } public static String createPrettyExpression(ASTNode expression) { if (expression instanceof ConstantExpression && ((ConstantExpression) expression).getValue() instanceof String) { return "'" + expression.getText() + "'"; } if (expression instanceof GStringExpression) { return "\"" + expression.getText() + "\""; } return expression.getText(); } }CodeNarc-0.23/src/main/java/org/codenarc/rule/0000755000175000017500000000000012623571301020414 5ustar ebourgebourgCodeNarc-0.23/src/main/java/org/codenarc/rule/AbstractSharedAstVisitorRule.java0000644000175000017500000000442712006632016027034 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule; import org.codehaus.groovy.ast.ClassNode; import org.codenarc.source.SourceCode; import java.util.List; /** * Abstract superclass for Rules that use a single, shared AstVisitor across all ClassNodes in a source (file). * * @author Chris Mair */ public abstract class AbstractSharedAstVisitorRule extends AbstractAstVisitorRule { protected abstract List getViolations(AstVisitor astVisitor, SourceCode sourceCode); @Override public void applyTo(SourceCode sourceCode, List violations) { if (!sourceCode.isValid()) { return; } AstVisitor visitor = getAstVisitor(sourceCode); applyVisitor(visitor, sourceCode); List allViolations = getViolations(visitor, sourceCode); List visitorViolations = removeSuppressedViolations(allViolations, sourceCode); violations.addAll(visitorViolations); } /** * Subclasses can override to provide an AstVisitor with SourceCode or AST-specific initialization. */ protected AstVisitor getAstVisitor(SourceCode sourceCode) { return super.getAstVisitor(); } protected void applyVisitor(AstVisitor visitor, SourceCode sourceCode) { visitor.setRule(this); visitor.setSourceCode(sourceCode); for (ClassNode classNode : sourceCode.getAst().getClasses()) { if (shouldApplyThisRuleTo(classNode)) { visitor.visitClass(classNode); } } } private List removeSuppressedViolations(List violations, SourceCode sourceCode) { return sourceCode.getSuppressionAnalyzer().filterSuppressedViolations(violations); } }CodeNarc-0.23/src/main/java/org/codenarc/rule/AbstractRule.java0000644000175000017500000003413312142570554023663 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule; import org.apache.log4j.Logger; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.ImportNode; import org.codenarc.source.SourceCode; import org.codenarc.source.SourceCodeCriteria; import org.codenarc.util.ImportUtil; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Abstract superclass for Rules. *

* Each subclass must define an name property (String) and a priority property * (integer 1..3). * * @author Chris Mair * @author Hamlet D'Arcy */ public abstract class AbstractRule implements Rule { private static final Logger LOG = Logger.getLogger(AbstractRule.class); /** * Flag indicating whether this rule should be enabled (applied). Defaults to true. * If set to false, this rule will not produce any violations. */ private boolean enabled = true; /** * This rule is only applied to source code (file) pathnames matching this regular expression. */ private String applyToFilesMatching; /** * This rule is NOT applied to source code (file) pathnames matching this regular expression. */ private String doNotApplyToFilesMatching; /** * This rule is only applied to source code (file) names matching this value. The name may optionally * contain a path. If a path is specified, then the source code path must match it. If no path is * specified, then only the source code (file) name is compared (i.e., its path is ignored). * The value may optionally be a comma-separated list of names, in which case one of the names must match. * The name(s) may optionally include wildcard characters ('*' or '?'). */ private String applyToFileNames; /** * This rule is NOT applied to source code (file) names matching this value. The name may optionally * contain a path. If a path is specified, then the source code path must match it. If no path is * specified, then only the source code (file) name is compared (i.e., its path is ignored). * The value may optionally be a comma-separated list of names, in which case any one of the names can match. * The name(s) may optionally include wildcard characters ('*' or '?'). */ private String doNotApplyToFileNames; /** * If not null, this is used as the message for all violations of this rule, overriding any * message generated by the concrete rule subclass. Defaults to null. Note that setting this * to an empty string "hides" the message, if any, generated by the actual rule. */ private String violationMessage; /** * If not null, this is used as the description text for this rule, overriding any * description text found in the i18n resource bundles. Defaults to null. */ private String description; /** * @return the unique name for this rule */ public abstract String getName(); /** * Set the unique name for this rule * @param name - the name for this rule; this should be unique */ public abstract void setName(String name); /** * @return the priority of this rule, between 1 (highest priority) and 3 (lowest priority), inclusive. */ public abstract int getPriority(); /** * Set the priority for this rule * @param priority - the priority of this rule, between 1 (highest priority) and 3 (lowest priority), inclusive. */ public abstract void setPriority(int priority); /** * @return the required compiler phase (as in {@link org.codehaus.groovy.control.Phases}) * of the AST of the {@link SourceCode} * handed to the rule via {@link #applyTo(SourceCode sourceCode)} */ public int getCompilerPhase() { return SourceCode.DEFAULT_COMPILER_PHASE; } /** * Apply this rule to the specified source and return a list of violations (or an empty List) * @param sourceCode - the source to apply this rule to * @param violations - the List of violations to which new violations from this rule are to be added */ public abstract void applyTo(SourceCode sourceCode, List violations); /** * Apply this rule to the specified source and return a list of violations (or an empty List). * This implementation delegates to the abstract applyCode(SourceCode,List), provided by * concrete subclasses. This template method simplifies subclass implementations and also * enables common handling of enablement logic. * @param sourceCode - the source to apply this rule to * @return the List of violations; may be empty */ public List applyTo(SourceCode sourceCode) throws Throwable { try { validateAstCompilerPhase(sourceCode); validate(); List violations = new ArrayList(); if (shouldApplyThisRuleTo(sourceCode)) { applyTo(sourceCode, violations); } overrideViolationMessageIfNecessary(violations); return violations; } catch(Throwable t) { LOG.error("Error from [" + getClass().getName() + "] processing source file [" + sourceCode.getPath() + "]", t); throw t; } } private void validateAstCompilerPhase(SourceCode sourceCode) { if (sourceCode.getAstCompilerPhase() != getCompilerPhase()) { throw new IllegalArgumentException("This rule requires SourceCode with AST compiler phase '" + getCompilerPhase() + "', but was handed one with AST compiler phase '" + sourceCode.getAstCompilerPhase() + "'"); } } /** * Allows rules to check whether preconditions are satisfied and short-circuit execution * (i.e., do nothing) if those preconditions are not satisfied. Return true by default. * This method is provided as a placeholder so subclasses can optionally override. * @return true if all preconditions for this rule are satisfied */ public boolean isReady() { return true; } /** * Allows rules to perform validation. Do nothing by default. * This method is provided as a placeholder so subclasses can optionally override. * Subclasses will typically use assert calls to verify required preconditions. */ public void validate() { } public String toString() { return String.format( "%s[name=%s, priority=%s]", getClassNameNoPackage(), getName(), getPriority() ); } /** * Create and return a new Violation for this rule and the specified values * @param lineNumber - the line number for the violation; may be null * @param sourceLine - the source line for the violation; may be null * @param message - the message for the violation; may be null * @return a new Violation object */ protected Violation createViolation(Integer lineNumber, String sourceLine, String message) { Violation violation = new Violation(); violation.setRule(this); violation.setSourceLine(sourceLine); violation.setLineNumber(lineNumber); violation.setMessage(message); return violation; } /** * Create and return a new Violation for this rule and the specified values * @param lineNumber - the line number for the violation; may be null * @return a new Violation object */ @Deprecated // should really supply an AST Node protected Violation createViolation(Integer lineNumber, String message) { return createViolation(lineNumber, null, message); } /** * Create and return a new Violation for this rule and the specified values * @param lineNumber - the line number for the violation; may be null * @return a new Violation object */ @Deprecated protected Violation createViolation(Integer lineNumber) { return createViolation(lineNumber, null, null); } /** * Create a new Violation for the AST node. * @param sourceCode - the SourceCode * @param node - the Groovy AST Node * @param message - the message for the violation; defaults to null */ protected Violation createViolation(SourceCode sourceCode, ASTNode node, String message) { String sourceLine = sourceCode.line(node.getLineNumber()-1); return createViolation(node.getLineNumber(), sourceLine, message); } /** * Create a new Violation for the AST node. * @param sourceCode - the SourceCode * @param node - the Groovy AST Node */ @Deprecated // should really supply a message protected Violation createViolation(SourceCode sourceCode, ASTNode node) { return createViolation(sourceCode, node, null); } /** * Create and return a new Violation for this rule and the specified import * @param sourceCode - the SourceCode * @param importNode - the ImportNode for the import triggering the violation * @return a new Violation object */ protected Violation createViolationForImport(SourceCode sourceCode, ImportNode importNode, String message) { Map importInfo = ImportUtil.sourceLineAndNumberForImport(sourceCode, importNode); Violation violation = new Violation(); violation.setRule(this); violation.setSourceLine((String) importInfo.get("sourceLine")); violation.setLineNumber((Integer) importInfo.get("lineNumber")); violation.setMessage(message); return violation; } /** * Create and return a new Violation for this rule and the specified import * @param sourceCode - the SourceCode * @param importNode - the ImportNode for the import triggering the violation * @return a new Violation object */ @Deprecated // should really supply a message protected Violation createViolationForImport(SourceCode sourceCode, ImportNode importNode) { return createViolationForImport(sourceCode, importNode, null); } /** * Create and return a new Violation for this rule and the specified import className and alias * @param sourceCode - the SourceCode * @param className - the class name (as specified within the import statement) * @param alias - the alias for the import statement * @param violationMessage - the violation message; may be null * @return a new Violation object */ protected Violation createViolationForImport(SourceCode sourceCode, String className, String alias, String violationMessage) { Map importInfo = ImportUtil.sourceLineAndNumberForImport(sourceCode, className, alias); Violation violation = new Violation(); violation.setRule(this); violation.setSourceLine((String) importInfo.get("sourceLine")); violation.setLineNumber((Integer) importInfo.get("lineNumber")); violation.setMessage(violationMessage); return violation; } private boolean shouldApplyThisRuleTo(SourceCode sourceCode) { if (!enabled) return false; if (!isReady()) return false; SourceCodeCriteria criteria = new SourceCodeCriteria(); criteria.setApplyToFilesMatching(getApplyToFilesMatching()); criteria.setDoNotApplyToFilesMatching(getDoNotApplyToFilesMatching()); criteria.setApplyToFileNames(getApplyToFileNames()); criteria.setDoNotApplyToFileNames(getDoNotApplyToFileNames()); return criteria.matches(sourceCode); } private String getClassNameNoPackage() { String className = getClass().getName(); int indexOfLastPeriod = className.lastIndexOf('.'); return (indexOfLastPeriod == -1) ? className : className.substring(indexOfLastPeriod + 1); } /** * If the violationMessage property of this rule has been set, then use it to set the * message within each violation, overriding the original message(s), if any. */ private void overrideViolationMessageIfNecessary(List violations) { if (violationMessage != null && violations != null) { for (Violation violation : violations) { violation.setMessage(violationMessage); } } } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public String getApplyToFilesMatching() { return applyToFilesMatching; } public void setApplyToFilesMatching(String applyToFilesMatching) { this.applyToFilesMatching = applyToFilesMatching; } public String getDoNotApplyToFilesMatching() { return doNotApplyToFilesMatching; } public void setDoNotApplyToFilesMatching(String doNotApplyToFilesMatching) { this.doNotApplyToFilesMatching = doNotApplyToFilesMatching; } public String getApplyToFileNames() { return applyToFileNames; } public void setApplyToFileNames(String applyToFileNames) { this.applyToFileNames = applyToFileNames; } public String getDoNotApplyToFileNames() { return doNotApplyToFileNames; } public void setDoNotApplyToFileNames(String doNotApplyToFileNames) { this.doNotApplyToFileNames = doNotApplyToFileNames; } public String getViolationMessage() { return violationMessage; } public void setViolationMessage(String violationMessage) { this.violationMessage = violationMessage; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }CodeNarc-0.23/src/main/java/org/codenarc/rule/Rule.java0000644000175000017500000000306712142570476022204 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule; import org.codenarc.source.SourceCode; import java.util.List; /** * Represents a source code analysis rule . * * @author Chris Mair */ public interface Rule { /** * Apply this rule to the specified source and return a list of violations (or an empty List) * @param sourceCode - the source to apply this rule to * @return the List of violations; may be empty * @throws Throwable could throw anything */ List applyTo(SourceCode sourceCode) throws Throwable; /** * @return the priority of this rule; must be 1, 2 or 3 */ int getPriority(); /** * @return the unique id for this rule */ String getName(); /** * @return the required compiler phase (as in {@link org.codehaus.groovy.control.Phases}) * of the AST of the {@link SourceCode} * handed to the rule via {@link #applyTo(SourceCode sourceCode)} */ int getCompilerPhase(); }CodeNarc-0.23/src/main/java/org/codenarc/rule/AbstractFieldVisitor.java0000644000175000017500000003113512463433073025356 0ustar ebourgebourgpackage org.codenarc.rule; import org.codehaus.groovy.ast.*; import org.codehaus.groovy.ast.expr.*; import org.codehaus.groovy.ast.stmt.*; import org.codehaus.groovy.classgen.BytecodeExpression; import org.codehaus.groovy.control.SourceUnit; import org.codenarc.source.SourceCode; import org.codenarc.util.AstUtil; import java.util.*; /** * This is the base class for AST Visitors that only need to visit the fields of * a class. It will not visit anything except the FieldNode. It is much faster than * the alternative of visiting the whole class.
*
* When you override visitField(FieldNode), there is no need to invoke the super method. */ public class AbstractFieldVisitor extends ClassCodeVisitorSupport implements AstVisitor { private Rule rule; private SourceCode sourceCode; private final List violations = new ArrayList(); @Override public void visitClass(ClassNode node) { Set nodes = new HashSet(); for (PropertyNode property : node.getProperties()) { if (property.getField() != null) { nodes.add(property.getField()); } } for (FieldNode field : node.getFields()) { nodes.add(field); } List sortedFields = new ArrayList(nodes); Collections.sort(sortedFields, new Comparator() { public int compare(FieldNode o1, FieldNode o2) { return o1.getLineNumber() - o2.getLineNumber(); } }); for (FieldNode field : sortedFields) { visitField(field); } } /** * Add a new Violation to the list of violations found by this visitor. * Only add the violation if the node lineNumber >= 0. * * @param node - the Groovy AST Node * @param message - the message for the violation; defaults to null */ protected void addViolation(FieldNode node, String message) { if (node.getLineNumber() >= 0) { int lineNumber = AstUtil.findFirstNonAnnotationLine(node, sourceCode); String sourceLine = sourceCode.line(AstUtil.findFirstNonAnnotationLine(node, sourceCode) - 1); Violation violation = new Violation(); violation.setRule(rule); violation.setLineNumber(lineNumber); violation.setSourceLine(sourceLine); violation.setMessage(String.format( "Violation in class %s. %s", node.getOwner().getName(), message )); violations.add(violation); } } protected SourceCode getSourceCode() { return sourceCode; } /** * Set the Rule associated with this visitor * * @param rule - the Rule */ public void setRule(Rule rule) { this.rule = rule; } /** * Gets the rule for this visitor. * @return * the rule */ public Rule getRule() { return rule; } /** * Set the SourceCode associated with this visitor * * @param sourceCode - the SourceCode */ public void setSourceCode(SourceCode sourceCode) { this.sourceCode = sourceCode; } /** * Retrieve the List of Violations resulting from applying this visitor * * @return the List of Violations; may be empty */ public List getViolations() { return violations; } @Override protected final void visitObjectInitializerStatements(ClassNode node) { throw new UnsupportedOperationException(); } @Override protected final SourceUnit getSourceUnit() { throw new RuntimeException("should never be called"); } @Override public final void visitPackage(PackageNode node) { throw new UnsupportedOperationException(); } @Override public final void visitImports(ModuleNode node) { throw new UnsupportedOperationException(); } @Override public final void visitAnnotations(AnnotatedNode node) { throw new UnsupportedOperationException(); } @Override protected final void visitClassCodeContainer(Statement code) { throw new UnsupportedOperationException(); } @Override public final void visitVariableExpression(VariableExpression expression) { throw new UnsupportedOperationException(); } @Override protected final void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { throw new UnsupportedOperationException(); } @Override public final void visitConstructor(ConstructorNode node) { throw new UnsupportedOperationException(); } @Override public final void visitProperty(PropertyNode node) { throw new UnsupportedOperationException(); } @Override protected final void addError(String msg, ASTNode expr) { super.addError(msg, expr); } @Override protected final void visitStatement(Statement statement) { throw new UnsupportedOperationException(); } @Override public final void visitAssertStatement(AssertStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitBlockStatement(BlockStatement block) { throw new UnsupportedOperationException(); } @Override public final void visitBreakStatement(BreakStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitCaseStatement(CaseStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitCatchStatement(CatchStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitContinueStatement(ContinueStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitDoWhileLoop(DoWhileStatement loop) { throw new UnsupportedOperationException(); } @Override public final void visitExpressionStatement(ExpressionStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitForLoop(ForStatement forLoop) { throw new UnsupportedOperationException(); } @Override public final void visitIfElse(IfStatement ifElse) { throw new UnsupportedOperationException(); } @Override public final void visitReturnStatement(ReturnStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitSwitch(SwitchStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitSynchronizedStatement(SynchronizedStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitThrowStatement(ThrowStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitTryCatchFinally(TryCatchStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitWhileLoop(WhileStatement loop) { throw new UnsupportedOperationException(); } @Override protected final void visitEmptyStatement(EmptyStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitMethodCallExpression(MethodCallExpression call) { throw new UnsupportedOperationException(); } @Override public final void visitStaticMethodCallExpression(StaticMethodCallExpression call) { throw new UnsupportedOperationException(); } @Override public final void visitConstructorCallExpression(ConstructorCallExpression call) { throw new UnsupportedOperationException(); } @Override public final void visitBinaryExpression(BinaryExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitTernaryExpression(TernaryExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitShortTernaryExpression(ElvisOperatorExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitPostfixExpression(PostfixExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitPrefixExpression(PrefixExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitBooleanExpression(BooleanExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitNotExpression(NotExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitClosureExpression(ClosureExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitTupleExpression(TupleExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitListExpression(ListExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitArrayExpression(ArrayExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitMapExpression(MapExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitMapEntryExpression(MapEntryExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitRangeExpression(RangeExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitSpreadExpression(SpreadExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitSpreadMapExpression(SpreadMapExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitMethodPointerExpression(MethodPointerExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitUnaryMinusExpression(UnaryMinusExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitUnaryPlusExpression(UnaryPlusExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitBitwiseNegationExpression(BitwiseNegationExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitCastExpression(CastExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitConstantExpression(ConstantExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitClassExpression(ClassExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitDeclarationExpression(DeclarationExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitPropertyExpression(PropertyExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitAttributeExpression(AttributeExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitFieldExpression(FieldExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitGStringExpression(GStringExpression expression) { throw new UnsupportedOperationException(); } @Override protected final void visitListOfExpressions(List list) { throw new UnsupportedOperationException(); } @Override public final void visitArgumentlistExpression(ArgumentListExpression ale) { throw new UnsupportedOperationException(); } @Override public final void visitClosureListExpression(ClosureListExpression cle) { throw new UnsupportedOperationException(); } @Override public final void visitBytecodeExpression(BytecodeExpression cle) { throw new UnsupportedOperationException(); } @Override public final void visitMethod(MethodNode node) { throw new UnsupportedOperationException(); } } CodeNarc-0.23/src/main/java/org/codenarc/rule/AbstractMethodCallExpressionVisitor.java0000644000175000017500000003061212463433117030425 0ustar ebourgebourgpackage org.codenarc.rule; import org.codehaus.groovy.ast.*; import org.codehaus.groovy.ast.expr.*; import org.codehaus.groovy.ast.stmt.*; import org.codehaus.groovy.classgen.BytecodeExpression; import org.codehaus.groovy.control.SourceUnit; import org.codenarc.source.SourceCode; import org.codenarc.util.AstUtil; import java.util.ArrayList; import java.util.List; /** * This is the base class for AST Visitors that only need to visit the MethodCallExpressions of * a class. It will not visit anything except MethodCallExpression-s. It is much faster than * the alternative of visiting the whole class.
*
* When you override visitField(FieldNode), there is no need to invoke the super method. */ public class AbstractMethodCallExpressionVisitor extends ClassCodeVisitorSupport implements AstVisitor { private Rule rule; private SourceCode sourceCode; private final List violations = new ArrayList(); private ClassNode currentClassNode = null; @Override public void visitClass(ClassNode node) { currentClassNode = node; if (sourceCode == null) { throw new IllegalStateException("CodeNarc developer error. SourceCode may not be null"); } List expressions = sourceCode.getMethodCallExpressions().get(node); if (expressions != null) { for (MethodCallExpression expression : expressions) { visitMethodCallExpression(expression); } } currentClassNode = null; } /** * Add a new Violation to the list of violations found by this visitor. * Only add the violation if the node lineNumber >= 0. * * @param node - the Groovy AST Node * @param message - the message for the violation; defaults to null */ protected void addViolation(MethodCallExpression node, String message) { if (node.getLineNumber() >= 0) { int lineNumber = AstUtil.findFirstNonAnnotationLine(node, sourceCode); String sourceLine = sourceCode.line(AstUtil.findFirstNonAnnotationLine(node, sourceCode) - 1); Violation violation = new Violation(); violation.setRule(rule); violation.setLineNumber(lineNumber); violation.setSourceLine(sourceLine); if (currentClassNode != null) { violation.setMessage(String.format( "Violation in class %s. %s", currentClassNode.getName(), message )); } else { violation.setMessage(message); } violations.add(violation); } } protected SourceCode getSourceCode() { return sourceCode; } /** * Set the Rule associated with this visitor * * @param rule - the Rule */ public void setRule(Rule rule) { this.rule = rule; } /** * Gets the rule for this visitor. * @return * the rule */ public Rule getRule() { return rule; } /** * Set the SourceCode associated with this visitor * * @param sourceCode - the SourceCode */ public void setSourceCode(SourceCode sourceCode) { this.sourceCode = sourceCode; } /** * Retrieve the List of Violations resulting from applying this visitor * * @return the List of Violations; may be empty */ public List getViolations() { return violations; } @Override protected final void visitObjectInitializerStatements(ClassNode node) { super.visitObjectInitializerStatements(node); } @Override protected final SourceUnit getSourceUnit() { throw new RuntimeException("should never be called"); } @Override public final void visitPackage(PackageNode node) { super.visitPackage(node); } @Override public final void visitImports(ModuleNode node) { super.visitImports(node); } @Override public final void visitAnnotations(AnnotatedNode node) { super.visitAnnotations(node); } @Override protected final void visitClassCodeContainer(Statement code) { super.visitClassCodeContainer(code); } @Override public final void visitVariableExpression(VariableExpression expression) { super.visitVariableExpression(expression); } @Override protected final void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { super.visitConstructorOrMethod(node, isConstructor); } @Override public final void visitConstructor(ConstructorNode node) { super.visitConstructor(node); } @Override public final void visitProperty(PropertyNode node) { super.visitProperty(node); } @Override protected final void addError(String msg, ASTNode expr) { super.addError(msg, expr); } @Override protected final void visitStatement(Statement statement) { super.visitStatement(statement); } @Override public final void visitAssertStatement(AssertStatement statement) { super.visitAssertStatement(statement); } @Override public final void visitBlockStatement(BlockStatement block) { super.visitBlockStatement(block); } @Override public final void visitBreakStatement(BreakStatement statement) { super.visitBreakStatement(statement); } @Override public final void visitCaseStatement(CaseStatement statement) { super.visitCaseStatement(statement); } @Override public final void visitCatchStatement(CatchStatement statement) { super.visitCatchStatement(statement); } @Override public final void visitContinueStatement(ContinueStatement statement) { super.visitContinueStatement(statement); } @Override public final void visitDoWhileLoop(DoWhileStatement loop) { super.visitDoWhileLoop(loop); } @Override public final void visitExpressionStatement(ExpressionStatement statement) { super.visitExpressionStatement(statement); } @Override public final void visitForLoop(ForStatement forLoop) { super.visitForLoop(forLoop); } @Override public final void visitIfElse(IfStatement ifElse) { super.visitIfElse(ifElse); } @Override public final void visitReturnStatement(ReturnStatement statement) { super.visitReturnStatement(statement); } @Override public final void visitSwitch(SwitchStatement statement) { super.visitSwitch(statement); } @Override public final void visitSynchronizedStatement(SynchronizedStatement statement) { super.visitSynchronizedStatement(statement); } @Override public final void visitThrowStatement(ThrowStatement statement) { super.visitThrowStatement(statement); } @Override public final void visitTryCatchFinally(TryCatchStatement statement) { super.visitTryCatchFinally(statement); } @Override public final void visitWhileLoop(WhileStatement loop) { super.visitWhileLoop(loop); } @Override protected final void visitEmptyStatement(EmptyStatement statement) { super.visitEmptyStatement(statement); } @Override public final void visitStaticMethodCallExpression(StaticMethodCallExpression call) { super.visitStaticMethodCallExpression(call); } @Override public final void visitConstructorCallExpression(ConstructorCallExpression call) { super.visitConstructorCallExpression(call); } @Override public final void visitBinaryExpression(BinaryExpression expression) { super.visitBinaryExpression(expression); } @Override public final void visitTernaryExpression(TernaryExpression expression) { super.visitTernaryExpression(expression); } @Override public final void visitShortTernaryExpression(ElvisOperatorExpression expression) { super.visitShortTernaryExpression(expression); } @Override public final void visitPostfixExpression(PostfixExpression expression) { super.visitPostfixExpression(expression); } @Override public final void visitPrefixExpression(PrefixExpression expression) { super.visitPrefixExpression(expression); } @Override public final void visitBooleanExpression(BooleanExpression expression) { super.visitBooleanExpression(expression); } @Override public final void visitNotExpression(NotExpression expression) { super.visitNotExpression(expression); } @Override public final void visitClosureExpression(ClosureExpression expression) { super.visitClosureExpression(expression); } @Override public final void visitTupleExpression(TupleExpression expression) { super.visitTupleExpression(expression); } @Override public final void visitListExpression(ListExpression expression) { super.visitListExpression(expression); } @Override public final void visitArrayExpression(ArrayExpression expression) { super.visitArrayExpression(expression); } @Override public final void visitMapExpression(MapExpression expression) { super.visitMapExpression(expression); } @Override public final void visitMapEntryExpression(MapEntryExpression expression) { super.visitMapEntryExpression(expression); } @Override public final void visitRangeExpression(RangeExpression expression) { super.visitRangeExpression(expression); } @Override public final void visitSpreadExpression(SpreadExpression expression) { super.visitSpreadExpression(expression); } @Override public final void visitSpreadMapExpression(SpreadMapExpression expression) { super.visitSpreadMapExpression(expression); } @Override public final void visitMethodPointerExpression(MethodPointerExpression expression) { super.visitMethodPointerExpression(expression); } @Override public final void visitUnaryMinusExpression(UnaryMinusExpression expression) { super.visitUnaryMinusExpression(expression); } @Override public final void visitUnaryPlusExpression(UnaryPlusExpression expression) { super.visitUnaryPlusExpression(expression); } @Override public final void visitBitwiseNegationExpression(BitwiseNegationExpression expression) { super.visitBitwiseNegationExpression(expression); } @Override public final void visitCastExpression(CastExpression expression) { super.visitCastExpression(expression); } @Override public final void visitConstantExpression(ConstantExpression expression) { super.visitConstantExpression(expression); } @Override public final void visitClassExpression(ClassExpression expression) { super.visitClassExpression(expression); } @Override public final void visitDeclarationExpression(DeclarationExpression expression) { super.visitDeclarationExpression(expression); } @Override public final void visitPropertyExpression(PropertyExpression expression) { super.visitPropertyExpression(expression); } @Override public final void visitAttributeExpression(AttributeExpression expression) { super.visitAttributeExpression(expression); } @Override public final void visitFieldExpression(FieldExpression expression) { super.visitFieldExpression(expression); } @Override public final void visitGStringExpression(GStringExpression expression) { super.visitGStringExpression(expression); } @Override protected final void visitListOfExpressions(List list) { super.visitListOfExpressions(list); } @Override public final void visitArgumentlistExpression(ArgumentListExpression ale) { super.visitArgumentlistExpression(ale); } @Override public final void visitClosureListExpression(ClosureListExpression cle) { super.visitClosureListExpression(cle); } @Override public final void visitBytecodeExpression(BytecodeExpression cle) { super.visitBytecodeExpression(cle); } @Override public final void visitMethod(MethodNode node) { throw new UnsupportedOperationException(); } @Override public final void visitField(FieldNode node) { throw new UnsupportedOperationException(); } } CodeNarc-0.23/src/main/java/org/codenarc/rule/AbstractMethodVisitor.java0000644000175000017500000003263412463433150025554 0ustar ebourgebourgpackage org.codenarc.rule; import org.codehaus.groovy.ast.*; import org.codehaus.groovy.ast.expr.*; import org.codehaus.groovy.ast.stmt.*; import org.codehaus.groovy.classgen.BytecodeExpression; import org.codehaus.groovy.control.SourceUnit; import org.codenarc.source.SourceCode; import org.codenarc.util.AstUtil; import java.util.ArrayList; import java.util.List; /** * This is the base class for AST Visitors that only need to visit the methods of * a class. It will not visit anything except the MethodNode. It is much faster than * the alternative of visiting the whole class.
*
* When you override visitMethod(MethodNode), there is no need to invoke the super method. */ public class AbstractMethodVisitor extends ClassCodeVisitorSupport implements AstVisitor { private Rule rule; private SourceCode sourceCode; private final List violations = new ArrayList(); private ClassNode currentClassNode = null; @Override public void visitClass(ClassNode node) { currentClassNode = node; for (MethodNode method : node.getMethods()) { visitMethod(method); } currentClassNode = null; } protected final ClassNode getCurrentClassNode() { return currentClassNode; } protected final String getCurrentClassName() { if (currentClassNode == null) { return ""; } return currentClassNode.getName(); } /** * Add a new Violation to the list of violations found by this visitor. * Only add the violation if the node lineNumber >= 0. * * @param node - the Groovy AST Node * @param message - the message for the violation; defaults to null */ protected void addViolation(ASTNode node, String message) { if (node.getLineNumber() >= 0) { int lineNumber = AstUtil.findFirstNonAnnotationLine(node, sourceCode); String sourceLine = sourceCode.line(AstUtil.findFirstNonAnnotationLine(node, sourceCode) - 1); Violation violation = new Violation(); violation.setRule(rule); violation.setLineNumber(lineNumber); violation.setSourceLine(sourceLine); violation.setMessage(message); violations.add(violation); } } /** * Add a new Violation to the list of violations found by this visitor. * Only add the violation if the node lineNumber >= 0. * * @param node - the Groovy AST Node * @param message - the message for the violation; defaults to null */ protected void addViolation(MethodNode node, String message) { addViolation((ASTNode) node, String.format( "Violation in class %s. %s", node.getDeclaringClass().getNameWithoutPackage(), message )); } /** * Add a new Violation to the list of violations found by this visitor. * Only add the violation if the node lineNumber >= 0. * * @param node - the Groovy AST Node * @param message - the message for the violation; defaults to null */ protected void addViolation(ClassNode node, String message) { addViolation((ASTNode) node, String.format( "Violation in class %s. %s", node.getNameWithoutPackage(), message )); } protected SourceCode getSourceCode() { return sourceCode; } /** * Set the Rule associated with this visitor * * @param rule - the Rule */ public void setRule(Rule rule) { this.rule = rule; } /** * Gets the rule for this visitor. * * @return the rule */ public Rule getRule() { return rule; } /** * Set the SourceCode associated with this visitor * * @param sourceCode - the SourceCode */ public void setSourceCode(SourceCode sourceCode) { this.sourceCode = sourceCode; } /** * Retrieve the List of Violations resulting from applying this visitor * * @return the List of Violations; may be empty */ public List getViolations() { return violations; } @Override public final void visitField(FieldNode node) { throw new UnsupportedOperationException(); } @Override protected final void visitObjectInitializerStatements(ClassNode node) { throw new UnsupportedOperationException(); } @Override protected final SourceUnit getSourceUnit() { throw new RuntimeException("should never be called"); } @Override public final void visitPackage(PackageNode node) { throw new UnsupportedOperationException(); } @Override public final void visitImports(ModuleNode node) { throw new UnsupportedOperationException(); } @Override public final void visitAnnotations(AnnotatedNode node) { throw new UnsupportedOperationException(); } @Override protected final void visitClassCodeContainer(Statement code) { throw new UnsupportedOperationException(); } @Override public final void visitVariableExpression(VariableExpression expression) { throw new UnsupportedOperationException(); } @Override protected final void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { throw new UnsupportedOperationException(); } @Override public final void visitConstructor(ConstructorNode node) { throw new UnsupportedOperationException(); } @Override public final void visitProperty(PropertyNode node) { throw new UnsupportedOperationException(); } @Override protected final void addError(String msg, ASTNode expr) { super.addError(msg, expr); } @Override protected final void visitStatement(Statement statement) { throw new UnsupportedOperationException(); } @Override public final void visitAssertStatement(AssertStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitBlockStatement(BlockStatement block) { throw new UnsupportedOperationException(); } @Override public final void visitBreakStatement(BreakStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitCaseStatement(CaseStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitCatchStatement(CatchStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitContinueStatement(ContinueStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitDoWhileLoop(DoWhileStatement loop) { throw new UnsupportedOperationException(); } @Override public final void visitExpressionStatement(ExpressionStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitForLoop(ForStatement forLoop) { throw new UnsupportedOperationException(); } @Override public final void visitIfElse(IfStatement ifElse) { throw new UnsupportedOperationException(); } @Override public final void visitReturnStatement(ReturnStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitSwitch(SwitchStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitSynchronizedStatement(SynchronizedStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitThrowStatement(ThrowStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitTryCatchFinally(TryCatchStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitWhileLoop(WhileStatement loop) { throw new UnsupportedOperationException(); } @Override protected final void visitEmptyStatement(EmptyStatement statement) { throw new UnsupportedOperationException(); } @Override public final void visitMethodCallExpression(MethodCallExpression call) { throw new UnsupportedOperationException(); } @Override public final void visitStaticMethodCallExpression(StaticMethodCallExpression call) { throw new UnsupportedOperationException(); } @Override public final void visitConstructorCallExpression(ConstructorCallExpression call) { throw new UnsupportedOperationException(); } @Override public final void visitBinaryExpression(BinaryExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitTernaryExpression(TernaryExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitShortTernaryExpression(ElvisOperatorExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitPostfixExpression(PostfixExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitPrefixExpression(PrefixExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitBooleanExpression(BooleanExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitNotExpression(NotExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitClosureExpression(ClosureExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitTupleExpression(TupleExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitListExpression(ListExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitArrayExpression(ArrayExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitMapExpression(MapExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitMapEntryExpression(MapEntryExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitRangeExpression(RangeExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitSpreadExpression(SpreadExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitSpreadMapExpression(SpreadMapExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitMethodPointerExpression(MethodPointerExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitUnaryMinusExpression(UnaryMinusExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitUnaryPlusExpression(UnaryPlusExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitBitwiseNegationExpression(BitwiseNegationExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitCastExpression(CastExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitConstantExpression(ConstantExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitClassExpression(ClassExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitDeclarationExpression(DeclarationExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitPropertyExpression(PropertyExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitAttributeExpression(AttributeExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitFieldExpression(FieldExpression expression) { throw new UnsupportedOperationException(); } @Override public final void visitGStringExpression(GStringExpression expression) { throw new UnsupportedOperationException(); } @Override protected final void visitListOfExpressions(List list) { throw new UnsupportedOperationException(); } @Override public final void visitArgumentlistExpression(ArgumentListExpression ale) { throw new UnsupportedOperationException(); } @Override public final void visitClosureListExpression(ClosureListExpression cle) { throw new UnsupportedOperationException(); } @Override public final void visitBytecodeExpression(BytecodeExpression cle) { throw new UnsupportedOperationException(); } @Override public void visitMethod(MethodNode node) { throw new UnsupportedOperationException(); } } CodeNarc-0.23/src/main/java/org/codenarc/rule/AbstractAstVisitorRule.java0000644000175000017500000001504012044607772025713 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.ModuleNode; import org.codenarc.source.SourceCode; import org.codenarc.util.WildcardPattern; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * Abstract superclass for Rules that use a Groovy AST Visitor. *

* Each subclass must set the astVisitorClass property or else define a new * property with the same name, specifying the Class of the AstVisitor * to applied to the specified source code. * * @author Chris Mair * @author Hamlet D'Arcy */ public abstract class AbstractAstVisitorRule extends AbstractRule { protected static final String DEFAULT_CONST_NAME = "[A-Z][A-Z0-9_]*"; protected static final String DEFAULT_FIELD_NAME = "[a-z][a-zA-Z0-9]*"; protected static final String DEFAULT_VAR_NAME = "[a-z][a-zA-Z0-9]*"; protected static final String DEFAULT_TEST_FILES = ".*(Test|Tests|TestCase)\\.groovy"; protected static final String DEFAULT_TEST_CLASS_NAMES = "*Test,*Tests,*TestCase"; public static final String CLOSURE_TEXT = "{ -> ... }"; /** Each concrete subclass must either set this property or define its own property with the same name */ protected Class getAstVisitorClass() { return null; } /** * This rule is only applied to classes with names matching this value. * * The value may optionally be a comma-separated list of names, in which case one of the names must match. * * If a name includes a period ('.'), then it is assumed to specify a full package name, so the name * (pattern) is matched against each fully-qualified class name. Otherwise it is matched only against * the class name without a package. * * The name(s) may optionally include wildcard characters ('*' or '?'). */ private String applyToClassNames; /** * This rule is NOT applied to classes with names matching this value. * * The value may optionally be a comma-separated list of names, in which case any one of the names can match. * * If a name includes a period ('.'), then it is assumed to specify a full package name, so the name * (pattern) is matched against each fully-qualified class name. Otherwise it is matched only against * the class name without a package. * * The name(s) may optionally include wildcard characters ('*' or '?'). */ private String doNotApplyToClassNames; public AstVisitor getAstVisitor() { Class visitorClass = getAstVisitorClass(); if (visitorClass == null) throw new IllegalArgumentException("The astVisitorClass property must not be null"); if (!AstVisitor.class.isAssignableFrom(visitorClass)) throw new IllegalArgumentException("The astVisitorClass property must specify a class that implements AstVisitor"); try { return (AstVisitor) visitorClass.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } @Override public void applyTo(SourceCode sourceCode, List violations) { // If AST is null, skip this source code ModuleNode ast = sourceCode.getAst(); if (ast != null && ast.getClasses() != null) { for (ClassNode classNode : ast.getClasses()) { if (shouldApplyThisRuleTo(classNode)) { AstVisitor visitor = getAstVisitor(); visitor.setRule(this); visitor.setSourceCode(sourceCode); visitor.visitClass(classNode); violations.addAll(visitor.getViolations()); } } } Collections.sort(violations, new Comparator() { public int compare(Violation o1, Violation o2) { if (o1 == null && o2 == null) return 0; if (o1 == null) return -1; if (o2 == null) return 1; if (o1.getLineNumber() == null && o2.getLineNumber() == null) return 0; if (o1.getLineNumber() == null) return -1; if (o2.getLineNumber() == null) return 1; return o1.getLineNumber().compareTo(o2.getLineNumber()); } }); } /** * Return true if this rule should be applied for the specified ClassNode, based on the * configuration of this rule. * @param classNode - the ClassNode * @return true if this rule should be applied for the specified ClassNode */ protected boolean shouldApplyThisRuleTo(ClassNode classNode) { // TODO Consider caching applyTo, doNotApplyTo and associated WildcardPatterns boolean shouldApply = true; String applyTo = getApplyToClassNames(); String doNotApplyTo = getDoNotApplyToClassNames(); if (applyTo != null && applyTo.length() > 0) { WildcardPattern pattern = new WildcardPattern(applyTo, true); shouldApply = pattern.matches(classNode.getNameWithoutPackage()) || pattern.matches(classNode.getName()); } if (shouldApply && doNotApplyTo != null && doNotApplyTo.length() > 0) { WildcardPattern pattern = new WildcardPattern(doNotApplyTo, true); shouldApply = !pattern.matches(classNode.getNameWithoutPackage()) && !pattern.matches(classNode.getName()); } return shouldApply; } public String getApplyToClassNames() { return applyToClassNames; } public void setApplyToClassNames(String applyToClassNames) { this.applyToClassNames = applyToClassNames; } public String getDoNotApplyToClassNames() { return doNotApplyToClassNames; } public void setDoNotApplyToClassNames(String doNotApplyToClassNames) { this.doNotApplyToClassNames = doNotApplyToClassNames; } }CodeNarc-0.23/src/main/java/org/codenarc/rule/AbstractAstVisitor.java0000644000175000017500000001576412465654210025074 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.rule; import org.codehaus.groovy.ast.*; import org.codehaus.groovy.control.SourceUnit; import org.codenarc.source.SourceCode; import org.codenarc.util.AstUtil; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Abstract superclass for Groovy AST Visitors used with Rules * * @author Chris Mair * @author Hamlet D'Arcy */ public class AbstractAstVisitor extends ClassCodeVisitorSupport implements AstVisitor { // TODO Inheriting from ClassCodeVisitorSupportHack is a workaround for a known groovy issue: http://jira.codehaus.org/browse/GROOVY-4922 // TODO Revert to inheriting from ClassCodeVisitorSupport once that Groovy issue is fixed. // TODO Also see CodeNarc issue #3436461: StackOverflowErrors with CodeNarc 0.16 private final List violations = new ArrayList(); private Rule rule; private SourceCode sourceCode; private Set visited = new HashSet(); private ClassNode currentClassNode = null; /** * Return true if the AST expression has not already been visited. If it is * the first visit, register the expression so that the next visit will return false. * * @param expression - the AST expression to check * @return true if the AST expression has NOT already been visited */ protected boolean isFirstVisit(Object expression) { if (visited.contains(expression)) { return false; } visited.add(expression); return true; } /** * Return the trimmed source line corresponding to the specified AST node * * @param node - the Groovy AST node */ protected String sourceLineTrimmed(ASTNode node) { return sourceCode.line(AstUtil.findFirstNonAnnotationLine(node, sourceCode) - 1); } /** * Return the raw source line corresponding to the specified AST node * * @param node - the Groovy AST node */ protected String sourceLine(ASTNode node) { return sourceCode.getLines().get(AstUtil.findFirstNonAnnotationLine(node, sourceCode) - 1); } /** * Return the last raw source line corresponding to the specified AST node * * @param node - the Groovy AST node */ protected String lastSourceLine(ASTNode node) { return sourceCode.getLines().get(node.getLastLineNumber() - 1); } /** * Return the trimmed last source line corresponding to the specified AST node * * @param node - the Groovy AST node */ protected String lastSourceLineTrimmed(ASTNode node) { return sourceCode.line(node.getLastLineNumber() - 1); } /** * Add a new Violation to the list of violations found by this visitor. * Only add the violation if the node lineNumber >= 0. * * @param node - the Groovy AST Node * @deprecated Always define a message. Use the other addViolation method instead of this one. */ @Deprecated protected void addViolation(ASTNode node) { addViolation(node, null); } /** * Add a new Violation to the list of violations found by this visitor. * Only add the violation if the node lineNumber >= 0. * * @param node - the Groovy AST Node * @param message - the message for the violation; defaults to null */ protected void addViolation(ASTNode node, String message) { int lineNumber = node.getLineNumber(); if (lineNumber >= 0) { if (node instanceof AnnotatedNode) { lineNumber = AstUtil.findFirstNonAnnotationLine(node, sourceCode); } String sourceLine = sourceLineTrimmed(node); Violation violation = new Violation(); violation.setRule(rule); violation.setLineNumber(lineNumber); violation.setSourceLine(sourceLine); violation.setMessage(message); violations.add(violation); } } /** * Add a new Violation to the list of violations found by this visitor. * * @param violation - the violation to add */ protected void addViolation(Violation violation) { violations.add(violation); } protected SourceUnit getSourceUnit() { throw new RuntimeException("should never be called"); } public final void visitClass(final ClassNode node) { currentClassNode = node; visitClassEx(node); super.visitClass(node); visitClassComplete(node); currentClassNode = null; } protected void visitClassEx(ClassNode node) { // empty on purpose } protected void visitClassComplete(ClassNode node) { // empty on purpose } public final void visitMethod(final MethodNode node) { if (shouldVisitMethod(node)) { visitMethodEx(node); if (node != null && node.getParameters() != null) { for (Parameter parameter : node.getParameters()) { if (parameter.hasInitialExpression()) { parameter.getInitialExpression().visit(AbstractAstVisitor.this); } } } super.visitMethod(node); visitMethodComplete(node); } } protected boolean shouldVisitMethod(MethodNode node) { return true; } protected void visitMethodComplete(MethodNode node) { // empty on purpose } protected void visitMethodEx(MethodNode node) { // empty on purpose } public void setRule(Rule rule) { this.rule = rule; } public void setSourceCode(SourceCode sourceCode) { this.sourceCode = sourceCode; } public List getViolations() { return violations; } public Set getVisited() { return visited; } public Rule getRule() { return rule; } public SourceCode getSourceCode() { return sourceCode; } public void setVisited(Set visited) { this.visited = visited; } protected String getCurrentClassName() { return currentClassNode.getName(); } protected ClassNode getCurrentClassNode() { return currentClassNode; } } CodeNarc-0.23/src/main/java/org/codenarc/source/0000755000175000017500000000000012623571301020745 5ustar ebourgebourgCodeNarc-0.23/src/main/java/org/codenarc/source/ExpressionCollector.java0000644000175000017500000000304712006632014025614 0ustar ebourgebourgpackage org.codenarc.source; import org.codehaus.groovy.ast.ClassCodeVisitorSupport; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.ModuleNode; import org.codehaus.groovy.ast.expr.MethodCallExpression; import org.codehaus.groovy.control.SourceUnit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; class ExpressionCollector { Map> getMethodCalls(ModuleNode module) { Map> result = new HashMap>(); if (module != null && module.getClasses() != null) { for (ClassNode classNode : module.getClasses()) { ExpressionCollectorVisitor collector = new ExpressionCollectorVisitor(); collector.visitClass(classNode); result.put(classNode, collector.methodCalls); } } return result; } private static class ExpressionCollectorVisitor extends ClassCodeVisitorSupport { private final List methodCalls = new ArrayList(); @Override public void visitMethodCallExpression(MethodCallExpression call) { if (!methodCalls.contains(call)) { methodCalls.add(call); } super.visitMethodCallExpression(call); } @Override protected SourceUnit getSourceUnit() { throw new UnsupportedOperationException(); } } }CodeNarc-0.23/src/main/java/org/codenarc/ant/0000755000175000017500000000000012623571301020227 5ustar ebourgebourgCodeNarc-0.23/src/main/java/org/codenarc/ant/AntFileSetSourceAnalyzer.java0000644000175000017500000002200712253152040025752 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.ant; import org.apache.log4j.Logger; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.FileSet; import org.codenarc.analyzer.AbstractSourceAnalyzer; import org.codenarc.results.DirectoryResults; import org.codenarc.results.FileResults; import org.codenarc.results.Results; import org.codenarc.rule.Violation; import org.codenarc.ruleset.RuleSet; import org.codenarc.source.SourceFile; import org.codenarc.util.PathUtil; import java.io.File; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; /** * SourceAnalyzer implementation that gets source files from one or more Ant FileSets. * * @author Chris Mair */ public class AntFileSetSourceAnalyzer extends AbstractSourceAnalyzer { private static final Logger LOG = Logger.getLogger(AntFileSetSourceAnalyzer.class); private static final int POOL_TIMEOUT_SECONDS = 60 * 60; private final Project project; protected final List fileSets; // Concurrent shared state private final ConcurrentMap> resultsMap = new ConcurrentHashMap>(); private final ConcurrentMap fileCountMap = new ConcurrentHashMap(); /** * Construct a new instance on the specified Ant FileSet. * * @param project - the Ant Project; must not be null * @param fileSet - the Ant FileSet; must not be null */ public AntFileSetSourceAnalyzer(Project project, FileSet fileSet) { if (fileSet == null) { throw new IllegalArgumentException("Null: fileSet"); } if (project == null) { throw new IllegalArgumentException("Null: project"); } this.project = project; this.fileSets = Arrays.asList(fileSet); } /** * Construct a new instance on the specified List of Ant FileSets. * * @param project - the Ant Project * @param fileSets - the List of Ant FileSet; my be empty; must not be null */ AntFileSetSourceAnalyzer(Project project, List fileSets) { if (fileSets == null) { throw new IllegalArgumentException("Null: fileSets"); } if (project == null) { throw new IllegalArgumentException("Null: project"); } this.project = project; this.fileSets = new ArrayList(fileSets); } /** * Analyze all source code using the specified RuleSet and return the report results. * * @param ruleSet - the RuleSet to apply to each source component; must not be null. * @return the results from applying the RuleSet to all of the source */ public Results analyze(RuleSet ruleSet) { long startTime = System.currentTimeMillis(); DirectoryResults reportResults = new DirectoryResults(); int numThreads = Runtime.getRuntime().availableProcessors() + 1; ExecutorService pool = Executors.newFixedThreadPool(numThreads); for (FileSet fileSet : fileSets) { processFileSet(fileSet, ruleSet, pool); } pool.shutdown(); try { boolean completed = pool.awaitTermination(POOL_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (!completed) { throw new IllegalStateException("Thread Pool terminated before completion"); } } catch (InterruptedException e) { throw new IllegalStateException("Thread Pool interrupted before completion"); } addDirectoryResults(reportResults); LOG.info("Analysis time=" + (System.currentTimeMillis() - startTime) + "ms"); return reportResults; } public List getSourceDirectories() { String baseDir = project.getBaseDir().getAbsolutePath(); List result = new ArrayList(); for (FileSet fileSet : fileSets) { String path = fileSet.getDir(project).getPath(); String trimmedPath = PathUtil.removePathPrefix(baseDir, path); result.add(trimmedPath); } return result; } //-------------------------------------------------------------------------- // Internal Helper Methods //-------------------------------------------------------------------------- private void processFileSet(FileSet fileSet, RuleSet ruleSet, ExecutorService pool) { DirectoryScanner dirScanner = fileSet.getDirectoryScanner(project); File baseDir = fileSet.getDir(project); String[] includedFiles = dirScanner.getIncludedFiles(); if (includedFiles == null || includedFiles.length == 0) { LOG.info("No matching files found for FileSet with basedir [" + baseDir + "]"); return; } for (String filePath : includedFiles) { Runnable task = buildTask(baseDir, filePath, ruleSet); pool.submit(task); } } private Runnable buildTask(final File baseDir, final String filePath, final RuleSet ruleSet) { return new Runnable() { public void run() { try { processFile(baseDir, filePath, ruleSet); } catch (Throwable t) { LOG.info("Error processing filePath: '" + filePath + "'", t); } } }; } private void processFile(File baseDir, String filePath, RuleSet ruleSet) { File file = new File(baseDir, filePath); SourceFile sourceFile = new SourceFile(file); List allViolations = collectViolations(sourceFile, ruleSet); FileResults fileResults = null; if (allViolations != null && !allViolations.isEmpty()) { fileResults = new FileResults(PathUtil.normalizePath(filePath), allViolations); } String parentPath = PathUtil.getParentPath(filePath); String safeParentPath = parentPath != null ? parentPath : ""; addToResultsMap(safeParentPath, fileResults); incrementFileCount(safeParentPath); } private void incrementFileCount(String parentPath) { AtomicInteger initialZeroCount = new AtomicInteger(0); fileCountMap.putIfAbsent(parentPath, initialZeroCount); AtomicInteger fileCount = fileCountMap.get(parentPath); fileCount.incrementAndGet(); } private void addToResultsMap(String parentPath, FileResults results) { List initialEmptyResults = Collections.synchronizedList(new ArrayList()); resultsMap.putIfAbsent(parentPath, initialEmptyResults); if (results != null) { List dirResults = resultsMap.get(parentPath); dirResults.add(results); } } private void addToParentResults(DirectoryResults reportResults, Results results) { String parentPath = PathUtil.getParentPath(results.getPath()); if (parentPath == null) { reportResults.addChild(results); return; } DirectoryResults parent = (DirectoryResults) reportResults.findResultsForPath(parentPath); if (parent == null) { parent = new DirectoryResults(parentPath); addToParentResults(reportResults, parent); } parent.addChild(results); } private void addDirectoryResults(DirectoryResults reportResults) { Set set = resultsMap.keySet(); ArrayList allPaths = new ArrayList(set); Collections.sort(allPaths); for (String path : allPaths) { DirectoryResults dirResults = new DirectoryResults(path); List allResults = resultsMap.get(path); Collections.sort(allResults, new Comparator() { public int compare(FileResults o1, FileResults o2) { return o1.getPath().compareTo(o2.getPath()); } }); for (FileResults child : allResults) { dirResults.addChild(child); } AtomicInteger cnt = fileCountMap.get(path); dirResults.setNumberOfFilesInThisDirectory(cnt != null ? cnt.get() : 0); addToParentResults(reportResults, dirResults); } } }CodeNarc-0.23/src/site/0000755000175000017500000000000012623571301014177 5ustar ebourgebourgCodeNarc-0.23/src/site/resources/0000755000175000017500000000000012623571301016211 5ustar ebourgebourgCodeNarc-0.23/src/site/resources/StarterRuleSet-AllRules.groovy.txt0000644000175000017500000002325312470770455024767 0ustar ebourgebourgruleset { description ''' A Sample Groovy RuleSet containing all CodeNarc Rules You can use this as a template for your own custom RuleSet. Just delete the rules that you don't want to include. ''' AbcComplexity // DEPRECATED: Use the AbcMetric rule instead. Requires the GMetrics jar AbcMetric // Requires the GMetrics jar AbstractClassName AbstractClassWithPublicConstructor AbstractClassWithoutAbstractMethod AddEmptyString AssertWithinFinallyBlock AssignCollectionSort AssignCollectionUnique AssignmentInConditional BigDecimalInstantiation BitwiseOperatorInConditional BlankLineBeforePackage BooleanGetBoolean BooleanMethodReturnsNull BracesForClass BracesForForLoop BracesForIfElse BracesForMethod BracesForTryCatchFinally BrokenNullCheck BrokenOddnessCheck BuilderMethodWithSideEffects BusyWait CatchArrayIndexOutOfBoundsException CatchError CatchException CatchIllegalMonitorStateException CatchIndexOutOfBoundsException CatchNullPointerException CatchRuntimeException CatchThrowable ChainedTest ClassForName ClassJavadoc ClassName ClassNameSameAsFilename ClassSize CloneWithoutCloneable CloneableWithoutClone CloseWithoutCloseable ClosureAsLastMethodParameter ClosureStatementOnOpeningLineOfMultipleLineClosure CollectAllIsDeprecated CompareToWithoutComparable ComparisonOfTwoConstants ComparisonWithSelf ConfusingClassNamedException ConfusingMethodName ConfusingMultipleReturns ConfusingTernary ConsecutiveBlankLines ConsecutiveLiteralAppends ConsecutiveStringConcatenation ConstantAssertExpression ConstantIfExpression ConstantTernaryExpression ConstantsOnlyInterface CouldBeElvis CoupledTestCase CrapMetric // Requires the GMetrics jar and a Cobertura coverage file CyclomaticComplexity // Requires the GMetrics jar DeadCode DirectConnectionManagement DoubleCheckedLocking DoubleNegative DuplicateCaseStatement DuplicateImport DuplicateListLiteral DuplicateMapKey DuplicateMapLiteral DuplicateNumberLiteral DuplicateSetValue DuplicateStringLiteral ElseBlockBraces EmptyCatchBlock EmptyClass EmptyElseBlock EmptyFinallyBlock EmptyForStatement EmptyIfStatement EmptyInstanceInitializer EmptyMethod EmptyMethodInAbstractClass EmptyStaticInitializer EmptySwitchStatement EmptySynchronizedStatement EmptyTryBlock EmptyWhileStatement EnumCustomSerializationIgnored EqualsAndHashCode EqualsOverloaded ExceptionExtendsError ExceptionExtendsThrowable ExceptionNotThrown ExplicitArrayListInstantiation ExplicitCallToAndMethod ExplicitCallToCompareToMethod ExplicitCallToDivMethod ExplicitCallToEqualsMethod ExplicitCallToGetAtMethod ExplicitCallToLeftShiftMethod ExplicitCallToMinusMethod ExplicitCallToModMethod ExplicitCallToMultiplyMethod ExplicitCallToOrMethod ExplicitCallToPlusMethod ExplicitCallToPowerMethod ExplicitCallToRightShiftMethod ExplicitCallToXorMethod ExplicitGarbageCollection ExplicitHashMapInstantiation ExplicitHashSetInstantiation ExplicitLinkedHashMapInstantiation ExplicitLinkedListInstantiation ExplicitStackInstantiation ExplicitTreeSetInstantiation FactoryMethodName FieldName FileCreateTempFile FileEndsWithoutNewline FinalClassWithProtectedMember ForLoopShouldBeWhileLoop ForStatementBraces GStringAsMapKey GStringExpressionWithinString GetterMethodCouldBeProperty GrailsDomainHasEquals GrailsDomainHasToString GrailsDomainReservedSqlKeywordName GrailsDomainWithServiceReference GrailsDuplicateConstraint GrailsDuplicateMapping GrailsMassAssignment GrailsPublicControllerMethod GrailsServletContextReference GrailsSessionReference // DEPRECATED GrailsStatelessService GroovyLangImmutable HardCodedWindowsFileSeparator HardCodedWindowsRootDirectory HashtableIsObsolete IfStatementBraces IfStatementCouldBeTernary IllegalClassMember IllegalClassReference IllegalPackageReference IllegalRegex IllegalString IllegalSubclass ImplementationAsType ImportFromSamePackage ImportFromSunPackages InconsistentPropertyLocking InconsistentPropertySynchronization InsecureRandom Instanceof IntegerGetInteger InterfaceName InvertedIfElse JUnitAssertAlwaysFails JUnitAssertAlwaysSucceeds JUnitAssertEqualsConstantActualValue JUnitFailWithoutMessage JUnitLostTest JUnitPublicField JUnitPublicNonTestMethod JUnitPublicProperty JUnitSetUpCallsSuper JUnitStyleAssertions JUnitTearDownCallsSuper JUnitTestMethodWithoutAssert JUnitUnnecessarySetUp JUnitUnnecessaryTearDown JUnitUnnecessaryThrowsException JavaIoPackageAccess JdbcConnectionReference JdbcResultSetReference JdbcStatementReference LineLength LocaleSetDefault LoggerForDifferentClass LoggerWithWrongModifiers LoggingSwallowsStacktrace LongLiteralWithLowerCaseL MethodCount MethodName MethodSize MisorderedStaticImports MissingBlankLineAfterImports MissingBlankLineAfterPackage MissingNewInThrowStatement MultipleLoggers MultipleUnaryOperators NestedBlockDepth NestedForLoop NestedSynchronization NoDef NoWildcardImports NonFinalPublicField NonFinalSubclassOfSensitiveInterface ObjectFinalize ObjectOverrideMisspelledMethodName PackageName PackageNameMatchesFilePath ParameterCount ParameterName ParameterReassignment PrintStackTrace Println PrivateFieldCouldBeFinal PropertyName PublicFinalizeMethod PublicInstanceField RandomDoubleCoercedToZero RemoveAllOnSelf RequiredRegex RequiredString ReturnFromFinallyBlock ReturnNullFromCatchBlock ReturnsNullInsteadOfEmptyArray ReturnsNullInsteadOfEmptyCollection SerialPersistentFields SerialVersionUID SerializableClassMustDefineSerialVersionUID SimpleDateFormatMissingLocale SpaceAfterCatch SpaceAfterClosingBrace SpaceAfterComma SpaceAfterFor SpaceAfterIf SpaceAfterOpeningBrace SpaceAfterSemicolon SpaceAfterSwitch SpaceAfterWhile SpaceAroundClosureArrow SpaceAroundMapEntryColon SpaceAroundOperator SpaceBeforeClosingBrace SpaceBeforeOpeningBrace SpockIgnoreRestUsed StatelessClass StatelessSingleton StaticCalendarField StaticConnection StaticDateFormatField StaticMatcherField StaticSimpleDateFormatField SwallowThreadDeath SynchronizedMethod SynchronizedOnBoxedPrimitive SynchronizedOnGetClass SynchronizedOnReentrantLock SynchronizedOnString SynchronizedOnThis SynchronizedReadObjectMethod SystemErrPrint SystemExit SystemOutPrint SystemRunFinalizersOnExit TernaryCouldBeElvis ThisReferenceEscapesConstructor ThreadGroup ThreadLocalNotStaticFinal ThreadYield ThrowError ThrowException ThrowExceptionFromFinallyBlock ThrowNullPointerException ThrowRuntimeException ThrowThrowable ToStringReturnsNull TrailingWhitespace UnnecessaryBigDecimalInstantiation UnnecessaryBigIntegerInstantiation UnnecessaryBooleanExpression UnnecessaryBooleanInstantiation UnnecessaryCallForLastElement UnnecessaryCallToSubstring UnnecessaryCast UnnecessaryCatchBlock UnnecessaryCollectCall UnnecessaryCollectionCall UnnecessaryConstructor UnnecessaryDefInFieldDeclaration UnnecessaryDefInMethodDeclaration UnnecessaryDefInVariableDeclaration UnnecessaryDotClass UnnecessaryDoubleInstantiation UnnecessaryElseStatement UnnecessaryFail UnnecessaryFinalOnPrivateMethod UnnecessaryFloatInstantiation UnnecessaryGString UnnecessaryGetter UnnecessaryGroovyImport UnnecessaryIfStatement UnnecessaryInstanceOfCheck UnnecessaryInstantiationToGetClass UnnecessaryIntegerInstantiation UnnecessaryLongInstantiation UnnecessaryModOne UnnecessaryNullCheck UnnecessaryNullCheckBeforeInstanceOf UnnecessaryObjectReferences UnnecessaryOverridingMethod UnnecessaryPackageReference UnnecessaryParenthesesForMethodCallWithClosure UnnecessaryPublicModifier UnnecessaryReturnKeyword UnnecessarySafeNavigationOperator UnnecessarySelfAssignment UnnecessarySemicolon UnnecessaryStringInstantiation UnnecessarySubstring UnnecessaryTernaryExpression UnnecessaryToString UnnecessaryTransientModifier UnsafeArrayDeclaration UnsafeImplementationAsMap UnusedArray UnusedImport UnusedMethodParameter UnusedObject UnusedPrivateField UnusedPrivateMethod UnusedPrivateMethodParameter UnusedVariable UseAssertEqualsInsteadOfAssertTrue UseAssertFalseInsteadOfNegation UseAssertNullInsteadOfAssertEquals UseAssertSameInsteadOfAssertTrue UseAssertTrueInsteadOfAssertEquals UseAssertTrueInsteadOfNegation UseCollectMany UseCollectNested UseOfNotifyMethod VariableName VectorIsObsolete VolatileArrayField VolatileLongOrDoubleField WaitOutsideOfWhileLoop WhileStatementBraces }CodeNarc-0.23/src/site/resources/CodeNarc-Grails-Report.html0000644000175000017500000605342412006632012023253 0ustar ebourgebourgCodeNarc Report: Grails-core-2.0.0.RC1

CodeNarc Report

Summary by Package

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages933475-8391722
buildSrc/src/main/groovy/org/grails/gradle11--2
grails-bootstrap/src/main/groovy/grails/build/interactive/completors148-18
grails-bootstrap/src/main/groovy/grails/util43-649
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli1----
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/interactive21-36
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/interactive/completors11-1-
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/cli/support1----
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/plugins33-2551
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/plugins/build/scopes1----
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/resolve55-626
grails-bootstrap/src/main/groovy/org/codehaus/groovy/grails/resolve/config31--2
grails-core/src/main/groovy/grails/validation2----
grails-core/src/main/groovy/org/codehaus/groovy/grails/commons/cfg22--10
grails-core/src/main/groovy/org/codehaus/groovy/grails/commons/metaclass21--1
grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler22-17
grails-core/src/main/groovy/org/codehaus/groovy/grails/documentation1----
grails-core/src/main/groovy/org/codehaus/groovy/grails/exceptions21-714
grails-core/src/main/groovy/org/codehaus/groovy/grails/plugins21--3
grails-core/src/main/groovy/org/codehaus/groovy/grails/plugins/publishing33-53
grails-core/src/main/groovy/org/codehaus/groovy/grails/plugins/support22-11
grails-core/src/main/groovy/org/codehaus/groovy/grails/support1----
grails-core/src/main/groovy/org/codehaus/groovy/grails/validation1----
grails-crud/src/main/groovy/org/codehaus/groovy/grails/scaffolding11-44
grails-docs/src/main/groovy/grails/doc43-127
grails-docs/src/main/groovy/grails/doc/ant1----
grails-docs/src/main/groovy/grails/doc/filters32-29
grails-docs/src/main/groovy/grails/doc/gradle31--6
grails-docs/src/main/groovy/grails/doc/internal4----
grails-docs/src/main/groovy/grails/doc/macros21-1-
grails-docs/src/test/groovy/grails/doc/internal1----
grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/orm/hibernate22-27
grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/orm/hibernate/cfg123-311
grails-hibernate/src/main/groovy/org/codehaus/groovy/grails/plugins/orm/hibernate11-711
grails-plugin-async/src/main/groovy/org/codehaus/groovy/grails/plugins/web/async22--7
grails-plugin-async/src/main/groovy/org/codehaus/groovy/grails/plugins/web/async/api11-1-
grails-plugin-codecs/src/main/groovy/org/codehaus/groovy/grails/plugins11--3
grails-plugin-codecs/src/main/groovy/org/codehaus/groovy/grails/plugins/codecs114--10
grails-plugin-codecs/src/test/groovy/org/codehaus/groovy/grails/web/codecs113-32
grails-plugin-controllers/src/main/groovy/org/codehaus/groovy/grails/plugins/web11-310
grails-plugin-controllers/src/main/groovy/org/codehaus/groovy/grails/web/metaclass32-36
grails-plugin-controllers/src/main/groovy/org/codehaus/groovy/grails/web/plugins/support11-210
grails-plugin-converters/src/main/groovy/grails/web1----
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/plugins/converters22-13
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/plugins/converters/api1----
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/plugins/converters/codecs2----
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/web/converters32--2
grails-plugin-converters/src/main/groovy/org/codehaus/groovy/grails/web/converters/configuration11--5
grails-plugin-datasource/src/main/groovy/org/codehaus/groovy/grails/plugins/datasource11-36
grails-plugin-domain-class/src/main/groovy/org/codehaus/groovy/grails/domain11--1
grails-plugin-domain-class/src/main/groovy/org/codehaus/groovy/grails/plugins22-213
grails-plugin-filters/src/main/groovy/org/codehaus/groovy/grails/plugins/web/filters63-66
grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web11-214
grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web/taglib98-1048
grails-plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/web/filters1----
grails-plugin-i18n/src/main/groovy/org/codehaus/groovy/grails/plugins/i18n11--1
grails-plugin-log4j/src/main/groovy/org/codehaus/groovy/grails/plugins/log4j22--10
grails-plugin-mimetypes/src/main/groovy/org/codehaus/groovy/grails/plugins/web/api43-25
grails-plugin-mimetypes/src/main/groovy/org/codehaus/groovy/grails/plugins/web/mimes31--1
grails-plugin-mimetypes/src/main/groovy/org/codehaus/groovy/grails/web/mime21-12
grails-plugin-scaffolding/src/main/groovy/org/codehaus/groovy/grails/plugins/scaffolding11-12
grails-plugin-services/src/main/groovy/org/codehaus/groovy/grails/plugins/services11--3
grails-plugin-servlets/src/main/groovy/org/codehaus/groovy/grails/plugins/web21--1
grails-plugin-servlets/src/main/groovy/org/codehaus/groovy/grails/plugins/web/api1----
grails-plugin-testing/src/main/groovy/grails/test76-2310
grails-plugin-testing/src/main/groovy/grails/test/mixin/domain11--1
grails-plugin-testing/src/main/groovy/grails/test/mixin/services1----
grails-plugin-testing/src/main/groovy/grails/test/mixin/support11--6
grails-plugin-testing/src/main/groovy/grails/test/mixin/web44-120
grails-plugin-testing/src/main/groovy/grails/test/mixin/webflow2----
grails-plugin-testing/src/test/groovy/grails/test/mixin4----
grails-plugin-tomcat/src/main/groovy/org/grails/plugins/tomcat54-1011
grails-plugin-url-mappings/src/main/groovy/grails/test11-1713
grails-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/plugins/web/mapping11-216
grails-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping1----
grails-plugin-validation/src/main/groovy/org/codehaus/groovy/grails/plugins11-16
grails-plugin-validation/src/main/groovy/org/codehaus/groovy/grails/validation1----
grails-plugin-validation/src/main/groovy/org/codehaus/groovy/grails/web/plugins/support1----
grails-plugin-validation/src/test/groovy/org/codehaus/groovy/grails/plugins11--2
grails-resources/src/grails/grails-app/conf6----
grails-resources/src/grails/grails-app/conf/spring1----
grails-resources/src/grails/plugin/grails-app/conf2----
grails-spring/src/main/groovy/grails/spring11-16
grails-test-suite-base/src/main/groovy/org/codehaus/groovy/grails/plugins/web11-12
grails-test-suite-base/src/main/groovy/org/codehaus/groovy/grails/web/servlet/mvc11-35
grails-test-suite-base/src/main/groovy/org/codehaus/groovy/grails/web/taglib11-185
grails-test-suite-persistence/src/test/groovy/grails/test/mixin/domain1----
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate21690-115199
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/binding42-23
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/cfg64-1032
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/metaclass11-22
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/support22--25
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/hibernate/validation81-228
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/orm/support11--1
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/plugins11-2-
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/plugins/scaffolding11--2
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/plugins/services22-12
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/reload21-1-
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/scaffolding22-24
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/scaffolding/view22-22
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/validation31--1
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/web/binding32-22
grails-test-suite-persistence/src/test/groovy/org/codehaus/groovy/grails/web/converters11-2-
grails-test-suite-uber/src/test/groovy/grails/ant11-2-
grails-test-suite-uber/src/test/groovy/grails/persistence1----
grails-test-suite-uber/src/test/groovy/grails/spring21-1021
grails-test-suite-uber/src/test/groovy/grails/test1110-4827
grails-test-suite-uber/src/test/groovy/grails/test/mixin1913-1943
grails-test-suite-uber/src/test/groovy/grails/util75-940
grails-test-suite-uber/src/test/groovy/grails/web1----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/cli21-24
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/cli/support22-18
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/commons116-1626
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/commons/cfg3----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/commons/metaclass43-115
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/compiler11--4
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/compiler/injection11--2
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/context/support11-32
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/documentation11--2
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/domain8----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins76-1110
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/datasource1----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/grails-app/conf2----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/grails-app/services1----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/i18n11--5
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/logging11-15
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/metadata1----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/publishing11-2-
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/testing3----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/web33-69
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/plugins/web/mapping11-1-
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/reload21-31
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/resolve21-914
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/test/support2----
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/validation63-4164
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/context11-23
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/errors11-21
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/filters11--3
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/i18n11-112
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/json11--1
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/metaclass31-31
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/servlet65-711
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/servlet/filter11-1-
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/servlet/mvc147-623
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/sitemesh32-142
grails-test-suite-uber/src/test/groovy/org/codehaus/groovy/grails/web/util42-47
grails-test-suite-uber/src/test/resources/grails/spring1----
grails-test-suite-uber/src/test/resources/org/codehaus/groovy/grails/commons1----
grails-test-suite-uber/src/test/resources/org/codehaus/groovy/grails/commons/cfg2----
grails-test-suite-uber/src/test/resources/org/codehaus/groovy/grails/plugins11-3-
grails-test-suite-uber/test/resources/grails-app/conf1----
grails-test-suite-uber/test/resources/grails-plugin-utils/global-plugins/logging-0.11----
grails-test-suite-uber/test/resources/grails-plugin-utils/global-plugins/logging-0.1/scripts2----
grails-test-suite-uber/test/resources/grails-plugin-utils/grails-debug/scripts1----
grails-test-suite-uber/test/resources/grails-plugin-utils/plugins/jsecurity-0.31----
grails-test-suite-uber/test/resources/grails-plugin-utils/plugins/jsecurity-0.3/scripts2----
grails-test-suite-uber/test/resources/spring1----
grails-test-suite-uber/test/test-projects/inline-plugins/app/grails-app/conf1----
grails-test-suite-uber/test/test-projects/inline-plugins/plugins/foo1----
grails-test-suite-uber/test/test-projects/inline-plugins/plugins/foo/grails-app/controllers/foo1----
grails-test-suite-uber/test/test-projects/inline-plugins/plugins/foobar1----
grails-test-suite-uber/test/test-projects/inline-plugins/plugins/foobar/grails-app/controllers/foobar1----
grails-test-suite-uber/test/test-projects/nested-inline-plugins/app/grails-app/conf1----
grails-test-suite-uber/test/test-projects/nested-inline-plugins/plugins/plugin-one1----
grails-test-suite-uber/test/test-projects/nested-inline-plugins/plugins/plugin-one/grails-app/conf1----
grails-test-suite-uber/test/test-projects/nested-inline-plugins/plugins/plugin-two1----
grails-test-suite-uber/test/test-projects/plugin-build-settings/grails-app/conf5----
grails-test-suite-uber/test/test-projects/plugin-build-settings/grails-app/conf/spring1----
grails-test-suite-uber/test/test-projects/plugin-build-settings/plugins/hibernate-1.2-SNAPSHOT2----
grails-test-suite-uber/test/test-projects/plugin-build-settings/plugins/hibernate-1.2-SNAPSHOT/scripts3----
grails-test-suite-uber/test/test-projects/plugin-build-settings/plugins/webflow-1.2-SNAPSHOT2----
grails-test-suite-uber/test/test-projects/plugin-build-settings/plugins/webflow-1.2-SNAPSHOT/scripts3----
grails-test-suite-web/src/test/groovy/grails/test11-438
grails-test-suite-web/src/test/groovy/grails/test/mixin22-11
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/plugins/web1----
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/plugins/web/filters51-23
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/plugins/webflow21--1
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/binding143-42
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/converters73-35
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/filters11--4
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/mapping2214-532
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/mapping/filter21--3
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/mime21-2-
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/pages179-189
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/pages/ext/jsp99-833
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/servlet/view11-11
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/taglib3926-5873
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/webflow55-615
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/webflow/engine/builder88-129
grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/webflow/support11-610
grails-test/src/main/groovy/grails/test11--1
grails-test/src/main/groovy/org/codehaus/groovy/grails/plugins/testing43-319
grails-test/src/main/groovy/org/codehaus/groovy/grails/test31--2
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/event21-4-
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/io2----
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/junit411--2
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/junit4/listener21-51
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/junit4/result1----
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/junit4/runner31--2
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/report/junit1----
grails-test/src/main/groovy/org/codehaus/groovy/grails/test/support73-17
grails-web/src/jsp21/groovy/org/codehaus/groovy/grails/web/pages/ext/jsp22--6
grails-web/src/main/groovy/grails/gsp11-4911
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/errors1----
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/i18n1----
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping22-28
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mime11--1
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/pages33--8
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/pages/ext/jsp76-2024
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/mvc1----
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/mvc/exceptions1----
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/taglib22-13
grails-web/src/main/groovy/org/codehaus/groovy/grails/web/util11--1
grails-webflow/src/main/groovy/grails/test11-47
grails-webflow/src/main/groovy/org/codehaus/groovy/grails/webflow11--21
grails-webflow/src/main/groovy/org/codehaus/groovy/grails/webflow/context/servlet11--4
grails-webflow/src/main/groovy/org/codehaus/groovy/grails/webflow/engine/builder139-1633
scripts7324-1781

Package: buildSrc.src.main.groovy.org.grails.gradle

➥ GrailsBuildPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport310

[SRC]import org.gradle.api.DefaultTask

[MSG]The [org.gradle.api.DefaultTask] import is never referenced

UnusedImport312

[SRC]import org.gradle.api.specs.Specs

[MSG]The [org.gradle.api.specs.Specs] import is never referenced

Package: grails-bootstrap.src.main.groovy.grails.build.interactive.completors

➥ CreateController.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.CreateController. getURL() can probably be rewritten as URL

➥ CreateScaffoldController.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.CreateScaffoldController. getURL() can probably be rewritten as URL

➥ CreateService.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.CreateService. getURL() can probably be rewritten as URL

➥ CreateTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.CreateTagLib. getURL() can probably be rewritten as URL

➥ GenerateAll.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.GenerateAll. getURL() can probably be rewritten as URL

➥ GenerateController.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.GenerateController. getURL() can probably be rewritten as URL

➥ GenerateViews.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]GrailsResourceUtils.isDomainClass(res.getURL())

[MSG]Violation in class grails.build.interactive.completors.GenerateViews. getURL() can probably be rewritten as URL

➥ RegexCompletor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter234

[SRC]int complete(String buffer, int cursor, List candidates) {

[MSG]Violation in class RegexCompletor. Method parameter [cursor] is never referenced in the method complete of class grails.build.interactive.completors.RegexCompletor

UnnecessaryElseStatement339

[SRC]else return -1

[MSG]When an if statement block ends with a return statement the else is unnecessary

Package: grails-bootstrap.src.main.groovy.grails.util

➥ BuildSettings.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity21003

[SRC]protected void postLoadConfig() {

[MSG]Violation in class grails.util.BuildSettings. The cyclomatic complexity for method [postLoadConfig] is [21]

CyclomaticComplexity21316

[SRC]private void establishProjectStructure() {

[MSG]Violation in class grails.util.BuildSettings. The cyclomatic complexity for method [establishProjectStructure] is [25]

UnnecessaryElseStatement3488

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3589

[SRC]getCompileDependencies()

[MSG]Violation in class grails.util.BuildSettings. getCompileDependencies() can probably be rewritten as compileDependencies

UnnecessaryGetter3603

[SRC]getProvidedDependencies()

[MSG]Violation in class grails.util.BuildSettings. getProvidedDependencies() can probably be rewritten as providedDependencies

UnnecessaryGetter3616

[SRC]getRuntimeDependencies()

[MSG]Violation in class grails.util.BuildSettings. getRuntimeDependencies() can probably be rewritten as runtimeDependencies

UnnecessaryGetter3630

[SRC]getTestDependencies()

[MSG]Violation in class grails.util.BuildSettings. getTestDependencies() can probably be rewritten as testDependencies

UnnecessaryGetter3644

[SRC]getBuildDependencies()

[MSG]Violation in class grails.util.BuildSettings. getBuildDependencies() can probably be rewritten as buildDependencies

UnnecessaryDefInMethodDeclaration3783

[SRC]protected def loadBuildPropertiesFromClasspath(Propertie..uildProps) {

[MSG]Violation in class grails.util.BuildSettings. The def keyword is unneeded when a method is marked protected

UnnecessaryGetter31011

[SRC]def configURL = config.getConfigFile()

[MSG]Violation in class grails.util.BuildSettings. getConfigFile() can probably be rewritten as configFile

UnnecessaryGetter31012

[SRC]def configFile = configURL ? new File(configURL.getFile()) : null

[MSG]Violation in class grails.util.BuildSettings. getFile() can probably be rewritten as file

UnnecessaryGetter31014

[SRC]def metadataFile = Metadata.current.getMetadataFile()

[MSG]Violation in class grails.util.BuildSettings. getMetadataFile() can probably be rewritten as metadataFile

UnnecessaryGetter31148

[SRC]gcl = rootLoader != null ? new GroovyClassLoader(rootLoa..assLoader())

[MSG]Violation in class grails.util.BuildSettings. getSystemClassLoader() can probably be rewritten as systemClassLoader

UnnecessaryGetter31157

[SRC]def appName = metadata.getApplicationName() ?: "grails"

[MSG]Violation in class grails.util.BuildSettings. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter31158

[SRC]def appVersion = metadata.getApplicationVersion() ?: grailsVersion

[MSG]Violation in class grails.util.BuildSettings. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter31217

[SRC]def pluginDirs = getPluginDirectories()

[MSG]Violation in class grails.util.BuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter31311

[SRC]appName: Metadata.current.getApplicationName(),

[MSG]Violation in class grails.util.BuildSettings. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter31312

[SRC]appVersion: Metadata.current.getApplicationVersion())

[MSG]Violation in class grails.util.BuildSettings. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter31335

[SRC]def workingDirName = metadata.getApplicationName() ?: CO..ING_DIR_NAME

[MSG]Violation in class grails.util.BuildSettings. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter31344

[SRC]def version = metadata.getApplicationVersion()

[MSG]Violation in class grails.util.BuildSettings. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter31345

[SRC]def appName = metadata.getApplicationName() ?: baseDir.name

[MSG]Violation in class grails.util.BuildSettings. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter31512

[SRC]getBasePluginDescriptor() != null

[MSG]Violation in class grails.util.BuildSettings. getBasePluginDescriptor() can probably be rewritten as basePluginDescriptor

➥ GrailsMain.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter324

[SRC]props.load(getClass().getClassLoader().getResourceAsStre..roperties"))

[MSG]Violation in class grails.util.None. getClassLoader() can probably be rewritten as classLoader

➥ PluginBuildSettings.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2187

[SRC]GrailsPluginInfo[] getPluginInfos(String pluginDirPath=t..inDirPath) {

[MSG]Violation in class PluginBuildSettings. Method parameter [pluginDirPath] is never referenced in the method getPluginInfos of class grails.util.PluginBuildSettings

EmptyCatchBlock2203

[SRC]catch (e) {

[MSG]The catch block is empty

EmptyCatchBlock2739

[SRC]catch (e) {

[MSG]The catch block is empty

UnusedVariable2759

[SRC]def (name, version, xml) = result

[MSG]The variable [xml] in class grails.util.PluginBuildSettings is not used

UnnecessaryGetter3112

[SRC]for (pluginDir in getInlinePluginDirectories()) {

[MSG]Violation in class grails.util.PluginBuildSettings. getInlinePluginDirectories() can probably be rewritten as inlinePluginDirectories

UnnecessaryDefInMethodDeclaration3160

[SRC]protected def addPluginScopeInfoForDirAndInfo(PluginScop..ource dir) {

[MSG]Violation in class grails.util.PluginBuildSettings. The def keyword is unneeded when a method is marked protected

UnnecessaryGetter3192

[SRC]Resource[] pluginDescriptors = getPluginDescriptors()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDescriptors() can probably be rewritten as pluginDescriptors

UnnecessaryGetter3215

[SRC]buildSettings?.isInlinePluginLocation(pluginLocation?.getFile())

[MSG]Violation in class grails.util.PluginBuildSettings. getFile() can probably be rewritten as file

UnnecessaryGetter3226

[SRC]locations = buildSettings.getInlinePluginDirectories().c..source(it) }

[MSG]Violation in class grails.util.PluginBuildSettings. getInlinePluginDirectories() can probably be rewritten as inlinePluginDirectories

UnnecessaryGetter3239

[SRC]if (!pluginInfosMap) getPluginInfos() // initialize the infos

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3252

[SRC]if (!pluginInfosMap) getPluginInfos() // initialize the infos

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3264

[SRC]def pluginDirs = getPluginDirectories()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessarySubstring3275

[SRC]sourcePath = sourcePath.substring(pluginPath.length())

[MSG]Violation in class grails.util.PluginBuildSettings. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3287

[SRC]def baseDir = buildSettings?.getBaseDir()?.getCanonicalPath()

[MSG]Violation in class grails.util.PluginBuildSettings. getCanonicalPath() can probably be rewritten as canonicalPath

UnnecessaryGetter3287

[SRC]def baseDir = buildSettings?.getBaseDir()?.getCanonicalPath()

[MSG]Violation in class grails.util.PluginBuildSettings. getBaseDir() can probably be rewritten as baseDir

UnnecessaryGetter3386

[SRC]return getPluginSourceDirectories()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginSourceDirectories() can probably be rewritten as pluginSourceDirectories

UnnecessaryGetter3414

[SRC]getPluginSourceDirectories() // initialize cache

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginSourceDirectories() can probably be rewritten as pluginSourceDirectories

UnnecessaryGetter3454

[SRC]pluginDirectoryResources = buildSettings.getPluginDirect..s Resource[]

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3469

[SRC]if (pluginManager == null) return getPluginInfos()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3471

[SRC]def pluginInfos = getPluginInfos().findAll {GrailsPluginInfo info ->

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3472

[SRC]def plugin = pluginManager.getGrailsPlugin(info.getName())

[MSG]Violation in class grails.util.PluginBuildSettings. getName() can probably be rewritten as name

UnnecessaryGetter3486

[SRC]implicitPluginDirectories = buildSettings.getImplicitPlu..source(it) }

[MSG]Violation in class grails.util.PluginBuildSettings. getImplicitPluginDirectories() can probably be rewritten as implicitPluginDirectories

UnnecessaryGetter3498

[SRC]return buildSettings?.getPluginBaseDirectories() ?: []

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginBaseDirectories() can probably be rewritten as pluginBaseDirectories

UnnecessaryGetter3578

[SRC]artefactResources.addAll compileScopePluginInfo.getArtefactResources()

[MSG]Violation in class grails.util.PluginBuildSettings. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3579

[SRC]artefactResources.addAll providedScopePluginInfo.getArte..tResources()

[MSG]Violation in class grails.util.PluginBuildSettings. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3581

[SRC]if (Environment.getCurrent() == Environment.TEST) {

[MSG]Violation in class grails.util.PluginBuildSettings. getCurrent() can probably be rewritten as current

UnnecessaryGetter3582

[SRC]artefactResources.addAll testScopePluginInfo.getArtefactResources()

[MSG]Violation in class grails.util.PluginBuildSettings. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3584

[SRC]def inlineDirectories = getInlinePluginDirectories()

[MSG]Violation in class grails.util.PluginBuildSettings. getInlinePluginDirectories() can probably be rewritten as inlinePluginDirectories

UnnecessaryGetter3615

[SRC]def baseDescriptor = getBasePluginDescriptor()

[MSG]Violation in class grails.util.PluginBuildSettings. getBasePluginDescriptor() can probably be rewritten as basePluginDescriptor

UnnecessaryGetter3619

[SRC]for (inlinePluginDir in getInlinePluginDirectories()) {

[MSG]Violation in class grails.util.PluginBuildSettings. getInlinePluginDirectories() can probably be rewritten as inlinePluginDirectories

UnnecessaryGetter3635

[SRC]def pluginDirs = getPluginDirectories().toList()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3824

[SRC]Resource[] pluginDirs = getPluginDirectories()

[MSG]Violation in class grails.util.PluginBuildSettings. getPluginDirectories() can probably be rewritten as pluginDirectories

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.cli.interactive

➥ InteractiveMode.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity285

[SRC]void run() {

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. The cyclomatic complexity for method [run] is [31]

EmptyCatchBlock2203

[SRC]catch(ScriptExitException e) {

[MSG]The catch block is empty

EmptyCatchBlock2226

[SRC]} catch (e) {

[MSG]The catch block is empty

UnnecessaryGetter348

[SRC]@Delegate GrailsConsole console = GrailsConsole.getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getInstance() can probably be rewritten as instance

UnnecessaryGetter364

[SRC]GroovySystem.getMetaClassRegistry().addMetaClassRegistry..stryCleaner)

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

UnnecessaryGetter382

[SRC]getCurrent() != null && getCurrent().interactiveModeActive

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getCurrent() can probably be rewritten as current

UnnecessaryGetter382

[SRC]getCurrent() != null && getCurrent().interactiveModeActive

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getCurrent() can probably be rewritten as current

UnnecessaryGetter3136

[SRC]final desktop = Desktop.getDesktop()

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getDesktop() can probably be rewritten as desktop

UnnecessaryGetter3238

[SRC]def parser = GrailsScriptRunner.getCommandLineParser()

[MSG]Violation in class org.codehaus.groovy.grails.cli.interactive.InteractiveMode. getCommandLineParser() can probably be rewritten as commandLineParser

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.cli.interactive.completors

➥ ClassNameCompletor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter261

[SRC]boolean shouldInclude(Resource res) { true }

[MSG]Violation in class ClassNameCompletor. Method parameter [res] is never referenced in the method shouldInclude of class org.codehaus.groovy.grails.cli.interactive.completors.ClassNameCompletor

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ GrailsPluginUtils.groovy

Rule NamePriorityLine #Source Line / Message
SynchronizedMethod2120

[SRC]static synchronized PluginBuildSettings getPluginBuildSettings() {

[MSG]Violation in class GrailsPluginUtils. The method getPluginBuildSettings is synchronized at the method level

SynchronizedMethod2127

[SRC]static synchronized setPluginBuildSettings(PluginBuildSe.. settings) {

[MSG]Violation in class GrailsPluginUtils. The method setPluginBuildSettings is synchronized at the method level

UnusedMethodParameter2134

[SRC]static GrailsPluginInfo[] getPluginInfos(String pluginDi..Dir?.path) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginInfos of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2144

[SRC]static GrailsPluginInfo[] getSupportedPluginInfos(String..Dir?.path) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getSupportedPluginInfos of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2152

[SRC]static List<String> getPluginBaseDirectories(String pluginDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginBaseDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2167

[SRC]static Resource[] getPluginDirectories(String pluginDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2174

[SRC]static List<Resource> getImplicitPluginDirectories(Strin..Dir?.path) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getImplicitPluginDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2185

[SRC]static Resource[] getArtefactResources(String basedir) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [basedir] is never referenced in the method getArtefactResources of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2199

[SRC]static Resource[] getPluginXmlMetadata(String pluginsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginXmlMetadata of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2206

[SRC]static Resource[] getAvailableScripts(String grailsHome,..g basedir) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [grailsHome] is never referenced in the method getAvailableScripts of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2206

[SRC]static Resource[] getAvailableScripts(String grailsHome,..g basedir) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getAvailableScripts of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2206

[SRC]static Resource[] getAvailableScripts(String grailsHome,..g basedir) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [basedir] is never referenced in the method getAvailableScripts of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2213

[SRC]static Resource[] getPluginScripts(String pluginDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginScripts of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2220

[SRC]static Resource[] getPluginResourceBundles(String pluginDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginDirPath] is never referenced in the method getPluginResourceBundles of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2227

[SRC]static Resource[] getPluginSourceFiles(String pluginsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginSourceFiles of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2234

[SRC]static Resource[] getPluginJarFiles(String pluginsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginJarFiles of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2241

[SRC]static Resource[] getPluginDescriptors(String basedir, S..nsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [basedir] is never referenced in the method getPluginDescriptors of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2241

[SRC]static Resource[] getPluginDescriptors(String basedir, S..nsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginDescriptors of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2260

[SRC]static Resource[] getPluginLibDirectories(String pluginsDirPath) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginLibDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2267

[SRC]static Resource[] getPluginI18nDirectories(String plugin..Dir?.path) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginI18nDirectories of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

UnusedMethodParameter2302

[SRC]static Resource getPluginDirForName(String pluginsDirPat..luginName) {

[MSG]Violation in class GrailsPluginUtils. Method parameter [pluginsDirPath] is never referenced in the method getPluginDirForName of class org.codehaus.groovy.grails.plugins.GrailsPluginUtils

SynchronizedMethod2309

[SRC]static synchronized clearCaches() {

[MSG]Violation in class GrailsPluginUtils. The method clearCaches is synchronized at the method level

UnnecessaryGetter3135

[SRC]return getPluginBuildSettings().getPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3135

[SRC]return getPluginBuildSettings().getPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3145

[SRC]final PluginBuildSettings settings = getPluginBuildSettings()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3146

[SRC]return settings.getSupportedPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getSupportedPluginInfos() can probably be rewritten as supportedPluginInfos

UnnecessaryGetter3153

[SRC]getPluginBuildSettings().getPluginBaseDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBaseDirectories() can probably be rewritten as pluginBaseDirectories

UnnecessaryGetter3153

[SRC]getPluginBuildSettings().getPluginBaseDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3160

[SRC]getPluginBuildSettings().getPluginBaseDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBaseDirectories() can probably be rewritten as pluginBaseDirectories

UnnecessaryGetter3160

[SRC]getPluginBuildSettings().getPluginBaseDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3164

[SRC]getPluginBuildSettings().getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3164

[SRC]getPluginBuildSettings().getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3168

[SRC]getPluginBuildSettings().getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3168

[SRC]getPluginBuildSettings().getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3175

[SRC]getPluginBuildSettings().getImplicitPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getImplicitPluginDirectories() can probably be rewritten as implicitPluginDirectories

UnnecessaryGetter3175

[SRC]getPluginBuildSettings().getImplicitPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3179

[SRC]getPluginBuildSettings().isGlobalPluginLocation(pluginDir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3186

[SRC]getPluginBuildSettings().getArtefactResources()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3186

[SRC]getPluginBuildSettings().getArtefactResources()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3193

[SRC]getPluginBuildSettings().getArtefactResourcesForOne(projectDir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3200

[SRC]getPluginBuildSettings().getPluginXmlMetadata()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginXmlMetadata() can probably be rewritten as pluginXmlMetadata

UnnecessaryGetter3200

[SRC]getPluginBuildSettings().getPluginXmlMetadata()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3207

[SRC]getPluginBuildSettings().getAvailableScripts()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getAvailableScripts() can probably be rewritten as availableScripts

UnnecessaryGetter3207

[SRC]getPluginBuildSettings().getAvailableScripts()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3214

[SRC]getPluginBuildSettings().getPluginScripts()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginScripts() can probably be rewritten as pluginScripts

UnnecessaryGetter3214

[SRC]getPluginBuildSettings().getPluginScripts()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3221

[SRC]getPluginBuildSettings().getPluginResourceBundles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginResourceBundles() can probably be rewritten as pluginResourceBundles

UnnecessaryGetter3221

[SRC]getPluginBuildSettings().getPluginResourceBundles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3228

[SRC]getPluginBuildSettings().getPluginSourceFiles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginSourceFiles() can probably be rewritten as pluginSourceFiles

UnnecessaryGetter3228

[SRC]getPluginBuildSettings().getPluginSourceFiles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3235

[SRC]getPluginBuildSettings().getPluginJarFiles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginJarFiles() can probably be rewritten as pluginJarFiles

UnnecessaryGetter3235

[SRC]getPluginBuildSettings().getPluginJarFiles()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3242

[SRC]getPluginBuildSettings().getPluginDescriptors()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginDescriptors() can probably be rewritten as pluginDescriptors

UnnecessaryGetter3242

[SRC]getPluginBuildSettings().getPluginDescriptors()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3246

[SRC]getPluginBuildSettings().getBasePluginDescriptor(basedir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3254

[SRC]getPluginBuildSettings().getDescriptorForPlugin(pluginDir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3261

[SRC]getPluginBuildSettings().getPluginLibDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginLibDirectories() can probably be rewritten as pluginLibDirectories

UnnecessaryGetter3261

[SRC]getPluginBuildSettings().getPluginLibDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3268

[SRC]getPluginBuildSettings().getPluginI18nDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginI18nDirectories() can probably be rewritten as pluginI18nDirectories

UnnecessaryGetter3268

[SRC]getPluginBuildSettings().getPluginI18nDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3275

[SRC]getPluginBuildSettings().getGlobalPluginsPath()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getGlobalPluginsPath() can probably be rewritten as globalPluginsPath

UnnecessaryGetter3275

[SRC]getPluginBuildSettings().getGlobalPluginsPath()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3282

[SRC]getPluginBuildSettings().getPluginDirForName(pluginName)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3289

[SRC]getPluginBuildSettings().getMetadataForPlugin(pluginName)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3296

[SRC]getPluginBuildSettings().getMetadataForPlugin(pluginDir)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3303

[SRC]getPluginBuildSettings().getPluginDirForName(pluginName)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3310

[SRC]getPluginBuildSettings().clearCache()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtils. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

➥ GrailsVersionUtils.groovy

Rule NamePriorityLine #Source Line / Message
EqualsAndHashCode2100

[SRC]class VersionComparator implements Comparator {

[MSG]The class org.codehaus.groovy.grails.plugins.VersionComparator defines equals(Object) but not hashCode()

UnusedMethodParameter2167

[SRC]boolean equals(obj) { false }

[MSG]Violation in class VersionComparator. Method parameter [obj] is never referenced in the method equals of class org.codehaus.groovy.grails.plugins.VersionComparator

➥ PluginInfo.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock244

[SRC]catch(e) {

[MSG]The catch block is empty

UnnecessaryGetter356

[SRC]input = pluginXml.getInputStream()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getInputStream() can probably be rewritten as inputStream

UnnecessaryGetter397

[SRC]"${getName()}-${getVersion()}"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getName() can probably be rewritten as name

UnnecessaryGetter397

[SRC]"${getName()}-${getVersion()}"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getVersion() can probably be rewritten as version

UnnecessaryGetter3101

[SRC][name:getName(), version:getVersion()]

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getName() can probably be rewritten as name

UnnecessaryGetter3101

[SRC][name:getName(), version:getVersion()]

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. getVersion() can probably be rewritten as version

UnnecessaryDefInMethodDeclaration3119

[SRC]private def lookupFromMetadata(String name) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.PluginInfo. The def keyword is unneeded when a method is marked private

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.resolve

➥ EnhancedDefaultDependencyDescriptor.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3121

[SRC]Field field = getClass().getSuperclass().getDeclaredFiel..Transitive")

[MSG]Violation in class org.codehaus.groovy.grails.resolve.EnhancedDefaultDependencyDescriptor. getSuperclass() can probably be rewritten as superclass

UnnecessaryGetter3128

[SRC]Field field = getClass().getSuperclass().getDeclaredFiel..isChanging")

[MSG]Violation in class org.codehaus.groovy.grails.resolve.EnhancedDefaultDependencyDescriptor. getSuperclass() can probably be rewritten as superclass

➥ IvyDependencyManager.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport334

[SRC]import org.apache.ivy.plugins.resolver.ChainResolver

[MSG]The [org.apache.ivy.plugins.resolver.ChainResolver] import is never referenced

UnusedImport335

[SRC]import org.apache.ivy.util.Message

[MSG]The [org.apache.ivy.util.Message] import is never referenced

UnusedImport336

[SRC]import org.apache.ivy.util.MessageLogger

[MSG]The [org.apache.ivy.util.MessageLogger] import is never referenced

UnnecessaryElseStatement3254

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3396

[SRC]def candidates = getPluginDependencyDescriptors().findAl..pplication }

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManager. getPluginDependencyDescriptors() can probably be rewritten as pluginDependencyDescriptors

➥ PluginInstallEngine.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2366

[SRC]def (name, version, xml) = readMetadataFromZip(zipLocation)

[MSG]The variable [xml] in class org.codehaus.groovy.grails.resolve.PluginInstallEngine is not used

UnusedMethodParameter2429

[SRC]protected void resolvePluginJarDependencies(fullPluginNa..ies = [:]) {

[MSG]Violation in class PluginInstallEngine. Method parameter [pluginName] is never referenced in the method resolvePluginJarDependencies of class org.codehaus.groovy.grails.resolve.PluginInstallEngine

BooleanGetBoolean2446

[SRC]def runningUpgrade = Boolean.getBoolean('runningGrailsUpgrade')

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. Boolean.getBoolean(String) is a confusing API for reading System properties. Prefer the System.getProperty(String) API.

UnusedMethodParameter2504

[SRC]protected Map processPluginDependencies(String pluginNam..pluginXml) {

[MSG]Violation in class PluginInstallEngine. Method parameter [pluginName] is never referenced in the method processPluginDependencies of class org.codehaus.groovy.grails.resolve.PluginInstallEngine

UnusedPrivateMethod2731

[SRC]private registerMetadataForPluginLocation(Resource pluginDir) {

[MSG]The method registerMetadataForPluginLocation is not used within PluginInstallEngine.groovy

UnnecessaryGetter391

[SRC]applicationPluginsLocation = settings.getProjectPluginsDir()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getProjectPluginsDir() can probably be rewritten as projectPluginsDir

UnnecessaryGetter3228

[SRC]cacheDir currentDependencyManager.ivySettings.getDefault..absolutePath

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getDefaultCache() can probably be rewritten as defaultCache

UnnecessaryObjectReferences3237

[SRC]pluginResolver.setCheckmodified(true)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessarySelfAssignment3390

[SRC]PluginBuildSettings pluginSettings = pluginSettings

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter3461

[SRC]grails.build.logging.GrailsConsole.getInstance().warn("""

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getInstance() can probably be rewritten as instance

UnnecessaryPackageReference3461

[SRC]grails.build.logging.GrailsConsole.getInstance().warn("""

[MSG]The grails.build.logging.GrailsConsole class was explicitly imported, so specifying the package name is not necessary

UnnecessaryGetter3510

[SRC]def grailsVersion = settings.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter3563

[SRC]GrailsConsole.getInstance().addStatus("Uninstalled plugin [$name]")

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getInstance() can probably be rewritten as instance

UnnecessaryGetter3566

[SRC]GrailsConsole.getInstance().warning("No plugin [$name${v.. uninstall")

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getInstance() can probably be rewritten as instance

UnnecessaryDefInMethodDeclaration3585

[SRC]private def addToMetadata(pluginName, pluginVersion) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. The def keyword is unneeded when a method is marked private

UnnecessaryGetter3649

[SRC]GrailsConsole.getInstance().userInput(msg, ['y','n'] as ..ng[]) == 'y'

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getInstance() can probably be rewritten as instance

UnnecessaryGetter3657

[SRC]def pluginInfos = pluginSettings.getPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginInstallEngine. getPluginInfos() can probably be rewritten as pluginInfos

➥ PluginResolveEngine.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2273

[SRC]catch(e) {

[MSG]The catch block is empty

UnnecessaryGetter374

[SRC]output.println getPluginInfoHeader()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. getPluginInfoHeader() can probably be rewritten as pluginInfoHeader

UnnecessaryGetter3129

[SRC]output.println getPluginInfoFooter()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. getPluginInfoFooter() can probably be rewritten as pluginInfoFooter

UnnecessaryDefInMethodDeclaration3136

[SRC]protected def printDependencies(output, dependencies) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. The def keyword is unneeded when a method is marked protected

UnnecessaryDefInMethodDeclaration3145

[SRC]protected def printSectionTitle(PrintWriter output, String title) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. The def keyword is unneeded when a method is marked protected

UnnecessaryDefInMethodDeclaration3151

[SRC]protected def printLineSeparator(PrintWriter output) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.PluginResolveEngine. The def keyword is unneeded when a method is marked protected

➥ ResolveException.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter328

[SRC]for(IvyNode node in confReport.getUnresolvedDependencies()) {

[MSG]Violation in class org.codehaus.groovy.grails.resolve.ResolveException. getUnresolvedDependencies() can probably be rewritten as unresolvedDependencies

UnnecessaryGetter331

[SRC]def failedDownloads = confReport.getFailedArtifactsReports()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.ResolveException. getFailedArtifactsReports() can probably be rewritten as failedArtifactsReports

Package: grails-bootstrap.src.main.groovy.org.codehaus.groovy.grails.resolve.config

➥ RepositoriesConfigurer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences391

[SRC]fileSystemResolver.settings = dependencyManager.ivySettings

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3169

[SRC]urlResolver.setCheckmodified(true)

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.commons.cfg

➥ ConfigurationHelper.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGroovyImport321

[SRC]import java.util.Map

UnnecessaryGetter353

[SRC]getCachedConfigs().clear()

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getCachedConfigs() can probably be rewritten as cachedConfigs

UnnecessaryGetter364

[SRC]classLoader = application.getClassLoader()

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getClassLoader() can probably be rewritten as classLoader

UnnecessaryGetter377

[SRC]co = getCachedConfigs().get(cacheKey)

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getCachedConfigs() can probably be rewritten as cachedConfigs

UnnecessaryGetter3111

[SRC]getCachedConfigs().put(cacheKey, co)

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getCachedConfigs() can probably be rewritten as cachedConfigs

UnnecessaryGetter3127

[SRC]binding.put(CONFIG_BINDING_APP_NAME, application.getMeta..ATION_NAME))

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getMetadata() can probably be rewritten as metadata

UnnecessaryGetter3128

[SRC]binding.put(CONFIG_BINDING_APP_VERSION, application.getM..ON_VERSION))

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getMetadata() can probably be rewritten as metadata

UnnecessaryGetter3142

[SRC]getCachedConfigs().put(DEV_CACHE_KEY, config)

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getCachedConfigs() can probably be rewritten as cachedConfigs

UnnecessaryGetter3192

[SRC]stream = resource.getInputStream()

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.ConfigurationHelper. getInputStream() can probably be rewritten as inputStream

➥ MapBasedSmartPropertyOverrideConfigurer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter345

[SRC]def beans = getBeansConfig()

[MSG]Violation in class org.codehaus.groovy.grails.commons.cfg.MapBasedSmartPropertyOverrideConfigurer. getBeansConfig() can probably be rewritten as beansConfig

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.commons.metaclass

➥ MetaClassEnhancer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]method.invoke(method.getDeclaringClass(), instance, *args)

[MSG]Violation in class org.codehaus.groovy.grails.commons.metaclass.MetaClassEnhancer$1. getDeclaringClass() can probably be rewritten as declaringClass

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.compiler

➥ GrailsProjectCompiler.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField243

[SRC]private static final List<String> PLUGIN_EXCLUDE_PATHS =..ial handling

[MSG]The field PLUGIN_EXCLUDE_PATHS is not used within the class org.codehaus.groovy.grails.compiler.GrailsProjectCompiler

UnnecessaryGetter397

[SRC]pluginSettings.getArtefactResourcesForCurrentEnvironment())

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectCompiler. getArtefactResourcesForCurrentEnvironment() can probably be rewritten as artefactResourcesForCurrentEnvironment

UnnecessaryGetter3142

[SRC]def jarFiles = getJarFiles()

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectCompiler. getJarFiles() can probably be rewritten as jarFiles

UnnecessaryGetter3195

[SRC]jarFiles.addAll(getExtraDependencies())

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectCompiler. getExtraDependencies() can probably be rewritten as extraDependencies

➥ GrailsProjectPackager.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter342

[SRC]GrailsConsole grailsConsole = GrailsConsole.getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectPackager. getInstance() can probably be rewritten as instance

UnnecessaryGetter3119

[SRC]ant.copy(todir:buildSettings.getClassesDir(), failonerror:false) {

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectPackager. getClassesDir() can probably be rewritten as classesDir

UnnecessaryGetter3269

[SRC]def pluginInfos = pluginSettings.getSupportedPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectPackager. getSupportedPluginInfos() can probably be rewritten as supportedPluginInfos

UnnecessaryGetter3295

[SRC]def pluginInfos = pluginSettings.getSupportedPluginInfos()

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsProjectPackager. getSupportedPluginInfos() can probably be rewritten as supportedPluginInfos

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.exceptions

➥ DefaultStackTracePrinter.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity243

[SRC]String prettyPrint(Throwable t) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. The cyclomatic complexity for method [prettyPrint] is [23]

CyclomaticComplexity2167

[SRC]String prettyPrintCodeSnippet(Throwable exception) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. The cyclomatic complexity for method [prettyPrintCodeSnippet] is [21]

EmptyCatchBlock2239

[SRC]catch (e) {

[MSG]The catch block is empty

EmptyCatchBlock2245

[SRC]} catch (e) {

[MSG]The catch block is empty

EmptyCatchBlock2278

[SRC]} catch (e) {

[MSG]The catch block is empty

UnusedMethodParameter2318

[SRC]String formatCodeSnippetEnd(Resource resource, int lineNumber) {

[MSG]Violation in class DefaultStackTracePrinter. Method parameter [resource] is never referenced in the method formatCodeSnippetEnd of class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter

UnusedMethodParameter2318

[SRC]String formatCodeSnippetEnd(Resource resource, int lineNumber) {

[MSG]Violation in class DefaultStackTracePrinter. Method parameter [lineNumber] is never referenced in the method formatCodeSnippetEnd of class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter

UnnecessaryDefInMethodDeclaration3139

[SRC]protected def printCausedByMessage(PrintWriter sb, Throwable e) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. The def keyword is unneeded when a method is marked protected

UnnecessaryDefInMethodDeclaration3144

[SRC]protected def printHeader(PrintWriter sb, String header) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. The def keyword is unneeded when a method is marked protected

UnnecessaryGetter3164

[SRC]res == null ? te.className : res.getFilename()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getFilename() can probably be rewritten as filename

UnnecessaryGetter3284

[SRC]Object message = mcee.getErrorCollector().getErrors().it..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getErrors() can probably be rewritten as errors

UnnecessaryGetter3284

[SRC]Object message = mcee.getErrorCollector().getErrors().it..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getErrorCollector() can probably be rewritten as errorCollector

UnnecessaryGetter3287

[SRC]final tmp = new FileSystemResource(sem.getCause().getSourceLocator())

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getSourceLocator() can probably be rewritten as sourceLocator

UnnecessaryGetter3287

[SRC]final tmp = new FileSystemResource(sem.getCause().getSourceLocator())

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

UnnecessaryGetter3309

[SRC]Object message = mcee.getErrorCollector().getErrors().it..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getErrors() can probably be rewritten as errors

UnnecessaryGetter3309

[SRC]Object message = mcee.getErrorCollector().getErrors().it..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getErrorCollector() can probably be rewritten as errorCollector

UnnecessaryGetter3312

[SRC]lineNumber = sem.getCause().getLine()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getLine() can probably be rewritten as line

UnnecessaryGetter3312

[SRC]lineNumber = sem.getCause().getLine()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

UnnecessaryGetter3344

[SRC]while (ex.getCause() != null && !ex.equals(ex.getCause())) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

UnnecessaryGetter3344

[SRC]while (ex.getCause() != null && !ex.equals(ex.getCause())) {

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

UnnecessaryGetter3345

[SRC]ex = ex.getCause()

[MSG]Violation in class org.codehaus.groovy.grails.exceptions.DefaultStackTracePrinter. getCause() can probably be rewritten as cause

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ CoreGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter345

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter380

[SRC]if (getParentCtx()?.containsBean('pluginManager')) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPlugin. getParentCtx() can probably be rewritten as parentCtx

UnnecessaryCollectCall399

[SRC]def locations = new ArrayList(settings.pluginDirectories..olutePath })

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPlugin. The call to collect could probably be rewritten as a spread expression: settings.pluginDirectories*.absolutePath

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.plugins.publishing

➥ DefaultPluginPublisher.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2157

[SRC]protected GPathResult getPluginMetadata(String pluginName) {

[MSG]Violation in class DefaultPluginPublisher. Method parameter [pluginName] is never referenced in the method getPluginMetadata of class org.codehaus.groovy.grails.plugins.publishing.DefaultPluginPublisher

UnnecessaryCallForLastElement3120

[SRC]def lastPlugin = allPlugins[allPlugins.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to allPlugins.last() or allPlugins[-1]

UnnecessaryGetter3140

[SRC]InputStream stream = pluginsListFile.getInputStream()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.publishing.DefaultPluginPublisher. getInputStream() can probably be rewritten as inputStream

➥ PluginDescriptorGenerator.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity283

[SRC]protected void generatePluginXml(pluginProps, MarkupBuilder xml) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.publishing.PluginDescriptorGenerator. The cyclomatic complexity for method [generatePluginXml] is [28]

UnusedImport327

[SRC]import org.apache.ivy.plugins.resolver.URLResolver

[MSG]The [org.apache.ivy.plugins.resolver.URLResolver] import is never referenced

➥ PluginPackager.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2139

[SRC]String packageSource(String pluginName, File classesDir,..targetDir) {

[MSG]Violation in class PluginPackager. Method parameter [classesDir] is never referenced in the method packageSource of class org.codehaus.groovy.grails.plugins.publishing.PluginPackager

UnusedMethodParameter2139

[SRC]String packageSource(String pluginName, File classesDir,..targetDir) {

[MSG]Violation in class PluginPackager. Method parameter [targetDir] is never referenced in the method packageSource of class org.codehaus.groovy.grails.plugins.publishing.PluginPackager

UnusedVariable2149

[SRC]def pluginGrailsVersion = "${GrailsUtil.grailsVersion} > *"

[MSG]The variable [pluginGrailsVersion] in class org.codehaus.groovy.grails.plugins.publishing.PluginPackager is not used

Package: grails-core.src.main.groovy.org.codehaus.groovy.grails.plugins.support

➥ GrailsPluginUtils.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter313

[SRC]return GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.support.GrailsPluginUtils. getGrailsVersion() can probably be rewritten as grailsVersion

➥ WatchPattern.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock259

[SRC]} catch (e) {

[MSG]The catch block is empty

Package: grails-crud.src.main.groovy.org.codehaus.groovy.grails.scaffolding

➥ DefaultGrailsTemplateGenerator.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethod2144

[SRC]private generateListView(domainClass, destDir) {

[MSG]The method generateListView is not used within DefaultGrailsTemplateGenerator.groovy

UnusedPrivateMethod2154

[SRC]private generateShowView(domainClass, destDir) {

[MSG]The method generateShowView is not used within DefaultGrailsTemplateGenerator.groovy

UnusedPrivateMethod2164

[SRC]private generateEditView(domainClass, destDir) {

[MSG]The method generateEditView is not used within DefaultGrailsTemplateGenerator.groovy

UnusedPrivateMethod2174

[SRC]private generateCreateView(domainClass, destDir) {

[MSG]The method generateCreateView is not used within DefaultGrailsTemplateGenerator.groovy

UnnecessaryGetter3113

[SRC]for (t in getTemplateNames()) {

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator. getTemplateNames() can probably be rewritten as templateNames

UnnecessaryGetter3255

[SRC]def response = GrailsConsole.getInstance().userInput("Fi..as String[])

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator. getInstance() can probably be rewritten as instance

UnnecessaryGetter3284

[SRC]return templateFile.inputStream.getText()

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator. getText() can probably be rewritten as text

UnnecessarySubstring3306

[SRC]template = template.substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.DefaultGrailsTemplateGenerator. The String.substring(int) method can be replaced with the subscript operator

Package: grails-docs.src.main.groovy.grails.doc

➥ DocEngine.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2227

[SRC]void appendCreateLink(StringBuffer buffer, String name, String view) {

[MSG]Violation in class DocEngine. Method parameter [view] is never referenced in the method appendCreateLink of class grails.doc.DocEngine

UnusedMethodParameter2301

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class BlockQuoteFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.BlockQuoteFilter

UnusedMethodParameter2310

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class ItalicFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.ItalicFilter

UnusedMethodParameter2319

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class BoldFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.BoldFilter

UnusedMethodParameter2329

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class CodeFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.CodeFilter

UnusedMethodParameter2363

[SRC]void handleMatch(StringBuffer buffer, MatchResult result..t context) {

[MSG]Violation in class TextileLinkFilter. Method parameter [context] is never referenced in the method handleMatch of class grails.doc.TextileLinkFilter

UnusedImport321

[SRC]import java.util.regex.Pattern

[MSG]The [java.util.regex.Pattern] import is never referenced

UnusedImport330

[SRC]import org.radeox.macro.CodeMacro

[MSG]The [org.radeox.macro.CodeMacro] import is never referenced

UnusedImport332

[SRC]import org.radeox.macro.parameter.BaseMacroParameter

[MSG]The [org.radeox.macro.parameter.BaseMacroParameter] import is never referenced

UnusedImport336

[SRC]import org.radeox.util.Encoder

[MSG]The [org.radeox.util.Encoder] import is never referenced

➥ DocPublisher.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2101

[SRC]catch (e) {

[MSG]The catch block is empty

CyclomaticComplexity2130

[SRC]private void catPublish() {

[MSG]Violation in class grails.doc.DocPublisher. The cyclomatic complexity for method [catPublish] is [28]

UnusedVariable2251

[SRC]def fullToc = new StringBuilder()

[MSG]The variable [fullToc] in class grails.doc.DocPublisher is not used

UnusedVariable2295

[SRC]def reference = [:]

[MSG]The variable [reference] in class grails.doc.DocPublisher is not used

UnnecessaryObjectReferences3404

[SRC]varsCopy.content = engine.render(sourceFile.text, context)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3586

[SRC]URL url = getClass().getClassLoader().getResource(src)

[MSG]Violation in class grails.doc.DocPublisher. getClassLoader() can probably be rewritten as classLoader

➥ PdfBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField225

[SRC]private static final String LIVE_DOC_SITE = 'http://grails.org'

[MSG]The field LIVE_DOC_SITE is not used within the class grails.doc.PdfBuilder

UnusedMethodParameter227

[SRC]static void build(String baseDir, String styleDir = null) {

[MSG]Violation in class PdfBuilder. Method parameter [styleDir] is never referenced in the method build of class grails.doc.PdfBuilder

UnnecessaryGetter373

[SRC]Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()))

[MSG]Violation in class grails.doc.PdfBuilder. getBytes() can probably be rewritten as bytes

Package: grails-docs.src.main.groovy.grails.doc.filters

➥ HeaderFilter.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter232

[SRC]void handleMatch(StringBuffer out, MatchResult matchResu..erContext) {

[MSG]Violation in class HeaderFilter. Method parameter [filterContext] is never referenced in the method handleMatch of class grails.doc.filters.HeaderFilter

UnusedImport317

[SRC]import org.radeox.filter.regex.RegexFilter

[MSG]The [org.radeox.filter.regex.RegexFilter] import is never referenced

➥ LinkTestFilter.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable254

[SRC]Writer writer = new StringBufferWriter(buffer)

[MSG]The variable [writer] in class grails.doc.filters.LinkTestFilter is not used

UnusedImport322

[SRC]import org.radeox.filter.interwiki.InterWiki

[MSG]The [org.radeox.filter.interwiki.InterWiki] import is never referenced

UnnecessaryGetter348

[SRC]def engine = context.getRenderContext().getRenderEngine()

[MSG]Violation in class grails.doc.filters.LinkTestFilter. getRenderEngine() can probably be rewritten as renderEngine

UnnecessaryGetter348

[SRC]def engine = context.getRenderContext().getRenderEngine()

[MSG]Violation in class grails.doc.filters.LinkTestFilter. getRenderContext() can probably be rewritten as renderContext

UnnecessarySubstring371

[SRC]alias = name.substring(0, pipeIndex)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessarySubstring372

[SRC]name = name.substring(pipeIndex + 1)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring379

[SRC]hash = name.substring(hashIndex + 1)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring380

[SRC]name = name.substring(0, hashIndex)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessaryGetter3106

[SRC]context.getRenderContext().setCacheable(false)

[MSG]Violation in class grails.doc.filters.LinkTestFilter. getRenderContext() can probably be rewritten as renderContext

Package: grails-docs.src.main.groovy.grails.doc.gradle

➥ PublishGuide.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences356

[SRC]publisher.css = project.file("${resourcesDir}/css")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences357

[SRC]publisher.js = project.file("${resourcesDir}/js")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences358

[SRC]publisher.style = project.file("${resourcesDir}/style")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences359

[SRC]publisher.version = props."grails.version"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences360

[SRC]publisher.logo = '<a href="http://grails.org" target="_b..r="0"/></a>'

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences361

[SRC]publisher.sponsorLogo = '<a href="http://springsource.co..r="0"/></a>'

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-docs.src.main.groovy.grails.doc.macros

➥ GspTagSourceMacro.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable227

[SRC]String code

[MSG]The variable [code] in class grails.doc.macros.GspTagSourceMacro is not used

Package: grails-hibernate.src.main.groovy.org.codehaus.groovy.grails.orm.hibernate

➥ GrailsHibernateTransactionManager.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import org.hibernate.Session

[MSG]The [org.hibernate.Session] import is never referenced

➥ HibernateGormEnhancer.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2194

[SRC]} catch (e) {

[MSG]The catch block is empty

ThrowExceptionFromFinallyBlock2961

[SRC]throw e

[MSG]Throwing an exception from a finally block can hide an underlying error

UnnecessaryGetter3148

[SRC]this.sessionFactory = datastore.getSessionFactory()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormStaticApi. getSessionFactory() can probably be rewritten as sessionFactory

UnnecessaryGetter3156

[SRC]grailsApplication = domainClassMappingContext.getGrailsApplication()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormStaticApi. getGrailsApplication() can probably be rewritten as grailsApplication

UnnecessaryGetter3668

[SRC]def sessionFactory = datastore.getSessionFactory()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormValidationApi. getSessionFactory() can probably be rewritten as sessionFactory

UnnecessaryGetter3673

[SRC]def grailsApplication = domainClassMappingContext.getGra..pplication()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormValidationApi. getGrailsApplication() can probably be rewritten as grailsApplication

UnnecessaryGetter3736

[SRC]sessionFactory = datastore.getSessionFactory()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi. getSessionFactory() can probably be rewritten as sessionFactory

UnnecessaryGetter3741

[SRC]def grailsApplication = domainClassMappingContext.getGra..pplication()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi. getGrailsApplication() can probably be rewritten as grailsApplication

Package: grails-hibernate.src.main.groovy.org.codehaus.groovy.grails.orm.hibernate.cfg

➥ GORMEnhancingBeanPostProcessor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter243

[SRC]def postProcessBeforeInitialization(Object bean, String ..me) { bean }

[MSG]Violation in class GORMEnhancingBeanPostProcessor. Method parameter [beanName] is never referenced in the method postProcessBeforeInitialization of class org.codehaus.groovy.grails.orm.hibernate.cfg.GORMEnhancingBeanPostProcessor

UnusedMethodParameter245

[SRC]Object postProcessAfterInitialization(Object bean, String beanName) {

[MSG]Violation in class GORMEnhancingBeanPostProcessor. Method parameter [beanName] is never referenced in the method postProcessAfterInitialization of class org.codehaus.groovy.grails.orm.hibernate.cfg.GORMEnhancingBeanPostProcessor

➥ HibernateMappingBuilder.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2373

[SRC]private handleMethodMissing = { String name, args ->

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.HibernateMappingBuilder. The cyclomatic complexity for method [handleMethodMissing] is [46]

UnnecessaryObjectReferences3382

[SRC]property.cascade = namedArgs.cascade ?: property.cascade

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3383

[SRC]property.sort = namedArgs.sort ?: property.sort

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3384

[SRC]property.order = namedArgs.order ?: property.order

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3385

[SRC]property.batchSize = namedArgs.batchSize instanceof Inte..ty.batchSize

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3386

[SRC]property.ignoreNotFound = namedArgs.ignoreNotFound != nu..noreNotFound

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3387

[SRC]property.typeParams = namedArgs.params ?: property.typeParams

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3577

[SRC]column.length = args["length"] ?: -1

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3578

[SRC]column.precision = args["precision"] ?: -1

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3579

[SRC]column.scale = args["scale"] ?: -1

[MSG]The code could be more concise by using a with() or identity() block

➥ HibernateNamedQueriesBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3231

[SRC]def preparedClosure = getPreparedCriteriaClosure()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.NamedCriteriaProxy. getPreparedCriteriaClosure() can probably be rewritten as preparedCriteriaClosure

UnnecessaryGetter3287

[SRC]def previousClosure = previousInChain.getPreparedCriteriaClosure()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.NamedCriteriaProxy. getPreparedCriteriaClosure() can probably be rewritten as preparedCriteriaClosure

Package: grails-hibernate.src.main.groovy.org.codehaus.groovy.grails.plugins.orm.hibernate

➥ HibernatePluginSupport.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity279

[SRC]static doWithSpring = {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. The cyclomatic complexity for method [doWithSpring] is [55]

UnusedVariable2186

[SRC]def cacheClass = getClass().classLoader.loadClass(cacheProvider)

[MSG]The variable [cacheClass] in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport is not used

UnusedVariable2349

[SRC]String prefix = isDefault ? '' : datasourceName + '_'

[MSG]The variable [prefix] in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport is not used

UnusedPrivateMethod2590

[SRC]private static List<String> removeNullNames(Map query) {

[MSG]The method removeNullNames is not used within HibernatePluginSupport.groovy

ThrowExceptionFromFinallyBlock2612

[SRC]throw e

[MSG]Throwing an exception from a finally block can hide an underlying error

EmptyCatchBlock2638

[SRC]} catch (TypeMismatchException e) {

[MSG]The catch block is empty

EmptyCatchBlock2669

[SRC]} catch (FileNotFoundException fnfe) {

[MSG]The catch block is empty

UnusedImport332

[SRC]import org.codehaus.groovy.grails.orm.hibernate.cfg.Defa..onfiguration

[MSG]The [org.codehaus.groovy.grails.orm.hibernate.cfg.DefaultGrailsDomainConfiguration] import is never referenced

UnusedImport367

[SRC]import org.codehaus.groovy.grails.domain.GrailsDomainCla..istentEntity

[MSG]The [org.codehaus.groovy.grails.domain.GrailsDomainClassPersistentEntity] import is never referenced

UnnecessaryGetter381

[SRC]if (getSpringConfig().containsBean(ConstraintsEvaluator.BEAN_NAME)) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter396

[SRC]if (getSpringConfig().containsBean('dataSource')) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3107

[SRC]new PersistentConstraintFactory(getSpringConfig().getUnr..onContext(),

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter3107

[SRC]new PersistentConstraintFactory(getSpringConfig().getUnr..onContext(),

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryCollectCall3252

[SRC]hibConfigLocations.addAll(explicitLocations.collect { it.toString() })

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. The call to collect could probably be rewritten as a spread expression: explicitLocations*.toString()

UnnecessaryGetter3320

[SRC]if (getSpringConfig().containsBean("controllerHandlerMappings")) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3323

[SRC]if (getSpringConfig().containsBean("annotationHandlerMapping")) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3510

[SRC]for (PersistentEntity entity in mappingContext.getPersis..ntities()) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport. getPersistentEntities() can probably be rewritten as persistentEntities

UnnecessaryObjectReferences3701

[SRC]validateMethods.remove 'setValidateMethod'

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-plugin-async.src.main.groovy.org.codehaus.groovy.grails.plugins.web.async

➥ ControllersAsyncGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.ControllersAsyncGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

➥ GrailsAsyncContext.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport325

[SRC]import org.codehaus.groovy.grails.web.sitemesh.SpringMVCViewDecorator

[MSG]The [org.codehaus.groovy.grails.web.sitemesh.SpringMVCViewDecorator] import is never referenced

UnnecessaryGetter345

[SRC]def applicationContext = webRequest.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter358

[SRC]GrailsWebRequest webRequest = new GrailsWebRequest(reque..etContext())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter384

[SRC]def targetResponse = bufferingResponse.getTargetResponse()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getTargetResponse() can probably be rewritten as targetResponse

UnnecessaryGetter385

[SRC]def content = bufferingResponse.getContent()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getContent() can probably be rewritten as content

UnnecessaryGetter391

[SRC]content.writeOriginal(targetResponse.getWriter())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.async.GrailsAsyncContext. getWriter() can probably be rewritten as writer

Package: grails-plugin-async.src.main.groovy.org.codehaus.groovy.grails.plugins.web.async.api

➥ ControllersAsyncApi.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter239

[SRC]AsyncContext startAsync(instance) {

[MSG]Violation in class ControllersAsyncApi. Method parameter [instance] is never referenced in the method startAsync of class org.codehaus.groovy.grails.plugins.web.async.api.ControllersAsyncApi

Package: grails-plugin-codecs.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ CodecsGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter332

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CodecsGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter372

[SRC]def encodeMethod = codecClass.getEncodeMethod()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CodecsGrailsPlugin. getEncodeMethod() can probably be rewritten as encodeMethod

UnnecessaryGetter384

[SRC]def decodeMethod = codecClass.getDecodeMethod()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CodecsGrailsPlugin. getDecodeMethod() can probably be rewritten as decodeMethod

Package: grails-plugin-codecs.src.main.groovy.org.codehaus.groovy.grails.plugins.codecs

➥ Base64Codec.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import org.codehaus.groovy.runtime.DefaultGroovyMethods

[MSG]The [org.codehaus.groovy.runtime.DefaultGroovyMethods] import is never referenced

UnnecessaryGetter349

[SRC]return Base64.decodeBase64(theTarget.toString().getBytes())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.Base64Codec. getBytes() can probably be rewritten as bytes

➥ HexCodec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure332

[SRC]theTarget.each() {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.HexCodec. Parentheses in the 'each' method call are unnecessary and can be removed.

➥ SHA256Codec.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import java.security.MessageDigest

[MSG]The [java.security.MessageDigest] import is never referenced

➥ URLCodec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGroovyImport318

[SRC]import java.net.URLEncoder

UnnecessaryGroovyImport319

[SRC]import java.net.URLDecoder

UnnecessaryGetter330

[SRC]URLEncoder.encode(obj.toString(), URLCodec.getEncoding())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.URLCodec. getEncoding() can probably be rewritten as encoding

UnnecessaryGetter334

[SRC]URLDecoder.decode(obj.toString(), URLCodec.getEncoding())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.URLCodec. getEncoding() can probably be rewritten as encoding

UnnecessaryDefInMethodDeclaration337

[SRC]private static def getEncoding() {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.URLCodec. The def keyword is unneeded when a method is marked private

UnnecessaryGetter338

[SRC]def request = RequestContextHolder.getRequestAttributes()?.request

[MSG]Violation in class org.codehaus.groovy.grails.plugins.codecs.URLCodec. getRequestAttributes() can probably be rewritten as requestAttributes

Package: grails-plugin-codecs.src.test.groovy.org.codehaus.groovy.grails.web.codecs

➥ Base64CodecTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper214

[SRC]protected void setUp() {

[MSG]Violation in class Base64CodecTests. The method setUp() does not call super.setUp()

➥ HexCodecTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertNullInsteadOfAssertEquals321

[SRC]assertEquals(codec.encode(null), null)

[MSG]Violation in class org.codehaus.groovy.grails.web.codecs.HexCodecTests. assertEquals can be simplified using assertNull

UseAssertNullInsteadOfAssertEquals330

[SRC]assertEquals(codec.decode(null), null)

[MSG]Violation in class org.codehaus.groovy.grails.web.codecs.HexCodecTests. assertEquals can be simplified using assertNull

➥ URLCodecTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper214

[SRC]protected void setUp() {

[MSG]Violation in class URLCodecTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper219

[SRC]protected void tearDown() {

[MSG]Violation in class URLCodecTests. The method tearDown() does not call super.tearDown()

Package: grails-plugin-controllers.src.main.groovy.org.codehaus.groovy.grails.plugins.web

➥ ControllersGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2109

[SRC]def basedir = System.getProperty("base.dir")

[MSG]The variable [basedir] in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin is not used

UnusedVariable2110

[SRC]def grailsEnv = Environment.current.name

[MSG]The variable [grailsEnv] in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin is not used

UnusedMethodParameter2201

[SRC]static void enhanceDomainWithBinding(ApplicationContext ..aClass mc) {

[MSG]Violation in class ControllersGrailsPlugin. Method parameter [ctx] is never referenced in the method enhanceDomainWithBinding of class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin

UnnecessaryGetter350

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryCallForLastElement3113

[SRC]mappingElement = mappingElement[mappingElement.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to mappingElement.last() or mappingElement[-1]

UnnecessaryCallForLastElement3113

[SRC]mappingElement = mappingElement[mappingElement.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to mappingElement.last() or mappingElement[-1]

UnnecessaryCallForLastElement3125

[SRC]def lastFilter = filters[filters.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filters.last() or filters[-1]

UnnecessaryCallForLastElement3125

[SRC]def lastFilter = filters[filters.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filters.last() or filters[-1]

UnnecessaryCallForLastElement3126

[SRC]def lastFilterMapping = filterMappings[filterMappings.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filterMappings.last() or filterMappings[-1]

UnnecessaryCallForLastElement3126

[SRC]def lastFilterMapping = filterMappings[filterMappings.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filterMappings.last() or filterMappings[-1]

UnnecessaryGetter3169

[SRC]Object gspEnc = application.getFlatConfig().get("grails....encoding");

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin. getFlatConfig() can probably be rewritten as flatConfig

UnnecessaryDotClass3175

[SRC]def redirectListeners = ctx.getBeansOfType(RedirectEvent..tener.class)

[MSG]RedirectEventListener.class can be rewritten as RedirectEventListener

UnnecessaryGetter3178

[SRC]Object o = application.getFlatConfig().get(RedirectDynam..JSESSIONID);

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPlugin. getFlatConfig() can probably be rewritten as flatConfig

Package: grails-plugin-controllers.src.main.groovy.org.codehaus.groovy.grails.web.metaclass

➥ ChainMethod.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]def flash = webRequest.getFlashScope()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.ChainMethod. getFlashScope() can probably be rewritten as flashScope

UnnecessaryGetter365

[SRC]def appCtx = webRequest.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.ChainMethod. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter374

[SRC]def response = webRequest.getCurrentResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.ChainMethod. getCurrentResponse() can probably be rewritten as currentResponse

➥ WithFormMethod.groovy

Rule NamePriorityLine #Source Line / Message
SynchronizedMethod266

[SRC]protected synchronized boolean isTokenValid(GrailsWebReq..ebRequest) {

[MSG]Violation in class WithFormMethod. The method isTokenValid is synchronized at the method level

SynchronizedMethod288

[SRC]protected synchronized resetToken(GrailsWebRequest webRequest) {

[MSG]Violation in class WithFormMethod. The method resetToken is synchronized at the method level

UnusedMethodParameter2118

[SRC]protected Object invalidTokenInternal(Closure callable) { model }

[MSG]Violation in class ValidResponseHandler. Method parameter [callable] is never referenced in the method invalidTokenInternal of class org.codehaus.groovy.grails.web.metaclass.ValidResponseHandler

UnusedImport317

[SRC]import javax.servlet.http.HttpServletRequest

[MSG]The [javax.servlet.http.HttpServletRequest] import is never referenced

UnnecessaryGetter367

[SRC]final request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.WithFormMethod. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter389

[SRC]final request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.metaclass.WithFormMethod. getCurrentRequest() can probably be rewritten as currentRequest

Package: grails-plugin-controllers.src.main.groovy.org.codehaus.groovy.grails.web.plugins.support

➥ WebMetaUtils.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter285

[SRC]static void prepareCommandObjectBindingAction(Method act..ntext ctx) {

[MSG]Violation in class WebMetaUtils. Method parameter [action] is never referenced in the method prepareCommandObjectBindingAction of class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils

UnusedMethodParameter2230

[SRC]static registerCommonWebProperties(MetaClass mc, GrailsA..plication) {

[MSG]Violation in class WebMetaUtils. Method parameter [application] is never referenced in the method registerCommonWebProperties of class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils

UnnecessaryGetter3101

[SRC]def paramTypes = originalAction.getParameterTypes()

[MSG]Violation in class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils. getParameterTypes() can probably be rewritten as parameterTypes

UnnecessaryGetter3137

[SRC]constrainedProperty.getPropertyName()), errors)

[MSG]Violation in class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils. getPropertyName() can probably be rewritten as propertyName

UnnecessarySubstring3164

[SRC]return result.substring(0, result.size() - 8)

[MSG]Violation in class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessaryObjectReferences3250

[SRC]mc.getResponse = responseObject

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3252

[SRC]mc.getGrailsAttributes = grailsAttrsObject

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3254

[SRC]mc.getGrailsApplication = {-> RCH.currentRequestAttribut..pplication }

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3256

[SRC]mc.getActionName = {-> RCH.currentRequestAttributes().actionName }

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3257

[SRC]mc.getControllerName = {-> RCH.currentRequestAttributes(..rollerName }

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3258

[SRC]mc.getWebRequest = {-> RCH.currentRequestAttributes() }

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3264

[SRC]final MetaClass mc = taglib.getMetaClass()

[MSG]Violation in class org.codehaus.groovy.grails.web.plugins.support.WebMetaUtils. getMetaClass() can probably be rewritten as metaClass

Package: grails-plugin-converters.src.main.groovy.org.codehaus.groovy.grails.plugins.converters

➥ ConvertersGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter340

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.converters.ConvertersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter352

[SRC]controllers: GrailsUtil.getGrailsVersion(),

[MSG]Violation in class org.codehaus.groovy.grails.plugins.converters.ConvertersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter353

[SRC]domainClass: GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.converters.ConvertersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

➥ ConvertersPluginSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter244

[SRC]static void enhanceApplication(GrailsApplication applica..onContext) {

[MSG]Violation in class ConvertersPluginSupport. Method parameter [application] is never referenced in the method enhanceApplication of class org.codehaus.groovy.grails.plugins.converters.ConvertersPluginSupport

Package: grails-plugin-converters.src.main.groovy.org.codehaus.groovy.grails.web.converters

➥ JSONParsingParameterCreationListener.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter336

[SRC]def request = params.getRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONParsingParameterCreationListener. getRequest() can probably be rewritten as request

➥ XMLParsingParameterCreationListener.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]def request = params.getRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.XMLParsingParameterCreationListener. getRequest() can probably be rewritten as request

Package: grails-plugin-converters.src.main.groovy.org.codehaus.groovy.grails.web.converters.configuration

➥ configtest.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSamePackage33

[SRC]import org.codehaus.groovy.grails.web.converters.configu..nInitializer

ImportFromSamePackage34

[SRC]import org.codehaus.groovy.grails.web.converters.configu..rationHolder

ImportFromSamePackage36

[SRC]import org.codehaus.groovy.grails.web.converters.configu..onfiguration

ImportFromSamePackage37

[SRC]import org.codehaus.groovy.grails.web.converters.configu..onfiguration

UnnecessaryDotClass315

[SRC]def defcfg = ConvertersConfigurationHolder.getConverterC..(JSON.class)

[MSG]JSON.class can be rewritten as JSON

Package: grails-plugin-datasource.src.main.groovy.org.codehaus.groovy.grails.plugins.datasource

➥ DataSourceGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity272

[SRC]def createDatasource = { String datasourceName, ds ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. The cyclomatic complexity for method [createDatasource] is [22]

ClassForName2186

[SRC]codecClass = Class.forName(encryptionCodec, true, applic..classLoader)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)

EmptyCatchBlock2275

[SRC]} catch (e) {

[MSG]The catch block is empty

UnnecessaryGetter346

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter347

[SRC]def dependsOn = [core: GrailsUtil.getGrailsVersion()]

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryElseStatement3191

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryCallForLastElement3221

[SRC]listeners[listeners.size() - 1] + {

[MSG]Unnecessarily complex access of last element. This can be simplified to listeners.last() or listeners[-1]

UnnecessaryCallForLastElement3221

[SRC]listeners[listeners.size() - 1] + {

[MSG]Unnecessarily complex access of last element. This can be simplified to listeners.last() or listeners[-1]

UnnecessaryGetter3269

[SRC]connection = dataSource.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.datasource.DataSourceGrailsPlugin. getConnection() can probably be rewritten as connection

Package: grails-plugin-domain-class.src.main.groovy.org.codehaus.groovy.grails.domain

➥ GormApiSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter334

[SRC]PersistentEntity entity = ctx.getPersistentEntity(cls.getName())

[MSG]Violation in class org.codehaus.groovy.grails.domain.GormApiSupport. getName() can probably be rewritten as name

Package: grails-plugin-domain-class.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ DomainClassGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2113

[SRC]} catch (e) {

[MSG]The catch block is empty

CyclomaticComplexity2289

[SRC]public static addRelationshipManagementMethods(GrailsDom..ntext ctx) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. The cyclomatic complexity for method [addRelationshipManagementMethods] is [27]

UnusedImport319

[SRC]import grails.util.ClosureToMapPopulator

[MSG]The [grails.util.ClosureToMapPopulator] import is never referenced

UnusedImport340

[SRC]import org.codehaus.groovy.grails.commons.spring.GrailsR..Configurator

[MSG]The [org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator] import is never referenced

UnnecessaryGetter355

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryPackageReference3112

[SRC]org.grails.datastore.mapping.reflect.ClassPropertyFetche..hers.clear()

[MSG]The org.grails.datastore.mapping.reflect.ClassPropertyFetcher class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3112

[SRC]org.grails.datastore.mapping.reflect.ClassPropertyFetche..hers.clear()

[MSG]The org.grails.datastore.mapping.reflect.ClassPropertyFetcher class was explicitly imported, so specifying the package name is not necessary

UnnecessaryGetter3170

[SRC]for (GrailsDomainClass component in dc.getComponents()) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getComponents() can probably be rewritten as components

UnnecessaryGetter3225

[SRC]def attributes = rch.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3232

[SRC]def attributes = rch.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3261

[SRC]delegate.setErrors (new BeanPropertyBindingResult(delega...getName()))

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin. getName() can probably be rewritten as name

UnnecessaryElseStatement3306

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ DomainClassPluginSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import org.springframework.validation.BeanPropertyBindingResult

[MSG]The [org.springframework.validation.BeanPropertyBindingResult] import is never referenced

UnnecessaryGetter341

[SRC]prop.validate(object, object.getProperty(prop.getPropert..localErrors)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassPluginSupport. getPropertyName() can probably be rewritten as propertyName

UnnecessaryGetter346

[SRC]def fieldName = localError.getField()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.DomainClassPluginSupport. getField() can probably be rewritten as field

Package: grails-plugin-filters.src.main.groovy.org.codehaus.groovy.grails.plugins.web.filters

➥ FilterConfig.groovy

Rule NamePriorityLine #Source Line / Message
ConsecutiveStringConcatenation3100

[SRC]"Invalid filter definition in ${filtersDefinition.getCla..} - trying "

[MSG]String concatenation in class org.codehaus.groovy.grails.plugins.web.filters.FilterConfig can be joined into a single literal

➥ FilterToHandlerAdapter.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2116

[SRC]boolean preHandle(HttpServletRequest request, HttpServle.. Object o) {

[MSG]Violation in class FilterToHandlerAdapter. Method parameter [o] is never referenced in the method preHandle of class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter

UnusedMethodParameter2138

[SRC]void postHandle(HttpServletRequest request, HttpServletR..elAndView) {

[MSG]Violation in class FilterToHandlerAdapter. Method parameter [o] is never referenced in the method postHandle of class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter

UnusedMethodParameter2182

[SRC]void afterCompletion(HttpServletRequest request, HttpSer...Exception {

[MSG]Violation in class FilterToHandlerAdapter. Method parameter [response] is never referenced in the method afterCompletion of class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter

UnusedMethodParameter2182

[SRC]void afterCompletion(HttpServletRequest request, HttpSer...Exception {

[MSG]Violation in class FilterToHandlerAdapter. Method parameter [o] is never referenced in the method afterCompletion of class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter

UnnecessaryGetter3112

[SRC]if (!uri) uri = request.getRequestURI()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter. getRequestURI() can probably be rewritten as requestURI

UnnecessaryGetter3113

[SRC]return uri.substring(request.getContextPath().length())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter. getContextPath() can probably be rewritten as contextPath

UnnecessarySubstring3113

[SRC]return uri.substring(request.getContextPath().length())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3223

[SRC]actionName = controllerClass?.getDefaultAction()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FilterToHandlerAdapter. getDefaultAction() can probably be rewritten as defaultAction

➥ FiltersGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2100

[SRC]def filterClass = applicationContext.getBean("${c.fullName}Class")

[MSG]The variable [filterClass] in class org.codehaus.groovy.grails.plugins.web.filters.FiltersGrailsPlugin is not used

UnusedVariable2149

[SRC]def filterClass = applicationContext.getBean("${c.fullName}Class")

[MSG]The variable [filterClass] in class org.codehaus.groovy.grails.plugins.web.filters.FiltersGrailsPlugin is not used

UnnecessaryGetter340

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.filters.FiltersGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-gsp.src.main.groovy.org.codehaus.groovy.grails.plugins.web

➥ GroovyPagesGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity289

[SRC]def doWithSpring = {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. The cyclomatic complexity for method [doWithSpring] is [23]

UnusedVariable2289

[SRC]GrailsPluginManager pluginManager = getManager()

[MSG]The variable [pluginManager] in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin is not used

UnusedImport325

[SRC]import org.codehaus.groovy.grails.commons.GrailsClassUtils

[MSG]The [org.codehaus.groovy.grails.commons.GrailsClassUtils] import is never referenced

UnusedImport326

[SRC]import org.codehaus.groovy.grails.commons.GrailsTagLibClass

[MSG]The [org.codehaus.groovy.grails.commons.GrailsTagLibClass] import is never referenced

UnnecessaryGetter361

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessarySelfAssignment3167

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3167

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3172

[SRC]jspTagLibraryResolver = jspTagLibraryResolver

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3172

[SRC]jspTagLibraryResolver = jspTagLibraryResolver

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3178

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3178

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3202

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3202

[SRC]groovyPageLocator = groovyPageLocator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter3269

[SRC]if (Modifier.isAbstract(superClass.getModifiers()) && !s..Enhanced)) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. getModifiers() can probably be rewritten as modifiers

UnnecessaryGetter3278

[SRC]nonEnhancedClasses.each { enhancer.enhance it.getMetaClass() }

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. getMetaClass() can probably be rewritten as metaClass

UnnecessaryGetter3289

[SRC]GrailsPluginManager pluginManager = getManager()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.GroovyPagesGrailsPlugin. getManager() can probably be rewritten as manager

Package: grails-plugin-gsp.src.main.groovy.org.codehaus.groovy.grails.plugins.web.taglib

➥ ApplicationTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport326

[SRC]import org.codehaus.groovy.runtime.DefaultGroovyMethods;

[MSG]The [org.codehaus.groovy.runtime.DefaultGroovyMethods] import is never referenced

UnnecessaryElseStatement380

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryElseStatement3203

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3233

[SRC]def writer = getOut()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib. getOut() can probably be rewritten as out

UnnecessaryElseStatement3398

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ CountryTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall3274

[SRC]ISO3166_3.entrySet().sort { a, b -> a.value.compareTo(b...) { it.key }

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.CountryTagLib. The call to collect could probably be rewritten as a spread expression: ISO3166_3.entrySet().sort(<not implemented yet for class: org.codehaus.groovy.ast.expr.ClosureExpression>)*.key

UnnecessaryParenthesesForMethodCallWithClosure3274

[SRC]ISO3166_3.entrySet().sort { a, b -> a.value.compareTo(b...) { it.key }

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.CountryTagLib. Parentheses in the 'collect' method call are unnecessary and can be removed.

➥ FormTagLib.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2477

[SRC]Closure datePicker = { attrs ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. The cyclomatic complexity for method [datePicker] is [58]

AddEmptyString2667

[SRC]def h = '' + i

[MSG]Concatenating an empty string is an inefficient way to convert an object to a String. Consider using toString() or String.valueOf(Object)

AddEmptyString2696

[SRC]def m = '' + i

[MSG]Concatenating an empty string is an inefficient way to convert an object to a String. Consider using toString() or String.valueOf(Object)

CyclomaticComplexity2813

[SRC]Closure select = { attrs ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. The cyclomatic complexity for method [select] is [26]

EmptyCatchBlock2952

[SRC]catch (e) {

[MSG]The catch block is empty

UnusedImport325

[SRC]import org.codehaus.groovy.grails.web.util.StreamCharBuffer

[MSG]The [org.codehaus.groovy.grails.web.util.StreamCharBuffer] import is never referenced

UnnecessaryGetter3319

[SRC]def writer = getOut()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getOut() can probably be rewritten as out

UnnecessarySelfAssignment3478

[SRC]def out = out // let x = x ?

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3478

[SRC]def out = out // let x = x ?

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter3485

[SRC]xdefault = DateFormat.getInstance().parse(xdefault)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getInstance() can probably be rewritten as instance

UnnecessaryGetter3723

[SRC]attrs.from = TimeZone.getAvailableIDs()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getAvailableIDs() can probably be rewritten as availableIDs

UnnecessaryGetter3724

[SRC]attrs.value = (attrs.value ? attrs.value.ID : TimeZone.g..efault().ID)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getDefault() can probably be rewritten as default

UnnecessaryGetter3755

[SRC]attrs.from = Locale.getAvailableLocales()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getAvailableLocales() can probably be rewritten as availableLocales

UnnecessaryGetter3820

[SRC]def messageSource = grailsAttributes.getApplicationConte..sageSource")

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib. getApplicationContext() can probably be rewritten as applicationContext

➥ FormatTagLib.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2227

[SRC]Closure formatNumber = { attrs ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib. The cyclomatic complexity for method [formatNumber] is [26]

UnnecessaryGetter3162

[SRC]timeZone = TimeZone.getDefault()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib. getDefault() can probably be rewritten as default

UnnecessaryGetter3281

[SRC]dcfs = decimalFormat.getDecimalFormatSymbols()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib. getDecimalFormatSymbols() can probably be rewritten as decimalFormatSymbols

UnnecessaryGetter3338

[SRC]locale = Locale.getDefault()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.FormatTagLib. getDefault() can probably be rewritten as default

➥ JavascriptTagLib.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock255

[SRC]} catch (e) {

[MSG]The catch block is empty

UnusedPrivateMethod262

[SRC]private void initHasResourceProcessor() {

[MSG]The method initHasResourceProcessor is not used within JavascriptTagLib.groovy

UnnecessarySubstring3162

[SRC]reqResCtx = (requestPluginContext.startsWith("/") ? requ..ntext) + '/'

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3193

[SRC]getProvider().doRemoteFunction(owner, attrs, out)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib. getProvider() can probably be rewritten as provider

UnnecessaryGetter3349

[SRC]def p = getProvider()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib. getProvider() can probably be rewritten as provider

UnnecessaryGetter3388

[SRC]def p = getProvider()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib. getProvider() can probably be rewritten as provider

➥ RenderTagLib.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2329

[SRC]Closure paginate = { attrs ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. The cyclomatic complexity for method [paginate] is [40]

UnnecessaryGetter352

[SRC]return getRequest().getAttribute(PAGE)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getRequest() can probably be rewritten as request

UnnecessaryGetter3107

[SRC]def oldPage = getPage()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3151

[SRC]def parser = getFactory().getPageParser(contentType)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getFactory() can probably be rewritten as factory

UnnecessaryGetter3158

[SRC]def decoratorMapper = getFactory().getDecoratorMapper()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getDecoratorMapper() can probably be rewritten as decoratorMapper

UnnecessaryGetter3158

[SRC]def decoratorMapper = getFactory().getDecoratorMapper()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getFactory() can probably be rewritten as factory

UnnecessaryGetter3165

[SRC]def t = groovyPagesTemplateEngine.createTemplate(d.getPage())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3177

[SRC]return FactoryHolder.getFactory()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getFactory() can probably be rewritten as factory

UnnecessaryGetter3197

[SRC]def htmlPage = getPage()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessarySubstring3216

[SRC]out << propertyName.substring(propertyName.lastIndexOf('.') + 1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3244

[SRC]def htmlPage = getPage()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3291

[SRC]getPage().writeBody(out)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3302

[SRC]getPage().writeHead(out)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPage() can probably be rewritten as page

UnnecessaryGetter3565

[SRC]groovyPagesTemplateRenderer.render(getWebRequest(), getP..y, getOut())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getWebRequest() can probably be rewritten as webRequest

UnnecessaryGetter3565

[SRC]groovyPagesTemplateRenderer.render(getWebRequest(), getP..y, getOut())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getPageScope() can probably be rewritten as pageScope

UnnecessaryGetter3565

[SRC]groovyPagesTemplateRenderer.render(getWebRequest(), getP..y, getOut())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.RenderTagLib. getOut() can probably be rewritten as out

➥ SitemeshTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2172

[SRC]def content = captureTagContent(out, 'meta', attrs, body, true)

[MSG]The variable [content] in class org.codehaus.groovy.grails.plugins.web.taglib.SitemeshTagLib is not used

➥ ValidationTagLib.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall3115

[SRC]checkList = model.findAll {it.value?.errors instanceof E..t {it.value}

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The call to collect could probably be rewritten as a spread expression: model.findAll(<not implemented yet for class: org.codehaus.groovy.ast.expr.ClosureExpression>)*.value

UnnecessaryParenthesesForMethodCallWithClosure3249

[SRC]mkp.errors() {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. Parentheses in the 'errors' method call are unnecessary and can be removed.

UnnecessarySubstring3348

[SRC]def againstClass = attrs.against ?: form.substring(0,1)...substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessarySubstring3348

[SRC]def againstClass = attrs.against ?: form.substring(0,1)...substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryCollectCall3356

[SRC]appliedConstraints += it.collect{ it.appliedConstraints }

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The call to collect could probably be rewritten as a spread expression: it*.appliedConstraints

UnnecessarySubstring3384

[SRC]def scriptName = "org/apache/commons/validator/javascrip..g(1) + ".js"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessarySubstring3384

[SRC]def scriptName = "org/apache/commons/validator/javascrip..g(1) + ".js"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3410

[SRC]def validateType = k.substring(0,1).toUpperCase() + k.substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessarySubstring3410

[SRC]def validateType = k.substring(0,1).toUpperCase() + k.substring(1)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3426

[SRC]PropertyEditorRegistry registry = RequestContextHolder.c..orRegistry()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.taglib.ValidationTagLib. getPropertyEditorRegistry() can probably be rewritten as propertyEditorRegistry

Package: grails-plugin-i18n.src.main.groovy.org.codehaus.groovy.grails.plugins.i18n

➥ I18nGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]String version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.i18n.I18nGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-log4j.src.main.groovy.org.codehaus.groovy.grails.plugins.log4j

➥ Log4jConfig.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3181

[SRC]Logger root = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3229

[SRC]BuildSettings settings = BuildSettingsHolder.getSettings()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getSettings() can probably be rewritten as settings

UnnecessaryGetter3230

[SRC]def targetDir = settings?.getProjectTargetDir()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getProjectTargetDir() can probably be rewritten as projectTargetDir

UnnecessaryGetter3240

[SRC]def root = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3320

[SRC]LogLog.error "Appender $appender not found configuring l...getName()}"

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getName() can probably be rewritten as name

UnnecessaryGetter3375

[SRC]Logger.getRootLogger().removeAppender name

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.Log4jConfig. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryDefInMethodDeclaration3444

[SRC]def EnvironmentsLog4JConfig(Log4jConfig config) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.EnvironmentsLog4JConfig. The def keyword is unneeded on constructors

➥ LoggingGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter335

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.log4j.LoggingGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryCallForLastElement355

[SRC]mappingElement = mappingElement[mappingElement.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to mappingElement.last() or mappingElement[-1]

UnnecessaryCallForLastElement355

[SRC]mappingElement = mappingElement[mappingElement.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to mappingElement.last() or mappingElement[-1]

Package: grails-plugin-mimetypes.src.main.groovy.org.codehaus.groovy.grails.plugins.web.api

➥ ControllersMimeTypesApi.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter250

[SRC]def withFormat(instance, Closure callable) {

[MSG]Violation in class ControllersMimeTypesApi. Method parameter [instance] is never referenced in the method withFormat of class org.codehaus.groovy.grails.plugins.web.api.ControllersMimeTypesApi

➥ RequestMimeTypesApi.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter376

[SRC]parser.configuredMimeTypes = getMimeTypes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.RequestMimeTypesApi. getMimeTypes() can probably be rewritten as mimeTypes

➥ ResponseMimeTypesApi.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter2122

[SRC]private MimeType[] getMimeTypesInternal(HttpServletReque.. response) {

[MSG]Violation in class ResponseMimeTypesApi. Method parameter [response] is never referenced in the method getMimeTypesInternal of class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi

UnnecessaryGetter372

[SRC]HttpServletRequest request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter377

[SRC]def allMimes = getMimeTypes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi. getMimeTypes() can probably be rewritten as mimeTypes

UnnecessaryGetter379

[SRC]result = mime ? mime.extension : getMimeTypes()[0].extension

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi. getMimeTypes() can probably be rewritten as mimeTypes

UnnecessaryGetter3130

[SRC]parser.configuredMimeTypes = getMimeTypes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.api.ResponseMimeTypesApi. getMimeTypes() can probably be rewritten as mimeTypes

Package: grails-plugin-mimetypes.src.main.groovy.org.codehaus.groovy.grails.plugins.web.mimes

➥ MimeTypesGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.mimes.MimeTypesGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-mimetypes.src.main.groovy.org.codehaus.groovy.grails.web.mime

➥ DefaultAcceptHeaderParser.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable245

[SRC]def qualifiedMimes = []

[MSG]The variable [qualifiedMimes] in class org.codehaus.groovy.grails.web.mime.DefaultAcceptHeaderParser is not used

UnnecessaryGetter343

[SRC]def config = application?.getConfig()

[MSG]Violation in class org.codehaus.groovy.grails.web.mime.DefaultAcceptHeaderParser. getConfig() can probably be rewritten as config

UnnecessaryGetter356

[SRC]return MimeType.getConfiguredMimeTypes()

[MSG]Violation in class org.codehaus.groovy.grails.web.mime.DefaultAcceptHeaderParser. getConfiguredMimeTypes() can probably be rewritten as configuredMimeTypes

Package: grails-plugin-scaffolding.src.main.groovy.org.codehaus.groovy.grails.plugins.scaffolding

➥ ScaffoldingGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2188

[SRC]catch (Exception e) {

[MSG]The catch block is empty

UnusedImport329

[SRC]import org.springframework.beans.factory.config.BeanDefinition

[MSG]The [org.springframework.beans.factory.config.BeanDefinition] import is never referenced

UnnecessaryGetter350

[SRC]def version = grails.util.GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.scaffolding.ScaffoldingGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-services.src.main.groovy.org.codehaus.groovy.grails.plugins.services

➥ ServicesGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter339

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.services.ServicesGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter390

[SRC]"${serviceClass.propertyName}"(serviceClass.getClazz()) { bean ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.services.ServicesGrailsPlugin. getClazz() can probably be rewritten as clazz

UnnecessaryGetter3158

[SRC]"$serviceName"(serviceClass.getClazz()) { bean ->

[MSG]Violation in class org.codehaus.groovy.grails.plugins.services.ServicesGrailsPlugin. getClazz() can probably be rewritten as clazz

Package: grails-plugin-servlets.src.main.groovy.org.codehaus.groovy.grails.plugins.web

➥ ServletsGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter331

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-plugin-testing.src.main.groovy.grails.test

➥ AbstractCliTestCase.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField222

[SRC]private final Condition waiting = lock.newCondition()

[MSG]The field waiting is not used within the class grails.test.AbstractCliTestCase

JUnitPublicNonTestMethod291

[SRC]String getOutput() {

[MSG]Violation in class AbstractCliTestCase. The method getOutput is public but not a test method

JUnitPublicNonTestMethod295

[SRC]void setOutput(String output) {

[MSG]Violation in class AbstractCliTestCase. The method setOutput is public but not a test method

JUnitPublicNonTestMethod2103

[SRC]File getWorkDir() {

[MSG]Violation in class AbstractCliTestCase. The method getWorkDir is public but not a test method

JUnitPublicNonTestMethod2107

[SRC]void setWorkDir(File dir) {

[MSG]Violation in class AbstractCliTestCase. The method setWorkDir is public but not a test method

JUnitPublicNonTestMethod2117

[SRC]void enterInput(String input) {

[MSG]Violation in class AbstractCliTestCase. The method enterInput is public but not a test method

JUnitPublicNonTestMethod2127

[SRC]int waitForProcess() {

[MSG]Violation in class AbstractCliTestCase. The method waitForProcess is public but not a test method

UnusedVariable2129

[SRC]final monitor = "monitor"

[MSG]The variable [monitor] in class grails.test.AbstractCliTestCase is not used

EmptyCatchBlock2139

[SRC]catch (InterruptedException ex) {

[MSG]The catch block is empty

JUnitPublicNonTestMethod2214

[SRC]public boolean isWindows() {

[MSG]Violation in class AbstractCliTestCase. The method isWindows is public but not a test method

➥ ControllerUnitTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod258

[SRC]Class getControllerClass() {

[MSG]Violation in class ControllerUnitTestCase. The method getControllerClass is public but not a test method

➥ GroovyPagesTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod237

[SRC]void setControllerName(String name) {

[MSG]Violation in class GroovyPagesTestCase. The method setControllerName is public but not a test method

JUnitPublicNonTestMethod249

[SRC]void assertOutputEquals(expected, template, params = [:]..tring() }) {

[MSG]Violation in class GroovyPagesTestCase. The method assertOutputEquals is public but not a test method

JUnitPublicNonTestMethod261

[SRC]String applyTemplate(template, params = [:]) {

[MSG]Violation in class GroovyPagesTestCase. The method applyTemplate is public but not a test method

JUnitPublicNonTestMethod267

[SRC]void applyTemplate(StringWriter sw, template, params = [:]) {

[MSG]Violation in class GroovyPagesTestCase. The method applyTemplate is public but not a test method

➥ MockUtils.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter2567

[SRC]private static void addDynamicFinders(Class clazz, List ..Instances) {

[MSG]Violation in class MockUtils. Method parameter [testInstances] is never referenced in the method addDynamicFinders of class grails.test.MockUtils

UnusedPrivateMethodParameter2655

[SRC]private static void addCountMethods(Class clazz, GrailsD..Instances) {

[MSG]Violation in class MockUtils. Method parameter [dc] is never referenced in the method addCountMethods of class grails.test.MockUtils

UnusedPrivateMethodParameter2732

[SRC]private static void addOtherStaticMethods(Class clazz, L..Instances) {

[MSG]Violation in class MockUtils. Method parameter [testInstances] is never referenced in the method addOtherStaticMethods of class grails.test.MockUtils

CyclomaticComplexity2752

[SRC]private static void addDynamicInstanceMethods(Class claz..Instances) {

[MSG]Violation in class grails.test.MockUtils. The cyclomatic complexity for method [addDynamicInstanceMethods] is [24]

CyclomaticComplexity2917

[SRC]private static void addValidateMethod(

[MSG]Violation in class grails.test.MockUtils. The cyclomatic complexity for method [addValidateMethod] is [27]

CyclomaticComplexity21097

[SRC]private static processInstances(instances, property, com..tor, args) {

[MSG]Violation in class grails.test.MockUtils. The cyclomatic complexity for method [processInstances] is [26]

UnusedImport342

[SRC]import org.springframework.validation.BeanPropertyBindingResult

[MSG]The [org.springframework.validation.BeanPropertyBindingResult] import is never referenced

ConstantAssertExpression3295

[SRC]assert false : "'template' attribute must be provided."

[MSG]The assert statement within class grails.test.MockUtils has a constant boolean expression [false]

UnnecessaryGetter3315

[SRC]clazz.metaClass.getSession = {-> mockRequest.getSession() }

[MSG]Violation in class grails.test.MockUtils. getSession() can probably be rewritten as session

UnnecessarySubstring3359

[SRC]def shortName = clazz.name.substring(pos + 1)

[MSG]Violation in class grails.test.MockUtils. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryElseStatement3633

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryDotClass3945

[SRC]while (clazz != Object.class) {

[MSG]Object.class can be rewritten as Object

UnnecessaryGetter3947

[SRC]clazz = clazz.getSuperclass()

[MSG]Violation in class grails.test.MockUtils. getSuperclass() can probably be rewritten as superclass

UnnecessaryDotClass31322

[SRC]if (value instanceof Number && Long.class.equals(targetType)) {

[MSG]Long.class can be rewritten as Long

➥ MvcUnitTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod285

[SRC]Class getTestClass() {

[MSG]Violation in class MvcUnitTestCase. The method getTestClass is public but not a test method

UnusedImport317

[SRC]import grails.util.GrailsNameUtils

[MSG]The [grails.util.GrailsNameUtils] import is never referenced

UnnecessaryDefInMethodDeclaration3122

[SRC]protected def bindMockWebRequest(GrailsMockHttpServletRe..kResponse) {

[MSG]Violation in class grails.test.MvcUnitTestCase. The def keyword is unneeded when a method is marked protected

➥ TagLibUnitTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod265

[SRC]Class getTagLibClass() {

[MSG]Violation in class TagLibUnitTestCase. The method getTagLibClass is public but not a test method

Package: grails-plugin-testing.src.main.groovy.grails.test.mixin.domain

➥ DomainClassUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass3153

[SRC]def validator = applicationContext.getBean(validationBea..dator.class)

[MSG]Validator.class can be rewritten as Validator

Package: grails-plugin-testing.src.main.groovy.grails.test.mixin.support

➥ GrailsUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass380

[SRC]CachedIntrospectionResults.clearClassLoader(GrailsUnitTe..classLoader)

[MSG]GrailsUnitTestMixin.class can be rewritten as GrailsUnitTestMixin

UnnecessaryGetter3169

[SRC]result = ScriptBytecodeAdapter.unwrap(gre).getMessage()

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getMessage() can probably be rewritten as message

UnnecessaryGetter3173

[SRC]result = e.getMessage()

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getMessage() can probably be rewritten as message

UnnecessaryGetter3201

[SRC]throw new AssertionFailedError("Closure " + code + " sho..z.getName())

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getName() can probably be rewritten as name

UnnecessaryGetter3203

[SRC]throw new AssertionFailedError("Closure " + code + " sho..ion " + th);

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getName() can probably be rewritten as name

UnnecessaryGetter3205

[SRC]return th.getMessage();

[MSG]Violation in class grails.test.mixin.support.GrailsUnitTestMixin. getMessage() can probably be rewritten as message

Package: grails-plugin-testing.src.main.groovy.grails.test.mixin.web

➥ ControllerUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3124

[SRC]webRequest.getParams()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getParams() can probably be rewritten as params

UnnecessaryGetter3159

[SRC]webRequest.getFlashScope()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getFlashScope() can probably be rewritten as flashScope

UnnecessaryGetter3184

[SRC]final classLoader = ControllerUnitTestMixin.class.getClassLoader()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getClassLoader() can probably be rewritten as classLoader

UnnecessaryDotClass3184

[SRC]final classLoader = ControllerUnitTestMixin.class.getClassLoader()

[MSG]ControllerUnitTestMixin.class can be rewritten as ControllerUnitTestMixin

UnnecessaryGetter3252

[SRC]request = webRequest.getCurrentRequest()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter3253

[SRC]response = webRequest.getCurrentResponse()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getCurrentResponse() can probably be rewritten as currentResponse

UnnecessaryGetter3254

[SRC]servletContext = webRequest.getServletContext()

[MSG]Violation in class grails.test.mixin.web.ControllerUnitTestMixin. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter3349

[SRC]return factory.getObject()

[MSG]Violation in class grails.test.mixin.web.TestResponseMimeTypesApi. getObject() can probably be rewritten as object

UnnecessaryGetter3359

[SRC]return factory.getObject()

[MSG]Violation in class grails.test.mixin.web.TestRequestMimeTypesApi. getObject() can probably be rewritten as object

➥ FiltersUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter364

[SRC]getCompositeInterceptor().handlers?.clear()

[MSG]Violation in class grails.test.mixin.web.FiltersUnitTestMixin. getCompositeInterceptor() can probably be rewritten as compositeInterceptor

UnnecessaryGetter394

[SRC]return getCompositeInterceptor()

[MSG]Violation in class grails.test.mixin.web.FiltersUnitTestMixin. getCompositeInterceptor() can probably be rewritten as compositeInterceptor

UnnecessaryGetter3116

[SRC]final interceptor = getCompositeInterceptor()

[MSG]Violation in class grails.test.mixin.web.FiltersUnitTestMixin. getCompositeInterceptor() can probably be rewritten as compositeInterceptor

➥ GroovyPageUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter397

[SRC]MetaClass mc = tagLib.getMetaClass()

[MSG]Violation in class grails.test.mixin.web.GroovyPageUnitTestMixin. getMetaClass() can probably be rewritten as metaClass

➥ UrlMappingsUnitTestMixin.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2182

[SRC]void assertForwardUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. The cyclomatic complexity for method [assertForwardUrlMapping] is [23]

MisorderedStaticImports328

[SRC]import static junit.framework.Assert.assertEquals

[MSG]Static imports should appear before normal imports

MisorderedStaticImports329

[SRC]import static junit.framework.Assert.assertNotNull

[MSG]Static imports should appear before normal imports

UnnecessarySelfAssignment354

[SRC]grailsApplication = grailsApplication

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter360

[SRC]getUrlMappingsHolder()

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. getUrlMappingsHolder() can probably be rewritten as urlMappingsHolder

UnnecessaryGetter377

[SRC]UrlMappingsHolder mappingsHolder = getUrlMappingsHolder()

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. getUrlMappingsHolder() can probably be rewritten as urlMappingsHolder

UnnecessarySubstring3217

[SRC]if (actual[0] == "/") actual = actual.substring(1)

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3218

[SRC]if (expected[0] == "/") expected = expected.substring(1)

[MSG]Violation in class grails.test.mixin.web.UrlMappingsUnitTestMixin. The String.substring(int) method can be replaced with the subscript operator

Package: grails-plugin-tomcat.src.main.groovy.org.grails.plugins.tomcat

➥ InlineExplodedTomcatServer.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock255

[SRC]} catch (e) {

[MSG]The catch block is empty

MisorderedStaticImports325

[SRC]import static grails.build.logging.GrailsConsole.instance as CONSOLE

[MSG]Static imports should appear before normal imports

UnnecessaryGetter373

[SRC]def pluginManager = PluginManagerHolder.getPluginManager()

[MSG]Violation in class org.grails.plugins.tomcat.InlineExplodedTomcatServer. getPluginManager() can probably be rewritten as pluginManager

UnnecessaryObjectReferences3120

[SRC]sslConnector.setAttribute("keystorePass", keyPassword)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3121

[SRC]sslConnector.URIEncoding = 'UTF-8'

[MSG]The code could be more concise by using a with() or identity() block

➥ IsolatedWarTomcatServer.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock295

[SRC]try { err = errFile.text } catch (IOException e) {}

[MSG]The catch block is empty

EmptyCatchBlock2126

[SRC]} catch(e) {

[MSG]The catch block is empty

UnnecessaryGetter375

[SRC]for (entry in getConfigParams()) {

[MSG]Violation in class org.grails.plugins.tomcat.IsolatedWarTomcatServer. getConfigParams() can probably be rewritten as configParams

➥ TomcatLoader.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod252

[SRC]void addPropertyChangeListener(PropertyChangeListener listener) {}

[MSG]Violation in class TomcatLoader. The method addPropertyChangeListener is both empty and not marked with @Override

UnusedMethodParameter252

[SRC]void addPropertyChangeListener(PropertyChangeListener listener) {}

[MSG]Violation in class TomcatLoader. Method parameter [listener] is never referenced in the method addPropertyChangeListener of class org.grails.plugins.tomcat.TomcatLoader

EmptyMethod258

[SRC]void backgroundProcess() {}

[MSG]Violation in class TomcatLoader. The method backgroundProcess is both empty and not marked with @Override

EmptyMethod268

[SRC]void removePropertyChangeListener(PropertyChangeListener listener) {}

[MSG]Violation in class TomcatLoader. The method removePropertyChangeListener is both empty and not marked with @Override

UnusedMethodParameter268

[SRC]void removePropertyChangeListener(PropertyChangeListener listener) {}

[MSG]Violation in class TomcatLoader. Method parameter [listener] is never referenced in the method removePropertyChangeListener of class org.grails.plugins.tomcat.TomcatLoader

UnnecessaryGetter382

[SRC]log.info("Dual registration of jndi stream handler: " + ..etMessage())

[MSG]Violation in class org.grails.plugins.tomcat.TomcatLoader. getMessage() can probably be rewritten as message

UnnecessaryGetter386

[SRC]DirContextURLStreamHandler.bind(classLoader, container.getResources())

[MSG]Violation in class org.grails.plugins.tomcat.TomcatLoader. getResources() can probably be rewritten as resources

➥ TomcatServer.groovy

Rule NamePriorityLine #Source Line / Message
ClassForName2161

[SRC]Class.forName('sun.security.tools.KeyTool')

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)

ClassForName2164

[SRC]Class.forName('com.ibm.crypto.tools.KeyTool')

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)

MisorderedStaticImports323

[SRC]import static grails.build.logging.GrailsConsole.instance as CONSOLE

[MSG]Static imports should appear before normal imports

UnnecessaryGetter350

[SRC]buildSettings = BuildSettingsHolder.getSettings()

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. getSettings() can probably be rewritten as settings

UnnecessaryGetter351

[SRC]pluginSettings = GrailsPluginUtils.getPluginBuildSettings()

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. getPluginBuildSettings() can probably be rewritten as pluginBuildSettings

UnnecessaryGetter3145

[SRC]getKeyToolClass().main(

[MSG]Violation in class org.grails.plugins.tomcat.TomcatServer. getKeyToolClass() can probably be rewritten as keyToolClass

Package: grails-plugin-url-mappings.src.main.groovy.grails.test

➥ GrailsUrlMappingsTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod256

[SRC]def createMappingsHolder() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method createMappingsHolder is public but not a test method

JUnitPublicNonTestMethod263

[SRC]def createControllerMap() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method createControllerMap is public but not a test method

JUnitPublicNonTestMethod271

[SRC]def getUrlMappingEvaluatees() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method getUrlMappingEvaluatees is public but not a test method

JUnitSetUpCallsSuper284

[SRC]void setUp() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper291

[SRC]void tearDown() {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method tearDown() does not call super.tearDown()

JUnitPublicNonTestMethod295

[SRC]def getActions(controller) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method getActions is public but not a test method

JUnitPublicNonTestMethod2104

[SRC]def getDefaultAction(controllerName) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method getDefaultAction is public but not a test method

JUnitPublicNonTestMethod2109

[SRC]def assertController(controller, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertController is public but not a test method

JUnitPublicNonTestMethod2115

[SRC]def assertAction(controller, action, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertAction is public but not a test method

JUnitPublicNonTestMethod2121

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertView is public but not a test method

JUnitPublicNonTestMethod2129

[SRC]void assertUrlMapping(assertions, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertUrlMapping is public but not a test method

JUnitPublicNonTestMethod2133

[SRC]void assertUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertUrlMapping is public but not a test method

JUnitPublicNonTestMethod2140

[SRC]void assertForwardUrlMapping(assertions, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertForwardUrlMapping is public but not a test method

JUnitPublicNonTestMethod2144

[SRC]void assertForwardUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertForwardUrlMapping is public but not a test method

CyclomaticComplexity2144

[SRC]void assertForwardUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class grails.test.GrailsUrlMappingsTestCase. The cyclomatic complexity for method [assertForwardUrlMapping] is [21]

JUnitPublicNonTestMethod2202

[SRC]void assertReverseUrlMapping(assertions, url) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertReverseUrlMapping is public but not a test method

JUnitPublicNonTestMethod2206

[SRC]void assertReverseUrlMapping(assertions, url, paramAssertions) {

[MSG]Violation in class GrailsUrlMappingsTestCase. The method assertReverseUrlMapping is public but not a test method

UnusedImport318

[SRC]import grails.util.GrailsWebUtil

[MSG]The [grails.util.GrailsWebUtil] import is never referenced

UnusedImport320

[SRC]import org.codehaus.groovy.grails.commons.DefaultGrailsApplication

[MSG]The [org.codehaus.groovy.grails.commons.DefaultGrailsApplication] import is never referenced

UnusedImport321

[SRC]import org.codehaus.groovy.grails.commons.GrailsApplication

[MSG]The [org.codehaus.groovy.grails.commons.GrailsApplication] import is never referenced

UnusedImport324

[SRC]import org.codehaus.groovy.grails.plugins.web.mapping.Ur..GrailsPlugin

[MSG]The [org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin] import is never referenced

UnusedImport325

[SRC]import org.codehaus.groovy.grails.support.MockApplicationContext

[MSG]The [org.codehaus.groovy.grails.support.MockApplicationContext] import is never referenced

UnusedImport328

[SRC]import org.codehaus.groovy.grails.web.multipart.ContentL..partResolver

[MSG]The [org.codehaus.groovy.grails.web.multipart.ContentLengthAwareCommonsMultipartResolver] import is never referenced

UnusedImport330

[SRC]import org.springframework.web.context.WebApplicationContext

[MSG]The [org.springframework.web.context.WebApplicationContext] import is never referenced

UnusedImport332

[SRC]import org.springframework.web.servlet.DispatcherServlet

[MSG]The [org.springframework.web.servlet.DispatcherServlet] import is never referenced

UnusedImport334

[SRC]import org.springframework.web.context.ServletContextAware

[MSG]The [org.springframework.web.context.ServletContextAware] import is never referenced

UnusedImport335

[SRC]import javax.servlet.ServletContext

[MSG]The [javax.servlet.ServletContext] import is never referenced

DuplicateImport336

[SRC]import org.codehaus.groovy.grails.commons.GrailsClassUtils

UnnecessarySubstring3176

[SRC]if (actual[0] == "/") actual = actual.substring(1)

[MSG]Violation in class grails.test.GrailsUrlMappingsTestCase. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3177

[SRC]if (expected[0] == "/") expected = expected.substring(1)

[MSG]Violation in class grails.test.GrailsUrlMappingsTestCase. The String.substring(int) method can be replaced with the subscript operator

Package: grails-plugin-url-mappings.src.main.groovy.org.codehaus.groovy.grails.plugins.web.mapping

➥ UrlMappingsGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter2161

[SRC]private UrlMappingsHolder createUrlMappingsHolder(Grails..inManager) {

[MSG]Violation in class UrlMappingsGrailsPlugin. Method parameter [application] is never referenced in the method createUrlMappingsHolder of class org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin

UnusedPrivateMethodParameter2161

[SRC]private UrlMappingsHolder createUrlMappingsHolder(Grails..inManager) {

[MSG]Violation in class UrlMappingsGrailsPlugin. Method parameter [pluginManager] is never referenced in the method createUrlMappingsHolder of class org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin

UnnecessaryGetter347

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryPackageReference363

[SRC]urlMappingsTargetSource(org.springframework.aop.target.H..)) { bean ->

[MSG]The org.springframework.aop.target.HotSwappableTargetSource class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference363

[SRC]urlMappingsTargetSource(org.springframework.aop.target.H..)) { bean ->

[MSG]The org.springframework.aop.target.HotSwappableTargetSource class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference369

[SRC]proxyInterfaces = [org.codehaus.groovy.grails.web.mappin..pingsHolder]

[MSG]The org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference369

[SRC]proxyInterfaces = [org.codehaus.groovy.grails.web.mappin..pingsHolder]

[MSG]The org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder class was explicitly imported, so specifying the package name is not necessary

UnnecessaryCallForLastElement375

[SRC]def lastFilter = filters[filters.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filters.last() or filters[-1]

UnnecessaryCallForLastElement375

[SRC]def lastFilter = filters[filters.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filters.last() or filters[-1]

UnnecessaryCallForLastElement385

[SRC]def lastServlet = servlets[servlets.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to servlets.last() or servlets[-1]

UnnecessaryCallForLastElement385

[SRC]def lastServlet = servlets[servlets.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to servlets.last() or servlets[-1]

UnnecessaryCallForLastElement395

[SRC]def lastMapping = servletMappings[servletMappings.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to servletMappings.last() or servletMappings[-1]

UnnecessaryCallForLastElement395

[SRC]def lastMapping = servletMappings[servletMappings.size()-1]

[MSG]Unnecessarily complex access of last element. This can be simplified to servletMappings.last() or servletMappings[-1]

UnnecessaryCallForLastElement3124

[SRC]welcomeFileList = welcomeFileList[welcomeFileList.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to welcomeFileList.last() or welcomeFileList[-1]

UnnecessaryCallForLastElement3124

[SRC]welcomeFileList = welcomeFileList[welcomeFileList.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to welcomeFileList.last() or welcomeFileList[-1]

UnnecessaryCallForLastElement3132

[SRC]def lastFilterMapping = filterMappings[filterMappings.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filterMappings.last() or filterMappings[-1]

UnnecessaryCallForLastElement3132

[SRC]def lastFilterMapping = filterMappings[filterMappings.size() - 1]

[MSG]Unnecessarily complex access of last element. This can be simplified to filterMappings.last() or filterMappings[-1]

UnnecessaryGetter3166

[SRC]final urlMappingsHolder = factory.getObject()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.mapping.UrlMappingsGrailsPlugin. getObject() can probably be rewritten as object

Package: grails-plugin-validation.src.main.groovy.org.codehaus.groovy.grails.plugins

➥ ValidationGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter255

[SRC]private static addValidationMethods(application, validat..lass, ctx) {

[MSG]Violation in class ValidationGrailsPlugin. Method parameter [ctx] is never referenced in the method addValidationMethods of class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin

UnusedImport326

[SRC]import org.springframework.core.type.filter.AnnotationTypeFilter

[MSG]The [org.springframework.core.type.filter.AnnotationTypeFilter] import is never referenced

UnnecessaryGetter333

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryGetter364

[SRC]def attributes = rch.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter371

[SRC]def attributes = rch.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter390

[SRC]errors = new BeanPropertyBindingResult(delegate, delegat..).getName())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getName() can probably be rewritten as name

UnnecessaryGetter3100

[SRC]delegate.setErrors(new BeanPropertyBindingResult(delegat...getName()))

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin. getName() can probably be rewritten as name

Package: grails-plugin-validation.src.test.groovy.org.codehaus.groovy.grails.plugins

➥ ValidationGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSamePackage33

[SRC]import org.codehaus.groovy.grails.plugins.ValidationGrailsPlugin

UnnecessaryGetter312

[SRC]def registry = GroovySystem.getMetaClassRegistry()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.ValidationGrailsPluginTests. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

Package: grails-spring.src.main.groovy.grails.spring

➥ DynamicElementReader.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod275

[SRC]protected void afterInvocation() {

[MSG]Violation in class DynamicElementReader. The method afterInvocation is both empty and not marked with @Override

UnnecessaryGetter353

[SRC]EntityResolver entityResolver = new DelegatingEntityReso..assLoader())

[MSG]Violation in class grails.spring.DynamicElementReader. getClassLoader() can probably be rewritten as classLoader

UnnecessaryDotClass353

[SRC]EntityResolver entityResolver = new DelegatingEntityReso..assLoader())

[MSG]DynamicElementReader.class can be rewritten as DynamicElementReader

UnnecessaryGetter3121

[SRC]Element element = documentLoader.loadDocument(is, entity..entElement()

[MSG]Violation in class grails.spring.DynamicElementReader. getDocumentElement() can probably be rewritten as documentElement

UnnecessaryGetter3126

[SRC]BeanDefinitionHolder holder = new BeanDefinitionHolder(b..n.getName())

[MSG]Violation in class grails.spring.DynamicElementReader. getBeanDefinition() can probably be rewritten as beanDefinition

UnnecessaryGetter3126

[SRC]BeanDefinitionHolder holder = new BeanDefinitionHolder(b..n.getName())

[MSG]Violation in class grails.spring.DynamicElementReader. getName() can probably be rewritten as name

UnnecessaryGetter3128

[SRC]beanConfiguration.setBeanDefinition(holder.getBeanDefinition())

[MSG]Violation in class grails.spring.DynamicElementReader. getBeanDefinition() can probably be rewritten as beanDefinition

Package: grails-test-suite-base.src.main.groovy.org.codehaus.groovy.grails.plugins.web

➥ AbstractGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper282

[SRC]protected final void tearDown() {

[MSG]Violation in class AbstractGrailsPluginTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter350

[SRC]ga = new DefaultGrailsApplication(gcl.getLoadedClasses(),gcl)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.AbstractGrailsPluginTests. getLoadedClasses() can probably be rewritten as loadedClasses

UnnecessaryGetter375

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.AbstractGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test-suite-base.src.main.groovy.org.codehaus.groovy.grails.web.servlet.mvc

➥ AbstractGrailsControllerTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2150

[SRC]def withConfig(String text, Closure callable) {

[MSG]Violation in class AbstractGrailsControllerTests. The method withConfig is public but not a test method

JUnitPublicNonTestMethod2162

[SRC]GrailsWebRequest buildMockRequest(ConfigObject config) t.. Exception {

[MSG]Violation in class AbstractGrailsControllerTests. The method buildMockRequest is public but not a test method

JUnitPublicNonTestMethod2174

[SRC]void runTest(Closure callable) {

[MSG]Violation in class AbstractGrailsControllerTests. The method runTest is public but not a test method

UnnecessaryGetter376

[SRC]ga = new DefaultGrailsApplication(gcl.getLoadedClasses(), gcl)

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getLoadedClasses() can probably be rewritten as loadedClasses

UnnecessaryGetter3112

[SRC]servletContext = ctx.getServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter3119

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3169

[SRC]appCtx.getServletContext().setAttribute(GrailsApplicatio..EXT, appCtx)

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter3170

[SRC]appCtx.getServletContext().setAttribute(WebApplicationCo..UTE, appCtx)

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests. getServletContext() can probably be rewritten as servletContext

Package: grails-test-suite-base.src.main.groovy.org.codehaus.groovy.grails.web.taglib

➥ AbstractGrailsTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod268

[SRC]def withConfig(String text, Closure callable) {

[MSG]Violation in class AbstractGrailsTagTests. The method withConfig is public but not a test method

JUnitPublicNonTestMethod280

[SRC]GrailsWebRequest buildMockRequest(ConfigObject config) t.. Exception {

[MSG]Violation in class AbstractGrailsTagTests. The method buildMockRequest is public but not a test method

JUnitPublicNonTestMethod289

[SRC]def profile(String name, Closure callable) {

[MSG]Violation in class AbstractGrailsTagTests. The method profile is public but not a test method

JUnitPublicNonTestMethod299

[SRC]def withTag(String tagName, Writer out, Closure callable) {

[MSG]Violation in class AbstractGrailsTagTests. The method withTag is public but not a test method

UnusedVariable2122

[SRC]GroovyPageOutputStack stack=GroovyPageOutputStack.createNew(out)

[MSG]The variable [stack] in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests is not used

JUnitSetUpCallsSuper2150

[SRC]protected void setUp() throws Exception {

[MSG]Violation in class AbstractGrailsTagTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper2240

[SRC]protected void tearDown() {

[MSG]Violation in class AbstractGrailsTagTests. The method tearDown() does not call super.tearDown()

JUnitPublicNonTestMethod2265

[SRC]void runTest(Closure callable) {

[MSG]Violation in class AbstractGrailsTagTests. The method runTest is public but not a test method

JUnitPublicNonTestMethod2269

[SRC]void printCompiledSource(template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method printCompiledSource is public but not a test method

JUnitPublicNonTestMethod2275

[SRC]def getCompiledSource(template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method getCompiledSource is public but not a test method

UnusedVariable2289

[SRC]String text = sw.toString()

[MSG]The variable [text] in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests is not used

JUnitPublicNonTestMethod2292

[SRC]def assertCompiledSourceContains(expected, template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method assertCompiledSourceContains is public but not a test method

JUnitPublicNonTestMethod2297

[SRC]void assertOutputContains(expected, template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method assertOutputContains is public but not a test method

JUnitPublicNonTestMethod2302

[SRC]void assertOutputNotContains(expected, template, params = [:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method assertOutputNotContains is public but not a test method

JUnitPublicNonTestMethod2320

[SRC]void assertOutputEquals(expected, template, params = [:]..tring() }) {

[MSG]Violation in class AbstractGrailsTagTests. The method assertOutputEquals is public but not a test method

JUnitPublicNonTestMethod2356

[SRC]def applyTemplate(template, params = [:], target = null,..me = null) {

[MSG]Violation in class AbstractGrailsTagTests. The method applyTemplate is public but not a test method

JUnitPublicNonTestMethod2381

[SRC]String sitemeshPreprocess(String template) {

[MSG]Violation in class AbstractGrailsTagTests. The method sitemeshPreprocess is public but not a test method

JUnitPublicNonTestMethod2386

[SRC]String applyLayout(String layout, String template, Map params=[:]) {

[MSG]Violation in class AbstractGrailsTagTests. The method applyLayout is public but not a test method

UnnecessaryGetter385

[SRC]initThemeSource(request.getCurrentRequest(), messageSource)

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter3204

[SRC]JstlUtils.exposeLocalizationContext webRequest.getRequest(),null

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. getRequest() can probably be rewritten as request

UnnecessaryGetter3215

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryDefInMethodDeclaration3235

[SRC]private def initThemeSource(request, StaticMessageSource..ageSource) {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3343

[SRC]protected def assertTemplateOutputEquals(expected, Groov..tring() }) {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.AbstractGrailsTagTests. The def keyword is unneeded when a method is marked protected

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate

➥ AbstractGrailsHibernateTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2121

[SRC]void onApplicationCreated() {}

[MSG]Violation in class AbstractGrailsHibernateTests. The method onApplicationCreated is public but not a test method

JUnitPublicNonTestMethod2137

[SRC]GrailsWebRequest buildMockRequest(ConfigObject config = .. Exception {

[MSG]Violation in class AbstractGrailsHibernateTests. The method buildMockRequest is public but not a test method

EmptyCatchBlock2158

[SRC]catch(e) {

[MSG]The catch block is empty

EmptyCatchBlock2165

[SRC]catch(e) {

[MSG]The catch block is empty

UnnecessaryGetter372

[SRC]ga = new DefaultGrailsApplication(gcl.getLoadedClasses(), gcl)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getLoadedClasses() can probably be rewritten as loadedClasses

UnnecessaryGetter386

[SRC]ga.setMainContext(springConfig.getUnrefreshedApplicationContext())

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter387

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3162

[SRC]getClass().classLoader.loadClass("net.sf.ehcache.CacheManager")

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getInstance() can probably be rewritten as instance

UnnecessaryGetter3198

[SRC]GroovySystem.getMetaClassRegistry().removeMetaClass meta..tyMode.POJO)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AbstractGrailsHibernateTests. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

➥ AbstractInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable283

[SRC]def Abstract = ga.getDomainClass("AbstractInheritanceAbs..Base").clazz

[MSG]The variable [Abstract] in class org.codehaus.groovy.grails.orm.hibernate.AbstractInheritanceTests is not used

UnusedVariable2104

[SRC]def Comment = ga.getDomainClass("AbstractInheritanceComment").clazz

[MSG]The variable [Comment] in class org.codehaus.groovy.grails.orm.hibernate.AbstractInheritanceTests is not used

➥ AllDeleteOrphanMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert236

[SRC]void testDeleteOrphanMapping() {

[MSG]Violation in class AllDeleteOrphanMappingTests. Test method 'testDeleteOrphanMapping' makes no assertions

➥ AssertionFailureInEventTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert216

[SRC]void testNoAssertionErrorInEvent() {

[MSG]Violation in class AssertionFailureInEventTests. Test method 'testNoAssertionErrorInEvent' makes no assertions

➥ AutoImportPackedDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertEqualsInsteadOfAssertTrue327

[SRC]assertTrue models.size() == 1

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AutoImportPackedDomainTests. Replace assertTrue with a call to assertEquals()

UseAssertEqualsInsteadOfAssertTrue330

[SRC]assertTrue models.size() == 1

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AutoImportPackedDomainTests. Replace assertTrue with a call to assertEquals()

UseAssertEqualsInsteadOfAssertTrue333

[SRC]assertTrue models.size() == 1

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.AutoImportPackedDomainTests. Replace assertTrue with a call to assertEquals()

➥ BidirectionalHasOneMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert227

[SRC]void testRefreshHasOneAssociation() {

[MSG]Violation in class BidirectionalHasOneMappingTests. Test method 'testRefreshHasOneAssociation' makes no assertions

➥ BidirectionalListMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper222

[SRC]protected void setUp() {

[MSG]Violation in class BidirectionalListMappingTests. The method setUp() does not call super.setUp()

UnusedVariable259

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable297

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable2147

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable2169

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable2188

[SRC]PersistentClass faqSection = config.getClassMapping("TestFaqSection")

[MSG]The variable [faqSection] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

UnusedVariable2276

[SRC]SimpleValue indexColumnValue = indexColumn.getValue()

[MSG]The variable [indexColumnValue] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests is not used

JUnitUnnecessaryTearDown354

[SRC]protected void tearDown() {

[MSG]Violation in class BidirectionalListMappingTests. The tearDown() method contains no logic and can be removed

UnnecessaryOverridingMethod354

[SRC]protected void tearDown() {

[MSG]Violation in class BidirectionalListMappingTests. The method tearDown contains no logic and can be safely deleted

UnnecessaryGetter374

[SRC]assertNull elementsIndexBackref.getCascade()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascade() can probably be rewritten as cascade

UnnecessaryGetter375

[SRC]assertEquals CascadeStyle.NONE, elementsIndexBackref.getCascadeStyle()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascadeStyle() can probably be rewritten as cascadeStyle

UnnecessaryGetter376

[SRC]assertEquals "TestFaqSection.elements", elementsIndexBa..ectionRole()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCollectionRole() can probably be rewritten as collectionRole

UnnecessaryGetter377

[SRC]assertEquals 1, elementsIndexBackref.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter378

[SRC]assertEquals "TestFaqSection", elementsIndexBackref.getEntityName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getEntityName() can probably be rewritten as entityName

UnnecessaryGetter379

[SRC]assertEquals PropertyGeneration.NEVER, elementsIndexBack..Generation()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getGeneration() can probably be rewritten as generation

UnnecessaryGetter380

[SRC]assertEquals "_elementsIndexBackref", elementsIndexBackref.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter381

[SRC]assertNull elementsIndexBackref.getNodeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNodeName() can probably be rewritten as nodeName

UnnecessaryGetter382

[SRC]assertNull elementsIndexBackref.getPropertyAccessorName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPropertyAccessorName() can probably be rewritten as propertyAccessorName

UnnecessaryGetter383

[SRC]assertEquals IntegerType, elementsIndexBackref.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter384

[SRC]assertEquals SimpleValue, elementsIndexBackref.getValue().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter386

[SRC]SimpleValue value = elementsIndexBackref.getValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3112

[SRC]assertNull elementsBackref.getCascade()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascade() can probably be rewritten as cascade

UnnecessaryGetter3113

[SRC]assertEquals CascadeStyle.NONE, elementsBackref.getCascadeStyle()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascadeStyle() can probably be rewritten as cascadeStyle

UnnecessaryGetter3114

[SRC]assertEquals "TestFaqSection.elements", elementsBackref...ectionRole()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCollectionRole() can probably be rewritten as collectionRole

UnnecessaryGetter3115

[SRC]assertEquals 1, elementsBackref.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3116

[SRC]assertEquals "TestFaqSection", elementsBackref.getEntityName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getEntityName() can probably be rewritten as entityName

UnnecessaryGetter3117

[SRC]assertEquals PropertyGeneration.NEVER, elementsBackref.getGeneration()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getGeneration() can probably be rewritten as generation

UnnecessaryGetter3118

[SRC]assertEquals "_TestFaqSection_elementsBackref", elements..ef.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter3119

[SRC]assertNull elementsBackref.getNodeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNodeName() can probably be rewritten as nodeName

UnnecessaryGetter3120

[SRC]assertEquals "TestFaqElement", elementsBackref.getPersis..tClassName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getClassName() can probably be rewritten as className

UnnecessaryGetter3120

[SRC]assertEquals "TestFaqElement", elementsBackref.getPersis..tClassName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPersistentClass() can probably be rewritten as persistentClass

UnnecessaryGetter3121

[SRC]assertNull elementsBackref.getPropertyAccessorName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPropertyAccessorName() can probably be rewritten as propertyAccessorName

UnnecessaryGetter3122

[SRC]assertEquals LongType, elementsBackref.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3123

[SRC]assertEquals DependantValue, elementsBackref.getValue().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3125

[SRC]DependantValue value = elementsBackref.getValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3133

[SRC]assertEquals 1,value.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3134

[SRC]assertTrue value.getColumnInsertability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3135

[SRC]assertEquals 1,value.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3136

[SRC]assertTrue value.getColumnUpdateability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3138

[SRC]assertEquals 1, value.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3139

[SRC]assertEquals FetchMode.SELECT, value.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3140

[SRC]assertNull value.getForeignKeyName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getForeignKeyName() can probably be rewritten as foreignKeyName

UnnecessaryGetter3141

[SRC]assertEquals "assigned", value.getIdentifierGeneratorStrategy()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getIdentifierGeneratorStrategy() can probably be rewritten as identifierGeneratorStrategy

UnnecessaryGetter3142

[SRC]assertNull value.getNullValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNullValue() can probably be rewritten as nullValue

UnnecessaryGetter3143

[SRC]assertEquals LongType, value.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3161

[SRC]assertEquals "none", section.getCascade()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascade() can probably be rewritten as cascade

UnnecessaryGetter3162

[SRC]assertEquals CascadeStyle.NONE, section.getCascadeStyle()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCascadeStyle() can probably be rewritten as cascadeStyle

UnnecessaryGetter3163

[SRC]assertEquals 1, section.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3164

[SRC]assertEquals PropertyGeneration.NEVER, section.getGeneration()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getGeneration() can probably be rewritten as generation

UnnecessaryGetter3165

[SRC]assertEquals "section", section.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter3172

[SRC]Column sectionColumn = section.getColumnIterator().next()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnIterator() can probably be rewritten as columnIterator

UnnecessaryGetter3174

[SRC]assertEquals "section_id", sectionColumn.getCanonicalName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCanonicalName() can probably be rewritten as canonicalName

UnnecessaryGetter3175

[SRC]assertNull sectionColumn.getCheckConstraint()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCheckConstraint() can probably be rewritten as checkConstraint

UnnecessaryGetter3176

[SRC]assertNull sectionColumn.getComment()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getComment() can probably be rewritten as comment

UnnecessaryGetter3177

[SRC]assertNull sectionColumn.getDefaultValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getDefaultValue() can probably be rewritten as defaultValue

UnnecessaryGetter3178

[SRC]assertEquals 255, sectionColumn.getLength()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getLength() can probably be rewritten as length

UnnecessaryGetter3179

[SRC]assertEquals "section_id", sectionColumn.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter3180

[SRC]assertEquals 19, sectionColumn.getPrecision()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPrecision() can probably be rewritten as precision

UnnecessaryGetter3181

[SRC]assertEquals "section_id", sectionColumn.getQuotedName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getQuotedName() can probably be rewritten as quotedName

UnnecessaryGetter3182

[SRC]assertEquals 2, sectionColumn.getScale()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getScale() can probably be rewritten as scale

UnnecessaryGetter3183

[SRC]assertEquals "section_id", sectionColumn.getText()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getText() can probably be rewritten as text

UnnecessaryGetter3184

[SRC]assertEquals 0, sectionColumn.getTypeIndex()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getTypeIndex() can probably be rewritten as typeIndex

UnnecessaryGetter3192

[SRC]ManyToOne manyToOne = section.getValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3193

[SRC]assertEquals 1,manyToOne.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3194

[SRC]assertTrue manyToOne.getColumnInsertability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3195

[SRC]assertEquals 1,manyToOne.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3196

[SRC]assertTrue manyToOne.getColumnUpdateability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3208

[SRC]assertEquals 1, manyToOne.getConstraintColumns().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getConstraintColumns() can probably be rewritten as constraintColumns

UnnecessaryGetter3209

[SRC]assertEquals FetchMode.DEFAULT, manyToOne.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3210

[SRC]assertNull manyToOne.getForeignKeyName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getForeignKeyName() can probably be rewritten as foreignKeyName

UnnecessaryGetter3211

[SRC]assertEquals "assigned", manyToOne.getIdentifierGeneratorStrategy()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getIdentifierGeneratorStrategy() can probably be rewritten as identifierGeneratorStrategy

UnnecessaryGetter3212

[SRC]assertNull manyToOne.getNullValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNullValue() can probably be rewritten as nullValue

UnnecessaryGetter3213

[SRC]assertEquals "TestFaqSection", manyToOne.getReferencedEntityName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getReferencedEntityName() can probably be rewritten as referencedEntityName

UnnecessaryGetter3214

[SRC]assertNull manyToOne.getReferencedPropertyName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getReferencedPropertyName() can probably be rewritten as referencedPropertyName

UnnecessaryGetter3215

[SRC]assertEquals ManyToOneType, manyToOne.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3216

[SRC]assertEquals "TestFaqSection", manyToOne.getTypeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getTypeName() can probably be rewritten as typeName

UnnecessaryGetter3246

[SRC]assertEquals 0,list.getBaseIndex()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getBaseIndex() can probably be rewritten as baseIndex

UnnecessaryGetter3248

[SRC]Table t = list.getCollectionTable()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCollectionTable() can probably be rewritten as collectionTable

UnnecessaryGetter3250

[SRC]assertEquals 0, list.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3251

[SRC]assertNull list.getCacheConcurrencyStrategy()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCacheConcurrencyStrategy() can probably be rewritten as cacheConcurrencyStrategy

UnnecessaryGetter3252

[SRC]assertEquals "TestFaqSection.elements", list.getCacheRegionName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCacheRegionName() can probably be rewritten as cacheRegionName

UnnecessaryGetter3253

[SRC]assertEquals 0,list.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3254

[SRC]assertEquals 0, list.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3255

[SRC]assertNull list.getElementNodeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getElementNodeName() can probably be rewritten as elementNodeName

UnnecessaryGetter3256

[SRC]SimpleValue index = list.getIndex()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getIndex() can probably be rewritten as index

UnnecessaryGetter3258

[SRC]assertEquals 1,index.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3259

[SRC]assertTrue index.getColumnInsertability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3260

[SRC]assertEquals 1,index.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3261

[SRC]assertTrue index.getColumnUpdateability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3263

[SRC]assertEquals 1, index.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3265

[SRC]Column indexColumn = index.getColumnIterator().next()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnIterator() can probably be rewritten as columnIterator

UnnecessaryGetter3266

[SRC]assertEquals "elements_idx", indexColumn.getCanonicalName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCanonicalName() can probably be rewritten as canonicalName

UnnecessaryGetter3267

[SRC]assertNull indexColumn.getCheckConstraint()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getCheckConstraint() can probably be rewritten as checkConstraint

UnnecessaryGetter3268

[SRC]assertNull indexColumn.getComment()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getComment() can probably be rewritten as comment

UnnecessaryGetter3269

[SRC]assertNull indexColumn.getDefaultValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getDefaultValue() can probably be rewritten as defaultValue

UnnecessaryGetter3270

[SRC]assertEquals 255, indexColumn.getLength()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getLength() can probably be rewritten as length

UnnecessaryGetter3271

[SRC]assertEquals "elements_idx", indexColumn.getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getName() can probably be rewritten as name

UnnecessaryGetter3272

[SRC]assertEquals 19, indexColumn.getPrecision()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getPrecision() can probably be rewritten as precision

UnnecessaryGetter3273

[SRC]assertEquals "elements_idx", indexColumn.getQuotedName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getQuotedName() can probably be rewritten as quotedName

UnnecessaryGetter3274

[SRC]assertEquals 2, indexColumn.getScale()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getScale() can probably be rewritten as scale

UnnecessaryGetter3275

[SRC]assertEquals "elements_idx", indexColumn.getText()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getText() can probably be rewritten as text

UnnecessaryGetter3276

[SRC]SimpleValue indexColumnValue = indexColumn.getValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getValue() can probably be rewritten as value

UnnecessaryGetter3278

[SRC]assertEquals FetchMode.SELECT, index.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3279

[SRC]assertNull index.getForeignKeyName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getForeignKeyName() can probably be rewritten as foreignKeyName

UnnecessaryGetter3280

[SRC]assertEquals "assigned", index.getIdentifierGeneratorStrategy()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getIdentifierGeneratorStrategy() can probably be rewritten as identifierGeneratorStrategy

UnnecessaryGetter3281

[SRC]assertNull index.getNullValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNullValue() can probably be rewritten as nullValue

UnnecessaryGetter3282

[SRC]assertEquals IntegerType, index.getType()?.getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3283

[SRC]assertEquals "integer", index.getTypeName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getTypeName() can probably be rewritten as typeName

UnnecessaryGetter3284

[SRC]assertNull index.getTypeParameters()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getTypeParameters() can probably be rewritten as typeParameters

UnnecessaryGetter3286

[SRC]KeyValue key = list.getKey()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getKey() can probably be rewritten as key

UnnecessaryGetter3288

[SRC]assertEquals 1,key.getColumnInsertability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3289

[SRC]assertTrue key.getColumnInsertability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnInsertability() can probably be rewritten as columnInsertability

UnnecessaryGetter3290

[SRC]assertEquals 1,key.getColumnUpdateability().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3291

[SRC]assertTrue key.getColumnUpdateability()[0]

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnUpdateability() can probably be rewritten as columnUpdateability

UnnecessaryGetter3293

[SRC]assertEquals 1, key.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3294

[SRC]assertEquals FetchMode.SELECT, key.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3295

[SRC]assertNull key.getNullValue()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getNullValue() can probably be rewritten as nullValue

UnnecessaryGetter3296

[SRC]assertEquals LongType, key.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

UnnecessaryGetter3298

[SRC]OneToMany element = list.getElement()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getElement() can probably be rewritten as element

UnnecessaryGetter3300

[SRC]assertEquals 1, element.getColumnSpan()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getColumnSpan() can probably be rewritten as columnSpan

UnnecessaryGetter3301

[SRC]assertEquals FetchMode.JOIN, element.getFetchMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3302

[SRC]PersistentClass associatedClass = element.getAssociatedClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getAssociatedClass() can probably be rewritten as associatedClass

UnnecessaryGetter3303

[SRC]assertEquals "TestFaqElement", associatedClass.getClassName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getClassName() can probably be rewritten as className

UnnecessaryGetter3304

[SRC]assertEquals ManyToOneType, element.getType().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListMappingTests. getType() can probably be rewritten as type

➥ BidirectionalListPersistTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]section = session.get(sectionClass.getClazz(),1L)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalListPersistTests. getClazz() can probably be rewritten as clazz

➥ BidirectionalOneToManyAndCircularOneToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter367

[SRC]assertEquals uploadsProperty.getOtherSide(), recipientProperty

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyAndCircularOneToManyTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter368

[SRC]assertEquals recipientProperty.getOtherSide(), uploadsProperty

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyAndCircularOneToManyTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter380

[SRC]assertEquals uploadLogsProperty.getOtherSide(), senderProperty

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyAndCircularOneToManyTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter381

[SRC]assertEquals senderProperty.getOtherSide(), uploadLogsProperty

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyAndCircularOneToManyTests. getOtherSide() can probably be rewritten as otherSide

➥ BidirectionalOneToManyAndOneToOneTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert230

[SRC]void testSaveAndLoad() {

[MSG]Violation in class BidirectionalOneToManyAndOneToOneTests. Test method 'testSaveAndLoad' makes no assertions

➥ BidirectionalOneToManyWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable252

[SRC]def configItemClass = ga.getDomainClass("ConfigurationItem").clazz

[MSG]The variable [configItemClass] in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOneToManyWithInheritanceTests is not used

➥ BidirectionalOnetoManyWithInheritanceRelationshipManagementTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter344

[SRC]def otherSide = collection.getOtherSide()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.BidirectionalOnetoManyWithInheritanceRelationshipManagementTests. getOtherSide() can probably be rewritten as otherSide

➥ CascadingDeleteBehaviour2Tests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod255

[SRC]void onSetUp() {

[MSG]Violation in class CascadingDeleteBehaviour2Tests. The method onSetUp is public but not a test method

➥ CascadingDeleteBehaviour3Tests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod237

[SRC]void onSetUp() {

[MSG]Violation in class CascadingDeleteBehaviour3Tests. The method onSetUp is public but not a test method

UnusedImport33

[SRC]import org.codehaus.groovy.grails.commons.GrailsDomainClass

[MSG]The [org.codehaus.groovy.grails.commons.GrailsDomainClass] import is never referenced

➥ CascadingDeleteBehaviourTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod285

[SRC]void onSetUp() {

[MSG]Violation in class CascadingDeleteBehaviourTests. The method onSetUp is public but not a test method

➥ CascadingSaveAndUniqueConstraintTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert231

[SRC]void testCascadingSaveAndUniqueConstraint() {

[MSG]Violation in class CascadingSaveAndUniqueConstraintTests. Test method 'testCascadingSaveAndUniqueConstraint' makes no assertions

UnusedVariable234

[SRC]def face = faceClass.newInstance(nose:noseClass.newInstance()).save()

[MSG]The variable [face] in class org.codehaus.groovy.grails.orm.hibernate.CascadingSaveAndUniqueConstraintTests is not used

➥ CircularRelationshipTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod228

[SRC]void onSetUp() {

[MSG]Violation in class CircularRelationshipTests. The method onSetUp is public but not a test method

➥ CircularUnidirectionalOneToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod233

[SRC]void onSetUp() {

[MSG]Violation in class CircularUnidirectionalOneToManyTests. The method onSetUp is public but not a test method

➥ ClassHeirarchyInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod232

[SRC]void onSetUp() {

[MSG]Violation in class ClassHeirarchyInheritanceTests. The method onSetUp is public but not a test method

➥ CreateCriteriaTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod258

[SRC]void onSetUp() {

[MSG]Violation in class CreateCriteriaTests. The method onSetUp is public but not a test method

➥ CreateMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod227

[SRC]void onSetUp() {

[MSG]Violation in class CreateMethodTests. The method onSetUp is public but not a test method

➥ CriteriaBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3135

[SRC]def criteriaInstance = getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.CriteriaBuilderTests. getInstance() can probably be rewritten as instance

UnnecessaryGetter3149

[SRC]def criteriaInstance = getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.CriteriaBuilderTests. getInstance() can probably be rewritten as instance

➥ CriteriaListDistinctTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable232

[SRC]def Plant = ga.getDomainClass("Plant").clazz

[MSG]The variable [Plant] in class org.codehaus.groovy.grails.orm.hibernate.CriteriaListDistinctTests is not used

UnusedVariable266

[SRC]def Plant = ga.getDomainClass("Plant").clazz

[MSG]The variable [Plant] in class org.codehaus.groovy.grails.orm.hibernate.CriteriaListDistinctTests is not used

➥ CustomCascadeMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable238

[SRC]def twoClass = ga.getDomainClass("CustomCascadeMappingTwo").clazz

[MSG]The variable [twoClass] in class org.codehaus.groovy.grails.orm.hibernate.CustomCascadeMappingTests is not used

➥ CyclicManyToManyWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert247

[SRC]void testCyclicManyToManyWithInheritance() {

[MSG]Violation in class CyclicManyToManyWithInheritanceTests. Test method 'testCyclicManyToManyWithInheritance' makes no assertions

➥ DataBindingDynamicConstructorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod211

[SRC]void onSetUp() {

[MSG]Violation in class DataBindingDynamicConstructorTests. The method onSetUp is public but not a test method

➥ DataSourceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter327

[SRC]sessionFactoryConnection = sessionFactoryConnection.getW..Connection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getWrappedConnection() can probably be rewritten as wrappedConnection

UnnecessaryGetter330

[SRC]sessionFactoryConnection = sessionFactoryConnection.getT..Connection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getTargetConnection() can probably be rewritten as targetConnection

UnnecessaryGetter336

[SRC]dataSourceConnection = dataSourceConnection.getTargetConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getTargetConnection() can probably be rewritten as targetConnection

UnnecessaryGetter339

[SRC]dataSourceConnection = dataSourceConnection.getWrappedConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getWrappedConnection() can probably be rewritten as wrappedConnection

UnnecessaryGetter342

[SRC]dataSourceConnection = dataSourceConnection.getTargetConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. getTargetConnection() can probably be rewritten as targetConnection

UseAssertSameInsteadOfAssertTrue348

[SRC]assertTrue sessionFactoryConnection.is(dataSourceConnection)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. assert method can be simplified using the assertSame method

UseAssertSameInsteadOfAssertTrue349

[SRC]assertFalse unproxiedConnection.is(dataSourceConnection)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DataSourceTests. assert method can be simplified using the assertSame method

➥ DeepHierarchyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod280

[SRC]void onSetUp() {

[MSG]Violation in class DeepHierarchyTests. The method onSetUp is public but not a test method

➥ DefaultSortOrderForCollectionTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable230

[SRC]def Book = ga.getDomainClass("DefaultSortOrderForCollect..Book").clazz

[MSG]The variable [Book] in class org.codehaus.groovy.grails.orm.hibernate.DefaultSortOrderForCollectionTests is not used

➥ DeleteFromCollectionTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable236

[SRC]def bookClass = ga.getDomainClass("DeleteBook").clazz

[MSG]The variable [bookClass] in class org.codehaus.groovy.grails.orm.hibernate.DeleteFromCollectionTests is not used

➥ DeleteMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod225

[SRC]void onSetUp() {

[MSG]Violation in class DeleteMethodTests. The method onSetUp is public but not a test method

➥ DerivedPropertiesTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod246

[SRC]protected void afterPluginInitialization() {

[MSG]Violation in class DerivedPropertiesTests. The method afterPluginInitialization is both empty and not marked with @Override

EmptyMethod249

[SRC]protected void onTearDown() {

[MSG]Violation in class DerivedPropertiesTests. The method onTearDown is both empty and not marked with @Override

UnusedVariable254

[SRC]def mc = mdc.clazz

[MSG]The variable [mc] in class org.codehaus.groovy.grails.orm.hibernate.DerivedPropertiesTests is not used

➥ DirtyTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3126

[SRC]assertEquals 0, d.getDirtyPropertyNames().size()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DirtyTests. getDirtyPropertyNames() can probably be rewritten as dirtyPropertyNames

➥ DiscriminatorColumnMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable245

[SRC]def Child2 = ga.getDomainClass("Child2").clazz

[MSG]The variable [Child2] in class org.codehaus.groovy.grails.orm.hibernate.DiscriminatorColumnMappingTests is not used

➥ DiscriminatorFormulaMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2116

[SRC]def Root = ga.getDomainClass("Root").clazz

[MSG]The variable [Root] in class org.codehaus.groovy.grails.orm.hibernate.DiscriminatorFormulaMappingTests is not used

UseAssertNullInsteadOfAssertEquals3101

[SRC]assertEquals null, rs.getString("tree")

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DiscriminatorFormulaMappingTests. assertEquals can be simplified using assertNull

UnnecessaryObjectReferences3111

[SRC]rs.close()

[MSG]The code could be more concise by using a with() or identity() block

➥ DomainEventsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert240

[SRC]void testNoModifyVersion() {

[MSG]Violation in class DomainEventsTests. Test method 'testNoModifyVersion' makes no assertions

UnusedVariable2154

[SRC]def success = false

[MSG]The variable [success] in class org.codehaus.groovy.grails.orm.hibernate.DomainEventsTests is not used

➥ DomainEventsWithMethodsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2276

[SRC]void onSetUp() {

[MSG]Violation in class DomainEventsWithMethodsTests. The method onSetUp is public but not a test method

➥ DontFlushAfterDataAccessExceptionTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter348

[SRC]assertEquals FlushMode.AUTO, session.getFlushMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DontFlushAfterDataAccessExceptionTests. getFlushMode() can probably be rewritten as flushMode

UnnecessaryGetter358

[SRC]assertEquals FlushMode.MANUAL, session.getFlushMode()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.DontFlushAfterDataAccessExceptionTests. getFlushMode() can probably be rewritten as flushMode

➥ EagerFindByQueryTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable233

[SRC]def tagClass = ga.getDomainClass("EagerFindByQueryTag").clazz

[MSG]The variable [tagClass] in class org.codehaus.groovy.grails.orm.hibernate.EagerFindByQueryTests is not used

UnusedVariable250

[SRC]def tagClass = ga.getDomainClass("EagerFindByQueryTag").clazz

[MSG]The variable [tagClass] in class org.codehaus.groovy.grails.orm.hibernate.EagerFindByQueryTests is not used

UnusedVariable267

[SRC]def tagClass = ga.getDomainClass("EagerFindByQueryTag").clazz

[MSG]The variable [tagClass] in class org.codehaus.groovy.grails.orm.hibernate.EagerFindByQueryTests is not used

UnusedVariable283

[SRC]def tagClass = ga.getDomainClass("EagerFindByQueryTag").clazz

[MSG]The variable [tagClass] in class org.codehaus.groovy.grails.orm.hibernate.EagerFindByQueryTests is not used

➥ EnumMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter381

[SRC]def con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.EnumMappingTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3104

[SRC]def con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.EnumMappingTests. getConnection() can probably be rewritten as connection

➥ ExecuteUpdateTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod220

[SRC]def init() {

[MSG]Violation in class ExecuteUpdateTests. The method init is public but not a test method

➥ ExistsTests.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSamePackage33

[SRC]import org.codehaus.groovy.grails.orm.hibernate.Abstract..bernateTests

➥ FindAllMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences350

[SRC]theClass.findAll("from FindAllTest where name = 'Angus'"..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences355

[SRC]theClass.findAll("from FindAllTest where name = 'Malcolm..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences360

[SRC]theClass.findAll("from FindAllTest where name = 'Malcolm..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3103

[SRC]theClass.findAll("from FindAllTest where name = :name", ..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3108

[SRC]theClass.findAll("from FindAllTest where name = :name", ..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3113

[SRC]theClass.findAll("from FindAllTest where name = :name", ..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

➥ FindByMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2186

[SRC]def jakeB = new Person(firstName: 'Jake', lastName: 'Bro..: 11).save()

[MSG]The variable [jakeB] in class org.codehaus.groovy.grails.orm.hibernate.FindByMethodTests is not used

➥ FindMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod25

[SRC]void onSetUp() {

[MSG]Violation in class FindMethodTests. The method onSetUp is public but not a test method

UnnecessaryObjectReferences374

[SRC]theClass.find("from FindMethodTestClass where one = 'Ang..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences379

[SRC]theClass.find("from FindMethodTestClass where one = 'Mal..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences384

[SRC]theClass.find("from FindMethodTestClass where one = 'Mal..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences389

[SRC]theClass.find("from FindMethodTestClass where one = :nam..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences394

[SRC]theClass.find("from FindMethodTestClass where one = :nam..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences399

[SRC]theClass.find("from FindMethodTestClass where one = :nam..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3104

[SRC]theClass.find("from FindMethodTestClass where one = :nam..che: false])

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3109

[SRC]theClass.find("from FindMethodTestClass where one = :nam..ache: true])

[MSG]The code could be more concise by using a with() or identity() block

➥ FindOrCreateWherePersistenceMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import grails.persistence.Entity

[MSG]The [grails.persistence.Entity] import is never referenced

➥ FindOrSaveWherePersistenceMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import grails.persistence.Entity

[MSG]The [grails.persistence.Entity] import is never referenced

➥ HibernateCriteriaBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod219

[SRC]List retrieveListOfNames() { ['bart'] }

[MSG]Violation in class HibernateCriteriaBuilderTests. The method retrieveListOfNames is public but not a test method

UnusedVariable21004

[SRC]List results = parse("{ " +

[MSG]The variable [results] in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests is not used

UnusedVariable21032

[SRC]List results = parse("{ " +

[MSG]The variable [results] in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests is not used

UnnecessaryGetter3437

[SRC]assertEquals clazzName , result.getClass().getName()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests. getName() can probably be rewritten as name

UnnecessaryGetter31689

[SRC]GroovyClassLoader cl = grailsApplication.getClassLoader()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests. getClassLoader() can probably be rewritten as classLoader

UnnecessaryGetter31706

[SRC]Class tc = grailsApplication.getArtefact(DomainClassArte..).getClazz()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.HibernateCriteriaBuilderTests. getClazz() can probably be rewritten as clazz

➥ HibernateEventListenerTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod251

[SRC]void onPostInsert(PostInsertEvent event) {}

[MSG]Violation in class TestAuditListener. The method onPostInsert is both empty and not marked with @Override

UnusedMethodParameter251

[SRC]void onPostInsert(PostInsertEvent event) {}

[MSG]Violation in class TestAuditListener. Method parameter [event] is never referenced in the method onPostInsert of class org.codehaus.groovy.grails.orm.hibernate.TestAuditListener

EmptyMethod252

[SRC]void onPostDelete(PostDeleteEvent event) {}

[MSG]Violation in class TestAuditListener. The method onPostDelete is both empty and not marked with @Override

UnusedMethodParameter252

[SRC]void onPostDelete(PostDeleteEvent event) {}

[MSG]Violation in class TestAuditListener. Method parameter [event] is never referenced in the method onPostDelete of class org.codehaus.groovy.grails.orm.hibernate.TestAuditListener

EmptyMethod253

[SRC]void onSaveOrUpdate(SaveOrUpdateEvent event) {}

[MSG]Violation in class TestAuditListener. The method onSaveOrUpdate is both empty and not marked with @Override

UnusedMethodParameter253

[SRC]void onSaveOrUpdate(SaveOrUpdateEvent event) {}

[MSG]Violation in class TestAuditListener. Method parameter [event] is never referenced in the method onSaveOrUpdate of class org.codehaus.groovy.grails.orm.hibernate.TestAuditListener

➥ ListDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable29

[SRC]def authorClass = ga.getDomainClass("Author")

[MSG]The variable [authorClass] in class org.codehaus.groovy.grails.orm.hibernate.ListDomainTests is not used

JUnitPublicNonTestMethod223

[SRC]void onSetUp() {

[MSG]Violation in class ListDomainTests. The method onSetUp is public but not a test method

➥ ListMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable245

[SRC]def ids = [a1.id, a2.id, a2.id]

[MSG]The variable [ids] in class org.codehaus.groovy.grails.orm.hibernate.ListMappingTests is not used

JUnitPublicNonTestMethod254

[SRC]void onSetUp() {

[MSG]Violation in class ListMappingTests. The method onSetUp is public but not a test method

➥ LoadMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2107

[SRC]def o = clazz.newInstance()

[MSG]The variable [o] in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests is not used

UnusedImport37

[SRC]import org.springframework.orm.hibernate3.HibernateObjec..ureException

[MSG]The [org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException] import is never referenced

UnnecessaryGetter329

[SRC]assertEquals "id is accessible even if object doesn't ex..ance.getId()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests. getId() can probably be rewritten as id

UnnecessaryGetter351

[SRC]assertEquals "id is accessible even if object doesn't ex..ance.getId()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests. getId() can probably be rewritten as id

UseAssertSameInsteadOfAssertTrue377

[SRC]assertTrue getInstance.is(loadInstance)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests. assert method can be simplified using the assertSame method

UseAssertSameInsteadOfAssertTrue396

[SRC]assertFalse getInstance.is(loadInstance)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.LoadMethodTests. assert method can be simplified using the assertSame method

➥ ManyToManyCompositeIdTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod272

[SRC]void onSetUp() {

[MSG]Violation in class ManyToManyCompositeIdTests. The method onSetUp is public but not a test method

UnusedImport33

[SRC]import junit.framework.TestCase

[MSG]The [junit.framework.TestCase] import is never referenced

➥ ManyToManyLazinessTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod228

[SRC]void onSetUp() {

[MSG]Violation in class ManyToManyLazinessTests. The method onSetUp is public but not a test method

➥ ManyToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2114

[SRC]void onSetUp() {

[MSG]Violation in class ManyToManyTests. The method onSetUp is public but not a test method

➥ ManyToManyWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable232

[SRC]def ShapeAttribute = ga.getDomainClass("ShapeAttribute").clazz

[MSG]The variable [ShapeAttribute] in class org.codehaus.groovy.grails.orm.hibernate.ManyToManyWithInheritanceTests is not used

➥ MapDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod228

[SRC]void onSetUp() {

[MSG]Violation in class MapDomainTests. The method onSetUp is public but not a test method

➥ MapMappingJoinTableTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod230

[SRC]void onSetUp() {

[MSG]Violation in class MapMappingJoinTableTests. The method onSetUp is public but not a test method

➥ MapMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertFalseInsteadOfNegation226

[SRC]assertTrue !book.hasErrors()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MapMappingTests. assertTrue(!book.hasErrors()) can be simplified to assertFalse(book.hasErrors())

JUnitPublicNonTestMethod290

[SRC]void onSetUp() {

[MSG]Violation in class MapMappingTests. The method onSetUp is public but not a test method

➥ MappedByColumn2Tests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod226

[SRC]void onSetUp() {

[MSG]Violation in class MappedByColumn2Tests. The method onSetUp is public but not a test method

➥ MappedByColumnTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod242

[SRC]void onSetUp() {

[MSG]Violation in class MappedByColumnTests. The method onSetUp is public but not a test method

➥ MappingDefaultsTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertFalseInsteadOfNegation273

[SRC]assertTrue "should have inherited blank from shared cons..", !cp.blank

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDefaultsTests. assertTrue(!cp.blank) can be simplified to assertFalse(cp.blank)

UseAssertFalseInsteadOfNegation275

[SRC]assertTrue "should not have inherited matches from [anot..", !cp.email

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDefaultsTests. assertTrue(!cp.email) can be simplified to assertFalse(cp.email)

ChainedTest279

[SRC]testMappingDefaults()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDefaultsTests. The test method testMappingDefaults() is being invoked explicitly from within a unit test. Tests should be isolated and not dependent on one another

UseAssertEqualsInsteadOfAssertTrue374

[SRC]assertTrue "size should have been in the specified range..0 == cp.size

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDefaultsTests. Replace assertTrue with a call to assertEquals()

➥ MappingDefinitionInheritedBySubclassTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertTrueInsteadOfAssertEquals348

[SRC]assert rs.next() == true

[MSG]The expression '(rs.next() == true)' can be simplified to 'rs.next()'

➥ MappingDslTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testTableMapping() {

[MSG]Violation in class MappingDslTests. Test method 'testTableMapping' makes no assertions

UnusedVariable2113

[SRC]DataSource ds = applicationContext.dataSource

[MSG]The variable [ds] in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests is not used

UnusedVariable2203

[SRC]def personClass = ga.getDomainClass("MappedPerson").clazz

[MSG]The variable [personClass] in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests is not used

JUnitTestMethodWithoutAssert2283

[SRC]void testCompositeIdAssignedGenerator_GRAILS_6289() {

[MSG]Violation in class MappingDslTests. Test method 'testCompositeIdAssignedGenerator_GRAILS_6289' makes no assertions

UnnecessaryGetter317

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter335

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter382

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3121

[SRC]final cmd = session.getSessionFactory().getClassMetadata..Class.clazz)

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getSessionFactory() can probably be rewritten as sessionFactory

UnnecessaryGetter3153

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3192

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3220

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3248

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3273

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

UnnecessaryGetter3303

[SRC]connection = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.MappingDslTests. getConnection() can probably be rewritten as connection

➥ MultipleDataSourceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2348

[SRC]def Library = ga.getDomainClass('MdsLibrary').clazz

[MSG]The variable [Library] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2349

[SRC]def Visit = ga.getDomainClass('MdsVisit').clazz

[MSG]The variable [Visit] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2379

[SRC]def Library = ga.getDomainClass('MdsLibrary').clazz

[MSG]The variable [Library] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2380

[SRC]def Visit = ga.getDomainClass('MdsVisit').clazz

[MSG]The variable [Visit] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2409

[SRC]def Library = ga.getDomainClass('MdsLibrary').clazz

[MSG]The variable [Library] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

UnusedVariable2410

[SRC]def Visit = ga.getDomainClass('MdsVisit').clazz

[MSG]The variable [Visit] in class org.codehaus.groovy.grails.orm.hibernate.MultipleDataSourceTests is not used

➥ NamedCriteriaInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import grails.persistence.Entity

[MSG]The [grails.persistence.Entity] import is never referenced

➥ NamedCriteriaPublication.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure379

[SRC]thisWeeksPaperbacks() {

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.NamedCriteriaPublication. Parentheses in the 'thisWeeksPaperbacks' method call are unnecessary and can be removed.

➥ NamedCriteriaTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2504

[SRC]def titles = publications.title

[MSG]The variable [titles] in class org.codehaus.groovy.grails.orm.hibernate.NamedCriteriaTests is not used

➥ NamingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring377

[SRC]names << ddl.substring(0, ddl.indexOf(' '))

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.NamingTests. The String.substring(int, int) method can be replaced with the subscript operator

➥ OneToManySelfInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable235

[SRC]def Root = ga.getDomainClass("onetomanyselfinheritancete..Root").clazz

[MSG]The variable [Root] in class org.codehaus.groovy.grails.orm.hibernate.OneToManySelfInheritanceTests is not used

➥ OneToManyWithComposideIdentifierTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert247

[SRC]void testPersistAssociationWithCompositeId() {

[MSG]Violation in class OneToManyWithComposideIdentifierTests. Test method 'testPersistAssociationWithCompositeId' makes no assertions

JUnitTestMethodWithoutAssert257

[SRC]void testUpdateInverseSide() {

[MSG]Violation in class OneToManyWithComposideIdentifierTests. Test method 'testUpdateInverseSide' makes no assertions

➥ OneToManyWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.springframework.util.Log4jConfigurer

[MSG]The [org.springframework.util.Log4jConfigurer] import is never referenced

➥ OneToManyWithSelfAndInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable239

[SRC]def orgB = Organization.newInstance(name:'Org B', descri..org1).save()

[MSG]The variable [orgB] in class org.codehaus.groovy.grails.orm.hibernate.OneToManyWithSelfAndInheritanceTests is not used

UnusedVariable240

[SRC]def orgaa = Organization.newInstance(name:'Org aa', desc..orgA).save()

[MSG]The variable [orgaa] in class org.codehaus.groovy.grails.orm.hibernate.OneToManyWithSelfAndInheritanceTests is not used

UnusedVariable244

[SRC]def xorgB = ExtOrganization.newInstance(name:'ExtOrg B',..org1).save()

[MSG]The variable [xorgB] in class org.codehaus.groovy.grails.orm.hibernate.OneToManyWithSelfAndInheritanceTests is not used

UnusedVariable245

[SRC]def xorgaa = ExtOrganization.newInstance(name:'ExtOrg aa..orgA).save()

[MSG]The variable [xorgaa] in class org.codehaus.groovy.grails.orm.hibernate.OneToManyWithSelfAndInheritanceTests is not used

➥ PersistenceMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2750

[SRC]MetaClass domain = obj.getMetaClass()

[MSG]The variable [domain] in class org.codehaus.groovy.grails.orm.hibernate.PersistenceMethodTests is not used

UnnecessaryGetter3438

[SRC]returnValue = domainClass.getAll()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.PersistenceMethodTests. getAll() can probably be rewritten as all

UnnecessaryGetter3750

[SRC]MetaClass domain = obj.getMetaClass()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.PersistenceMethodTests. getMetaClass() can probably be rewritten as metaClass

➥ PessimisticLockingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert211

[SRC]void testLockMethod() {

[MSG]Violation in class PessimisticLockingTests. Test method 'testLockMethod' makes no assertions

JUnitPublicNonTestMethod243

[SRC]void onSetUp() {

[MSG]Violation in class PessimisticLockingTests. The method onSetUp is public but not a test method

➥ SavePersistentMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3159

[SRC]datastore.getEventTriggeringInterceptor().failOnError = true

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.SavePersistentMethodTests. getEventTriggeringInterceptor() can probably be rewritten as eventTriggeringInterceptor

UnnecessaryGetter3177

[SRC]def interceptor = datastore.getEventTriggeringInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.SavePersistentMethodTests. getEventTriggeringInterceptor() can probably be rewritten as eventTriggeringInterceptor

➥ SimpleBelongsToMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable210

[SRC]def bookClass = ga.getDomainClass("Book")

[MSG]The variable [bookClass] in class org.codehaus.groovy.grails.orm.hibernate.SimpleBelongsToMappingTests is not used

JUnitPublicNonTestMethod215

[SRC]void onSetUp() {

[MSG]Violation in class SimpleBelongsToMappingTests. The method onSetUp is public but not a test method

➥ TablePerHierarchyAssocationTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable236

[SRC]def sub1Class = ga.getDomainClass("TablePerHierarchSub1").clazz

[MSG]The variable [sub1Class] in class org.codehaus.groovy.grails.orm.hibernate.TablePerHierarchyAssocationTests is not used

➥ TablePerSubclassIdentityMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert237

[SRC]void testMappedIdentityForSubclass() {

[MSG]Violation in class TablePerSubclassIdentityMappingTests. Test method 'testMappedIdentityForSubclass' makes no assertions

UnnecessaryGetter342

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.TablePerSubclassIdentityMappingTests. getConnection() can probably be rewritten as connection

➥ TablePerSubclassWithCustomTableNameTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert237

[SRC]void testGeneratedTables() {

[MSG]Violation in class TablePerSubclassWithCustomTableNameTests. Test method 'testGeneratedTables' makes no assertions

UnnecessaryGetter342

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.TablePerSubclassWithCustomTableNameTests. getConnection() can probably be rewritten as connection

➥ TwoManyToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2100

[SRC]void onSetUp() {

[MSG]Violation in class TwoManyToManyTests. The method onSetUp is public but not a test method

➥ TwoUnidirectionalOneToManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert27

[SRC]void testTwoUniOneToManys() {

[MSG]Violation in class TwoUnidirectionalOneToManyTests. Test method 'testTwoUniOneToManys' makes no assertions

JUnitPublicNonTestMethod223

[SRC]void onSetUp() {

[MSG]Violation in class TwoUnidirectionalOneToManyTests. The method onSetUp is public but not a test method

➥ URLMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod222

[SRC]void onSetUp() {

[MSG]Violation in class URLMappingTests. The method onSetUp is public but not a test method

UnnecessaryObjectReferences316

[SRC]b.discard()

[MSG]The code could be more concise by using a with() or identity() block

➥ UnidirectionalOneToManyHibernateMappedTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testAnnotatedOneToManyDomain() {

[MSG]Violation in class UnidirectionalOneToManyHibernateMappedTests. Test method 'testAnnotatedOneToManyDomain' makes no assertions

➥ UnidirectionalOneToManyWithJoinTableTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert226

[SRC]void testUnidirectionalOneToManyWithExplicityJoinTable() {

[MSG]Violation in class UnidirectionalOneToManyWithJoinTableTests. Test method 'testUnidirectionalOneToManyWithExplicityJoinTable' makes no assertions

➥ UserTypeMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3148

[SRC]con = ds.getConnection()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.UserTypeMappingTests. getConnection() can probably be rewritten as connection

➥ ValidationFailureTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod25

[SRC]void onSetUp() {

[MSG]Violation in class ValidationFailureTests. The method onSetUp is public but not a test method

➥ VersionColumnTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert240

[SRC]void testVersionColumnMapping() {

[MSG]Violation in class VersionColumnTests. Test method 'testVersionColumnMapping' makes no assertions

UnusedImport33

[SRC]import java.sql.Connection

[MSG]The [java.sql.Connection] import is never referenced

➥ WithCriteriaMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod224

[SRC]void onSetUp() {

[MSG]Violation in class WithCriteriaMethodTests. The method onSetUp is public but not a test method

➥ WithTransactionMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod233

[SRC]void onSetUp() {

[MSG]Violation in class WithTransactionMethodTests. The method onSetUp is public but not a test method

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.binding

➥ AssociationDataBindingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2197

[SRC]def book = Book.newInstance(title: "Pattern Recognition"..Error: true)

[MSG]The variable [book] in class org.codehaus.groovy.grails.orm.hibernate.binding.AssociationDataBindingTests is not used

UnnecessaryObjectReferences3332

[SRC]request.addParameter("books[0].reviewers['bob'].name", "Bob Bloggs")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3333

[SRC]request.addParameter("books[0].reviewers['chuck'].name",..uck Bloggs")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3334

[SRC]request.addParameter("books[1].title", "The Stand")

[MSG]The code could be more concise by using a with() or identity() block

➥ NonDomainCollectionBindingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod211

[SRC]void onSetUp() {

[MSG]Violation in class NonDomainCollectionBindingTests. The method onSetUp is public but not a test method

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.cfg

➥ GrailsDomainBinderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3672

[SRC]ConstrainedProperty constrainedProperty = getConstrained..ngProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3677

[SRC]constrainedProperty = getConstrainedStringProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3682

[SRC]constrainedProperty = getConstrainedStringProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3686

[SRC]constrainedProperty = getConstrainedStringProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3692

[SRC]constrainedProperty = getConstrainedStringProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedStringProperty() can probably be rewritten as constrainedStringProperty

UnnecessaryGetter3702

[SRC]ConstrainedProperty constrainedProperty = getConstrained..alProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryGetter3709

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3710

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...l("123.45"))

[MSG]Can be rewritten as 123.45 or 123.45G

UnnecessaryGetter3715

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3717

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...("-123.45"))

[MSG]Can be rewritten as -123.45 or -123.45G

UnnecessaryGetter3721

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3722

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...("123.45")))

[MSG]Can be rewritten as 123.45 or 123.45G

UnnecessaryGetter3726

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3727

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...mal("123")))

[MSG]Can be rewritten as -123.45 or -123.45G

UnnecessaryGetter3731

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryGetter3737

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3738

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...l("123.45"))

[MSG]Can be rewritten as 123.45 or 123.45G

UnnecessaryGetter3744

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3745

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty..."123.4567"))

[MSG]Can be rewritten as 123.4567 or 123.4567G

UnnecessaryGetter3751

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3752

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty..."123.4567"))

[MSG]Can be rewritten as 123.4567 or 123.4567G

UnnecessaryGetter3754

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3755

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...7890.4567"))

[MSG]Can be rewritten as 12345678901234567890.4567 or 12345678901234567890.4567G

UnnecessaryGetter3757

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3758

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...-123.4567"))

[MSG]Can be rewritten as -123.4567 or -123.4567G

UnnecessaryGetter3760

[SRC]constrainedProperty = getConstrainedBigDecimalProperty()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinderTests. getConstrainedBigDecimalProperty() can probably be rewritten as constrainedBigDecimalProperty

UnnecessaryBigDecimalInstantiation3761

[SRC]constrainedProperty.applyConstraint(ConstrainedProperty...7890.4567"))

[MSG]Can be rewritten as -12345678901234567890.4567 or -12345678901234567890.4567G

➥ GrailsHibernateUtilTests.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports34

[SRC]import static org.codehaus.groovy.grails.orm.hibernate.c..ernateUtil.*

[MSG]Static imports should appear before normal imports

JUnitUnnecessarySetUp38

[SRC]@Override protected void setUp() {

[MSG]Violation in class GrailsHibernateUtilTests. The setUp() method contains no logic and can be removed

UnnecessaryOverridingMethod38

[SRC]@Override protected void setUp() {

[MSG]Violation in class GrailsHibernateUtilTests. The method setUp contains no logic and can be safely deleted

JUnitUnnecessaryTearDown312

[SRC]@Override protected void tearDown() {

[MSG]Violation in class GrailsHibernateUtilTests. The tearDown() method contains no logic and can be removed

UnnecessaryOverridingMethod312

[SRC]@Override protected void tearDown() {

[MSG]Violation in class GrailsHibernateUtilTests. The method tearDown contains no logic and can be safely deleted

➥ MonetaryAmountUserType.groovy

Rule NamePriorityLine #Source Line / Message
EqualsOverloaded216

[SRC]boolean equals(Object x, Object y) { x == y }

[MSG]Violation in class MonetaryAmountUserType. The class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType overloads the equals method, it does not override it.

UnusedMethodParameter221

[SRC]Object nullSafeGet(ResultSet resultSet, String[] names, ..LException {

[MSG]Violation in class MonetaryAmountUserType. Method parameter [owner] is never referenced in the method nullSafeGet of class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType

UnusedMethodParameter244

[SRC]Object assemble(Serializable cached, Object owner) { cached }

[MSG]Violation in class MonetaryAmountUserType. Method parameter [owner] is never referenced in the method assemble of class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType

UnusedMethodParameter246

[SRC]Object replace(Object original, Object target, Object ow..{ original }

[MSG]Violation in class MonetaryAmountUserType. Method parameter [target] is never referenced in the method replace of class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType

UnusedMethodParameter246

[SRC]Object replace(Object original, Object target, Object ow..{ original }

[MSG]Violation in class MonetaryAmountUserType. Method parameter [owner] is never referenced in the method replace of class org.codehaus.groovy.grails.orm.hibernate.cfg.MonetaryAmountUserType

➥ MyUserType.groovy

Rule NamePriorityLine #Source Line / Message
EqualsOverloaded222

[SRC]boolean equals(Object x, Object y) { x.name == y.name }

[MSG]Violation in class MyUserType. The class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType overloads the equals method, it does not override it.

UnusedMethodParameter227

[SRC]Object nullSafeGet(ResultSet resultSet, String[] names, ..LException {

[MSG]Violation in class MyUserType. Method parameter [owner] is never referenced in the method nullSafeGet of class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType

UnusedMethodParameter243

[SRC]Object assemble(Serializable cached, Object owner) { cached }

[MSG]Violation in class MyUserType. Method parameter [owner] is never referenced in the method assemble of class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType

UnusedMethodParameter245

[SRC]Object replace(Object original, Object target, Object ow..{ original }

[MSG]Violation in class MyUserType. Method parameter [target] is never referenced in the method replace of class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType

UnusedMethodParameter245

[SRC]Object replace(Object original, Object target, Object ow..{ original }

[MSG]Violation in class MyUserType. Method parameter [owner] is never referenced in the method replace of class org.codehaus.groovy.grails.orm.hibernate.cfg.MyUserType

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.metaclass

➥ BeforeValidateHelperTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter265

[SRC]def beforeValidate(List properties) {

[MSG]Violation in class ClassWithListArgBeforeValidate. Method parameter [properties] is never referenced in the method beforeValidate of class org.codehaus.groovy.grails.orm.hibernate.metaclass.ClassWithListArgBeforeValidate

UnusedMethodParameter276

[SRC]def beforeValidate(List properties) {

[MSG]Violation in class ClassWithOverloadedBeforeValidate. Method parameter [properties] is never referenced in the method beforeValidate of class org.codehaus.groovy.grails.orm.hibernate.metaclass.ClassWithOverloadedBeforeValidate

UnusedImport33

[SRC]import groovy.mock.interceptor.MockFor

[MSG]The [groovy.mock.interceptor.MockFor] import is never referenced

ImportFromSamePackage34

[SRC]import org.codehaus.groovy.grails.orm.hibernate.metaclas..idateHelper;

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.support

➥ FlushOnRedirectTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport36

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest] import is never referenced

➥ HibernatePersistenceContextInterceptorTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport36

[SRC]import org.springframework.orm.hibernate3.SessionHolder

[MSG]The [org.springframework.orm.hibernate3.SessionHolder] import is never referenced

UnnecessaryGetter328

[SRC]def interceptor = getInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptorTests. getInterceptor() can probably be rewritten as interceptor

UseAssertTrueInsteadOfAssertEquals329

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals331

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals333

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals335

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals337

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryGetter341

[SRC]def interceptor = getInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptorTests. getInterceptor() can probably be rewritten as interceptor

UseAssertTrueInsteadOfAssertEquals342

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals345

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals347

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals349

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals351

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals354

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryObjectReferences355

[SRC]interceptor.destroy()

[MSG]The code could be more concise by using a with() or identity() block

UseAssertTrueInsteadOfAssertEquals356

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryGetter360

[SRC]def interceptor = getInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptorTests. getInterceptor() can probably be rewritten as interceptor

UseAssertTrueInsteadOfAssertEquals370

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals372

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals374

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryGetter381

[SRC]def interceptor = getInterceptor()

[MSG]Violation in class org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptorTests. getInterceptor() can probably be rewritten as interceptor

UseAssertTrueInsteadOfAssertEquals393

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals395

[SRC]assertEquals("interceptor open", true, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals397

[SRC]assertEquals("interceptor open", false, interceptor.open)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.hibernate.validation

➥ UniqueConstraintTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable215

[SRC]def userClass = ga.getDomainClass("User")

[MSG]The variable [userClass] in class org.codehaus.groovy.grails.orm.hibernate.validation.UniqueConstraintTests is not used

JUnitPublicNonTestMethod2265

[SRC]void onSetUp() {

[MSG]Violation in class UniqueConstraintTests. The method onSetUp is public but not a test method

UnnecessaryObjectReferences350

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences352

[SRC]user.save(true)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences363

[SRC]user.organization = "organization1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences364

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences368

[SRC]user.id = 123L

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences369

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences379

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences383

[SRC]user.code = "321"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences384

[SRC]user.login = "login1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences385

[SRC]user.grp = "group1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences386

[SRC]user.department = "department1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences387

[SRC]user.organization = "organization2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences388

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences392

[SRC]user.grp = "group2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences393

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences397

[SRC]user.grp = "group1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences398

[SRC]user.department = "department2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences399

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3103

[SRC]user.login = "login2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3104

[SRC]user.grp = "group2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3105

[SRC]user.department = "department1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3106

[SRC]user.organization = "organization1"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3107

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3111

[SRC]user.organization = "organization2"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3112

[SRC]user.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3228

[SRC]user1.save(true)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3236

[SRC]user2.save(true)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3244

[SRC]user3.save(true)

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.orm.support

➥ TransactionManagerPostProcessorTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySelfAssignment328

[SRC]dataSource = dataSource

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.plugins

➥ RelationshipManagementMethodsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable259

[SRC]def addressClass = ga.getDomainClass("Address")

[MSG]The variable [addressClass] in class org.codehaus.groovy.grails.plugins.RelationshipManagementMethodsTests is not used

JUnitPublicNonTestMethod2142

[SRC]void onSetUp() {

[MSG]Violation in class RelationshipManagementMethodsTests. The method onSetUp is public but not a test method

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.plugins.scaffolding

➥ ScaffoldingGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter375

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.scaffolding.ScaffoldingGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter387

[SRC]gcl.getLoadedClasses().find { it.name.endsWith("TagLib") })

[MSG]Violation in class org.codehaus.groovy.grails.plugins.scaffolding.ScaffoldingGrailsPluginTests. getLoadedClasses() can probably be rewritten as loadedClasses

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.plugins.services

➥ ScopedProxyAndServiceClassTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport35

[SRC]import org.springframework.web.context.support.WebApplic..ContextUtils

[MSG]The [org.springframework.web.context.support.WebApplicationContextUtils] import is never referenced

➥ ServicesGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod212

[SRC]void onSetUp() {

[MSG]Violation in class ServicesGrailsPluginTests. The method onSetUp is public but not a test method

UnnecessaryGetter3110

[SRC]springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.services.ServicesGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.reload

➥ ServiceReloadTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod246

[SRC]void onSetUp() {

[MSG]Violation in class ServiceReloadTests. The method onSetUp is public but not a test method

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.scaffolding

➥ DefaultGrailsTemplateGeneratorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper226

[SRC]protected void setUp() {

[MSG]Violation in class DefaultGrailsTemplateGeneratorTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper233

[SRC]protected void tearDown() {

[MSG]Violation in class DefaultGrailsTemplateGeneratorTests. The method tearDown() does not call super.tearDown()

UnusedImport314

[SRC]import org.codehaus.groovy.grails.plugins.PluginManagerHolder

[MSG]The [org.codehaus.groovy.grails.plugins.PluginManagerHolder] import is never referenced

UseAssertTrueInsteadOfAssertEquals368

[SRC]assert sw.toString().contains('g:datePicker name="regula..}"') == true

[MSG]The expression '(sw.toString().contains(g:datePicker name="regularDate" precision="day" value="${scaffoldingTestInstance?.regularDate}") == true)' can be simplified to 'sw.toString().contains(g:datePicker name="regularDate" precision="day" value="${scaffoldingTestInstance?.regularDate}")'

UseAssertTrueInsteadOfAssertEquals369

[SRC]assert sw.toString().contains('datePicker name="sqlDate"..e}') == true

[MSG]The expression '(sw.toString().contains(datePicker name="sqlDate" precision="day" value="${scaffoldingTestInstance?.sqlDate}) == true)' can be simplified to 'sw.toString().contains(datePicker name="sqlDate" precision="day" value="${scaffoldingTestInstance?.sqlDate})'

➥ TemplateGeneratingResponseHandlerTests.groovy

Rule NamePriorityLine #Source Line / Message
DuplicateImport37

[SRC]import org.springframework.web.context.request.*

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.scaffolding.view

➥ ScaffoldedGroovyPageViewTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper233

[SRC]void tearDown() {

[MSG]Violation in class ScaffoldedGroovyPageViewTests. The method tearDown() does not call super.tearDown()

➥ ScaffoldingViewResolverTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter260

[SRC]protected String generateViewSource(String viewName, Gra..mainClass) {

[MSG]Violation in class TestScaffoldingViewResolver. Method parameter [domainClass] is never referenced in the method generateViewSource of class org.codehaus.groovy.grails.scaffolding.view.TestScaffoldingViewResolver

UnnecessaryGetter338

[SRC]viewResolver.servletContext = webRequest.getServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.view.ScaffoldingViewResolverTests. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter348

[SRC]def view = viewResolver.loadView("/foo/list", Locale.getDefault())

[MSG]Violation in class org.codehaus.groovy.grails.scaffolding.view.ScaffoldingViewResolverTests. getDefault() can probably be rewritten as default

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.validation

➥ VetoingNullableBehaviourTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertEqualsInsteadOfAssertTrue3100

[SRC]assertTrue("Error not found for field ${field}, errors w..ld) == null)

[MSG]Violation in class org.codehaus.groovy.grails.validation.VetoingNullableBehaviourTests. Replace assertTrue with a call to assertEquals()

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.web.binding

➥ DataBindingWithAssociationTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable293

[SRC]def Book = ga.getDomainClass("databindingwithassociation..ook3").clazz

[MSG]The variable [Book] in class org.codehaus.groovy.grails.web.binding.DataBindingWithAssociationTests is not used

UnusedVariable2120

[SRC]def Book = ga.getDomainClass("databindingwithassociation..ook3").clazz

[MSG]The variable [Book] in class org.codehaus.groovy.grails.web.binding.DataBindingWithAssociationTests is not used

➥ DataBindingWithEmbeddedTests.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports36

[SRC]import static org.hamcrest.CoreMatchers.*

[MSG]Static imports should appear before normal imports

MisorderedStaticImports37

[SRC]import static org.junit.Assert.assertThat

[MSG]Static imports should appear before normal imports

Package: grails-test-suite-persistence.src.test.groovy.org.codehaus.groovy.grails.web.converters

➥ ConvertsWithHibernateProxiesTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable255

[SRC]def converter = parent as JSON

[MSG]The variable [converter] in class org.codehaus.groovy.grails.web.converters.ConvertsWithHibernateProxiesTests is not used

UnusedVariable274

[SRC]def converter = parent as XML

[MSG]The variable [converter] in class org.codehaus.groovy.grails.web.converters.ConvertsWithHibernateProxiesTests is not used

Package: grails-test-suite-uber.src.test.groovy.grails.ant

➥ GrailsTaskTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod210

[SRC]void testWithClasspath() {

[MSG]Violation in class GrailsTaskTests. The method testWithClasspath is both empty and not marked with @Override

JUnitTestMethodWithoutAssert210

[SRC]void testWithClasspath() {

[MSG]Violation in class GrailsTaskTests. Test method 'testWithClasspath' makes no assertions

Package: grails-test-suite-uber.src.test.groovy.grails.spring

➥ BeanBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2706

[SRC]def dataSource = ctx.getBean("dataSource")

[MSG]The variable [dataSource] in class grails.spring.BeanBuilderTests is not used

JUnitTestMethodWithoutAssert2709

[SRC]void testHolyGrailWiring() {

[MSG]Violation in class BeanBuilderTests. Test method 'testHolyGrailWiring' makes no assertions

JUnitTestMethodWithoutAssert2760

[SRC]void testBeanBuilderWithScript() {

[MSG]Violation in class BeanBuilderTests. Test method 'testBeanBuilderWithScript' makes no assertions

EmptyMethod2867

[SRC]Object remove(String name) {

[MSG]Violation in class TestScope. The method remove is both empty and not marked with @Override

UnusedMethodParameter2867

[SRC]Object remove(String name) {

[MSG]Violation in class TestScope. Method parameter [name] is never referenced in the method remove of class grails.spring.TestScope

EmptyMethod2871

[SRC]void registerDestructionCallback(String name, Runnable callback) {}

[MSG]Violation in class TestScope. The method registerDestructionCallback is both empty and not marked with @Override

UnusedMethodParameter2871

[SRC]void registerDestructionCallback(String name, Runnable callback) {}

[MSG]Violation in class TestScope. Method parameter [name] is never referenced in the method registerDestructionCallback of class grails.spring.TestScope

UnusedMethodParameter2871

[SRC]void registerDestructionCallback(String name, Runnable callback) {}

[MSG]Violation in class TestScope. Method parameter [callback] is never referenced in the method registerDestructionCallback of class grails.spring.TestScope

UnusedMethodParameter2875

[SRC]Object get(String name, ObjectFactory<?> objectFactory) {

[MSG]Violation in class TestScope. Method parameter [name] is never referenced in the method get of class grails.spring.TestScope

UnusedMethodParameter2880

[SRC]Object resolveContextualObject(String s) { null }

[MSG]Violation in class TestScope. Method parameter [s] is never referenced in the method resolveContextualObject of class grails.spring.TestScope

UnusedImport318

[SRC]import org.codehaus.groovy.grails.plugins.GrailsPluginManager;

[MSG]The [org.codehaus.groovy.grails.plugins.GrailsPluginManager] import is never referenced

UnnecessaryGetter3149

[SRC]GenericApplicationContext appCtx = bb.getSpringConfig()...ionContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter3149

[SRC]GenericApplicationContext appCtx = bb.getSpringConfig()...ionContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3150

[SRC]appCtx.getBeanFactory().registerScope("test", scope)

[MSG]Violation in class grails.spring.BeanBuilderTests. getBeanFactory() can probably be rewritten as beanFactory

UnnecessaryGetter3176

[SRC]appCtx = bb.getSpringConfig().getUnrefreshedApplicationContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter3176

[SRC]appCtx = bb.getSpringConfig().getUnrefreshedApplicationContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3177

[SRC]appCtx.getBeanFactory().registerScope("test", scope)

[MSG]Violation in class grails.spring.BeanBuilderTests. getBeanFactory() can probably be rewritten as beanFactory

UnnecessaryGetter3237

[SRC]GenericApplicationContext appCtx = bb.getSpringConfig()...ionContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getUnrefreshedApplicationContext() can probably be rewritten as unrefreshedApplicationContext

UnnecessaryGetter3237

[SRC]GenericApplicationContext appCtx = bb.getSpringConfig()...ionContext()

[MSG]Violation in class grails.spring.BeanBuilderTests. getSpringConfig() can probably be rewritten as springConfig

UnnecessaryGetter3239

[SRC]appCtx.getBeanFactory().registerScope("test", scope)

[MSG]Violation in class grails.spring.BeanBuilderTests. getBeanFactory() can probably be rewritten as beanFactory

UnnecessarySelfAssignment3305

[SRC]quest = quest

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryPackageReference3312

[SRC]shouldFail(org.springframework.beans.factory.BeanIsAbstr..Exception) {

[MSG]The org.springframework.beans.factory.BeanIsAbstractException class was explicitly imported, so specifying the package name is not necessary

UnnecessarySelfAssignment3327

[SRC]quest = quest

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UseAssertTrueInsteadOfAssertEquals3376

[SRC]assertEquals true, bean1.props?.overweight

[MSG]assertEquals can be simplified using assertTrue or assertFalse

ConstantAssertExpression3590

[SRC]assert "marge", marge.person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [marge]

ConstantAssertExpression3608

[SRC]assert "marge", marge.person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [marge]

ConstantAssertExpression3632

[SRC]assert "homer", homer.person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [homer]

ConstantAssertExpression3633

[SRC]assert 45, homer.age

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [45]

ConstantAssertExpression3635

[SRC]assert "marge", ctx.getBean("marge").person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [marge]

ConstantAssertExpression3637

[SRC]assert "mcBain", ctx.getBean("mcBain").person

[MSG]The assert statement within class grails.spring.BeanBuilderTests has a constant boolean expression [mcBain]

UnnecessaryGetter3877

[SRC]objectFactory.getObject()

[MSG]Violation in class grails.spring.TestScope. getObject() can probably be rewritten as object

Package: grails-test-suite-uber.src.test.groovy.grails.test

➥ ControllerUnitTestCaseTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert210

[SRC]void testControllerClass() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testControllerClass' makes no assertions

JUnitTestMethodWithoutAssert217

[SRC]void testExplicitControllerClass() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testExplicitControllerClass' makes no assertions

JUnitTestMethodWithoutAssert225

[SRC]void testMockCommandObject() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testMockCommandObject' makes no assertions

JUnitTestMethodWithoutAssert232

[SRC]void testGetSetModelAndView() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testGetSetModelAndView' makes no assertions

JUnitTestMethodWithoutAssert239

[SRC]void testResetWithResponseNotCommitted() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testResetWithResponseNotCommitted' makes no assertions

JUnitTestMethodWithoutAssert246

[SRC]void testResetWithResponseCommitted() {

[MSG]Violation in class ControllerUnitTestCaseTests. Test method 'testResetWithResponseCommitted' makes no assertions

JUnitTestMethodWithoutAssert256

[SRC]void testModelAndView() {

[MSG]Violation in class UnitTestControllerTestCase. Test method 'testModelAndView' makes no assertions

JUnitTestMethodWithoutAssert289

[SRC]void testResetWithResponseNotCommitted() {

[MSG]Violation in class UnitTestControllerTestCase. Test method 'testResetWithResponseNotCommitted' makes no assertions

➥ GrailsMockTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2386

[SRC]String multiMethod(String str) { "static" }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [str] is never referenced in the method multiMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2388

[SRC]String multiMethod(String str, Map map) { "static" }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [str] is never referenced in the method multiMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2388

[SRC]String multiMethod(String str, Map map) { "static" }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [map] is never referenced in the method multiMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2390

[SRC]String someMethod(String str1, Object[] args, String str..{ 'static' }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [str1] is never referenced in the method someMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2390

[SRC]String someMethod(String str1, Object[] args, String str..{ 'static' }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [args] is never referenced in the method someMethod of class grails.test.GrailsMockCollaborator

UnusedMethodParameter2390

[SRC]String someMethod(String str1, Object[] args, String str..{ 'static' }

[MSG]Violation in class GrailsMockCollaborator. Method parameter [str2] is never referenced in the method someMethod of class grails.test.GrailsMockCollaborator

UnnecessaryParenthesesForMethodCallWithClosure397

[SRC]mockControl.demand.update() { -> "Success!"}

[MSG]Violation in class grails.test.GrailsMockTests. Parentheses in the 'update' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3151

[SRC]mockControl.demand.static.findByNothing() { -> "Success!"}

[MSG]Violation in class grails.test.GrailsMockTests. Parentheses in the 'findByNothing' method call are unnecessary and can be removed.

UnnecessaryGetter3407

[SRC]setMetaClass(GroovySystem.getMetaClassRegistry().getMeta..erty.class);

[MSG]Violation in class grails.test.GrailsMockWithMetaClassGetProperty. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

UnnecessaryDotClass3407

[SRC]setMetaClass(GroovySystem.getMetaClassRegistry().getMeta..erty.class);

[MSG]GrailsMockWithMetaClassGetProperty.class can be rewritten as GrailsMockWithMetaClassGetProperty

UnnecessaryDotClass3407

[SRC]setMetaClass(GroovySystem.getMetaClassRegistry().getMeta..erty.class);

[MSG]GrailsMockWithMetaClassGetProperty.class can be rewritten as GrailsMockWithMetaClassGetProperty

UnnecessaryGetter3417

[SRC]GroovySystem.getMetaClassRegistry().setMetaClass(nodeCla..wMetaClass);

[MSG]Violation in class grails.test.GrailsMockWithMetaClassGetProperty. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

➥ GrailsUnitTestCaseTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper232

[SRC]protected void setUp() {

[MSG]Violation in class GrailsUnitTestCaseTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper237

[SRC]protected void tearDown() {

[MSG]Violation in class GrailsUnitTestCaseTests. The method tearDown() does not call super.tearDown()

JUnitTestMethodWithoutAssert242

[SRC]void testMockConfig() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockConfig' makes no assertions

JUnitTestMethodWithoutAssert265

[SRC]void testMockConfigReturnsConfig() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockConfigReturnsConfig' makes no assertions

JUnitTestMethodWithoutAssert272

[SRC]void testMockLogging() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockLogging' makes no assertions

JUnitTestMethodWithoutAssert282

[SRC]void testMockLoggingWithDebugEnabled() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockLoggingWithDebugEnabled' makes no assertions

JUnitTestMethodWithoutAssert292

[SRC]void testMockDomainErrors() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockDomainErrors' makes no assertions

JUnitTestMethodWithoutAssert2106

[SRC]void testMockForConstraintsTests() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockForConstraintsTests' makes no assertions

JUnitTestMethodWithoutAssert2118

[SRC]void testMockFor() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockFor' makes no assertions

JUnitTestMethodWithoutAssert2141

[SRC]void testCascadingValidation() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testCascadingValidation' makes no assertions

JUnitTestMethodWithoutAssert2148

[SRC]void testMockDynamicMethodsWithInstanceList() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testMockDynamicMethodsWithInstanceList' makes no assertions

JUnitTestMethodWithoutAssert2162

[SRC]void testLoadCodec() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testLoadCodec' makes no assertions

JUnitTestMethodWithoutAssert2169

[SRC]void testConverters() {

[MSG]Violation in class GrailsUnitTestCaseTests. Test method 'testConverters' makes no assertions

UnusedMethodParameter2412

[SRC]def foo(s) { 1 }

[MSG]Violation in class ClassToMock. Method parameter [s] is never referenced in the method foo of class grails.test.ClassToMock

UnnecessaryObjectReferences3126

[SRC]testCase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3128

[SRC]testCase.setUp()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3129

[SRC]testCase.testMockInterface1()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3130

[SRC]testCase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3132

[SRC]testCase.setUp()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3133

[SRC]testCase.testMockInterface2()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3134

[SRC]testCase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3177

[SRC]testCase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryParenthesesForMethodCallWithClosure3223

[SRC]mocker.demand.foo() {s -> 1 }

[MSG]Violation in class grails.test.TestUnitTestCase. Parentheses in the 'foo' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3231

[SRC]mocker.demand.foo() {s -> 1 }

[MSG]Violation in class grails.test.TestUnitTestCase. Parentheses in the 'foo' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3239

[SRC]mocker.demand.foo() {s -> 1 }

[MSG]Violation in class grails.test.TestUnitTestCase. Parentheses in the 'foo' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3247

[SRC]mocker.demand.foo() {s -> 1 }

[MSG]Violation in class grails.test.TestUnitTestCase. Parentheses in the 'foo' method call are unnecessary and can be removed.

UnnecessaryObjectReferences3365

[SRC]log.warn "Test warning with exception", new Exception("s..ent wrong!")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3366

[SRC]log.info "Test info message"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3367

[SRC]log.info "Test info message with exception", new Excepti..ent wrong!")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3368

[SRC]log.debug "Test debug"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3369

[SRC]log.debug "Test debug with exception", new Exception("so..ent wrong!")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3370

[SRC]log.trace "Test trace"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3371

[SRC]log.trace "Test trace with exception", new Exception("so..ent wrong!")

[MSG]The code could be more concise by using a with() or identity() block

➥ MockDomainWithInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper214

[SRC]protected void tearDown() {

[MSG]Violation in class MockDomainWithInheritanceTests. The method tearDown() does not call super.tearDown()

JUnitTestMethodWithoutAssert218

[SRC]void testMockDomainWithInheritance() {

[MSG]Violation in class MockDomainWithInheritanceTests. Test method 'testMockDomainWithInheritance' makes no assertions

JUnitTearDownCallsSuper234

[SRC]protected void tearDown() {

[MSG]Violation in class PersonTests. The method tearDown() does not call super.tearDown()

➥ MockForTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert211

[SRC]void testUnregisteredMockedStaticMethods() {

[MSG]Violation in class MockForTests. Test method 'testUnregisteredMockedStaticMethods' makes no assertions

UnnecessaryObjectReferences319

[SRC]testcase.tearDown()

[MSG]The code could be more concise by using a with() or identity() block

➥ MockUtilsAndHasManyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper217

[SRC]protected void setUp() {

[MSG]Violation in class MockUtilsAndHasManyTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper222

[SRC]protected void tearDown() {

[MSG]Violation in class MockUtilsAndHasManyTests. The method tearDown() does not call super.tearDown()

JUnitTestMethodWithoutAssert226

[SRC]void testMockDomainWithHasMany() {

[MSG]Violation in class MockUtilsAndHasManyTests. Test method 'testMockDomainWithHasMany' makes no assertions

JUnitTearDownCallsSuper236

[SRC]protected void tearDown() {

[MSG]Violation in class MagazineTests. The method tearDown() does not call super.tearDown()

➥ MockUtilsDeleteDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper230

[SRC]void setUp() {

[MSG]Violation in class MockUtilsDeleteDomainTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper235

[SRC]void tearDown() {

[MSG]Violation in class MockUtilsDeleteDomainTests. The method tearDown() does not call super.tearDown()

➥ MockUtilsSaveDomainTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper234

[SRC]protected void setUp() {

[MSG]Violation in class MockUtilsSaveDomainTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper241

[SRC]protected void tearDown() {

[MSG]Violation in class MockUtilsSaveDomainTests. The method tearDown() does not call super.tearDown()

UnusedVariable278

[SRC]def domain1 = new TestDomainWithUUID(name: "Alice Doe", ..: 35).save()

[MSG]The variable [domain1] in class grails.test.MockUtilsSaveDomainTests is not used

➥ MockUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertFalseInsteadOfNegation21135

[SRC]assertTrue !model

[MSG]Violation in class grails.test.MockUtilsTests. assertTrue(!model) can be simplified to assertFalse(model)

EqualsAndHashCode21589

[SRC]class TestDomain {

[MSG]The class grails.test.TestDomain defines equals(Object) but not hashCode()

EqualsAndHashCode21685

[SRC]class TestDomainWithUUID {

[MSG]The class grails.test.TestDomainWithUUID defines equals(Object) but not hashCode()

UnusedMethodParameter21882

[SRC]def beforeValidate(List properties) {

[MSG]Violation in class ClassWithListArgBeforeValidate. Method parameter [properties] is never referenced in the method beforeValidate of class grails.test.ClassWithListArgBeforeValidate

UnusedMethodParameter21896

[SRC]def beforeValidate(List properties) {

[MSG]Violation in class ClassWithOverloadedBeforeValidate. Method parameter [properties] is never referenced in the method beforeValidate of class grails.test.ClassWithOverloadedBeforeValidate

UnnecessaryObjectReferences31202

[SRC]cmd.validate()

[MSG]The code could be more concise by using a with() or identity() block

➥ TagLibUnitTestCaseTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert28

[SRC]void testTagThatPopulatesPageScope() {

[MSG]Violation in class TagLibUnitTestCaseTests. Test method 'testTagThatPopulatesPageScope' makes no assertions

JUnitTestMethodWithoutAssert216

[SRC]void testTagThatAccessesPageScope() {

[MSG]Violation in class TagLibUnitTestCaseTests. Test method 'testTagThatAccessesPageScope' makes no assertions

Package: grails-test-suite-uber.src.test.groovy.grails.test.mixin

➥ AstEnhancedControllerUnitTestMixinTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter322

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter334

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter342

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter350

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter360

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter370

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter381

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3104

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3112

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3121

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3131

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3149

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3159

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3168

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3178

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3188

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3196

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.AstEnhancedControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

➥ AutowireServiceViaDefineBeansTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert216

[SRC]void testThatBeansAreWired() {

[MSG]Violation in class AutowireServiceViaDefineBeansTests. Test method 'testThatBeansAreWired' makes no assertions

UnusedImport33

[SRC]import org.junit.Before

[MSG]The [org.junit.Before] import is never referenced

UnusedImport37

[SRC]import org.junit.BeforeClass

[MSG]The [org.junit.BeforeClass] import is never referenced

➥ BidirectionalOneToManyUnitTestTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testRelationship() {

[MSG]Violation in class BidirectionalOneToManyUnitTestTests. Test method 'testRelationship' makes no assertions

➥ ControllerAndFilterMixinInteractionTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod225

[SRC]def index() { }

[MSG]Violation in class SecureUserController. The method index is both empty and not marked with @Override

➥ ControllerAndMockForTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert29

[SRC]void testIndexWithoutUsingMockFor() {

[MSG]Violation in class ControllerAndMockForTests. Test method 'testIndexWithoutUsingMockFor' makes no assertions

JUnitTestMethodWithoutAssert229

[SRC]void testIndexWithoutUsingMockForAgain() {

[MSG]Violation in class ControllerAndMockForTests. Test method 'testIndexWithoutUsingMockForAgain' makes no assertions

➥ ControllerUnitTestMixinTests.groovy

Rule NamePriorityLine #Source Line / Message
BrokenOddnessCheck2564

[SRC]if(val.size() % 2 == 1) {

[MSG]The code uses '(val.size() % 2 == 1)' to check for oddness, which does not work for negative numbers. Use (val.size() & 1 == 1) or (val.size() % 2 != 0) instead

BrokenOddnessCheck2564

[SRC]if(val.size() % 2 == 1) {

[MSG]The code uses '(val.size() % 2 == 1)' to check for oddness, which does not work for negative numbers. Use (val.size() & 1 == 1) or (val.size() % 2 != 0) instead

UnnecessaryGetter326

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter347

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter355

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter363

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter373

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter383

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter394

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3117

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3125

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3134

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3143

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3154

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3172

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3182

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3191

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3201

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3211

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3219

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3229

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryGetter3251

[SRC]def controller = getMockController()

[MSG]Violation in class grails.test.mixin.ControllerUnitTestMixinTests. getMockController() can probably be rewritten as mockController

UnnecessaryOverridingMethod3552

[SRC]def method1() {

[MSG]Violation in class SubController. The method method1 contains no logic and can be safely deleted

➥ ControllerWithMockCollabTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testFirstCall() {

[MSG]Violation in class ControllerWithMockCollabTests. Test method 'testFirstCall' makes no assertions

JUnitTestMethodWithoutAssert217

[SRC]void testSecondCall() {

[MSG]Violation in class ControllerWithMockCollabTests. Test method 'testSecondCall' makes no assertions

UseAssertTrueInsteadOfAssertEquals335

[SRC]assert called == true

[MSG]The expression '(called == true)' can be simplified to 'called'

➥ DomainClassAnnotatedSetupMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod216

[SRC]void testSaveInSetup() {

[MSG]Violation in class DomainClassAnnotatedSetupMethodTests. The method testSaveInSetup is both empty and not marked with @Override

JUnitTestMethodWithoutAssert216

[SRC]void testSaveInSetup() {

[MSG]Violation in class DomainClassAnnotatedSetupMethodTests. Test method 'testSaveInSetup' makes no assertions

➥ DomainClassControllerUnitTestMixinTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport36

[SRC]import grails.validation.ValidationErrors

[MSG]The [grails.validation.ValidationErrors] import is never referenced

UseAssertTrueInsteadOfAssertEquals357

[SRC]assert book.validate() == false

[MSG]The expression '(book.validate() == false)' can be simplified to '!book.validate()'

➥ DomainClassSetupMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper212

[SRC]void setUp() {

[MSG]Violation in class DomainClassSetupMethodTests. The method setUp() does not call super.setUp()

➥ MockForTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter246

[SRC]void request(HttpServletRequest request) {

[MSG]Violation in class SolrServer. Method parameter [request] is never referenced in the method request of class grails.test.mixin.SolrServer

➥ ServiceAndMockForTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert235

[SRC]void testIndexWithoutUsingMockForAgain() {

[MSG]Violation in class ServiceAndMockForTests. Test method 'testIndexWithoutUsingMockForAgain' makes no assertions

➥ UrlMappingsTestMixinTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock273

[SRC]catch (e) {}

[MSG]The catch block is empty

EmptyMethod2151

[SRC]@Action def action1(){}

[MSG]Violation in class GrailsUrlMappingsTestCaseFakeController. The method action1 is both empty and not marked with @Override

EmptyMethod2152

[SRC]@Action def action2(){}

[MSG]Violation in class GrailsUrlMappingsTestCaseFakeController. The method action2 is both empty and not marked with @Override

EmptyMethod2153

[SRC]@Action def action3(){}

[MSG]Violation in class GrailsUrlMappingsTestCaseFakeController. The method action3 is both empty and not marked with @Override

EmptyMethod2157

[SRC]@Action def publicProfile() {}

[MSG]Violation in class UserController. The method publicProfile is both empty and not marked with @Override

Package: grails-test-suite-uber.src.test.groovy.grails.util

➥ BuildScopeTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper29

[SRC]protected void tearDown() {

[MSG]Violation in class BuildScopeTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter314

[SRC]assertEquals BuildScope.ALL, BuildScope.getCurrent()

[MSG]Violation in class grails.util.BuildScopeTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter318

[SRC]assertEquals BuildScope.WAR, BuildScope.getCurrent()

[MSG]Violation in class grails.util.BuildScopeTests. getCurrent() can probably be rewritten as current

➥ BuildSettingsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper215

[SRC]protected void setUp() {

[MSG]Violation in class BuildSettingsTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper229

[SRC]protected void tearDown() {

[MSG]Violation in class BuildSettingsTests. The method tearDown() does not call super.tearDown()

EmptyMethod2332

[SRC]void receiveGrailsBuildEvent(String name, Object[] args) {}

[MSG]Violation in class BuildSettingsTestsGrailsBuildListener. The method receiveGrailsBuildEvent is both empty and not marked with @Override

UnusedMethodParameter2332

[SRC]void receiveGrailsBuildEvent(String name, Object[] args) {}

[MSG]Violation in class BuildSettingsTestsGrailsBuildListener. Method parameter [name] is never referenced in the method receiveGrailsBuildEvent of class grails.util.BuildSettingsTestsGrailsBuildListener

UnusedMethodParameter2332

[SRC]void receiveGrailsBuildEvent(String name, Object[] args) {}

[MSG]Violation in class BuildSettingsTestsGrailsBuildListener. Method parameter [args] is never referenced in the method receiveGrailsBuildEvent of class grails.util.BuildSettingsTestsGrailsBuildListener

➥ EnvironmentTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper29

[SRC]protected void tearDown() {

[MSG]Violation in class EnvironmentTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter314

[SRC]Metadata.getCurrent().clear()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter320

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter351

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter368

[SRC]assertEquals Environment.CUSTOM, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter388

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3107

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3126

[SRC]assertEquals Environment.CUSTOM, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3148

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3151

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3154

[SRC]assertEquals Environment.CUSTOM, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3169

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3172

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3175

[SRC]assertEquals Environment.PRODUCTION, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3178

[SRC]assertEquals Environment.DEVELOPMENT, Environment.getCurrent()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3186

[SRC]assertFalse "reload should be disabled by default in pro..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3189

[SRC]assertFalse "reload should be disabled by default in dev..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3192

[SRC]assertTrue "reload should be enabled by default in devel..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3196

[SRC]assertFalse "reload should be disabled by default in pro..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter3199

[SRC]assertFalse "reload should be disabled by default in pro..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

UnnecessaryObjectReferences3201

[SRC]System.setProperty(Environment.RELOAD_LOCATION, ".")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3202

[SRC]assertTrue "reload should be enabled by default in produ..oadEnabled()

[MSG]Violation in class grails.util.EnvironmentTests. getCurrent() can probably be rewritten as current

➥ MetadataTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter315

[SRC]assertEquals "1.1", m.getInstalledPlugins().tomcat

[MSG]Violation in class grails.util.MetadataTests. getInstalledPlugins() can probably be rewritten as installedPlugins

UnnecessaryGetter316

[SRC]assertEquals "1.2", m.getInstalledPlugins().hibernate

[MSG]Violation in class grails.util.MetadataTests. getInstalledPlugins() can probably be rewritten as installedPlugins

➥ PluginBuildSettingsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod228

[SRC]PluginBuildSettings createPluginBuildSettings(File proje.._PROJ_DIR) {

[MSG]Violation in class PluginBuildSettingsTests. The method createPluginBuildSettings is public but not a test method

UseAssertFalseInsteadOfNegation2277

[SRC]assertTrue("should not be a plugin-two dir in same dir a..pp.exists())

[MSG]Violation in class grails.util.PluginBuildSettingsTests. assertTrue(!pluginTwoInSameDirAsRootApp.exists()) can be simplified to assertFalse(pluginTwoInSameDirAsRootApp.exists())

UnnecessaryGetter371

[SRC]def sourceFiles = pluginSettings.getPluginSourceFiles()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginSourceFiles() can probably be rewritten as pluginSourceFiles

UnnecessaryGetter3102

[SRC]assertEquals 2, pluginSettings.getPluginLibDirectories().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginLibDirectories() can probably be rewritten as pluginLibDirectories

UnnecessaryGetter3103

[SRC]assertEquals 2, pluginSettings.getPluginLibDirectories().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginLibDirectories() can probably be rewritten as pluginLibDirectories

UnnecessaryGetter3108

[SRC]assertEquals 2, pluginSettings.getPluginDescriptors().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginDescriptors() can probably be rewritten as pluginDescriptors

UnnecessaryGetter3109

[SRC]assertEquals 2, pluginSettings.getPluginDescriptors().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginDescriptors() can probably be rewritten as pluginDescriptors

UnnecessaryGetter3116

[SRC]assertEquals 6, pluginSettings.getArtefactResources().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3117

[SRC]assertEquals 6, pluginSettings.getArtefactResources().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getArtefactResources() can probably be rewritten as artefactResources

UnnecessaryGetter3131

[SRC]def scripts = pluginSettings.getAvailableScripts()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getAvailableScripts() can probably be rewritten as availableScripts

UnnecessaryGetter3143

[SRC]def scripts = pluginSettings.getPluginScripts()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginScripts() can probably be rewritten as pluginScripts

UnnecessaryGetter3151

[SRC]assertEquals 2, pluginSettings.getPluginXmlMetadata().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginXmlMetadata() can probably be rewritten as pluginXmlMetadata

UnnecessaryGetter3152

[SRC]assertEquals 2, pluginSettings.getPluginXmlMetadata().size()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginXmlMetadata() can probably be rewritten as pluginXmlMetadata

UnnecessaryGetter3158

[SRC]def pluginInfos = pluginSettings.getPluginInfos()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginInfos() can probably be rewritten as pluginInfos

UnnecessaryGetter3177

[SRC]def pluginDirs = createPluginBuildSettings().getImplicit..irectories()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getImplicitPluginDirectories() can probably be rewritten as implicitPluginDirectories

UnnecessaryGetter3199

[SRC]def pluginDirs = pluginSettings.getPluginDirectories()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3282

[SRC]def pluginInfos = pluginSettings.getPluginInfos()

[MSG]Violation in class grails.util.PluginBuildSettingsTests. getPluginInfos() can probably be rewritten as pluginInfos

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.cli

➥ AbstractCliTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper242

[SRC]protected void setUp() {

[MSG]Violation in class AbstractCliTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper251

[SRC]protected void tearDown() {

[MSG]Violation in class AbstractCliTests. The method tearDown() does not call super.tearDown()

UnnecessaryObjectReferences3100

[SRC]settings.resourcesDir = new File("$projectDir/resources")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3101

[SRC]settings.testClassesDir = new File("$projectDir/test-classes")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3102

[SRC]settings.projectPluginsDir = new File("$projectDir/plugins")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3103

[SRC]settings.globalPluginsDir = new File("$workDir/global-plugins")

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.cli.support

➥ GrailsBuildHelperTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert213

[SRC]void testSetDepedenciesExternallyConfigured() {

[MSG]Violation in class GrailsBuildHelperTests. Test method 'testSetDepedenciesExternallyConfigured' makes no assertions

UnnecessaryObjectReferences342

[SRC]testHelper.projectPluginsDir = new File("plugins")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences343

[SRC]testHelper.globalPluginsDir = new File("global-work/plugins")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences344

[SRC]testHelper.testReportsDir = new File("target/test-reports")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences345

[SRC]testHelper.compileDependencies = testCompileDeps

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences346

[SRC]testHelper.testDependencies = testTestDeps

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences347

[SRC]testHelper.runtimeDependencies = testRuntimeDeps

[MSG]The code could be more concise by using a with() or identity() block

➥ JndiBindingSupportTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import javax.naming.Context

[MSG]The [javax.naming.Context] import is never referenced

UnusedImport35

[SRC]import javax.naming.spi.ObjectFactory

[MSG]The [javax.naming.spi.ObjectFactory] import is never referenced

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.commons

➥ DefaultGrailsCodecClassTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper29

[SRC]protected void setUp() {

[MSG]Violation in class DefaultGrailsCodecClassTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper213

[SRC]protected void tearDown() {

[MSG]Violation in class DefaultGrailsCodecClassTests. The method tearDown() does not call super.tearDown()

UnusedMethodParameter236

[SRC]def encode(obj) { "encoded" }

[MSG]Violation in class CodecWithMethodsCodec. Method parameter [obj] is never referenced in the method encode of class org.codehaus.groovy.grails.commons.CodecWithMethodsCodec

UnusedMethodParameter237

[SRC]def decode(obj) { "decoded" }

[MSG]Violation in class CodecWithMethodsCodec. Method parameter [obj] is never referenced in the method decode of class org.codehaus.groovy.grails.commons.CodecWithMethodsCodec

UnnecessaryGetter319

[SRC]assertEquals "encoded", codecClass.getEncodeMethod().call("stuff")

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsCodecClassTests. getEncodeMethod() can probably be rewritten as encodeMethod

UnnecessaryGetter320

[SRC]assertEquals "decoded", codecClass.getDecodeMethod().call("stuff")

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsCodecClassTests. getDecodeMethod() can probably be rewritten as decodeMethod

➥ DefaultGrailsDomainClassPropertyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper213

[SRC]void setUp() {

[MSG]Violation in class DefaultGrailsDomainClassPropertyTests. The method setUp() does not call super.setUp()

ComparisonWithSelf224

[SRC]assertTrue(prop1Child.equals(prop1Child))

[MSG]Comparing an object to itself is useless and may indicate a bug: prop1Child.equals(prop1Child)

UnnecessaryGroovyImport33

[SRC]import groovy.util.GroovyTestCase

UnnecessaryDotClass315

[SRC]parentClass = new DefaultGrailsDomainClass(ParentClass.class)

[MSG]ParentClass.class can be rewritten as ParentClass

UnnecessaryDotClass316

[SRC]childClass = new DefaultGrailsDomainClass(ChildClass.class)

[MSG]ChildClass.class can be rewritten as ChildClass

➥ DefaultGrailsDomainClassTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2272

[SRC]Class topClass = gcl.parseClass("class Top {\n" +

[MSG]The variable [topClass] in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests is not used

UnusedVariable2279

[SRC]Class middleClass = gcl.parseClass("class Middle extends Top {\n" +

[MSG]The variable [middleClass] in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests is not used

UnusedVariable2284

[SRC]Class bottomClass = gcl.parseClass("class Bottom extends Middle {\n" +

[MSG]The variable [bottomClass] in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests is not used

EmptyCatchBlock2372

[SRC]catch(InvalidPropertyException ipe) {

[MSG]The catch block is empty

UnnecessaryGetter338

[SRC]assertEquals(GrailsDomainClassProperty.FETCH_EAGER, test..FetchMode())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter341

[SRC]assertEquals(GrailsDomainClassProperty.FETCH_LAZY, other..FetchMode())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getFetchMode() can probably be rewritten as fetchMode

UnnecessaryGetter3200

[SRC]domainMap.put(dc.getFullName(),dc)

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getFullName() can probably be rewritten as fullName

UnnecessaryGetter3207

[SRC]assertTrue(dc.getPropertyByName("children").getOtherSide..("parent")))

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter3208

[SRC]assertTrue(dc.getPropertyByName("parent").getOtherSide()..children")))

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter3256

[SRC]assertEquals(c1dc.getPropertyByName("ones").getOtherSide..me("other"))

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter3263

[SRC]assertEquals(c2dc.getPropertyByName("other").getOtherSid..ame("ones"))

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getOtherSide() can probably be rewritten as otherSide

UnnecessaryGetter3362

[SRC]assertEquals("UserTest",domainClass.getName())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getName() can probably be rewritten as name

UnnecessaryGetter3364

[SRC]assertNotNull(domainClass.getIdentifier())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getIdentifier() can probably be rewritten as identifier

UnnecessaryGetter3365

[SRC]assertNotNull(domainClass.getVersion())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getVersion() can probably be rewritten as version

UnnecessaryGetter3366

[SRC]assertTrue(domainClass.getIdentifier().isIdentity())

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getIdentifier() can probably be rewritten as identifier

UnnecessaryGetter3390

[SRC]GrailsDomainClassProperty[] persistantProperties = domai..Properties()

[MSG]Violation in class org.codehaus.groovy.grails.commons.DefaultGrailsDomainClassTests. getPersistentProperties() can probably be rewritten as persistentProperties

➥ GrailsMetaClassUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter315

[SRC]assertNotNull(GrailsMetaClassUtils.getRegistry())

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsMetaClassUtilsTests. getRegistry() can probably be rewritten as registry

UnnecessaryGetter339

[SRC]assertEquals "bar", d.getFoo()

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsMetaClassUtilsTests. getFoo() can probably be rewritten as foo

UnnecessaryGetter348

[SRC]assertEquals "bar", d.getFoo()

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsMetaClassUtilsTests. getFoo() can probably be rewritten as foo

➥ GrailsPluginManagerDescriptorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert28

[SRC]void testDoWithWebDescriptor() {

[MSG]Violation in class GrailsPluginManagerDescriptorTests. Test method 'testDoWithWebDescriptor' makes no assertions

UnusedVariable220

[SRC]def xml = new XmlSlurper().parseText(text)

[MSG]The variable [xml] in class org.codehaus.groovy.grails.commons.GrailsPluginManagerDescriptorTests is not used

JUnitTestMethodWithoutAssert223

[SRC]void testDevelopmentDescriptor() {

[MSG]Violation in class GrailsPluginManagerDescriptorTests. Test method 'testDevelopmentDescriptor' makes no assertions

UnusedVariable236

[SRC]def xml = new XmlSlurper().parseText(text)

[MSG]The variable [xml] in class org.codehaus.groovy.grails.commons.GrailsPluginManagerDescriptorTests is not used

➥ GrailsPluginManagerTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2122

[SRC]void testWithLoadLastPlugin() {

[MSG]Violation in class GrailsPluginManagerTests. Test method 'testWithLoadLastPlugin' makes no assertions

JUnitTestMethodWithoutAssert2134

[SRC]void testDependencyResolutionSucces() {

[MSG]Violation in class GrailsPluginManagerTests. Test method 'testDependencyResolutionSucces' makes no assertions

UnusedImport35

[SRC]import org.codehaus.groovy.grails.plugins.exceptions.PluginException

[MSG]The [org.codehaus.groovy.grails.plugins.exceptions.PluginException] import is never referenced

UnnecessaryGetter3103

[SRC]assertEquals(1, manager.getPluginResources().length)

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getPluginResources() can probably be rewritten as pluginResources

UnnecessaryGetter3112

[SRC]assertEquals("classEditor",plugin.getName())

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getName() can probably be rewritten as name

UnnecessaryGetter3113

[SRC]assertEquals("1.1", plugin.getVersion())

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getVersion() can probably be rewritten as version

UnnecessaryGetter3153

[SRC]def ctx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3171

[SRC]def ctx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.commons.GrailsPluginManagerTests. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.commons.metaclass

➥ DynamicMethodsExpandoMetaClassTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import org.springframework.beans.BeanUtils

[MSG]The [org.springframework.beans.BeanUtils] import is never referenced

UnnecessaryDotClass326

[SRC]def metaClass = new DynamicMethodsExpandoMetaClass(Book.class)

[MSG]Book.class can be rewritten as Book

UnnecessaryDotClass344

[SRC]def metaClass = new DynamicMethodsExpandoMetaClass(Book.class, true)

[MSG]Book.class can be rewritten as Book

UnnecessaryDotClass357

[SRC]def metaClass = new DynamicMethodsExpandoMetaClass(Book.class, true)

[MSG]Book.class can be rewritten as Book

UnnecessaryGetter376

[SRC]assertEquals "bar", b.getFoo()

[MSG]Violation in class org.codehaus.groovy.grails.commons.metaclass.DynamicMethodsExpandoMetaClassTests. getFoo() can probably be rewritten as foo

➥ LazyMetaPropertyMapTests.groovy

Rule NamePriorityLine #Source Line / Message
CoupledTestCase211

[SRC]def obj = new PropertyMapTest(name:"Homer", age:45)

[MSG]new PropertyMapTest([name:Homer, age:45]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase219

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..er:"stuff"))

[MSG]new PropertyMapTest([name:Bart, age:11, other:stuff]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase228

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest())

[MSG]new PropertyMapTest() creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase233

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest())

[MSG]new PropertyMapTest() creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase238

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest())

[MSG]new PropertyMapTest() creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase246

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..r", age:45))

[MSG]new PropertyMapTest([name:Homer, age:45]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase254

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..r", age:45))

[MSG]new PropertyMapTest([name:Homer, age:45]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase270

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..t", age:11))

[MSG]new PropertyMapTest([name:Bart, age:11]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase285

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..t", age:11))

[MSG]new PropertyMapTest([name:Bart, age:11]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

CoupledTestCase294

[SRC]def map = new LazyMetaPropertyMap(new PropertyMapTest(na..t", age:11))

[MSG]new PropertyMapTest([name:Bart, age:11]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

➥ MetaClassEnhancerTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper241

[SRC]protected void tearDown() throws Exception {

[MSG]Violation in class MetaClassEnhancerTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.compiler

➥ GrailsClassLoaderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.control.CompilerConfiguration

[MSG]The [org.codehaus.groovy.control.CompilerConfiguration] import is never referenced

UnusedImport34

[SRC]import org.codehaus.groovy.grails.compiler.support.Grail..sourceLoader

[MSG]The [org.codehaus.groovy.grails.compiler.support.GrailsResourceLoader] import is never referenced

UnnecessaryGetter332

[SRC]assert e == gcl.getCompilationError() : "should have sto..ation error"

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsClassLoaderTests. getCompilationError() can probably be rewritten as compilationError

UnnecessaryGetter338

[SRC]assert !gcl.getCompilationError() : "shouldn't have any ..tion errors"

[MSG]Violation in class org.codehaus.groovy.grails.compiler.GrailsClassLoaderTests. getCompilationError() can probably be rewritten as compilationError

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.compiler.injection

➥ GrailsASTUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertTrueInsteadOfAssertEquals364

[SRC]assert true == firstNameBindableExpression.value

[MSG]The expression '(true == firstNameBindableExpression.value)' can be simplified to 'firstNameBindableExpression.value'

UseAssertTrueInsteadOfAssertEquals372

[SRC]assert false == lastNameBindableExpression.value

[MSG]The expression '(false == lastNameBindableExpression.value)' can be simplified to '!lastNameBindableExpression.value'

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.context.support

➥ PluginAwareResourceBundleMessageSourceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper216

[SRC]protected void setUp() {

[MSG]Violation in class PluginAwareResourceBundleMessageSourceTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper220

[SRC]protected void tearDown() {

[MSG]Violation in class PluginAwareResourceBundleMessageSourceTests. The method tearDown() does not call super.tearDown()

UnusedMethodParameter261

[SRC]protected Resource[] getPluginBundles(String pluginName) {

[MSG]Violation in class TestPluginAwareResourceBundleMessageSource. Method parameter [pluginName] is never referenced in the method getPluginBundles of class org.codehaus.groovy.grails.context.support.TestPluginAwareResourceBundleMessageSource

UnnecessaryGetter317

[SRC]Metadata.getCurrent().put(Metadata.WAR_DEPLOYED, "true")

[MSG]Violation in class org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSourceTests. getCurrent() can probably be rewritten as current

UnnecessaryGetter321

[SRC]Metadata.getCurrent().put(Metadata.WAR_DEPLOYED, "")

[MSG]Violation in class org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSourceTests. getCurrent() can probably be rewritten as current

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.documentation

➥ MetadataGeneratingExpandoMetaClassTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import groovy.xml.StreamingMarkupBuilder

[MSG]The [groovy.xml.StreamingMarkupBuilder] import is never referenced

UnusedImport35

[SRC]import org.codehaus.groovy.grails.commons.ControllerArtefactHandler

[MSG]The [org.codehaus.groovy.grails.commons.ControllerArtefactHandler] import is never referenced

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins

➥ CoreGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert212

[SRC]void testComponentScan() {

[MSG]Violation in class CoreGrailsPluginTests. Test method 'testComponentScan' makes no assertions

UnusedVariable225

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]The variable [appCtx] in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests is not used

UnnecessaryGetter325

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter338

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter355

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3119

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.CoreGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

➥ DomainClassGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod212

[SRC]void onSetUp() {

[MSG]Violation in class DomainClassGrailsPluginTests. The method onSetUp is public but not a test method

UnusedMethodParameter2202

[SRC]boolean shouldInject(URL url) { true }

[MSG]Violation in class AlwaysInjector. Method parameter [url] is never referenced in the method shouldInject of class org.codehaus.groovy.grails.plugins.AlwaysInjector

UnusedMethodParameter2204

[SRC]protected boolean isDomainClass(ClassNode classNode, Sou..e) { true }

[MSG]Violation in class AlwaysInjector. Method parameter [classNode] is never referenced in the method isDomainClass of class org.codehaus.groovy.grails.plugins.AlwaysInjector

UnusedMethodParameter2204

[SRC]protected boolean isDomainClass(ClassNode classNode, Sou..e) { true }

[MSG]Violation in class AlwaysInjector. Method parameter [sourceNode] is never referenced in the method isDomainClass of class org.codehaus.groovy.grails.plugins.AlwaysInjector

UnusedMethodParameter2206

[SRC]protected boolean shouldInjectClass(ClassNode classNode) { true }

[MSG]Violation in class AlwaysInjector. Method parameter [classNode] is never referenced in the method shouldInjectClass of class org.codehaus.groovy.grails.plugins.AlwaysInjector

UnnecessaryObjectReferences343

[SRC]gcl.parseClass("""class Child3 extends grails.test.Parent2 {

[MSG]The code could be more concise by using a with() or identity() block

➥ GrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport34

[SRC]import grails.util.BuildSettings

[MSG]The [grails.util.BuildSettings] import is never referenced

UnnecessaryGetter3181

[SRC]System.setProperty(Environment.KEY, Environment.PRODUCTION.getName())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginTests. getName() can probably be rewritten as name

➥ GrailsPluginUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper217

[SRC]protected void setUp() {

[MSG]Violation in class GrailsPluginUtilsTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper237

[SRC]void tearDown() {

[MSG]Violation in class GrailsPluginUtilsTests. The method tearDown() does not call super.tearDown()

UnusedImport36

[SRC]import org.apache.commons.io.FileUtils

[MSG]The [org.apache.commons.io.FileUtils] import is never referenced

UnnecessaryGetter3146

[SRC]def pluginDirs = GrailsPluginUtils.getPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtilsTests. getPluginDirectories() can probably be rewritten as pluginDirectories

UnnecessaryGetter3155

[SRC]def pluginDirs = GrailsPluginUtils.getImplicitPluginDirectories()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.GrailsPluginUtilsTests. getImplicitPluginDirectories() can probably be rewritten as implicitPluginDirectories

➥ PluginDescriptorReaderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter250

[SRC]Resource createRelative(String relativePath) { new ByteA..xml.bytes) }

[MSG]Violation in class PluginDescriptorReaderTests$1. Method parameter [relativePath] is never referenced in the method createRelative of class org.codehaus.groovy.grails.plugins.PluginDescriptorReaderTests$1

➥ PluginInfoTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter238

[SRC]GPathResult parseMetadata(Resource pluginDir) { null }

[MSG]Violation in class MockPluginInfo. Method parameter [pluginDir] is never referenced in the method parseMetadata of class org.codehaus.groovy.grails.plugins.MockPluginInfo

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.i18n

➥ I18nGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences320

[SRC]ctx.registerMockResource("WEB-INF/grails-app/i18n/sub/di..properties")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences321

[SRC]ctx.registerMockResource("WEB-INF/grails-app/i18n/nobundle")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences322

[SRC]ctx.registerMockResource("WEB-INF/grails-app/i18n/nobundle.txt")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences323

[SRC]ctx.registerMockResource("WEB-INF/grails-app/i18n/nobundle.xml")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter334

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.i18n.I18nGrailsPluginTests. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.logging

➥ Log4jDslTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2201

[SRC]def consoleAppender

[MSG]The variable [consoleAppender] in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests is not used

UnnecessaryGetter3120

[SRC]def r = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3139

[SRC]r = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3158

[SRC]r = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3178

[SRC]def root = Logger.getRootLogger()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getRootLogger() can probably be rewritten as rootLogger

UnnecessaryGetter3181

[SRC]def appenders = root.getAllAppenders()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.logging.Log4jDslTests. getAllAppenders() can probably be rewritten as allAppenders

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.publishing

➥ DefaultPluginPublisherTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2249

[SRC]protected GPathResult getPluginMetadata(String pluginName) {

[MSG]Violation in class TestPluginPublisher. Method parameter [pluginName] is never referenced in the method getPluginMetadata of class org.codehaus.groovy.grails.plugins.publishing.TestPluginPublisher

UnusedMethodParameter2253

[SRC]GPathResult parsePluginList(Resource pluginsListFile) {

[MSG]Violation in class TestPluginPublisher. Method parameter [pluginsListFile] is never referenced in the method parsePluginList of class org.codehaus.groovy.grails.plugins.publishing.TestPluginPublisher

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.web

➥ ControllersGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2180

[SRC]Class parseTestBean() {

[MSG]Violation in class ControllersGrailsPluginTests. The method parseTestBean is public but not a test method

UseAssertEqualsInsteadOfAssertTrue3115

[SRC]assertTrue ga.config.grails.disableCommonsMultipart.size() == 0

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. Replace assertTrue with a call to assertEquals()

UnnecessaryGetter3131

[SRC]assertNotNull beanDef.getPropertyValues().getPropertyVal..seResource')

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getPropertyValues() can probably be rewritten as propertyValues

UnnecessaryGetter3133

[SRC]assertEquals "file:.", beanDef.getPropertyValues().getPr..).getValue()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getValue() can probably be rewritten as value

UnnecessaryGetter3133

[SRC]assertEquals "file:.", beanDef.getPropertyValues().getPr..).getValue()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getPropertyValues() can probably be rewritten as propertyValues

UnnecessaryGetter3136

[SRC]assertEquals "groovyPageLocator", beanDef.getPropertyVal..()?.beanName

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getValue() can probably be rewritten as value

UnnecessaryGetter3136

[SRC]assertEquals "groovyPageLocator", beanDef.getPropertyVal..()?.beanName

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ControllersGrailsPluginTests. getPropertyValues() can probably be rewritten as propertyValues

➥ LoggingGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable241

[SRC]def registry = GroovySystem.metaClassRegistry

[MSG]The variable [registry] in class org.codehaus.groovy.grails.plugins.web.LoggingGrailsPluginTests is not used

UnusedVariable247

[SRC]def registry = GroovySystem.metaClassRegistry

[MSG]The variable [registry] in class org.codehaus.groovy.grails.plugins.web.LoggingGrailsPluginTests is not used

UnusedVariable253

[SRC]def registry = GroovySystem.metaClassRegistry

[MSG]The variable [registry] in class org.codehaus.groovy.grails.plugins.web.LoggingGrailsPluginTests is not used

➥ ServletsGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable260

[SRC]def httpSessionMetaClass = GroovySystem.getMetaClassRegi..HttpSession)

[MSG]The variable [httpSessionMetaClass] in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPluginTests is not used

UnusedVariable261

[SRC]def metaClass = GroovySystem.getMetaClassRegistry().getM...getClass())

[MSG]The variable [metaClass] in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPluginTests is not used

UnnecessaryGroovyImport33

[SRC]import groovy.lang.GroovySystem;

UnnecessaryGetter360

[SRC]def httpSessionMetaClass = GroovySystem.getMetaClassRegi..HttpSession)

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPluginTests. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

UnnecessaryGetter361

[SRC]def metaClass = GroovySystem.getMetaClassRegistry().getM...getClass())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.web.ServletsGrailsPluginTests. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.plugins.web.mapping

➥ UrlMappingsGrailsPluginTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper287

[SRC]protected void tearDown() {

[MSG]Violation in class UrlMappingsGrailsPluginTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.reload

➥ TagLibReloadTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable218

[SRC]Class oldClass = ga.getTagLibClass("TestTagLib").getClazz()

[MSG]The variable [oldClass] in class org.codehaus.groovy.grails.reload.TagLibReloadTests is not used

UnusedVariable219

[SRC]def result

[MSG]The variable [result] in class org.codehaus.groovy.grails.reload.TagLibReloadTests is not used

JUnitPublicNonTestMethod245

[SRC]void onInit() {

[MSG]Violation in class TagLibReloadTests. The method onInit is public but not a test method

UnnecessaryGetter318

[SRC]Class oldClass = ga.getTagLibClass("TestTagLib").getClazz()

[MSG]Violation in class org.codehaus.groovy.grails.reload.TagLibReloadTests. getClazz() can probably be rewritten as clazz

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.resolve

➥ IvyDependencyManagerTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper223

[SRC]protected void setUp() {

[MSG]Violation in class IvyDependencyManagerTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper227

[SRC]protected void tearDown() {

[MSG]Violation in class IvyDependencyManagerTests. The method tearDown() does not call super.tearDown()

JUnitTestMethodWithoutAssert2119

[SRC]void testPluginResolve() {

[MSG]Violation in class IvyDependencyManagerTests. Test method 'testPluginResolve' makes no assertions

UnusedVariable2132

[SRC]def report = manager.resolveDependencies()

[MSG]The variable [report] in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests is not used

JUnitTestMethodWithoutAssert2449

[SRC]void testResolveApplicationDependencies() {

[MSG]Violation in class IvyDependencyManagerTests. Test method 'testResolveApplicationDependencies' makes no assertions

UnusedVariable2638

[SRC]def grailsVersion = getCurrentGrailsVersion()

[MSG]The variable [grailsVersion] in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests is not used

JUnitPublicNonTestMethod2671

[SRC]def getCurrentGrailsVersion() {

[MSG]Violation in class IvyDependencyManagerTests. The method getCurrentGrailsVersion is public but not a test method

JUnitTestMethodWithoutAssert2799

[SRC]void testResolve() {

[MSG]Violation in class IvyDependencyManagerTests. Test method 'testResolve' makes no assertions

UnusedVariable2831

[SRC]ModuleRevisionId junit = manager.dependencies.find { Mo.. == 'junit'}

[MSG]The variable [junit] in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests is not used

UseAssertTrueInsteadOfAssertEquals338

[SRC]assert manager.ivySettings.defaultUseOrigin == true

[MSG]The expression '(manager.ivySettings.defaultUseOrigin == true)' can be simplified to 'manager.ivySettings.defaultUseOrigin'

UnnecessaryGetter3219

[SRC]assertEquals "1.5", dd.getDependencyRevisionId().revision

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyRevisionId() can probably be rewritten as dependencyRevisionId

UnnecessaryGetter3226

[SRC]assertEquals "0.5.5", dd.getDependencyRevisionId().revision

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyRevisionId() can probably be rewritten as dependencyRevisionId

UnnecessaryGetter3233

[SRC]assertEquals "0.5.6", dd.getDependencyRevisionId().revision

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyRevisionId() can probably be rewritten as dependencyRevisionId

UnnecessaryGetter3298

[SRC]assertEquals 1, dep.getModuleConfigurations().length

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getModuleConfigurations() can probably be rewritten as moduleConfigurations

UnnecessaryGetter3486

[SRC]assertEquals 2, manager.getApplicationDependencyDescriptors().size()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getApplicationDependencyDescriptors() can probably be rewritten as applicationDependencyDescriptors

UnnecessaryGetter3617

[SRC]def grailsVersion = getCurrentGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getCurrentGrailsVersion() can probably be rewritten as currentGrailsVersion

UnnecessaryGetter3638

[SRC]def grailsVersion = getCurrentGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getCurrentGrailsVersion() can probably be rewritten as currentGrailsVersion

UnnecessaryGetter3741

[SRC]DefaultDependencyDescriptor dd = manager.getDependencyDe..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyDescriptors() can probably be rewritten as dependencyDescriptors

UnnecessaryGetter3757

[SRC]dd = manager.getDependencyDescriptors().iterator().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyDescriptors() can probably be rewritten as dependencyDescriptors

UnnecessaryGetter3772

[SRC]DefaultDependencyDescriptor dd = manager.getPluginDepend..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getPluginDependencyDescriptors() can probably be rewritten as pluginDependencyDescriptors

UnnecessaryGetter3786

[SRC]DefaultDependencyDescriptor dd = manager.getPluginDepend..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getPluginDependencyDescriptors() can probably be rewritten as pluginDependencyDescriptors

UnnecessaryGetter3850

[SRC]DefaultDependencyDescriptor dd = manager.getDependencyDe..tor().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyDescriptors() can probably be rewritten as dependencyDescriptors

UnnecessaryGetter3866

[SRC]dd = manager.getDependencyDescriptors().iterator().next()

[MSG]Violation in class org.codehaus.groovy.grails.resolve.IvyDependencyManagerTests. getDependencyDescriptors() can probably be rewritten as dependencyDescriptors

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.validation

➥ ConstrainedPropertyBuilderForCommandsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences3106

[SRC]gcl.parseClass('''

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3119

[SRC]gcl.parseClass('''

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3132

[SRC]gcl.parseClass('''

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3153

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3154

[SRC]assertEquals(5, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3155

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3156

[SRC]assertNotNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3160

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3161

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3162

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3163

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryObjectReferences3181

[SRC]personCommand.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3184

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3184

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3185

[SRC]assertEquals(1, personCommand.getErrors().getFieldErrors..me").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3186

[SRC]assertNull(personCommand.getErrors().getFieldErrors("fir..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3186

[SRC]assertNull(personCommand.getErrors().getFieldErrors("fir..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryObjectReferences3199

[SRC]person.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3202

[SRC]assertEquals(1, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3202

[SRC]assertEquals(1, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3203

[SRC]assertEquals(1, person.getErrors().getFieldErrors("firstName").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3204

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3204

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3214

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3215

[SRC]assertEquals(2, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3216

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3217

[SRC]assertNotNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3221

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3222

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3223

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3224

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3225

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryObjectReferences3243

[SRC]personCommand.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3246

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3246

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3247

[SRC]assertEquals(1, personCommand.getErrors().getFieldErrors..me").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3248

[SRC]assertNull(personCommand.getErrors().getFieldErrors("fir..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3248

[SRC]assertNull(personCommand.getErrors().getFieldErrors("fir..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryObjectReferences3261

[SRC]person.email = "wrongEmail"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3262

[SRC]person.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3265

[SRC]assertEquals(1, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3265

[SRC]assertEquals(1, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3266

[SRC]assertEquals(1, person.getErrors().getFieldErrors("email").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3267

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3267

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3277

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3278

[SRC]assertEquals(5, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3279

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3280

[SRC]assertNotNull(personCommand.getConstraints().get("telephone"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3282

[SRC]assertEquals(30, personCommand.getConstraints().get("fir..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3282

[SRC]assertEquals(30, personCommand.getConstraints().get("fir..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3283

[SRC]assertEquals(50, personCommand.getConstraints().get("las..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3283

[SRC]assertEquals(50, personCommand.getConstraints().get("las..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3286

[SRC]personCommand.getConstraints().get("telephone").getAppli..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3286

[SRC]personCommand.getConstraints().get("telephone").getAppli..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3290

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3291

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3292

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3293

[SRC]assertNotNull(person.getConstraints().get("telephone"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3295

[SRC]assertEquals(30, person.getConstraints().get("firstName"..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3295

[SRC]assertEquals(30, person.getConstraints().get("firstName"..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3296

[SRC]assertEquals(50, person.getConstraints().get("lastName")..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3296

[SRC]assertEquals(50, person.getConstraints().get("lastName")..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3297

[SRC]assertEquals("123123", person.getConstraints().get("tele..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3297

[SRC]assertEquals("123123", person.getConstraints().get("tele..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryObjectReferences3315

[SRC]personCommand.lastName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3316

[SRC]personCommand.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3319

[SRC]assertEquals(2, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3319

[SRC]assertEquals(2, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryObjectReferences3332

[SRC]person.firstName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3333

[SRC]person.email = "wrongEmail"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3334

[SRC]person.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3337

[SRC]assertEquals(2, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3337

[SRC]assertEquals(2, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3338

[SRC]assertEquals(1, person.getErrors().getFieldErrors("firstName").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3339

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3339

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3340

[SRC]assertEquals(1, person.getErrors().getFieldErrors("email").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3341

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3341

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3351

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3352

[SRC]assertEquals(5, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3353

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3354

[SRC]assertNotNull(personCommand.getConstraints().get("telephone"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3356

[SRC]assertEquals(10, personCommand.getConstraints().get("fir..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3356

[SRC]assertEquals(10, personCommand.getConstraints().get("fir..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3357

[SRC]assertEquals(20, personCommand.getConstraints().get("las..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3357

[SRC]assertEquals(20, personCommand.getConstraints().get("las..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3360

[SRC]personCommand.getConstraints().get("telephone").getAppli..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3360

[SRC]personCommand.getConstraints().get("telephone").getAppli..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3364

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3365

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3366

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3367

[SRC]assertNotNull(person.getConstraints().get("telephone"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3369

[SRC]assertEquals(30, person.getConstraints().get("firstName"..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3369

[SRC]assertEquals(30, person.getConstraints().get("firstName"..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3370

[SRC]assertEquals(50, person.getConstraints().get("lastName")..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3370

[SRC]assertEquals(50, person.getConstraints().get("lastName")..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3371

[SRC]assertEquals("123123", person.getConstraints().get("tele..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getParameter() can probably be rewritten as parameter

UnnecessaryGetter3371

[SRC]assertEquals("123123", person.getConstraints().get("tele..Parameter())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryObjectReferences3389

[SRC]personCommand.firstName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3390

[SRC]personCommand.lastName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3391

[SRC]personCommand.email = "wrongEmail"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3392

[SRC]personCommand.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3395

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3395

[SRC]assertEquals(1, personCommand.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryObjectReferences3408

[SRC]person.firstName = null

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3409

[SRC]person.email = "wrongEmail"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3410

[SRC]person.validate()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3413

[SRC]assertEquals(2, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrorCount() can probably be rewritten as errorCount

UnnecessaryGetter3413

[SRC]assertEquals(2, person.getErrors().getErrorCount())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3414

[SRC]assertEquals(1, person.getErrors().getFieldErrors("firstName").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3415

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3415

[SRC]assertNull(person.getErrors().getFieldErrors("firstName"..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3416

[SRC]assertEquals(1, person.getErrors().getFieldErrors("email").size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3417

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getRejectedValue() can probably be rewritten as rejectedValue

UnnecessaryGetter3417

[SRC]assertEquals("wrongEmail", person.getErrors().getFieldEr..ctedValue())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getErrors() can probably be rewritten as errors

UnnecessaryGetter3427

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3428

[SRC]assertEquals(2, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3429

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3430

[SRC]assertNotNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3431

[SRC]assertNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3435

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3436

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3437

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3438

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3439

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3449

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3450

[SRC]assertEquals(3, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3451

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3452

[SRC]assertNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3453

[SRC]assertNull(personCommand.getConstraints().get("lastName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3454

[SRC]assertNotNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3458

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3459

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3460

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3461

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3462

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3472

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3473

[SRC]assertEquals(3, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3474

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3475

[SRC]assertNotNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3476

[SRC]assertNotNull(personCommand.getConstraints().get("lastName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3477

[SRC]assertNotNull(personCommand.getConstraints().get("middleName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3478

[SRC]assertNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3482

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3483

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3484

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3485

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3486

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3497

[SRC]assertNotNull(personCommand.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3498

[SRC]assertEquals(2, personCommand.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3499

[SRC]assertNull(personCommand.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3500

[SRC]assertNotNull(personCommand.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3501

[SRC]assertNotNull(personCommand.getConstraints().get("lastName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3502

[SRC]assertNull(personCommand.getConstraints().get("middleName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3503

[SRC]assertNull(personCommand.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3507

[SRC]assertNotNull(person.getConstraints())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3508

[SRC]assertEquals(5, person.getConstraints().size())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3509

[SRC]assertNull(person.getConstraints().get("importFrom"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3510

[SRC]assertNotNull(person.getConstraints().get("firstName"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

UnnecessaryGetter3511

[SRC]assertNotNull(person.getConstraints().get("email"))

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilderForCommandsTests. getConstraints() can probably be rewritten as constraints

➥ ConstraintMessageTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter254

[SRC]void processValidate(Object target, Object propertyValue..rs errors) {

[MSG]Violation in class TestConstraint. Method parameter [propertyValue] is never referenced in the method processValidate of class org.codehaus.groovy.grails.validation.TestConstraint

UnusedMethodParameter258

[SRC]boolean supports(Class type) { true }

[MSG]Violation in class TestConstraint. Method parameter [type] is never referenced in the method supports of class org.codehaus.groovy.grails.validation.TestConstraint

UnnecessaryGetter339

[SRC]'test'] as String[], errors.getFieldError().getCodes())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstraintMessageTests. getCodes() can probably be rewritten as codes

UnnecessaryGetter339

[SRC]'test'] as String[], errors.getFieldError().getCodes())

[MSG]Violation in class org.codehaus.groovy.grails.validation.ConstraintMessageTests. getFieldError() can probably be rewritten as fieldError

➥ ConstraintsBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod274

[SRC]Errors validateInstance(instance, validator) {

[MSG]Violation in class ConstraintsBuilderTests. The method validateInstance is public but not a test method

JUnitPublicNonTestMethod280

[SRC]GrailsDomainClassValidator configureValidator(theClass, instance) {

[MSG]Violation in class ConstraintsBuilderTests. The method configureValidator is public but not a test method

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.context

➥ GrailsConfigUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable264

[SRC]def configurator = GrailsConfigUtils.determineGrailsRunt..ontext, ctx)

[MSG]The variable [configurator] in class org.codehaus.groovy.grails.web.context.GrailsConfigUtilsTests is not used

JUnitTearDownCallsSuper279

[SRC]protected void tearDown() {

[MSG]Violation in class GrailsConfigUtilsTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter348

[SRC]servletContext.addInitParameter("grailsConfiguratorClass..s.getName())

[MSG]Violation in class org.codehaus.groovy.grails.web.context.GrailsConfigUtilsTests. getName() can probably be rewritten as name

UnnecessaryDotClass348

[SRC]servletContext.addInitParameter("grailsConfiguratorClass..s.getName())

[MSG]MyGrailsRuntimeConfigurator.class can be rewritten as MyGrailsRuntimeConfigurator

UnnecessaryDotClass353

[SRC]assertEquals configurator.class.name, MyGrailsRuntimeCon..r.class.name

[MSG]MyGrailsRuntimeConfigurator.class can be rewritten as MyGrailsRuntimeConfigurator

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.errors

➥ GrailsExceptionResolverTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper237

[SRC]protected void tearDown() {

[MSG]Violation in class GrailsExceptionResolverTests. The method tearDown() does not call super.tearDown()

UnusedMethodParameter2264

[SRC]View resolveViewName(String viewName, Locale locale) {

[MSG]Violation in class DummyViewResolver. Method parameter [locale] is never referenced in the method resolveViewName of class org.codehaus.groovy.grails.web.errors.DummyViewResolver

UnnecessaryGetter3120

[SRC]assertEquals "/grails/foo/bar.dispatch",response.getForwardedUrl()

[MSG]Violation in class org.codehaus.groovy.grails.web.errors.GrailsExceptionResolverTests. getForwardedUrl() can probably be rewritten as forwardedUrl

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.filters

➥ HiddenHttpMethodFilterTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.springframework.mock.web.MockServletContext;

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

UnusedImport35

[SRC]import org.codehaus.groovy.grails.web.servlet.GrailsAppl..nAttributes;

[MSG]The [org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes] import is never referenced

UnusedImport36

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest;

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest] import is never referenced

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.i18n

➥ ParamsAwareLocaleChangeInterceptorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper216

[SRC]protected void tearDown() {

[MSG]Violation in class ParamsAwareLocaleChangeInterceptorTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter324

[SRC]def request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter325

[SRC]def response = webRequest.getCurrentResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentResponse() can probably be rewritten as currentResponse

UnnecessaryGetter347

[SRC]assertEquals "de", locale.getLanguage()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getLanguage() can probably be rewritten as language

UnnecessaryGetter348

[SRC]assertEquals "DE", locale.getCountry()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCountry() can probably be rewritten as country

UnnecessaryGetter355

[SRC]def request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter356

[SRC]def response = webRequest.getCurrentResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentResponse() can probably be rewritten as currentResponse

UnnecessaryGetter378

[SRC]assertEquals "de", locale.getLanguage()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getLanguage() can probably be rewritten as language

UnnecessaryGetter379

[SRC]assertEquals "DE", locale.getCountry()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCountry() can probably be rewritten as country

UnnecessaryGetter386

[SRC]MockHttpServletRequest request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter387

[SRC]def response = webRequest.getCurrentResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCurrentResponse() can probably be rewritten as currentResponse

UnnecessaryGetter3109

[SRC]assertEquals "de", locale.getLanguage()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getLanguage() can probably be rewritten as language

UnnecessaryGetter3110

[SRC]assertEquals "DE", locale.getCountry()

[MSG]Violation in class org.codehaus.groovy.grails.web.i18n.ParamsAwareLocaleChangeInterceptorTests. getCountry() can probably be rewritten as country

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.json

➥ JSONObjectTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertEqualsInsteadOfAssertTrue332

[SRC]assertTrue j1 == j2

[MSG]Violation in class org.codehaus.groovy.grails.web.json.JSONObjectTests. Replace assertTrue with a call to assertEquals()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.metaclass

➥ WithFormMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper230

[SRC]@Override protected void tearDown() {

[MSG]Violation in class WithFormMethodTests. The method tearDown() does not call super.tearDown()

UnusedVariable2146

[SRC]def result = withForm.withForm(request) {

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.metaclass.WithFormMethodTests is not used

UnusedVariable2170

[SRC]def result = withForm.withForm(request) {

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.metaclass.WithFormMethodTests is not used

UnusedImport320

[SRC]import org.apache.commons.lang.StringUtils;

[MSG]The [org.apache.commons.lang.StringUtils] import is never referenced

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.servlet

➥ BindDataMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2160

[SRC]void onSetUp() {

[MSG]Violation in class BindDataMethodTests. The method onSetUp is public but not a test method

UnnecessaryParenthesesForMethodCallWithClosure334

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure346

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure360

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure374

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure386

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3100

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3113

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3117

[SRC]input.each() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3133

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3147

[SRC]runTest() {

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.BindDataMethodTests. Parentheses in the 'runTest' method call are unnecessary and can be removed.

➥ DefaultGrailsApplicationAttributesTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper212

[SRC]void setUp() {

[MSG]Violation in class DefaultGrailsApplicationAttributesTests. The method setUp() does not call super.setUp()

➥ FlashScopeWithErrorsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport321

[SRC]import org.springframework.mock.web.MockHttpServletRequest

[MSG]The [org.springframework.mock.web.MockHttpServletRequest] import is never referenced

➥ GrailsHttpSessionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod230

[SRC]void onSetUp() {

[MSG]Violation in class GrailsHttpSessionTests. The method onSetUp is public but not a test method

UnusedVariable242

[SRC]def mock = new MockHttpSession()

[MSG]The variable [mock] in class org.codehaus.groovy.grails.web.servlet.GrailsHttpSessionTests is not used

➥ RenderMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2199

[SRC]def resopnse = mockController.response

[MSG]The variable [resopnse] in class org.codehaus.groovy.grails.web.servlet.RenderMethodTests is not used

UnusedVariable2213

[SRC]def resopnse = mockController.response

[MSG]The variable [resopnse] in class org.codehaus.groovy.grails.web.servlet.RenderMethodTests is not used

JUnitPublicNonTestMethod2291

[SRC]String toString() { foo }

[MSG]Violation in class RenderTest. The method toString is public but not a test method

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.servlet.filter

➥ AbstractServletFilterTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper254

[SRC]void tearDown() {

[MSG]Violation in class AbstractServletFilterTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.servlet.mvc

➥ CommandObjectEnhancementAppliedOnceTests.groovy

Rule NamePriorityLine #Source Line / Message
UseAssertTrueInsteadOfAssertEquals319

[SRC]assert WebMetaUtils.isCommandObjectAction(action) == true

[MSG]The expression '(WebMetaUtils.isCommandObjectAction(action) == true)' can be simplified to 'WebMetaUtils.isCommandObjectAction(action)'

UseAssertTrueInsteadOfAssertEquals323

[SRC]assert WebMetaUtils.isCommandObjectAction(fresh.index) == false

[MSG]The expression '(WebMetaUtils.isCommandObjectAction(fresh.index) == false)' can be simplified to '!WebMetaUtils.isCommandObjectAction(fresh.index)'

➥ ControllerInheritanceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert223

[SRC]void testCallSuperMethod() {

[MSG]Violation in class ControllerInheritanceTests. Test method 'testCallSuperMethod' makes no assertions

➥ ControllersDynamicMethodsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod217

[SRC]void onSetUp() {

[MSG]Violation in class ControllersDynamicMethodsTests. The method onSetUp is public but not a test method

JUnitPublicNonTestMethod228

[SRC]void runTest(Closure callable) {

[MSG]Violation in class ControllersDynamicMethodsTests. The method runTest is public but not a test method

JUnitTestMethodWithoutAssert2135

[SRC]void testRenderMethod() {

[MSG]Violation in class ControllersDynamicMethodsTests. Test method 'testRenderMethod' makes no assertions

UnnecessaryGetter353

[SRC]def appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.servlet.mvc.ControllersDynamicMethodsTests. getApplicationContext() can probably be rewritten as applicationContext

➥ GrailsParameterMapTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2240

[SRC]void testIterateOverMapContainingDate() {

[MSG]Violation in class GrailsParameterMapTests. Test method 'testIterateOverMapContainingDate' makes no assertions

UnusedImport34

[SRC]import grails.util.GrailsWebUtil

[MSG]The [grails.util.GrailsWebUtil] import is never referenced

UnusedImport36

[SRC]import org.springframework.web.context.WebApplicationContext

[MSG]The [org.springframework.web.context.WebApplicationContext] import is never referenced

UnnecessaryPackageReference321

[SRC]final webRequest = grails.util.GrailsWebUtil.bindMockWebRequest(ctx)

[MSG]The grails.util.GrailsWebUtil class was explicitly imported, so specifying the package name is not necessary

UnnecessaryObjectReferences3112

[SRC]map.aList = [1,2]

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3113

[SRC]map.array = ["one", "two" ] as String[]

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3114

[SRC]map.longNumber = 1234567890

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3115

[SRC]map.z = 'z'

[MSG]The code could be more concise by using a with() or identity() block

UseAssertTrueInsteadOfAssertEquals3209

[SRC]assertEquals false, map.boolean('one')

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals3210

[SRC]assertEquals true, map.boolean('nonexistent', Boolean.TRUE)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals3211

[SRC]assertEquals false, map.boolean('nonexistent', Boolean.FALSE)

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UseAssertTrueInsteadOfAssertEquals3212

[SRC]assertEquals true, map.boolean('bool')

[MSG]assertEquals can be simplified using assertTrue or assertFalse

UnnecessaryObjectReferences3262

[SRC]mockRequest.addParameter("a.e.g", "gValue")

[MSG]The code could be more concise by using a with() or identity() block

➥ ParamsObjectTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences324

[SRC]request.addParameter("book.id", "10")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences325

[SRC]request.addParameter("publisher.name", "Apress")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences326

[SRC]request.addParameter("publisher.authors[0].name", "Fred")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences327

[SRC]request.addParameter("publisher.authors[1].name", "Joe")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences328

[SRC]request.addParameter("test..foo..bar", "Stuff")

[MSG]The code could be more concise by using a with() or identity() block

➥ RenderDynamicMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
ConsecutiveStringConcatenation3107

[SRC]render "${'te' + 'xt'}"

[MSG]String concatenation in class org.codehaus.groovy.grails.web.servlet.mvc.RenderDynamicMethodTestController can be joined into the literal 'text'

ConsecutiveStringConcatenation3107

[SRC]render "${'te' + 'xt'}"

[MSG]String concatenation in class org.codehaus.groovy.grails.web.servlet.mvc.RenderDynamicMethodTestController can be joined into the literal 'text'

➥ TagLibDynamicMethodsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod217

[SRC]void onSetUp() {

[MSG]Violation in class TagLibDynamicMethodsTests. The method onSetUp is public but not a test method

ImportFromSamePackage38

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.*

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.sitemesh

➥ FactoryHolderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter236

[SRC]boolean isPathExcluded(String path) { false }

[MSG]Violation in class DummyFactory. Method parameter [path] is never referenced in the method isPathExcluded of class org.codehaus.groovy.grails.web.sitemesh.DummyFactory

UnusedMethodParameter237

[SRC]boolean shouldParsePage(String contentType) { false }

[MSG]Violation in class DummyFactory. Method parameter [contentType] is never referenced in the method shouldParsePage of class org.codehaus.groovy.grails.web.sitemesh.DummyFactory

EmptyMethod239

[SRC]void refresh() {}

[MSG]Violation in class DummyFactory. The method refresh is both empty and not marked with @Override

UnusedMethodParameter240

[SRC]PageParser getPageParser(String contentType) { null }

[MSG]Violation in class DummyFactory. Method parameter [contentType] is never referenced in the method getPageParser of class org.codehaus.groovy.grails.web.sitemesh.DummyFactory

UnnecessaryGetter312

[SRC]assertSame factory, FactoryHolder.getFactory()

[MSG]Violation in class org.codehaus.groovy.grails.web.sitemesh.FactoryHolderTests. getFactory() can probably be rewritten as factory

UnnecessaryGetter318

[SRC]FactoryHolder.getFactory()

[MSG]Violation in class org.codehaus.groovy.grails.web.sitemesh.FactoryHolderTests. getFactory() can probably be rewritten as factory

➥ GSPSitemeshPageTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable215

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable223

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable231

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable239

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable252

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable261

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable279

[SRC]def result = applyTemplate(template, [:], target1)

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable296

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

UnusedVariable2113

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.sitemesh.GSPSitemeshPageTests is not used

JUnitTearDownCallsSuper2125

[SRC]void tearDown() {

[MSG]Violation in class GSPSitemeshPageTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-uber.src.test.groovy.org.codehaus.groovy.grails.web.util

➥ StreamCharBufferGroovyTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper27

[SRC]protected void setUp() {

[MSG]Violation in class StreamCharBufferGroovyTests. The method setUp() does not call super.setUp()

➥ WebUtilsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper222

[SRC]protected void setUp() {

[MSG]Violation in class WebUtilsTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper242

[SRC]protected void tearDown() {

[MSG]Violation in class WebUtilsTests. The method tearDown() does not call super.tearDown()

JUnitPublicNonTestMethod2141

[SRC]void clearGrailsWebRequest() {

[MSG]Violation in class WebUtilsTests. The method clearGrailsWebRequest is public but not a test method

UnnecessaryDefInMethodDeclaration361

[SRC]private def bindMockRequest(DefaultGrailsApplication ga) {

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. The def keyword is unneeded when a method is marked private

UnnecessaryGetter367

[SRC]ctx.registerMockBean(MimeType.BEAN_NAME, factory.getObject())

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getObject() can probably be rewritten as object

UnnecessaryGetter3103

[SRC]assertNull RequestContextHolder.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3123

[SRC]assertNull RequestContextHolder.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3137

[SRC]assertEquals mockWebRequest, RequestContextHolder.getReq..Attributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3154

[SRC]assertNull RequestContextHolder.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3160

[SRC]assertNull RequestContextHolder.getRequestAttributes()

[MSG]Violation in class org.codehaus.groovy.grails.web.util.WebUtilsTests. getRequestAttributes() can probably be rewritten as requestAttributes

Package: grails-test-suite-uber.src.test.resources.org.codehaus.groovy.grails.plugins

➥ ClassEditorGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod25

[SRC]def withSpring() {}

[MSG]Violation in class ClassEditorGrailsPlugin. The method withSpring is both empty and not marked with @Override

EmptyMethod27

[SRC]def withApplicationContext(ctx) {}

[MSG]Violation in class ClassEditorGrailsPlugin. The method withApplicationContext is both empty and not marked with @Override

UnusedMethodParameter27

[SRC]def withApplicationContext(ctx) {}

[MSG]Violation in class ClassEditorGrailsPlugin. Method parameter [ctx] is never referenced in the method withApplicationContext of class ClassEditorGrailsPlugin

Package: grails-test-suite-web.src.test.groovy.grails.test

➥ GrailsUrlMappingsTestCaseTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert263

[SRC]void testSetup() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'testSetup' makes no assertions

JUnitTestMethodWithoutAssert273

[SRC]void testSetupExplicitMappingClass() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'testSetupExplicitMappingClass' makes no assertions

JUnitTestMethodWithoutAssert2176

[SRC]void test_GRAILS_3571_Bug() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'test_GRAILS_3571_Bug' makes no assertions

EmptyCatchBlock2209

[SRC]catch (e) {}

[MSG]The catch block is empty

JUnitTestMethodWithoutAssert2265

[SRC]void testGrails5786() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'testGrails5786' makes no assertions

JUnitTestMethodWithoutAssert2272

[SRC]void testGrails5222() {

[MSG]Violation in class GrailsUrlMappingsTestCaseTests. Test method 'testGrails5222' makes no assertions

JUnitPublicNonTestMethod2353

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class MultipleMappingsTestCase. The method assertView is public but not a test method

UnusedMethodParameter2353

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class MultipleMappingsTestCase. Method parameter [controller] is never referenced in the method assertView of class grails.test.MultipleMappingsTestCase

UnusedMethodParameter2353

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class MultipleMappingsTestCase. Method parameter [view] is never referenced in the method assertView of class grails.test.MultipleMappingsTestCase

UnusedMethodParameter2353

[SRC]def assertView(controller, view, url) {

[MSG]Violation in class MultipleMappingsTestCase. Method parameter [url] is never referenced in the method assertView of class grails.test.MultipleMappingsTestCase

EqualsAndHashCode2396

[SRC]class MockUrlMapping implements UrlMapping {

[MSG]The class grails.test.MockUrlMapping defines equals(Object) but not hashCode()

UnusedMethodParameter2410

[SRC]UrlMappingInfo match(String uri) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [uri] is never referenced in the method match of class grails.test.MockUrlMapping

UnusedMethodParameter2414

[SRC]int compareTo(Object o) { 0 }

[MSG]Violation in class MockUrlMapping. Method parameter [o] is never referenced in the method compareTo of class grails.test.MockUrlMapping

UnusedMethodParameter2416

[SRC]String createURL(Map parameterValues, String encoding) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2416

[SRC]String createURL(Map parameterValues, String encoding) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2418

[SRC]String createURL(Map parameterValues, String encoding, S..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2418

[SRC]String createURL(Map parameterValues, String encoding, S..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2418

[SRC]String createURL(Map parameterValues, String encoding, S..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [fragment] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2420

[SRC]String createURL(String controller, String action, Map p..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [controller] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2420

[SRC]String createURL(String controller, String action, Map p..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [action] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2420

[SRC]String createURL(String controller, String action, Map p..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2420

[SRC]String createURL(String controller, String action, Map p..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2422

[SRC]String createRelativeURL(String controller, String actio..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [controller] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2422

[SRC]String createRelativeURL(String controller, String actio..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [action] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2422

[SRC]String createRelativeURL(String controller, String actio..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2422

[SRC]String createRelativeURL(String controller, String actio..ng) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [controller] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [action] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2424

[SRC]String createRelativeURL(String controller, String actio..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [fragment] is never referenced in the method createRelativeURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [controller] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [action] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [encoding] is never referenced in the method createURL of class grails.test.MockUrlMapping

UnusedMethodParameter2426

[SRC]String createURL(String controller, String action, Map p..nt) { null }

[MSG]Violation in class MockUrlMapping. Method parameter [fragment] is never referenced in the method createURL of class grails.test.MockUrlMapping

EmptyMethod2436

[SRC]void setParameterValues(Map parameterValues) {}

[MSG]Violation in class MockUrlMapping. The method setParameterValues is both empty and not marked with @Override

UnusedMethodParameter2436

[SRC]void setParameterValues(Map parameterValues) {}

[MSG]Violation in class MockUrlMapping. Method parameter [parameterValues] is never referenced in the method setParameterValues of class grails.test.MockUrlMapping

EmptyMethod2438

[SRC]void setParseRequest(boolean shouldParse) {

[MSG]Violation in class MockUrlMapping. The method setParseRequest is both empty and not marked with @Override

UnusedMethodParameter2438

[SRC]void setParseRequest(boolean shouldParse) {

[MSG]Violation in class MockUrlMapping. Method parameter [shouldParse] is never referenced in the method setParseRequest of class grails.test.MockUrlMapping

EmptyMethod2444

[SRC]void setMappingName(String name) {}

[MSG]Violation in class MockUrlMapping. The method setMappingName is both empty and not marked with @Override

UnusedMethodParameter2444

[SRC]void setMappingName(String name) {}

[MSG]Violation in class MockUrlMapping. Method parameter [name] is never referenced in the method setMappingName of class grails.test.MockUrlMapping

UnusedMethodParameter2446

[SRC]boolean hasRuntimeVariable(String name) { false }

[MSG]Violation in class MockUrlMapping. Method parameter [name] is never referenced in the method hasRuntimeVariable of class grails.test.MockUrlMapping

UnnecessaryObjectReferences3224

[SRC]test.assertUrlMapping(500, controller: "grailsUrlMapping..: "action1")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3226

[SRC]test.assertForwardUrlMapping("/controllerView", controll..iew: "view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3235

[SRC]test.assertUrlMapping("/absoluteView", view: "view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3236

[SRC]test.assertUrlMapping("/absoluteView", view: "/view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3237

[SRC]test.assertUrlMapping("/absoluteViewWithSlash", view: "view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3238

[SRC]test.assertUrlMapping("/absoluteViewWithSlash", view: "/view")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3240

[SRC]test.assertUrlMapping("/params/value1/value2", controlle.."action3") {

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3260

[SRC]test.assertUrlMapping("/params/value1", controller: "gra.."action3") {

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-test-suite-web.src.test.groovy.grails.test.mixin

➥ TagLibWithServiceMockTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryConstructor326

[SRC]TimeTagLib() {

[MSG]The constructor can be safely deleted

➥ UrlMappingsTestForTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod223

[SRC]def list() { }

[MSG]Violation in class BookController. The method list is both empty and not marked with @Override

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.plugins.web.filters

➥ FilterConfigTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper227

[SRC]void setUp() {

[MSG]Violation in class FilterConfigTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper2135

[SRC]void tearDown() {

[MSG]Violation in class FilterConfigTests. The method tearDown() does not call super.tearDown()

UseAssertTrueInsteadOfAssertEquals380

[SRC]assert mockDefinition.generateNumberCalled == true

[MSG]The expression '(mockDefinition.generateNumberCalled == true)' can be simplified to 'mockDefinition.generateNumberCalled'

UseAssertTrueInsteadOfAssertEquals385

[SRC]assert mockDefinition.generateNumberCalled == true

[MSG]The expression '(mockDefinition.generateNumberCalled == true)' can be simplified to 'mockDefinition.generateNumberCalled'

UseAssertTrueInsteadOfAssertEquals390

[SRC]assert mockDefinition.generateNumberCalled == true

[MSG]The expression '(mockDefinition.generateNumberCalled == true)' can be simplified to 'mockDefinition.generateNumberCalled'

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.plugins.webflow

➥ MockWebFlowGrailsPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter329

[SRC]def version = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.webflow.MockWebFlowGrailsPlugin. getGrailsVersion() can probably be rewritten as grailsVersion

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.binding

➥ BindingToNullableTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable248

[SRC]def model = controller.update()

[MSG]The variable [model] in class org.codehaus.groovy.grails.web.binding.BindingToNullableTests is not used

UnusedImport34

[SRC]import org.springframework.web.context.request.RequestContextHolder

[MSG]The [org.springframework.web.context.request.RequestContextHolder] import is never referenced

➥ DataBindingLazyMetaPropertyMapTests.groovy

Rule NamePriorityLine #Source Line / Message
CoupledTestCase223

[SRC]def map = new DataBindingLazyMetaPropertyMap(new Propert..er:"stuff"))

[MSG]new PropertyMapTest([name:Bart, age:11, other:stuff]) creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object

➥ DataBindingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2185

[SRC]def error = b.errors.getFieldError('site')

[MSG]The variable [error] in class org.codehaus.groovy.grails.web.binding.DataBindingTests is not used

UnusedVariable2246

[SRC]def authorClass = ga.getDomainClass("databindingtests.Au..).getClazz()

[MSG]The variable [authorClass] in class org.codehaus.groovy.grails.web.binding.DataBindingTests is not used

UnnecessaryGetter3246

[SRC]def authorClass = ga.getDomainClass("databindingtests.Au..).getClazz()

[MSG]Violation in class org.codehaus.groovy.grails.web.binding.DataBindingTests. getClazz() can probably be rewritten as clazz

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.converters

➥ JSONArrayTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter312

[SRC]assertEquals(getJSONArray(), getJSONArray())

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONArrayTests. getJSONArray() can probably be rewritten as JSONArray

UnnecessaryGetter312

[SRC]assertEquals(getJSONArray(), getJSONArray())

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONArrayTests. getJSONArray() can probably be rewritten as JSONArray

UnnecessaryGetter317

[SRC]assertEquals(getJSONArray().hashCode(), getJSONArray().hashCode())

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONArrayTests. getJSONArray() can probably be rewritten as JSONArray

UnnecessaryGetter317

[SRC]assertEquals(getJSONArray().hashCode(), getJSONArray().hashCode())

[MSG]Violation in class org.codehaus.groovy.grails.web.converters.JSONArrayTests. getJSONArray() can probably be rewritten as JSONArray

➥ JSONConverterTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod2100

[SRC]void onSetUp() {

[MSG]Violation in class JSONConverterTests. The method onSetUp is public but not a test method

UnnecessaryPackageReference382

[SRC]enumClass.metaClass.asType = {java.lang.Class clazz ->

[MSG]Specifying the package name is not necessary for java.lang.Class

➥ XMLConverterTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable292

[SRC]def proxy = [getHibernateLazyInitializer:{hibernateIniti..bernateProxy

[MSG]The variable [proxy] in class org.codehaus.groovy.grails.web.converters.XMLConverterTests is not used

JUnitPublicNonTestMethod2106

[SRC]void onSetUp() {

[MSG]Violation in class XMLConverterTests. The method onSetUp is public but not a test method

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.filters

➥ FilterToHandlerAdapterTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitUnnecessarySetUp316

[SRC]protected void setUp() {

[MSG]Violation in class FilterToHandlerAdapterTests. The setUp() method contains no logic and can be removed

UnnecessaryOverridingMethod316

[SRC]protected void setUp() {

[MSG]Violation in class FilterToHandlerAdapterTests. The method setUp contains no logic and can be safely deleted

JUnitUnnecessaryTearDown320

[SRC]protected void tearDown() {

[MSG]Violation in class FilterToHandlerAdapterTests. The tearDown() method contains no logic and can be removed

UnnecessaryOverridingMethod320

[SRC]protected void tearDown() {

[MSG]Violation in class FilterToHandlerAdapterTests. The method tearDown contains no logic and can be safely deleted

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.mapping

➥ DefaultUrlCreatorTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper233

[SRC]void tearDown() {

[MSG]Violation in class DefaultUrlCreatorTests. The method tearDown() does not call super.tearDown()

➥ DoubleWildcardUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport35

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

UnnecessaryGetter372

[SRC]assertEquals 'wrong controller name', 'someOther', info...rollerName()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DoubleWildcardUrlMappingTests. getControllerName() can probably be rewritten as controllerName

➥ DynamicParameterValuesTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport35

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

➥ IdUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod226

[SRC]void onSetUp() {

[MSG]Violation in class IdUrlMappingTests. The method onSetUp is public but not a test method

UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport35

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

➥ RegexUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2357

[SRC]void testInit() {

[MSG]Violation in class RegexUrlMappingTests. Test method 'testInit' makes no assertions

UnusedVariable2359

[SRC]def m = new RegexUrlMapping(parser.parse("/(*)/hello"), ..vletContext)

[MSG]The variable [m] in class org.codehaus.groovy.grails.web.mapping.RegexUrlMappingTests is not used

UnusedImport36

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

UnnecessaryGetter372

[SRC]assertEquals "/x/y", info.getURI()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.RegexUrlMappingTests. getURI() can probably be rewritten as URI

UnnecessaryDotClass3308

[SRC]def cp = new ConstrainedProperty(RegexUrlMappingTests.cl..tring.class)

[MSG]RegexUrlMappingTests.class can be rewritten as RegexUrlMappingTests

UnnecessaryDotClass3308

[SRC]def cp = new ConstrainedProperty(RegexUrlMappingTests.cl..tring.class)

[MSG]String.class can be rewritten as String

UnnecessaryDotClass3325

[SRC]def cp = new ConstrainedProperty(RegexUrlMappingTests.cl..tring.class)

[MSG]RegexUrlMappingTests.class can be rewritten as RegexUrlMappingTests

UnnecessaryDotClass3325

[SRC]def cp = new ConstrainedProperty(RegexUrlMappingTests.cl..tring.class)

[MSG]String.class can be rewritten as String

➥ ResponseCodeUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport36

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport38

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

UnnecessaryDefInFieldDeclaration322

[SRC]def UrlMappingsHolder holder

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. The def keyword is unneeded when a field type is specified

UnnecessaryGetter359

[SRC]assertEquals("errors", info.getControllerName());

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. getControllerName() can probably be rewritten as controllerName

UnnecessaryGetter360

[SRC]assertEquals("error404", info.getActionName());

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. getActionName() can probably be rewritten as actionName

UnnecessaryGetter366

[SRC]assertEquals("errors", info.getControllerName());

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. getControllerName() can probably be rewritten as controllerName

UnnecessaryGetter367

[SRC]assertEquals("error500", info.getActionName());

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ResponseCodeUrlMappingTests. getActionName() can probably be rewritten as actionName

➥ RestfulMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.validation.ConstrainedProperty;

[MSG]The [org.codehaus.groovy.grails.validation.ConstrainedProperty] import is never referenced

UnusedImport36

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

➥ RestfulReverseUrlRenderingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

➥ ReverseMappingWithDefaultActionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod211

[SRC]void onSetUp() {

[MSG]Violation in class ReverseMappingWithDefaultActionTests. The method onSetUp is public but not a test method

➥ UrlMappingParameterTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.Abstra..trollerTests

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.AbstractGrailsControllerTests] import is never referenced

UnusedImport34

[SRC]import org.springframework.core.io.ByteArrayResource

[MSG]The [org.springframework.core.io.ByteArrayResource] import is never referenced

UnusedImport35

[SRC]import org.springframework.mock.web.MockServletContext

[MSG]The [org.springframework.mock.web.MockServletContext] import is never referenced

➥ UrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.validation.ConstrainedProperty;

[MSG]The [org.codehaus.groovy.grails.validation.ConstrainedProperty] import is never referenced

➥ UrlMappingWithCustomValidatorTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInFieldDeclaration321

[SRC]def UrlMappingsHolder holder

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.UrlMappingWithCustomValidatorTests. The def keyword is unneeded when a field type is specified

➥ UrlMappingsHolderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.validation.ConstrainedProperty;

[MSG]The [org.codehaus.groovy.grails.validation.ConstrainedProperty] import is never referenced

➥ ViewUrlMappingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInFieldDeclaration320

[SRC]def UrlMappingsHolder holder

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ViewUrlMappingTests. The def keyword is unneeded when a field type is specified

UnnecessaryGetter340

[SRC]assertEquals "book.gsp", info.getViewName()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ViewUrlMappingTests. getViewName() can probably be rewritten as viewName

UnnecessaryGetter347

[SRC]assertEquals "book.gsp", info.getViewName()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.ViewUrlMappingTests. getViewName() can probably be rewritten as viewName

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.mapping.filter

➥ RestfulMappingsFilterTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport37

[SRC]import org.codehaus.groovy.grails.commons.ControllerArtefactHandler;

[MSG]The [org.codehaus.groovy.grails.commons.ControllerArtefactHandler] import is never referenced

UnusedImport38

[SRC]import org.codehaus.groovy.grails.commons.DefaultGrailsApplication

[MSG]The [org.codehaus.groovy.grails.commons.DefaultGrailsApplication] import is never referenced

UnnecessaryGetter352

[SRC]def mappings = evaluator.evaluateMappings(new ByteArrayR..getBytes()))

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.filter.RestfulMappingsFilterTests. getBytes() can probably be rewritten as bytes

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.mime

➥ AcceptHeaderParserTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper213

[SRC]protected void setUp() {

[MSG]Violation in class AcceptHeaderParserTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper230

[SRC]protected void tearDown() {

[MSG]Violation in class AcceptHeaderParserTests. The method tearDown() does not call super.tearDown()

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.pages

➥ GroovyPageBindingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter315

[SRC]assertEquals binding.getMetaClass(), binding.metaClass

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageBindingTests. getMetaClass() can probably be rewritten as metaClass

UnnecessaryGetter326

[SRC]assertEquals(shouldbe, binding.getVariables())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageBindingTests. getVariables() can probably be rewritten as variables

UnnecessaryGetter328

[SRC]for(e in binding.getVariables().entrySet()) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageBindingTests. getVariables() can probably be rewritten as variables

➥ GroovyPageLineNumberTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert214

[SRC]void testSpanningMultipleLines() {

[MSG]Violation in class GroovyPageLineNumberTests. Test method 'testSpanningMultipleLines' makes no assertions

➥ GroovyPageMethodDispatchWithNamespaceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod28

[SRC]void onSetUp() {

[MSG]Violation in class GroovyPageMethodDispatchWithNamespaceTests. The method onSetUp is public but not a test method

➥ GroovyPageTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod267

[SRC]def runPageCode(pageCode) {

[MSG]Violation in class GroovyPageTests. The method runPageCode is public but not a test method

JUnitPublicNonTestMethod2146

[SRC]def getBinding(out) {

[MSG]Violation in class GroovyPageTests. The method getBinding is public but not a test method

UnnecessaryGetter3157

[SRC]binding.setVariable(GroovyPage.SESSION, request.getSession())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageTests. getSession() can probably be rewritten as session

UnnecessaryObjectReferences3160

[SRC]binding.setVariable(GroovyPage.OUT, out)

[MSG]The code could be more concise by using a with() or identity() block

➥ GroovyPagesTemplateEngineTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable2188

[SRC]def webRequest = GrailsWebUtil.bindMockWebRequest()

[MSG]The variable [webRequest] in class org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngineTests is not used

JUnitTearDownCallsSuper2570

[SRC]void tearDown() {

[MSG]Violation in class GroovyPagesTemplateEngineTests. The method tearDown() does not call super.tearDown()

JUnitSetUpCallsSuper2574

[SRC]void setUp() {

[MSG]Violation in class GroovyPagesTemplateEngineTests. The method setUp() does not call super.setUp()

UnusedImport38

[SRC]import org.codehaus.groovy.grails.plugins.MockGrailsPluginManager;

[MSG]The [org.codehaus.groovy.grails.plugins.MockGrailsPluginManager] import is never referenced

UseAssertEqualsInsteadOfAssertTrue340

[SRC]assertTrue(sw.toString().indexOf("should not be in the output") == -1)

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngineTests. Replace assertTrue with a call to assertEquals()

➥ GroovyPagesWhitespaceParsingTagTests.groovy

Rule NamePriorityLine #Source Line / Message
ComparisonOfTwoConstants229

[SRC]test="${2 > 1}">rejoice</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants236

[SRC]<g:if test="${2 > 1}">rejoice</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants246

[SRC]<g:if test="${2 > 1}">testing</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants259

[SRC]<g:if test="${2 > 1}">testing</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants271

[SRC]def template = """Hello <g:if test="${2 > 1}">one</g:if>..ee</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants271

[SRC]def template = """Hello <g:if test="${2 > 1}">one</g:if>..ee</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants271

[SRC]def template = """Hello <g:if test="${2 > 1}">one</g:if>..ee</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants277

[SRC]def template = """Hello <g:if test="${2 > 1}">one</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants278

[SRC]<g:if test="${2 > 1}">two</g:if>

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

ComparisonOfTwoConstants279

[SRC]<g:if test="${2 > 1}">three</g:if>"""

[MSG]Comparing two constants or constant literals is useless and may indicate a bug: (2 > 1)

➥ ModifyOurScopeWithBodyTagTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport35

[SRC]import junit.framework.TestCase

[MSG]The [junit.framework.TestCase] import is never referenced

➥ StaticContentRenderingTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport34

[SRC]import org.codehaus.groovy.grails.commons.ConfigurationHolder

[MSG]The [org.codehaus.groovy.grails.commons.ConfigurationHolder] import is never referenced

➥ TagLibNamespaceTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod222

[SRC]void onTearDown() {

[MSG]Violation in class TagLibNamespaceTests. The method onTearDown is public but not a test method

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.pages.ext.jsp

➥ GroovyPageWithJSPTagsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter322

[SRC]def rootLoader = new RootLoader([] as URL[], Thread.curr..assLoader())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPageWithJSPTagsTests. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter324

[SRC]rootLoader.addURL res.getURL()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPageWithJSPTagsTests. getURL() can probably be rewritten as URL

UnnecessaryGetter326

[SRC]rootLoader.addURL it.getURL()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPageWithJSPTagsTests. getURL() can probably be rewritten as URL

UnnecessaryGetter330

[SRC]webRequest.getCurrentRequest().setAttribute(GroovyPagesS..esServlet())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPageWithJSPTagsTests. getCurrentRequest() can probably be rewritten as currentRequest

➥ GroovyPagesPageContextTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper213

[SRC]protected void setUp() {

[MSG]Violation in class GroovyPagesPageContextTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper217

[SRC]protected void tearDown() {

[MSG]Violation in class GroovyPagesPageContextTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter325

[SRC]assert pageContext.getServletConfig()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getServletConfig() can probably be rewritten as servletConfig

UnnecessaryGetter326

[SRC]assert pageContext.getServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter327

[SRC]assert pageContext.getRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getRequest() can probably be rewritten as request

UnnecessaryGetter328

[SRC]assert pageContext.getResponse()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getResponse() can probably be rewritten as response

UnnecessaryGetter329

[SRC]assert pageContext.getPage()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContextTests. getPage() can probably be rewritten as page

➥ IterativeJspTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper221

[SRC]protected void setUp() {

[MSG]Violation in class IterativeJspTagTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper226

[SRC]protected void tearDown() {

[MSG]Violation in class IterativeJspTagTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter323

[SRC]webRequest.getCurrentRequest().setAttribute(GroovyPagesS..esServlet())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter334

[SRC]def rootLoader = new RootLoader([] as URL[], Thread.curr..assLoader())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter336

[SRC]rootLoader.addURL res.getURL()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getURL() can probably be rewritten as URL

UnnecessaryGetter352

[SRC]JstlUtils.exposeLocalizationContext webRequest.getRequest(),null

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getRequest() can probably be rewritten as request

UnnecessaryGetter355

[SRC]def pageContext = PageContextFactory.getCurrent()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.IterativeJspTagTests. getCurrent() can probably be rewritten as current

➥ MockRootLoaderTagLibraryResolver.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter315

[SRC]def rootLoader = new RootLoader([] as URL[], Thread.curr..assLoader())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockRootLoaderTagLibraryResolver. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter317

[SRC]rootLoader.addURL res.getURL()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockRootLoaderTagLibraryResolver. getURL() can probably be rewritten as URL

➥ SimpleJspTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper222

[SRC]protected void setUp() {

[MSG]Violation in class SimpleJspTagTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper227

[SRC]protected void tearDown() {

[MSG]Violation in class SimpleJspTagTests. The method tearDown() does not call super.tearDown()

UnusedImport39

[SRC]import org.springframework.core.io.FileSystemResource

[MSG]The [org.springframework.core.io.FileSystemResource] import is never referenced

UnnecessaryGetter324

[SRC]webRequest.getCurrentRequest().setAttribute(GroovyPagesS..esServlet())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.SimpleJspTagTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter347

[SRC]JstlUtils.exposeLocalizationContext webRequest.getRequest(),null

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.SimpleJspTagTests. getRequest() can probably be rewritten as request

➥ SimpleTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper221

[SRC]protected void setUp() {

[MSG]Violation in class SimpleTagTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper226

[SRC]protected void tearDown() {

[MSG]Violation in class SimpleTagTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter323

[SRC]webRequest.getCurrentRequest().setAttribute(GroovyPagesS..esServlet())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.SimpleTagTests. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter361

[SRC]getJspContext().getOut().println("extendsSimpleTagSupport:output");

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.ExtendsSimpleTagSupport. getOut() can probably be rewritten as out

UnnecessaryGetter361

[SRC]getJspContext().getOut().println("extendsSimpleTagSupport:output");

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.ExtendsSimpleTagSupport. getJspContext() can probably be rewritten as jspContext

UnnecessaryGetter368

[SRC]JspWriter out = getJspContext().getOut()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.BodySimpleTagSupport. getOut() can probably be rewritten as out

UnnecessaryGetter368

[SRC]JspWriter out = getJspContext().getOut()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.BodySimpleTagSupport. getJspContext() can probably be rewritten as jspContext

UnnecessaryGetter370

[SRC]super.getJspBody().invoke(out)

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.BodySimpleTagSupport. getJspBody() can probably be rewritten as jspBody

➥ TagLibraryResolverTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter365

[SRC]new RootLoader([] as URL[], Thread.currentThread().getCo..assLoader())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockWebXmlTagLibraryResolver. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter372

[SRC]new ByteArrayResource('''<?xml version="1.0" encoding="UTF-8"?>

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockWebXmlTagLibraryResolver. getInputStream() can probably be rewritten as inputStream

UnnecessaryGetter372

[SRC]new ByteArrayResource('''<?xml version="1.0" encoding="UTF-8"?>

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockWebXmlTagLibraryResolver. getBytes() can probably be rewritten as bytes

UnnecessaryGetter3118

[SRC]new ByteArrayResource('''<?xml version="1.0" encoding="UTF-8"?>

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.MockWebXmlTagLibraryResolver. getBytes() can probably be rewritten as bytes

➥ TldReaderTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter328

[SRC]def is = new InputSource(res.getInputStream())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReaderTests. getInputStream() can probably be rewritten as inputStream

UnnecessaryGetter333

[SRC]def reader = factory.newSAXParser().getXMLReader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReaderTests. getXMLReader() can probably be rewritten as XMLReader

➥ WebXmlTagLibraryReaderTests.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSamePackage320

[SRC]import org.codehaus.groovy.grails.web.pages.ext.jsp.WebX..ibraryReader

UnnecessaryGetter331

[SRC]def reader = factory.newSAXParser().getXMLReader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReaderTests. getXMLReader() can probably be rewritten as XMLReader

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.servlet.view

➥ GroovyPageViewTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTearDownCallsSuper245

[SRC]void tearDown() {

[MSG]Violation in class GroovyPageViewTests. The method tearDown() does not call super.tearDown()

DuplicateImport37

[SRC]import org.springframework.web.context.request.*

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.web.taglib

➥ ApplicationTagLibResourcesTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod221

[SRC]void onInitMockBeans() {

[MSG]Violation in class ApplicationTagLibResourcesTests. The method onInitMockBeans is public but not a test method

JUnitPublicNonTestMethod225

[SRC]def replaceMetaClass(Object o) {

[MSG]Violation in class ApplicationTagLibResourcesTests. The method replaceMetaClass is public but not a test method

UnusedImport33

[SRC]import grails.util.GrailsUtil

[MSG]The [grails.util.GrailsUtil] import is never referenced

UnusedImport35

[SRC]import javax.servlet.http.Cookie

[MSG]The [javax.servlet.http.Cookie] import is never referenced

UnusedImport37

[SRC]import groovy.mock.interceptor.StubFor

[MSG]The [groovy.mock.interceptor.StubFor] import is never referenced

UnusedImport39

[SRC]import org.codehaus.groovy.grails.commons.ConfigurationHolder

[MSG]The [org.codehaus.groovy.grails.commons.ConfigurationHolder] import is never referenced

UnusedImport311

[SRC]import org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib;

[MSG]The [org.codehaus.groovy.grails.plugins.web.taglib.JavascriptTagLib] import is never referenced

UnusedImport312

[SRC]import org.codehaus.groovy.grails.web.pages.GroovyPageBinding

[MSG]The [org.codehaus.groovy.grails.web.pages.GroovyPageBinding] import is never referenced

UnusedImport313

[SRC]import org.codehaus.groovy.grails.web.servlet.GrailsAppl..onAttributes

[MSG]The [org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes] import is never referenced

UnusedImport314

[SRC]import org.codehaus.groovy.grails.web.taglib.exceptions...TagException

[MSG]The [org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException] import is never referenced

UnusedImport316

[SRC]import org.codehaus.groovy.grails.commons.TagLibArtefactHandler

[MSG]The [org.codehaus.groovy.grails.commons.TagLibArtefactHandler] import is never referenced

UnusedImport317

[SRC]import org.springframework.mock.web.MockHttpServletResponse

[MSG]The [org.springframework.mock.web.MockHttpServletResponse] import is never referenced

UnnecessaryDotClass340

[SRC]def taglib = appCtx.getBean(ApplicationTagLib.class.name)

[MSG]ApplicationTagLib.class can be rewritten as ApplicationTagLib

UnnecessaryDotClass360

[SRC]def taglib = appCtx.getBean(ApplicationTagLib.class.name)

[MSG]ApplicationTagLib.class can be rewritten as ApplicationTagLib

➥ ApplicationTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport37

[SRC]import groovy.mock.interceptor.StubFor

[MSG]The [groovy.mock.interceptor.StubFor] import is never referenced

UnusedImport315

[SRC]import org.codehaus.groovy.grails.commons.TagLibArtefactHandler

[MSG]The [org.codehaus.groovy.grails.commons.TagLibArtefactHandler] import is never referenced

UnnecessaryGetter323

[SRC]assertOutputEquals "/test/plugins/controllers-${GrailsUt..g", template

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.ApplicationTagLibTests. getGrailsVersion() can probably be rewritten as grailsVersion

➥ CoreTagsTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import grails.util.GrailsUtil

[MSG]The [grails.util.GrailsUtil] import is never referenced

➥ CountryTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod288

[SRC]void assertResultContains(result, expectedSubstring) {

[MSG]Violation in class CountryTagLibTests. The method assertResultContains is public but not a test method

➥ FormRenderingTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod226

[SRC]void assertOutputEquals(expected, template, params = [:]) {

[MSG]Violation in class FormRenderingTagLibTests. The method assertOutputEquals is public but not a test method

➥ FormTagLib2Tests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField216

[SRC]private static final def SELECT_TAG_NAME = "testSelect"

[MSG]The field SELECT_TAG_NAME is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests

JUnitTestMethodWithoutAssert223

[SRC]void testDatePickerTagWithDefaultDateAndPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithDefaultDateAndPrecision' makes no assertions

JUnitTestMethodWithoutAssert227

[SRC]void testDatePickerTagWithYearPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithYearPrecision' makes no assertions

JUnitTestMethodWithoutAssert231

[SRC]void testDatePickerTagWithMonthPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithMonthPrecision' makes no assertions

JUnitTestMethodWithoutAssert235

[SRC]void testDatePickerTagWithDayPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithDayPrecision' makes no assertions

JUnitTestMethodWithoutAssert239

[SRC]void testDatePickerTagWithHourPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithHourPrecision' makes no assertions

JUnitTestMethodWithoutAssert243

[SRC]void testDatePickerTagWithMinutePrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithMinutePrecision' makes no assertions

JUnitTestMethodWithoutAssert247

[SRC]void testDatePickerTagWithCustomDate() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithCustomDate' makes no assertions

JUnitTestMethodWithoutAssert274

[SRC]void testDatePickerTagWithCustomDateAndPrecision() {

[MSG]Violation in class FormTagLib2Tests. Test method 'testDatePickerTagWithCustomDateAndPrecision' makes no assertions

UnusedVariable2121

[SRC]String xp

[MSG]The variable [xp] in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests is not used

UnusedPrivateMethod2230

[SRC]private void assertSelectFieldPresentWithValue(Document ..ing value) {

[MSG]The method assertSelectFieldPresentWithValue is not used within FormTagLib2Tests.groovy

UnusedPrivateMethod2236

[SRC]private void assertSelectFieldPresentWithValueAndText(Do..ing label) {

[MSG]The method assertSelectFieldPresentWithValueAndText is not used within FormTagLib2Tests.groovy

UnusedPrivateMethod2248

[SRC]private void assertSelectPresent(Document document, Stri..fieldName) {

[MSG]The method assertSelectPresent is not used within FormTagLib2Tests.groovy

UnnecessaryDefInFieldDeclaration316

[SRC]private static final def SELECT_TAG_NAME = "testSelect"

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests. The def keyword is unneeded when a field is marked private

UnnecessaryGetter352

[SRC]def defaultDate = Calendar.getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests. getInstance() can probably be rewritten as instance

UnnecessaryGetter354

[SRC]Document document = getDatePickerOutput(null, 'day', def..e.getTime())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests. getTime() can probably be rewritten as time

UnnecessaryGetter369

[SRC]DateFormat defaultFormat = DateFormat.getInstance()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib2Tests. getInstance() can probably be rewritten as instance

➥ FormTagLib3Tests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField217

[SRC]private static final String DATE_PICKER_TAG_NAME = "testDatePicker"

[MSG]The field DATE_PICKER_TAG_NAME is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnusedPrivateField219

[SRC]private static final Collection DATE_PRECISIONS_INCLUDIN..s String[]))

[MSG]The field DATE_PRECISIONS_INCLUDING_MINUTE is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnusedPrivateField220

[SRC]private static final Collection DATE_PRECISIONS_INCLUDIN..s String[]))

[MSG]The field DATE_PRECISIONS_INCLUDING_HOUR is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnusedPrivateField221

[SRC]private static final Collection DATE_PRECISIONS_INCLUDIN..s String[]))

[MSG]The field DATE_PRECISIONS_INCLUDING_DAY is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnusedPrivateField222

[SRC]private static final Collection DATE_PRECISIONS_INCLUDIN..s String[]))

[MSG]The field DATE_PRECISIONS_INCLUDING_MONTH is not used within the class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests

UnnecessaryGetter3207

[SRC]final Element inputElement = document.getDocumentElement()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests. getDocumentElement() can probably be rewritten as documentElement

UnnecessaryGetter3233

[SRC]final Element inputElement = document.getDocumentElement()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests. getDocumentElement() can probably be rewritten as documentElement

UnnecessaryGetter3262

[SRC]final Element inputElement = document.getDocumentElement()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests. getDocumentElement() can probably be rewritten as documentElement

UnnecessaryGetter3288

[SRC]final Element inputElement = document.getDocumentElement()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormTagLib3Tests. getDocumentElement() can probably be rewritten as documentElement

➥ FormTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2234

[SRC]void testBooleanAttributes() {

[MSG]Violation in class FormTagLibTests. Test method 'testBooleanAttributes' makes no assertions

➥ FormatTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter332

[SRC]assertOutputEquals("1980-02-03", template, [date:calender.getTime()])

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormatTagLibTests. getTime() can probably be rewritten as time

UnnecessaryGetter338

[SRC]assertOutputEquals("February 3, 1980", template, [date:c...getTime()])

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormatTagLibTests. getTime() can probably be rewritten as time

UnnecessaryGetter344

[SRC]assertOutputEquals("February 3, 1980 12:00 AM", template...getTime()])

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormatTagLibTests. getTime() can probably be rewritten as time

UnnecessaryGetter379

[SRC]assertOutputEquals("1980-02-03", template, [date:calender.getTime()])

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.FormatTagLibTests. getTime() can probably be rewritten as time

➥ GroovyEachTagTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport33

[SRC]import org.codehaus.groovy.grails.web.taglib.exceptions...TagException

[MSG]The [org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException] import is never referenced

UnnecessaryGetter321

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyEachTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter321

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyEachTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter337

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyEachTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter337

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyEachTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

➥ GroovyFindAllTagTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGroovyImport33

[SRC]import java.io.ByteArrayInputStream

UnnecessaryGroovyImport34

[SRC]import java.io.PrintWriter

UnnecessaryGroovyImport35

[SRC]import java.util.HashMap

UnnecessaryGroovyImport36

[SRC]import java.util.Map

UnnecessaryDotClass325

[SRC]context.put(GroovyPageParser.class, parser);

[MSG]GroovyPageParser.class can be rewritten as GroovyPageParser

UnnecessaryGetter355

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in eval...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyFindAllTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter355

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in eval...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyFindAllTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter364

[SRC]assertEquals("findAll", tag.getName())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyFindAllTagTests. getName() can probably be rewritten as name

➥ GroovyGrepTagTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock215

[SRC]catch(Exception e) {

[MSG]The catch block is empty

UnnecessaryGetter323

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyGrepTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

UnnecessaryGetter323

[SRC]assertEquals("for( "+tag.getForeachRenamedIt()+" in test...toString())

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.GroovyGrepTagTests. getForeachRenamedIt() can probably be rewritten as foreachRenamedIt

➥ GroovySyntaxTagTests.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod256

[SRC]void doEndTag() {}

[MSG]Violation in class MyGroovySyntaxTag. The method doEndTag is both empty and not marked with @Override

EmptyMethod258

[SRC]void doStartTag() {}

[MSG]Violation in class MyGroovySyntaxTag. The method doStartTag is both empty and not marked with @Override

➥ InvokeTagLibAsMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod25

[SRC]void onSetUp() {

[MSG]Violation in class InvokeTagLibAsMethodTests. The method onSetUp is public but not a test method

➥ JavascriptTagLibResourcesTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod27

[SRC]def replaceMetaClass(o) {

[MSG]Violation in class JavascriptTagLibResourcesTests. The method replaceMetaClass is public but not a test method

JUnitPublicNonTestMethod218

[SRC]void onInitMockBeans() {

[MSG]Violation in class JavascriptTagLibResourcesTests. The method onInitMockBeans is public but not a test method

UnusedVariable272

[SRC]def result = applyTemplate(template, [:])

[MSG]The variable [result] in class org.codehaus.groovy.grails.web.taglib.JavascriptTagLibResourcesTests is not used

➥ JavascriptTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable246

[SRC]String newLine = EOL

[MSG]The variable [newLine] in class org.codehaus.groovy.grails.web.taglib.JavascriptTagLibTests is not used

JUnitPublicNonTestMethod293

[SRC]def replaceMetaClass(Object o) {

[MSG]Violation in class JavascriptTagLibTests. The method replaceMetaClass is public but not a test method

JUnitPublicNonTestMethod2287

[SRC]def setRequestContext() {

[MSG]Violation in class JavascriptTagLibTests. The method setRequestContext is public but not a test method

JUnitPublicNonTestMethod2291

[SRC]def setRequestContext(path) {

[MSG]Violation in class JavascriptTagLibTests. The method setRequestContext is public but not a test method

JUnitPublicNonTestMethod2295

[SRC]def setupPluginController(tag) {

[MSG]Violation in class JavascriptTagLibTests. The method setupPluginController is public but not a test method

UnusedMethodParameter2295

[SRC]def setupPluginController(tag) {

[MSG]Violation in class JavascriptTagLibTests. Method parameter [tag] is never referenced in the method setupPluginController of class org.codehaus.groovy.grails.web.taglib.JavascriptTagLibTests

UnusedMethodParameter2312

[SRC]def doRemoteFunction(Object taglib, Object attrs, Object out) {

[MSG]Violation in class TestProvider. Method parameter [taglib] is never referenced in the method doRemoteFunction of class org.codehaus.groovy.grails.web.taglib.TestProvider

UnusedMethodParameter2312

[SRC]def doRemoteFunction(Object taglib, Object attrs, Object out) {

[MSG]Violation in class TestProvider. Method parameter [attrs] is never referenced in the method doRemoteFunction of class org.codehaus.groovy.grails.web.taglib.TestProvider

EmptyMethod2316

[SRC]def prepareAjaxForm(Object attrs) {}

[MSG]Violation in class TestProvider. The method prepareAjaxForm is both empty and not marked with @Override

UnusedMethodParameter2316

[SRC]def prepareAjaxForm(Object attrs) {}

[MSG]Violation in class TestProvider. Method parameter [attrs] is never referenced in the method prepareAjaxForm of class org.codehaus.groovy.grails.web.taglib.TestProvider

UnusedImport313

[SRC]import org.codehaus.groovy.grails.commons.TagLibArtefactHandler

[MSG]The [org.codehaus.groovy.grails.commons.TagLibArtefactHandler] import is never referenced

UnnecessaryGetter352

[SRC]def grailsVersion = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.JavascriptTagLibTests. getGrailsVersion() can probably be rewritten as grailsVersion

➥ LayoutWriterStackTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod245

[SRC]void assertEqualsIgnoreWhiteSpace(String s1, String s2) {

[MSG]Violation in class LayoutWriterStackTests. The method assertEqualsIgnoreWhiteSpace is public but not a test method

➥ LinkRenderingTagLib2Tests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod238

[SRC]void assertOutputEquals(expected, template, params = [:]) {

[MSG]Violation in class LinkRenderingTagLib2Tests. The method assertOutputEquals is public but not a test method

UnusedImport33

[SRC]import org.codehaus.groovy.runtime.InvokerHelper

[MSG]The [org.codehaus.groovy.runtime.InvokerHelper] import is never referenced

➥ LinkRenderingTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
DuplicateMapKey246

[SRC]assertOutputEquals '<a href="/demo" class="B">demo</a>',..'7', x: '4']

[MSG]Key 'x' is duplicated.

UnusedImport33

[SRC]import org.codehaus.groovy.runtime.InvokerHelper

[MSG]The [org.codehaus.groovy.runtime.InvokerHelper] import is never referenced

➥ NamespacedTagLibMethodTests.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport34

[SRC]import org.springframework.validation.MapBindingResult

[MSG]The [org.springframework.validation.MapBindingResult] import is never referenced

➥ PluginTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter313

[SRC]def grailsVersion = GrailsUtil.getGrailsVersion()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.PluginTagLibTests. getGrailsVersion() can probably be rewritten as grailsVersion

➥ PropertyEditorTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall384

[SRC]assertEquals(["grails", "groovy"], obj.tags.collect {it.name})

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.PropertyEditorTests. The call to collect could probably be rewritten as a spread expression: obj.tags*.name

UnnecessaryGetter3119

[SRC]Object v = getValue()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.TestCustomPropertyEditor. getValue() can probably be rewritten as value

➥ RenderTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert241

[SRC]void testPaginateTag() {

[MSG]Violation in class RenderTagLibTests. Test method 'testPaginateTag' makes no assertions

UnusedVariable2103

[SRC]def head = ""

[MSG]The variable [head] in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests is not used

JUnitTestMethodWithoutAssert2205

[SRC]void testSortableColumnTag() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTag' makes no assertions

JUnitTestMethodWithoutAssert2219

[SRC]void testSortableColumnTagWithTitleKey() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagWithTitleKey' makes no assertions

JUnitTestMethodWithoutAssert2265

[SRC]void testSortableColumnTagWithAction() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagWithAction' makes no assertions

JUnitTestMethodWithoutAssert2279

[SRC]void testSortableColumnTagWithDefaultOrder() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagWithDefaultOrder' makes no assertions

JUnitTestMethodWithoutAssert2323

[SRC]void testSortableColumnTagWithAdditionalAttributes() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagWithAdditionalAttributes' makes no assertions

JUnitTestMethodWithoutAssert2338

[SRC]void testSortableColumnTagSorted() {

[MSG]Violation in class RenderTagLibTests. Test method 'testSortableColumnTagSorted' makes no assertions

JUnitPublicNonTestMethod2422

[SRC]void checkTagOutput(output, expectedClassValue, expected..edContent) {

[MSG]Violation in class RenderTagLibTests. The method checkTagOutput is public but not a test method

JUnitPublicNonTestMethod2463

[SRC]void checkTagOutput(output, expectedClassValue, expected..therAttrs) {

[MSG]Violation in class RenderTagLibTests. The method checkTagOutput is public but not a test method

UnnecessaryGetter3347

[SRC]webRequest.getParams().put("sort", "title")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3348

[SRC]webRequest.getParams().put("order", "asc")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3364

[SRC]webRequest.getParams().put("sort", "title")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3365

[SRC]webRequest.getParams().put("order", "desc")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3381

[SRC]webRequest.getParams().put("sort", "price")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3382

[SRC]webRequest.getParams().put("order", "desc")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3398

[SRC]webRequest.getParams().put("sort", "price")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3399

[SRC]webRequest.getParams().put("order", "desc")

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getParams() can probably be rewritten as params

UnnecessaryGetter3553

[SRC]assertEquals 'my/contenttype', response.getContentType()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getContentType() can probably be rewritten as contentType

UseAssertNullInsteadOfAssertEquals3557

[SRC]assertEquals null, response.getContentType()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. assertEquals can be simplified using assertNull

UnnecessaryGetter3557

[SRC]assertEquals null, response.getContentType()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getContentType() can probably be rewritten as contentType

UnnecessaryGetter3560

[SRC]assertEquals 'my/contenttype', response.getContentType()

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.RenderTagLibTests. getContentType() can probably be rewritten as contentType

➥ ReturnValueTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod24

[SRC]void onSetUp() {

[MSG]Violation in class ReturnValueTagLibTests. The method onSetUp is public but not a test method

➥ SelectTagTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitTestMethodWithoutAssert2255

[SRC]void testMultipleSelect() {

[MSG]Violation in class SelectTagTests. Test method 'testMultipleSelect' makes no assertions

JUnitTestMethodWithoutAssert2267

[SRC]void testMultipleSelectWithObjectValues() {

[MSG]Violation in class SelectTagTests. Test method 'testMultipleSelectWithObjectValues' makes no assertions

JUnitPublicNonTestMethod2281

[SRC]void checkMultiSelect(List categories, List selected, Cl..sSelected) {

[MSG]Violation in class SelectTagTests. The method checkMultiSelect is public but not a test method

UnusedPrivateMethod2370

[SRC]private void assertSelectFieldNotPresent(Document docume..fieldName) {

[MSG]The method assertSelectFieldNotPresent is not used within SelectTagTests.groovy

UnnecessaryParenthesesForMethodCallWithClosure3136

[SRC]range.each() {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3154

[SRC]range.each() {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3201

[SRC]range.each() {

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3227

[SRC]categoryMap.each() { value, text ->

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3233

[SRC]categoryMap.each() { value, text ->

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3250

[SRC]categoryMap.each() { value, text ->

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3306

[SRC]categories.each() { cat ->

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.SelectTagTests. Parentheses in the 'each' method call are unnecessary and can be removed.

➥ ValidationTagLibTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences3214

[SRC]b.publisherURL = new URL("http://canoo.com/gia")

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3215

[SRC]b.releaseDate = new Date()

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3216

[SRC]b.usPrice = 10.99

[MSG]The code could be more concise by using a with() or identity() block

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.webflow

➥ FlowCommandObjectsTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod287

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowCommandObjectsTests. The method getFlowClosure is public but not a test method

UnusedImport34

[SRC]import org.springframework.webflow.definition.FlowDefinition

[MSG]The [org.springframework.webflow.definition.FlowDefinition] import is never referenced

UnusedImport35

[SRC]import org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder

[MSG]The [org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder] import is never referenced

UnusedImport36

[SRC]import org.springframework.webflow.context.servlet.Servl..ernalContext

[MSG]The [org.springframework.webflow.context.servlet.ServletExternalContext] import is never referenced

UnnecessaryGetter323

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowCommandObjectsTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter351

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowCommandObjectsTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter374

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowCommandObjectsTests. getFlowScope() can probably be rewritten as flowScope

➥ FlowRedirectTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod252

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowRedirectTests. The method getFlowClosure is public but not a test method

UnusedImport310

[SRC]import org.springframework.webflow.definition.FlowDefinition

[MSG]The [org.springframework.webflow.definition.FlowDefinition] import is never referenced

UnnecessaryGetter323

[SRC]assertEquals "contextRelative:/test/foo",context.getExte..edirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowRedirectTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

UnnecessaryGetter332

[SRC]assertEquals "contextRelative:/test/foo/1",context.getEx..edirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowRedirectTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

UnnecessaryGetter344

[SRC]assertEquals "contextRelative:/mycontroller/foo",context..edirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowRedirectTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

➥ FlowTagInvokationTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod233

[SRC]void onInit() {

[MSG]Violation in class FlowTagInvokationTests. The method onInit is public but not a test method

JUnitPublicNonTestMethod242

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowTagInvokationTests. The method getFlowClosure is public but not a test method

UnusedImport34

[SRC]import org.springframework.webflow.definition.FlowDefinition

[MSG]The [org.springframework.webflow.definition.FlowDefinition] import is never referenced

UnusedImport35

[SRC]import org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder

[MSG]The [org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder] import is never referenced

UnnecessaryGetter320

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowTagInvokationTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter329

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.FlowTagInvokationTests. getFlowScope() can probably be rewritten as flowScope

➥ SubflowExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod229

[SRC]Closure getFlowClosure() {

[MSG]Violation in class SubflowExecutionTests. The method getFlowClosure is public but not a test method

➥ SubflowExecutionWithExternalSubflowTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod221

[SRC]Closure getFlowClosure() {

[MSG]Violation in class SubflowExecutionWithExternalSubflowTests. The method getFlowClosure is public but not a test method

UnusedImport33

[SRC]import junit.framework.TestCase

[MSG]The [junit.framework.TestCase] import is never referenced

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.webflow.engine.builder

➥ FlowBuilderDecisionExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod210

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderDecisionExecutionTests. The method getFlowClosure is public but not a test method

➥ FlowBuilderDynamicTransitionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod233

[SRC]String getFlowId() { "myFlow" }

[MSG]Violation in class FlowBuilderDynamicTransitionTests. The method getFlowId is public but not a test method

JUnitPublicNonTestMethod235

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderDynamicTransitionTests. The method getFlowClosure is public but not a test method

UnnecessaryGetter312

[SRC]def startState = flowDefinition.getStartState()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderDynamicTransitionTests. getStartState() can probably be rewritten as startState

➥ FlowBuilderExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod210

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderExecutionTests. The method getFlowClosure is public but not a test method

UnnecessaryGetter341

[SRC]def model = getFlowScope()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderExecutionTests. getFlowScope() can probably be rewritten as flowScope

➥ FlowBuilderSubFlowExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod229

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderSubFlowExecutionTests. The method getFlowClosure is public but not a test method

JUnitPublicNonTestMethod259

[SRC]def foo() { "bar" }

[MSG]Violation in class FlowBuilderSubFlowExecutionTests. The method foo is public but not a test method

UnnecessaryGetter373

[SRC]def theFlow = getFlowDefinition()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderSubFlowExecutionTests. getFlowDefinition() can probably be rewritten as flowDefinition

➥ FlowBuilderSubFlowExecutionWithInputOuputTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod247

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderSubFlowExecutionWithInputOuputTests. The method getFlowClosure is public but not a test method

UnusedVariable289

[SRC]GrailsWebRequest webrequest = grails.util.GrailsWebUtil...WebRequest()

[MSG]The variable [webrequest] in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderSubFlowExecutionWithInputOuputTests is not used

EmptyCatchBlock2124

[SRC]catch (FlowInputMappingException e) {}

[MSG]The catch block is empty

➥ FlowBuilderTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper216

[SRC]void setUp() {

[MSG]Violation in class FlowBuilderTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper226

[SRC]void tearDown() {

[MSG]Violation in class FlowBuilderTests. The method tearDown() does not call super.tearDown()

UnnecessaryGetter323

[SRC]flowBuilderServices.expressionParser = DefaultExpression..sionParser()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderTests. getExpressionParser() can probably be rewritten as expressionParser

UnnecessaryGetter3154

[SRC]def flow = new FlowBuilder("myFlow",getFlowBuilderServic..pl()).flow {

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilderTests. getFlowBuilderServices() can probably be rewritten as flowBuilderServices

➥ FlowBuilderTransitionCriteriaTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod27

[SRC]Closure getFlowClosure() {

[MSG]Violation in class FlowBuilderTransitionCriteriaTests. The method getFlowClosure is public but not a test method

➥ RuntimeRedirectActionTests.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter327

[SRC]context.getFlowScope().put("id", "1")

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectActionTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter329

[SRC]assert "contextRelative:/book/show/1" == ext.getExternalRedirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectActionTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

UnnecessaryGetter331

[SRC]context.getFlowScope().put("id", "2")

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectActionTests. getFlowScope() can probably be rewritten as flowScope

UnnecessaryGetter333

[SRC]assert "contextRelative:/book/show/2" == ext.getExternalRedirectUrl()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectActionTests. getExternalRedirectUrl() can probably be rewritten as externalRedirectUrl

Package: grails-test-suite-web.src.test.groovy.org.codehaus.groovy.grails.webflow.support

➥ AbstractGrailsTagAwareFlowExecutionTests.groovy

Rule NamePriorityLine #Source Line / Message
JUnitSetUpCallsSuper264

[SRC]final void setUp() throws Exception {

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method setUp() does not call super.setUp()

JUnitTearDownCallsSuper2138

[SRC]final void tearDown() {

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method tearDown() does not call super.tearDown()

JUnitPublicNonTestMethod2158

[SRC]FlowDefinition registerFlow(String flowId, Closure flowClosure) {

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method registerFlow is public but not a test method

JUnitPublicNonTestMethod2167

[SRC]FlowDefinition getFlowDefinition() {

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method getFlowDefinition is public but not a test method

JUnitPublicNonTestMethod2175

[SRC]String getFlowId() { 'testFlow' }

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method getFlowId is public but not a test method

JUnitPublicNonTestMethod2177

[SRC]abstract Closure getFlowClosure()

[MSG]Violation in class AbstractGrailsTagAwareFlowExecutionTests. The method getFlowClosure is public but not a test method

UnusedImport315

[SRC]import org.codehaus.groovy.runtime.InvokerHelper

[MSG]The [org.codehaus.groovy.runtime.InvokerHelper] import is never referenced

UnusedImport340

[SRC]import org.springframework.webflow.definition.registry.F..itionLocator

[MSG]The [org.springframework.webflow.definition.registry.FlowDefinitionLocator] import is never referenced

UnnecessaryGetter3111

[SRC]appCtx = springConfig.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getApplicationContext() can probably be rewritten as applicationContext

UnnecessaryGetter3120

[SRC]flowBuilderServices.expressionParser = DefaultExpression..sionParser()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getExpressionParser() can probably be rewritten as expressionParser

UnnecessaryGetter3159

[SRC]FlowBuilder builder = new FlowBuilder(flowId, flowClosur..nRegistry())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowDefinitionRegistry() can probably be rewritten as flowDefinitionRegistry

UnnecessaryGetter3162

[SRC]FlowAssembler assembler = new FlowAssembler(builder, bui..erContext())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowBuilderContext() can probably be rewritten as flowBuilderContext

UnnecessaryGetter3163

[SRC]getFlowDefinitionRegistry().registerFlowDefinition(new D..(assembler))

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowDefinitionRegistry() can probably be rewritten as flowDefinitionRegistry

UnnecessaryGetter3164

[SRC]return getFlowDefinitionRegistry().getFlowDefinition(flowId)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowDefinitionRegistry() can probably be rewritten as flowDefinitionRegistry

UnnecessaryGetter3168

[SRC]return registerFlow(getFlowId(), getFlowClosure())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowId() can probably be rewritten as flowId

UnnecessaryGetter3168

[SRC]return registerFlow(getFlowId(), getFlowClosure())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.support.AbstractGrailsTagAwareFlowExecutionTests. getFlowClosure() can probably be rewritten as flowClosure

Package: grails-test.src.main.groovy.grails.test

➥ GrailsMock.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3140

[SRC]def methods = demand.mockMetaClass.getMetaMethods()

[MSG]Violation in class grails.test.GrailsMock. getMetaMethods() can probably be rewritten as metaMethods

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.plugins.testing

➥ AbstractGrailsMockHttpServletResponse.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter343

[SRC]HttpServletRequest request = GrailsWebRequest.lookup().g..entRequest()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter389

[SRC]webRequest.setOut(getWriter())

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getWriter() can probably be rewritten as writer

UnnecessaryGetter394

[SRC]getRedirectedUrl()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getRedirectedUrl() can probably be rewritten as redirectedUrl

UnnecessaryGetter3106

[SRC]if (getStatus() in [301, 302]) {

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getStatus() can probably be rewritten as status

UnnecessaryGetter3110

[SRC]return super.getRedirectedUrl()

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.AbstractGrailsMockHttpServletResponse. getRedirectedUrl() can probably be rewritten as redirectedUrl

➥ GrailsMockErrors.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import org.codehaus.groovy.grails.commons.GrailsClassUtils

[MSG]The [org.codehaus.groovy.grails.commons.GrailsClassUtils] import is never referenced

➥ GrailsMockHttpServletRequest.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod2455

[SRC]void delete() {

[MSG]Violation in class MockPart. The method delete is both empty and not marked with @Override

UnusedMethodParameter2497

[SRC]void dispatch(javax.servlet.ServletContext context, String path) {

[MSG]Violation in class MockAsyncContext. Method parameter [context] is never referenced in the method dispatch of class org.codehaus.groovy.grails.plugins.testing.MockAsyncContext

EmptyMethod2501

[SRC]void complete() {

[MSG]Violation in class MockAsyncContext. The method complete is both empty and not marked with @Override

UnusedImport334

[SRC]import javax.servlet.DispatcherType

[MSG]The [javax.servlet.DispatcherType] import is never referenced

UnnecessaryPackageReference363

[SRC]javax.servlet.DispatcherType dispatcherType;

[MSG]The javax.servlet.DispatcherType class was explicitly imported, so specifying the package name is not necessary

UnnecessaryGetter3339

[SRC]multipartFiles.add(file.getName(), file);

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletRequest. getName() can probably be rewritten as name

UnnecessaryGetter3396

[SRC]getFileMap().values().collect {new MockPart(it)}

[MSG]Violation in class org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletRequest. getFileMap() can probably be rewritten as fileMap

UnnecessaryPackageReference3399

[SRC]javax.servlet.http.Part getPart(String name) {

[MSG]The javax.servlet.http.Part class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3406

[SRC]javax.servlet.AsyncContext startAsync() {

[MSG]The javax.servlet.AsyncContext class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3415

[SRC]javax.servlet.AsyncContext startAsync(javax.servlet.Serv..tResponse) {

[MSG]The javax.servlet.AsyncContext class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3415

[SRC]javax.servlet.AsyncContext startAsync(javax.servlet.Serv..tResponse) {

[MSG]The javax.servlet.ServletRequest class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3415

[SRC]javax.servlet.AsyncContext startAsync(javax.servlet.Serv..tResponse) {

[MSG]The javax.servlet.ServletResponse class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3526

[SRC]void addListener(javax.servlet.AsyncListener listener) {

[MSG]The javax.servlet.AsyncListener class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3530

[SRC]void addListener(javax.servlet.AsyncListener listener, j..tResponse) {

[MSG]The javax.servlet.AsyncListener class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3530

[SRC]void addListener(javax.servlet.AsyncListener listener, j..tResponse) {

[MSG]The javax.servlet.ServletRequest class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3530

[SRC]void addListener(javax.servlet.AsyncListener listener, j..tResponse) {

[MSG]The javax.servlet.ServletResponse class was explicitly imported, so specifying the package name is not necessary

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test

➥ GrailsTestTargetPattern.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring361

[SRC]methodName = rawPattern.substring(pos + 1)

[MSG]Violation in class org.codehaus.groovy.grails.test.GrailsTestTargetPattern. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring362

[SRC]classPattern = rawPattern.substring(0, pos)

[MSG]Violation in class org.codehaus.groovy.grails.test.GrailsTestTargetPattern. The String.substring(int, int) method can be replaced with the subscript operator

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.event

➥ GrailsTestEventConsoleReporter.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter242

[SRC]protected doTestFailure(String name, failure, boolean isError) {

[MSG]Violation in class GrailsTestEventConsoleReporter. Method parameter [failure] is never referenced in the method doTestFailure of class org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter

UnusedMethodParameter242

[SRC]protected doTestFailure(String name, failure, boolean isError) {

[MSG]Violation in class GrailsTestEventConsoleReporter. Method parameter [isError] is never referenced in the method doTestFailure of class org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter

UnusedMethodParameter247

[SRC]protected doTestCaseEnd(String name, String out, String err) {

[MSG]Violation in class GrailsTestEventConsoleReporter. Method parameter [name] is never referenced in the method doTestCaseEnd of class org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter

UnusedMethodParameter247

[SRC]protected doTestCaseEnd(String name, String out, String err) {

[MSG]Violation in class GrailsTestEventConsoleReporter. Method parameter [err] is never referenced in the method doTestCaseEnd of class org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.junit4

➥ JUnit4GrailsTestType.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter353

[SRC]def testClasses = getTestClasses()

[MSG]Violation in class org.codehaus.groovy.grails.test.junit4.JUnit4GrailsTestType. getTestClasses() can probably be rewritten as testClasses

UnnecessaryGetter376

[SRC]new GrailsTestCaseRunnerBuilder(mode, getApplicationCont..getPatterns)

[MSG]Violation in class org.codehaus.groovy.grails.test.junit4.JUnit4GrailsTestType. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.junit4.listener

➥ SuiteRunListener.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod246

[SRC]void testRunStarted(Description description) {

[MSG]Violation in class SuiteRunListener. The method testRunStarted is both empty and not marked with @Override

UnusedMethodParameter246

[SRC]void testRunStarted(Description description) {

[MSG]Violation in class SuiteRunListener. Method parameter [description] is never referenced in the method testRunStarted of class org.codehaus.groovy.grails.test.junit4.listener.SuiteRunListener

UnusedMethodParameter268

[SRC]void testRunFinished(Result result) {

[MSG]Violation in class SuiteRunListener. Method parameter [result] is never referenced in the method testRunFinished of class org.codehaus.groovy.grails.test.junit4.listener.SuiteRunListener

EmptyMethod272

[SRC]void testIgnored(Description description) {

[MSG]Violation in class SuiteRunListener. The method testIgnored is both empty and not marked with @Override

UnusedMethodParameter272

[SRC]void testIgnored(Description description) {

[MSG]Violation in class SuiteRunListener. Method parameter [description] is never referenced in the method testIgnored of class org.codehaus.groovy.grails.test.junit4.listener.SuiteRunListener

UnnecessaryGetter369

[SRC]getPerTestRunListener().finish()

[MSG]Violation in class org.codehaus.groovy.grails.test.junit4.listener.SuiteRunListener. getPerTestRunListener() can probably be rewritten as perTestRunListener

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.junit4.runner

➥ GrailsTestCaseRunner.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport325

[SRC]import org.junit.runner.notification.RunNotifier

[MSG]The [org.junit.runner.notification.RunNotifier] import is never referenced

UnusedImport335

[SRC]import org.codehaus.groovy.grails.test.support.GrailsTestInterceptor

[MSG]The [org.codehaus.groovy.grails.test.support.GrailsTestInterceptor] import is never referenced

Package: grails-test.src.main.groovy.org.codehaus.groovy.grails.test.support

➥ GrailsTestInterceptor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter281

[SRC]protected initRequestEnvironmentIfNecessary(Closure body) {

[MSG]Violation in class GrailsTestInterceptor. Method parameter [body] is never referenced in the method initRequestEnvironmentIfNecessary of class org.codehaus.groovy.grails.test.support.GrailsTestInterceptor

UnnecessaryGetter384

[SRC]def controllerName = getControllerName()

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestInterceptor. getControllerName() can probably be rewritten as controllerName

➥ GrailsTestTransactionInterceptor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import org.springframework.web.context.request.RequestContextHolder

[MSG]The [org.springframework.web.context.request.RequestContextHolder] import is never referenced

➥ GrailsTestTypeSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3117

[SRC]Thread.currentThread().contextClassLoader = getTestClassLoader()

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. getTestClassLoader() can probably be rewritten as testClassLoader

UnnecessaryGetter3157

[SRC]def classPathAdditions = [getSourceDir()]

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. getSourceDir() can probably be rewritten as sourceDir

UnnecessaryGetter3210

[SRC]def basePath = getSourceDir().canonicalPath

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. getSourceDir() can probably be rewritten as sourceDir

UnnecessarySubstring3216

[SRC]def relativePath = filePath.substring(basePath.size() + 1)

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3250

[SRC]getTestClassLoader().loadClass(className)

[MSG]Violation in class org.codehaus.groovy.grails.test.support.GrailsTestTypeSupport. getTestClassLoader() can probably be rewritten as testClassLoader

Package: grails-web.src.jsp21.groovy.org.codehaus.groovy.grails.web.pages.ext.jsp

➥ GroovyPagesJspFactory21.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter317

[SRC]def jspCtx = servletContext.getAttribute(GroovyPagesJspA..t.getName())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory21. getName() can probably be rewritten as name

UnnecessaryGetter321

[SRC]if (!servletContext.getAttribute(GroovyPagesJspApplicati..etName())) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory21. getName() can probably be rewritten as name

UnnecessaryGetter323

[SRC]servletContext.setAttribute(GroovyPagesJspApplicationCon..e(), jspCtx)

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory21. getName() can probably be rewritten as name

➥ GroovyPagesPageContext21.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter330

[SRC]if (JspFactory.getDefaultFactory() == null) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContext21. getDefaultFactory() can probably be rewritten as defaultFactory

UnnecessaryGetter339

[SRC]def jspContext = JspFactory.getDefaultFactory().getJspAp..etContext())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContext21. getDefaultFactory() can probably be rewritten as defaultFactory

UnnecessaryGetter339

[SRC]def jspContext = JspFactory.getDefaultFactory().getJspAp..etContext())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesPageContext21. getServletContext() can probably be rewritten as servletContext

Package: grails-web.src.main.groovy.grails.gsp

➥ PageRenderer.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2165

[SRC]long getDateHeader(String name) { -1L }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getDateHeader of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2167

[SRC]String getHeader(String name) { null }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getHeader of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2169

[SRC]Enumeration getHeaders(String name) {

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getHeaders of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2177

[SRC]int getIntHeader(String name) { -1 }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getIntHeader of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2191

[SRC]boolean isUserInRole(String role) { false }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [role] is never referenced in the method isUserInRole of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2205

[SRC]HttpSession getSession(boolean create) { throw new Unsup..erations") }

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [create] is never referenced in the method getSession of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2264

[SRC]String[] getParameterValues(String name) {

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [name] is never referenced in the method getParameterValues of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2318

[SRC]RequestDispatcher getRequestDispatcher(String path) {

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [path] is never referenced in the method getRequestDispatcher of class grails.gsp.PageRenderer$PageRenderRequest

UnusedMethodParameter2322

[SRC]String getRealPath(String path) {

[MSG]Violation in class PageRenderer$PageRenderRequest. Method parameter [path] is never referenced in the method getRealPath of class grails.gsp.PageRenderer$PageRenderRequest

EmptyMethod2389

[SRC]void addCookie(Cookie cookie) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method addCookie is both empty and not marked with @Override

UnusedMethodParameter2389

[SRC]void addCookie(Cookie cookie) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [cookie] is never referenced in the method addCookie of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2393

[SRC]boolean containsHeader(String name) { false }

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method containsHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2403

[SRC]void sendError(int sc, String msg) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method sendError is both empty and not marked with @Override

UnusedMethodParameter2403

[SRC]void sendError(int sc, String msg) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sc] is never referenced in the method sendError of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2403

[SRC]void sendError(int sc, String msg) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [msg] is never referenced in the method sendError of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2407

[SRC]void sendError(int sc) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method sendError is both empty and not marked with @Override

UnusedMethodParameter2407

[SRC]void sendError(int sc) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sc] is never referenced in the method sendError of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2411

[SRC]void sendRedirect(String location) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method sendRedirect is both empty and not marked with @Override

UnusedMethodParameter2411

[SRC]void sendRedirect(String location) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [location] is never referenced in the method sendRedirect of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2415

[SRC]void setDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setDateHeader is both empty and not marked with @Override

UnusedMethodParameter2415

[SRC]void setDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method setDateHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2415

[SRC]void setDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [date] is never referenced in the method setDateHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2419

[SRC]void addDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method addDateHeader is both empty and not marked with @Override

UnusedMethodParameter2419

[SRC]void addDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method addDateHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2419

[SRC]void addDateHeader(String name, long date) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [date] is never referenced in the method addDateHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2423

[SRC]void setHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setHeader is both empty and not marked with @Override

UnusedMethodParameter2423

[SRC]void setHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method setHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2423

[SRC]void setHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [value] is never referenced in the method setHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2427

[SRC]void addHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method addHeader is both empty and not marked with @Override

UnusedMethodParameter2427

[SRC]void addHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method addHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2427

[SRC]void addHeader(String name, String value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [value] is never referenced in the method addHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2431

[SRC]void setIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setIntHeader is both empty and not marked with @Override

UnusedMethodParameter2431

[SRC]void setIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method setIntHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2431

[SRC]void setIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [value] is never referenced in the method setIntHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2435

[SRC]void addIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method addIntHeader is both empty and not marked with @Override

UnusedMethodParameter2435

[SRC]void addIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method addIntHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2435

[SRC]void addIntHeader(String name, int value) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [value] is never referenced in the method addIntHeader of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2439

[SRC]void setStatus(int sc) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setStatus is both empty and not marked with @Override

UnusedMethodParameter2439

[SRC]void setStatus(int sc) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sc] is never referenced in the method setStatus of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2443

[SRC]void setStatus(int sc, String sm) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setStatus is both empty and not marked with @Override

UnusedMethodParameter2443

[SRC]void setStatus(int sc, String sm) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sc] is never referenced in the method setStatus of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2443

[SRC]void setStatus(int sc, String sm) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [sm] is never referenced in the method setStatus of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2451

[SRC]String getHeader(String name) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method getHeader of class grails.gsp.PageRenderer$PageRenderResponse

UnusedMethodParameter2455

[SRC]Collection<String> getHeaders(String name) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [name] is never referenced in the method getHeaders of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2467

[SRC]void setContentLength(int len) {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method setContentLength is both empty and not marked with @Override

UnusedMethodParameter2467

[SRC]void setContentLength(int len) {

[MSG]Violation in class PageRenderer$PageRenderResponse. Method parameter [len] is never referenced in the method setContentLength of class grails.gsp.PageRenderer$PageRenderResponse

EmptyMethod2471

[SRC]void flushBuffer() {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method flushBuffer is both empty and not marked with @Override

EmptyMethod2475

[SRC]void resetBuffer() {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method resetBuffer is both empty and not marked with @Override

EmptyMethod2481

[SRC]void reset() {

[MSG]Violation in class PageRenderer$PageRenderResponse. The method reset is both empty and not marked with @Override

UnusedImport320

[SRC]import java.util.concurrent.ConcurrentLinkedQueue

[MSG]The [java.util.concurrent.ConcurrentLinkedQueue] import is never referenced

UnusedImport332

[SRC]import org.codehaus.groovy.grails.web.pages.GroovyPagesUriSupport

[MSG]The [org.codehaus.groovy.grails.web.pages.GroovyPagesUriSupport] import is never referenced

UnusedImport337

[SRC]import org.springframework.core.io.ResourceLoader

[MSG]The [org.springframework.core.io.ResourceLoader] import is never referenced

UnusedImport340

[SRC]import org.springframework.web.context.support.ServletCo..sourceLoader

[MSG]The [org.springframework.web.context.support.ServletContextResourceLoader] import is never referenced

UnusedImport343

[SRC]import org.codehaus.groovy.grails.web.pages.discovery.Gr..ScriptSource

[MSG]The [org.codehaus.groovy.grails.web.pages.discovery.GroovyPageResourceScriptSource] import is never referenced

UnusedImport344

[SRC]import org.codehaus.groovy.grails.web.pages.discovery.Gr..ScriptSource

[MSG]The [org.codehaus.groovy.grails.web.pages.discovery.GroovyPageCompiledScriptSource] import is never referenced

UnnecessaryGetter3126

[SRC]def oldRequestAttributes = RequestContextHolder.getRequestAttributes()

[MSG]Violation in class grails.gsp.PageRenderer. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter3198

[SRC]return new StringBuffer(getRequestURI())

[MSG]Violation in class grails.gsp.PageRenderer$PageRenderRequest. getRequestURI() can probably be rewritten as requestURI

UnnecessaryGetter3309

[SRC]return Locale.getDefault()

[MSG]Violation in class grails.gsp.PageRenderer$PageRenderRequest. getDefault() can probably be rewritten as default

UnnecessaryGetter3313

[SRC]return new IteratorEnumeration(Locale.getAvailableLocale...iterator())

[MSG]Violation in class grails.gsp.PageRenderer$PageRenderRequest. getAvailableLocales() can probably be rewritten as availableLocales

UnnecessaryGetter3381

[SRC]Locale locale = Locale.getDefault()

[MSG]Violation in class grails.gsp.PageRenderer$PageRenderResponse. getDefault() can probably be rewritten as default

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.mapping

➥ DefaultLinkGenerator.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity264

[SRC]String link(Map attrs, String encoding = 'UTF-8') {

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. The cyclomatic complexity for method [link] is [27]

EmptyCatchBlock2142

[SRC]} catch(e){}

[MSG]The catch block is empty

UnnecessaryGetter374

[SRC]if (cp == null) cp = getContextPath()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getContextPath() can probably be rewritten as contextPath

UnnecessaryGetter397

[SRC]def controller = controllerAttribute != null ? controlle..rollerName()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getControllerName() can probably be rewritten as controllerName

UnnecessaryGetter3149

[SRC]final cp = contextPathAttribute != null ? contextPathAtt..ontextPath()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getContextPath() can probably be rewritten as contextPath

UnnecessaryGetter3177

[SRC]final cp = contextPathAttribute == null ? getContextPath..athAttribute

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getContextPath() can probably be rewritten as contextPath

UnnecessaryGetter3216

[SRC]contextPath = requestStateLookupStrategy.getContextPath()

[MSG]Violation in class org.codehaus.groovy.grails.web.mapping.DefaultLinkGenerator. getContextPath() can probably be rewritten as contextPath

UnnecessaryElseStatement3259

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryElseStatement3263

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ ForwardUrlMappingInfo.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport317

[SRC]import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest

[MSG]The [org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest] import is never referenced

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.mime

➥ MimeType.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter362

[SRC]def context = webRequest?.getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.mime.MimeType. getApplicationContext() can probably be rewritten as applicationContext

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.pages

➥ GroovyPageCompiler.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter387

[SRC]def relPackagePath = relativePath(viewsDir, gspfile.getParentFile())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompiler. getParentFile() can probably be rewritten as parentFile

UnnecessaryGetter3119

[SRC]gspgroovyfile.getParentFile().mkdirs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompiler. getParentFile() can probably be rewritten as parentFile

➥ GroovyPageCompilerTask.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter358

[SRC]classpath = new Path(getProject())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask. getProject() can probably be rewritten as project

UnnecessaryGetter381

[SRC]throw new BuildException("destination [${destdir}] direc..tLocation())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask. getLocation() can probably be rewritten as location

UnnecessaryGetter387

[SRC]throw new BuildException("source [${srcdir}] directory d..tLocation())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask. getLocation() can probably be rewritten as location

UnnecessaryGetter3100

[SRC]GrailsConsole.getInstance().updateStatus("Compiling ${gs..kagename}]")

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPageCompilerTask. getInstance() can probably be rewritten as instance

➥ GroovyPagesMetaUtils.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGroovyImport34

[SRC]import groovy.lang.MetaClass

UnnecessaryGetter320

[SRC]methodMissingForTagLib(mc, mc.getTheClass(), gspTagLibra..ToMetaClass)

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.GroovyPagesMetaUtils. getTheClass() can probably be rewritten as theClass

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.pages.ext.jsp

➥ GroovyPagesJspFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [servlet] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [servletRequest] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [servletResponse] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [s] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [b] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [i] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter216

[SRC]PageContext getPageContext(Servlet servlet, ServletReque..oolean b1) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [b1] is never referenced in the method getPageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnusedMethodParameter219

[SRC]void releasePageContext(PageContext pageContext) {

[MSG]Violation in class GroovyPagesJspFactory. Method parameter [pageContext] is never referenced in the method releasePageContext of class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory

UnnecessaryGetter324

[SRC]return { getSpecificationVersion() } as JspEngineInfo

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.GroovyPagesJspFactory. getSpecificationVersion() can probably be rewritten as specificationVersion

➥ JspTagImpl.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity260

[SRC]void doTag(Writer targetWriter, Map attributes, Closure body) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl. The cyclomatic complexity for method [doTag] is [23]

UnusedMethodParameter2153

[SRC]protected handleSimpleTag(SimpleTag tag, Map attributes,..pageContext,

[MSG]Violation in class JspTagImpl. Method parameter [attributes] is never referenced in the method handleSimpleTag of class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl

UnnecessaryGetter362

[SRC]GroovyPagesPageContext pageContext = PageContextFactory.getCurrent();

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl. getCurrent() can probably be rewritten as current

UnnecessaryGetter399

[SRC]def out = pageContext.getOut()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl. getOut() can probably be rewritten as out

UnnecessaryGetter3121

[SRC]LOG.warn "Tag ${tag.getClass().getName()} returned SKIP_..rted in GSP"

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.JspTagImpl. getName() can probably be rewritten as name

➥ PageContextFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter338

[SRC]def classLoader = Thread.currentThread().getContextClassLoader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.PageContextFactory. getContextClassLoader() can probably be rewritten as contextClassLoader

UnnecessaryGetter351

[SRC]def request = webRequest.getCurrentRequest()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.PageContextFactory. getCurrentRequest() can probably be rewritten as currentRequest

UnnecessaryGetter356

[SRC]ServletContext servletContext = webRequest.getServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.PageContextFactory. getServletContext() can probably be rewritten as servletContext

➥ TagLibraryResolver.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter364

[SRC]def jarURLs = grailsApplication.isWarDeployed() ? getJar..().getURLs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getJarsFromServletContext() can probably be rewritten as jarsFromServletContext

UnnecessaryGetter364

[SRC]def jarURLs = grailsApplication.isWarDeployed() ? getJar..().getURLs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getURLs() can probably be rewritten as URLs

UnnecessaryGetter370

[SRC]ZipEntry entry = zipInput.getNextEntry()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getNextEntry() can probably be rewritten as nextEntry

UnnecessaryGetter376

[SRC]entry = zipInput.getNextEntry()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getNextEntry() can probably be rewritten as nextEntry

UnnecessaryGetter386

[SRC]Resource webXml = getWebXmlFromServletContext()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getWebXmlFromServletContext() can probably be rewritten as webXmlFromServletContext

UnnecessaryGetter398

[SRC]def jarURLs = grailsApplication.isWarDeployed() ? getJar..().getURLs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getJarsFromServletContext() can probably be rewritten as jarsFromServletContext

UnnecessaryGetter398

[SRC]def jarURLs = grailsApplication.isWarDeployed() ? getJar..().getURLs()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getURLs() can probably be rewritten as URLs

UnnecessaryGetter3115

[SRC]def source = new InputSource(webXml.getInputStream())

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getInputStream() can probably be rewritten as inputStream

UnnecessaryGetter3120

[SRC]def reader = factory.newSAXParser().getXMLReader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getXMLReader() can probably be rewritten as XMLReader

UnnecessaryGetter3126

[SRC]for (entry in webXmlReader.getTagLocations()) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getTagLocations() can probably be rewritten as tagLocations

UnnecessaryGetter3157

[SRC]ZipEntry entry = zipInput.getNextEntry()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getNextEntry() can probably be rewritten as nextEntry

UnnecessaryGetter3159

[SRC]def name = entry.getName()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getName() can probably be rewritten as name

UnnecessaryGetter3169

[SRC]if ("taglib".equals(pullParser.getName())) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getName() can probably be rewritten as name

UnnecessaryGetter3175

[SRC]if (token == XmlPullParser.START_TAG && "uri".equals(pul..etName())) {

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getName() can probably be rewritten as name

UnnecessaryGetter3177

[SRC]tagLibURI = pullParser.getText()?.trim()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getText() can probably be rewritten as text

UnnecessaryGetter3191

[SRC]entry = zipInput.getNextEntry()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getNextEntry() can probably be rewritten as nextEntry

UnnecessaryGetter3216

[SRC]def reader = factory.newSAXParser().getXMLReader()

[MSG]Violation in class org.codehaus.groovy.grails.web.pages.ext.jsp.TagLibraryResolver. getXMLReader() can probably be rewritten as XMLReader

➥ TldReader.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter236

[SRC]void startElement(String nsuri, String localName, String..ttributes) {

[MSG]Violation in class TldReader. Method parameter [nsuri] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

UnusedMethodParameter236

[SRC]void startElement(String nsuri, String localName, String..ttributes) {

[MSG]Violation in class TldReader. Method parameter [localName] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

UnusedMethodParameter236

[SRC]void startElement(String nsuri, String localName, String..ttributes) {

[MSG]Violation in class TldReader. Method parameter [attributes] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

UnusedMethodParameter246

[SRC]void endElement(String nsuri, String localName, String qName) {

[MSG]Violation in class TldReader. Method parameter [nsuri] is never referenced in the method endElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

UnusedMethodParameter246

[SRC]void endElement(String nsuri, String localName, String qName) {

[MSG]Violation in class TldReader. Method parameter [localName] is never referenced in the method endElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.TldReader

➥ WebXmlTagLibraryReader.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter241

[SRC]void startElement(String ns, String localName, String qN..ttributes) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [ns] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

UnusedMethodParameter241

[SRC]void startElement(String ns, String localName, String qN..ttributes) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [localName] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

UnusedMethodParameter241

[SRC]void startElement(String ns, String localName, String qN..ttributes) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [attributes] is never referenced in the method startElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

UnusedMethodParameter251

[SRC]void endElement(String ns, String localName, String qName) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [ns] is never referenced in the method endElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

UnusedMethodParameter251

[SRC]void endElement(String ns, String localName, String qName) {

[MSG]Violation in class WebXmlTagLibraryReader. Method parameter [localName] is never referenced in the method endElement of class org.codehaus.groovy.grails.web.pages.ext.jsp.WebXmlTagLibraryReader

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.taglib

➥ NamespacedTagDispatcher.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter359

[SRC]GroovyPagesMetaUtils.methodMissingForTagLib(getMetaClass..lopmentMode)

[MSG]Violation in class org.codehaus.groovy.grails.web.taglib.NamespacedTagDispatcher. getMetaClass() can probably be rewritten as metaClass

➥ TemplateNamespacedTagDispatcher.groovy

Rule NamePriorityLine #Source Line / Message
SynchronizedOnThis222

[SRC]synchronized(this) {

[MSG]The synchronized statement uses the 'this' reference

UnusedImport33

[SRC]import grails.util.CollectionUtils;

[MSG]The [grails.util.CollectionUtils] import is never referenced

UnnecessaryGroovyImport35

[SRC]import java.util.Map;

Package: grails-web.src.main.groovy.org.codehaus.groovy.grails.web.util

➥ TypeConvertingMap.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport318

[SRC]import org.apache.commons.lang.builder.HashCodeBuilder

[MSG]The [org.apache.commons.lang.builder.HashCodeBuilder] import is never referenced

Package: grails-webflow.src.main.groovy.grails.test

➥ WebFlowTestCase.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod260

[SRC]abstract getFlow()

[MSG]Violation in class WebFlowTestCase. The method getFlow is public but not a test method

JUnitPublicNonTestMethod265

[SRC]String getFlowId() { "test" }

[MSG]Violation in class WebFlowTestCase. The method getFlowId is public but not a test method

JUnitPublicNonTestMethod2106

[SRC]FlowDefinition registerFlow(String flowId, Closure flowClosure) {

[MSG]Violation in class WebFlowTestCase. The method registerFlow is public but not a test method

JUnitPublicNonTestMethod2115

[SRC]FlowDefinition getFlowDefinition() {

[MSG]Violation in class WebFlowTestCase. The method getFlowDefinition is public but not a test method

UnnecessaryGetter369

[SRC]GrailsWebRequest webRequest = RequestContextHolder.getRe..Attributes()

[MSG]Violation in class grails.test.WebFlowTestCase. getRequestAttributes() can probably be rewritten as requestAttributes

UnnecessaryGetter374

[SRC]mockServletContext = webRequest.getServletContext()

[MSG]Violation in class grails.test.WebFlowTestCase. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter375

[SRC]applicationContext = WebApplicationContextUtils.getWebAp..etContext())

[MSG]Violation in class grails.test.WebFlowTestCase. getServletContext() can probably be rewritten as servletContext

UnnecessaryGetter395

[SRC]flowBuilderServices.expressionParser = DefaultExpression..sionParser()

[MSG]Violation in class grails.test.WebFlowTestCase. getExpressionParser() can probably be rewritten as expressionParser

UnnecessaryGetter3110

[SRC]FlowAssembler assembler = new FlowAssembler(builder, bui..erContext())

[MSG]Violation in class grails.test.WebFlowTestCase. getFlowBuilderContext() can probably be rewritten as flowBuilderContext

UnnecessaryGetter3116

[SRC]def flow = getFlow()

[MSG]Violation in class grails.test.WebFlowTestCase. getFlow() can probably be rewritten as flow

UnnecessaryGetter3123

[SRC]return registerFlow(getFlowId(), flow)

[MSG]Violation in class grails.test.WebFlowTestCase. getFlowId() can probably be rewritten as flowId

Package: grails-webflow.src.main.groovy.org.codehaus.groovy.grails.webflow

➥ WebFlowPluginSupport.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport324

[SRC]import org.codehaus.groovy.grails.webflow.persistence.Fl..ssionContext

[MSG]The [org.codehaus.groovy.grails.webflow.persistence.FlowAwareCurrentSessionContext] import is never referenced

UnusedImport325

[SRC]import org.codehaus.groovy.grails.webflow.persistence.Se..tionListener

[MSG]The [org.codehaus.groovy.grails.webflow.persistence.SessionAwareHibernateFlowExecutionListener] import is never referenced

UnusedImport340

[SRC]import org.springframework.webflow.execution.factory.Sta..stenerLoader

[MSG]The [org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader] import is never referenced

UnnecessarySelfAssignment371

[SRC]viewFactoryCreator = viewFactoryCreator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment371

[SRC]viewFactoryCreator = viewFactoryCreator

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryPackageReference380

[SRC]hibernateConversationListener(org.codehaus.groovy.grails..tionManager)

[MSG]The org.codehaus.groovy.grails.webflow.persistence.SessionAwareHibernateFlowExecutionListener class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference380

[SRC]hibernateConversationListener(org.codehaus.groovy.grails..tionManager)

[MSG]The org.codehaus.groovy.grails.webflow.persistence.SessionAwareHibernateFlowExecutionListener class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference381

[SRC]executionListenerLoader(org.springframework.webflow.exec..ionListener)

[MSG]The org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference381

[SRC]executionListenerLoader(org.springframework.webflow.exec..ionListener)

[MSG]The org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference382

[SRC]sessionFactory.currentSessionContextClass = org.codehaus..ssionContext

[MSG]The org.codehaus.groovy.grails.webflow.persistence.FlowAwareCurrentSessionContext class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference382

[SRC]sessionFactory.currentSessionContextClass = org.codehaus..ssionContext

[MSG]The org.codehaus.groovy.grails.webflow.persistence.FlowAwareCurrentSessionContext class was explicitly imported, so specifying the package name is not necessary

UnnecessarySelfAssignment3103

[SRC]flowExecutor = flowExecutor

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessarySelfAssignment3103

[SRC]flowExecutor = flowExecutor

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter3122

[SRC]def assembler = new FlowAssembler(builder, builder.getFl..erContext())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getFlowBuilderContext() can probably be rewritten as flowBuilderContext

UnnecessaryGetter3170

[SRC]controller.getReference().getWrappedInstance().metaClass..rollerClass)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getWrappedInstance() can probably be rewritten as wrappedInstance

UnnecessaryGetter3170

[SRC]controller.getReference().getWrappedInstance().metaClass..rollerClass)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getReference() can probably be rewritten as reference

UnnecessaryDefInVariableDeclaration3172

[SRC]def FlowBuilder builder = new FlowBuilder(("${controller..lowRegistry)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. The def keyword is unneeded when a variable is declared with a type

UnnecessaryDefInVariableDeclaration3172

[SRC]def FlowBuilder builder = new FlowBuilder(("${controller..lowRegistry)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. The def keyword is unneeded when a variable is declared with a type

UnnecessaryGetter3176

[SRC]FlowAssembler flowAssembler = new FlowAssembler(builder,..erContext())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getFlowBuilderContext() can probably be rewritten as flowBuilderContext

UnnecessaryGetter3182

[SRC]controller.getReference().getWrappedInstance().metaClass..entMetaClass

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getWrappedInstance() can probably be rewritten as wrappedInstance

UnnecessaryGetter3182

[SRC]controller.getReference().getWrappedInstance().metaClass..entMetaClass

[MSG]Violation in class org.codehaus.groovy.grails.webflow.WebFlowPluginSupport. getReference() can probably be rewritten as reference

Package: grails-webflow.src.main.groovy.org.codehaus.groovy.grails.webflow.context.servlet

➥ GrailsFlowUrlHandler.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport326

[SRC]import org.springframework.webflow.execution.repository...onRepository

[MSG]The [org.springframework.webflow.execution.repository.FlowExecutionRepository] import is never referenced

UnusedImport332

[SRC]import org.codehaus.groovy.grails.webflow.execution.Grai..ExecutorImpl

[MSG]The [org.codehaus.groovy.grails.webflow.execution.GrailsFlowExecutorImpl] import is never referenced

UnnecessarySubstring368

[SRC]String actionName = flowId.substring(flowId.lastIndexOf('/')+1)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.context.servlet.GrailsFlowUrlHandler. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3107

[SRC]String actionName = flowId.substring(flowId.lastIndexOf('/') + 1)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.context.servlet.GrailsFlowUrlHandler. The String.substring(int) method can be replaced with the subscript operator

Package: grails-webflow.src.main.groovy.org.codehaus.groovy.grails.webflow.engine.builder

➥ AbstractDelegate.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInVariableDeclaration366

[SRC]def MetaProperty property = metaClass.getMetaProperty(name)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.AbstractDelegate. The def keyword is unneeded when a variable is declared with a type

UnnecessaryGetter367

[SRC]def ctx = getApplicationContext()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.AbstractDelegate. getApplicationContext() can probably be rewritten as applicationContext

➥ AbstractMapper.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod2123

[SRC]void setValue(Object context, Object value) {}

[MSG]Violation in class KeyExpression. The method setValue is both empty and not marked with @Override

UnusedMethodParameter2123

[SRC]void setValue(Object context, Object value) {}

[MSG]Violation in class KeyExpression. Method parameter [context] is never referenced in the method setValue of class org.codehaus.groovy.grails.webflow.engine.builder.KeyExpression

UnusedMethodParameter2123

[SRC]void setValue(Object context, Object value) {}

[MSG]Violation in class KeyExpression. Method parameter [value] is never referenced in the method setValue of class org.codehaus.groovy.grails.webflow.engine.builder.KeyExpression

UnusedMethodParameter2125

[SRC]Class getValueType(Object context) {Object}

[MSG]Violation in class KeyExpression. Method parameter [context] is never referenced in the method getValueType of class org.codehaus.groovy.grails.webflow.engine.builder.KeyExpression

➥ ClosureExpression.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable235

[SRC]def attrs = context?.attributes ? context.attributes : [:]

[MSG]The variable [attrs] in class org.codehaus.groovy.grails.webflow.engine.builder.ClosureExpression is not used

EmptyMethod241

[SRC]void setValue(Object context, Object value) {

[MSG]Violation in class ClosureExpression. The method setValue is both empty and not marked with @Override

UnusedMethodParameter241

[SRC]void setValue(Object context, Object value) {

[MSG]Violation in class ClosureExpression. Method parameter [context] is never referenced in the method setValue of class org.codehaus.groovy.grails.webflow.engine.builder.ClosureExpression

UnusedMethodParameter241

[SRC]void setValue(Object context, Object value) {

[MSG]Violation in class ClosureExpression. Method parameter [value] is never referenced in the method setValue of class org.codehaus.groovy.grails.webflow.engine.builder.ClosureExpression

UnusedMethodParameter245

[SRC]Class getValueType(Object context) { Object }

[MSG]Violation in class ClosureExpression. Method parameter [context] is never referenced in the method getValueType of class org.codehaus.groovy.grails.webflow.engine.builder.ClosureExpression

➥ ClosureInvokingAction.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField241

[SRC]private static final String RESULT = "result"

[MSG]The field RESULT is not used within the class org.codehaus.groovy.grails.webflow.engine.builder.ClosureInvokingAction

EmptyCatchBlock2154

[SRC]catch (MissingPropertyException e) {

[MSG]The catch block is empty

UnnecessaryDotClass353

[SRC]this.hasCommandObjects = noOfParams > 1 || (noOfParams =..ntext.class)

[MSG]Object.class can be rewritten as Object

UnnecessaryDotClass353

[SRC]this.hasCommandObjects = noOfParams > 1 || (noOfParams =..ntext.class)

[MSG]RequestContext.class can be rewritten as RequestContext

UnnecessaryGetter373

[SRC]prop.validate(delegate, delegate.getProperty(prop.getPro..localErrors)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.ClosureInvokingAction. getPropertyName() can probably be rewritten as propertyName

➥ FlowBuilder.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock2252

[SRC]catch (MissingPropertyException mpe) {

[MSG]The catch block is empty

EmptyCatchBlock2262

[SRC]catch (MissingPropertyException mpe) {

[MSG]The catch block is empty

UnnecessaryGetter3100

[SRC]this.metaClass = GroovySystem.getMetaClassRegistry().get..ilder.class)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getMetaClassRegistry() can probably be rewritten as metaClassRegistry

UnnecessaryDotClass3100

[SRC]this.metaClass = GroovySystem.getMetaClassRegistry().get..ilder.class)

[MSG]FlowBuilder.class can be rewritten as FlowBuilder

UnnecessaryGetter3113

[SRC]super.getContext()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getContext() can probably be rewritten as context

UnnecessaryGetter3124

[SRC]Flow flow = super.getFlow()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3130

[SRC]FlowArtifactFactory flowFactory = getContext().getFlowAr..actFactory()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlowArtifactFactory() can probably be rewritten as flowArtifactFactory

UnnecessaryGetter3130

[SRC]FlowArtifactFactory flowFactory = getContext().getFlowAr..actFactory()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getContext() can probably be rewritten as context

UnnecessaryGetter3171

[SRC]state = flowFactory.createEndState(name, getFlow(), getA..ntryAction),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3195

[SRC]state.getExceptionHandlerSet().add(eh)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getExceptionHandlerSet() can probably be rewritten as exceptionHandlerSet

UnnecessaryGetter3201

[SRC]getFlow().setStartState(startFlow)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessarySubstring3246

[SRC]key = key.substring(GrailsApplicationAttributes.ERRORS.length() + 1)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3276

[SRC]getFlow(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3294

[SRC]def controllerClass = flowInfo.subflow.getThisObject().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getThisObject() can probably be rewritten as thisObject

UnnecessaryGetter3306

[SRC]Class controllerClass = flowClosure.getThisObject().getClass()

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getThisObject() can probably be rewritten as thisObject

UnnecessaryGetter3313

[SRC]return flowFactory.createSubflowState(stateId, getFlow()..on(subflow),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3321

[SRC]getFlow(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3333

[SRC]return flowFactory.createEndState(stateId, getFlow(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getFlow() can probably be rewritten as flow

UnnecessaryGetter3346

[SRC]ViewFactory viewFactory = flowBuilderServices.getViewFac..ViewFactory(

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getViewFactoryCreator() can probably be rewritten as viewFactoryCreator

UnnecessaryGetter3348

[SRC]flowBuilderServices.getExpressionParser(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getExpressionParser() can probably be rewritten as expressionParser

UnnecessaryGetter3349

[SRC]flowBuilderServices.getConversionService(),

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowBuilder. getConversionService() can probably be rewritten as conversionService

UnnecessaryGetter3454

[SRC]throw new FlowDefinitionException("Event handler in flow..etFlowId() +

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.FlowInfoCapturer. getFlowId() can probably be rewritten as flowId

➥ GrailsSubflowAttributeMapper.groovy

Rule NamePriorityLine #Source Line / Message
EmptyMethod247

[SRC]void mapSubflowOutput(AttributeMap output, RequestContext context) {}

[MSG]Violation in class GrailsSubflowAttributeMapper. The method mapSubflowOutput is both empty and not marked with @Override

UnusedMethodParameter247

[SRC]void mapSubflowOutput(AttributeMap output, RequestContext context) {}

[MSG]Violation in class GrailsSubflowAttributeMapper. Method parameter [output] is never referenced in the method mapSubflowOutput of class org.codehaus.groovy.grails.webflow.engine.builder.GrailsSubflowAttributeMapper

UnusedMethodParameter247

[SRC]void mapSubflowOutput(AttributeMap output, RequestContext context) {}

[MSG]Violation in class GrailsSubflowAttributeMapper. Method parameter [context] is never referenced in the method mapSubflowOutput of class org.codehaus.groovy.grails.webflow.engine.builder.GrailsSubflowAttributeMapper

➥ InputMapper.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryElseStatement341

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ RuntimeRedirectAction.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter352

[SRC]return new GroovyShell(new BeanBinding(delegate)).evalua...getValue())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectAction. getValue() can probably be rewritten as value

UnnecessaryGetter369

[SRC]context.getExternalContext().requestExternalRedirect("co..ative:$url")

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.RuntimeRedirectAction. getExternalContext() can probably be rewritten as externalContext

➥ UriRedirectAction.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import org.codehaus.groovy.grails.web.mapping.UrlCreator

[MSG]The [org.codehaus.groovy.grails.web.mapping.UrlCreator] import is never referenced

UnusedImport320

[SRC]import org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder

[MSG]The [org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder] import is never referenced

UnnecessarySelfAssignment337

[SRC]def uri = uri

[MSG]Assignment a variable to itself should be unnecessary. Remove this dead code

UnnecessaryGetter340

[SRC]uri = new GroovyShell(new BeanBinding(delegate)).evaluat...getValue())

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.UriRedirectAction. getValue() can probably be rewritten as value

UnnecessaryGetter343

[SRC]context.getExternalContext().requestExternalRedirect(uri)

[MSG]Violation in class org.codehaus.groovy.grails.webflow.engine.builder.UriRedirectAction. getExternalContext() can probably be rewritten as externalContext

Package: scripts

➥ Console.groovy

Rule NamePriorityLine #Source Line / Message
BusyWait248

[SRC]sleep(Integer.MAX_VALUE)

[MSG]Busy wait detected. Switch the usage of Thread.sleep() to a lock or gate from java.util.concurrent

EmptyMethod280

[SRC]void focusLost(FocusEvent e) {}

[MSG]Violation in class ConsoleFocusListener. The method focusLost is both empty and not marked with @Override

UnusedMethodParameter280

[SRC]void focusLost(FocusEvent e) {}

[MSG]Violation in class ConsoleFocusListener. Method parameter [e] is never referenced in the method focusLost of class ConsoleFocusListener

➥ DependencyReport.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable238

[SRC]def ivySettings = ant.project.setProperty("ivy.cache.dir..bsolutePath)

[MSG]The variable [ivySettings] in class None is not used

➥ Help_.groovy

Rule NamePriorityLine #Source Line / Message
UnusedVariable270

[SRC]def helpText = ""

[MSG]The variable [helpText] in class None is not used

UnnecessaryGetter355

[SRC]String scriptname = script.getName()

[MSG]Violation in class None. getName() can probably be rewritten as name

UnnecessarySubstring356

[SRC]return new File(helpDir, scriptname.substring(0, scriptn..)) + ".txt")

[MSG]Violation in class None. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessaryCollectCall368

[SRC]def scripts = pluginSettings.availableScripts.collect { it.file }

[MSG]Violation in class None. The call to collect could probably be rewritten as a spread expression: pluginSettings.availableScripts*.file

UnnecessaryGetter3112

[SRC]grails ${scriptName} -- ${getDefaultDescription()}

[MSG]Violation in class None. getDefaultDescription() can probably be rewritten as defaultDescription

➥ ListPluginUpdates.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter361

[SRC]def availablePluginVersions = getAvailablePluginVersions()

[MSG]Violation in class None. getAvailablePluginVersions() can probably be rewritten as availablePluginVersions

UnnecessaryGetter362

[SRC]def installedPluginVersions = getInstalledPluginVersions()

[MSG]Violation in class None. getInstalledPluginVersions() can probably be rewritten as installedPluginVersions

➥ ListPlugins_.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter366

[SRC]def pluginInfos = pluginSettings.getPluginInfos()

[MSG]Violation in class None. getPluginInfos() can probably be rewritten as pluginInfos

➥ RefreshDependencies.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport317

[SRC]import groovy.xml.NamespaceBuilder

[MSG]The [groovy.xml.NamespaceBuilder] import is never referenced

UnusedImport318

[SRC]import org.codehaus.groovy.grails.resolve.IvyDependencyManager

[MSG]The [org.codehaus.groovy.grails.resolve.IvyDependencyManager] import is never referenced

➥ Stats.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring371

[SRC]file.path.substring(baseDirPathLength) =~ info.path &&

[MSG]Violation in class None. The String.substring(int) method can be replaced with the subscript operator

➥ Upgrade.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [35]

UnnecessaryParenthesesForMethodCallWithClosure3125

[SRC]['Config.groovy'].each() {template ->

[MSG]Violation in class None. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3131

[SRC]['BuildConfig.groovy'].each() {template ->

[MSG]Violation in class None. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3138

[SRC]['DataSource.groovy'].each() {template ->

[MSG]Violation in class None. Parentheses in the 'each' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure3146

[SRC]['UrlMappings.groovy'].each() {template ->

[MSG]Violation in class None. Parentheses in the 'each' method call are unnecessary and can be removed.

➥ _GrailsArgParsing.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter326

[SRC]if (getBinding().variables.containsKey("_grails_arg_pars..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsBootstrap.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall365

[SRC]def locations = new ArrayList(grailsSettings.pluginDirec..olutePath })

[MSG]Violation in class None. The call to collect could probably be rewritten as a spread expression: grailsSettings.pluginDirectories*.absolutePath

➥ _GrailsClasspath.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter329

[SRC]if (getBinding().variables.containsKey("_grails_classpat..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsClean.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter326

[SRC]if (getBinding().variables.containsKey("_grails_clean_called")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

UnnecessaryObjectReferences348

[SRC]ant.delete(dir:classesDirPath)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences349

[SRC]ant.delete(dir:pluginClassesDirPath, failonerror:false)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences350

[SRC]ant.delete(dir:resourcesDirPath)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences351

[SRC]ant.delete(dir:testDirPath)

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences352

[SRC]ant.delete(failonerror:false, includeemptydirs: true) {

[MSG]The code could be more concise by using a with() or identity() block

➥ _GrailsCreateArtifacts.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [26]

➥ _GrailsDocs.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [30]

UnnecessaryGetter3209

[SRC]def context = DocumentationContext.getInstance()

[MSG]Violation in class None. getInstance() can probably be rewritten as instance

UnnecessaryObjectReferences3254

[SRC]publisher.license = ""

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3255

[SRC]publisher.copyright = ""

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3256

[SRC]publisher.footer = ""

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3257

[SRC]publisher.engineProperties = config?.grails?.doc

[MSG]The code could be more concise by using a with() or identity() block

➥ _GrailsEvents.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter328

[SRC]if (getBinding().variables.containsKey("_grails_events_c..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsInit.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport325

[SRC]import org.springframework.core.io.FileSystemResource

[MSG]The [org.springframework.core.io.FileSystemResource] import is never referenced

UnusedImport326

[SRC]import grails.util.GrailsNameUtils

[MSG]The [grails.util.GrailsNameUtils] import is never referenced

UnnecessaryGetter331

[SRC]if (getBinding().variables.containsKey("_init_called")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsPackage.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter328

[SRC]if (getBinding().variables.containsKey("_grails_package_..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsPluginDev.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethod2130

[SRC]private loadBasePlugin() {

[MSG]The method loadBasePlugin is not used within _GrailsPluginDev.groovy

UnusedImport317

[SRC]import groovy.xml.MarkupBuilder

[MSG]The [groovy.xml.MarkupBuilder] import is never referenced

UnusedImport318

[SRC]import grails.util.GrailsNameUtils

[MSG]The [grails.util.GrailsNameUtils] import is never referenced

UnusedImport319

[SRC]import grails.util.PluginBuildSettings

[MSG]The [grails.util.PluginBuildSettings] import is never referenced

UnusedImport321

[SRC]import org.apache.commons.io.FilenameUtils

[MSG]The [org.apache.commons.io.FilenameUtils] import is never referenced

UnusedImport322

[SRC]import org.apache.ivy.core.report.ArtifactDownloadReport

[MSG]The [org.apache.ivy.core.report.ArtifactDownloadReport] import is never referenced

UnnecessaryGetter364

[SRC]def descriptor = pluginSettings.getBasePluginDescriptor()

[MSG]Violation in class None. getBasePluginDescriptor() can probably be rewritten as basePluginDescriptor

UnnecessaryCollectCall3104

[SRC]packager.jarFiles = deps.collect { it.localFile }

[MSG]Violation in class None. The call to collect could probably be rewritten as a spread expression: deps*.localFile

➥ _GrailsPlugins.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport317

[SRC]import groovy.xml.dom.DOMCategory

[MSG]The [groovy.xml.dom.DOMCategory] import is never referenced

UnusedImport319

[SRC]import org.codehaus.groovy.grails.plugins.GrailsPluginInfo

[MSG]The [org.codehaus.groovy.grails.plugins.GrailsPluginInfo] import is never referenced

UnusedImport320

[SRC]import org.codehaus.groovy.grails.resolve.PluginResolveEngine

[MSG]The [org.codehaus.groovy.grails.resolve.PluginResolveEngine] import is never referenced

UnusedImport321

[SRC]import grails.util.BuildSettings

[MSG]The [grails.util.BuildSettings] import is never referenced

➥ _GrailsRun.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [24]

UnusedMethodParameter2183

[SRC]void actionPerformed(ActionEvent e) {

[MSG]Violation in class None$1. Method parameter [e] is never referenced in the method actionPerformed of class None$1

UnnecessaryGroovyImport324

[SRC]import java.net.ServerSocket

UnnecessaryGetter3128

[SRC]Metadata.getCurrent().put(Metadata.WAR_DEPLOYED, "true")

[MSG]Violation in class None. getCurrent() can probably be rewritten as current

➥ _GrailsSettings.groovy

Rule NamePriorityLine #Source Line / Message
UnusedImport319

[SRC]import grails.util.GrailsNameUtils

[MSG]The [grails.util.GrailsNameUtils] import is never referenced

UnusedImport321

[SRC]import grails.util.Metadata

[MSG]The [grails.util.Metadata] import is never referenced

UnusedImport325

[SRC]import org.springframework.core.io.ClassPathResource

[MSG]The [org.springframework.core.io.ClassPathResource] import is never referenced

UnusedImport326

[SRC]import org.springframework.core.io.FileSystemResource

[MSG]The [org.springframework.core.io.FileSystemResource] import is never referenced

UnusedImport327

[SRC]import org.springframework.core.io.Resource

[MSG]The [org.springframework.core.io.Resource] import is never referenced

UnusedImport328

[SRC]import org.springframework.core.io.support.PathMatchingR..ternResolver

[MSG]The [org.springframework.core.io.support.PathMatchingResourcePatternResolver] import is never referenced

UnusedImport329

[SRC]import org.springframework.util.FileCopyUtils

[MSG]The [org.springframework.util.FileCopyUtils] import is never referenced

UnnecessaryGetter340

[SRC]if (getBinding().variables.containsKey("_settings_called")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

UnnecessaryGetter376

[SRC]if (grailsSettings.defaultEnv && getBinding().variables...riptEnv")) {

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

UnnecessaryGetter388

[SRC]if (getBinding().variables.containsKey("scriptScope")) {

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

➥ _GrailsTest.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [53]

UnusedImport317

[SRC]import grails.util.GrailsUtil

[MSG]The [grails.util.GrailsUtil] import is never referenced

UnusedImport327

[SRC]import org.codehaus.groovy.grails.test.report.junit.JUni..portsFactory

[MSG]The [org.codehaus.groovy.grails.test.report.junit.JUnitReportsFactory] import is never referenced

UnusedImport333

[SRC]import org.codehaus.groovy.grails.test.event.GrailsTestE..soleReporter

[MSG]The [org.codehaus.groovy.grails.test.event.GrailsTestEventConsoleReporter] import is never referenced

UnnecessaryGetter3126

[SRC]if (reRunTests) testNames = getFailedTests()

[MSG]Violation in class None. getFailedTests() can probably be rewritten as failedTests

➥ _GrailsWar.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [32]

UnusedVariable2191

[SRC]def compileScopePluginInfo = ps.compileScopePluginInfo

[MSG]The variable [compileScopePluginInfo] in class None is not used

UnnecessaryGetter3192

[SRC]def compileScopePluginInfos = ps.getCompileScopedSupport..luginInfos()

[MSG]Violation in class None. getCompileScopedSupportedPluginInfos() can probably be rewritten as compileScopedSupportedPluginInfos

UnnecessaryGetter3193

[SRC]def resourceList = ps.getCompileScopedArtefactResources()

[MSG]Violation in class None. getCompileScopedArtefactResources() can probably be rewritten as compileScopedArtefactResources

UnnecessaryGetter3219

[SRC]attribute(name:"Bundle-Version",value:"${metadata.getApp..Version()}")

[MSG]Violation in class None. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter3225

[SRC]switch (metadata.getServletVersion()) {

[MSG]Violation in class None. getServletVersion() can probably be rewritten as servletVersion

UnnecessaryGetter3258

[SRC]attribute(name:"Implementation-Version",value:"${metadat..Version()}")

[MSG]Violation in class None. getApplicationVersion() can probably be rewritten as applicationVersion

UnnecessaryGetter3259

[SRC]attribute(name:"Grails-Version",value:"${metadata.getGra..Version()}")

[MSG]Violation in class None. getGrailsVersion() can probably be rewritten as grailsVersion

UnnecessaryDefInMethodDeclaration3334

[SRC]protected def createDescriptorInternal(pluginInfos, resourceList) {

[MSG]Violation in class None. The def keyword is unneeded when a method is marked protected

UnnecessaryDefInMethodDeclaration3395

[SRC]private def warPluginsInternal(pluginInfos) {

[MSG]Violation in class None. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3405

[SRC]private def warPluginForPluginInfo(GrailsPluginInfo info) {

[MSG]Violation in class None. The def keyword is unneeded when a method is marked private

UnnecessaryGetter3497

[SRC]def version = metadata.getApplicationVersion()

[MSG]Violation in class None. getApplicationVersion() can probably be rewritten as applicationVersion

➥ _PluginDependencies.groovy

Rule NamePriorityLine #Source Line / Message
CyclomaticComplexity2

[SRC]true

[MSG]Violation in class None. The cyclomatic complexity for method [run] is [32]

UnusedVariable2151

[SRC]def application

[MSG]The variable [application] in class None is not used

EmptyCatchBlock2302

[SRC]catch (e) {

[MSG]The catch block is empty

UnusedImport317

[SRC]import grails.util.BuildSettings

[MSG]The [grails.util.BuildSettings] import is never referenced

UnusedImport320

[SRC]import grails.util.PluginBuildSettings

[MSG]The [grails.util.PluginBuildSettings] import is never referenced

UnusedImport326

[SRC]import org.codehaus.groovy.control.CompilationUnit

[MSG]The [org.codehaus.groovy.control.CompilationUnit] import is never referenced

UnusedImport328

[SRC]import org.codehaus.groovy.grails.documentation.DocumentationContext

[MSG]The [org.codehaus.groovy.grails.documentation.DocumentationContext] import is never referenced

UnusedImport329

[SRC]import org.codehaus.groovy.grails.documentation.DocumentedMethod

[MSG]The [org.codehaus.groovy.grails.documentation.DocumentedMethod] import is never referenced

UnusedImport330

[SRC]import org.codehaus.groovy.grails.documentation.DocumentedProperty

[MSG]The [org.codehaus.groovy.grails.documentation.DocumentedProperty] import is never referenced

UnnecessaryGetter352

[SRC]if (getBinding().variables.containsKey("_plugin_dependen..ed")) return

[MSG]Violation in class None. getBinding() can probably be rewritten as binding

UnnecessaryGetter3147

[SRC]def pluginFiles = pluginSettings.getPluginDescriptorsFor..nvironment()

[MSG]Violation in class None. getPluginDescriptorsForCurrentEnvironment() can probably be rewritten as pluginDescriptorsForCurrentEnvironment

UnnecessaryObjectReferences3308

[SRC]pluginInstallEngine.pluginDirVariableStore = binding

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3309

[SRC]pluginInstallEngine.pluginScriptRunner = runPluginScript

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3317

[SRC]GrailsResourceLoaderHolder.resourceLoader = new GrailsRe..vironment())

[MSG]Violation in class None. getArtefactResourcesForCurrentEnvironment() can probably be rewritten as artefactResourcesForCurrentEnvironment

Rule Descriptions

#Rule NameDescription
1AddEmptyStringFinds empty string literals which are being added. This is an inefficient way to convert any type to a String.
2AssertWithinFinallyBlockChecks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one.
3AssignmentInConditionalAn assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended.
4BigDecimalInstantiationChecks for calls to the BigDecimal constructors that take a double parameter, which may result in an unexpected BigDecimal value.
5BitwiseOperatorInConditionalChecks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable.
6BooleanGetBooleanThis rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop'].
7BrokenNullCheckLooks for faulty checks for null that can cause a NullPointerException.
8BrokenOddnessCheckThe code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.
9BusyWaitBusy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package.
10ChainedTestA test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another.
11ClassForNameUsing Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time.
12ComparisonOfTwoConstantsChecks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values., e.g.: 23 == 67, Boolean.FALSE != false, 0.17 <= 0.99, "abc" > "ddd", [a:1] <=> [a:2], [1,2].equals([3,4]) or [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE].
13ComparisonWithSelfChecks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x =>= x, x.equals(x) or x.compareTo(x), where x is a variable.
14ConsecutiveLiteralAppendsViolations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation.
15ConsecutiveStringConcatenationCatches concatenation of two string literals on the same line. These can safely by joined.
16ConstantAssertExpressionChecks for assert statements where the assert boolean condition expression is a constant or literal value.
17ConstantIfExpressionChecks for if statements with a constant value for the if expression, such as true, false, null, or a literal constant value.
18ConstantTernaryExpressionChecks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value.
19CoupledTestCaseThis rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused.
20CyclomaticComplexityChecks the cyclomatic complexity for methods/classes.A method (or "closure field") with a cyclomatic complexity value greater than the maxMethodComplexity property (20) causes a violation. Likewise, a class that has an (average method) cyclomatic complexityvalue greater than the maxClassAverageMethodComplexity property (20) causes a violation.
21DeadCodeDead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted.
22DoubleCheckedLockingThis rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern.
23DoubleNegativeThere is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well.
24DuplicateCaseStatementCheck for duplicate case statements in a switch block, such as two equal integers or strings.
25DuplicateImportDuplicate import statements are unnecessary.
26DuplicateMapKeyA map literal is created with duplicated key. The map entry will be overwritten.
27DuplicateSetValueA Set literal is created with duplicate constant value. A set cannot contain two elements with the same value.
28EmptyCatchBlockIn most cases, exceptions should not be caught and ignored (swallowed).
29EmptyElseBlockEmpty else blocks are confusing and serve no purpose.
30EmptyFinallyBlockEmpty finally blocks are confusing and serve no purpose.
31EmptyForStatementEmpty for statements are confusing and serve no purpose.
32EmptyIfStatementEmpty if statements are confusing and serve no purpose.
33EmptyInstanceInitializerAn empty class instance initializer was found. It is safe to remove it.
34EmptyMethodA method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation.
35EmptyStaticInitializerAn empty static initializer was found. It is safe to remove it.
36EmptySwitchStatementEmpty switch statements are confusing and serve no purpose.
37EmptySynchronizedStatementEmpty synchronized statements are confusing and serve no purpose.
38EmptyTryBlockEmpty try blocks are confusing and serve no purpose.
39EmptyWhileStatementEmpty while statements are confusing and serve no purpose.
40EqualsAndHashCodeIf either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden.
41EqualsOverloadedThe class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it.
42ExplicitGarbageCollectionCalls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself.
43ForLoopShouldBeWhileLoopA for loop without an init and update statement can be simplified to a while loop.
44HardCodedWindowsFileSeparatorThis rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant.
45HardCodedWindowsRootDirectoryThis rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative.
46ImportFromSamePackageAn import of a class that is within the same package is unnecessary.
47ImportFromSunPackagesAvoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.
48InconsistentPropertyLockingClass contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all.
49InconsistentPropertySynchronizationClass contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not.
50IntegerGetIntegerThis rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop'].
51JUnitAssertAlwaysFailsChecks for JUnit assert() method calls with constant arguments such that the assertion always fails. This includes: assertTrue(false), assertFalse(true) and assertNull(CONSTANT).
52JUnitAssertAlwaysSucceedsChecks for JUnit assert() method calls with constant arguments such that the assertion always succeeds. This includes: assertTrue(true), assertFalse(false) and assertNull(null).
53JUnitFailWithoutMessageThis rule detects JUnit calling the fail() method without an argument. For better error reporting you should always provide a message.
54JUnitPublicNonTestMethodChecks if a JUnit test class contains public methods other than standard test methods, JUnit framework methods or methods with JUnit annotations.
55JUnitSetUpCallsSuperChecks that if the JUnit setUp() method is defined, that it includes a call to super.setUp().
56JUnitTearDownCallsSuperChecks that if the JUnit tearDown() method is defined, that it includes a call to super.tearDown().
57JUnitTestMethodWithoutAssertThis rule searches for test methods that do not contain assert statements. Either the test method is missing assert statements, which is an error, or the test method contains custom assert statements that do not follow a proper assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test annotation. By default this rule applies to the default test class names, but this can be changed using the rule's applyToClassNames property.
58JUnitUnnecessarySetUpChecks for JUnit setUp() methods that contain only a call to super.setUp().
59JUnitUnnecessaryTearDownChecks for JUnit tearDown() methods that contain only a call to super.tearDown().
60MisorderedStaticImportsStatic imports should never be declared after nonstatic imports.
61NestedSynchronizationNested synchronized statements should be avoided. Nested synchronized statements are either useless (if the lock objects are identical) or prone to deadlock.
62RandomDoubleCoercedToZeroThe Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug.
63RemoveAllOnSelfDon't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException.
64ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
65SpockIgnoreRestUsedIf Spock's @IgnoreRest appears on any method, all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed.
66StaticCalendarFieldCalendar objects should not be used as static fields. Calendars are inherently unsafe for multihtreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
67StaticConnectionCreates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions.
68StaticDateFormatFieldDateFormat objects should not be used as static fields. DateFormat are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
69StaticMatcherFieldMatcher objects should not be used as static fields. Matcher instances are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
70StaticSimpleDateFormatFieldSimpleDateFormat objects should not be used as static fields. SimpleDateFormat are inherently unsafe for multi-threaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
71SynchronizedMethodThis rule reports uses of the synchronized keyword on methods. Synchronized methods are the same as synchronizing on 'this', which effectively make your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.
72SynchronizedOnBoxedPrimitiveThe code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock
73SynchronizedOnGetClassSynchronization on getClass rather than class literal. This instance method synchronizes on this.getClass(). If this class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended.
74SynchronizedOnReentrantLockSynchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method.
75SynchronizedOnStringSynchronization on a String field can lead to deadlock because Strings are interned by the JVM and can be shared.
76SynchronizedOnThisThis rule reports uses of the synchronized blocks where the synchronization reference is 'this'. Doing this effectively makes your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.
77SynchronizedReadObjectMethodCatches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style.
78SystemRunFinalizersOnExitMethod calls to System.runFinalizersOnExit() should not be allowed. This method is inherently non-thread-safe, may result in data corruption, deadlock, and may effect parts of the program far removed from it's call point. It is deprecated, and it's use strongly discouraged.
79ThreadGroupAvoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe.
80ThreadLocalNotStaticFinalThreadLocal fields should be static and final. In the most common case a java.lang.ThreadLocal instance associates state with a thread. A non-static non-final java.lang.ThreadLocal field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior.
81ThreadYieldMethod calls to Thread.yield() should not be allowed. This method has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions.
82ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
83UnnecessaryBigDecimalInstantiationIt is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G.
84UnnecessaryBigIntegerInstantiationIt is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G.
85UnnecessaryBooleanExpressionChecks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or a Map/List/String/Number literal. Also checks for negation (!) of true, false, null, or a Map/List/String/Number literal.
86UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
87UnnecessaryCallForLastElementThis rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a get, getAt, or array-style access is used with an object size check.
88UnnecessaryCallToSubstringCalling String.substring(0) always returns the original string. This code is meaningless.
89UnnecessaryCatchBlockViolations are triggered when a catch block does nothing but throw the original exception. In this scenario there is usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out.
90UnnecessaryCollectCallSome method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect { it.multiply(2) } can be replaced by list*.multiply(2).
91UnnecessaryCollectionCallUseless call to collections. This call doesn't make sense. For any collection c, calling c.containsAll(c) should always be true, and c.retainAll(c) should have no effect.
92UnnecessaryConstructorThis rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments.
93UnnecessaryDefInFieldDeclarationIf a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}.
94UnnecessaryDefInMethodDeclarationIf a method has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'.
95UnnecessaryDefInVariableDeclarationIf a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'.
96UnnecessaryDotClassTo make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String.
97UnnecessaryDoubleInstantiationIt is unnecessary to instantiate Double objects. Instead just use the double literal or the 'D' identifier to force the type, such as 123.45d or 0.42d.
98UnnecessaryElseStatementWhen an if statement block ends with a return statement the else is unnecessary. The logic in the else branch can be run without being in a new scope.
99UnnecessaryFailIn a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all.
100UnnecessaryFinalOnPrivateMethodA private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary.
101UnnecessaryFloatInstantiationIt is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f.
102UnnecessaryGetterChecks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). Getters do not take method arguments.
103UnnecessaryGroovyImportA Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger.
104UnnecessaryIfStatementChecks for if statements where the if and else blocks are merely returning true and false constants. These cases can be replaced by a simple return statement.
105UnnecessaryInstanceOfCheckThis rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean.
106UnnecessaryInstantiationToGetClassAvoid instantiating an object just to call getClass() on it; use the .class public member instead.
107UnnecessaryIntegerInstantiationIt is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i.
108UnnecessaryLongInstantiationIt is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L.
109UnnecessaryModOneAny expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2).
110UnnecessaryNullCheckGroovy contains the safe dereference operator, which can be used in boolean conditional statements to safely replace explicit "x == null" tests.
111UnnecessaryNullCheckBeforeInstanceOfThere is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.
112UnnecessaryObjectReferencesViolations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block.
113UnnecessaryOverridingMethodThe overriding method merely calls the same method defined in a superclass
114UnnecessaryPackageReferenceChecks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, java.util.Map and groovy.lang.Closure.
115UnnecessaryParenthesesForMethodCallWithClosureIf a method is called and the only parameter to that method is an inline closure then the parentheses of the method call can be omitted.
116UnnecessarySelfAssignmentMethod contains a pointless self-assignment to a variable or property.
117UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
118UnnecessarySubstringThis rule finds usages of String.substring(int) and String.substring(int, int) that can be replaced by use of the subscript operator. For instance, var.substring(5) can be replaced with var[5..-1].
119UnnecessaryTernaryExpressionChecks for ternary expressions where the conditional expression always evaluates to a boolean and the true and false expressions are merely returning true and false constants. Also checks for ternary expressions where both expressions are the same constant or variable.
120UnnecessaryTransientModifierThe field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect.
121UnusedArrayChecks for array allocations that are not assigned or used, unless it is the last statement within a block.
122UnusedImportImports for a class that is never referenced within the source file is unnecessary.
123UnusedMethodParameterThis rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override.
124UnusedObjectChecks for object allocations that are not assigned or used, unless it is the last statement within a block
125UnusedPrivateFieldChecks for private fields that are not referenced within the same class.
126UnusedPrivateMethodChecks for private methods that are not referenced within the same class.
127UnusedPrivateMethodParameterChecks for parameters to private methods that are not referenced within the method body.
128UnusedVariableChecks for variables that are never referenced.
129UseAssertEqualsInsteadOfAssertTrueThis rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.
130UseAssertFalseInsteadOfNegationIn unit tests, if a condition is expected to be false then there is no sense using assertTrue with the negation operator. For instance, assertTrue(!condition) can always be simplified to assertFalse(condition)
131UseAssertNullInsteadOfAssertEqualsThis rule detects JUnit calling assertEquals where the first or second parameter is null. These assertion should be made against the assertNull method instead.
132UseAssertSameInsteadOfAssertTrueThis rule detects JUnit calling assertTrue where the first or second parameter is an Object#is() call testing for reference equality. These assertion should be made against the assertSame method instead.
133UseAssertTrueInsteadOfAssertEqualsThis rule detects JUnit calling assertEquals where the first parameter is a boolean. These assertions should be made by more specific methods, like assertTrue or assertFalse.
134UseAssertTrueInsteadOfNegationIn unit tests, if a condition is expected to be true then there is no sense using assertFalse with the negation operator. For instance, assertFalse(!condition) can always be simplified to assertTrue(condition)
135UseOfNotifyMethodThis code calls notify() rather than notifyAll(). Java monitors are often used for multiple conditions. Calling notify() only wakes up one thread, meaning that the thread woken up might not be the one waiting for the condition that the caller just satisfied.
136VolatileArrayFieldVolatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not.
137VolatileLongOrDoubleFieldLong or double fields should not be declared as volatile. Java specifies that reads and writes from such fields are atomic, but many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronize access to such fields rather than declare them volatile. This rule flags fields marked volatile when their type is double or long or the name of their type is "Double" or "Long".
138WaitOutsideOfWhileLoopCalls to Object.wait() must be within a while loop. Consider using the Java concurrency utilities instead of wait() and notify().
CodeNarc-0.23/src/site/resources/StarterRuleSet-AllRulesByCategory.groovy.txt0000644000175000017500000002463712470770456026770 0ustar ebourgebourgruleset { description ''' A Sample Groovy RuleSet containing all CodeNarc Rules, grouped by category. You can use this as a template for your own custom RuleSet. Just delete the rules that you don't want to include. ''' // rulesets/basic.xml AssertWithinFinallyBlock AssignmentInConditional BigDecimalInstantiation BitwiseOperatorInConditional BooleanGetBoolean BrokenNullCheck BrokenOddnessCheck ClassForName ComparisonOfTwoConstants ComparisonWithSelf ConstantAssertExpression ConstantIfExpression ConstantTernaryExpression DeadCode DoubleNegative DuplicateCaseStatement DuplicateMapKey DuplicateSetValue EmptyCatchBlock EmptyClass EmptyElseBlock EmptyFinallyBlock EmptyForStatement EmptyIfStatement EmptyInstanceInitializer EmptyMethod EmptyStaticInitializer EmptySwitchStatement EmptySynchronizedStatement EmptyTryBlock EmptyWhileStatement EqualsAndHashCode EqualsOverloaded ExplicitGarbageCollection ForLoopShouldBeWhileLoop HardCodedWindowsFileSeparator HardCodedWindowsRootDirectory IntegerGetInteger MultipleUnaryOperators RandomDoubleCoercedToZero RemoveAllOnSelf ReturnFromFinallyBlock ThrowExceptionFromFinallyBlock // rulesets/braces.xml ElseBlockBraces ForStatementBraces IfStatementBraces WhileStatementBraces // rulesets/concurrency.xml BusyWait DoubleCheckedLocking InconsistentPropertyLocking InconsistentPropertySynchronization NestedSynchronization StaticCalendarField StaticConnection StaticDateFormatField StaticMatcherField StaticSimpleDateFormatField SynchronizedMethod SynchronizedOnBoxedPrimitive SynchronizedOnGetClass SynchronizedOnReentrantLock SynchronizedOnString SynchronizedOnThis SynchronizedReadObjectMethod SystemRunFinalizersOnExit ThisReferenceEscapesConstructor ThreadGroup ThreadLocalNotStaticFinal ThreadYield UseOfNotifyMethod VolatileArrayField VolatileLongOrDoubleField WaitOutsideOfWhileLoop // rulesets/convention.xml ConfusingTernary CouldBeElvis HashtableIsObsolete IfStatementCouldBeTernary InvertedIfElse LongLiteralWithLowerCaseL NoDef ParameterReassignment TernaryCouldBeElvis VectorIsObsolete // rulesets/design.xml AbstractClassWithPublicConstructor AbstractClassWithoutAbstractMethod BooleanMethodReturnsNull BuilderMethodWithSideEffects CloneableWithoutClone CloseWithoutCloseable CompareToWithoutComparable ConstantsOnlyInterface EmptyMethodInAbstractClass FinalClassWithProtectedMember ImplementationAsType Instanceof LocaleSetDefault NestedForLoop PrivateFieldCouldBeFinal PublicInstanceField ReturnsNullInsteadOfEmptyArray ReturnsNullInsteadOfEmptyCollection SimpleDateFormatMissingLocale StatelessSingleton ToStringReturnsNull // rulesets/dry.xml DuplicateListLiteral DuplicateMapLiteral DuplicateNumberLiteral DuplicateStringLiteral // rulesets/enhanced.xml CloneWithoutCloneable JUnitAssertEqualsConstantActualValue UnsafeImplementationAsMap // rulesets/exceptions.xml CatchArrayIndexOutOfBoundsException CatchError CatchException CatchIllegalMonitorStateException CatchIndexOutOfBoundsException CatchNullPointerException CatchRuntimeException CatchThrowable ConfusingClassNamedException ExceptionExtendsError ExceptionExtendsThrowable ExceptionNotThrown MissingNewInThrowStatement ReturnNullFromCatchBlock SwallowThreadDeath ThrowError ThrowException ThrowNullPointerException ThrowRuntimeException ThrowThrowable // rulesets/formatting.xml BlankLineBeforePackage BracesForClass BracesForForLoop BracesForIfElse BracesForMethod BracesForTryCatchFinally ClassJavadoc ClosureStatementOnOpeningLineOfMultipleLineClosure ConsecutiveBlankLines FileEndsWithoutNewline LineLength MissingBlankLineAfterImports MissingBlankLineAfterPackage SpaceAfterCatch SpaceAfterClosingBrace SpaceAfterComma SpaceAfterFor SpaceAfterIf SpaceAfterOpeningBrace SpaceAfterSemicolon SpaceAfterSwitch SpaceAfterWhile SpaceAroundClosureArrow SpaceAroundMapEntryColon SpaceAroundOperator SpaceBeforeClosingBrace SpaceBeforeOpeningBrace TrailingWhitespace // rulesets/generic.xml IllegalClassMember IllegalClassReference IllegalPackageReference IllegalRegex IllegalString IllegalSubclass RequiredRegex RequiredString StatelessClass // rulesets/grails.xml GrailsDomainHasEquals GrailsDomainHasToString GrailsDomainReservedSqlKeywordName GrailsDomainWithServiceReference GrailsDuplicateConstraint GrailsDuplicateMapping GrailsMassAssignment GrailsPublicControllerMethod GrailsServletContextReference GrailsSessionReference // DEPRECATED GrailsStatelessService // rulesets/groovyism.xml AssignCollectionSort AssignCollectionUnique ClosureAsLastMethodParameter CollectAllIsDeprecated ConfusingMultipleReturns ExplicitArrayListInstantiation ExplicitCallToAndMethod ExplicitCallToCompareToMethod ExplicitCallToDivMethod ExplicitCallToEqualsMethod ExplicitCallToGetAtMethod ExplicitCallToLeftShiftMethod ExplicitCallToMinusMethod ExplicitCallToModMethod ExplicitCallToMultiplyMethod ExplicitCallToOrMethod ExplicitCallToPlusMethod ExplicitCallToPowerMethod ExplicitCallToRightShiftMethod ExplicitCallToXorMethod ExplicitHashMapInstantiation ExplicitHashSetInstantiation ExplicitLinkedHashMapInstantiation ExplicitLinkedListInstantiation ExplicitStackInstantiation ExplicitTreeSetInstantiation GStringAsMapKey GStringExpressionWithinString GetterMethodCouldBeProperty GroovyLangImmutable UseCollectMany UseCollectNested // rulesets/imports.xml DuplicateImport ImportFromSamePackage ImportFromSunPackages MisorderedStaticImports NoWildcardImports UnnecessaryGroovyImport UnusedImport // rulesets/jdbc.xml DirectConnectionManagement JdbcConnectionReference JdbcResultSetReference JdbcStatementReference // rulesets/junit.xml ChainedTest CoupledTestCase JUnitAssertAlwaysFails JUnitAssertAlwaysSucceeds JUnitFailWithoutMessage JUnitLostTest JUnitPublicField JUnitPublicNonTestMethod JUnitPublicProperty JUnitSetUpCallsSuper JUnitStyleAssertions JUnitTearDownCallsSuper JUnitTestMethodWithoutAssert JUnitUnnecessarySetUp JUnitUnnecessaryTearDown JUnitUnnecessaryThrowsException SpockIgnoreRestUsed UnnecessaryFail UseAssertEqualsInsteadOfAssertTrue UseAssertFalseInsteadOfNegation UseAssertNullInsteadOfAssertEquals UseAssertSameInsteadOfAssertTrue UseAssertTrueInsteadOfAssertEquals UseAssertTrueInsteadOfNegation // rulesets/logging.xml LoggerForDifferentClass LoggerWithWrongModifiers LoggingSwallowsStacktrace MultipleLoggers PrintStackTrace Println SystemErrPrint SystemOutPrint // rulesets/naming.xml AbstractClassName ClassName ClassNameSameAsFilename ConfusingMethodName FactoryMethodName FieldName InterfaceName MethodName ObjectOverrideMisspelledMethodName PackageName PackageNameMatchesFilePath ParameterName PropertyName VariableName // rulesets/security.xml FileCreateTempFile InsecureRandom JavaIoPackageAccess NonFinalPublicField NonFinalSubclassOfSensitiveInterface ObjectFinalize PublicFinalizeMethod SystemExit UnsafeArrayDeclaration // rulesets/serialization.xml EnumCustomSerializationIgnored SerialPersistentFields SerialVersionUID SerializableClassMustDefineSerialVersionUID // rulesets/size.xml AbcComplexity // DEPRECATED: Use the AbcMetric rule instead. Requires the GMetrics jar AbcMetric // Requires the GMetrics jar ClassSize CrapMetric // Requires the GMetrics jar and a Cobertura coverage file CyclomaticComplexity // Requires the GMetrics jar MethodCount MethodSize NestedBlockDepth ParameterCount // rulesets/unnecessary.xml AddEmptyString ConsecutiveLiteralAppends ConsecutiveStringConcatenation UnnecessaryBigDecimalInstantiation UnnecessaryBigIntegerInstantiation UnnecessaryBooleanExpression UnnecessaryBooleanInstantiation UnnecessaryCallForLastElement UnnecessaryCallToSubstring UnnecessaryCast UnnecessaryCatchBlock UnnecessaryCollectCall UnnecessaryCollectionCall UnnecessaryConstructor UnnecessaryDefInFieldDeclaration UnnecessaryDefInMethodDeclaration UnnecessaryDefInVariableDeclaration UnnecessaryDotClass UnnecessaryDoubleInstantiation UnnecessaryElseStatement UnnecessaryFinalOnPrivateMethod UnnecessaryFloatInstantiation UnnecessaryGString UnnecessaryGetter UnnecessaryIfStatement UnnecessaryInstanceOfCheck UnnecessaryInstantiationToGetClass UnnecessaryIntegerInstantiation UnnecessaryLongInstantiation UnnecessaryModOne UnnecessaryNullCheck UnnecessaryNullCheckBeforeInstanceOf UnnecessaryObjectReferences UnnecessaryOverridingMethod UnnecessaryPackageReference UnnecessaryParenthesesForMethodCallWithClosure UnnecessaryPublicModifier UnnecessaryReturnKeyword UnnecessarySafeNavigationOperator UnnecessarySelfAssignment UnnecessarySemicolon UnnecessaryStringInstantiation UnnecessarySubstring UnnecessaryTernaryExpression UnnecessaryToString UnnecessaryTransientModifier // rulesets/unused.xml UnusedArray UnusedMethodParameter UnusedObject UnusedPrivateField UnusedPrivateMethod UnusedPrivateMethodParameter UnusedVariable }CodeNarc-0.23/src/site/resources/images/0000755000175000017500000000000012623571301017456 5ustar ebourgebourgCodeNarc-0.23/src/site/resources/images/codenarc-logo.png0000644000175000017500000007725711616364172022731 0ustar ebourgebourgPNG  IHDRf>sRGBbKGDC pHYs.#.#x?vtIME & IDATxw|%u̜޶$ٜ˖ޤ( vݵ\byUDEw"; ȕPIvv7dkzr&_fux3eAw7 @cB^͝[ѢXxvᥥo*2v5ѷC[yH;g[f4и5X jح̔ǎ(EǏbF ECb$7 laxg`WkǢ%nXC2 0LKIJ(XN@ 11L՘$IBuI`@k20{%5GjO4v1X0}vls[>zdm}/J_fIt{w}Vu- J @QxUF15ijo<~%&W>)QXҀåy2i& ox1 L\@3Q4uX|2}$ @B #  XUvǺ|x _IjhJ6D$Xj!xÈAU.lKV jJfTkj`?mM۞Y | +"l7[-"@^- k/H^ߴny4?V_fltJmԳ8ٛ7USTYM\b1USlB=ؙQ?us=U->oJ q4\W_|!\|:= __5p0cA]GɐN'o>cacN4k%)@A #$"NUgnp&pII"E1@UWll&/>̓u@/pas]8Ŀ49xY3T+0ʥMQ\>W;J!$i@@DTa۱_ 'v?cpr& /UXDo=vӻ~rޑUd84`jn;sSѓ:. =."+m(ئb+⇫kg$q lAT]U'8ثRni[?xCEP)@ApPmڶyMϝ&q%bgNz'b!Dqqlyinޢo?+@oޤOj\V!19EDn{oG`E N t7`APEa47Eua @ iyh|H7:šNhr8¯EH%@w7h{^Un/ u[|wow]{e@]v:#v*71{# PGGpW","8?OP׹Ny 9ɦqNs7_nmU4fC @@T~ ([͛߀U&%ҹ(&al?"aaXaXoRoD&y r @kh8)}VDRG N抒á&cCj;3c'\Wtp{^i @@w0k*ښW5,6u\ PUD4u I0C5`'e|rH`p^ cbbc.(#)>Ʀ5D-?KXٽ^_Mh 4,Y˾Uz~%v6ew%6?ѴmcKmsZy>oU?0LjH"Tά';˃@|79`bV+\Hɦ}_˼pJRU|/f˻Ȃ³-wSPƮ>{0eh^DbC L Xt*CW|DdO8C⚢isE t'3Cؙat׵1G1bXXV3 E1(F(*F(lioisIoEuk:ڶ5}lf7и(7zCזuLVzv|h5w.I`š\jc-iWڰdKB}cSh{90 twYǺ̻*bgRLbk'p0n6dQ@0C8bp 3RiE (T$Խ:3rU}p;p+EKqjatQɥU>lVEi17)%/Ag#ʀaVKtSÒ ɦD[U]1j$Z4-T[ ˁsUg`m_UPV]-N6=[eg+Ɂ< g"Z4PaVÊ b.N NE'3DYcq-HlL{^ |Ѧ ĸ4u)0 WIxfL=j#b4,c˪Omr >=L,1"ٻtb@ؙ cĖʆ~ڗ>Ѷ_rRQٽ ,vXAwo,>s%ة4bVˤ18,.n8M(}&%kaE\tamlM-U"_u?e P4d4ivIUR,P @}#wOd%N6M:9ƈ~BU}%jf2zS>+le.Qض4l>k;XR_u#];w5?BqG-;N#}fZ^p92fʧC熫BˢHJv8vV!.7(Xg ]ڭg;:q 7ILH7 z{'R ]ߋk-I9ryb1"*e+ffyRodΊ./sC6C\%<}Vi)[qiEsO+)-@;Cdi'.\G?zp+5qfbj wVenɸ!E$k}ﻛ@sE=M=m  CT0!B\""U5uжjQucnv;:6dQukڨx뺠꺨:...bNMvj/PCuE0{ຫPf>>Y0s'VU+foT׎oU 8ڶ3+U_u;=ڽdfEkzfHlgx}9i۳ l+vj+v*gb` E>Q[]uTݜ u]#u׵εďz+%, -n: 25JiZ [ZrH_d&s [ױ;^>6LHTq-!VH$S},ZPM:qnS7?Di'+aㆅaF 1 0s`^N.68YpDk8kgٺdFp-uӮ>#"mlo@NݦdcML2lCp!"r~pOpqe,b(#g4ݵm4=uz:i?μ+67[IQ#7k ` KEId\JU %G*-ayo`B4ϖ#ۡ(lxN%ˋ6MvӾe+NWɈdPa NqijqD+sڀi!fôPiVwQS<! ,BN ٲ{Q8OOmnshl DyAMٖx-!e.~ۯ[}E׵?JM} c;iO;#qlΙF:ߨcӻ"No<^Jy?!J;FH{pA㋡K%9;T矷EI`oo"ӏ ,VdlXt":v1қvY̙1xTƏ$Z4 s<7Ʋ0iyc` l~ D8VBśJ[Ѣ*&_4uuž<[;X8HFK]=9{ueiQnN#=߾^7?zl~jΤ"~8#'7! iY l:jN[+/~gԾ|pUZJY˩:k9󟿔H *19A>HL,@1mB&Xo`]6=$6'Nj66$giR"? Ocp`r=c듷ӳIC ӔhɌ~#%j?KU,"-"8PYѻUE UhraۻBo\aDSx_?gZAD?DD? dDkkUq MlX|e^tK!״3s̭ƈ)\8'dT]R]a` HaK|ES? ߿?@B=az62$?zly PPčXz,Rn/rXUSwHd(?g箮6O3}i9j;u3uoX <vg燻v]Nk>X%sigΞǜ|;p՜Ľ*[دj89sh "0zگ݅.b"%=Ԭ/f#Xd^sp3O e6o5 Q@QU3C=hgD0߹-Of9v.IP 3DPa;nY7|JU#"olo}lUeeW^?6=cEoUM^6~Y_ҷnx]]ߎCױ$߆杻%__SDhܦX>鼌C=?cյuLi(bȟL7+-(|YXκp@bVׁCkg3|)#L4{|}um|BKD%e%z\<[{ǩjUMD>sfUMݪ]f " Ȼkl1:XMU/QibW<-F.qMbxobP֑"###0U.l[&L6 =˓oTG'K%7b'E![s5^O폓ITp]=>(F4VYkViIl܄Y4F:Gi 7csN_*kIMMa`#1OF>Z0 +PyfK,^y iS+լ3wۀ:CvP \ ^U|*"!r~6obioޖ؟N@Lr+w>>VDޭ-I'w>^;XO"bWUյ||9ʘ"1Lef}vumt_ p Pc "#"?m:U5uT`1/Uדw'Mm/"7ͳ?=sH js s{{{6&%9N~Al $0¨dwba?sBtzN>ם KYXJ)&:'쾫{`=*Vq!u%:Oybù(1a.H)hLLjpmd ?!]B"B(RUMo\\mʤjhd_5J"&hT>VVUDu_aS F[USW*"WjĿ@uvUMF!`p9T6niY3pD F$/VFyPժI)z;`'cZ"r.}oT}0x=*ևؚo Zյw*յqSU? Vfe IDATY=t0׎=Su7pb2ĖTmbأE\3R\VFբ7aƦnH&\Q:QL6E1j.|f[ۍto~UK5YK zvclT͋/2ky?䙏}L,^B >:"]4h '`,mMD Jf,LfY˾6 CE,౦ks2U˪plߴzߊt^(N>7_?RQm9s~n~.o]\' pPUߔCm&'U=!C.V+VM󭱅]|R";U53Gڸ'7>ZU]^(*Oy'z+c U={qPՋEP!oOSxC 4X5_qPŠ 3Ѧ󇛚X|6Ѳ9+Eipg8+1vև."̥f,y#'Y@SÔq)~1ʁo2)8j7}&Oz>J`wRg2U@ʮwX NU|ه9i+'#^f_USg:`,"H!\7yndLyuSG۠BU[M0?Uw"\6c%5#V163bdz{1 hJ(:ln*E3R4*y=o/%Ke;ClMt8b@!|B8oרvTU/""3}$2""G" UsD&&y7$rjQT7%@á\7>­:qxAD?3"gD^|585bR94"%ɑ&YIzv/TWK?m[n͍c0Prd=E˖a=yy4lptaz5Z*`- ^;tH/%;[fD(|OlW#O񣜢N7[ S{֓: e|OhJbҿ&Jwmy9iϺV_un"ohLM++:.{wo~[69s;5T"bXb+'& 3羅R> uJѫXt7}̝C'a(D1G^KGXټy7 V)& I: G @0OJ~!֋Ѭ݁),$[4:>J dڂתp 1e&"+[o V-rN8o<'2ȈH`nL`y6 M:$OjDDjhi7NxKo.>}L:-Z)iH$)-aE9: s1KvlOO739 ,.#PF-!=0H{y'B 3(\aYB;R!zF@1H 2 #$dzέޜ1#y~INjR "%)]1.tK]@sc{ 1GSyigCVU}pDf1v@ 8 G3ʋD:Q̿W>{c\ hWտ[g92Dd;j !U3EUNv=THGdgIzW!"$FrAIZNxo5x=3<{y ({6iGUq)Tk>c{-B5JȟU{}ssM[yOAQpX"5)ƈI@(λGwywaˏ~J.:-E&^v\-E03L{nfQ]YYTNd)s; s &5 ljȼrX.Av_J^l0b[XBp!fPC)PNjlo}`^RF=!vPJ'T{E5c|xnPlb Nr$caHft^С$|-"7/*_d'ݾOn$W#KsUKdKȷe^Ρ(i1/uxY/7/"r7f5^}+ӨTDC8A"TJ,__ɦJ1"B;GXoor'j<8:#C-Q^;l쾽oLlw/C?Ͷ_uW_͓߿v N/ }).He(,(IQQќ#ȓa[PA gw:G"HV人\tKIz~|B`>0s ':܅mwx2U54P&"յ"Oxd?O0XS'no,|%E$)"Nl͇IJ DwD( /#ryR)ܣI-}xۡ>VU:txU{9伱tWt'SGO7z jbU]x{.߳\{c k2F +%-JhCIcNTbۋu_A*n͎Q2q6ف!~R;vзy<IrVsH9ƝqLdX߾]TWDLj*Cخw20rY{w[e!B#Hۆ)XZi*VpW8.W4c"Է[\Ȋb3񄙷GbRU]2y(ﰻO("EDm7xe1q}^8)XDd| +:GϋWq-"ҧ~NDTU)<#_+jN$#W-FTuxՊchO4@yжWt_?j|SyĔ J|ơ7f{VDp1" یdICST(&|~[̏,dplv13Kн{݃dm95"ٺq(/eGvcC 2Y0!wa ³*0cap\d96VXP1h膖xC55&Q@˦xKXtLg&+"s`&RWӈJĶ<_D#17w HUϙUPi=)gΝ/>jUEdgii|WqS٣ITʑ0#,<9 9f*%rzLA#_IaUW3.r[`X1ʘ`b&Νh( wB~\Ɏu" .>0[fKoʹfV۟@XX Ͼd! ]60 \vs Y^ {I(ňs&L(8ٴPl|JU?LjkfdS+:{f4E`q ojDq'8VU'{''P]c64wJf21UdTu2yˏm+:~G?>2"2b^URUOU 2B)+9f~NO6cEkn(&S<݃+:_=0SUB~$8yL!`'U' hx( $ux1CRA$W@+c={R.`vbn1Kfژ̫$ə2Ma,̜r~yx3eXE& ']z\jL""1Q%TV RrPWlu]GL5~W}4NDռFv ng_"hx ʮ|'׻8LD|<"7UôwWEdD_?y)UՓ' [ٞm0{0'|w=Ms2M*o+ 0NTSH""sVYu6>+_\ϪVvul'"wou"WYx\Di>4Tvݥe|ל61\M'' zҬ! lMٵ4M,bq6o를8ʜ 0dƦ0p vޛ tyazmFYi)ٔCAEii03䅷 C0P<˝0Xt6cK8H SF]&s@3eE."P4uזd+"q~=|w+:յ+\8wtlQu r hnjɗ|O )ܙ""Nj*[]?] UQK+:z9m֩I/o{2jqp*NGhntumOajvVꑓhz}:~Vk$Ps]}g/v=Q;Q}:uCEQ4l! !3-GQ$\xV6Շ}f/bg\?EUOSղIڒ/}LUUuTBx/O{<iQSptȣٴ0žSDT^{um|GLdwVvul#[#wyi}i#Wc9(,{Ż׿"?d}/@XjbU"G;7UO L@]{+xsFYG5@]F_ǐ >BP ɺ 1PYZP2pH"^^D&kgh$)BmU!Om}f*Ƶ+1Gk&f?r0"QܤW59GC!PF2 j?:"rZMT 7y"⮮?x ! OU1Pվ]c~|q>ar7֯jr߉Y&!'U5uQ9ȩi1q2J%-.&ޙQyT{O:[ެkXDDܺAFų3#3: t+MX{Y}z?ܤɧ;}s{#"G_(]7ṷ'.7ĂozYUQfU_0S/^Гdfh Ph7n&6c5.Lglq5 3YH 1q1cTZ27p,o+l~2g B%AQS?l]Eo/yb IDATࠞR&P6>EU+8Sr=\cP&6I}sSض#wDsj)AYPg7-'`*W'LlUvm | q-{Hw`+AT n%I)ERD+h'۞z:ҭ_0g:3kr]$T1LnJz`-|KDdpLYrE3׷&)"LuLL`B#6Kw+/k\f\!Q`9س iӥ BUzpfjq; -= ^`g2BU},k_>JUe]INU74m:X:ø*OTYW˗d@ɝXT,ա)sni*H| LD"E\ S[ W"^_ *"r6~KNDmNzqu{EH$OOs}K#9uK J49 x 7p]Xԡz$XBX4'|w0 dNqϧ!7ɊI{{AXJF1 !Bx 8Ě^Pͽ쥪)<ơgyHH3k6$DUup[DDRDm0晘=R[l{AUJ2CLjoٞ́18j6M"4<7I^sTIlwL"8Bw?iϙX* k+ϻ%6; ED#"+f*.[Ddd:wN3$ "eU}tznϰ:3?}q~)E%`T$yVDء^&K:+^3$'V*XΤ{eq=NЄgh^)0xd%x^=шcYJeް-Hw{i=ˏ; ፎUӸBnn + Lvz5Rض<&:EBqni\ˆY4ZĹ+*4&Vt33KpI`xtm=,?EDZ&LZ2^=3A+mgY$L7T4.5=!rUmA?9utklT*io'EiL~s-(=is3DdXU?qAOgת/" _tgv}tJB8b:9~YK&Sg{%ӐZfR *nL6 6}{^K6I TS* i^T$q$ Nχc25E͵$o>I"6#~N\Uq+%~߶9N>flf$gu^K訏 Ls}8& = 8ĢDb)":ƚ\{EQwf變!d!<("?*mdfCU-{{U?v!c$Y`nMga|b4Գ̿T'vTu4}+4%yzx ,MVU*~e=Ͷxs|YU,ܫx 3Mnf-KwXzU@_~}䉆i12@TZ;3ٹ~AUѾK+;Dc/(Qޅ_3A['JCƶmш͂Z6n-۲H%bm #vr8ͯ0?JT"IwRI7.V4D }wxgn v*%jnf-k@z88xn 8[+NݻUd'۷% ag;ҭuH* L/LԦB~nUzhw:U=͚yr"ZinCռ$57Or-VUg;AV Xc%sh*-9U?O>`SGr(va |~|*:ɘ끓T53 wT=xYK8q5dHOC("X@&:E ,"jKtUkegEⰸ@D^TIJxcYL A'Yת({.mlhǶF){>mİxr+5uumJ^qq1ıТ02RcMn9Dؑ1>8W5?pwܙ3=h!hs"CB;uf-τ&=7VXE'7_>d`fS]'!"߭ٞcg ^'"MjDv׊ȻDS`9T޿ 񹠏#Ph!UM`Tn{di!kHod0OP8:ۧ'?aKpO4,YtNfYM"UՆ2k#&Y=_~D~4im߮Ӎ鐲*i AS/[ś}-XXbؖHP3vRpR@hg4]iK~ȣv2y^F XMAO0ׇZppbQh;²$0G0y%궇nl> krugoNmGgj4̷M@#l`ɰf{~e-ˁDXU}a\LjLj+mNIOU1Q=MnTKkD8CMQDnSٻ:rPdH>kR](+`6lylZOnuK25/_ޮ&PAĄ8L{Fhn6N<ⰫzAr®#߼#5i^-v٥T.7z P} ~D ǀ]{HS4̟͸(Rg!5L N4IraX0F>>{@ͪݧܙ~~ xᇿL7A*h 0y63My搞6p*XYKq)6ddaaϗT<g'!;@u2& dfyݳ=""[H^bi  r 0_Ūѐ!tKcYGfL^8MC]q -=ltQz p INت8=l]:UPQQzĵ//8ٿ& -ѴZVH4~ 8KWsK2y(#q M%#$d6Q[ԝrR+3a37G۱'>}! +kYƊDvƷl!uppXSęt5}bw v+y ǼK't(uۖPiiTg=00<2}Lwυ\La1_~-i䟳>8XFټtpP1PQ\ pBUo}=VU?T DblSAE8zRKC>}GGp"6G/9u&cw !8{ ץz(?z?p6C]3g|k~w{gZԝ״P0`xo|= ێ[("SKI!0'SI}% }HF%u 96X=LAgrq;=rU7e >5Qy^Me!MvFL^;=gB|0טO6yϴ- tX{H!"ɤ<ȼS^iu4̿bG ~cP(XzʞG-eK/_7}'G}q~sW1tf߂,M9 ?=Q>jqVbrppqIߖ{ٛ{t8hA}g{"np54OUk{ &l ؞."t+"1n~>)fa¦+0ږ+9XŤ3 OTU~赨)~,s9o2t-"y 3x)绽vr;ҭsTQ+7zadL`blS^ijp(k_K$WfpdJm'YǟȪeMغ{MdoJ`0i'ufsl6VG? %"W+_k:d xuZU?L@nƬW"QrRC}orppn\D6/ĉncJQwj:L{M:4DO89#z:cH"vݏ+Y|9-btv-Ė#~qıߜclK"6Nl"8# ;NL3?>}G?v-s]E+]E R[ycF&8_8{0LRUM"rJ@P$33}dՑn=yHŊ"wԷ꭪z ,RW6[_I4Nt3tӑnMd^UDjTxCP'" #^s~9ϵ81?ʣkW1C{X zx"jVL[s n<=4>`ȴt+ɸiJzG9=h@;? p<[ʂwunW4VPRHui>TRۀuD1 !KP/}[|eJʝu׭:}^&Ͽ\l\t^n <Z#:ODE%۳=_g&[,SX6SD\ޅnܞpyh}mi!gGU?<~DEQD."^m3̯ܖڗbipVխBg&[OP[PˁEx"Ֆ wkH1sꦩ\BW/OVҁUUcF:#ݚjwLתꈈljuCMϜLv@UGF| 4wf^UuC"-"+([r]ߙɮ2"""P{wEf!.F'q"R%T('E\WRj-"OxNQUKmjU9_U"ou @%(?IDk}KWeDeAZ*!Ŷ#AE`; XKcuqRssH\]WmYl+sx2::F?#w۸򥬺[Dp EV^O KLtQ4qI%@A}Śk+q+3v&ka/!$R8lMbY( jdh_1`SMcמ/ɷ~3<+pۋŭ18t[E΄@L Bs06(\ sg&;D)/kӹb*Ҟd>ۚV@h|U]>v*CUҸ:3wEde^+ d߯庴#%9"ÏY, iw8g3YHVDt9;ˀLcm| &OܖO7@qrhA!!Q74@Oˤ$PgjNO푦tGK =bADx|,_|m"))")"Vx-׵3=VՍl1VlNP3=M~n2BiJDR!NĸWߙUCÝU0BS>`]g&;gDp]:v6stkA==ܙ֨;T"rpTsH3qAa €"C9PU_Kjy74զࣝUuSU0R3gLeN^D^$"?0㩌}"rW(ꇀU~:z>Wg/¿BD>c?N~9@Zk BU}G]k$UxeRXbjJSۼqze|{.Np{7YXӂ<q<zgѧ0TPĎ%Z9+mŽTcߥDXޓXtΉQqzjj<(HĻkOTnEa>Dr~RYgN~uB\l4ʁP=&"db.L֢44?6T&V7o6U #s;3ٷm<+r]tJLB_[Ús4ڙɞ]U("d[-LJVևPWU s\ayܛwdxg&{~8MD3Zn~D(|LΏݾt;Ig'S;w)xap0~ _nA]O,;_rg-*hҮ^bVdy~\c͋{[ፏWWß4?==Ɨ2V,$AC> ztcR~|73h/[/#$VA˲>PhGvZT|% VZ,և97~xKK'"oH^ٞ^"t6gm<Ֆd`s v[?i!< 5Бn=iÁ#_7:ҭwOivm/C ;ҭ "2hҽ8 JLl=}*&[DT|6mDafr]V,\vfZ#< ӑnMk37 #"?z}*+SMױ0iU \ p$q{ləJ9(Kc&vb(M<쉼a|sx?`€d}M5ˎ \\}ւkˆ}KS/` ¶fׁځW=ױ^K\ݷtnL"s- oG! m?aId*k4EK8SYfob-^#XW]R,gHX8N`]8l!VĊ~PF}tOZ.iȯ;ҭ \f\x> j+coODWUo4F9͹$ϙ -up$NDl.H=%ݙɆgW*M ̩{e̪)T:1(|L{q࣓(s_Rϋȫͺf{E$jY_r] L0^/"1A:qn鞇` T!R V40OtO>5'jM"rg,ɤkkz/'vLb"r 6"%D1*"?ZӰ==ԑn^h]ٞvg8D}FzDW>'(ek>әC@ _ftfT5e\;eX &q{x5̤Q^D.ub/ Lֿ3A>qMˁsc*=0 >` ':3+L/W'O3VE̵?z?a|siE{kǘ-pȒI@Y;ŭo5W=ߔ1tR Lq3bQl O5࠳"`?ŊKw >\= x4ѷenQ("}e}%\4_.Nn<05UYC4>#DJlNѤ&(A}ۉKuPQ;؈؈e-UG V#~Dq # eRe GtxO.>t׶OnyQ9Ǫ L~n3nL\WVY@Xqs/8}Wi$R+W;[t .ْps{QW>3}[d~qwUc7őZ pIϭ$I ;Î$p)x-D[f'2,9nSG)vr~_ř-\ER;:G'9\]]/(끶\WAl_<,MZL41Gr+`(z$.@HU^D>_H\weU`ѫNM:-}䀾:)iAm1A E5UR%Cx]39I6`G+DWEj_{MŇ{T`rB7l58i-Tb?6gL_Hr~VU^b!TnrH?Ҹz+R/eƴmweMv[ȇE?3ֿ= [RHS 7⁣TGKP-]glj4m&Ѱx]3-2wGq!N6oEq;3/>_[9|_U3iت) U4.;;bT*Uy@ #};\Wm'&TD{q|\|,wG;□]x,+1\XJHf?y,Z?~u%e;ر(V$X>^i0KhvbE?s⯾yGMD6UmŪ*X#Hчv^ezűq ZMT*U94[GݒG}/x?_7љAQ҅5yvr/6wX6EŅWl f'8 F!Mj$jS8N<%&x>' G>,>[\46HilTDŽ&$&&$N,T#d]Yl"/eTͪ؞"=ݏx9tw]Fש{7^:f+*U!x)*NLik8ZiBH&_xzuK/ɢPS>բ`'Mdr&pb5X%qNX\"Dfͯ%=>7){?^Vڷ6ӺUxT Ў9RK{:6s]EYڶ?.P͝uz!,D_{)#R&cYƉbGRSC UHN[ȿHAe[O \.ry6U}/p~lUJU `UAy틎>S>aI.ML|ZDB5*UJU^ўޗ*""WҧzBԪ=㎎Eo.;J@wURT8ЖUOK9<8 qUmLb*UJU^ hYDߙfE\E ru[mմ֪T*U KTLgiwѹ$SW?e{űcHLNk{kW5*UJU.KypmF[RmDVď/[)W~?UpJURRXUx[Ŗ`>e"YEŤ/yΦ;R{cQ+?T*U1Axkial7Zd\Ϋ>^fڷW[RT SGKJ(*"qE˂hm.T*U9PlUt<+|Wi{_y艃D ?!ZW{$^ v񻧭;y§Me&<*g]G '/i S)pQV\XO|Q_SˍlD >n+,=p,']$Ϛ*۔v; M+*#jv,pH]jjȑuUUk u0ۣG:$Aus=+vGq7ߜ3wJW8bhW]Rź ǰD?KKHX;ᇩ* qO0m0a݇Uw'6h_2y8YD:WV}if 5"og@gR7Sҽf-+H3w+ 01p) z&ip{ʕbY_k5"`8 1nᳯՌ!23q1_"c(jL畡-8C tA$MZ8hXTf1WAN ]_Hw }gQXj*E0c}ޭ@&O`xo`(Sjw`CB(fjzϽ\[{?? lR.J\s粋>_FӦp\Nu423O}!8 Tˆn@b2+ٳe*;rDB/2یUxZΕhĉ4UؓjZsFHGMJ)KŻ-Znj5>4|X78{zqq\y*VN [Іo 4"ۡ P 2rf o߮۠rXDD++gHXfRuD jvyۢ@:}0]!Ͻr+*w3SA.~yZ!5 *wK4YJT7\޽1YջCݚE9 Zgwfֲ 3}S:c}%TLM W֯d )`$*X\!}eˈwG;t(ԛoRKSEϞNP4"Tc@E(G\d*OqFKzg"Yu@[Z'=}Pw*Ɇnk)ݏ=9+Wsr(^8L9j]pk}&;7-kĈAUrX'O.bOD}7+HfVeD~]wMc~Zw.ɓ)~޼ħ5V(t6)CSvC a n~X)n})ŽU] V6 r~~559WK :lsPb@!PtR@3cF@ Ued[@CHHa^68Uinn;79 Yn꿸ng\3h"WȫԒ;+rWc!W T,Zcg I;pU"`(0:4`v 7`@~>EϙC-4& 5^_P@W7hV^SŲ hmWWVirf5\GB?]`/!8RtZ zP,ك cY$< jEq_f7.6"$ËbJSOq|&Q?oOuMrX'.|]+q+#XgaG4JhȘ^B "c2dzӧEk>dȀ]`*(^ JzQg o"f?i YY4M[d@i7کST"o )PxM ѯD6QWzjD-{"B xM0vRrW]Əe3dHʭU! E=\:犐7fq$2Q*34]CY`y?dؕ 6ՄNjmc! *w QƍT[NLg1;2bWU~@Sc_!_ )MI%hl>T5`' ff@k (s`U7?Wi4o۴:mZ4Sy&oOJ*D*b,  S.^FQG b^!ܸᵔz)'A }.}e@ "t̽VQAl- 0*j{o7Ѡca@.g8c3av{)A LaVqsW* Uh j A)Ʋٞ%KDhj3p+W2@J{Z!*o(" CZ{R?p:MAxC㎞;W EFh>B5>o,?TBY;nd߾'xLpIv*˹?  Rڬ'(=\ތ.wu^  i /?4f>7|{T6VcYu @yLb=zj슱 m$WAW:s&/՚ |j^8 [XWZCg ЋouK+{Ws !Qbub PR X}!E=ބZZ2rqq>c[pC]]v [ox^ڂ-EfYrdP81-֬9D" YZŽj +5">ŋA`5Rn"(E:tԻD^Bw?K2ހy+Ycn6Ѡ`MFS)SgSRӲDAE~ V{/Hyq+PY =Űq{[]?p K>?EpU KE)MŬP\)Wyb޳WG:0!sJ Ѥddf&%qG !!jz=<\1²# uXB0b03Ug`mn GytiDz:fK a ޓ[A_]壅ڛ(OnR.5 U*ޒ94~)Ȃd }U 7 x4OAëTY>Ydn$j5>|fddwbRx1RlUgvO6f{L!dT6$+>|xj*?v`}umA~A5|XإSXؒ9nWx)Y,s`-$|WZswրM~ Ê3G<)ڲǓ rq5|XiGwf[SZi k)T1쐵wVKdn3/]0aU$!p8Қ{+9bG N6F0 ,#llj_Z OB%KҲg&tj(ᆰ0+P1@@npXH t.i Pɔ$n3J7XkQj "3!z,@_j2V<7zպ:oB0(6+WcM6QyP0 w8*gPƠ0e=H&~d9FjK+ti[~nNr8N`uiy ޘ~sr^ab_aNâ %[jP q`}{d'Gs6^`: ź .W6nu4cY1VauuN7Phb/fA*CCz-W"-L5X{}}vM^E{:s}4S nƚ8vTc6kRB=^1h-Wx,|f 9"gLs<|x[Sf*wlLͽpCmh ˖RTfN1S}I(L-z-@}57bϧkB *mnٳ٨s˦ i+LS1Fhc 2`I5Sic BFTc ׯp5 م99iWc/4){+LcTV`%8,*nM361V\bf*m0@ /OU< 35SicFGPΝT<I))mJ*Nwh]a\ rJW-M4Sic%e_)ȎΦ 4c^T:$F^5Sis`J }r"WҢJ[gDo׿]}h{f EEiPisXo۷.n i+lב7D?M+ *m=VVo>qTz ,W +4X泳Mh6QV´iϺ N~}V?<G;W#끦Z%Amp=۪A7^,P?꤇6o4y\-4yaT4 \PiӦAMJ6mT_YMUQBt-IENDB`CodeNarc-0.23/src/site/resources/images/getit.png0000644000175000017500000003533012470771407021315 0ustar ebourgebourgPNG  IHDRu[[bKGD pHYs  tIME38.iTXtCommentCreated with GIMPd.e IDATx}yUՕ((" "2q qjN'Fc;i[_SbŇ/cD;_ԶUg (ŠX<q{ϽU`!P͏w8s^{o}[>~,F20@ }{@!0DȤ_Xc2uk0=OqDyO_??ݝ!Xz l;` 2R t…[Op5 X~0|nFFVl?o g'mc#f -(PӋ+^$b~x^aܼvu=*,Ϭ;8Lf韉3qFƃFpC'Dqvf䮅/.T8Njޏ90.Fh[E>/Np ?40w) C{}J}O=WF00z?Mg =nK$vؠ3\[XD~:}8`B? kD>IOA>ψIPz~I伡C_{oyOploXJFdXaİ# ?|͎A{$Z* Wq"^D2pV $[0|ϞwMdQx3`(I_hswyz3(g һ23~hx8&03A,+Z_Vv\p^%Q"h 9@ 9nU|J'`eXQL"x<#H_ՅF 1$i% jgǕɮNy9n2Z[XoOA׭M:ٵ<%',!~=^\.b}8_Zz Y/R!q(ΘB@axw!XdB@o`lv~PI8, -ę| >v `$ʌ8xX^$pz 0*vIa"^O:?Ɛu\A F.ш_I.l;^ :߽fXg2A?b`H`DxfB\;@JIEV Pw_I4p6@C8=Дu 1<2DFy&*>lg|_(3ηBDWssスa1MEe<6ldH%)'i ,UH/nqq73㶊bmYB9^&TH'vwͥZQOcI'_ f1[[{aCu!߯ e[&3~LX7 Jp f`d:)>>߈CBiD{oVW3H|j'-X^O JKqޔ>ZaD,ܽl/䗘E2#}4NvVv$4 %oNiG2Pb``qS 2֮E[m-rPX^q03q9`ؔ)dq`M !u6ƪylײg ijQotMl9hbRr Z!p& GkH7_M<Sn.zI}-Xkaoe3fEӶkW|V3&uݡ\)M$7H"ʚT/]thaO!X IH;֐.wk)L-7wz[oň~6{2^WѶkWζ5 ~{HL?S4~<Λsx$ LrFw{;Ѽ};\oO?ޮ^P2A_yY-I_݁(lk H4]&T-{*{-`wIWnm5a.IsEWK>gg/G`ÿ{6 Y#O<|Sz}:^N=wQ^Xy<{yLsUeX*'-:#{Q ,oju6`y`…Y81}7Λ/.go z^vw"*Zg{سrunՆ) Brn+:][$8}̙s_ƫwjj$2 Î-'þp>wmBdme}Pؽb3BO\z HsYcvn\ Sf]H*& 諮GŎ^`7tL{>SWQ|ToIQ_j%#`Y/DQ*mqS @cjj ɉk!(D h? ?\-_>T @nI xa1v_zmxqac8&H1(% ݁u!qu H~ؿ~V(3vҥ(9sGx()!0.Ӻ{7=|4or`wg4Š0~"hΈlVV1Q!l(7kfR |:QՂ7C0llۧ °i{z2Bn!|3nUEgG?W\FtaL6 35! vpV 4])*%QOmN4La /?Ib9d 7*_5LlldeڽlyTjZ&ܭ"T-$^j@X-gb!U3,(Vl,FO'M?|Gpyo|ټ}*cQ0|xr҂ukV%S9&X@"ð(r.GoV`#YDtǺЩ%UIfN6W[T={:Qti`#O8a~5k$DYB{daZ$ eIwrvoXأB)fئp2d鍙 uPaT~* ׽^Xgwӆ$ ξz\bXCFd3+3$To(-8` BTa'L5o$L$ k BÙHd3**P]\N; G~+׬]v(ޢ%ȓNTMݲJ&lѕY>$5y2Op% Ij.D^k^J39LTؼpa90[PEt>Jꄺ5k2~HOiaBΐ!}͘ זO6[y0v" 4Z1!MRrz ְVMe׳oc2kP, sάzmZ$;9hNqъ~8Taa:*(6jSG5jb̹=F a-^WkЙZGMX-rϷ۷]͝}{YJR@G5kֈ,u"OK >GD IDtwNeU\oO\5WK…ؽdI(b\{*?G8dw>aflzQlzQV M⨿}.,<tq.m{gI͎Bs22Ȭ!q%>NV `(Ŵ38F[w I~s r0JEFBO>,nLD©jP49%A7;Mƣn :{eN( Wyfc+enH%b#KbeQhȠ ԀFjY AǂPqoyR QwL cC7L}A !z A/PbdhTekTG?U)($[57hi4|D&s1(BRFNATwqii^Ud?,=04+I ^D.% ٰ[1 -&wϿMbSs^ҀEB/c|bKZ(pʨVhޞIwv<kg0 [ Bsddc u[^`Tini+%s-1on $M))rW_ƈd hN $+)񽪜 :>a|Q'b .<G RbhNqIQ: Ga +Sc9Kzw I,R?W26"Hq>;VN ť Qt] {;݄]#Aaݠ(QbߘD[#LQXRx[eإ   zm*fi B#peyF:gB<fE<6بO޴xk[!Ԣs\E@ąrWN}%dEM)%*' LPK&Ӭ(Ҋ3I$lhk $>8cPm} UWn"q%6PBB _^t;K\ ))k3%K16^H my#kQɁ$39l*28rb7Ǖm5ЖAb R'Q!!VYa#OBa(&KpArKsYTh Z᜛@0GpH`(+" ~bR+ 83x+(6 uh8Tg,j2^w5\jh7h˿;}*(0IDATޭD8d NZ-.+N0|_"Ɯsʎ=CƎE^q1lg'jkRU?;-¦GEG}}FϜE0^^p wwhC(:3fdDOA-ݍΦ&VW~zT/[-/7D"%Yc (4 EGEag0hH!'?&7]jmE{M wDgJԯ_Ϊ &\u("WOP"}YA#9Qd8n=4^u!74`~w]͉&QNT.t{Iyt!8s1:o2=Յ|y'kjDߪh6 !SOŸ /İF*7wqsU6?<h޶q:/}]>a-s Ni|!4 [)P8Z7fa`>_Yϝw֮ ޅ8&r/uƟmc;_&vF}jD8G]e%ϟ{"\ I+E!1i`B7p)j矏/QMz Ѭ(R?LBgPtѨMo`8h1g]1O Qr%R[zp5 Pɯk=u],qsp/} ?r3٫sx̙?%K\2B :dHZȜBOg߿hhj; K#X7CǍa_*Q8a!Jh$Ԓ*LP *Zus Zj%T"TU\!.Q<9meNG2 .D-A$L^T|!dw"9k$'IH"QAl,L"EBE\6yeG&#/Æe>_UcM lכرM$rr0{äK/8Ѽx.Pō je֯(5'}{zםRJcG8,$.dA̸⅚4mg׊/˃;Ru/-E[uu/,@&#ۼ%J_jڞ!y$v պgt#^ud)=t%i бղs<{`qEhPS(E ᠤ,IqPR?`4ݻfK|_EcfjkwK"F(9z*{㍌mܲO̙JF; f\sMƢlu-B2$(3c~3X}睨߰AEҀ̃x֭ N܋90)BHT %L&VFï+LNh/Gg_ >9bIP 'pG4j}K~S,S&XXAZߒ{)SP2a?\}5Əz(`Ꜣ"̸Z 32i S @8@zJ;d,|Z GI3ꪭ1+6+83#6\K4lڄGcW`5d=neX}]D3FxB/<|78o̾'}Oz}?_E򆕢AŨsQ~=.EͪUhB[]Z cQ6k*N9y=Wy-w0m($$+!KR wΓP_43Kf,AKji} ozqw0TLrL^/]z80{ pqiQ{AXfA(29#Y|Q9P(+N(!174 \9r>7A4WR<Xu~u?::/ACe%F.?Fu7}aS7 _S).bͽ榰3T-X5AƲ)*(dL5x[],LI"UF-7o^u?~o Ԯ?EW_^Th{zto |d7|%G_S 3~(yqsh5/$!WG:#I `n 0(9R&6n'kB|w ?^1"^dnzx|.9+oJkT v_"79ENJ Tkױ^;BJFy8uE,jr d2H" (v8ddH ,#or  JYNdq51W aWcyeb2[ @KX5>~NJDYDÿX C{M7/뇍0c-ݒԁ)Ѵ⫛wIh8_4}K) i h@@'DBq}Խ,y(N="b LPHac"٨mdIL$ w0'O-ƓLN vڦ67f7^> {`dq^ (n# b2L'YFX?MT%&YNs.PKh'Ҿ{Y˓Xҳە4>Z=e{L ZvVj3'7xws;䢵m#iP kr F5s Q? w 4CP!@bD)$T*a|F 'u>hQs=&D0DOTbph 3@Ç9[7׺:W_p@o$<+ 1nY5ž *. cZJBς CXĨRZxw1[K7}$Rm'h*Ykw/xw;{ʘeVX13=fdd"[5oٱ?YrTO}V_׼";=/NEYAЈ|)!P5o–Ot+)ح=oe~g |շŻ%5=H#,;z1knvz=>Mք[?K-?.N+y~9nW2/ܱ4I>2rT9?džRN׷ԑO5ygȁ(=Ȟ)5KD[ q^[ ͝BMA/"4e \҄cn+/F\gs@r+Z vh>7a7a߾'/.-z|ᇟz]G^T̀de )eݘ'Y{1vr( Ck{CfqP1~?O( >w?Gy+oGs1޾gQCå M2is@AkQNx~ oۭQ\RC+P!Cw\l&dx"ʒ9Rvb(6 8?^mv{K7nԵ_ۿfA>Z J5j<5ŵ0-}"5K~FEwԧrlj{ꭙ(dt`~h^ʝ:AF +Tzsړ|Ld_ K"߷}T??! ǜ2c/ ;md &]cmqxɟ|5~^8}ʠrPfRos*Ϗɐ[g `6t=I\ӏo5xu o}Z G]f׸ג` @Zڠ2OYTn Bl"w%G y'A*kÀq _XF8;hZ݇@;B(ɬHѤ,vZ 0yJ6m(6ǠY1SR5 {O<=Vބ4|:;8x`{Ib}̾C363q-cQF5C4#i6-|P7>+je}r$*tM$%bHdQ^s9lOD.g$<ԛKdx>?{gǎLDW}#cξa3ç`hAuxr=rcY^ZQ3WμhZ= 1|ŗĸ[Bs@P a9p@>T+l *ŸoI"vdte!9FN&7joFUPY^ن=D%K+Hlii.r,1l'LÓb8 0W~~|\VG&=SxeI#mx %:FMqg|et"Z9(xYRxzєw$*$k :3D'Njed{Q& ߠMT[U@)5Qcls14-S͟ ѕ> QmM9ÈҜmMhBK 6n\H$r|\FW[Ğ܃#7O+s(;۴td4dMjOA!S8tHMN=skvΊA.D4EA30nNI+q}˦hg -Jx Ь9dJl&4Ohe$~OK?4[薺zqO^v<;ߌPF͢ryh/&:2dvEYZ\ ZMο>v}-q(ڞYgM>!L3ɿe!U# awVu^I2WLbDR{2 |;;d2 @իWHHܧdw񌲻mPIP{M΋Nxye6FCWaJHxR\b 9I />19̥HInK!d$.6@Ck-cw La%Ģ't!ؐQa'SȦUA | # cv0ŭvOPtΒ(PX=$>\&F# I]_ !E[PߔD:[FlF6k D2-"EZ; *aDr$m}fНgQC<ZZ{E7tae1A]TTNgʤ-i] 2Q{Ceكuj-PfU"tSJGi"Y ʪ,Id{ܡ_rH1fz7̘6Mʒ`p:fH%0ki.]JhUwk2m4ghrafګ [V~p4^jd碭!.'UFP|Kzn&#\}mc±E)6aWP-Kn`TvlNCԳ#[lbdfR™'._a^'h,7Rpp@RTJ%\FAv&;9ʆt+`THB?\O JJeUa$K@o$uq'ŢRj׼DkJT>X+Tv1!G8G+dKYir(җZ~\>Q!7E>LcG%$';&d [Cեl@$rĂ˳gj}@W9V^{@0Cre#lpa4>oK"R]eDnYM6!I,'M7.r +GiҢ;;O'r$: )Md{1g0sy#aBQ;i4bs "!koT#uYcP( w(]1TmF_X69(K БA~{]쿳qMCE2GC3R5TWז%!gޱ2G"#z\jS[Nn\ʬn[NUYܞQ"fHg2.,gn`(#ϽDEaK=o2&\wsނ"ڗJ45"f&(Hdb=p5T*.7~r,r|CF Ʈn& IY釣}}ao[KPCW RQg5|j>H!ف㿾M[Vu2"`|74K!pgrZ MkmaE^ ,ĠŘx E){bf&Xx F9v{R ^_ Zv&8QН]縺 ɰeآ'M)YJzB5(i<h|c$e8[ch:QZpS4S4>T~\ԉ4~3s 6-e&sHUT_@' :I6قnj tչAH f, Œ]y!N;ʢgB‚AP"] Abw%}O'l)!Cs (,{082g{< o l:Y@8 SSdB_iL@Ҧ7mtSoBߩJ͓KiV[Ƹ g pFxSI#c3*Q`~M '4)Zpmzdw1eixSF&q襥NDqPna`z8+D:4,|27ڂx+[ҜtkqjIyo Z a9GmJϽ/VU"As Z1b Mwل4Ai׈*1&Rf6hf\V祛FߐCνL g, M8MP+FsSKUbRK`e0tSꭙ537Bbe-ar?Aҙrs+GgIŻV͖($,߳#'5t]<]126&ѓO^fn]:ZLLc+qvMF01p*ݠ;e)FRâ:]/qDNԧPOcaрw}6d=+*\Y3&ޘu ;lϠςN]9jV~Bxe> k}6,yN;&Yyݼ U>Op]x`ԛIt"*Y3.S(+vb$dakvnN jжB`z@ \ 7x%eJXjOֆY8Mh E/#TOg\QzrP;2{OGKh "iЖ^ eShBJubp3 0ՔuP4do֌͎ePX)AC9ў(<4T終}ػmZYn4ցRܜ8X( Y؉D2r-EMc%mRlF 'E;(pNg*!M!@u"97:۲pff+f5(HZG75u,w;h֡lּP; B3fC~ 5|D~P)ll&7o#pnyaJ3h KTɀ 9i[os gh^(JrᎧC45jѽ&Dk0pM")Nj8Wvly9)c f9IyBb̂P=P]nnq}KW2 0mjL"+<./=l=# 5'u E3i% 0Һ1Z ]PY2߁O!QHq@yPСжs >PX#K;({X[/_7A)fcFS5Snݶ24--MV‡++Ŋa䈅܆YKUh Mk#o&vZTGoѡt,U#W:d ms֑˅%Lq~ (A2։NJJGLm3MP(#z9!#KRʓk\Jt#|ݙ޾:VK@FbM.m7XHyrdFŘlr]v|0g%Rw"I0ˍs9,@?yVNJA.x+Jl*f6]AҐ ˮm)&V$O*bDo\eut5)(V[~A4hVY>كK6M|9RSWVZX)0Jg0Tĝ-n#YUp6= 섫͘XQ&t7Մݷ[rSa߽И ]r7Cs2TAƷ'('"byҰȍeQF@g_J Y+e7ej7bnsoskuxTjLbcڂ8W6{:9  xOW{ ʅWUo;:7"TR&\D}wVw%'ұc9TLfmY*%^`!eA*2d0J3-&CQr-9ֱ/lD) /.,Q X,b.~MehW? XҳA[W~U|kNfs\9UA** 9IDAT['''+VpXbcy˃I>).t-TtW]?i:@]peYav>;pYxN H'f4 DhYf JZH*4W FN-N.˻ڜ + 9oDrX(gflD0&e0{pUQ7qX>$Cm^J=8h4zÞ(BgK-iS1U:s6#({3~-&l.(PZ)@m'%7٪:z'cpKt;}=9_2"&:نn+#Ǖ??JXUʩcdR^^VpI=l8LVVYA08PʖL]oZ|8ֈGk,>hM**/n)klW(eSdk+Z#Vb܉!XHCjxb$os>HYI'lNZ5dȯRkdZUϳFIL"0n/^я;W_n}ߡ;> Ҧ_@r搢4^.b+b9;L `dZ[ }X|6r yB^1X٨mB& ukᅶ/ m Go:3 ^ա {D|s^m9RP Į'= %dZUF+Wu˥á 6nX":٭Ч 8'Sy/MDx9Jŵ'J'QY?7zocH uPQvjɠ,ZQ 5D{{?De lRrl>y$ B%Rb^$KeYA.*u^0sfޜbBN-˘p{vImZArP׮E> e? |xD5:O%Z!4, Մ^mbJC M8$M2*Pgfhsm>m8Aۍ؆U'V 8* uUy>>sӁ|ϚeR5jXJ*A!T.LlF$\NZ4i jStP/X)]D׃u>G^Ltc!%4Ѧ;){ &g??s!󚫇OeGFI|-P_Xj81}}3]=r%Ao<~6rC4+ZMQ+ Ohja+kMΟ=g>ēOVʝ-׻aUtK ap ^\˔D +Lg3RiI|5 iAWCMZuX!g򅶧D$59h2pg(7~y^??=ASOeχ-ўà !پ3Bژ⪗plw_B"ET ͽi"hx)aD3 =ghjputͥ֬i-M㟼z7[|%u)` N68dDtRQ'H6Qsb4g$z7f2`fgX_p"bs41R K&1%N;Ns&~xGrxw$i>(nˈqn҃¬DvzDTJ=ak/ؼ#S(Ɂ.b9IoI./(eֽIө3o$$v$[ ]4V7~,~w>;#PSY9X7#\nn\kW=_ׯ}7\[~7>d? 榊JIENDB`CodeNarc-0.23/src/site/resources/images/tryit.png0000644000175000017500000003374612006632020021343 0ustar ebourgebourgPNG  IHDRu[[sRGBbKGD pHYs  tIME ;5tEXtCommentCreated with GIMPW IDATx}yUoﺩTUJT AP@\.=Q66Hݸ -tϥԠI@ILH%EԐy|w{oU(IUn/;|>{~Q~8 Sa/"`D3gs3@qx1ߩ] @~ycA; 0@`\|%\*vrέ&{qчxmTo(p K#4`s 0Nidg& ɬ4ˆł jE  מ^PXH-聞74t_]c\ v'fcLҰQxy34`|jA?f#%.aq] T8?ora]߹y>M5{s 'Lm04Ɛń $Ex Y/0] WQ s]ٹ>W&M0zg=27W|H&A9orptv"Bfȏ#& 7)ߟpu:T>e޳!T8!zw{\ / RA(cYQhSQf:񑫯4o0D &&i<{"$1ybE{masDxw&뒽:`h˼E~e,-QC2SIHdlm (dP F:x>CV[#M%EBLxw.$:{o_/=x K(#r?7=NĐYvBSX&L"Z@\r%աY,wXs񉶶7x=['s`$&/"^ q<{' JcS9+A ťOToc_tR芇O9,{q{8ê!0&|@5щ2-3c wx8" J\ݱi3` j]ec ̜_=nk@W:;13}Fے%&DK Wf 7/BG496eF^{x `zنbŁpY%U`ζ! 6ţD#IC-Ozn^xQtVfС0c*~wK,& RLrac^.H3{`o% =E1VH!&2ʳPGD Pc<^^\b7{@o2)02qu4zy,q*LۜG{y20ՕS=;_y@^OZ#DyEo< DC3qpV+uI'؏>?[Z}r}Yl/_\]kaC sY+}EPHϛWt2k8Jt  M/Q\ȯJS'no塇W dô($CrI콥Vbaz.*qB̰ *0Nѓ1YR2$Lr<^ u Oɽ'˟y&mk>[1*54csǖ 4U}Wy`Ǿ{,r#*=yM*НвUhh9qF8c+}ڛ/2YԹ)SqAP-jp8!ƝVb[-'o{7oѹU w-'$z0xCZa'&dC1K8Wk=fgZ!Ih3;zJ0Vd4d",1@0QKl{7oƺx^-=mFNg0tkƾ][Jw{` ڛYwoق vX'P X2.;6))n[dO49pQG+Y}i$m˖a?}S{Ckj_Ry[¾]c CЍ!3IO#Պ3S@AjL jzJg1kdHc((r7CHlky-K׹ Vji?{Г,=4?u?%z1uQYOPWE:׿xg dh[%$*A璚%KԴ URa<8*;Y;cҔ8t\)IϑN $ŹkC/jr)rɩG .A={G|RXG@^qGT&LG-w]>J #@f|*&ܗ!CH!htG6Nlw]A8Œ`r9ߥY4둂Ray$rFiVkUعz:KQJwޅSŊjB0Fh:q:S I #ؒ([~u=jݦ7$RbhUHѩPg*U7j]u\ ~[B$&@2rR튭Հxފ\_{ʃ%բSbr AML虇3ߌvG+>޹ap]Z0iVTky{MuU ݱЄ4JM2/+.!%,K4wFŽ73l|dOf#fPd聜U[D{s3N:F|Vc"~ڴ=+0#Q7> 5#F+-y52szFVPܒ(đظĶZBߎ_"+?8s&M~[z@%uٚi ʒBbA(p [sbz7>L2bSW|ksNRGK7d(tp!y!*4n<ъ z۹_|7XJ U_(@,`6 UΗ^ze}&J-$ $8ߌVs-Œ?Qk/| )SVa-[B5 W{֬Ր Sܶ~ߖ5ՁYg- bѦLd;4 agVb[Ua)=Q{?~GAielX#9N"Ԉw] ($Bx"Tk_C޲%,an.B5RYfhY*,T.RFK~k׾=F) LUzP!snX=kh=f8_܇ןzG|C8S8gJ s6n'RlƆ]*YbDO.wSC잃4?= VH4Q3O?],n_C'c .G!)yr?Y'd=%*-(l9{̾J\~K0$Kkb+1Ba}IV6q? 0kyq;5^'Nx?ޑ4zW.cM_Fсr*IB|FMD 5YmW"3E'ŒY5H,lJG#z5s4/Xq(RO:9ϬlN>P$khqlGZ#Vts*V! LYb 2T%C!1Bfh*hs(S6Oy5cڼq§>S>WލF$Zס $ɣc QJ5t|#yGѡ{0q܉KdWn'JzUnkUWOw؟1kWuxt"~whT2٤6֭mLLT!%+2~H/nRAq1!:aԘH?6Xz}%Pi|.ɑ4₲[}cVl\GqktB LT%oi%)-=3CU0LFR/]'.߽E-zA1[pĬiP-fYfW(MٮQi@0>R;DaeD-ƞ*1*hhu%(ԄS;O%_7/Eģd{$X6 =`d9{8iNK#\ɤRt$:i&#GQ8FwunX?`"ݯ0n <4.tm؀m^^L -Vʊgf(!gZjPM(crg>Km"Smn۳ & )?-% tㄠ2Y&4E#S'򳞵Mnin,kJEDh=F(LHb8G%ځhX%[N클- ,dzVhY|?bEA*Ħ"Oczr'-A**;ؙ"gMAQ`T, yR!-ϝAwq;YU:e LX%~VU z0Qe#$#&;3Q']!\A4Ѳ0L>l*JZ'bb2UH4$s w"YԦ$cˬY/H9t\e.S$uVjY@Tsިb&B8G}H!BI !Ŗ 9Th&}GH8rCOqLV⶗j#{?jc3%-لǯj ]`8$gBHۆ?]W"sgmp2wW Mİ- zr !/#&hOqkU0 q̏f6IlYj F ~C>^̐%Z b6aTʅWQ/ģwY0sn4c\xs|7|X^EOxͽB|G*߳u+~2wvL*DW- Z`4pmG+=SM } sσl]t26E<^?}wixkᆆBUqB MNj 5.<~-w[}ۢ5XDπFpd:Y0w'z$E4"I0).U/AcDF Dz) Dx5 uZaӏ9* pcŊHr'e'yOjBdVTjb֘ |rYYҘ7`zbk[Z>vo=Z`REڷb]AJQE,>2܏&%$T2 Ȣe!ug)5ߕqj&kFƗ?W6n8rk~}s3sLMWPXsXMP4d( r*LItNkR,F.#ũђ욧ydm'rһSXiVAD*3ΨJڳu+zEQk+%tUGf[VJ.ف%M#rn͐W0[~RjIƑPy!N9dGv nԄ1o s׿7Z<[ }&Dh<9g[dק!0E&Z)ʷ!%~DEM{1й'5IDATu^}Ud׾EHt` /n}{6w-uu80?w桾\_N۵ ^x+V`$GLա̶ bC:EeR8^* O,=QZa͛1g)f+V?VȼĹ~E &a$_ՙuW^<| 6-ZyqG%<ӧnt%FVsZ\IQ $v"v 良`L~0}Rq4@/ldU*n.O9wUѰ;;w\{=X,BuvyQma#94m*zч+~{|҉ ׾]2FEԩsj+3BR'2I04ˁ|8趐c1O(5/D%,!wJ%?Ό'ڱz5sV?`5Po/?~hr߯;Dnge$} G]r1J _ t\>77pCf* 0r9u(ElXbᣋCFxXMc?zo{ߋCL>@qWpWc+Y_uz>d<5-{*{|&]*aWTRc,'G_vyrŖFebvm*x~~B~RB) pYUDے% }3Ķ}b:v o;wj(M|o5KģP8wPP$_:d~ɟn[ޞ@S(k TAs /<8Flա"u eKr#ahpf0gK/e8*+N->tY9܊J;y? )C}sH01~!1W]={idSG^rq2I/boC]rTһ3D\Ua~РghR:bح :1l>M fƼ;|L>䐚hU@ϯϡ5Ra --cߎA! TAuS4x1ڝ@vDkh[.( <)B$*+Mc|74]? èjzfy5 YDsf6…c9羝;oGڋp 8QQ݋UB@j&z_P'{ǘUy`.P__IS@&s6.ZP"pBBTAKMS;`OҮNLj -Ú?g:HAhXvȊn2piz|+a}Oz(Fo;6mԘ44fa ծ+8>1;O<]P0RSG^ziz[ =mm^NK))R"lZ/.yketCZ|WɜPGS79@nƤVbr_2aѝ"ضw;Mr`>5'*b&'TWg¯ " $Xs;iEBYUT#\O(RV4"Z6&V:c4!bC[1iœΗ_bmh_tX ILl(QiC@q%"̽}Ż_{ ۟~**/M#?hۻqP .K/=//`HA1h]Z2ڠ3ۿq??#d6%:&Ca ǯ sѱvWtonN/3ގmK<I-wy7qG?ֳŒN(MwBצMsh t,҇QRٕzs<)@Cʆ_vdϑfZfUvEFShR](%r1J j-$v/Vzox 7 d5̆ӝrHMsQϹ4WcIZPP̓ ﲑd;AUi+L_SϯI+p>ɢ̎dƠ?u͚VIR w/[)t>mM[>[wF6"=mi% f7X@hHܽj3gM N۱ݪI`)PS<aӀMj#B`VY ъ1ϰ9|j;|`&wft.l.W0C6FfD `+eaX\Rlo2Ҧ_v̈ٝd&QK]a"ж'TT"{JE xV[n}aےo>hONΑAؒ>pk?8 X3)*9֠ 1'd6Ťv6EZCSϒ*'E)aAkޞK%oXsPx{6ۼxc]*IYA2isfՅ r^s $* ;s0cD ;d$ 9CAjCyu$ ãcELĆ1X,hkL^OvV<9$rB͇%S dH ]GT"͔ Ec@Jʶ_<YO;[ً4guFjDe[_R8|D%wץd?yABjŹ#˨MI|X#G>7P Fb.řOR 6ln񊆟Upqۣl.jKV)@ ų^Wf4# IV۩m5孙{ΐ19/@TRmB'C$6HSc;sE=!{奄E[*&B?FV>oO0*[ۯ=/=9lύn_?Bnm R(:TP5ҡ3ER@6mڙz[59lvoUK3]1V/ р (*FQ$7)*otәpJ9_L %FΒ1t q=9QrgF3 XJy`usgZe"yD{R @4&* YQd P`ÌUv@APްF"aLbB e0lm0ћJR$=HpeKV=$]AN#)w}wrp~ʱb/t剬hY,:so%ozǜ!E?f$ Y,*V-Y~B%IPc`c%8Mxtct aeV+,:9Cjb:Uu096mY_U#18ycR{V1o9!b_: F(T%yCE4slhq{`SԒ!KhL]Ù{wYA $j4NoP絶5=7R@"dʃ&YvP ٻo{&cΛ1Y{wRѱ{Baiw;IWc{Y@A=} e;hYE\aJ0{kS3oe87p=&Mrg!d3!J06!>$! 䠊\ ,lrP:=u-:Y%a!{@r#8D! f,vEΗgJC%}}on_QFi8 Sԍjc$UtCWb6:@O>Ei ur o}b1(7MMV-`}) K+Oɴ塌5P.\*=:e76v{RIENDB`CodeNarc-0.23/src/site/resources/images/notes.txt0000644000175000017500000000010512006632014021335 0ustar ebourgebourgFont for button: 42 Point Sans Bold Italic White Sort of centered. CodeNarc-0.23/src/site/resources/SampleCodeNarcHtmlReport.html0000644000175000017500000006066512470770660023766 0ustar ebourgebourgCodeNarc Report: Sample Project

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages106--8
<Root>73--3
io33--5

➥ ModifiersUtilTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports320

[SRC]import static org.codenarc.test.TestUtil.shouldFailWithM..geContaining

[MSG]Static imports should appear before normal imports

➥ PropertyUtilTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports322

[SRC]import static org.codenarc.test.TestUtil.shouldFail

[MSG]Static imports should appear before normal imports

➥ SourceCodeUtilTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports327

[SRC]import static org.codenarc.test.TestUtil.shouldFail

[MSG]Static imports should appear before normal imports

Package: io

➥ ClassPathResourceTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports321

[SRC]import static org.codenarc.test.TestUtil.shouldFail

[MSG]Static imports should appear before normal imports

MisorderedStaticImports322

[SRC]import static org.codenarc.test.TestUtil.shouldFailWithM..geContaining

[MSG]Static imports should appear before normal imports

➥ DefaultResourceFactoryTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports322

[SRC]import static org.codenarc.test.TestUtil.shouldFailWithM..geContaining

[MSG]Static imports should appear before normal imports

➥ UrlResourceTest.groovy

Rule NamePriorityLine #Source Line / Message
MisorderedStaticImports321

[SRC]import static org.codenarc.test.TestUtil.shouldFail

[MSG]Static imports should appear before normal imports

MisorderedStaticImports322

[SRC]import static org.codenarc.test.TestUtil.shouldFailWithM..geContaining

[MSG]Static imports should appear before normal imports

Rule Descriptions

#Rule NameDescription
1AssertWithinFinallyBlockChecks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one.
2AssignmentInConditionalAn assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended.
3BigDecimalInstantiationChecks for calls to the BigDecimal constructors that take a double parameter, which may result in an unexpected BigDecimal value.
4BitwiseOperatorInConditionalChecks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable.
5BooleanGetBooleanThis rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop'].
6BrokenNullCheckLooks for faulty checks for null that can cause a NullPointerException.
7BrokenOddnessCheckThe code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.
8ClassForNameUsing Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time.
9ComparisonOfTwoConstantsChecks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values., e.g.: 23 == 67, Boolean.FALSE != false, 0.17 <= 0.99, "abc" > "ddd", [a:1] <=> [a:2], [1,2].equals([3,4]) or [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE].
10ComparisonWithSelfChecks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x =>= x, x.equals(x) or x.compareTo(x), where x is a variable.
11ConstantAssertExpressionChecks for assert statements where the assert boolean condition expression is a constant or literal value.
12ConstantIfExpressionChecks for if statements with a constant value for the if expression, such as true, false, null, or a literal constant value.
13ConstantTernaryExpressionChecks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value.
14DeadCodeDead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted.
15DoubleNegativeThere is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well.
16DuplicateCaseStatementCheck for duplicate case statements in a switch block, such as two equal integers or strings.
17DuplicateImportDuplicate import statements are unnecessary.
18DuplicateMapKeyA map literal is created with duplicated key. The map entry will be overwritten.
19DuplicateSetValueA Set literal is created with duplicate constant value. A set cannot contain two elements with the same value.
20EmptyCatchBlockIn most cases, exceptions should not be caught and ignored (swallowed).
21EmptyClassReports classes without methods, fields or properties. Why would you need a class like this?
22EmptyElseBlockEmpty else blocks are confusing and serve no purpose.
23EmptyFinallyBlockEmpty finally blocks are confusing and serve no purpose.
24EmptyForStatementEmpty for statements are confusing and serve no purpose.
25EmptyIfStatementEmpty if statements are confusing and serve no purpose.
26EmptyInstanceInitializerAn empty class instance initializer was found. It is safe to remove it.
27EmptyMethodA method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation.
28EmptyStaticInitializerAn empty static initializer was found. It is safe to remove it.
29EmptySwitchStatementEmpty switch statements are confusing and serve no purpose.
30EmptySynchronizedStatementEmpty synchronized statements are confusing and serve no purpose.
31EmptyTryBlockEmpty try blocks are confusing and serve no purpose.
32EmptyWhileStatementEmpty while statements are confusing and serve no purpose.
33EqualsAndHashCodeIf either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden.
34EqualsOverloadedThe class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it.
35ExplicitGarbageCollectionCalls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself.
36ForLoopShouldBeWhileLoopA for loop without an init and update statement can be simplified to a while loop.
37HardCodedWindowsFileSeparatorThis rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant.
38HardCodedWindowsRootDirectoryThis rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative.
39ImportFromSamePackageAn import of a class that is within the same package is unnecessary.
40ImportFromSunPackagesAvoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.
41IntegerGetIntegerThis rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop'].
42MisorderedStaticImportsStatic imports should never be declared after nonstatic imports.
43MultipleUnaryOperatorsChecks for multiple consecutive unary operators. These are confusing, and are likely typos and bugs.
44NoWildcardImportsWildcard imports, static or otherwise, should not be used.
45RandomDoubleCoercedToZeroThe Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug.
46RemoveAllOnSelfDon't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException.
47ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
48ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
49UnnecessaryGroovyImportA Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger.
50UnusedImportImports for a class that is never referenced within the source file is unnecessary.
CodeNarc-0.23/src/site/resources/CodeNarc-Gradle-Report.html0000644000175000017500000121147212006632014023224 0ustar ebourgebourgCodeNarc Report: Gradle-1.0-milestone-9

CodeNarc Report

Summary by Package

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages258125-56389
src/org/gradle/api/internal1----
src/org/gradle/api/internal/artifacts/dsl11--4
src/org/gradle/api/internal/artifacts/dsl/dependencies22--3
src/org/gradle/api/internal/file43--4
src/org/gradle/api/internal/plugins1----
src/org/gradle/api/internal/project33--18
src/org/gradle/api/internal/tasks/compile31-11
src/org/gradle/api/internal/tasks/scala11-12
src/org/gradle/api/plugins75--13
src/org/gradle/api/plugins/announce3----
src/org/gradle/api/plugins/announce/internal126-77
src/org/gradle/api/plugins/osgi1----
src/org/gradle/api/plugins/quality197--25
src/org/gradle/api/plugins/quality/internal11-42
src/org/gradle/api/plugins/scala22-111
src/org/gradle/api/plugins/sonar2----
src/org/gradle/api/plugins/sonar/internal11--1
src/org/gradle/api/plugins/sonar/model42--2
src/org/gradle/api/publication42--3
src/org/gradle/api/publication/maven6----
src/org/gradle/api/publication/maven/internal11--2
src/org/gradle/api/publication/maven/internal/ant22--2
src/org/gradle/api/publication/maven/internal/model31--1
src/org/gradle/api/publication/maven/internal/modelbuilder2----
src/org/gradle/api/tasks2----
src/org/gradle/api/tasks/application11--20
src/org/gradle/api/tasks/bundling22--9
src/org/gradle/api/tasks/compile71--2
src/org/gradle/api/tasks/javadoc21--1
src/org/gradle/api/tasks/scala31-12
src/org/gradle/api/tasks/testing/testng11--4
src/org/gradle/api/tasks/util11-28
src/org/gradle/groovy/scripts22--12
src/org/gradle/initialization32--3
src/org/gradle/integtests/fixtures1715-3052
src/org/gradle/plugins/binaries/model/internal11--1
src/org/gradle/plugins/binaries/tasks1----
src/org/gradle/plugins/cpp3----
src/org/gradle/plugins/cpp/cdt1----
src/org/gradle/plugins/cpp/cdt/model41-1-
src/org/gradle/plugins/cpp/cdt/tasks1----
src/org/gradle/plugins/cpp/gpp32--8
src/org/gradle/plugins/cpp/msvcpp1----
src/org/gradle/plugins/ear22--4
src/org/gradle/plugins/ear/descriptor/internal42-22
src/org/gradle/plugins/ide/api3----
src/org/gradle/plugins/ide/eclipse72--11
src/org/gradle/plugins/ide/eclipse/internal2----
src/org/gradle/plugins/ide/eclipse/model2712--28
src/org/gradle/plugins/ide/eclipse/model/internal82--4
src/org/gradle/plugins/ide/idea43--3
src/org/gradle/plugins/ide/idea/internal1----
src/org/gradle/plugins/ide/idea/model1713--49
src/org/gradle/plugins/ide/idea/model/internal2----
src/org/gradle/plugins/ide/internal22-111
src/org/gradle/plugins/ide/internal/configurer31--3
src/org/gradle/plugins/ide/internal/generator32-22
src/org/gradle/plugins/signing74-128
src/org/gradle/plugins/signing/signatory3----
src/org/gradle/plugins/signing/signatory/pgp41--1
src/org/gradle/plugins/signing/type61--3
src/org/gradle/plugins/signing/type/pgp1----
src/org/gradle/profile11-1-
src/org/gradle/testing/internal/util1----
src/org/gradle/util85-117

Package: src.org.gradle.api.internal.artifacts.dsl

➥ DefaultArtifactHandler.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration335

[SRC]def DefaultArtifactHandler(ConfigurationContainer config..ctFactory) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler. The def keyword is unneeded on constructors

UnnecessaryPackageReference340

[SRC]private PublishArtifact pushArtifact(org.gradle.api.arti..reClosure) {

[MSG]The org.gradle.api.artifacts.Configuration class was explicitly imported, so specifying the package name is not necessary

UnnecessaryDefInMethodDeclaration355

[SRC]public def methodMissing(String name, args) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler. The def keyword is unneeded when a method is marked public

UnnecessaryGetter358

[SRC]if (!getMetaClass().respondsTo(this, name, args.size())) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler. getMetaClass() can probably be rewritten as metaClass

Package: src.org.gradle.api.internal.artifacts.dsl.dependencies

➥ DefaultDependencyHandler.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration334

[SRC]def DefaultDependencyHandler(ConfigurationContainer conf..encyFactory,

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler. The def keyword is unneeded on constructors

UnnecessaryGetter393

[SRC]if (!getMetaClass().respondsTo(this, name, args.size())) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler. getMetaClass() can probably be rewritten as metaClass

➥ ModuleDescriptorDelegate.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration329

[SRC]def ModuleFactoryDelegate(ClientModule clientModule, Dep..cyFactory) {

[MSG]Violation in class org.gradle.api.internal.artifacts.dsl.dependencies.ModuleFactoryDelegate. The def keyword is unneeded on constructors

Package: src.org.gradle.api.internal.file

➥ AntFileCollectionBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure333

[SRC]node."${childNodeName ?: 'resources'}"() {

[MSG]Violation in class org.gradle.api.internal.file.AntFileCollectionBuilder. Parentheses in the 'null' method call are unnecessary and can be removed.

➥ AntFileCollectionMatchingTaskBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration324

[SRC]def AntFileCollectionMatchingTaskBuilder(Iterable<Direct..fileTrees) {

[MSG]Violation in class org.gradle.api.internal.file.AntFileCollectionMatchingTaskBuilder. The def keyword is unneeded on constructors

➥ AntFileTreeBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration324

[SRC]def AntFileTreeBuilder(Map<String, File> files) {

[MSG]Violation in class org.gradle.api.internal.file.AntFileTreeBuilder. The def keyword is unneeded on constructors

UnnecessaryParenthesesForMethodCallWithClosure329

[SRC]node."${childNodeName ?: 'resources'}"() {

[MSG]Violation in class org.gradle.api.internal.file.AntFileTreeBuilder. Parentheses in the 'null' method call are unnecessary and can be removed.

Package: src.org.gradle.api.internal.project

➥ DefaultAntBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration332

[SRC]def DefaultAntBuilder(Project gradleProject) {

[MSG]Violation in class org.gradle.api.internal.project.DefaultAntBuilder. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration336

[SRC]def Object invokeMethod(String methodName, Object args) {

[MSG]Violation in class org.gradle.api.internal.project.DefaultAntBuilder. The def keyword is unneeded when a method returns the Object type

UnnecessaryOverridingMethod336

[SRC]def Object invokeMethod(String methodName, Object args) {

[MSG]Violation in class DefaultAntBuilder. The method invokeMethod contains no logic and can be safely deleted

UnnecessaryDefInMethodDeclaration344

[SRC]private def doSetProperty(String property, newValue) {

[MSG]Violation in class org.gradle.api.internal.project.DefaultAntBuilder. The def keyword is unneeded when a method is marked private

UnnecessaryGetter375

[SRC]antProject.setUserProperty(MagicNames.ANT_FILE, file.get..olutePath())

[MSG]Violation in class org.gradle.api.internal.project.DefaultAntBuilder. getAbsolutePath() can probably be rewritten as absolutePath

➥ DefaultIsolatedAntBuilder.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration331

[SRC]def DefaultIsolatedAntBuilder(ClassPathRegistry classPat..erFactory) {

[MSG]Violation in class org.gradle.api.internal.project.DefaultIsolatedAntBuilder. The def keyword is unneeded on constructors

UnnecessaryDotClass3103

[SRC]Object antBuilder = gradleLoader.loadClass(BasicAntBuild..ewInstance()

[MSG]BasicAntBuilder.class can be rewritten as BasicAntBuilder

UnnecessaryDotClass3105

[SRC]Object antLogger = gradleLoader.loadClass(AntLoggingAdap..ewInstance()

[MSG]AntLoggingAdapter.class can be rewritten as AntLoggingAdapter

UnnecessaryGetter3106

[SRC]antBuilder.project.removeBuildListener(antBuilder.projec..teners()[0])

[MSG]Violation in class org.gradle.api.internal.project.DefaultIsolatedAntBuilder. getBuildListeners() can probably be rewritten as buildListeners

UnnecessaryDefInMethodDeclaration3124

[SRC]def AntBuilderDelegate(builder, antlibClassLoader) {

[MSG]Violation in class org.gradle.api.internal.project.AntBuilderDelegate. The def keyword is unneeded on constructors

➥ ProjectScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration329

[SRC]def void apply(Closure closure) {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration333

[SRC]def void apply(Map options) {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration337

[SRC]def ScriptHandler getBuildscript() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration341

[SRC]def void buildscript(Closure configureClosure) {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration345

[SRC]def StandardOutputCapture getStandardOutputCapture() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration349

[SRC]def LoggingManager getLogging() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration353

[SRC]def Logger getLogger() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration357

[SRC]def String toString() {

[MSG]Violation in class org.gradle.api.internal.project.ProjectScript. The def keyword is unneeded when a method specifies a return type

Package: src.org.gradle.api.internal.tasks.compile

➥ AntGroovyCompiler.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField235

[SRC]private static Logger logger = LoggerFactory.getLogger(A..ovyCompiler)

[MSG]The field logger is not used within the class org.gradle.api.internal.tasks.compile.AntGroovyCompiler

UnnecessaryDefInMethodDeclaration342

[SRC]def AntGroovyCompiler(IsolatedAntBuilder ant, ClassPathR..hRegistry) {

[MSG]Violation in class org.gradle.api.internal.tasks.compile.AntGroovyCompiler. The def keyword is unneeded on constructors

Package: src.org.gradle.api.internal.tasks.scala

➥ AntScalaCompiler.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField227

[SRC]private static Logger logger = LoggerFactory.getLogger(A..alaCompiler)

[MSG]The field logger is not used within the class org.gradle.api.internal.tasks.scala.AntScalaCompiler

UnnecessaryDefInMethodDeclaration333

[SRC]def AntScalaCompiler(IsolatedAntBuilder antBuilder) {

[MSG]Violation in class org.gradle.api.internal.tasks.scala.AntScalaCompiler. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration339

[SRC]def AntScalaCompiler(IsolatedAntBuilder antBuilder, Iter..nsionDirs) {

[MSG]Violation in class org.gradle.api.internal.tasks.scala.AntScalaCompiler. The def keyword is unneeded on constructors

Package: src.org.gradle.api.plugins

➥ ApplicationPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences398

[SRC]installTask.doLast {

[MSG]The code could be more concise by using a with() or identity() block

➥ BasePlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass377

[SRC]Delete clean = project.tasks.add(CLEAN_TASK_NAME, Delete.class)

[MSG]Delete.class can be rewritten as Delete

UnnecessarySubstring392

[SRC]String targetTaskName = taskName.substring(prefix.length())

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring3118

[SRC]Configuration configuration = project.configurations.fin...length())))

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3120

[SRC]project.tasks.add(taskName).dependsOn(configuration.getA..figuration))

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. getAllArtifacts() can probably be rewritten as allArtifacts

UnnecessaryGetter3158

[SRC]Upload upload = project.getTasks().add(name, Upload.class)

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. getTasks() can probably be rewritten as tasks

UnnecessaryDotClass3158

[SRC]Upload upload = project.getTasks().add(name, Upload.class)

[MSG]Upload.class can be rewritten as Upload

UnnecessaryGetter3161

[SRC]upload.descriptorDestination = new File(project.getBuild.., "ivy.xml")

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. getBuildDir() can probably be rewritten as buildDir

UnnecessaryGetter3168

[SRC]ConfigurationContainer configurations = project.getConfigurations();

[MSG]Violation in class org.gradle.api.plugins.BasePlugin. getConfigurations() can probably be rewritten as configurations

➥ JavaPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass374

[SRC]sourceSets = instantiator.newInstance(DefaultSourceSetCo..nstantiator)

[MSG]DefaultSourceSetContainer.class can be rewritten as DefaultSourceSetContainer

UnnecessaryGetter3185

[SRC]return ConfigureUtil.configure(closure, new DefaultManif..eResolver));

[MSG]Violation in class org.gradle.api.plugins.JavaPluginConvention. getProject() can probably be rewritten as project

➥ ProjectReportsPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration329

[SRC]def ProjectReportsPluginConvention(Project project) {

[MSG]Violation in class org.gradle.api.plugins.ProjectReportsPluginConvention. The def keyword is unneeded on constructors

➥ WarPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration327

[SRC]def WarPluginConvention(Project project) {

[MSG]Violation in class org.gradle.api.plugins.WarPluginConvention. The def keyword is unneeded on constructors

Package: src.org.gradle.api.plugins.announce.internal

➥ AnnouncingBuildListener.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter235

[SRC]void beforeExecute(Task task) {

[MSG]Violation in class AnnouncingBuildListener. Method parameter [task] is never referenced in the method beforeExecute of class org.gradle.api.plugins.announce.internal.AnnouncingBuildListener

UnnecessaryElseStatement373

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ AppleScriptBackedGrowlAnnouncer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration356

[SRC]private def escape(String value) {

[MSG]Violation in class org.gradle.api.plugins.announce.internal.AppleScriptBackedGrowlAnnouncer. The def keyword is unneeded when a method is marked private

➥ DefaultAnnouncerFactory.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock266

[SRC]} catch (ClassNotFoundException e) {

[MSG]The catch block is empty

UnusedMethodParameter278

[SRC]void send(String title, String message) {

[MSG]Violation in class UnknownAnnouncer. Method parameter [title] is never referenced in the method send of class org.gradle.api.plugins.announce.internal.UnknownAnnouncer

UnusedMethodParameter278

[SRC]void send(String title, String message) {

[MSG]Violation in class UnknownAnnouncer. Method parameter [message] is never referenced in the method send of class org.gradle.api.plugins.announce.internal.UnknownAnnouncer

UnnecessaryElseStatement351

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter365

[SRC]return getClass().getClassLoader().loadClass("org.gradle..conProvider)

[MSG]Violation in class org.gradle.api.plugins.announce.internal.DefaultAnnouncerFactory. getClassLoader() can probably be rewritten as classLoader

➥ GrowlNotifyBackedAnnouncer.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethod246

[SRC]private def escape(String value) {

[MSG]The method escape is not used within GrowlNotifyBackedAnnouncer.groovy

UnnecessaryDefInMethodDeclaration346

[SRC]private def escape(String value) {

[MSG]Violation in class org.gradle.api.plugins.announce.internal.GrowlNotifyBackedAnnouncer. The def keyword is unneeded when a method is marked private

➥ Snarl.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter343

[SRC]with(new PrintWriter(sock.getOutputStream(), true)) { out ->

[MSG]Violation in class org.gradle.api.plugins.announce.internal.Snarl. getOutputStream() can probably be rewritten as outputStream

UnnecessaryElseStatement366

[SRC]else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ Twitter.groovy

Rule NamePriorityLine #Source Line / Message
ImportFromSunPackages220

[SRC]import sun.misc.BASE64Encoder

[MSG]The file imports sun.misc.BASE64Encoder, which is not portable and likely to change

UnusedMethodParameter240

[SRC]void send(String title, String message) {

[MSG]Violation in class Twitter. Method parameter [title] is never referenced in the method send of class org.gradle.api.plugins.announce.internal.Twitter

Package: src.org.gradle.api.plugins.quality

➥ Checkstyle.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter366

[SRC]getConfigProperties()

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getConfigProperties() can probably be rewritten as configProperties

UnnecessaryGetter3144

[SRC]antBuilder.withClasspath(getCheckstyleClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getCheckstyleClasspath() can probably be rewritten as checkstyleClasspath

UnnecessaryGetter3147

[SRC]ant.checkstyle(config: getConfigFile(), failOnViolation:..pertyName) {

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getConfigFile() can probably be rewritten as configFile

UnnecessaryGetter3148

[SRC]getSource().addToAntBuilder(ant, 'fileset', FileCollecti..ype.FileSet)

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getSource() can probably be rewritten as source

UnnecessaryGetter3149

[SRC]getClasspath().addToAntBuilder(ant, 'classpath')

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter3155

[SRC]getConfigProperties().each { key, value ->

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getConfigProperties() can probably be rewritten as configProperties

UnnecessaryGetter3160

[SRC]if (!getIgnoreFailures() && ant.project.properties[propertyName]) {

[MSG]Violation in class org.gradle.api.plugins.quality.Checkstyle. getIgnoreFailures() can probably be rewritten as ignoreFailures

➥ CodeNarc.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3102

[SRC]antBuilder.withClasspath(getCodenarcClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.CodeNarc. getCodenarcClasspath() can probably be rewritten as codenarcClasspath

UnnecessaryGetter3105

[SRC]ant.codenarc(ruleSetFiles: "file:${getConfigFile()}", ma..ations: 0) {

[MSG]Violation in class org.gradle.api.plugins.quality.CodeNarc. getConfigFile() can probably be rewritten as configFile

UnnecessaryGetter3116

[SRC]if (getIgnoreFailures()) {

[MSG]Violation in class org.gradle.api.plugins.quality.CodeNarc. getIgnoreFailures() can probably be rewritten as ignoreFailures

➥ FindBugs.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3113

[SRC]antBuilder.withClasspath(getFindbugsClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getFindbugsClasspath() can probably be rewritten as findbugsClasspath

UnnecessaryGetter3116

[SRC]getFindbugsClasspath().addToAntBuilder(ant, 'classpath')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getFindbugsClasspath() can probably be rewritten as findbugsClasspath

UnnecessaryGetter3117

[SRC]getPluginClasspath().addToAntBuilder(ant, 'pluginList')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getPluginClasspath() can probably be rewritten as pluginClasspath

UnnecessaryGetter3118

[SRC]getClasses().addToAntBuilder(ant, 'auxAnalyzepath')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getClasses() can probably be rewritten as classes

UnnecessaryGetter3121

[SRC]addUnlessEmpty(ant, getClasspath(), 'auxClasspath')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter3122

[SRC]addUnlessEmpty(ant, getSource(), 'sourcePath')

[MSG]Violation in class org.gradle.api.plugins.quality.FindBugs. getSource() can probably be rewritten as source

➥ GroovyCodeQualityPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration340

[SRC]def GroovyCodeQualityPluginConvention(Project project) {

[MSG]Violation in class org.gradle.api.plugins.quality.GroovyCodeQualityPluginConvention. The def keyword is unneeded on constructors

➥ JDepend.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter399

[SRC]antBuilder.withClasspath(getJdependClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.JDepend. getJdependClasspath() can probably be rewritten as jdependClasspath

UnnecessaryGetter3103

[SRC]pathElement(location: getClassesDir())

[MSG]Violation in class org.gradle.api.plugins.quality.JDepend. getClassesDir() can probably be rewritten as classesDir

➥ JavaCodeQualityPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration340

[SRC]def JavaCodeQualityPluginConvention(Project project) {

[MSG]Violation in class org.gradle.api.plugins.quality.JavaCodeQualityPluginConvention. The def keyword is unneeded on constructors

➥ Pmd.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter368

[SRC]antBuilder.withClasspath(getPmdClasspath()).execute {

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getPmdClasspath() can probably be rewritten as pmdClasspath

UnnecessaryGetter370

[SRC]ant.pmd(failOnRuleViolation: !getIgnoreFailures()) {

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getIgnoreFailures() can probably be rewritten as ignoreFailures

UnnecessaryGetter371

[SRC]getSource().addToAntBuilder(ant, 'fileset', FileCollecti..ype.FileSet)

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getSource() can probably be rewritten as source

UnnecessaryGetter372

[SRC]getRuleSets().each {

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getRuleSets() can probably be rewritten as ruleSets

UnnecessaryGetter375

[SRC]getRuleSetFiles().each {

[MSG]Violation in class org.gradle.api.plugins.quality.Pmd. getRuleSetFiles() can probably be rewritten as ruleSetFiles

Package: src.org.gradle.api.plugins.quality.internal

➥ AbstractCodeQualityPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2106

[SRC]protected void configureTaskDefaults(T task, String baseName) {

[MSG]Violation in class AbstractCodeQualityPlugin. Method parameter [task] is never referenced in the method configureTaskDefaults of class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin

UnusedMethodParameter2106

[SRC]protected void configureTaskDefaults(T task, String baseName) {

[MSG]Violation in class AbstractCodeQualityPlugin. Method parameter [baseName] is never referenced in the method configureTaskDefaults of class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin

UnusedMethodParameter2118

[SRC]protected void configureForSourceSet(SourceSet sourceSet, T task) {

[MSG]Violation in class AbstractCodeQualityPlugin. Method parameter [sourceSet] is never referenced in the method configureForSourceSet of class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin

UnusedMethodParameter2118

[SRC]protected void configureForSourceSet(SourceSet sourceSet, T task) {

[MSG]Violation in class AbstractCodeQualityPlugin. Method parameter [task] is never referenced in the method configureForSourceSet of class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin

UnnecessarySubstring3101

[SRC]prunedName = prunedName[0].toLowerCase() + prunedName.substring(1)

[MSG]Violation in class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryCollectCall3123

[SRC]project.tasks['check'].dependsOn { extension.sourceSets...me, null) }}

[MSG]Violation in class org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin. The call to collect could probably be rewritten as a spread expression: extension.sourceSets*.getTaskName(taskBaseName, null)

Package: src.org.gradle.api.plugins.scala

➥ ScalaBasePlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateMethodParameter264

[SRC]private void configureCompileDefaults(final Project proj..avaPlugin) {

[MSG]Violation in class ScalaBasePlugin. Method parameter [javaPlugin] is never referenced in the method configureCompileDefaults of class org.gradle.api.plugins.scala.ScalaBasePlugin

UnnecessaryDotClass335

[SRC]JavaBasePlugin javaPlugin = project.plugins.apply(JavaBa..ugin.class);

[MSG]JavaBasePlugin.class can be rewritten as JavaBasePlugin

UnnecessaryDotClass346

[SRC]project.convention.getPlugin(JavaPluginConvention.class)..sourceSet ->

[MSG]JavaPluginConvention.class can be rewritten as JavaPluginConvention

UnnecessaryDotClass354

[SRC]ScalaCompile scalaCompile = project.tasks.add(taskName, ..pile.class);

[MSG]ScalaCompile.class can be rewritten as ScalaCompile

UnnecessaryDotClass365

[SRC]project.tasks.withType(ScalaCompile.class) {ScalaCompile compile ->

[MSG]ScalaCompile.class can be rewritten as ScalaCompile

UnnecessaryGetter371

[SRC]project.getTasks().withType(ScalaDoc.class) {ScalaDoc scalaDoc ->

[MSG]Violation in class org.gradle.api.plugins.scala.ScalaBasePlugin. getTasks() can probably be rewritten as tasks

UnnecessaryDotClass371

[SRC]project.getTasks().withType(ScalaDoc.class) {ScalaDoc scalaDoc ->

[MSG]ScalaDoc.class can be rewritten as ScalaDoc

➥ ScalaPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass330

[SRC]project.plugins.apply(ScalaBasePlugin.class);

[MSG]ScalaBasePlugin.class can be rewritten as ScalaBasePlugin

UnnecessaryDotClass331

[SRC]project.plugins.apply(JavaPlugin.class);

[MSG]JavaPlugin.class can be rewritten as JavaPlugin

UnnecessaryGetter337

[SRC]project.getTasks().withType(ScalaDoc.class) {ScalaDoc scalaDoc ->

[MSG]Violation in class org.gradle.api.plugins.scala.ScalaPlugin. getTasks() can probably be rewritten as tasks

UnnecessaryDotClass337

[SRC]project.getTasks().withType(ScalaDoc.class) {ScalaDoc scalaDoc ->

[MSG]ScalaDoc.class can be rewritten as ScalaDoc

UnnecessaryDotClass341

[SRC]ScalaDoc scalaDoc = project.tasks.add(SCALA_DOC_TASK_NAM..laDoc.class)

[MSG]ScalaDoc.class can be rewritten as ScalaDoc

Package: src.org.gradle.api.plugins.sonar.internal

➥ SonarCodeAnalyzer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences371

[SRC]projectDef.workDir = sonarProject.workDir

[MSG]The code could be more concise by using a with() or identity() block

Package: src.org.gradle.api.plugins.sonar.model

➥ IncludeProperties.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryPackageReference326

[SRC]public @interface IncludeProperties {}

[MSG]The java.lang.annotation.Annotation class was explicitly imported, so specifying the package name is not necessary

➥ SonarProperty.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryPackageReference326

[SRC]public @interface SonarProperty {

[MSG]The java.lang.annotation.Annotation class was explicitly imported, so specifying the package name is not necessary

Package: src.org.gradle.api.publication

➥ PublicationPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass336

[SRC]project.task("publishArchives", dependsOn: 'assemble', t..ons.class) {

[MSG]PublishPublications.class can be rewritten as PublishPublications

UnnecessaryDotClass339

[SRC]project.task("installArchives", dependsOn: 'assemble', t..ons.class) {

[MSG]InstallPublications.class can be rewritten as InstallPublications

➥ Publications.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter327

[SRC]ConfigureUtil.configure(c, getMaven())

[MSG]Violation in class org.gradle.api.publication.Publications. getMaven() can probably be rewritten as maven

Package: src.org.gradle.api.publication.maven.internal

➥ MavenPublicationPomGenerator.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryObjectReferences344

[SRC]model.description = publication.description

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences355

[SRC]dependency.optional = mavenDep.optional

[MSG]The code could be more concise by using a with() or identity() block

Package: src.org.gradle.api.publication.maven.internal.ant

➥ DefaultGroovyMavenDeployer.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryElseStatement347

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ DefaultMavenPublisher.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration355

[SRC]private def execute(MavenPublication publication, Instal..port task) {

[MSG]Violation in class org.gradle.api.publication.maven.internal.ant.DefaultMavenPublisher. The def keyword is unneeded when a method is marked private

Package: src.org.gradle.api.publication.maven.internal.model

➥ DefaultMavenPublication.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter342

[SRC]ConfigureUtil.configure(c, getRepository())

[MSG]Violation in class org.gradle.api.publication.maven.internal.model.DefaultMavenPublication. getRepository() can probably be rewritten as repository

Package: src.org.gradle.api.tasks.application

➥ CreateStartScripts.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter369

[SRC]if (!getApplicationName()) {

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter372

[SRC]return "${GUtil.toConstant(getApplicationName())}_OPTS"

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter380

[SRC]if (!getApplicationName()) {

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter383

[SRC]return "${GUtil.toConstant(getApplicationName())}_EXIT_CONSOLE"

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter388

[SRC]return new File(getOutputDir(), getApplicationName())

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter388

[SRC]return new File(getOutputDir(), getApplicationName())

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter393

[SRC]return new File(getOutputDir(), "${getApplicationName()}.bat")

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter393

[SRC]return new File(getOutputDir(), "${getApplicationName()}.bat")

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter398

[SRC]getOutputDir().mkdirs()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter3101

[SRC]generator.applicationName = getApplicationName()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getApplicationName() can probably be rewritten as applicationName

UnnecessaryGetter3102

[SRC]generator.mainClassName = getMainClassName()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getMainClassName() can probably be rewritten as mainClassName

UnnecessaryGetter3103

[SRC]generator.optsEnvironmentVar = getOptsEnvironmentVar()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getOptsEnvironmentVar() can probably be rewritten as optsEnvironmentVar

UnnecessaryGetter3104

[SRC]generator.exitEnvironmentVar = getExitEnvironmentVar()

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getExitEnvironmentVar() can probably be rewritten as exitEnvironmentVar

UnnecessaryGetter3105

[SRC]generator.classpath = getClasspath().collect { "lib/${it.name}" }

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter3106

[SRC]generator.scriptRelPath = "bin/${getUnixScript().name}"

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getUnixScript() can probably be rewritten as unixScript

UnnecessaryObjectReferences3106

[SRC]generator.scriptRelPath = "bin/${getUnixScript().name}"

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3107

[SRC]generator.generateUnixScript(getUnixScript())

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getUnixScript() can probably be rewritten as unixScript

UnnecessaryObjectReferences3107

[SRC]generator.generateUnixScript(getUnixScript())

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3108

[SRC]generator.generateWindowsScript(getWindowsScript())

[MSG]Violation in class org.gradle.api.tasks.application.CreateStartScripts. getWindowsScript() can probably be rewritten as windowsScript

UnnecessaryObjectReferences3108

[SRC]generator.generateWindowsScript(getWindowsScript())

[MSG]The code could be more concise by using a with() or identity() block

Package: src.org.gradle.api.tasks.bundling

➥ Jar.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter347

[SRC]Manifest manifest = getManifest() ?: new DefaultManifest(null)

[MSG]Violation in class org.gradle.api.tasks.bundling.Jar. getManifest() can probably be rewritten as manifest

UnnecessaryGetter386

[SRC]if (getManifest() == null) {

[MSG]Violation in class org.gradle.api.tasks.bundling.Jar. getManifest() can probably be rewritten as manifest

UnnecessaryGetter389

[SRC]ConfigureUtil.configure(configureClosure, getManifest());

[MSG]Violation in class org.gradle.api.tasks.bundling.Jar. getManifest() can probably be rewritten as manifest

UnnecessaryGetter3107

[SRC]return ConfigureUtil.configure(configureClosure, getMetaInf())

[MSG]Violation in class org.gradle.api.tasks.bundling.Jar. getMetaInf() can probably be rewritten as metaInf

➥ War.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter346

[SRC]def classpath = getClasspath()

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter352

[SRC]def classpath = getClasspath()

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getClasspath() can probably be rewritten as classpath

UnnecessaryGetter358

[SRC]getWebXml()

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getWebXml() can probably be rewritten as webXml

UnnecessaryGetter380

[SRC]return ConfigureUtil.configure(configureClosure, getWebInf())

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getWebInf() can probably be rewritten as webInf

UnnecessaryGetter3110

[SRC]FileCollection oldClasspath = getClasspath()

[MSG]Violation in class org.gradle.api.tasks.bundling.War. getClasspath() can probably be rewritten as classpath

Package: src.org.gradle.api.tasks.compile

➥ AbstractOptions.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter348

[SRC]((field.getModifiers() & Modifier.STATIC) == 0) &&

[MSG]Violation in class org.gradle.api.tasks.compile.AbstractOptions. getModifiers() can probably be rewritten as modifiers

UnnecessaryGetter349

[SRC](field.getName() != "metaClass") &&

[MSG]Violation in class org.gradle.api.tasks.compile.AbstractOptions. getName() can probably be rewritten as name

Package: src.org.gradle.api.tasks.javadoc

➥ AntGroovydoc.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration331

[SRC]def AntGroovydoc(IsolatedAntBuilder ant, ClassPathRegist..hRegistry) {

[MSG]Violation in class org.gradle.api.tasks.javadoc.AntGroovydoc. The def keyword is unneeded on constructors

Package: src.org.gradle.api.tasks.scala

➥ AntScalaDoc.groovy

Rule NamePriorityLine #Source Line / Message
UnusedPrivateField224

[SRC]private static Logger logger = LoggerFactory.getLogger(AntScalaDoc)

[MSG]The field logger is not used within the class org.gradle.api.tasks.scala.AntScalaDoc

UnnecessaryDefInMethodDeclaration330

[SRC]def AntScalaDoc(IsolatedAntBuilder antBuilder) {

[MSG]Violation in class org.gradle.api.tasks.scala.AntScalaDoc. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration336

[SRC]def AntScalaDoc(IsolatedAntBuilder antBuilder, Iterable<..nsionDirs) {

[MSG]Violation in class org.gradle.api.tasks.scala.AntScalaDoc. The def keyword is unneeded on constructors

Package: src.org.gradle.api.tasks.testing.testng

➥ TestNGOptions.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3194

[SRC]return suiteXmlBuilder.getMetaClass()."${name}"

[MSG]Violation in class org.gradle.api.tasks.testing.testng.TestNGOptions. getMetaClass() can probably be rewritten as metaClass

UnnecessaryElseStatement3195

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3202

[SRC]return suiteXmlBuilder.getMetaClass().invokeMethod(suite.. name, args)

[MSG]Violation in class org.gradle.api.tasks.testing.testng.TestNGOptions. getMetaClass() can probably be rewritten as metaClass

UnnecessaryElseStatement3203

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

Package: src.org.gradle.api.tasks.util

➥ PatternSet.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2206

[SRC]def addToAntBuilder(node, String childNodeName = null) {

[MSG]Violation in class PatternSet. Method parameter [childNodeName] is never referenced in the method addToAntBuilder of class org.gradle.api.tasks.util.PatternSet

UnusedMethodParameter2242

[SRC]def addToAntBuilder(Object node, String childNodeName) {

[MSG]Violation in class IntersectionPatternSet. Method parameter [childNodeName] is never referenced in the method addToAntBuilder of class org.gradle.api.tasks.util.IntersectionPatternSet

UnnecessaryDefInFieldDeclaration351

[SRC]def boolean caseSensitive = true

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a field type is specified

UnnecessaryDefInMethodDeclaration357

[SRC]static def setGlobalExcludes(Collection<String> excludes) {

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a method is marked static

UnnecessaryDefInMethodDeclaration362

[SRC]static def resetGlobalExcludes() {

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a method is marked static

UnnecessaryDefInMethodDeclaration366

[SRC]def boolean equals(Object o) {

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration376

[SRC]def int hashCode() {

[MSG]Violation in class org.gradle.api.tasks.util.PatternSet. The def keyword is unneeded when a method specifies a return type

UnnecessaryDefInMethodDeclaration3234

[SRC]def IntersectionPatternSet(PatternSet other) {

[MSG]Violation in class org.gradle.api.tasks.util.IntersectionPatternSet. The def keyword is unneeded on constructors

UnnecessaryGetter3239

[SRC]return new AndSpec<FileTreeElement>([super.getAsSpec(), ..] as Spec[])

[MSG]Violation in class org.gradle.api.tasks.util.IntersectionPatternSet. getAsSpec() can probably be rewritten as asSpec

UnnecessaryGetter3239

[SRC]return new AndSpec<FileTreeElement>([super.getAsSpec(), ..] as Spec[])

[MSG]Violation in class org.gradle.api.tasks.util.IntersectionPatternSet. getAsSpec() can probably be rewritten as asSpec

Package: src.org.gradle.groovy.scripts

➥ BasicScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass334

[SRC]standardOutputCapture = services.get(StandardOutputCapture.class)

[MSG]StandardOutputCapture.class can be rewritten as StandardOutputCapture

UnnecessaryDefInMethodDeclaration338

[SRC]def Object getScriptTarget() {

[MSG]Violation in class org.gradle.groovy.scripts.BasicScript. The def keyword is unneeded when a method returns the Object type

UnnecessaryDefInMethodDeclaration342

[SRC]def StandardOutputCapture getStandardOutputCapture() {

[MSG]Violation in class org.gradle.groovy.scripts.BasicScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryGetter365

[SRC]return target.getProperties()

[MSG]Violation in class org.gradle.groovy.scripts.BasicScript. getProperties() can probably be rewritten as properties

➥ DefaultScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass343

[SRC]private static final Logger LOGGER = Logging.getLogger(Script.class)

[MSG]Script.class can be rewritten as Script

UnnecessaryDefInMethodDeclaration349

[SRC]def void init(Object target, ServiceRegistry services) {

[MSG]Violation in class org.gradle.groovy.scripts.DefaultScript. The def keyword is unneeded when a method specifies a return type

UnnecessaryDotClass352

[SRC]loggingManager = services.get(LoggingManager.class)

[MSG]LoggingManager.class can be rewritten as LoggingManager

UnnecessaryDotClass368

[SRC]ObjectConfigurationAction action = new DefaultObjectConf..criptTarget)

[MSG]ScriptPluginFactory.class can be rewritten as ScriptPluginFactory

UnnecessaryDotClass374

[SRC]ObjectConfigurationAction action = new DefaultObjectConf..criptTarget)

[MSG]ScriptPluginFactory.class can be rewritten as ScriptPluginFactory

UnnecessaryDotClass380

[SRC]return services.get(ScriptHandler.class);

[MSG]ScriptHandler.class can be rewritten as ScriptHandler

UnnecessaryGetter384

[SRC]ConfigureUtil.configure(configureClosure, getBuildscript())

[MSG]Violation in class org.gradle.groovy.scripts.DefaultScript. getBuildscript() can probably be rewritten as buildscript

UnnecessaryDefInMethodDeclaration3172

[SRC]def String toString() {

[MSG]Violation in class org.gradle.groovy.scripts.DefaultScript. The def keyword is unneeded when a method specifies a return type

Package: src.org.gradle.initialization

➥ InitScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter323

[SRC]getBuildscript()

[MSG]Violation in class org.gradle.initialization.InitScript. getBuildscript() can probably be rewritten as buildscript

UnnecessaryDefInMethodDeclaration330

[SRC]def String toString() {

[MSG]Violation in class org.gradle.initialization.InitScript. The def keyword is unneeded when a method specifies a return type

➥ SettingsScript.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration321

[SRC]def String toString() {

[MSG]Violation in class org.gradle.initialization.SettingsScript. The def keyword is unneeded when a method specifies a return type

Package: src.org.gradle.integtests.fixtures

➥ AbstractAutoTestedSamplesTest.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod226

[SRC]void runSamplesFrom(String dir) {

[MSG]Violation in class AbstractAutoTestedSamplesTest. The method runSamplesFrom is public but not a test method

JUnitPublicNonTestMethod241

[SRC]void includeOnly(String includes) {

[MSG]Violation in class AbstractAutoTestedSamplesTest. The method includeOnly is public but not a test method

➥ AbstractIntegrationSpec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter344

[SRC]distribution.getTestDir();

[MSG]Violation in class org.gradle.integtests.fixtures.AbstractIntegrationSpec. getTestDir() can probably be rewritten as testDir

UnnecessaryGetter348

[SRC]getTestDir().file(path);

[MSG]Violation in class org.gradle.integtests.fixtures.AbstractIntegrationSpec. getTestDir() can probably be rewritten as testDir

UnnecessaryGetter3130

[SRC]executer.withUserHomeDir(distribution.getUserHomeDir())

[MSG]Violation in class org.gradle.integtests.fixtures.AbstractIntegrationSpec. getUserHomeDir() can probably be rewritten as userHomeDir

UnnecessaryGetter3131

[SRC]return new GradleBackedArtifactBuilder(executer, getTest..artifacts"))

[MSG]Violation in class org.gradle.integtests.fixtures.AbstractIntegrationSpec. getTestDir() can probably be rewritten as testDir

➥ AutoTestedSamplesUtil.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure334

[SRC]list.each() { runSamplesFromFile(it, runner) }

[MSG]Violation in class org.gradle.integtests.fixtures.AutoTestedSamplesUtil. Parentheses in the 'each' method call are unnecessary and can be removed.

➥ CrossVersionIntegrationSpec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]current.getTestDir();

[MSG]Violation in class org.gradle.integtests.fixtures.CrossVersionIntegrationSpec. getTestDir() can probably be rewritten as testDir

➥ CrossVersionTestRunner.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring368

[SRC]def minVersion = targetGradleVersion.substring(0, target..ength() - 1)

[MSG]Violation in class org.gradle.integtests.fixtures.CrossVersionTestRunner$PreviousVersionExecution. The String.substring(int, int) method can be replaced with the subscript operator

➥ HttpServer.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2338

[SRC]boolean reauthenticate(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [user] is never referenced in the method reauthenticate of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

UnusedMethodParameter2342

[SRC]boolean isUserInRole(Principal user, String role) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [user] is never referenced in the method isUserInRole of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

UnusedMethodParameter2342

[SRC]boolean isUserInRole(Principal user, String role) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [role] is never referenced in the method isUserInRole of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

EmptyMethod2346

[SRC]void disassociate(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. The method disassociate is both empty and not marked with @Override

UnusedMethodParameter2346

[SRC]void disassociate(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [user] is never referenced in the method disassociate of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

UnusedMethodParameter2349

[SRC]Principal pushRole(Principal user, String role) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [role] is never referenced in the method pushRole of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

EmptyMethod2357

[SRC]void logout(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. The method logout is both empty and not marked with @Override

UnusedMethodParameter2357

[SRC]void logout(Principal user) {

[MSG]Violation in class HttpServer$TestUserRealm. Method parameter [user] is never referenced in the method logout of class org.gradle.integtests.fixtures.HttpServer$TestUserRealm

UnnecessaryDotClass331

[SRC]private static Logger logger = LoggerFactory.getLogger(H..erver.class)

[MSG]HttpServer.class can be rewritten as HttpServer

UnnecessarySubstring393

[SRC]def relativePath = request.pathInfo.substring(path.length() + 1)

[MSG]Violation in class org.gradle.integtests.fixtures.HttpServer$3. The String.substring(int) method can be replaced with the subscript operator

➥ JUnitTestExecutionResult.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2100

[SRC]TestClassExecutionResult assertTestSkipped(String name) {

[MSG]Violation in class JUnitTestClassExecutionResult. Method parameter [name] is never referenced in the method assertTestSkipped of class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult

UnusedMethodParameter2110

[SRC]TestClassExecutionResult assertConfigMethodPassed(String name) {

[MSG]Violation in class JUnitTestClassExecutionResult. Method parameter [name] is never referenced in the method assertConfigMethodPassed of class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult

UnusedMethodParameter2114

[SRC]TestClassExecutionResult assertConfigMethodFailed(String name) {

[MSG]Violation in class JUnitTestClassExecutionResult. Method parameter [name] is never referenced in the method assertConfigMethodFailed of class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult

MisorderedStaticImports321

[SRC]import static org.hamcrest.Matchers.*

[MSG]Static imports should appear before normal imports

MisorderedStaticImports322

[SRC]import static org.junit.Assert.assertThat

[MSG]Static imports should appear before normal imports

UnnecessaryDefInMethodDeclaration327

[SRC]def JUnitTestExecutionResult(TestFile projectDir, String..= 'build') {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestExecutionResult. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration341

[SRC]private def findTestClass(String testClass) {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration349

[SRC]private def findClasses() {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration369

[SRC]def JUnitTestClassExecutionResult(GPathResult testClassN..ClassName) {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration3130

[SRC]private def findTests() {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3160

[SRC]private def findIgnoredTests() {

[MSG]Violation in class org.gradle.integtests.fixtures.JUnitTestClassExecutionResult. The def keyword is unneeded when a method is marked private

➥ MavenRepository.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall3106

[SRC]artifactNames = names.collect { it.replace('-SNAPSHOT', ..-${build}")}

[MSG]Violation in class org.gradle.integtests.fixtures.MavenModule. The call to collect could probably be rewritten as a spread expression: names*.replace(-SNAPSHOT, -$timestamp-$build)

UnnecessaryCollectCall3283

[SRC]assert dependencies.collect { it.artifactId} as Set == a..ctIds as Set

[MSG]Violation in class org.gradle.integtests.fixtures.MavenScope. The call to collect could probably be rewritten as a spread expression: dependencies*.artifactId

➥ PreviousGradleVersionExecuter.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration360

[SRC]def String toString() {

[MSG]Violation in class org.gradle.integtests.fixtures.PreviousGradleVersionExecuter. The def keyword is unneeded when a method specifies a return type

UnnecessaryElseStatement3102

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryDefInMethodDeclaration3158

[SRC]def TestFile getGradleHomeDir() {

[MSG]Violation in class org.gradle.integtests.fixtures.PreviousGradleVersionExecuter. The def keyword is unneeded when a method specifies a return type

➥ SFTPServer.groovy

Rule NamePriorityLine #Source Line / Message
EmptyCatchBlock270

[SRC]} catch (Throwable e) {}

[MSG]The catch block is empty

EmptyCatchBlock273

[SRC]} catch (Throwable e) {}

[MSG]The catch block is empty

EmptyCatchBlock277

[SRC]} catch (Throwable e) {}

[MSG]The catch block is empty

EmptyMethod2105

[SRC]public void showMessage(String message) {

[MSG]Violation in class SFTPServer$1. The method showMessage is both empty and not marked with @Override

UnusedMethodParameter2128

[SRC]boolean authenticate(String username, PublicKey key, Ser..n session) {

[MSG]Violation in class SFTPServer$3. Method parameter [username] is never referenced in the method authenticate of class org.gradle.integtests.fixtures.SFTPServer$3

UnusedMethodParameter2128

[SRC]boolean authenticate(String username, PublicKey key, Ser..n session) {

[MSG]Violation in class SFTPServer$3. Method parameter [key] is never referenced in the method authenticate of class org.gradle.integtests.fixtures.SFTPServer$3

UnusedMethodParameter2128

[SRC]boolean authenticate(String username, PublicKey key, Ser..n session) {

[MSG]Violation in class SFTPServer$3. Method parameter [session] is never referenced in the method authenticate of class org.gradle.integtests.fixtures.SFTPServer$3

UnusedMethodParameter2160

[SRC]boolean authenticate(String username, String password, o..n session) {

[MSG]Violation in class DummyPasswordAuthenticator. Method parameter [session] is never referenced in the method authenticate of class org.gradle.integtests.fixtures.DummyPasswordAuthenticator

UnnecessaryGetter3114

[SRC]FileUtils.copyURLToFile(fileUrl, new File(configDir.getR..-dsa.key"));

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryGetter3118

[SRC]sshServer.setFileSystemFactory(new TestNativeFileSystemF..stLogger() {

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryGetter3125

[SRC]sshServer.setKeyPairProvider(new SimpleGeneratorHostKeyP..-dsa.key"));

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryObjectReferences3126

[SRC]sshServer.setPasswordAuthenticator(new DummyPasswordAuthenticator());

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryObjectReferences3127

[SRC]sshServer.setPublickeyAuthenticator(new PublickeyAuthenticator() {

[MSG]The code could be more concise by using a with() or identity() block

UnnecessaryGetter3136

[SRC]new File(baseDir.getRoot(), filePathToCheck).exists()

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryGetter3140

[SRC]new TestFile(new File(baseDir.getRoot(), expectedPath))

[MSG]Violation in class org.gradle.integtests.fixtures.SFTPServer. getRoot() can probably be rewritten as root

UnnecessaryPackageReference3160

[SRC]boolean authenticate(String username, String password, o..n session) {

[MSG]The org.apache.sshd.server.session.ServerSession class was explicitly imported, so specifying the package name is not necessary

➥ TestNGExecutionResult.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter284

[SRC]TestClassExecutionResult assertTestsSkipped(String... testNames) {

[MSG]Violation in class TestNgTestClassExecutionResult. Method parameter [testNames] is never referenced in the method assertTestsSkipped of class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult

UnusedMethodParameter2107

[SRC]TestClassExecutionResult assertStdout(Matcher<? super St..> matcher) {

[MSG]Violation in class TestNgTestClassExecutionResult. Method parameter [matcher] is never referenced in the method assertStdout of class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult

UnusedMethodParameter2111

[SRC]TestClassExecutionResult assertStderr(Matcher<? super St..> matcher) {

[MSG]Violation in class TestNgTestClassExecutionResult. Method parameter [matcher] is never referenced in the method assertStderr of class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult

UnnecessaryDefInMethodDeclaration330

[SRC]def TestNGExecutionResult(projectDir) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNGExecutionResult. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration346

[SRC]private def findTestClass(String testClass) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNGExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration354

[SRC]private def findTestClasses() {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNGExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInFieldDeclaration364

[SRC]def String testClass

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a field type is specified

UnnecessaryDefInFieldDeclaration365

[SRC]def GPathResult testClassNode

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a field type is specified

UnnecessaryDefInMethodDeclaration367

[SRC]def TestNgTestClassExecutionResult(String testClass, GPa..resultXml) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration3127

[SRC]private def findConfigMethod(String testName) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3135

[SRC]private def findConfigMethods() {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3143

[SRC]private def findTestMethod(String testName) {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3151

[SRC]private def findTestMethods() {

[MSG]Violation in class org.gradle.integtests.fixtures.TestNgTestClassExecutionResult. The def keyword is unneeded when a method is marked private

➥ TestNativeFileSystem.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter367

[SRC]return getFile(baseDir.getAbsolutePath(), file);

[MSG]Violation in class org.gradle.integtests.fixtures.TestNativeFileSystemView. getAbsolutePath() can probably be rewritten as absolutePath

UnnecessarySubstring377

[SRC]String userFileName = physicalName.substring("/".length() - 1);

[MSG]Violation in class org.gradle.integtests.fixtures.TestNativeFileSystemView. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3107

[SRC]String userName = session.getUsername();

[MSG]Violation in class org.gradle.integtests.fixtures.TestNativeFileSystemFactory. getUsername() can probably be rewritten as username

➥ TestProxyServer.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter251

[SRC]void filter(HttpRequest httpRequest) {

[MSG]Violation in class TestProxyServer$1. Method parameter [httpRequest] is never referenced in the method filter of class org.gradle.integtests.fixtures.TestProxyServer$1

➥ UserGuideSamplesRunner.groovy

Rule NamePriorityLine #Source Line / Message
EmptyIfStatement2176

[SRC]if (line.matches('Download .+')) {

[MSG]The if statement is empty

UnnecessaryDefInMethodDeclaration342

[SRC]def UserGuideSamplesRunner(Class<?> testClass) {

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. The def keyword is unneeded on constructors

UnnecessaryGetter345

[SRC]this.dirFilter = getDirFilterPattern()

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. getDirFilterPattern() can probably be rewritten as dirFilterPattern

UnnecessaryDefInMethodDeclaration388

[SRC]private def cleanup(SampleRun run) {

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration399

[SRC]private def runSample(GradleRun run) {

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3138

[SRC]private def compareStrings(String expected, String actua..xtraLines) {

[MSG]Violation in class org.gradle.integtests.fixtures.UserGuideSamplesRunner. The def keyword is unneeded when a method is marked private

UnnecessaryPackageReference3197

[SRC]actual = actual.replaceAll(java.util.regex.Pattern.quote..le/samples')

[MSG]The java.util.regex.Pattern class was explicitly imported, so specifying the package name is not necessary

UnnecessaryPackageReference3199

[SRC]actual = actual.replaceAll(java.util.regex.Pattern.quote..rator), '/')

[MSG]The java.util.regex.Pattern class was explicitly imported, so specifying the package name is not necessary

➥ WellBehavedPluginTest.groovy

Rule NamePriorityLine #Source Line / Message
JUnitPublicNonTestMethod223

[SRC]String getPluginId() {

[MSG]Violation in class WellBehavedPluginTest. The method getPluginId is public but not a test method

JUnitPublicNonTestMethod231

[SRC]String getMainTask() {

[MSG]Violation in class WellBehavedPluginTest. The method getMainTask is public but not a test method

JUnitPublicNonTestMethod235

[SRC]def "plugin does not force creation of build dir during ..uration"() {

[MSG]Violation in class WellBehavedPluginTest. The method plugin does not force creation of build dir during configuration is public but not a test method

JUnitPublicNonTestMethod246

[SRC]def "plugin can build with empty project"() {

[MSG]Violation in class WellBehavedPluginTest. The method plugin can build with empty project is public but not a test method

UnnecessaryGetter337

[SRC]buildFile << "apply plugin: '${getPluginId()}'"

[MSG]Violation in class org.gradle.integtests.fixtures.WellBehavedPluginTest. getPluginId() can probably be rewritten as pluginId

UnnecessaryGetter348

[SRC]buildFile << "apply plugin: '${getPluginId()}'"

[MSG]Violation in class org.gradle.integtests.fixtures.WellBehavedPluginTest. getPluginId() can probably be rewritten as pluginId

Package: src.org.gradle.plugins.binaries.model.internal

➥ ConfigurationBasedNativeDependencySet.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter350

[SRC]def headersConfiguration = getHeadersConfiguration()

[MSG]Violation in class org.gradle.plugins.binaries.model.internal.ConfigurationBasedNativeDependencySet. getHeadersConfiguration() can probably be rewritten as headersConfiguration

Package: src.org.gradle.plugins.cpp.cdt.model

➥ CprojectDescriptor.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2109

[SRC]protected void store(Node xml) {

[MSG]Violation in class CprojectDescriptor. Method parameter [xml] is never referenced in the method store of class org.gradle.plugins.cpp.cdt.model.CprojectDescriptor

Package: src.org.gradle.plugins.cpp.gpp

➥ GppCompileSpec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter367

[SRC]task.outputs.file { getOutputFile() }

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getOutputFile() can probably be rewritten as outputFile

UnnecessaryGetter3143

[SRC]project.file "$project.buildDir/binaries/${getOutputFileName()}"

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getOutputFileName() can probably be rewritten as outputFileName

UnnecessaryGetter3150

[SRC]return "${getBaseName()}.${extension}"

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getBaseName() can probably be rewritten as baseName

UnnecessaryElseStatement3151

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3152

[SRC]return getDefaultOutputFileName()

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getDefaultOutputFileName() can probably be rewritten as defaultOutputFileName

UnnecessaryGetter3157

[SRC]return OperatingSystem.current().getExecutableName(getBaseName())

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppCompileSpec. getBaseName() can probably be rewritten as baseName

➥ GppLibraryCompileSpec.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter334

[SRC]return OperatingSystem.current().getSharedLibraryName(getBaseName())

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppLibraryCompileSpec. getBaseName() can probably be rewritten as baseName

UnnecessaryGetter338

[SRC]return installName ?: getOutputFileName()

[MSG]Violation in class org.gradle.plugins.cpp.gpp.GppLibraryCompileSpec. getOutputFileName() can probably be rewritten as outputFileName

Package: src.org.gradle.plugins.ear

➥ Ear.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter355

[SRC]getLibDirName()

[MSG]Violation in class org.gradle.plugins.ear.Ear. getLibDirName() can probably be rewritten as libDirName

UnnecessarySubstring366

[SRC]module = new DefaultEarWebModule(details.path, details.p..dexOf('.')))

[MSG]Violation in class org.gradle.plugins.ear.Ear. The String.substring(int, int) method can be replaced with the subscript operator

UnnecessaryGetter3128

[SRC]return ConfigureUtil.configure(configureClosure, getLib())

[MSG]Violation in class org.gradle.plugins.ear.Ear. getLib() can probably be rewritten as lib

➥ EarPluginConvention.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration365

[SRC]def EarPluginConvention(FileResolver fileResolver) {

[MSG]Violation in class org.gradle.plugins.ear.EarPluginConvention. The def keyword is unneeded on constructors

Package: src.org.gradle.plugins.ear.descriptor.internal

➥ DefaultDeploymentDescriptor.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3189

[SRC]if (file.getParentFile() != null) {

[MSG]Violation in class org.gradle.plugins.ear.descriptor.internal.DefaultDeploymentDescriptor. getParentFile() can probably be rewritten as parentFile

UnnecessaryGetter3190

[SRC]file.getParentFile().mkdirs()

[MSG]Violation in class org.gradle.plugins.ear.descriptor.internal.DefaultDeploymentDescriptor. getParentFile() can probably be rewritten as parentFile

➥ DefaultEarWebModule.groovy

Rule NamePriorityLine #Source Line / Message
UnusedObject239

[SRC]new Node(web, nodeNameFor("web-uri", name), path)

[MSG]The instantiated object is not used

UnusedObject240

[SRC]new Node(web, nodeNameFor("context-root", name), contextRoot)

[MSG]The instantiated object is not used

Package: src.org.gradle.plugins.ide.eclipse

➥ EclipseWtpPlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter344

[SRC]EclipsePlugin delegatePlugin = project.getPlugins().appl..ugin.class);

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getPlugins() can probably be rewritten as plugins

UnnecessaryDotClass344

[SRC]EclipsePlugin delegatePlugin = project.getPlugins().appl..ugin.class);

[MSG]EclipsePlugin.class can be rewritten as EclipsePlugin

UnnecessaryGetter350

[SRC]delegatePlugin.getLifecycleTask().dependsOn(getLifecycleTask())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getLifecycleTask() can probably be rewritten as lifecycleTask

UnnecessaryGetter350

[SRC]delegatePlugin.getLifecycleTask().dependsOn(getLifecycleTask())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getLifecycleTask() can probably be rewritten as lifecycleTask

UnnecessaryGetter351

[SRC]delegatePlugin.getCleanTask().dependsOn(getCleanTask())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getCleanTask() can probably be rewritten as cleanTask

UnnecessaryGetter351

[SRC]delegatePlugin.getCleanTask().dependsOn(getCleanTask())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.EclipseWtpPlugin. getCleanTask() can probably be rewritten as cleanTask

UnnecessaryDotClass396

[SRC]if (WarPlugin.class.isAssignableFrom(type)) {

[MSG]WarPlugin.class can be rewritten as WarPlugin

UnnecessaryDotClass3102

[SRC]} else if (EarPlugin.class.isAssignableFrom(type)) {

[MSG]EarPlugin.class can be rewritten as EarPlugin

➥ GenerateEclipseJdt.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]jdt = services.get(Instantiator).newInstance(EclipseJdt,..nsformer()))

[MSG]Violation in class org.gradle.plugins.ide.eclipse.GenerateEclipseJdt. getTransformer() can probably be rewritten as transformer

UnnecessaryGetter341

[SRC]return new Jdt(getTransformer())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.GenerateEclipseJdt. getTransformer() can probably be rewritten as transformer

UnnecessaryGetter345

[SRC]def jdtModel = getJdt()

[MSG]Violation in class org.gradle.plugins.ide.eclipse.GenerateEclipseJdt. getJdt() can probably be rewritten as jdt

Package: src.org.gradle.plugins.ide.eclipse.model

➥ AbstractClasspathEntry.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter361

[SRC]def allAttributes = attributes.findAll { it.value } + [k.. path: path]

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.AbstractClasspathEntry. getKind() can probably be rewritten as kind

➥ AccessRule.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration325

[SRC]def AccessRule(kind, pattern) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.AccessRule. The def keyword is unneeded on constructors

➥ BuildCommand.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration325

[SRC]def BuildCommand(String name, Map arguments = [:]) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.BuildCommand. The def keyword is unneeded on constructors

➥ EclipseWtpComponent.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3144

[SRC]getLibConfigurations()

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.EclipseWtpComponent. getLibConfigurations() can probably be rewritten as libConfigurations

➥ EclipseWtpFacet.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3115

[SRC]xmlFacet.configure(getFacets())

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.EclipseWtpFacet. getFacets() can probably be rewritten as facets

➥ Facet.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration330

[SRC]def Facet() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Facet. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration334

[SRC]def Facet(Node node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Facet. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration338

[SRC]def Facet(String name, String version) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Facet. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration342

[SRC]def Facet(FacetType type, String name, String version) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Facet. The def keyword is unneeded on constructors

➥ Link.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration329

[SRC]def Link(String name, String type, String location, Stri..cationUri) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Link. The def keyword is unneeded on constructors

➥ Output.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration327

[SRC]def Output(Node node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Output. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration331

[SRC]def Output(String path) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Output. The def keyword is unneeded on constructors

UnnecessaryGetter341

[SRC]node.appendNode('classpathentry', [kind: getKind(), path: path])

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Output. getKind() can probably be rewritten as kind

➥ Project.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration359

[SRC]def Project(XmlTransformer xmlTransformer) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration376

[SRC]private def readReferencedProjects() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration382

[SRC]private def readNatures() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration386

[SRC]private def readBuildCommands() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration396

[SRC]private def readLinkedResources() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3132

[SRC]private def addReferencedProjectsToXml() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3139

[SRC]private def addNaturesToXml() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3146

[SRC]private def addBuildSpecToXml() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3160

[SRC]private def addLinkedResourcesToXml() {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.Project. The def keyword is unneeded when a method is marked private

➥ WbDependentModule.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration328

[SRC]def WbDependentModule(node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbDependentModule. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration332

[SRC]def WbDependentModule(String deployPath, String handle) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbDependentModule. The def keyword is unneeded on constructors

➥ WbProperty.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration326

[SRC]def WbProperty(node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbProperty. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration330

[SRC]def WbProperty(String name, String value) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbProperty. The def keyword is unneeded on constructors

➥ WbResource.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration328

[SRC]def WbResource(node) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbResource. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration332

[SRC]def WbResource(String deployPath, String sourcePath) {

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.WbResource. The def keyword is unneeded on constructors

Package: src.org.gradle.plugins.ide.eclipse.model.internal

➥ FileReferenceFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring349

[SRC]path = entry.key + filePath.substring(len)

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring391

[SRC]def file = new File(entry.value, path.substring(prefix.length()))

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryGetter3130

[SRC]", jarUrl='" + getJarURL() + '\'' +

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory$FileReferenceImpl. getJarURL() can probably be rewritten as jarURL

➥ WtpComponentFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryCollectCall3100

[SRC]dependencies.collect { it.resolve() }.flatten() as LinkedHashSet

[MSG]Violation in class org.gradle.plugins.ide.eclipse.model.internal.WtpComponentFactory. The call to collect could probably be rewritten as a spread expression: dependencies*.resolve()

Package: src.org.gradle.plugins.ide.idea

➥ GenerateIdeaModule.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter343

[SRC]getModule().mergeXmlModule(xmlModule)

[MSG]Violation in class org.gradle.plugins.ide.idea.GenerateIdeaModule. getModule() can probably be rewritten as module

➥ GenerateIdeaProject.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]getIdeaProject().mergeXmlProject(xmlModule)

[MSG]Violation in class org.gradle.plugins.ide.idea.GenerateIdeaProject. getIdeaProject() can probably be rewritten as ideaProject

➥ GenerateIdeaWorkspace.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]getWorkspace().mergeXmlWorkspace(xmlWorkspace)

[MSG]Violation in class org.gradle.plugins.ide.idea.GenerateIdeaWorkspace. getWorkspace() can probably be rewritten as workspace

Package: src.org.gradle.plugins.ide.idea.model

➥ IdeaModel.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter360

[SRC]ConfigureUtil.configure(closure, getModule())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModel. getModule() can probably be rewritten as module

UnnecessaryGetter371

[SRC]ConfigureUtil.configure(closure, getProject())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModel. getProject() can probably be rewritten as project

UnnecessaryGetter382

[SRC]ConfigureUtil.configure(closure, getWorkspace())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModel. getWorkspace() can probably be rewritten as workspace

➥ IdeaModule.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3277

[SRC]ConfigureUtil.configure(closure, getIml())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getIml() can probably be rewritten as iml

UnnecessaryGetter3288

[SRC]new File((File) iml.getGenerateTo(), getName() + ".iml")

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getGenerateTo() can probably be rewritten as generateTo

UnnecessaryGetter3288

[SRC]new File((File) iml.getGenerateTo(), getName() + ".iml")

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getName() can probably be rewritten as name

UnnecessaryGetter3302

[SRC]return new IdeaDependenciesProvider().provide(this, getPathFactory())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getPathFactory() can probably be rewritten as pathFactory

UnnecessaryGetter3330

[SRC]def path = { getPathFactory().path(it) }

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getPathFactory() can probably be rewritten as pathFactory

UnnecessaryGetter3331

[SRC]def contentRoot = path(getContentRoot())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getContentRoot() can probably be rewritten as contentRoot

UnnecessaryGetter3332

[SRC]Set sourceFolders = getSourceDirs().findAll { it.exists(..{ path(it) }

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getSourceDirs() can probably be rewritten as sourceDirs

UnnecessaryGetter3333

[SRC]Set testSourceFolders = getTestSourceDirs().findAll { it..{ path(it) }

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getTestSourceDirs() can probably be rewritten as testSourceDirs

UnnecessaryGetter3334

[SRC]Set excludeFolders = getExcludeDirs().collect { path(it) }

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getExcludeDirs() can probably be rewritten as excludeDirs

UnnecessaryGetter3335

[SRC]def outputDir = getOutputDir() ? path(getOutputDir()) : null

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter3335

[SRC]def outputDir = getOutputDir() ? path(getOutputDir()) : null

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getOutputDir() can probably be rewritten as outputDir

UnnecessaryGetter3336

[SRC]def testOutputDir = getTestOutputDir() ? path(getTestOut..ir()) : null

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getTestOutputDir() can probably be rewritten as testOutputDir

UnnecessaryGetter3336

[SRC]def testOutputDir = getTestOutputDir() ? path(getTestOut..ir()) : null

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getTestOutputDir() can probably be rewritten as testOutputDir

UnnecessaryGetter3340

[SRC]getInheritOutputDirs(), outputDir, testOutputDir, depend..etJdkName())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getInheritOutputDirs() can probably be rewritten as inheritOutputDirs

UnnecessaryGetter3340

[SRC]getInheritOutputDirs(), outputDir, testOutputDir, depend..etJdkName())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaModule. getJdkName() can probably be rewritten as jdkName

➥ IdeaProject.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3136

[SRC]getOutputFile().name.replaceFirst(/\.ipr$/, '')

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getOutputFile() can probably be rewritten as outputFile

UnnecessaryGetter3146

[SRC]ConfigureUtil.configure(closure, getIpr())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getIpr() can probably be rewritten as ipr

UnnecessaryGetter3162

[SRC]def modulePaths = getModules().collect {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getModules() can probably be rewritten as modules

UnnecessaryGetter3163

[SRC]getPathFactory().relativePath('PROJECT_DIR', it.outputFile)

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getPathFactory() can probably be rewritten as pathFactory

UnnecessaryGetter3165

[SRC]xmlProject.configure(modulePaths, getJdkName(), getLangu..Wildcards())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getJdkName() can probably be rewritten as jdkName

UnnecessaryGetter3165

[SRC]xmlProject.configure(modulePaths, getJdkName(), getLangu..Wildcards())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getLanguageLevel() can probably be rewritten as languageLevel

UnnecessaryGetter3165

[SRC]xmlProject.configure(modulePaths, getJdkName(), getLangu..Wildcards())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaProject. getWildcards() can probably be rewritten as wildcards

➥ IdeaWorkspace.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter348

[SRC]ConfigureUtil.configure(closure, getIws())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.IdeaWorkspace. getIws() can probably be rewritten as iws

➥ JarDirectory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration334

[SRC]def JarDirectory(path, recursive) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.JarDirectory. The def keyword is unneeded on constructors

➥ Jdk.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration330

[SRC]def Jdk(String jdkName, IdeaLanguageLevel ideaLanguageLevel) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Jdk. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration346

[SRC]def Jdk(assertKeyword, jdk15, languageLevel, projectJdkName) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Jdk. The def keyword is unneeded on constructors

➥ Module.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration3155

[SRC]protected def configure(Path contentPath, Set sourceFold..ludeFolders,

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Module. The def keyword is unneeded when a method is marked protected

➥ ModuleDependency.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration336

[SRC]def ModuleDependency(name, scope) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleDependency. The def keyword is unneeded on constructors

UnnecessaryGetter343

[SRC]parentNode.appendNode('orderEntry', [type: 'module', 'mo..dExported())

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleDependency. getAttributeMapForScopeAndExported() can probably be rewritten as attributeMapForScopeAndExported

UnnecessaryElseStatement368

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter377

[SRC]result = 31 * result + getScopeHash();

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleDependency. getScopeHash() can probably be rewritten as scopeHash

➥ ModuleLibrary.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration351

[SRC]def ModuleLibrary(Collection<Path> classes, Collection<P..ing scope) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleLibrary. The def keyword is unneeded on constructors

UnnecessaryGetter361

[SRC]Node libraryNode = parentNode.appendNode('orderEntry', [..e('library')

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleLibrary. getAttributeMapForScopeAndExported() can probably be rewritten as attributeMapForScopeAndExported

UnnecessaryElseStatement3104

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryGetter3117

[SRC]result = 31 * result + getScopeHash()

[MSG]Violation in class org.gradle.plugins.ide.idea.model.ModuleLibrary. getScopeHash() can probably be rewritten as scopeHash

➥ PathFactory.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring384

[SRC]expandedUrl = toUrl('file', new File(expandedUrl.substri..nonicalFile)

[MSG]Violation in class org.gradle.plugins.ide.idea.model.PathFactory. The String.substring(int) method can be replaced with the subscript operator

UnnecessarySubstring386

[SRC]def parts = expandedUrl.substring(6).split('!')

[MSG]Violation in class org.gradle.plugins.ide.idea.model.PathFactory. The String.substring(int) method can be replaced with the subscript operator

UnnecessaryDefInMethodDeclaration394

[SRC]private def toUrl(String scheme, File file) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.PathFactory. The def keyword is unneeded when a method is marked private

UnnecessaryElseStatement3106

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ Project.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration344

[SRC]def Project(XmlTransformer xmlTransformer, pathFactory) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Project. The def keyword is unneeded on constructors

UnnecessaryDefInMethodDeclaration396

[SRC]private def findProjectRootManager() {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3100

[SRC]private def findWildcardResourcePatterns() {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Project. The def keyword is unneeded when a method is marked private

UnnecessaryDefInMethodDeclaration3104

[SRC]private def findModules() {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Project. The def keyword is unneeded when a method is marked private

➥ SingleEntryModuleLibrary.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryElseStatement363

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

UnnecessaryElseStatement374

[SRC]} else {

[MSG]When an if statement block ends with a return statement the else is unnecessary

➥ Workspace.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInMethodDeclaration328

[SRC]def Workspace(XmlTransformer withXmlActions) {

[MSG]Violation in class org.gradle.plugins.ide.idea.model.Workspace. The def keyword is unneeded on constructors

Package: src.org.gradle.plugins.ide.internal

➥ IdeDependenciesExtractor.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryPackageReference3118

[SRC]def filter = { it instanceof SelfResolvingDependency && ..Dependency)}

[MSG]The org.gradle.api.artifacts.ProjectDependency class was explicitly imported, so specifying the package name is not necessary

UnnecessaryCollectCall3122

[SRC]def files = deps.collect { it.resolve() }.flatten()

[MSG]Violation in class org.gradle.plugins.ide.internal.IdeDependenciesExtractor. The call to collect could probably be rewritten as a spread expression: deps*.resolve()

UnnecessaryCollectCall3127

[SRC]def files = deps.collect { it.resolve() }.flatten()

[MSG]Violation in class org.gradle.plugins.ide.internal.IdeDependenciesExtractor. The call to collect could probably be rewritten as a spread expression: deps*.resolve()

➥ IdePlugin.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter265

[SRC]protected void onApply(Project target) {

[MSG]Violation in class IdePlugin. Method parameter [target] is never referenced in the method onApply of class org.gradle.plugins.ide.internal.IdePlugin

UnnecessaryGetter332

[SRC]String lifecyleTaskName = getLifecycleTaskName();

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getLifecycleTaskName() can probably be rewritten as lifecycleTaskName

UnnecessaryGetter349

[SRC]return project.getTasks().getByName(cleanName(worker.getName()));

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getTasks() can probably be rewritten as tasks

UnnecessaryGetter349

[SRC]return project.getTasks().getByName(cleanName(worker.getName()));

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getName() can probably be rewritten as name

UnnecessaryGetter358

[SRC]Delete cleanWorker = project.getTasks().add(cleanName(wo..elete.class)

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getTasks() can probably be rewritten as tasks

UnnecessaryGetter358

[SRC]Delete cleanWorker = project.getTasks().add(cleanName(wo..elete.class)

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getName() can probably be rewritten as name

UnnecessaryDotClass358

[SRC]Delete cleanWorker = project.getTasks().add(cleanName(wo..elete.class)

[MSG]Delete.class can be rewritten as Delete

UnnecessaryGetter359

[SRC]cleanWorker.delete(worker.getOutputs().getFiles())

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getFiles() can probably be rewritten as files

UnnecessaryGetter359

[SRC]cleanWorker.delete(worker.getOutputs().getFiles())

[MSG]Violation in class org.gradle.plugins.ide.internal.IdePlugin. getOutputs() can probably be rewritten as outputs

Package: src.org.gradle.plugins.ide.internal.configurer

➥ DeduplicationTarget.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInFieldDeclaration326

[SRC]def String moduleName

[MSG]Violation in class org.gradle.plugins.ide.internal.configurer.DeduplicationTarget. The def keyword is unneeded when a field type is specified

UnnecessaryDefInFieldDeclaration327

[SRC]def Project project

[MSG]Violation in class org.gradle.plugins.ide.internal.configurer.DeduplicationTarget. The def keyword is unneeded when a field type is specified

UnnecessaryDefInFieldDeclaration328

[SRC]def Closure updateModuleName

[MSG]Violation in class org.gradle.plugins.ide.internal.configurer.DeduplicationTarget. The def keyword is unneeded when a field type is specified

Package: src.org.gradle.plugins.ide.internal.generator

➥ AbstractPersistableConfigurationObject.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter338

[SRC]String defaultResourceName = getDefaultResourceName();

[MSG]Violation in class org.gradle.plugins.ide.internal.generator.AbstractPersistableConfigurationObject. getDefaultResourceName() can probably be rewritten as defaultResourceName

UnnecessaryGetter341

[SRC]throw new IllegalStateException(String.format("Failed to..getName()));

[MSG]Violation in class org.gradle.plugins.ide.internal.generator.AbstractPersistableConfigurationObject. getName() can probably be rewritten as name

➥ XmlPersistableConfigurationObject.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter251

[SRC]protected void load(Node xml) {

[MSG]Violation in class XmlPersistableConfigurationObject. Method parameter [xml] is never referenced in the method load of class org.gradle.plugins.ide.internal.generator.XmlPersistableConfigurationObject

UnusedMethodParameter258

[SRC]protected void store(Node xml) {

[MSG]Violation in class XmlPersistableConfigurationObject. Method parameter [xml] is never referenced in the method store of class org.gradle.plugins.ide.internal.generator.XmlPersistableConfigurationObject

Package: src.org.gradle.plugins.signing

➥ Sign.groovy

Rule NamePriorityLine #Source Line / Message
UnusedMethodParameter2138

[SRC]void signatureType(SignatureType type) {

[MSG]Violation in class Sign. Method parameter [type] is never referenced in the method signatureType of class org.gradle.plugins.signing.Sign

UnnecessaryGetter365

[SRC]isRequired() || getSignatory() != null

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter369

[SRC]inputs.property("signatory") { getSignatory()?.keyId?.asHex }

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter371

[SRC]inputs.files { getSignatures()*.toSign }

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter372

[SRC]outputs.files { getSignatures()*.toSign }

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter3161

[SRC]if (getSignatory() == null) {

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter3162

[SRC]throw new InvalidUserDataException("Cannot perform signi.. signatory")

[MSG]Violation in class org.gradle.plugins.signing.Sign. getPath() can probably be rewritten as path

UnnecessaryGetter3165

[SRC]getSignatures()*.generate()

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter3182

[SRC]def signatureSet = getSignatures()

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter3196

[SRC]new SimpleFileCollection(*getSignatures()*.toSign.findAl.. != null }))

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

UnnecessaryGetter3203

[SRC]new SimpleFileCollection(*getSignatures()*.file.findAll(.. != null }))

[MSG]Violation in class org.gradle.plugins.signing.Sign. getSignatures() can probably be rewritten as signatures

➥ SignOperation.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter361

[SRC]getDisplayName()

[MSG]Violation in class org.gradle.plugins.signing.SignOperation. getDisplayName() can probably be rewritten as displayName

➥ Signature.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3176

[SRC]name == null ? (toSignArtifact?.name ?: getFile()?.name) : name

[MSG]Violation in class org.gradle.plugins.signing.Signature. getFile() can probably be rewritten as file

UnnecessaryGetter3187

[SRC]extension == null ? getSignatureType()?.extension : extension

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3200

[SRC]def toSign = getToSign()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getToSign() can probably be rewritten as toSign

UnnecessaryGetter3201

[SRC]def signatureType = getSignatureType()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3234

[SRC]def file = getFile()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getFile() can probably be rewritten as file

UnnecessaryGetter3260

[SRC]def toSign = getToSign()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getToSign() can probably be rewritten as toSign

UnnecessaryGetter3261

[SRC]def signatureType = getSignatureType()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3279

[SRC]signatureSpec.getSignatory()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter3288

[SRC]signatureSpec.getSignatureType()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3300

[SRC]def toSign = getToSign()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getToSign() can probably be rewritten as toSign

UnnecessaryGetter3309

[SRC]def signatory = getSignatory()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter3318

[SRC]def signatureType = getSignatureType()

[MSG]Violation in class org.gradle.plugins.signing.Signature. getSignatureType() can probably be rewritten as signatureType

➥ SigningExtension.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter3118

[SRC]this.configuration = getDefaultConfiguration()

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getDefaultConfiguration() can probably be rewritten as defaultConfiguration

UnnecessaryGetter3198

[SRC]spec.conventionMapping.map('signatory') { getSignatory() }

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getSignatory() can probably be rewritten as signatory

UnnecessaryGetter3199

[SRC]spec.conventionMapping.map('signatureType') { getSignatureType() }

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getSignatureType() can probably be rewritten as signatureType

UnnecessaryGetter3222

[SRC]addSignaturesToConfiguration(signTask, getConfiguration())

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getConfiguration() can probably be rewritten as configuration

UnnecessaryGetter3243

[SRC]this.addSignaturesToConfiguration(signTask, getConfiguration())

[MSG]Violation in class org.gradle.plugins.signing.SigningExtension. getConfiguration() can probably be rewritten as configuration

Package: src.org.gradle.plugins.signing.signatory.pgp

➥ PgpKeyId.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessarySubstring363

[SRC]normalised = keyIdUpped.substring(2)

[MSG]Violation in class org.gradle.plugins.signing.signatory.pgp.PgpKeyId. The String.substring(int) method can be replaced with the subscript operator

Package: src.org.gradle.plugins.signing.type

➥ AbstractSignatureType.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryGetter337

[SRC]new File(toSign.path + ".${getExtension()}")

[MSG]Violation in class org.gradle.plugins.signing.type.AbstractSignatureType. getExtension() can probably be rewritten as extension

UnnecessaryGetter344

[SRC]getExtension()

[MSG]Violation in class org.gradle.plugins.signing.type.AbstractSignatureType. getExtension() can probably be rewritten as extension

UnnecessaryGetter346

[SRC]name[++dotIndex..-1] + ".${getExtension()}"

[MSG]Violation in class org.gradle.plugins.signing.type.AbstractSignatureType. getExtension() can probably be rewritten as extension

Package: src.org.gradle.profile

➥ HTMLProfileReport.groovy

Rule NamePriorityLine #Source Line / Message
StaticSimpleDateFormatField225

[SRC]private static final SimpleDateFormat DATE_FORMAT = new .. HH:mm:ss");

[MSG]Violation in class org.gradle.profile.HTMLProfileReport. SimpleDateFormat instances are not thread safe. Wrap the SimpleDateFormat field DATE_FORMAT in a ThreadLocal or make it an instance field

Package: src.org.gradle.util

➥ ReflectionUtil.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass349

[SRC]return Boolean.class;

[MSG]Boolean.class can be rewritten as Boolean

UnnecessaryDotClass351

[SRC]return Long.class;

[MSG]Long.class can be rewritten as Long

UnnecessaryDotClass353

[SRC]return Integer.class;

[MSG]Integer.class can be rewritten as Integer

UnnecessaryDotClass355

[SRC]return Short.class;

[MSG]Short.class can be rewritten as Short

UnnecessaryDotClass357

[SRC]return Byte.class;

[MSG]Byte.class can be rewritten as Byte

UnnecessaryDotClass359

[SRC]return Float.class;

[MSG]Float.class can be rewritten as Float

UnnecessaryDotClass361

[SRC]return Double.class;

[MSG]Double.class can be rewritten as Double

➥ Requires.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDotClass327

[SRC]@ExtensionAnnotation(TestPreconditionExtension.class)

[MSG]TestPreconditionExtension.class can be rewritten as TestPreconditionExtension

➥ TestDirHelper.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryDefInFieldDeclaration319

[SRC]def TestFile baseDir

[MSG]Violation in class org.gradle.util.TestDirHelper. The def keyword is unneeded when a field type is specified

UnnecessaryDefInMethodDeclaration321

[SRC]def TestDirHelper(TestFile baseDir) {

[MSG]Violation in class org.gradle.util.TestDirHelper. The def keyword is unneeded on constructors

➥ TestFileHelper.groovy

Rule NamePriorityLine #Source Line / Message
AssignmentInConditional240

[SRC]while (entry = zipStr.getNextEntry()) {

[MSG]Assignment used as conditional value, which always results in true. Use the == operator instead

MisorderedStaticImports322

[SRC]import static org.hamcrest.Matchers.equalTo

[MSG]Static imports should appear before normal imports

MisorderedStaticImports323

[SRC]import static org.junit.Assert.assertThat

[MSG]Static imports should appear before normal imports

MisorderedStaticImports324

[SRC]import static org.junit.Assert.assertTrue

[MSG]Static imports should appear before normal imports

UnnecessaryGetter340

[SRC]while (entry = zipStr.getNextEntry()) {

[MSG]Violation in class org.gradle.util.TestFileHelper. getNextEntry() can probably be rewritten as nextEntry

UnnecessarySubstring3110

[SRC]return perms.substring(1, 10)

[MSG]Violation in class org.gradle.util.TestFileHelper. The String.substring(int, int) method can be replaced with the subscript operator

➥ TestPreconditionExtension.groovy

Rule NamePriorityLine #Source Line / Message
UnnecessaryParenthesesForMethodCallWithClosure325

[SRC]spec.skipped = annotation.value().any() { !it.fulfilled }

[MSG]Violation in class org.gradle.util.TestPreconditionExtension. Parentheses in the 'any' method call are unnecessary and can be removed.

UnnecessaryParenthesesForMethodCallWithClosure330

[SRC]feature.skipped = annotation.value().any() { !it.fulfilled }

[MSG]Violation in class org.gradle.util.TestPreconditionExtension. Parentheses in the 'any' method call are unnecessary and can be removed.

Rule Descriptions

#Rule NameDescription
1AddEmptyStringFinds empty string literals which are being added. This is an inefficient way to convert any type to a String.
2AssertWithinFinallyBlockChecks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one.
3AssignmentInConditionalAn assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended.
4BigDecimalInstantiationChecks for calls to the BigDecimal constructors that take a double parameter, which may result in an unexpected BigDecimal value.
5BitwiseOperatorInConditionalChecks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable.
6BooleanGetBooleanThis rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop'].
7BrokenNullCheckLooks for faulty checks for null that can cause a NullPointerException.
8BrokenOddnessCheckThe code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.
9BusyWaitBusy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package.
10ChainedTestA test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another.
11ClassForNameUsing Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time.
12ComparisonOfTwoConstantsChecks for expressions where a comparison operator or equals() or compareTo() is used to compare two constants to each other or two literals that contain only constant values., e.g.: 23 == 67, Boolean.FALSE != false, 0.17 <= 0.99, "abc" > "ddd", [a:1] <=> [a:2], [1,2].equals([3,4]) or [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE].
13ComparisonWithSelfChecks for expressions where a comparison operator or equals() or compareTo() is used to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x =>= x, x.equals(x) or x.compareTo(x), where x is a variable.
14ConsecutiveLiteralAppendsViolations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation.
15ConsecutiveStringConcatenationCatches concatenation of two string literals on the same line. These can safely by joined.
16ConstantAssertExpressionChecks for assert statements where the assert boolean condition expression is a constant or literal value.
17ConstantIfExpressionChecks for if statements with a constant value for the if expression, such as true, false, null, or a literal constant value.
18ConstantTernaryExpressionChecks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value.
19CoupledTestCaseThis rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused.
20CyclomaticComplexityChecks the cyclomatic complexity for methods/classes.A method (or "closure field") with a cyclomatic complexity value greater than the maxMethodComplexity property (20) causes a violation. Likewise, a class that has an (average method) cyclomatic complexityvalue greater than the maxClassAverageMethodComplexity property (20) causes a violation.
21DeadCodeDead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted.
22DoubleCheckedLockingThis rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern.
23DoubleNegativeThere is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well.
24DuplicateCaseStatementCheck for duplicate case statements in a switch block, such as two equal integers or strings.
25DuplicateImportDuplicate import statements are unnecessary.
26DuplicateMapKeyA map literal is created with duplicated key. The map entry will be overwritten.
27DuplicateSetValueA Set literal is created with duplicate constant value. A set cannot contain two elements with the same value.
28EmptyCatchBlockIn most cases, exceptions should not be caught and ignored (swallowed).
29EmptyElseBlockEmpty else blocks are confusing and serve no purpose.
30EmptyFinallyBlockEmpty finally blocks are confusing and serve no purpose.
31EmptyForStatementEmpty for statements are confusing and serve no purpose.
32EmptyIfStatementEmpty if statements are confusing and serve no purpose.
33EmptyInstanceInitializerAn empty class instance initializer was found. It is safe to remove it.
34EmptyMethodA method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation.
35EmptyStaticInitializerAn empty static initializer was found. It is safe to remove it.
36EmptySwitchStatementEmpty switch statements are confusing and serve no purpose.
37EmptySynchronizedStatementEmpty synchronized statements are confusing and serve no purpose.
38EmptyTryBlockEmpty try blocks are confusing and serve no purpose.
39EmptyWhileStatementEmpty while statements are confusing and serve no purpose.
40EqualsAndHashCodeIf either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden.
41EqualsOverloadedThe class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it.
42ExplicitGarbageCollectionCalls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself.
43ForLoopShouldBeWhileLoopA for loop without an init and update statement can be simplified to a while loop.
44HardCodedWindowsFileSeparatorThis rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant.
45HardCodedWindowsRootDirectoryThis rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative.
46ImportFromSamePackageAn import of a class that is within the same package is unnecessary.
47ImportFromSunPackagesAvoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.
48InconsistentPropertyLockingClass contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all.
49InconsistentPropertySynchronizationClass contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not.
50IntegerGetIntegerThis rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop'].
51JUnitAssertAlwaysFailsChecks for JUnit assert() method calls with constant arguments such that the assertion always fails. This includes: assertTrue(false), assertFalse(true) and assertNull(CONSTANT).
52JUnitAssertAlwaysSucceedsChecks for JUnit assert() method calls with constant arguments such that the assertion always succeeds. This includes: assertTrue(true), assertFalse(false) and assertNull(null).
53JUnitFailWithoutMessageThis rule detects JUnit calling the fail() method without an argument. For better error reporting you should always provide a message.
54JUnitPublicNonTestMethodChecks if a JUnit test class contains public methods other than standard test methods, JUnit framework methods or methods with JUnit annotations.
55JUnitSetUpCallsSuperChecks that if the JUnit setUp() method is defined, that it includes a call to super.setUp().
56JUnitTearDownCallsSuperChecks that if the JUnit tearDown() method is defined, that it includes a call to super.tearDown().
57JUnitTestMethodWithoutAssertThis rule searches for test methods that do not contain assert statements. Either the test method is missing assert statements, which is an error, or the test method contains custom assert statements that do not follow a proper assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test annotation. By default this rule applies to the default test class names, but this can be changed using the rule's applyToClassNames property.
58JUnitUnnecessarySetUpChecks for JUnit setUp() methods that contain only a call to super.setUp().
59JUnitUnnecessaryTearDownChecks for JUnit tearDown() methods that contain only a call to super.tearDown().
60MisorderedStaticImportsStatic imports should never be declared after nonstatic imports.
61NestedSynchronizationNested synchronized statements should be avoided. Nested synchronized statements are either useless (if the lock objects are identical) or prone to deadlock.
62RandomDoubleCoercedToZeroThe Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug.
63RemoveAllOnSelfDon't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException.
64ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
65SpockIgnoreRestUsedIf Spock's @IgnoreRest appears on any method, all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed.
66StaticCalendarFieldCalendar objects should not be used as static fields. Calendars are inherently unsafe for multihtreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
67StaticConnectionCreates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions.
68StaticDateFormatFieldDateFormat objects should not be used as static fields. DateFormat are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
69StaticMatcherFieldMatcher objects should not be used as static fields. Matcher instances are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
70StaticSimpleDateFormatFieldSimpleDateFormat objects should not be used as static fields. SimpleDateFormat are inherently unsafe for multi-threaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application.
71SynchronizedMethodThis rule reports uses of the synchronized keyword on methods. Synchronized methods are the same as synchronizing on 'this', which effectively make your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.
72SynchronizedOnBoxedPrimitiveThe code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock
73SynchronizedOnGetClassSynchronization on getClass rather than class literal. This instance method synchronizes on this.getClass(). If this class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended.
74SynchronizedOnReentrantLockSynchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method.
75SynchronizedOnStringSynchronization on a String field can lead to deadlock because Strings are interned by the JVM and can be shared.
76SynchronizedOnThisThis rule reports uses of the synchronized blocks where the synchronization reference is 'this'. Doing this effectively makes your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects.
77SynchronizedReadObjectMethodCatches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style.
78SystemRunFinalizersOnExitMethod calls to System.runFinalizersOnExit() should not be allowed. This method is inherently non-thread-safe, may result in data corruption, deadlock, and may effect parts of the program far removed from it's call point. It is deprecated, and it's use strongly discouraged.
79ThreadGroupAvoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe.
80ThreadLocalNotStaticFinalThreadLocal fields should be static and final. In the most common case a java.lang.ThreadLocal instance associates state with a thread. A non-static non-final java.lang.ThreadLocal field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior.
81ThreadYieldMethod calls to Thread.yield() should not be allowed. This method has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions.
82ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
83UnnecessaryBigDecimalInstantiationIt is unnecessary to instantiate BigDecimal objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as 123.45 or 123.45G.
84UnnecessaryBigIntegerInstantiationIt is unnecessary to instantiate BigInteger objects. Instead just use the literal with the 'G' identifier to force the type, such as 8G or 42G.
85UnnecessaryBooleanExpressionChecks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or a Map/List/String/Number literal. Also checks for negation (!) of true, false, null, or a Map/List/String/Number literal.
86UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
87UnnecessaryCallForLastElementThis rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing array[array.length - 1], in Groovy it is simpler to either call array.last() or array[-1]. The same is true for lists. This violation is triggered whenever a get, getAt, or array-style access is used with an object size check.
88UnnecessaryCallToSubstringCalling String.substring(0) always returns the original string. This code is meaningless.
89UnnecessaryCatchBlockViolations are triggered when a catch block does nothing but throw the original exception. In this scenario there is usually no need for a catch block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the catch statement out.
90UnnecessaryCollectCallSome method calls to Object.collect(Closure) can be replaced with the spread operator. For instance, list.collect { it.multiply(2) } can be replaced by list*.multiply(2).
91UnnecessaryCollectionCallUseless call to collections. This call doesn't make sense. For any collection c, calling c.containsAll(c) should always be true, and c.retainAll(c) should have no effect.
92UnnecessaryConstructorThis rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments.
93UnnecessaryDefInFieldDeclarationIf a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}.
94UnnecessaryDefInMethodDeclarationIf a method has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'.
95UnnecessaryDefInVariableDeclarationIf a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'.
96UnnecessaryDotClassTo make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String.
97UnnecessaryDoubleInstantiationIt is unnecessary to instantiate Double objects. Instead just use the double literal or the 'D' identifier to force the type, such as 123.45d or 0.42d.
98UnnecessaryElseStatementWhen an if statement block ends with a return statement the else is unnecessary. The logic in the else branch can be run without being in a new scope.
99UnnecessaryFailIn a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all.
100UnnecessaryFinalOnPrivateMethodA private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary.
101UnnecessaryFloatInstantiationIt is unnecessary to instantiate Float objects. Instead just use the float literal with the 'F' identifier to force the type, such as 123.45F or 0.42f.
102UnnecessaryGetterChecks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches get[A-Z] but not getClass() or get[A-Z][A-Z] such as getURL(). Getters do not take method arguments.
103UnnecessaryGroovyImportA Groovy file does not need to include an import for classes from java.lang, java.util, java.io, java.net, groovy.lang and groovy.util, as well as the classes java.math.BigDecimal and java.math.BigInteger.
104UnnecessaryIfStatementChecks for if statements where the if and else blocks are merely returning true and false constants. These cases can be replaced by a simple return statement.
105UnnecessaryInstanceOfCheckThis rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean.
106UnnecessaryInstantiationToGetClassAvoid instantiating an object just to call getClass() on it; use the .class public member instead.
107UnnecessaryIntegerInstantiationIt is unnecessary to instantiate Integer objects. Instead just use the literal with the 'I' identifier to force the type, such as 8I or 42i.
108UnnecessaryLongInstantiationIt is unnecessary to instantiate Long objects. Instead just use the literal with the 'L' identifier to force the type, such as 8L or 42L.
109UnnecessaryModOneAny expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2).
110UnnecessaryNullCheckGroovy contains the safe dereference operator, which can be used in boolean conditional statements to safely replace explicit "x == null" tests.
111UnnecessaryNullCheckBeforeInstanceOfThere is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.
112UnnecessaryObjectReferencesViolations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a with or identity block.
113UnnecessaryOverridingMethodThe overriding method merely calls the same method defined in a superclass
114UnnecessaryPackageReferenceChecks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, java.util.Map and groovy.lang.Closure.
115UnnecessaryParenthesesForMethodCallWithClosureIf a method is called and the only parameter to that method is an inline closure then the parentheses of the method call can be omitted.
116UnnecessarySelfAssignmentMethod contains a pointless self-assignment to a variable or property.
117UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
118UnnecessarySubstringThis rule finds usages of String.substring(int) and String.substring(int, int) that can be replaced by use of the subscript operator. For instance, var.substring(5) can be replaced with var[5..-1].
119UnnecessaryTernaryExpressionChecks for ternary expressions where the conditional expression always evaluates to a boolean and the true and false expressions are merely returning true and false constants. Also checks for ternary expressions where both expressions are the same constant or variable.
120UnnecessaryTransientModifierThe field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect.
121UnusedArrayChecks for array allocations that are not assigned or used, unless it is the last statement within a block.
122UnusedImportImports for a class that is never referenced within the source file is unnecessary.
123UnusedMethodParameterThis rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override.
124UnusedObjectChecks for object allocations that are not assigned or used, unless it is the last statement within a block
125UnusedPrivateFieldChecks for private fields that are not referenced within the same class.
126UnusedPrivateMethodChecks for private methods that are not referenced within the same class.
127UnusedPrivateMethodParameterChecks for parameters to private methods that are not referenced within the method body.
128UnusedVariableChecks for variables that are never referenced.
129UseAssertEqualsInsteadOfAssertTrueThis rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.
130UseAssertFalseInsteadOfNegationIn unit tests, if a condition is expected to be false then there is no sense using assertTrue with the negation operator. For instance, assertTrue(!condition) can always be simplified to assertFalse(condition)
131UseAssertNullInsteadOfAssertEqualsThis rule detects JUnit calling assertEquals where the first or second parameter is null. These assertion should be made against the assertNull method instead.
132UseAssertSameInsteadOfAssertTrueThis rule detects JUnit calling assertTrue where the first or second parameter is an Object#is() call testing for reference equality. These assertion should be made against the assertSame method instead.
133UseAssertTrueInsteadOfAssertEqualsThis rule detects JUnit calling assertEquals where the first parameter is a boolean. These assertions should be made by more specific methods, like assertTrue or assertFalse.
134UseAssertTrueInsteadOfNegationIn unit tests, if a condition is expected to be true then there is no sense using assertFalse with the negation operator. For instance, assertFalse(!condition) can always be simplified to assertTrue(condition)
135UseOfNotifyMethodThis code calls notify() rather than notifyAll(). Java monitors are often used for multiple conditions. Calling notify() only wakes up one thread, meaning that the thread woken up might not be the one waiting for the condition that the caller just satisfied.
136VolatileArrayFieldVolatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not.
137VolatileLongOrDoubleFieldLong or double fields should not be declared as volatile. Java specifies that reads and writes from such fields are atomic, but many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronize access to such fields rather than declare them volatile. This rule flags fields marked volatile when their type is double or long or the name of their type is "Double" or "Long".
138WaitOutsideOfWhileLoopCalls to Object.wait() must be within a while loop. Consider using the Java concurrency utilities instead of wait() and notify().
CodeNarc-0.23/src/site/resources/SampleCodeNarcXmlReport.xml0000644000175000017500000003247412470770660023453 0ustar ebourgebourg src\test\groovy\org\codenarc\utilCodeNarc-0.23/src/site/resources/SampleCodeNarcTextReport.txt0000644000175000017500000000347412470770660023654 0ustar ebourgebourgCodeNarc Report: Sample Project - Feb 17, 2015 8:58:08 PM Summary: TotalFiles=10 FilesWithViolations=6 P1=0 P2=0 P3=8 File: ModifiersUtilTest.groovy Violation: Rule=MisorderedStaticImports P=3 Line=20 Msg=[Static imports should appear before normal imports] Src=[import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining] File: PropertyUtilTest.groovy Violation: Rule=MisorderedStaticImports P=3 Line=22 Msg=[Static imports should appear before normal imports] Src=[import static org.codenarc.test.TestUtil.shouldFail] File: SourceCodeUtilTest.groovy Violation: Rule=MisorderedStaticImports P=3 Line=27 Msg=[Static imports should appear before normal imports] Src=[import static org.codenarc.test.TestUtil.shouldFail] File: io/ClassPathResourceTest.groovy Violation: Rule=MisorderedStaticImports P=3 Line=21 Msg=[Static imports should appear before normal imports] Src=[import static org.codenarc.test.TestUtil.shouldFail] Violation: Rule=MisorderedStaticImports P=3 Line=22 Msg=[Static imports should appear before normal imports] Src=[import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining] File: io/DefaultResourceFactoryTest.groovy Violation: Rule=MisorderedStaticImports P=3 Line=22 Msg=[Static imports should appear before normal imports] Src=[import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining] File: io/UrlResourceTest.groovy Violation: Rule=MisorderedStaticImports P=3 Line=21 Msg=[Static imports should appear before normal imports] Src=[import static org.codenarc.test.TestUtil.shouldFail] Violation: Rule=MisorderedStaticImports P=3 Line=22 Msg=[Static imports should appear before normal imports] Src=[import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining] [CodeNarc (http://www.codenarc.org) v0.23] CodeNarc-0.23/src/site/resources/css/0000755000175000017500000000000012623571301017001 5ustar ebourgebourgCodeNarc-0.23/src/site/resources/css/site.css0000644000175000017500000000006712006632016020456 0ustar ebourgebourgtt { font-size: 110%; font-weight: bolder; }CodeNarc-0.23/src/site/xdoc/0000755000175000017500000000000012623571301015134 5ustar ebourgebourgCodeNarc-0.23/src/site/xdoc/index.xml0000644000175000017500000001207412470001356016767 0ustar ebourgebourg <author email="Codenarc-developer@lists.sourceforge.net">CodeNarc Development Team</author> </properties> <!-- Optional HEAD element, which is copied as is into the XHTML <head> element --> <head> <style media="screen" type="text/css"> table.bodyTable tr.a { background-color:#ffffff; } table.bodyTable tr.b { background-color:#ffffff; } table.bodyTable img { padding-right:8px; float:left; } </style> </head> <body> <div style="color:#990000;font-size:x-large;font-weight:900"> Static Analysis for Groovy: Less Bugs, Better Code </div> <p> <strong>CodeNarc</strong> analyzes Groovy code for defects, bad practices, inconsistencies, style issues and more. A flexible framework for rules, rulesets and custom rules means it's easy to configure CodeNarc to fit into your project. Build tool, framework support, and report generation are all enterprise ready. </p> <table> <tr> <td width="50%"> <a href="http://meetcodenarc.appspot.com/"><img src="images/tryit.png" class="bigimage"/></a> <a href="http://meetcodenarc.appspot.com/">CodeNarc Web Console</a> let's you play with the latest snapshot, containing over 175 rules with more added each week. Enter some text, click execute, and see the violations. Or run some <a href="http://meetcodenarc.appspot.com/">scripts</a> <a href="http://meetcodenarc.appspot.com/edit/2001">we</a> <a href="http://meetcodenarc.appspot.com/edit/1">made</a>. </td> <td> <a href="http://sourceforge.net/projects/codenarc/files//"><img src="images/getit.png" class="bigimage" /></a> CodeNarc triggers violations based on rules. Click the links to the left to view all the rules, such as the <a href="codenarc-rules-basic.html">basic</a>, or <a href="codenarc-rules-concurrency.html">concurrency</a> rules. Or you can <a href="codenarc-creating-ruleset.html">create your own ruleset</a>; see how easy it is in this <a href="http://www.youtube.com/watch?v=ZPu8FaZZwRw">screencast</a>. </td> </tr> <tr> <td> <section name="Running CodeNarc"> Run CodeNarc with the <a href="codenarc-ant-task.html">Ant Task</a>, the <a href="codenarc-command-line.html">command-line runner</a>, or <a href="codenarc-run-as-a-test.html">as part of your test suite</a>. Also, plugins exist for <a href="codenarc-other-tools-frameworks.html">Maven</a>, <a href="codenarc-other-tools-frameworks.html">Gradle</a>, <a href="codenarc-other-tools-frameworks.html">Grails</a>, <a href="codenarc-other-tools-frameworks.html">Griffon</a>, <a href="codenarc-other-tools-frameworks.html">Sonar</a> and <a href="codenarc-other-tools-frameworks.html">Hudson</a>. See our <a href="codenarc-other-tools-frameworks.html">Integration</a> page for more details. Reports come in HTML, XML, or text format. Take a look at a <a href="SampleCodeNarcHtmlReport.html">Sample CodeNarc HTML Report</a>, or a <a href="./SampleCodeNarcXmlReport.xml">Sample CodeNarc XML Report</a>. </section> </td> <td> <section name="Requirements"> <strong>CodeNarc</strong> requires: <ul> <li> <a href="http://groovy.codehaus.org/">Groovy</a> version 2.1</li> <li>Java 1.6 or later</li> <li><a href="http://logging.apache.org/log4j/index.html">Log4J</a> 1.2.13 or later on the classpath</li> </ul> </section> </td> </tr> <tr> <td> <section name="Get it from Maven2"> For projects built using <a href="http://maven.apache.org/">Maven</a>, <strong>CodeNarc</strong> is available from the <a href="http://repo1.maven.org/maven2/org/codenarc/CodeNarc/">Maven Central Repository</a> <ul> <li>groupId = org.codenarc</li> <li>artifactId = CodeNarc</li> </ul> </section> </td> <td> <section name="Inspirations"> We're inspired by the wonderful <a href="http://pmd.sourceforge.net/">PMD</a> and <a href="http://checkstyle.sourceforge.net/">Checkstyle</a> Java static analysis tools, as well as the extensive Groovy inspections performed by <a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a>. </section> </td> </tr> </table> </body> </document> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/site.xml���������������������������������������������������������������������0000644�0001750�0001750�00000011464�12405400606�015670� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<project name="CodeNarc"> <bannerLeft> <name>CodeNarc</name> <src>images/codenarc-logo.png</src> <href>/</href> </bannerLeft> <bannerRight> <name>Fork me on GitHub</name> <src>images/forkme_right_red_aa0000.png</src> <href>http://github.com/CodeNarc</href> </bannerRight> <publishDate format="dd MMM yyyy"/> <poweredBy> <logo name="Hosted on SourceForge.net" href="http://sourceforge.net" img="http://sflogo.sourceforge.net/sflogo.php?group_id=208647&type=2"/> <logo name="Build with Maven 2" href="http://maven.apache.org" img="images/logos/maven-feather.png"/> </poweredBy> <body> <links> </links> <head> <!-- <meta name="faq" content="codenarc"/> --> </head> <menu name="General"> <item name="Home" href="/index.html"/> <item name="Downloads" href="https://sourceforge.net/project/showfiles.php?group_id=250145"/> <item name="Javadocs" href="/apidocs/index.html"/> <item name="Mailing Lists" href="http://sourceforge.net/mail/?group_id=250145"/> <item name="Bug Tracker" href="http://sourceforge.net/tracker/?group_id=250145"/> <item name="SourceForge Project" href="http://sourceforge.net/projects/codenarc"/> <item name="GitHub Project" href="http://github.com/CodeNarc"/> </menu> <menu name="Running"> <item name="Ant Task Usage" href="/codenarc-ant-task.html"/> <item name="Command-Line" href="/codenarc-command-line.html"/> <item name="Run as a Test" href="/codenarc-run-as-a-test.html"/> <item name="Other Tools/Frameworks" href="/codenarc-other-tools-frameworks.html"/> </menu> <menu name="Using"> <item name="Creating a RuleSet" href="/codenarc-creating-ruleset.html"/> <item name="Creating a Rule" href="/codenarc-creating-rule.html"/> <item name="Configuring Rules" href="/codenarc-configuring-rules.html"/> <item name="Starter RuleSet (All)" href="/StarterRuleSet-AllRulesByCategory.groovy.txt"/> </menu> <menu name="Report Types"> <item name="HTML Report" href="/codenarc-HtmlReportWriter.html"/> <item name="XML Report" href="/codenarc-XmlReportWriter.html"/> <item name="Text and IDE Reports" href="/codenarc-TextReportWriter.html"/> </menu> <menu name="Sample Reports"> <item name="Sample HTML Report" href="/SampleCodeNarcHtmlReport.html"/> <item name="Sample XML Report" href="/SampleCodeNarcXmlReport.xml"/> </menu> <menu name="Rules"> <item name="Rule Index" href="/codenarc-rule-index.html"/> <item name="Basic Rules" href="/codenarc-rules-basic.html"/> <item name="Braces Rules" href="/codenarc-rules-braces.html"/> <item name="Concurrency Rules" href="/codenarc-rules-concurrency.html"/> <item name="Convention Rules" href="/codenarc-rules-convention.html"/> <item name="Design Rules" href="/codenarc-rules-design.html"/> <item name="DRY Rules" href="/codenarc-rules-dry.html"/> <item name="Enhanced Rules" href="/codenarc-rules-enhanced.html"/> <item name="Exceptions Rules" href="/codenarc-rules-exceptions.html"/> <item name="Formatting Rules" href="/codenarc-rules-formatting.html"/> <item name="Generic Rules" href="/codenarc-rules-generic.html"/> <item name="Grails Rules" href="/codenarc-rules-grails.html"/> <item name="Groovyism Rules" href="/codenarc-rules-groovyism.html"/> <item name="Imports Rules" href="/codenarc-rules-imports.html"/> <item name="JDBC Rules" href="/codenarc-rules-jdbc.html"/> <item name="JUnit Rules" href="/codenarc-rules-junit.html"/> <item name="Logging Rules" href="/codenarc-rules-logging.html"/> <item name="Naming Rules" href="/codenarc-rules-naming.html"/> <item name="Size/Complexity Rules" href="/codenarc-rules-size.html"/> <item name="Security Rules" href="/codenarc-rules-security.html"/> <item name="Serialization Rules" href="/codenarc-rules-serialization.html"/> <item name="Unnecessary Rules" href="/codenarc-rules-unnecessary.html"/> <item name="Unused Rules" href="/codenarc-rules-unused.html"/> </menu> <menu name="Developing"> <item name="Developer Guide" href="/codenarc-developer-guide.html"/> </menu> ${reports} </body> </project>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�014763� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-security.apt����������������������������������������������0000644�0001750�0001750�00000021536�12414257560�022261� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Security Rules -------------------------------------------------- Security Rules ("<rulesets/security.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Also see {{{./codenarc-rules-grails.html#GrailsMassAssignment}GrailsMassAssignment}}. * {FileCreateTempFile} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> The File.createTempFile() method is insecure, and has been deprecated by the ESAPI secure coding library. It has been replaced by the ESAPI Randomizer.getRandomFilename(String) method. For more information see the ESAPI website: http://code.google.com/p/owasp-esapi-java/ and the Randomizer Javadoc: {{http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/Randomizer.html}} * {InsecureRandom} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Reports usages of <<<java.util.Random>>>, which can produce very predictable results. If two instances of Random are created with the same seed and sequence of method calls, they will generate the exact same results. Use <<<java.security.SecureRandom>>> instead, which provides a cryptographically strong random number generator. SecureRandom uses PRNG, which means they are using a deterministic algorithm to produce a pseudo-random number from a true random seed. SecureRandom produces non-deterministic output. By default, this rule ignores test classes are ignored. For more information see: {{http://www.klocwork.com/products/documentation/current/Checkers:SV.RANDOM}} Example of violations: ------------------------------------------------------------------------------- def r1 = new Random() def r2 = new java.util.Random() Math.random() java.lang.Math.random() // this is OK new java.security.SecureRandom() new SecureRandom() ------------------------------------------------------------------------------- * {JavaIoPackageAccess} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> This rule reports violations of the Enterprise JavaBeans specification by using the java.io package to access files or the file system. The Enterprise JavaBeans specification requires that every bean provider follow a set of programming guidelines designed to ensure that the bean will be portable and behave consistently in any EJB container [1]. In this case, the program violates the following EJB guideline: "An enterprise bean must not use the java.io package to attempt to access files and directories in the file system." A requirement that the specification justifies in the following way: "The file system APIs are not well-suited for business components to access data. Business components should use a resource manager API, such as JDBC, to store data." REFERENCES [[1]] Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 576 [[2]] The Enterprise JavaBeans 2.1 Specification Sun Microsystems [] By default, this rule is not applied to tests and test cases. Example of violations: ------------------------------------------------------------------------------- FileSystem.getFileSystem() // any method on FileSystem FileSystem.fileSystem.delete(aFile) // property access of FileSystem // shouldn't create files new File(name) new File(name, parent) // don't create file readers new FileReader(name) // don't create file output streams new FileOutputStream(name) new FileOutputStream(name, true) // don't create random access file new RandomAccessFile(name, parent) ------------------------------------------------------------------------------- * {NonFinalPublicField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Finds code that violates secure coding principles for mobile code by declaring a member variable public but not final. All public member variables in an Applet and in classes used by an Applet should be declared final to prevent an attacker from manipulating or gaining unauthorized access to the internal state of the Applet. References: * Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 493 * G. McGraw Securing Java. Chapter 7: Java Security Guidelines * {NonFinalSubclassOfSensitiveInterface} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> The permissions classes such as <<<java.security.Permission>>> and <<<java.security.BasicPermission>>> are designed to be extended. Classes that derive from these permissions classes, however, must prohibit extension. This prohibition ensures that malicious subclasses cannot change the properties of the derived class. Classes that implement sensitive interfaces such as <<<java.security.PrivilegedAction>>> and <<<java.security.PrivilegedActionException>>> must also be declared <<<final>>> for analogous reasons. For more information see: {{https://www.securecoding.cert.org/confluence/display/java/SEC07-J.+Classes+that+derive+from+a+sensitive+class+or+implement+a+sensitive+interface+must+be+declared+final}} Example of violations: ------------------------------------------------------------------------------- class MyPermission extends java.security.Permission { MyPermission(String name) { super(name) } boolean implies(Permission permission) { true } boolean equals(Object obj) { true } int hashCode() { 0 } String getActions() { "action" } } class MyBasicPermission extends BasicPermission { MyBasicPermission(String name) { super(name) } } class MyPrivilegedAction implements PrivilegedAction { Object run() { 0 } } class MyPrivilegedActionException extends PrivilegedActionException { MyPrivilegedActionException(Exception exception) { super(exception) } } ------------------------------------------------------------------------------- * {PublicFinalizeMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Creates a violation when the program violates secure coding principles by declaring a <<<finalize()>>> method public. A program should never call finalize explicitly, except to call super.finalize() inside an implementation of <<<finalize()>>>. In mobile code situations, the otherwise error prone practice of manual garbage collection can become a security threat if an attacker can maliciously invoke one of your finalize() methods because it is declared with public access. If you are using <<<finalize()>>> as it was designed, there is no reason to declare <<<finalize()>>> with anything other than protected access. References: * Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 583 * G. McGraw Securing Java. Chapter 7: Java Security Guidelines * {ObjectFinalize} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> The finalize() method should only be called by the JVM after the object has been garbage collected. While the Java Language Specification allows an object's finalize() method to be called from outside the finalizer, doing so is usually a bad idea. For example, calling finalize() explicitly means that finalize() will be called more than once: the first time will be the explicit call and the last time will be the call that is made after the object is garbage collected. References: Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 586 * {SystemExit} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Web applications should never call System.exit(). A call to System.exit() is probably part of leftover debug code or code imported from a non-J2EE application. [[1]] Standards Mapping - OWASP Top 10 2004 - (OWASP 2004) A9 Application Denial of Service [[2]] Standards Mapping - Security Technical Implementation Guide Version 3 - (STIG 3) APP6080 CAT II [[3]] Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 382 [[4]] Standards Mapping - Payment Card Industry Data Security Standard Version 1.1 - (PCI 1.1) Requirement 6.5.9 * {UnsafeArrayDeclaration} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Triggers a violation when an array is declared public, final, and static. In most cases an array declared public, final and static is a bug. Because arrays are mutable objects, the final constraint requires that the array object itself be assigned only once, but makes no guarantees about the values of the array elements. Since the array is public, a malicious program can change the values stored in the array. In most situations the array should be made private. Example of violations: ------------------------------------------------------------------------------- class MyClass { public static final String[] myArray = init() public static final def myArray = [] as String[] } ------------------------------------------------------------------------------- ������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-basic.apt�������������������������������������������������0000644�0001750�0001750�00000072171�12323630032�021460� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Basic Rules -------------------------------------------------- Basic Rules ("<rulesets/basic.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * AssertWithinFinallyBlock ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for <assert> statements within a <finally> block. An <assert> can throw an exception, hiding the original exception, if there is one. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- int myMethod(int count) { try { doSomething() } finally { assert count > 0 // violation } } ------------------------------------------------------------------------------- * {AssignmentInConditional} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> An assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended. Example of violations: ------------------------------------------------------------------------------- if ((value = true)) { // should be == } while (value = true) { // should be == } (value = true) ? x : y (value = true) ?: x // the following code has no violations if (value == true) { } value == true ? x : y value == true ?: x ------------------------------------------------------------------------------- * {BigDecimalInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for calls to the <<<java.math.BigDecimal>>> constructors that take a <<<double>>> value as the first parameter. As described in the <<<BigDecimal>>> javadoc, the results from these constructors can be somewhat unpredictable, and their use is generally not recommended. This is because some numbers, such as 0.1, cannot be represented exactly as a <<<double>>>. For instance, executing <<<println new BigDecimal(0.1)>>> prints out <<<0.1000000000000000055511151231257827021181583404541015625>>>. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def b1 = new BigDecimal(0.1) // violation def b2 = new java.math.BigDecimal(23.45d) // violation ------------------------------------------------------------------------------- * {BitwiseOperatorInConditional} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> Checks for bitwise operations in conditionals. For instance, the condition <<<if (a | b)>>> is almost always a mistake and should be <<<if (a || b)>>>. If you need to do a bitwise operation then it is best practice to extract a temp variable. Example of violations: ------------------------------------------------------------------------------- if (a | b) { } if (a & b) { } ------------------------------------------------------------------------------- * {BooleanGetBoolean} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> This rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop̈́']. Example of violations: ------------------------------------------------------------------------------- // produces violation Boolean.getBoolean(value) // zero or two parameters is OK, must be different method Boolean.getBoolean(value, 1) Boolean.getBoolean() ------------------------------------------------------------------------------- * {BrokenNullCheck} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.17> Looks for faulty checks for <null> that can cause a <<<NullPointerException>>>. Examples: ------------------------------------------------------------------------------- if (name != null || name.length > 0) { } // violation if (name != null || name.length) { } // violation while (record == null && record.id < 10) { } // violation if (record == null && record.id && doStuff()) { } // violation def isNotValid = record == null && record.id < 10 // violation return record == null && !record.id // violation if (name != null || name.size() > 0) { } // violation if (string == null && string.equals("")) { } // violation def isValid = name != null || name.size() > 0 // violation return name != null || !name.size() // violation ------------------------------------------------------------------------------- * {BrokenOddnessCheck} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.13> The code uses <<<x % 2 == 1>>> to check to see if a value is odd, but this won't work for negative numbers (e.g., <<<(-5) % 2 == -1)>>>. If this code is intending to check for oddness, consider using <<<x & 1 == 1>>>, or <<< x % 2 != 0>>>. Examples: ------------------------------------------------------------------------------- if (x % 2 == 1) { } // violation if (method() % 2 == 1) { } // violation if (x & 1 == 1) { } // OK if (x % 2 != 0) { } // OK ------------------------------------------------------------------------------- * {ClassForName} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Using <<<Class.forName(...)>>> is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time. If you're forced to do dynamic class loading then use ClassLoader.loadClass instead. All variations of the <<<Class.forName(...)>>> method suffer from the same problem. For more information see these links: * {{http://blog.bjhargrave.com/2007/09/classforname-caches-defined-class-in.html}} * {{http://www.osgi.org/blog/2011/05/what-you-should-know-about-class.html}} [] Example of violations: ------------------------------------------------------------------------------- Class.forName('SomeClassName') Class.forName(aClassName, true, aClassLoader) ------------------------------------------------------------------------------- * {ComparisonOfTwoConstants} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.14> Checks for expressions where a <comparison operator> or <<<equals()>>> or <<<compareTo()>>> is used to compare two constants to each other or two literals that contain only constant values. Here are examples of code that produces a violation: ------------------------------------------------------------------------------- 23 == 67 // violation Boolean.FALSE != false // violation 23 < 88 // violation 0.17 <= 0.99 // violation "abc" > "ddd" // violation [Boolean.FALSE] >= [27] // violation [a:1] <=> [a:2] // violation [1,2].equals([3,4]) // violation [a:123, b:true].equals(['a':222, b:Boolean.FALSE]) // violation [a:123, b:456].compareTo([a:222, b:567] // violation [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE] // violation ------------------------------------------------------------------------------- * {ComparisonWithSelf} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.14> Checks for expressions where a <comparison operator> or <<<equals()>>> or <<<compareTo()>>> is used to compare a variable to itself, e.g.: <<<x == x, x != x, x \<=\> x, x \< x, x \>= x, x.equals(x) or x.compareTo(x)>>>, where <<<x>>> is a variable. Here are examples of code that produces a violation: ------------------------------------------------------------------------------- if (x == x) { } // violation if (x != x) { } // violation while (x < x) { } // violation if (x <= x) { } // violation while (x > x) { } // violation if (x >= x) { } // violation def c = (x <=> x) { } // violation println isReady = x.equals(x) // violation println x.compareTo(x) // violation ------------------------------------------------------------------------------- * {ConstantAssertExpression} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for <assert> statements with a constant value for the <assert> boolean expression, such as <<<true>>>, <<<false>>>, <<<null>>>, or a literal constant value. These <assert> statements will always pass or always fail, depending on the constant/literal value. Examples of violations include: ------------------------------------------------------------------------------- assert true assert false, "assertion message" assert Boolean.TRUE assert Boolean.FALSE assert null assert 0 assert 99.7 assert "" assert "abc" assert [:] assert [a:123, b:456] assert [a, b, c] ------------------------------------------------------------------------------- * {ConstantIfExpression} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for <if> statements with a constant value for the <if> boolean expression, such as <<<true>>>, <<<false>>>, <<<null>>>, or a literal constant value. These <if> statements can be simplified or avoided altogether. Examples of violations include: ------------------------------------------------------------------------------- if (true) { .. } if (false) { .. } if (Boolean.TRUE) { .. } if (Boolean.FALSE) { .. } if (null) { .. } if (0) { .. } if (99.7) { .. } if ("") { .. } if ("abc") { .. } if ([:]) { .. } if ([a:123, b:456]) { .. } if ([a, b, c]) { .. } ------------------------------------------------------------------------------- * {ConstantTernaryExpression} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for ternary expressions with a constant value for the boolean expression, such as <<<true>>>, <<<false>>>, <<<null>>>, or a literal constant value. Examples of violations include: ------------------------------------------------------------------------------- true ? x : y false ? x : y Boolean.TRUE ? x : y Boolean.FALSE ? x : y null ? x : y 0 ? x : y 99.7 ? x : y "" ? x : y "abc" ? x : y [:] ? x : y [a:123, b:456] ? x : y [a, b, c] ? x : y ------------------------------------------------------------------------------- The rule also checks for the same types of constant values for the boolean expressions within the "short" ternary expressions, also known as the "Elvis" operator, e.g.: ------------------------------------------------------------------------------- true ?: y null ?: y 99.7 ?: y "abc" ?: y [:] ?: y [a, b, c] ?: y ------------------------------------------------------------------------------- * {DeadCode} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Dead code appears after a <<<return>>> statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted. * {DoubleNegative} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> There is no point in using a double negative, it is always positive. For instance <<<!!x>>> can always be simplified to <<<x>>>. And <<<!(!x)>>> can as well. * {DuplicateCaseStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Check for duplicate <<<case>>> statements in a <<<switch>>> block, such as two equal integers or strings. Here are some examples of code that produces violations: ------------------------------------------------------------------------------- switch( 0 ) { case 1: break; case 2: break; case 2: break; // violation } switch( "test" ) { case "$a": break; case "$a": break; // ok; only flags constant values (not GStrings) case "ab": break; case "ab": break; // violation case "abc": break; } ------------------------------------------------------------------------------- * {DuplicateMapKey} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> A <Map> literal is created with duplicated key. The map entry will be overwritten. Example of violations: ------------------------------------------------------------------------------- def var1 = [a:1, a:2, b:3] //violation def var2 = [1:1, 1:2, 2:3] //violation def var3 = ["a":1, "a":2, "b":3] //violation // these are OK def var4 = [a:1, b:1, c:1] def var5 = [1:1, 2:1, 3:1] def var6 = ["a":1, "b":1, "c":1] ------------------------------------------------------------------------------- * {DuplicateSetValue} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> A <Set> literal is created with duplicate constant value. A set cannot contain two elements with the same value. Example of violations: ------------------------------------------------------------------------------- def a = [1, 2, 2, 4] as Set def b = [1, 2, 2, 4] as HashSet def c = [1, 2, 2, 4] as SortedSet def d = [1, 2, 2, 4] as FooSet def e = ['1', '2', '2', '4'] as Set def f = ['1', '2', '2', '4'] as HashSet def g = ['1', '2', '2', '4'] as SortedSet def h = ['1', '2', '2', '4'] as FooSet // these are OK def a = [1, 2, 3, 4] as Set def b = ['1', '2', '3', '4'] as Set def c = [1, '1'] as Set ------------------------------------------------------------------------------- * {EmptyCatchBlock} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <catch> blocks. In most cases, exceptions should not be caught and ignored (swallowed). The rule has a property named <<<ignoreRegex>>> that defaults to the value 'ignore|ignored'. If the name of the exception matches this regex then no violations are produced. *---------------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------------+----------------------------------------------------------------+------------------------+ | ignoreRegex | Regular expression - exception parameter names matching this | 'ignore|ignored' | | | regular expression are ignored and no volations are produced. | | *---------------------------------+----------------------------------------------------------------+------------------------+ Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { try { doSomething } catch(MyException e) { //violation // should do something here } } def myMethod() { try { doSomething } catch(MyException ignored) { //no violations because the parameter name is ignored } } ------------------------------------------------------------------------------- * {EmptyClass} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Reports classes without methods, fields or properties. Why would you need a class like this? This rule ignores interfaces, enums, anonymous inner classes, subclasses (extends), and classes with annotations. * {EmptyElseBlock} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <else> blocks. Empty <else> blocks are confusing and serve no purpose. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { if (x==23) { println 'ok' } else { // empty } } ------------------------------------------------------------------------------- * {EmptyFinallyBlock} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <finally> blocks. Empty <finally> blocks are confusing and serve no purpose. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { try { doSomething() } finally { // empty } } ------------------------------------------------------------------------------- * {EmptyForStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <for> blocks. Empty <for> statements are confusing and serve no purpose. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { for (int i=0; i < 23; i++) { // empty } } ------------------------------------------------------------------------------- * {EmptyIfStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <if> statements. Empty <if> statements are confusing and serve no purpose. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { if (x==23) { // empty } } ------------------------------------------------------------------------------- * {EmptyInstanceInitializer} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> An empty class instance initializer was found. It is safe to remove it. Example: ------------------------------------------------------------------------------- class MyClass { { } // empty instance initializer, not a closure } ------------------------------------------------------------------------------- * {EmptyMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> A method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the <<<@Override>>> annotation. This rule should not be used with Java 5 code because you cannot put <<<@Override>>> on a method implementing an interface. Use with Java 6 and higher. Example of violations: ------------------------------------------------------------------------------- class MyClass { // violation, empty method public void method1() {} // violation, empty method def method2() {} // OK because of @Override @Override public void method3() {} } abstract class MyBaseClass { // OK, handled by EmptyMethodInAbstractClass Rule public void method() {} } ------------------------------------------------------------------------------- * {EmptyStaticInitializer} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> An empty static initializer was found. It is safe to remove it. Example: ------------------------------------------------------------------------------- class MyClass { static { } } ------------------------------------------------------------------------------- * {EmptySwitchStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <switch> statements. Empty <switch> statements are confusing and serve no purpose. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { switch(myVariable) { // empty } } ------------------------------------------------------------------------------- * {EmptySynchronizedStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <synchronized> statements. Empty <synchronized> statements are confusing and serve no purpose. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- class MyClass { def myMethod() { synchronized(lock) { } } } ------------------------------------------------------------------------------- * {EmptyTryBlock} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <try> blocks. Empty <try> blocks are confusing and serve no purpose. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { try { // empty } catch(MyException e) { e.printStackTrace() } } ------------------------------------------------------------------------------- * {EmptyWhileStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for empty <while> statements. Empty <while> statements are confusing and serve no purpose. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { while (!stopped) { // empty } } ------------------------------------------------------------------------------- * {EqualsAndHashCode} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks that if either the <<<boolean equals(Object)>>> or the <<<int hashCode()>>> methods are overridden within a class, then both must be overridden. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- class MyClass { boolean equals(Object object) { // do something } } ------------------------------------------------------------------------------- And so does this: ------------------------------------------------------------------------------- class MyClass { int hashCode() { return 0 } } ------------------------------------------------------------------------------- * {EqualsOverloaded} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> The class has an <<<equals>>> method, but the parameter of the method is not of type <<<Object>>>. It is not overriding <<<equals>>> but instead overloading it. Example of violations: ------------------------------------------------------------------------------- class Object1 { //parameter should be Object not String boolean equals(String other) { true } } class Object2 { // Overloading equals() with 2 parameters is just mean boolean equals(Object other, String other2) { true } } class Object3 { // a no-arg equals()? What is this supposed to do? boolean equals() { true } } // all of these are OK and do not cause violations class Object4 { boolean equals(Object other) { true } } @SuppressWarnings('EqualsOverloaded') class Object5 { boolean equals(String other) { true } } class Object6 { boolean equals(java.lang.Object other) { true } } class Object7 { boolean equals(other) { true } } ------------------------------------------------------------------------------- * {ExplicitGarbageCollection} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Calls to <<<System.gc()>>>, <<<Runtime.getRuntime().gc()>>>, and <<<System.runFinalization()>>> are not advised. Code should have the same behavior whether the garbage collection is disabled using the option <<<-Xdisableexplicitgc>>> or not. Moreover, "modern" JVMs do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself. * {ForLoopShouldBeWhileLoop} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> A <<<for>>> loop without an init and update statement can be simplified to a <<<while>>> loop. Example of violations: ------------------------------------------------------------------------------- int i = 0; for(; i < 5;) { // Violation println i++ } // These are OK for(i in [1,2]) // OK println i for(int i = 0; i<5;) // OK println i++ int i = 0; for(; i < 5; i++) // OK println i for (Plan p : plans) { // OK println "Plan=$p" } ------------------------------------------------------------------------------- * {HardCodedWindowsFileSeparator} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> This rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant. Example of violations: ------------------------------------------------------------------------------- new File('.\\foo\\') new File('c:\\dir') new File('../foo\\') ------------------------------------------------------------------------------- * {HardCodedWindowsRootDirectory} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> This rule find cases where a File object is constructed with a windows-based path. This is not portable across operating systems or different machines, and using the File.listRoots() method is a better alternative. Example of violations: ------------------------------------------------------------------------------- new File('c:\\') new File('c:\\dir') new File('E:\\dir') ------------------------------------------------------------------------------- * {IntegerGetInteger} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> This rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop']. Example of violations: ------------------------------------------------------------------------------- // violations Integer.getInteger(value) Integer.getInteger(value, radix) // zero or more than 2 parameters is OK, must be different method Integer.getInteger() Integer.getInteger(value, radix, locale) ------------------------------------------------------------------------------- * {MultipleUnaryOperators} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Checks for multiple consecutive unary operators. These are confusing, and are likely typos and bugs. Example of violations: ------------------------------------------------------------------------------- int z = ~~2 // violation boolean b = !!true // violation boolean c = !!!false // 2 violations int j = -~7 // violation int k = +~8 // violation ------------------------------------------------------------------------------- * {RandomDoubleCoercedToZero} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> The Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer, Long, int, or long then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug. Example of violations: ------------------------------------------------------------------------------- (int) Math.random() (Integer) Math.random() int x = Math.random() Integer y = Math.random() int m() { Math.random() } Integer m() { Math.random() } (Math.random()) as int (Math.random()) as Integer ------------------------------------------------------------------------------- * {RemoveAllOnSelf} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Don't use <<<removeAll>>> to clear a collection. If you want to remove all elements from a collection <<<c>>>, use <<<c.clear>>>, not <<<c.removeAll(c)>>>. Calling <<<c.removeAll(c)>>> to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a <<<ConcurrentModificationException>>>. * {ReturnFromFinallyBlock} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for a return from within a <finally> block. Returning from a <finally> block is confusing and can hide the original exception. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- int myMethod() { try { doSomething() return 0 } catch(Exception e) { return -1 } finally { return 99 // violation } } ------------------------------------------------------------------------------- * ThrowExceptionFromFinallyBlock ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for throwing an exception from within a <finally> block. Throwing an exception from a <finally> block is confusing and can hide the original exception. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- int myMethod() { try { doSomething() throw new Exception() } finally { println 'finally' throw new Exception() // violation } } ------------------------------------------------------------------------------- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-enhanced-classpath-rules.apt������������������������������������0000644�0001750�0001750�00000005331�12414275030�024122� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Enhanced Classpath Rules -------------------------------------------------- CodeNarc - Enhanced Classpath Rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Several newer rules use a later compilation phase for parsing of the Groovy source code, allowing <<CodeNarc>> to use a richer and more complete Abstract Syntax Tree (AST). The downside is that the later compiler phase requires <<CodeNarc>> to have the application classes being analyzed, as well as any referenced classes, on the classpath. NOTE: If a rule requiring a later compiler phase is included in the active <<CodeNarc>> ruleset and enabled and one or more of the required classes is not on the classpath, then <<CodeNarc>> will log a Log4J WARN message for each source file that contains the missing references. * Grails-CodeNarc Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The {{{http://www.grails.org/plugin/codenarc/}Grails CodeNarc Plugin}} supports the new <enhanced classpath> rules out of the box. You are free to include these rules in your <<CodeNarc>> ruleset when you use the Grails CodeNarc plugin. * CodeNarc Ant Task - Expanding the Classpath ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TBD... <<CodeNarc>> users that use the Ant Task directly will need to adjust their Ant scripts to expand the classpath, if they want to take advantage of these special new rules. See the {{{./codenarc-ant-task.html}CodeNarc Ant Task}} for more information on configuring the Ant task. * CodeNarc - Other Tools and Frameworks - Expanding the Classpath? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Other tools/frameworks that use <<CodeNarc>> will most likely not be able to use these new rules initially, because the tool classpath will not support it. The hope is that the other <<CodeNarc>> tools will eventually be enhanced to provide the expanded classpath to <<CodeNarc>> – either optionally or always – so that they can also take advantage of these new rules. See the {{{./codenarc-other-tools-frameworks.html}CodeNarc - Integration with Other Tools / Frameworks}} for links to other tools and frameworks that use <<CodeNarc>>. TBD... * Now what? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We also expect to continue to introduce more of these "special" enhanced-classpath rules, since that greatly expands the capabilities for <<CodeNarc>> rules. Anyone who does not want to use the new rules or is unable to expand the classpath as required, can just omit these special rules from the <<CodeNarc>> ruleset or else disable the rules. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-creating-ruleset.apt��������������������������������������������0000644�0001750�0001750�00000044446�12006632016�022532� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Creating a RuleSet -------------------------------------------------- CodeNarc - Creating a RuleSet ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<Contents>> * {{{New_and_Improved_Way_To_Configure_a_RuleSet}New and Improved Way To Configure a RuleSet}} * {{{Creating_a_Groovy_RuleSet_File}Creating a Groovy RuleSet File}} * {{{Creating_an_XML_RuleSet_File}Creating an XML RuleSet File}} [] * New and Improved Way To Configure a RuleSet ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<NEW!>> The preferred way to configure the rules that <<CodeNarc>> will use is to create a custom <RuleSet> specifying the rule names (i.e., without depending on the <RuleSet> files provided with <<CodeNarc>>. This allows finer control over your custom RuleSet and insulates you from the provided <RuleSets> that can (and often do) change from release to release. ** Just Copy and Tweak One of the Starter RuleSet Files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See the {{{./StarterRuleSet-AllRulesByCategory.groovy.txt}Starter RuleSet - All Rules By Category}}. It contains all of the rules provided with the current version of <<CodeNarc>>, organized by category. Just delete or comment out the rules you don't want to use. Alternatively, there is a {{{./StarterRuleSet-AllRules.groovy.txt}Starter RuleSet - All Rules}}. It contains all of the rules provided with the current version of <<CodeNarc>>, in alphabetical order. Just delete or comment out the rules you don't want to use. ** The Other RuleSet Options Still Work ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can still create your own custom {{{A_Sample_Groovy_RuleSet_Using_the_Old_Syntax}Groovy}} <RuleSet> using the older syntax. You can even mix the new rule-name-only syntax with the older Groovy DSL syntax. It's all good! You can also continue to use the predefined <RuleSets> distributed with <<CodeNarc>> or you can create your own {{{Creating_an_XML_RuleSet_File}XML}} <RuleSet>. See the site navigation menu for a list of the <RuleSets> provided out of the box by <<CodeNarc>>. * {Creating a Groovy RuleSet File} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<CodeNarc>> provides a Groovy DSL (domain-specific language) for defining <RuleSets>. The preferred syntax for defining a <RuleSet> is to specify the list of rules using only the rule names. As mentioned above, this allows finer control over your custom RuleSet and insulates you from the provided <RuleSets> that can (and often do) change from release to release. ** A Sample Groovy RuleSet ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here is an example of a Groovy <RuleSet> file using the preferred syntax: +---------------------------------------------------------------------------------------- ruleset { description 'A custom Groovy RuleSet' CyclomaticComplexity { maxMethodComplexity = 1 } ClassName MethodName ConfusingTernary(priority:3) StatelessClass { name = 'StatelessDao' applyToClassNames = '*Dao' } } +---------------------------------------------------------------------------------------- Things to note: * The Groovy <RuleSet> file itself must be accessible on the classpath. * Each rule is specified by its rule <name>. * The <<StatelessClass>> rule redefines the <name> for that rule instance. You can have multiple instances of the same rule class as long as they have unique rule <names>. * You can optionally configure a rule instance by specifying rule properties in a <Map> after the rule <name> (see <<ConfusingTernary>> in the example). Or you can specify rule properties in a <Closure> after the rule <name> (see <<CyclomaticComplexity>> and <<StatelessClass>> in the example). * The easiest way to create a new custom <RuleSet> is to copy the {{{./StarterRuleSet-AllRulesByCategory.groovy.txt}Starter RuleSet}} (as a .groovy file). It contains all of the rules provided with the current version of <<CodeNarc>>, organized by category. Just delete or comment out the rules you don't want to use. And here is an example that mixes both the preferred (new) syntax along with the older syntax, to illustrate backward-compatibility: +---------------------------------------------------------------------------------------- ruleset { MethodName ConfusingTernary(priority:3) StatelessClass { name = 'StatelessDao' applyToClassNames = '*Dao' } // Old style rule(org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule) { priority = 3 } // Old style ruleset('rulesets/dry.xml') } +---------------------------------------------------------------------------------------- ** A Sample Groovy RuleSet Using the Old Syntax ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here is an example of a Groovy <RuleSet> file using the older syntax: +---------------------------------------------------------------------------------------- import org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule ruleset { description 'A sample Groovy RuleSet' ruleset('rulesets/basic.xml') { 'CatchThrowable' { priority = 1 enabled = false } 'EqualsAndHashCode' priority:3 exclude 'Empty*' } rule(ThrowExceptionFromFinallyBlockRule) { priority = 3 } rule("rules/MyCustomRuleScript.groovy") ruleset('MyGroovyRuleSet.groovy') } +---------------------------------------------------------------------------------------- Things to note: * The Groovy <RuleSet> file itself must be accessible on the classpath. * The "outer" <<ruleset>> defines the contents of the <RuleSet> (within a <closure>). It can include an optional <<description>> and any combination of <<ruleset>> (other <RuleSets>) and <<rule>> statements (individual <Rules>). About the "inner" <<ruleset>> statements: * Each <<ruleset>> statement loads a <RuleSet> file. The path specifies either a Groovy file or an XML file. By default, the paths specified are relative to the classpath. But these paths may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem), or "http:". * The 'rulesets/basic.xml' <RuleSet> file is interpreted as an XML file based on the '.xml' extension. Likewise, the 'MyGroovyRuleSet.groovy' file is interpreted as a Groovy <RuleSet> file. * The <RuleSet> can be customized by following the <RuleSet> path with an (optional) <closure>, containing any combination of the following: [[1]] <<Rule Configurations>> -- A <<ruleset>> statement can optionally provide configuration of the properties for individual rules within the <RuleSet>. Specify the name of the rule (as a <String>), followed by its configuration. (Remember to specify the rule <name>, not the class name. In most cases, the rule <name> is the class name without the "Rule" suffix). The name of the <Rule> can be followed by: [[a]] A <Map> of property names and values. See 'EqualsAndHashCode' within the example. [[b]] A <closure> containing property assignments statements. See 'CatchThrowable' within the example. [] Properties set this way can be of type <String>, <int>, <long> or <boolean>. [[2]] <<Rule Filtering (include or exclude statements)>> -- A <<ruleset>> statement can optionally specify <<include>> and/or <<exclude>> pattern(s) of rule names to include or exclude from the <RuleSet>. See {{{Filtering_Rules_Within_a_RuleSet}Filtering Rules Within a RuleSet}}. About the <<rule>> statements: * Each <<rule>> statements loads a single <Rule>. * The <<rule>> statement must specify either: [[a]] The class name for a <Rule>. See <<<ThrowExceptionFromFinallyBlockRule>>> within the example. The <Rule> class must be available on the classpath. [[b]] The path to a <Rule Script> file. See "MyGroovyRuleSet.groovy" within the example. By default, the paths specified are relative to the classpath. But these paths may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem) or "http:". * A <<rule>> can optionally provide configuration of the <Rule> properties by specifying a <closure> containing property assignment statements. See <<<ThrowExceptionFromFinallyBlockRule>>> within the example. As within <<ruleset>> statements, properties set this way can be of type <String>, <int>, <long> or <boolean>. * {Creating an XML RuleSet File} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The XML schema for a <<CodeNarc>> <RuleSet> file is embodied in the "ruleset-schema.xsd" file which is included within the <<CodeNarc>> jar. It contains three sections, all of which are optional, though the sections must be in the order listed: *-----------------------+---------------------------------------------------------------+--------------------------+ | <<XML Tag>> | <<Purpose>> | <<How many are allowed>> | *-----------------------+---------------------------------------------------------------+--------------------------+ | <<<\<description\>>>> | Describe the purpose of the <RuleSet> | Zero or one | *-----------------------+---------------------------------------------------------------+--------------------------+ | <<<\<ruleset-ref\>>>> | Include a nested <RuleSet>, optionally configuring and/or | Zero or more | | | filtering the rules within it. The path to the <RuleSet> | | | | can specify either an XML file or a Groovy <RuleSet> file. | | *-----------------------+---------------------------------------------------------------+--------------------------+ | <<<\<rule\>>>> | Include a single rule; specify its fully-qualified classname | Zero or more | *-----------------------+---------------------------------------------------------------+--------------------------+ | <<<\<rule-script\>>>> | Include a single rule implemented by a groovy script; | Zero or more | | | specify the path of the script. The path is relative to the | | | | classpath by default, but can optionally specify a URL prefix.| | *-----------------------+---------------------------------------------------------------+--------------------------+ ** A Sample XML RuleSet ~~~~~~~~~~~~~~~~~~~~~~~~ Here is an example XML <RuleSet> file: +---------------------------------------------------------------------------------------- <ruleset xmlns="http://codenarc.org/ruleset/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd" xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd"> <description>Sample rule set</description> <ruleset-ref path='rulesets/imports.xml'> <rule-config name='DuplicateImport'> <property name='priority' value='1'/> </rule-config> </ruleset-ref> <ruleset-ref path='rulesets/basic.xml'> <exclude name='StringInstantiation'/> </ruleset-ref> <rule class='org.codenarc.rule.generic.IllegalRegexRule'> <property name="name" value="AuthorTagNotAllowed"/> <property name='regex' value='\@author'/> </rule> <rule-script path='rules/MyStaticFieldRule.groovy'/> </ruleset> +---------------------------------------------------------------------------------------- Things to note: * The <RuleSet> file itself must be accessible on the classpath. * The top-level \<ruleset\> element must include the namespace declaration shown. About the \<ruleset-ref\> elements: * By default, The <path> of the \<ruleset-ref\> is relative to the classpath. But these paths may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem) or "http:". * You can optionally set arbitrary properties for the rules within the <RuleSet> by including one or more \<property\> elements within a \<rule-config\> element. In the example above, the <<DuplicateImportRule>> <priority> property is set to 1. Properties set this way can be of type <String>, <int>, <long> or <boolean>. * Remember that the <name> for a \<rule-config\> specifies the rule <name>, not the class name. (In most cases, the rule <name> is the class name without the "Rule" suffix.) About the \<rule\> elements: * You must specify the fully-qualified class name for each <Rule>. * The <Rule> class must be available on the classpath. * You can optionally set arbitrary properties for individual rules by including a \<property\> element within a \<rule\>. For the <<IllegalRegexRule>> rule above, the <name> property is set to "AuthorTagNotAllowed" and the <regex> property is set to "\@author". Properties set this way can be of type <String>, <int>, <long> or <boolean>. * Because the <name> property is customized for the <<IllegalRegexRule>>, the localized rule description will be retrieved from the custom messages resource bundle file ("codenarc-messages.properties"), if that bundle file exists, otherwise a default generic message will be used. The resource bundle message key will be based on the customized name. In this case, the message key will be "AuthorTagNotAllowed.description". About the \<rule-script\> elements: * You must specify the <path> for the rule script Groovy file. By default, this <path> is relative to the classpath. But these paths may be optionally prefixed by any of the valid java.net.URL prefixes, such as "file:" (to load from a relative or absolute path on the filesystem) or "http:". * The class defined within the rule script Groovy file must implement the <<<org.codenarc.rule.Rule>>> interface. * You can optionally set arbitrary properties for the rule by including a \<property\> element within a \<rule-script\> the same way you can for a \<rule\>. That is not shown here. * {Filtering Rules Within a RuleSet} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can use the \<include\> and \<exclude\> elements within a \<ruleset-ref\> to filter a <RuleSet> and include and/or the exclude individual rules. In the following <RuleSet> excerpt, the entire "rulesets/basic.xml" <RuleSet> is included, except for the <<BooleanInstantiationRule>> and <<StringInstantiationRule>>. +---------------------------------------------------------------------------------------- ruleset('rulesets/basic.xml') { exclude 'BooleanInstantiation' exclude 'StringInstantiation' } +---------------------------------------------------------------------------------------- And here is the same example in XML <RuleSet> format: +---------------------------------------------------------------------------------------- <ruleset-ref path='rulesets/basic.xml'> <exclude name='BooleanInstantiation'/> <exclude name='StringInstantiation'/> </ruleset-ref> +---------------------------------------------------------------------------------------- Alternatively, you may wish to explicitly specify the rules that you want included from a <RuleSet> rather than those that are excluded. In the following <RuleSet> excerpt, ONLY the <<ReturnFromFinallyBlockRule>> and <<StringInstantiationRule>> rules are included from the "rulesets/basic.xml" <RuleSet>. +---------------------------------------------------------------------------------------- ruleset('rulesets/basic.xml') { include 'ReturnFromFinallyBlockRule' include 'StringInstantiation' } +---------------------------------------------------------------------------------------- And here is the same example in XML <RuleSet> format: +---------------------------------------------------------------------------------------- <ruleset-ref path='rulesets/basic.xml'> <include name='ReturnFromFinallyBlockRule'/> <include name='StringInstantiation'/> </ruleset-ref> +---------------------------------------------------------------------------------------- <<Note>>: In all cases, the rule <name> is specified, not the class name. (In most cases, the rule <name> is the class name without the "Rule" suffix.) <<Note>>: If you specify at least one \<include\>, then ONLY rules matching an \<include\> will be included. <<Note>>: If you specify an \<include\> and an \<exclude\> for a rule, then the \<exclude\> takes precedence. ** Using Wildcards Within \<include\> and \<exclude\> Names ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You may optionally include wildcard characters ('*' or '?') in the rule <name> for both \<include\> and an \<exclude\> elements. The wildcard character '*' within the <name> matches a sequence of zero or more characters in the rule name, while the wildcard character '?' within the <name> matches exactly one character in the rule name. In the following <RuleSet> excerpt, all rules matching '*Instantiation' are included from the "rulesets/basic.xml" <RuleSet>. In this case, that will include the <<StringInstantiationRule>> and <<BooleanInstantiationRule>> rules. +---------------------------------------------------------------------------------------- <ruleset-ref path='rulesets/basic.xml'> <include name='*Instantiation'/> </ruleset-ref> +---------------------------------------------------------------------------------------- ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-groovyism.apt���������������������������������������������0000644�0001750�0001750�00000045642�12414302051�022436� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Groovyism Rules -------------------------------------------------- Groovy-ism Rules ("<rulesets/groovyism.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are rules covering Groovy idiomatic usage, and Groovy-specific bad practices. * {AssignCollectionSort} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> The Collections.sort() method mutates the list and returns the list as a value. If you are assigning the result of sort() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. This violation is triggered when a sort() method call appears as the right hand side of an assignment, or when it appears as the first method call in a series of chained method calls. Example of violations: ------------------------------------------------------------------------------- def a = myList.sort() def b = myList.sort() { it } def c = myList.sort().findAll { x < 1 } ------------------------------------------------------------------------------- * {AssignCollectionUnique} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> The Collections.unique() method mutates the list and returns the list as a value. If you are assigning the result of unique() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. This violation is triggered when a unique() method call appears as the right hand side of an assignment, or when it appears as the first method call in a series of chained method calls. Example of violations: ------------------------------------------------------------------------------- def a = myList.unique() def b = myList.unique() { it } def c = myList.unique().findAll { x < 1 } ------------------------------------------------------------------------------- * {ClosureAsLastMethodParameter} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> If a method is called and the last parameter is an inline closure then it can be declared outside of the method call parentheses. Example of violations: ------------------------------------------------------------------------------- // creates violation: poor Groovy style [1,2,3].each({ println it }) // no violation [1,2,3].each { println it } ------------------------------------------------------------------------------- * {CollectAllIsDeprecated} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> The <<<collectAll>>> method is deprecated since Groovy 1.8.1. Use <<<collectNested>>> instead. Example of violations: ------------------------------------------------------------------------------- def list = [1, 2, [3, 4, [5, 6]], 7] list.collectAll { it * 2 } // deprecated list.collectNested { it * 2 } // replacement ------------------------------------------------------------------------------- * {ConfusingMultipleReturns} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> Multiple return values can be used to set several variables at once. To use multiple return values, the left hand side of the assignment must be enclosed in parenthesis. If not, then you are not using multiple return values, you're only assigning the last element. Example of violations: ------------------------------------------------------------------------------- def a, b = [1, 2] // bad, b is null def c, d, e = [1, 2, 3] // bad, c and d are null class MyClass { def a, b, c = [1, 2, 3] // bad, a and b are null } def x = 1 // ok def (f, g) = [1, 2] // ok (a, b, c) = [1, 2, 3] // ok ------------------------------------------------------------------------------- * {ExplicitArrayListInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule checks for explicit calls to the no-argument constructor of <<<ArrayList>>>. In Groovy, it is best to write <<<new ArrayList() as []>>>, which creates the same object. * {ExplicitCallToAndMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<and(Object)>>> method is called directly in code instead of using the <<<&>>> operator. A groovier way to express this: <<<a.and(b)>>> is this: <<<a & b>>>. This rule can be configured to ignore <<<this.and(Object)>>> using the <ignoreThisReference> property. It defaults to <true>, so even <<<and(x)>>> will not trigger a violation. The default is <true> because <<<and>>> appears commonly in Grails criteria. This rule also ignores all calls to <<<super.and(Object)>>>. * {ExplicitCallToCompareToMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<compareTo(Object)>>> method is called directly in code instead of using the \<\=\>, \>, \>\=, \<, and \<\= operators. A groovier way to express this: <<<a.compareTo(b)>>> is this: <<<a \<\=\> b>>>, or using the other operators. Here are some other ways to write groovier code: ------------------------------------------------------------------------------- a.compareTo(b) == 0 // can be replaced by: a == b a.compareTo(b) // can be replaced by: a <=> b a.compareTo(b) > 0 // can be replaced by: a > b a.compareTo(b) >= 0 // can be replaced by: a >= b a.compareTo(b) < 0 // can be replaced by: a < b a.compareTo(b) <= 0 // can be replaced by: a <= b ------------------------------------------------------------------------------- This rule can be configured to ignore <<<this.compareTo(Object)>>> using the <ignoreThisReference> property. It defaults to <<<false>>>, so even <<<compareTo(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.compareTo(Object)>>>. * {ExplicitCallToDivMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<div(Object)>>> method is called directly in code instead of using the <<</>>> operator. A groovier way to express this: <<<a.div(b)>>> is this: <<<a / b>>>. This rule can be configured to ignore <<<div.xor(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<div(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.div(Object)>>>. * {ExplicitCallToEqualsMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<equals(Object)>>> method is called directly in code instead of using the <<<==>>> or <<<!=>>> operator. A groovier way to express this: <<<a.equals(b)>>> is this: <<<a == b>>> and a groovier way to express : <<<!a.equals(b)>>> is: <<<a != b>>>. This rule can be configured to ignore <<<this.equals(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<equals(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.equals(Object)>>>. * {ExplicitCallToGetAtMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<getAt(Object)>>> method is called directly in code instead of using the <<<[]>>> index operator. A groovier way to express this: <<<a.getAt(b)>>> is this: <<<a[b]>>>. This rule can be configured to ignore <<<this.getAt(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<getAt(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.getAt(Object)>>>. * {ExplicitCallToLeftShiftMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<leftShift(Object)>>> method is called directly in code instead of using the \<\< operator. A groovier way to express this: <<<a.leftShift(b)>>> is this: <<<a \<\< b>>>. This rule can be configured to ignore <<<this.leftShift(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<leftShift(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.leftShift(Object)>>>. * {ExplicitCallToMinusMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<minus(Object)>>> method is called directly in code instead of using the <<<->>> operator. A groovier way to express this: <<<a.minus(b)>>> is this: <<<a - b>>>. This rule can be configured to ignore <<<minus.xor(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<minus(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.minus(Object)>>>. * {ExplicitCallToMultiplyMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<multiply(Object)>>> method is called directly in code instead of using the <<<*>>> operator. A groovier way to express this: <<<a.multiply(b)>>> is this: <<<a * b>>>. This rule can be configured to ignore <<<this.multiply(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<multiply(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.multiply(Object)>>>. * {ExplicitCallToModMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<mod(Object)>>> method is called directly in code instead of using the <<<%>>> operator. A groovier way to express this: <<<a.mod(b)>>> is this: <<<a % b>>>. This rule can be configured to ignore <<<this.mod(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<mod(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.mod(Object)>>>. * {ExplicitCallToOrMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<or(Object)>>> method is called directly in code instead of using the <<<|>>> operator. A groovier way to express this: <<<a.or(b)>>> is this: <<<a | b>>>. This rule can be configured to ignore <<<this.or(Object)>>> using the <ignoreThisReference> property. It defaults to <true>, so even <<<or(x)>>> will not trigger a violation. This is the default because it is commonly used in Grails criteria. This rule also ignores all calls to <<<super.or(Object)>>>. * {ExplicitCallToPlusMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<plus(Object)>>> method is called directly in code instead of using the <<<+>>> operator. A groovier way to express this: <<<a.plus(b)>>> is this: <<<a + b>>>. This rule can be configured to ignore <<<this.plus(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<plus(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.plus(Object)>>>. * {ExplicitCallToPowerMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<power(Object)>>> method is called directly in code instead of using the <<<**>>> operator. A groovier way to express this: <<<a.power(b)>>> is this: <<<a ** b>>>. This rule can be configured to ignore <<<this.power(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<power(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.power(Object)>>>. * {ExplicitCallToRightShiftMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<rightShift(Object)>>> method is called directly in code instead of using the \>\> operator. A groovier way to express this: <<<a.rightShift(b)>>> is this: <<<a \>\> b>>>. This rule can be configured to ignore <<<this.rightShift(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<rightShift(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.rightShift(Object)>>>. * {ExplicitCallToXorMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when the <<<xor(Object)>>> method is called directly in code instead of using the <<<^>>> operator. A groovier way to express this: <<<a.xor(b)>>> is this: <<<a ^ b>>>. This rule can be configured to ignore <<<this.xor(Object)>>> using the <ignoreThisReference> property. It defaults to <false>, so even <<<xor(x)>>> will trigger a violation. This rule also ignores all calls to <<<super.xor(Object)>>>. * {ExplicitHashMapInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule checks for explicit calls to the no-argument constructor of <<<HashMap>>>. In Groovy, it is best to replace <<<new HashMap()>>> with <<<[:]>>>, which creates (mostly) the same object. <<<[:]>>> is technically a LinkedHashMap but it is very rare that someone absolutely needs an instance of <<<HashMap>>> and not a subclass. * {ExplicitLinkedHashMapInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since in CodeNarc 0.14> This rule checks for the explicit instantiation of a <<<LinkedHashMap>>> using the no-arg constructor. In Groovy, it is best to replace <<<new LinkedHashMap()>>> with <<<[:]>>>, which creates the same object. * {ExplicitHashSetInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule checks for explicit calls to the no-argument constructor of <<<HashSet>>>. In Groovy, it is best to replace <<<new HashSet()>>> with <<<[] as Set>>>, which creates the same object. * {ExplicitLinkedListInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule checks for explicit calls to the no-argument constructor of <<<LinkedList>>>. In Groovy, it is best to replace <<<new LinkedList()>>> with <<<[] as Queue>>>, which creates the same object. * {ExplicitStackInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule checks for explicit calls to the no-argument constructor of <<<Stack>>>. In Groovy, it is best to replace <<<new Stack()>>> with <<<[] as Stack>>>, which creates the same object. * {ExplicitTreeSetInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule checks for explicit calls to the no-argument constructor of <<<TreeSet>>>. In Groovy, it is best to replace <<<new TreeSet()>>> with <<<[] as SortedSet>>>, which creates the same object. * {GetterMethodCouldBeProperty} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> If a class defines a <<<public>>> method that follows the Java getter notation and that returns a constant, then it is cleaner to provide a Groovy property for the value rather than a Groovy method. Example of violations: ------------------------------------------------------------------------------- interface Parent { String getSomething() String getSomethingElse() } class Child extends Parent { static VALUE = 'value' @Override String getSomething() { 'something' // this could be simplified } @Override String getSomethingElse() { VALUE // this could be simplified } int getOtherValue() { 123 } static String getName() { 'MyName' } } class Child2 extends Parent { static VALUE = 'value' final String something = 'something' // this is cleaner final String somethingElse = VALUE // this is cleaner final int otherValue = 123 // this is cleaner static final String name = 'MyName' // this is cleaner } ------------------------------------------------------------------------------- * {GroovyLangImmutable} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> The <<<groovy.lang.Immutable>>> annotation has been deprecated and replaced by <<<groovy.transform.Immutable>>>. Do not use the <<<Immutable>>> in <<<groovy.lang>>>. Example of violations: ------------------------------------------------------------------------------- @Immutable class Person { } @groovy.lang.Immutable class Person { } import groovy.lang.Immutable as Imtl @Imtl class Person { } // the following code is OK @groovy.transform.Immutable class Person { } import groovy.transform.Immutable @Immutable class Person { } import groovy.transform.* @Immutable class Person { } import groovy.transform.Immutable as Imtl @Imtl class Person { } ------------------------------------------------------------------------------- * {GStringAsMapKey} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> A GString should not be used as a map key since its <hashcode> is not guaranteed to be stable. Consider calling <<<key.toString()>>>. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- Map map = ["${someRef}" : 'invalid' ] // violation ------------------------------------------------------------------------------- * {GStringExpressionWithinString} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Check for regular (single quote) strings containing a GString-type expression (${..}). Example of violations: ------------------------------------------------------------------------------- def str1 = 'total: ${count}' // violation def str2 = 'average: ${total / count}' // violation def str3 = "abc ${count}" // ok; GString def str4 = '$123' // ok def str5 = 'abc {123}' // ok ------------------------------------------------------------------------------- * {UseCollectMany} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> In many case <<<collectMany()>>> yields the same result as <<<collect{}.flatten()>>>. It is easier to understand and more clearly conveys the intent. Example of violations: ------------------------------------------------------------------------------- def l = [1, 2, 3, 4] l.collect{ [it, it*2] }.flatten() // suboptimal l.collectMany{ [it, it*2] } // same functionality, better readability ------------------------------------------------------------------------------- * {UseCollectNested} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> Instead of nested <<<collect{}>>> calls use <<<collectNested{}>>>. Example of violations: ------------------------------------------------------------------------------- def list = [1, 2, [3, 4, 5, 6], [7]] println list.collect { elem -> if (elem instanceof List) elem.collect {it *2} // violation else elem * 2 } println list.collect([8]) { if (it instanceof List) it.collect {it *2} // violation else it * 2 } println list.collectNested { it * 2 } // same functionality, better readability ------------------------------------------------------------------------------- ����������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-creating-rule.apt�����������������������������������������������0000644�0001750�0001750�00000015600�12414275015�022011� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Creating a Rule -------------------------------------------------- CodeNarc - Creating a Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<CodeNarc>> includes many predefined rules, but you can also create your own custom rules. See the site navigation menu for a list of rules provided out of the box by <<CodeNarc>>. <<CodeNarc>> provides abstract superclasses and helper classes for creating new rules. See this {{{http://www.youtube.com/watch?v=ZPu8FaZZwRw}screencast}} showing how easy it is to create a new rule. * The Rule Interface ~~~~~~~~~~~~~~~~~~~~~ All rules must implement the <<<org.codenarc.rule.Rule>>> interface. This interface specifies that all rules must define a <name>, a <priority> (from 1 to 3), and also implement the <<<List applyTo(SourceCode sourceCode)>>> method. The method returns the <List> of <<<Violation>>> objects that result from applying the rule to a single source file. * The AbstractRule Class ~~~~~~~~~~~~~~~~~~~~~~~~~ The <<<org.codenarc.rule.AbstractRule>>> class is the abstract superclass (or ancestor) for all rules provided with <<CodeNarc>>. It provides many standard properties and helper methods for subclasses, as described in {{{./codenarc-configuring-rules.html#Standard_Properties_for_Configuring_Rules} Standard Properties for Configuring Rules}}. ** {A Sample Rule Subclass of AbstractRule} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here is an example rule class that is a subclass of <<<AbstractRule>>>: +---------------------------------------------------------------------------------------- import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Sample rule. Checks for static fields. */ class MyStaticFieldRule extends AbstractRule { String name = 'MyStaticField' int priority = 2 void applyTo(SourceCode sourceCode, List violations) { sourceCode.ast.classes.each { clazz -> clazz.fields.each { fieldNode -> if (fieldNode.static) { violations << createViolation(sourceCode, fieldNode) } } } } } +---------------------------------------------------------------------------------------- Things to note about <<<MyStaticFieldRule>>> class: * It extends <<<AbstractRule>>>. * It provides <name> and <priority> properties as mandated by the <<<Rule>>> interface. * It implements the <<<void applyTo(SourceCode sourceCode, List violations)>>> method which is declared <abstract> in the <<<AbstractRule>>> superclass. * It accesses the AST for the source code, which is an instance of the <<<org.codehaus.groovy.ast.ModuleNode>>> class from Groovy. * It uses the <<<createViolation()>>> helper method from <<<AbstractRule>>>. See the <<CodeNarc>> source code for other examples (look for rule classes that are direct subclasses of <<<AbstractRule>>>). * The AbstractAstVisitorRule and AbstractAstVisitor Classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Many of the rules included with <<CodeNarc>> are implemented using the <Visitor> pattern, as supported by the Groovy AST (Abstract Syntax Tree). See the <<<ClassCodeVisitorSupport>>> class within the Groovy distribution ({{{http://groovy.codehaus.org/api/index.html}Javadocs}}). ** A Sample Rule Using AbstractAstVisitorRule and AbstractAstVisitor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here is an example rule class that is a subclass of <<<AbstractAstVisitorRule>>> that uses an associated AST <Visitor> class that is a subclass of <<<AbstractAstVisitor>>>. This is the code for the <<EmptyTryBlock>> rule included with <<CodeNarc>>. +---------------------------------------------------------------------------------------- import org.codenarc.rule.AbstractAstVisitor import org.codenarc.rule.AbstractAstVisitorRule import org.codehaus.groovy.ast.stmt.TryCatchStatement import org.codenarc.util.AstUtil class EmptyTryBlockRule extends AbstractAstVisitorRule { String name = 'EmptyTryBlock' int priority = 2 Class astVisitorClass = EmptyTryBlockAstVisitor } class EmptyTryBlockAstVisitor extends AbstractAstVisitor { void visitTryCatchFinally(TryCatchStatement tryCatchStatement) { if (AstUtil.isEmptyBlock(tryCatchStatement.tryStatement)) { addViolation(tryCatchStatement) } super.visitTryCatchFinally(tryCatchStatement) } } +---------------------------------------------------------------------------------------- Things to note about this example: * This file contains two classes. The <<<EmptyTryBlockRule>>> class extends <<<AbstractAstVisitorRule>>>. The <<<EmptyTryBlockAstVisitor>>> extends <<<AbstractAstVisitor>>>. * <<<EmptyTryBlockRule>>> includes an <astVisitorClass> property that specifies that it uses the <<<EmptyTryBlockAstVisitor>>> class. * <<<EmptyTryBlockAstVisitor>>> implements the <<<void visitTryCatchFinally(TryCatchStatement)>>> <visitor> method defined by the <<<ClassCodeVisitorSupport>>> so that it will <visit> every try/catch statement within the source code. * It uses the <<<AstUtil>>> utility class. See the <<CodeNarc>> source code and javadocs for more information and further examples. * Creating a Rule Script ~~~~~~~~~~~~~~~~~~~~~~~~~ You can also create a new rule using a Groovy script file (typically a .groovy file). The script must still define a class that implements the <<<org.codenarc.rule.Rule>>> interface. The main advantage is that the rule does not have to be compiled into a <<.class>> file first, so you can avoid the compile/build phase, and its associated hassles. The Groovy script file is parsed (and compiled) at runtime. ** A Sample Rule Script ~~~~~~~~~~~~~~~~~~~~~~~~ Here is an example rule script. Note that this is the same source code as in the sample rule class shown {{{A_Sample_Rule_Subclass_of_AbstractRule}above}}. +---------------------------------------------------------------------------------------- import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode /** * Sample rule script. Checks for static fields. */ class MyStaticFieldRule extends AbstractRule { String name = 'MyStaticField' int priority = 2 void applyTo(SourceCode sourceCode, List violations) { sourceCode.ast.classes.each { clazz -> clazz.fields.each { fieldNode -> if (fieldNode.static) { violations << createViolation(sourceCode, fieldNode) } } } } } +---------------------------------------------------------------------------------------- ��������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-formatting.apt��������������������������������������������0000644�0001750�0001750�00000061263�12436202541�022556� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Formatting Rules -------------------------------------------------- Formatting Rules ("<rulesets/formatting.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {BlankLineBeforePackage} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Makes sure there are no blank lines before the package declaration of a source code file. * {BracesForClass} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks the location of the opening brace (\{) for classes. By default, requires them on the same line, but the <<<sameLine>>> property can be set to false to override this. NOTE: This rule ignores annotation types, e.g. <<<@interface MyAnnotation {}>>>. * {BracesForForLoop} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks the location of the opening brace (\{) for for loops. By default, requires them on the same line, but the <<<sameLine>>> property can be set to false to override this. * {BracesForIfElse} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks the location of the opening brace (\{) for if statements. By default, requires them on the same line, but the <<<sameLine>>> property can be set to false to override this. * {BracesForMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks the location of the opening brace (\{) for constructors and methods. By default, requires them on the same line, but the <<<sameLine>>> property can be set to false to override this. * {BracesForTryCatchFinally} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks the location of the opening brace (\{) for try statements. By default, requires them on the line, but the <<<sameLine>>> property can be set to false to override this. * {ClassJavadoc} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Makes sure each class and interface definition is preceded by javadoc. Enum definitions are not checked, due to strange behavior in the Groovy AST. By default, only the main class in a file is checked for Javadoc. The main class is defined as the class that has the same name as the source file, for instance MyClass is the main class in MyClass.groovy but the class MyOtherClass defined in the same source file is not the main class. To check all the classes in the file set the rule property <<<applyToNonMainClasses>>> to true. * {ClosureStatementOnOpeningLineOfMultipleLineClosure} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.20> Checks for closure logic on first line (after <<<-\>>>>) for a multi-line closure. That breaks the symmetry of indentation (if the subsequent statements are indented normally), and that first statement can be easily missed when reading the code. Example of violations: ------------------------------------------------------------------------------- def closure = { name -> println name addToCounts() println “done” } ------------------------------------------------------------------------------- * {ConsecutiveBlankLines} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Makes sure there are no consecutive lines that are either blank or whitespace only. This reduces the need to scroll further than necessary when reading code, and increases the likelihood that a logical block of code will fit on one screen for easier comprehension. Example of violation: ------------------------------------------------------------------------------- def name def value def id ------------------------------------------------------------------------------- * {FileEndsWithoutNewline} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Makes sure each source file ends with a newline character. * {LineLength} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks the maximum length for each line of source code. It checks for number of characters, so lines that include tabs may appear longer than the allowed number when viewing the file. The maximum line length can be configured by setting the length property, which defaults to 120. NOTE: This rule does not support the @SuppressAnnotations annotation or the classname-based rule properties (applyToClassNames, doNotApplyToClassNames) to enable/disable the rule. If you want to specify or restrict where this rule is applied, you must use the file-based rule properties: applyToFileNames, doNotApplyToFileNames, applyToFilesMatching and doNotApplyToFilesMatching. * {MissingBlankLineAfterImports} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Makes sure there is a blank line after the imports of a source code file. Example of violation: ------------------------------------------------------------------------------- import org.apache.commons.lang.StringUtils class MyClass { } // violation ------------------------------------------------------------------------------- * {MissingBlankLineAfterPackage} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Makes sure there is a blank line after the package statement of a source code file. Example of violation: ------------------------------------------------------------------------------- package org.codenarc import java.util.Date // violation class MyClass { void go() { /* ... */ } } ------------------------------------------------------------------------------- * {SpaceAfterCatch} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is exactly one space (blank) after the <<<catch>>> keyword and before the opening parenthesis. Examples of violations: ------------------------------------------------------------------------------- try { } catch(Exception e) { } // violation try { } catch (Exception e) { } // violation ------------------------------------------------------------------------------- * {SpaceAfterComma} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Checks that there is at least one space or whitespace following each comma. That includes checks for method and closure declaration parameter lists, method call parameter lists, Map literals and List literals. Known limitations: * May not catch actual violations if the source line contains unicode character literals, e.g. <<<'\\u00A0'>>> [] Examples of violations: ------------------------------------------------------------------------------- def value = calculate(1,399, 'abc') // violation on parameter 399 def method1(int a,String b) { } // violation on parameter b def closure1 = { int a,String b -> } // violation on parameter b def list1 = [a,b, c] // violation on list element b def map1 = [a:1,b:2, c:3] // violation on map element b:2 ------------------------------------------------------------------------------- * {SpaceAfterClosingBrace} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is at least one space (blank) or whitespace after each closing brace ("\{") for method/class/interface declarations, closure expressions and block statements. A closure expression followed by a dot operator (.), a comma, a closing parenthesis, the spread-dot operator (*.), a semicolon or the null-safe operator (?.) does not cause a violation. *---------------------------+------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------+------------------------------------------------------------------+------------------------+ | checkClosureMapEntryValue | If <<<false>>>, then do not check for whitespace after closing | <<<true>>> | | | braces for closure expressions that are literal Map values, e.g. | | | | <<<[abc:{doStuff()}]>>>. | | *---------------------------+------------------------------------------------------------------+------------------------+ Known limitations: * May not catch actual violations if the source line contains unicode character literals, e.g. <<<'\\u00A0'>>> [] Examples of violations and exceptions: ------------------------------------------------------------------------------- if (ready) { return 9 }else { } // violation try { doStuff() }finally { } // violation def matching = list.find { it.isReady() }.filter() // no violation for dot operator assert list.every { it.isReady() }, "Error" // no violation for comma def m = [a:123, b:{ println 7 },c:99] // no violation for comma processItems(list.select { it.isReady() }) // no violation for closing parenthesis def names = records.findAll { it.age > 1 }*.name // no violation for spread operator list?.collect { it?.type }?.join(',') // no violation for null-safe operator ------------------------------------------------------------------------------- * {SpaceAfterFor} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is exactly one space (blank) after the <<<for>>> keyword and before the opening parenthesis. Examples of violations: ------------------------------------------------------------------------------- for(name in names) { } // violation for (int i=0; i < 10; i++) { } // violation ------------------------------------------------------------------------------- * {SpaceAfterIf} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is exactly one space (blank) after the <<<if>>> keyword and before the opening parenthesis. Examples of violations: ------------------------------------------------------------------------------- if(true) { } // violation if (true) { } // violation ------------------------------------------------------------------------------- * {SpaceAfterOpeningBrace} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is at least one space (blank) or whitespace after each opening brace ("\{") for method/class/interface declarations, closure expressions and block statements. *---------------------------+------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------+------------------------------------------------------------------+------------------------+ | checkClosureMapEntryValue | If <<<false>>>, then do not check for whitespace after opening | <<<true>>> | | | braces for closure expressions that are literal Map values, e.g. | | | | <<<[abc:{doStuff()}]>>>. | | *---------------------------+------------------------------------------------------------------+------------------------+ | ignoreEmptyBlock | If <<<true>>>, then allow for <<<[{}]>>> in code | <<<false>>> | *---------------------------+------------------------------------------------------------------+------------------------+ Examples of violations: ------------------------------------------------------------------------------- class MyClass{int count } // violation interface MyInterface {static final OK = 1 }// violation enum MyEnum {OK, BAD } // violation def myMethod() {int count } // violation if (ready) {println 9 } // violation if (ready) { } else {println 99} // violation for (int i=0; i<10; i++) {println i } // violation for (String name in names) {println name } // violation for (String name: names) {println name } // violation while (ready) {println time } // violation try {doStuff() // violation } catch(Exception e) {x=77 } // violation } finally {println 'error' } // violation list.each {name -> } // violation shouldFail(Exception) {doStuff() } // violation ------------------------------------------------------------------------------- * {SpaceAfterSemicolon} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is at least one space (blank) or whitespace following a semicolon that separates: * multiple statements on a single line * the clauses within a classic for loop, e.g. for (i=0;i\<10;i++) Examples of violations: ------------------------------------------------------------------------------- def myMethod() { println 1;println 2 // violation def closure = { x -> doStuff();x = 23; } // violation for (int i=0;i < 10;i++) { // violations (2) for (int j=0; j < 10;j++) { } // violation } } ------------------------------------------------------------------------------- * {SpaceAfterSwitch} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is exactly one space (blank) after the <<<switch>>> keyword and before the opening parenthesis. Examples of violations: ------------------------------------------------------------------------------- switch(x) { // violation case 1: println 'one' } switch (x) { // violation case 1: println 'one' } ------------------------------------------------------------------------------- * {SpaceAfterWhile} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is exactly one space (blank) after the <<<while>>> keyword and before the opening parenthesis. Examples of violations: ------------------------------------------------------------------------------- while(true) { } // violation while (true) { } // violation ------------------------------------------------------------------------------- * {SpaceAroundClosureArrow} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Checks that there is at least one space (blank) or whitespace around each closure arrow (->) symbol. Known limitations: * Does not catch violations if the closure arrow (->) is on a separate line from the start of the closure. [] Example of violations: ------------------------------------------------------------------------------- def closure1 = {->} // violation def closure2 = { ->} // violation def closure3 = {-> } // violation def closure4 = { count-> println 123 } // violation def closure5 = { count, name ->println 123 } // violation ------------------------------------------------------------------------------- * {SpaceAroundMapEntryColon} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.20> Check for proper formatting of whitespace around colons for literal Map entries. By default, no whitespace is allowed either before or after the Map entry colon, but you can change that through the configuration properties below. *---------------------------+------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------+------------------------------------------------------------------+------------------------+ | characterBeforeColonRegex | The regular expression that must match the character before | <<</\\S/>>> | | | the colon (:) for a literal <Map> entry. For example, <<</\\S/>>> | | | | matches any non-whitespace character and <<</\\s/>>> matches any | (i.e., no space allowed | | | whitespace character (thus requiring a space or whitespace). | before the colon) | *---------------------------+------------------------------------------------------------------+------------------------+ | characterAfterColonRegex | The regular expression that must match the character after | <<</\\S/>>> | | | the colon (:) for a literal <Map> entry. For example, <<</\\S/>>> | | | | matches any non-whitespace character and <<</\\s/>>> matches any | (i.e., no space allowed | | | whitespace character (thus requiring a space or whitespace). | before the colon) | *---------------------------+------------------------------------------------------------------+------------------------+ Example of violations: ------------------------------------------------------------------------------- Map m1 = [myKey : 12345] // violation (both before and after the colon) println [a :[1:11, 2:22], // violation on a (before colon) b:[(Integer): 33]] // violation on Integer (after colon) ------------------------------------------------------------------------------- * {SpaceAroundOperator} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is at least one space (blank) or whitespace around each binary operator, including: +, -, *, /, \>\>, \<\<, &&, ||, &, |, ?:, =, "as". Do not check dot ('.') operator. Do not check unary operators (!, +, -, ++, --, ?.). Do not check array ('[') operator. Known limitations: * Does not catch violations of missing space around equals operator (=) within a declaration expression, e.g. <<<def x=23>>> * Does not catch violations of certain ternary expressions and standalone elvis operator (?:) expressions [] Examples of violations: ------------------------------------------------------------------------------- def myMethod() { 3+ 5-x*23/ 100 // violation list \<\<123 // violation other\>\> writer // violation x=99 // violation x&& y // violation x ||y // violation x &y // violation x| y // violation [1,2]as String // violation } ------------------------------------------------------------------------------- * {SpaceBeforeClosingBrace} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is at least one space (blank) or whitespace before each closing brace ("\}") for method/class/interface declarations, closure expressions and block statements. *---------------------------+------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------+------------------------------------------------------------------+------------------------+ | checkClosureMapEntryValue | If <<<false>>>, then do not check for whitespace before closing | <<<true>>> | | | braces for closure expressions that are literal Map values, e.g. | | | | <<<[abc:{doStuff()}]>>>. | | *---------------------------+------------------------------------------------------------------+------------------------+ | ignoreEmptyBlock | If <<<true>>>, then allow for <<<[{}]>>> in code | <<<false>>> | *---------------------------+------------------------------------------------------------------+------------------------+ Known limitations: * May not catch actual violations if the source line contains unicode character literals, e.g. <<<'\\u00A0'>>> [] Examples of violations: ------------------------------------------------------------------------------- class MyClass { int count} // violation interface MyInterface { void doStuff()} // violation enum MyEnum { OK, BAD} // violation def myMethod() { return 9} // violation if (ready) { doStuff()} // violation if (ready) { } else { return 9} // violation for (int i=0; i<10; i++) { println i} // violation for (String name in names) { println name} // violation for (String name: names) { println name} // violation while (ready) { doStuff()} // violation try { doStuff()} // violation catch(Exception e) { logError(e)} // violation finally { cleanUp()} // violation list.each { name -> println name} // violation shouldFail(Exception) { doStuff()} // violation ------------------------------------------------------------------------------- * {SpaceBeforeOpeningBrace} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check that there is at least one space (blank) or whitespace before each opening brace ("\{") for method/class/interface declarations, closure expressions and block statements. *---------------------------+------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------+------------------------------------------------------------------+------------------------+ | checkClosureMapEntryValue | If <<<false>>>, then do not check for whitespace before opening | <<<true>>> | | | braces for closure expressions that are literal Map values, e.g. | | | | <<<[abc:{doStuff()}]>>>. | | *---------------------------+------------------------------------------------------------------+------------------------+ Known limitations: * May not catch actual violations if the source line contains unicode character literals, e.g. <<<'\\u00A0'>>> [] Examples of violations: ------------------------------------------------------------------------------- class MyClass{ } // violation class MyOtherClass extends AbstractClass{ } // violation interface MyInterface{ } // violation enum MyEnum{ OK, BAD } // violation def myMethod(){ } // violation if (ready){ } // violation if (ready) { } else{} // violation for (int i=0; i<10; i++){ } // violation for (String name in names){ } // violation for (String name: names){ } // violation while (ready){ } // violation try{ } finally { } // violation try { } catch(Exception e){ } // violation try { } finally{ } // violation list.each{ name -> } // violation shouldFail(Exception){ doStuff() } // violation ------------------------------------------------------------------------------- * {TrailingWhitespace} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Checks that no lines of source code end with whitespace characters. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-exceptions.apt��������������������������������������������0000644�0001750�0001750�00000017507�12407654152�022576� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Exceptions Rules -------------------------------------------------- Exceptions Rules ("<rulesets/exceptions.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {CatchArrayIndexOutOfBoundsException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Checks for catching a <<<ArrayIndexOutOfBoundsException>>>. Catching <<<ArrayIndexOutOfBoundsException>>> should be avoided in the first place by checking the array size before accessing an array element. Catching the exception may mask underlying errors. * {CatchError} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for catching a <<<Error>>>. In most cases that is much too broad, and is also dangerous because it can catch exceptions such as <<<ThreadDeath>>> and <<<OutOfMemoryError>>>. * {CatchException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for catching a <<<Exception>>>. In most cases that is too broad or general. It should usually be restricted to framework or infrastructure code, rather than application code. * {CatchIllegalMonitorStateException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Dubious catching of IllegalMonitorStateException. IllegalMonitorStateException is generally only thrown in case of a design flaw in your code (calling wait or notify on an object you do not hold a lock on). * {CatchIndexOutOfBoundsException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Checks for catching a <<<IndexOutOfBoundsException>>>. Catching <<<IndexOutOfBoundsException>>> should be avoided in the first place by checking for a valid index before accessing an indexed element. Catching the exception may mask underlying errors. * {CatchNullPointerException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for catching a <<<NullPointerException>>>. Catching <<<NullPointerException>>> is never appropriate. It should be avoided in the first place with proper null checking, and it can mask underlying errors. * {CatchRuntimeException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for catching a <<<RuntimeException>>>. In most cases that is too broad or general. It should usually be restricted to framework or infrastructure code, rather than application code. * {CatchThrowable} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for catching a <<<Throwable>>>. In most cases that is much too broad, and is also dangerous because it can catch exceptions such as <<<ThreadDeath>>> and <<<OutOfMemoryError>>>. * {ConfusingClassNamedException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This class is not derived from another exception, but ends with 'Exception'. This will be confusing to users of this class. * {ExceptionExtendsError} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Errors are system exceptions. Do not extend them. Examples: ------------------------------------------------------------------------------- class MyError extends Error { } // violation class MyError extends java.lang.Error { } // violation class MyException extends Exception { } // OK ------------------------------------------------------------------------------- * {ExceptionExtendsThrowable} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Checks for classes that extend <<<Throwable>>>. Custom exception classes should subclass <<<Exception>>> or one of its descendants. Example of violations: ------------------------------------------------------------------------------- class MyException extends Throwable { } // violation ------------------------------------------------------------------------------- * {ExceptionNotThrown} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Checks for an exception constructor call without a <<<throw>>> as the last statement within a catch block. This rule treats any constructor call for a class named <xxx><<Exception>> as an exception constructor call. Example of violations: ------------------------------------------------------------------------------- void execute() { try { } catch(Exception e) { new Exception(e) } // violation } try { doStuff() } catch(DaoException e) { log.warning("Ooops", e) new ServiceException(e) // violation } catch(Exception e) { new SystemException(e) // violation } try { doStuff() } catch(Exception e) { throw new DaoException(e) } // ok ------------------------------------------------------------------------------- * {MissingNewInThrowStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> A common Groovy mistake when throwing exceptions is to forget the new keyword. For instance, <<<throw RuntimeException()>>> instead of <<<throw new RuntimeException()>>>. If the error path is not unit tested then the production system will throw a Method Missing exception and hide the root cause. This rule finds constructs like <<<throw RuntimeException()>>> that look like a new keyword was meant to be used but forgotten. The following code will all cause violations: ------------------------------------------------------------------------------- throw RuntimeException() // ends in Exceptions, first letter Capitalized throw RuntimeFailure() // ends in Failure, first letter Capitalized throw RuntimeFault(foo) // ends in Fault, first letter Capitalized ------------------------------------------------------------------------------- The following code will not cause any exceptions: ------------------------------------------------------------------------------- throw new RuntimeException() throw runtimeFailure() // first letter lowercase, assumed to be method call ------------------------------------------------------------------------------- * {ReturnNullFromCatchBlock} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Returning null from a catch block often masks errors and requires the client to handle error codes. In some coding styles this is discouraged. This rule ignores methods with <<<void>>> return type. * {SwallowThreadDeath} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Detects code that catches java.lang.ThreadDeath without re-throwing it. Example of violations: ------------------------------------------------------------------------------- try { def a = 0 } catch (ThreadDeath td) { td.printStackTrace() } ------------------------------------------------------------------------------- * {ThrowError} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for throwing an instance of <<<java.lang.Error>>>. This is not appropriate within normal application code. Throw an instance of a more specific exception subclass instead. * {ThrowException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for throwing an instance of <<<java.lang.Exception>>>. Throw an instance of a more specific exception subclass instead. * {ThrowNullPointerException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for throwing an instance of <<<java.lang.NullPointerException>>>. Applications should never throw a <<<NullPointerException>>>. * {ThrowRuntimeException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for throwing an instance of <<<java.lang.RuntimeException>>>. Throw an instance of a more specific exception subclass instead. * {ThrowThrowable} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for throwing an instance of <<<java.lang.Throwable>>>. Throw an instance of a more specific exception subclass instead. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-generic.apt�����������������������������������������������0000644�0001750�0001750�00000063501�12415360352�022017� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Generic Rules -------------------------------------------------- Generic Rules ("<rulesets/generic.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These rules provide a generic check that only makes sense when customized. These rules are not <enabled> until the necessary configuration is provided. See {{{http://tenpercentnotcrap.wordpress.com/2013/08/04/codenarc-hidden-gems-using-codenarcs-generic-rules/}CodeNarc – Hidden Gems: Using CodeNarc’s generic rules}} for examples of using the <<CodeNarc>> <"generic"> rules to enforce your own custom best practices. * {IllegalClassMember} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Checks for classes containing fields/properties/methods matching configured illegal member modifiers or not matching any of the configured allowed member modifiers. *--------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *--------------------------+----------------------------------------------------------------+------------------------+ | allowedFieldModifiers | Specifies one or more groups of whitespace-delimited modifier | <<<null>>> | | | names (e.g. "public static" or "protected"). Multiple groups | | | | are separated by commas (e.g. "private final, protected"). If | | | | a field does not match all of the modifiers in any group, then | | | | trigger a violation. If <<<null>>> or empty, skip this check. | | *--------------------------+----------------------------------------------------------------+------------------------+ | allowedMethodModifiers | Specifies one or more groups of whitespace-delimited modifier | <<<null>>> | | | names (e.g. "public static" or "protected"). Multiple groups | | | | are separated by commas (e.g. "private final, protected"). If | | | | a method does not match all of the modifiers in any group, then| | | | trigger a violation. If <<<null>>> or empty, skip this check. | | *--------------------------+----------------------------------------------------------------+------------------------+ | allowedPropertyModifiers | Specifies one or more groups of whitespace-delimited modifier | <<<null>>> | | | names (e.g. "public static" or "protected"). Multiple groups | | | | are separated by commas (e.g. "private final, protected"). If a| | | | property does not match all of the modifiers in any group, then| | | | trigger a violation. If <<<null>>> or empty, skip this check. | | *--------------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodNames | Specifies one or more (comma-separated) method names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *--------------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodsWith- | Specifies one or more (comma-separated) annotation names that | <<<null>>> | | AnnotationNames | should be ignored (i.e., methods with those annotations should | | | | not cause a rule violation). The names may optionally contain | | | | wildcards (*,?). (Do not include the "@" in the annotation name.| | *--------------------------+----------------------------------------------------------------+------------------------+ | illegalFieldModifiers | Specifies one or more groups of whitespace-delimited modifier | <<<null>>> | | | names (e.g. "public static" or "protected"). Multiple groups | | | | are separated by commas (e.g. "private final, protected"). | | | | If a field matches all of the modifiers in any group, then | | | | trigger a violation. If <<<null>>> or empty, skip this check. | | *--------------------------+----------------------------------------------------------------+------------------------+ | illegalMethodModifiers | Specifies one or more groups of whitespace-delimited modifier | <<<null>>> | | | names (e.g. "public static" or "protected"). Multiple groups | | | | are separated by commas (e.g. "private final, protected"). | | | | If a method matches all of the modifiers in any group, then | | | | trigger a violation. If <<<null>>> or empty, skip this check. | | *--------------------------+----------------------------------------------------------------+------------------------+ | illegalPropertyModifiers | Specifies one or more groups of whitespace-delimited modifier | <<<null>>> | | | names (e.g. "public static" or "protected"). Multiple groups | | | | are separated by commas (e.g. "private final, protected"). | | | | If a property matches all of the modifiers in any group, then | | | | trigger a violation. If <<<null>>> or empty, skip this check. | | *--------------------------+----------------------------------------------------------------+------------------------+ Modifiers for fields and methods include: * public * protected * private * static * final * volatile (fields only) * transient (fields only) Modifiers for properties are only: * static * final Note that you must use the standard rule properties, such as <<<applyToClassNames>>>, <<<doNotApplyToFileNames>>> and <<<applyToFilesMatching>>> to apply this rule to a subset of all classes/files. These rule properties are described in {{{./codenarc-configuring-rules.html#Standard_Properties_for_Configuring_Rules} Standard Properties for Configuring Rules}}. Example of violations for methods: ------------------------------------------------------------------------------- // IllegalClassMember.allowedMethodModifiers = 'public final, private, protected static' class MyClass { public method1() { } // violation protected method2() { } // violation protected static method3() { } } ------------------------------------------------------------------------------- Example of violations for properties: ------------------------------------------------------------------------------- // IllegalClassMember.illegalPropertyModifiers = 'final' class MyClass { def property1 final property2 // violation static property3 } ------------------------------------------------------------------------------- A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule <name> and <classNames>, and (optionally) customized <violationMessage> and <priority>. ** Notes ~~~~~~~~~~~~ [[1]] At least one the <<<illegalFieldModifiers>>>, <<<allowedFieldModifiers>>>, <<<illegalPropertyModifiers>>>, <<<allowedPropertyModifiers>>>, <<<illegalMethodModifiers>>> or <<<allowedMethodModifiers>>> properties must be set (i.e., not null or empty) or else this rule does nothing. In other words, you must configure this rule with at least one kind of illegal or allowed class member. [[2]] At least one of the (standard) <<<applyToClassNames>>>, <<<applyToFileNames>>> or <<<applyToFilesMatching>>> properties must be set (i.e., not null or empty) or else this rule does nothing. In other words, you must configure this rule to apply to a specific set of classes or files. * {IllegalClassReference} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks for reference to any of the classes configured in <<<classNames>>>. *---------------------+------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+------------------------------------------------------------------+------------------------+ | classNames | Specifies the comma-separated list of (fully-qualified) class | <<<null>>> | | | names. The class name(s) may optionally include wildcard | | | | characters ('*' or '?'). Note that the '*' wildcard matches any | | | | sequence of zero or more characters in the class/package name, | | | | e.g. 'a.*.MyClass' matches <<<a.b.MyClass>>> as well as | | | | <<<a.b.c.d.MyClass>>>. | | | | | | | | If <<<classNames>>> is null or empty, do nothing. | | *---------------------+------------------------------------------------------------------+------------------------+ Note that you can use the standard rule properties, such as <<<applyToClassNames>>>, <<<doNotApplyToFileNames>>> and <<<applyToFilesMatching>>> to only apply this rule to a subset of all classes/files. These rule properties are described in {{{./codenarc-configuring-rules.html#Standard_Properties_for_Configuring_Rules} Standard Properties for Configuring Rules}}. This rule can be useful for governance and enforcement of <architectural layering>. For instance, making sure that view or model classes, for instance, do not contain references to DAO classes (e.g., *Dao). Here is an example configuration of this rule used to ensure that DAO classes are not referenced from within model classes: +---------------------------------------------------------------------------------------- ruleset { description "Example CodeNarc Ruleset" // ... IllegalClassReference { name = 'DoNotReferenceDaoFromModelClasses' priority = 2 classNames = '*Dao' applyToClassNames = 'com.example.model.*' description = 'Do not reference DAOs from model classes.' } } +---------------------------------------------------------------------------------------- A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule <name> and <classNames>, and (optionally) customized <violationMessage> and <priority>. * {IllegalPackageReference} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.14> Checks for reference to any of the packages configured in <<<packageNames>>>. *---------------------+------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+------------------------------------------------------------------+------------------------+ | packageNames | Specifies the comma-separated list of package names. | <<<null>>> | | | The package name(s) may optionally include wildcard characters | | | | ('*' or '?'). Note that the '*' wildcard matches any sequence | | | | of zero or more characters in the package name, e.g. 'a.*' | | | | matches 'a.b' as well as 'a.b.c.d'. | | | | | | | | If <<<packageNames>>> is null or empty, do nothing. | | *---------------------+------------------------------------------------------------------+------------------------+ Note that you can use the standard rule properties, such as <<<applyToClassNames>>>, <<<doNotApplyToFileNames>>> and <<<applyToFilesMatching>>> to only apply this rule to a subset of all classes/files. These rule properties are described in {{{./codenarc-configuring-rules.html#Standard_Properties_for_Configuring_Rules} Standard Properties for Configuring Rules}}. This rule can be useful for governance and enforcement of <architectural layering>. For instance, making sure that view or model classes, for instance, do not contain references to JDBC-specific packages (e.g. java.sql and javax.sql). Here is an example configuration of this rule used to ensure that JDBC packages/classes are only referenced within DAO classes: +---------------------------------------------------------------------------------------- ruleset { description "Example CodeNarc Ruleset" // ... IllegalPackageReference { name = 'UseJdbcOnlyInDaoClasses' priority = 2 packageNames = 'groovy.sql, java.sql, javax.sql' doNotApplyToClassNames = 'com.example.framework.dao.*, *Dao, *DaoImpl' description = 'Reference to JDBC packages should be restricted to DAO classes.' } } +---------------------------------------------------------------------------------------- A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule <name> and <packageNames>, and (optionally) customized <violationMessage> and <priority>. * {IllegalRegex} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for a specified illegal regular expression within the source code. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | The regular expression to check for. If null or empty | <<<null>>> | | | then do nothing. | | *---------------------+----------------------------------------------------------------+------------------------+ A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule <name> and <regex>, and (optionally) customized <violationMessage> and <priority>. <<NOTE:>> This rule applies to the text contents of an entire <file> rather than a specific <class>, so it does not support the <applyToClassNames> and <doNotApplyToClassNames> configuration properties. * {IllegalString} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.20> Checks for a specified illegal string within the source code. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | string | The String to check for. If null or empty then do nothing. | <<<null>>> | *---------------------+----------------------------------------------------------------+------------------------+ A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule <name> and <string>, and (optionally) customized <violationMessage> and <priority>. <<NOTE:>> This rule applies to the text contents of an entire <file> rather than a specific <class>, so it does not support the <applyToClassNames> and <doNotApplyToClassNames> configuration properties. * {IllegalSubclass} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Checks for classes that extend one of the specified set of illegal superclasses. *---------------------+-----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+-----------------------------------------------------------------+------------------------+ | superclassNames | Specifies the comma-separated list of (fully-qualified) class | <<<null>>> | | | names. The class name(s) may optionally include wildcard | | | | characters ('*' or '?'). Note that the '*' wildcard matches any | | | | sequence of zero or more characters in the class/package name, | | | | e.g. 'a.*.MyClass' matches <<<a.b.MyClass>>> as well as | | | | <<<a.b.c.d.MyClass>>>. | | | | | | | | If <<<classNames>>> is null or empty, do nothing. | | *---------------------+-----------------------------------------------------------------+------------------------+ A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule <name> and <string>, and (optionally) customized <violationMessage> and <priority>. * {RequiredRegex} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for a specified regular expression that must exist within the source code. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | The regular expression to check for. If null or empty | <<<null>>> | | | then do nothing. | | *---------------------+----------------------------------------------------------------+------------------------+ A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule <name> and <regex>, and (optionally) customized <violationMessage> and <priority>. <<NOTE:>> This rule applies to the text contents of an entire <file> rather than a specific <class>, so it does not support the <applyToClassNames> and <doNotApplyToClassNames> configuration properties. * {RequiredString} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for a specified text string that must exist within the source code. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | string | The String to check for. If null or empty then do nothing. | <<<null>>> | *---------------------+----------------------------------------------------------------+------------------------+ A RuleSet can contain any number of instances of this rule, but each should be configured with a unique rule <name> and <string>, and (optionally) customized <violationMessage> and <priority>. <<NOTE:>> This rule applies to the text contents of an entire <file> rather than a specific <class>, so it does not support the <applyToClassNames> and <doNotApplyToClassNames> configuration properties. * {StatelessClass} Rule ~~~~~~~~~~~~~~~~~~~~~~ Checks for non-<<<final>>> fields on a class. The intent of this rule is to check a configured set of classes that should remain "stateless" and reentrant. One example might be Grails service classes which are singletons, by default, and so they should be reentrant. This rule ignores <<<final>>> fields (either instance or static). Fields that are <<<static>>> and non-<<<final>>>, however, do cause a violation. This rule also ignores all classes annotated with the <<<@Immutable>>> transformation. See {{{http://groovy.codehaus.org/Immutable+transformation}http://groovy.codehaus.org/Immutable+transformation}}. This rule also ignores all fields annotated with the <<<@Inject>>> annotation. You can configure this rule to ignore certain fields either by name or by type. This can be useful to ignore fields that hold references to (static) dependencies (such as DAOs or Service objects) or static configuration. *-----------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *-----------------------+----------------------------------------------------------------+------------------------+ | ignoreFieldNames | Specifies one or more (comma-separated) field names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *-----------------------+----------------------------------------------------------------+------------------------+ | addToIgnoreFieldNames | Specifies one or more (comma-separated) field names to be | <<<null>>> | | | added to the <<<ignoreFieldNames>>> property value. This is a | | | | special write-only property, and each call to | | | | <<<setAddIgnoreFieldNames()>>> adds to (rather than overwrites)| | | | the list of field names to be ignored. | | *-----------------------+----------------------------------------------------------------+------------------------+ | ignoreFieldTypes | Specifies one or more (comma-separated) field types that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | | | | | *-----------------------+----------------------------------------------------------------+------------------------+ Note that you can use the standard rule properties, such as <<<applyToClassNames>>>, <<<doNotApplyToFileNames>>> and <<<applyToFilesMatching>>> to only apply this rule to a subset of all classes/files. These rule properties are described in {{{./codenarc-configuring-rules.html#Standard_Properties_for_Configuring_Rules} Standard Properties for Configuring Rules}}. ** Notes ~~~~~~~~~~~~ [[1]] The <<<ignoreFieldTypes>>> property matches the field type name as indicated in the field declaration, only including a full package specification IF it is included in the source code. For example, the field declaration <<<BigDecimal value>>> matches an <<<ignoreFieldTypes>>> value of <<<BigDecimal>>>, but not <<<java.lang.BigDecimal>>>. [[2]] There is one exception for the <<<ignoreFieldTypes>>> property: if the field is declared with a modifier/type of <<<def>>>, then the type resolves to <<<java.lang.Object>>>. [[3]] At least one of the (standard) <<<applyToClassNames>>>, <<<applyToFileNames>>> or <<<applyToFilesMatching>>> properties must be set (i.e., not null or empty) or else this rule does nothing. In other words, you must configure this rule to apply to a specific set of classes or files. [[4]] This rule will not catch violations of true <statelessness>/<reentrancy> if you define a <<<final>>> field whose value is itself mutable, e.g. a <<<final HashMap>>>. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-unnecessary.apt�������������������������������������������0000644�0001750�0001750�00000126042�12415362504�022743� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Unnecessary Rules -------------------------------------------------- Unnecessary Rules ("<rulesets/unnecessary.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {AddEmptyString} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Finds empty string literals which are being added. This is an inefficient way to convert any type to a String. Examples: ------------------------------------------------------------------------------- // do not add empty strings to things def a = '' + 123 def b = method('' + property) // these examples are OK and do not trigger violations def c = 456.toString() def d = property?.toString() ?: "" ------------------------------------------------------------------------------- * {ConsecutiveLiteralAppends} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Violations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation. Example of violations: ------------------------------------------------------------------------------- writer.append('foo').append('bar') // strings can be joined writer.append('foo').append(5) // string and number can be joined writer.append('Hello').append("$World") // GString can be joined ------------------------------------------------------------------------------- Example of passing code: ------------------------------------------------------------------------------- // usage not chained invocation writer.append('Hello') writer.append('World') writer.append(null).append(5) // nulls cannot be joined writer.append().append('Hello') // no arg append is unknown writer.append('a', 'b').append('Hello') // two arg append is unknown ------------------------------------------------------------------------------- * {ConsecutiveStringConcatenation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Catches concatenation of two string literals on the same line. These can safely by joined. In Java, the Java compiler will join two String literals together and place them in the Constant Pool. However, Groovy will not because the plus() method may override the + operator. Examples: ------------------------------------------------------------------------------- // Violations def a = 'Hello' + 'World' // should be 'HelloWorld' def b = "$Hello" + 'World' // should be "${Hello}World" def c = 'Hello' + "$World" // should be "Hello${World}" def d = 'Hello' + 5 // should be 'Hello5' def e = 'Hello' + ''' world // should be joined ''' def f = '''Hello ''' + 'world' // should be joined // Not Violations def g = 'Hello' + // OK because of line break 'World' def h = 'Hello' + null // OK because not a string def i = 'Hello' + method() // OK because not a string def j = 'Hello' - "$World" // OK because not + ------------------------------------------------------------------------------- * {UnnecessaryBigDecimalInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> It is unnecessary to instantiate <<<BigDecimal>>> objects. Instead just use the decimal literal or the 'G' identifier to force the type, such as <<<123.45>>> or <<<123.45G>>>. This rule does not produce violations when the parameter evaluates to an integer/long, e.g. <<<new BigDecimal(42)>>>, <<<new BigDecimal(42L)>>> or <<<new BigDecimal("42")>>>, because using the "G" suffix on an integer value produces a <<<BigInteger>>>, rather than a <<<BigDecimal>>>, e.g. <<<45G>>>. So that means there is no way to produce a <<<BigDecimal>>> with exactly that value using a literal. This rule also does not produce violations when the parameter is a double, e.g. <<<new BigDecimal(12.3)>>>. That scenario is covered by the {{{./codenarc-rules-basic.html#BigDecimalInstantiation}BigDecimalInstantiation}} rule, because that produces an unpredictable (double) value (and so it is <unsafe>, rather than <unnecessary>). * {UnnecessaryBigIntegerInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> It is unnecessary to instantiate <<<BigInteger>>> objects. Instead just use the literal with the 'G' identifier to force the type, such as <<<8G>>> or <<<42G>>>. * {UnnecessaryBooleanExpression} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with <<<true>>>, <<<false>>>, <<<null>>>, or a Map/List/String/Number literal. This rule also checks for negation (!) of <<<true>>>, <<<false>>>, <<<null>>>, or a Map/List/String/Number literal. Examples of violations include: ------------------------------------------------------------------------------- result = value && true // AND or OR with boolean constants if (false || value) { .. } return value && Boolean.FALSE result = null && value // AND or OR with null result = value && "abc" // AND or OR with String literal result = value && 123 // AND or OR with Number literal result = 678.123 || true result = value && [x, y] // AND or OR with List literal result = [a:123] && value // AND or OR with Map literal result = !true // Negation of boolean constants result = !false result = !Boolean.TRUE result = !null // Negation of null result = !"abc" // Negation of String literal result = ![a:123] // Negation of Map literal result = ![a,b] // Negation of List literal ------------------------------------------------------------------------------- * {UnnecessaryBooleanInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12 (formerly BooleanInstantiation Rule in the "basic" rule set)> Checks for direct call to a <<<Boolean>>> constructor. Use <<<Boolean.valueOf()>>> or the <<<Boolean.TRUE>>> and <<<Boolean.FALSE>>> constants instead of calling the <<<Boolean()>>> constructor directly. Also checks for <<<Boolean.valueOf(true)>>> or <<<Boolean.valueOf(false)>>>. Use the <<<Boolean.TRUE>>> or <<<Boolean.FALSE>>> constants instead. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def b1 = new Boolean(true) // violation def b2 = new java.lang.Boolean(false) // violation def b3 = Boolean.valueOf(true) // violation def b4 = Boolean.valueOf(false) // violation ------------------------------------------------------------------------------- * {UnnecessaryCallForLastElement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> This rule checks for excessively verbose methods of accessing the last element of an array or list. For instance, it is possible to access the last element of an array by performing <<<array[array.length - 1]>>>, in Groovy it is simpler to either call <<<array.last()>>> or <<<array[-1]>>>. The same is true for lists. This violation is triggered whenever a <<<get>>>, <<<getAt>>>, or array-style access is used with an object size check. Code like this all cause violations. ------------------------------------------------------------------------------- def x = [0, 1, 2] def a = x.get(x.size() -1) def b = x.get(x.length -1) def c = x.getAt(x.size() -1) def d = x.getAt(x.length -1) def f = x[(x.size() -1] def d = x[(x.length -1] ------------------------------------------------------------------------------- All of this code is fine though: ------------------------------------------------------------------------------- def x = [0, 1, 2] def a = x.last() def b = x[-1] def c = x.getAt(-1) def d = x.get(z.size() -1) // different objects def e = x.get(z.length -1) // different objects def f = x.getAt(z.size() -1) // different objects ------------------------------------------------------------------------------- * {UnnecessaryCallToSubstring} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Calling String.substring(0) always returns the original string. This code is meaningless. Examples: ------------------------------------------------------------------------------- string.substring(0) // violation method().substring(0) // violation prop.substring(1) // OK, not constant 0 prop.substring(0, 1) // OK, end is specified ------------------------------------------------------------------------------- * {UnnecessaryCast} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Checks for unnecessary cast operations. Example of violations: ------------------------------------------------------------------------------- int count = (int)123 // violation def longValue = (long)123456L // violation def bigDecimal = (BigDecimal)1234.56 // violation String name = (String) "Joe" // violation def list = (List)[1, 2, 3] // violation def map = (Map)[a:1] // violation ------------------------------------------------------------------------------- * {UnnecessaryCatchBlock} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Violations are triggered when a <catch> block does nothing but throw the original exception. In this scenario there is usually no need for a <catch> block, just let the exception be thrown from the original code. This condition frequently occurs when catching an exception for debugging purposes but then forgetting to take the <<<catch>>> statement out. * {UnnecessaryCollectCall} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Some method calls to <<<Object.collect(Closure)>>> can be replaced with the spread operator. For instance, <<<list.collect { it.multiply(2) }>>> can be replaced by <<<list*.multiply(2)>>>. Examples of violations include: ------------------------------------------------------------------------------- assert [1, 2, 3].collect { it.multiply(2) } assert [1, 2, 3].collect { x -> x.multiply(2) } ["1", "2", "3"].collect { it.bytes } ------------------------------------------------------------------------------- The following code does not produce violations: ------------------------------------------------------------------------------- [1, 2, 3].collect { it * it } // OK, closure parameter is referenced twice [1, 2, 3].mapMethod { it.multiply(5) } // OK, method call is not collect [1, 2, 3].collect(5) // OK, collect parameter is not a closure // OK, the closure is not a simple one line statement [1, 2, 3].collect { println it; it.multiply(5) } // OK, closure has too many arguments [1, 2, 3].collect { a, b -> a.multiply(b) } // OK, closure statement references parameter multiple times [1, 2, 3].collect { it.multiply(it) } // OK, it is referenced several times in the closure [1, 2, 3].collect { it.multiply(2).multiply(it) } ["1", "2", "3"].collect { it.bytes.foo(it) } // OK, chained methods are too complex to analyze at this point [1, 2, 3].collect { it.multiply(2).multiply(4) } // in general the above examples can be rewritten like this: [1, 2, 3]*.multiply(2) ["1", "2", "3"]*.bytes ------------------------------------------------------------------------------- * {UnnecessaryCollectionCall} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Checks for useless calls to collections. For any collection <<<c>>>, calling <<<c.containsAll(c)>>> should always be <<<true>>>, and <<<c.retainAll(c)>>> should have no effect. * {UnnecessaryConstructor} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's <<<public>>>, has an empty body, and takes no arguments, or else contains only a single call to <<<super()>>>. Example of violations: ------------------------------------------------------------------------------- class MyClass { public MyClass() { // violation; constructor is not necessary } } class MyClass2 extends OtherClass { MyClass2() { // violation; constructor is not necessary super() } } ------------------------------------------------------------------------------- * {UnnecessaryDefInFieldDeclaration} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> If a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}. Example of violations: ------------------------------------------------------------------------------- class MyClass { // def is redundant static def constraints = { } // def and private is redundant def private field1 = { } // def and protected is redundant def protected field2 = { } // def and public is redundant def public field3 = { } // def and static is redundant def static field4 = { } // def and type is redundant def Object field5 = { } } ------------------------------------------------------------------------------- * {UnnecessaryDefInMethodDeclaration} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> If a method has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'. Examples of violations: ------------------------------------------------------------------------------- // def and private is redundant def private method1() { return 4 } // def and protected is redundant def protected method2() { return 4 } // def and public is redundant def public method3() { return 4 } // def and static is redundant def static method4() { return 4 } // def and type is redundant def Object method5() { return 4 } class MyClass { def MyClass() {} // def is redundant } ------------------------------------------------------------------------------- * {UnnecessaryDefInVariableDeclaration} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> If a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'. Examples of violations: ------------------------------------------------------------------------------- // def and private is redundant def private string1 = 'example' // def and protected is redundant def protected string2 = 'example' // def and public is redundant def public string3 = 'example' // def and static is redundant def static string4 = 'example' // def and final is redundant def final string5 = 'example' // def and a type is redundant def String string6 = 'example' ------------------------------------------------------------------------------- * {UnnecessaryDotClass} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> To make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String. Example of violations: ------------------------------------------------------------------------------- // The '.class' identifier is unnecessary, violation occurs def x = String.class // Ok, unnecessary '.class' identifier has been excluded def x = String ------------------------------------------------------------------------------- * {UnnecessaryDoubleInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> It is unnecessary to instantiate <<<Double>>> objects. Instead just use the double literal with 'D' identifier to force the type, such as <<<123.45d>>> or <<<0.42d>>>. * {UnnecessaryElseStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> When an <<<if>>> statement block ends with a <<<return>>> statement, then the <<<else>>> is unnecessary. The logic in the <<<else>>> branch can be run without being in a new scope. Example of violations: ------------------------------------------------------------------------------- if(value){ println 'Executing if logic...' return true } else { println 'Executing else logic...' } // can be replaced by: if(value){ println 'Executing if logic...' return true } println 'Executing else logic...' ------------------------------------------------------------------------------- * {UnnecessaryFinalOnPrivateMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> A private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary. Example of violations: ------------------------------------------------------------------------------- private final method() {} ------------------------------------------------------------------------------- * {UnnecessaryFloatInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> It is unnecessary to instantiate <<<Float>>> objects. Instead just use the float literal with the 'F' identifier to force the type, such as <<<123.45F>>> or <<<0.42f>>>. * {UnnecessaryGetter} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Checks for explicit calls to getter/accessor methods which can, for the most part, be replaced by property access. A getter is defined as a method call that matches <<<get[A-Z]>>> but not <<<getClass()>>> or <<<get[A-Z][A-Z]>>> such as <<<getURL()>>>. Getters do not take method arguments. These bits of code produce violations: ------------------------------------------------------------------------------- x.getProperty() x.getFirst() x.getFirstName() x.getA() ------------------------------------------------------------------------------- These bits of code do not: ------------------------------------------------------------------------------- x.property x.first x.firstName x.a x.getURL() x.getClass() x.getProperty('key') ------------------------------------------------------------------------------- * {UnnecessaryGString} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> String objects should be created with single quotes, and GString objects created with double quotes. Creating normal String objects with double quotes is confusing to readers. Example of violations: ------------------------------------------------------------------------------- def a = "I am a string" // violation // violation def b = """ I am a string """ def c = "I am a ' string" // OK def d = """I am a ' string""" // OK def e = """I am a ' string""" // OK def f = "I am a \$ string" // OK // OK def g = """ I am a \$ string """ // OK def h = """ I am a $string """ def i = 'i am a string' def j = '''i am a string ''' ------------------------------------------------------------------------------- * {UnnecessaryIfStatement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for unnecessary <<if>> statements. The entire <<if>> statement, or at least the <if> or <else> block, are considered unnecessary for the four scenarios described below. (1) When the <if> and <else> blocks contain only an explicit return of <<<true>>> and <<<false>>> constants. These cases can be replaced by a simple <return> statement. Examples of violations include: ------------------------------------------------------------------------------- if (someExpression) // can be replaced by: return someExpression return true else return false if (someExpression) { // can be replaced by: return !someExpression return false } else { return true } if (someExpression) { // can be replaced by: return someExpression return Boolean.TRUE } else { return Boolean.FALSE } ------------------------------------------------------------------------------- (2) When the <<<if>>> statement is the last statement in a block and the <if> and <else> blocks are only <<<true>>> and <<<false>>> expressions. This is an <implicit> return of <<<true>>>/<<<false>>>. For example, the <<<if>>> statement in the following code can be replaced by <<<someExpression>>> or <<<someExpression as boolean>>>: ------------------------------------------------------------------------------- def myMethod() { doSomething() if (someExpression) true else false } ------------------------------------------------------------------------------- (3) When the second-to-last statement in a block is an <<<if>>> statement with no <<<else>>>, where the block contains a single <<<return>>> statement, and the last statement in the block is a <<<return>>> statement, and one <<<return>>> statement returns a <<<true>>> expression and the other returns a <<<false>>> expression. This check is disabled by setting <<<checkLastStatementImplicitElse>>> to <<<false>>>. For example, the <<<if>>> statement in the following code can be replaced by <<<return expression1>>>: ------------------------------------------------------------------------------- def myMethod() { doSomething() if (expression1) { return true } return false } ------------------------------------------------------------------------------- (4) When either the <if> block or <else> block of an <<<if>>> statement that is not the last statement in a block contain only a single constant or literal expression. For example, the <<<if>>> statement in the following code has no effect and can be removed: ------------------------------------------------------------------------------- def myMethod() { if (someExpression) { 123 } doSomething() } ------------------------------------------------------------------------------- * {UnnecessaryInstanceOfCheck} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> This rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that <<<(!variable instanceof String)>>> will never be true because the result of a not expression is always a boolean. Example of violations: ------------------------------------------------------------------------------- if (!variable instanceof String) { ... } // always false def x = !variable instanceof String // always false if (!variable instanceof Boolean) { ... } // always true def x = !variable instanceof Boolean // always true // this code is OK if (!(variable instanceof String)) { ... } ------------------------------------------------------------------------------- * {UnnecessaryInstantiationToGetClass} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since in CodeNarc 0.12> Avoid instantiating an object just to call getClass() on it; use the .class public member instead. ------------------------------------------------------------------------------- public class Foo { // Replace this Class c = new String().getClass(); // with this: Class c = String.class; } ------------------------------------------------------------------------------- * {UnnecessaryIntegerInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> It is unnecessary to instantiate <<<Integer>>> objects. Instead just use the literal with the 'I' identifier to force the type, such as <<<8I>>> or <<<42i>>>. * {UnnecessaryLongInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> It is unnecessary to instantiate <<<Long>>> objects. Instead just use the literal with the 'L' identifier to force the type, such as <<<8L>>> or <<<42L>>>. * {UnnecessaryModOne} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Any expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2). Examples: ------------------------------------------------------------------------------- if (exp % 1) {} // violation if (method() % 1) {} // violation if (exp & 1) {} // ok if (exp % 2) {} // ok ------------------------------------------------------------------------------- * {UnnecessaryObjectReferences} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Violations are triggered when an excessive set of consecutive statements all reference the same variable. This can be made more readable by using a <<<with>>> or <<<identity>>> block. By default, 5 references are allowed. You can override this property using the <<maxReferencesAllowed>>> property on the rule. These two bits of code produce violations: ------------------------------------------------------------------------------- def p1 = new Person() p1.firstName = 'Hamlet' p1.lastName = "D'Arcy" p1.employer = 'Canoo' p1.street = 'Kirschgaraten 5' p1.city = 'Basel' p1.zipCode = '4051' def p2 = new Person() p2.setFirstName('Hamlet') p2.setLastName("D'Arcy") p2.setEmployer('Canoo') p2.setStreet('Kirschgaraten 5') p2.setCity('Basel') p2.setZipCode('4051') ------------------------------------------------------------------------------- However, these two bits of code do not because they use either a <<<with>>> or <<<identity>>> block. ------------------------------------------------------------------------------- def p1 = new Person().with { firstName = 'Hamlet' lastName = "D'Arcy" employer = 'Canoo' street = 'Kirschgaraten 5' city = 'Basel' zipCode = '4051' } def p2 = new Person().identity { firstName = 'Hamlet' lastName = "D'Arcy" employer = 'Canoo' street = 'Kirschgaraten 5' city = 'Basel' zipCode = '4051' } ------------------------------------------------------------------------------- * {UnnecessaryNullCheck} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Groovy contains the safe dereference operator. It can be used in boolean conditional statements to safely replace explicit <<<x == null>>> tests. Also, testing the 'this' or 'super' reference for null equality is pointless and can be removed. Examples of violations: ------------------------------------------------------------------------------- if (obj != null && obj.method()) { } if (obj != null && obj.prop) { } // this is pointless and won't avoid NullPointerException if (obj.method() && obj != null ) { } if (this == null) { } if (null == this) { } if (this != null) { } if (null != this) { } if (super == null) { } if (null == super) { } if (super != null) { } if (null != super) { } ------------------------------------------------------------------------------- Examples of acceptable code: ------------------------------------------------------------------------------- // null check it OK if (obj != null) { } // null safe dereference in if is OK if (obj?.method()) { } // null safe dereference in ternary is OK (obj?.prop && obj?.prop2) ? x : y // obj is reused in a parameter list, so OK if (obj != null && obj.method() && isValid(obj)) { } // rule is not so complex yet... (obj != null && obj.prop && obj.method()) ? x : y ------------------------------------------------------------------------------- * {UnnecessaryNullCheckBeforeInstanceOf} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> There is no need to check for null before an instanceof; the instanceof keyword returns false when given a null argument. Example: ------------------------------------------------------------------------------- if (x != null && x instanceof MyClass) { // should drop the "x != null" check } if (x instanceof MyClass && x != null) { // should drop the "x != null" check } // should drop the "x != null" check (x != null && x instanceof MyClass) ? foo : bar if (x != null && x instanceof MyClass && x.isValid()) { // this is OK and causes no violation because the x.isValid() requires a non null reference } ------------------------------------------------------------------------------- * {UnnecessaryOverridingMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Checks for an overriding method that merely calls the same method defined in a superclass. Remove it. * {UnnecessaryPackageReference} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.14> Checks for explicit package reference for classes that Groovy imports by default, such as <<<java.lang.String>>>, <<<java.util.Map>>> and <<<groovy.lang.Closure>>>, as well as classes that were explicitly imported. You do not need to specify the package for any classes from <java.lang>, <java.util>, <java.io>, <java.net>, <groovy.lang> and <groovy.util>, as well as the classes <java.math.BigDecimal> and <java.math.BigInteger>. Examples of violations include: ------------------------------------------------------------------------------- // Field types class MyClass { java.math.BigDecimal amount = 42.10 // violation } // Within expressions if (value.class == java.math.BigInteger) { } // violation println "isClosure=${v instanceof groovy.lang.Closure}" // violation def p = java.lang.Runtime.availableProcessors() // violation // Constructor calls def url = new java.net.URL('http://abc@example.com') // violation // Variable types void doSomething() { java.math.BigInteger maxValue = 0 // violation java.net.URI uri // violation } // Method return types java.io.Reader getReader() { } // violation groovy.util.AntBuilder getAntBuilder() { } // violation // Method parameter types void writeCount(java.io.Writer writer, int count) { } // violation void init(String name, groovy.lang.Binding binding) { } // violation // Closure parameter types def writeCount = { java.io.Writer writer, int count -> } // violation // Extends and implements class MyHashMap extends java.util.HashMap { } // violation class MyList implements java.util.List { } // violation // Explicitly imported classes import javax.servlet.http.Cookie import javax.sql.DataSource class MyClass { void doStuff(javax.servlet.http.Cookie cookie) { // violation def dataSource = [:] as javax.sql.DataSource // violation } } ------------------------------------------------------------------------------- Known limitations: * Does not catch class declarations that explicitly extend <<<java.lang.Object>>>. For instance, <<<class MyClass extends java.lang.Object { }>>>. Just don't do that, okay? * Does not catch class declarations that explicitly extend <<<groovy.lang.Script>>>. For instance, <<<class MyScript extends groovy.lang.Script{ }>>>. Don't do that, either! * Does not catch unnecessary package references if they are the types of anonymous inner class definitions, for older versions of Groovy (< 1.7.10?). For instance, <<<def runnable = new java.lang.Runnable() { ... }>>>. * {UnnecessaryParenthesesForMethodCallWithClosure} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> If a method is called and the only parameter to that method is an inline closure then the parentheses of the method call can be omitted. Example of violations: ------------------------------------------------------------------------------- [1,2,3].each() { println it } ------------------------------------------------------------------------------- * {UnnecessaryPublicModifier} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> The 'public' modifier is not required on methods, constructors or classes. Example of violations: ------------------------------------------------------------------------------- // violation on class public class MyClass { // violation on constructor public MyClass() {} // violation on method public void myMethod() {} } ------------------------------------------------------------------------------- * {UnnecessaryReturnKeyword} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> In Groovy, the <<<return>>> keyword is often optional. If a statement is the last line in a method or closure then you do not need to have the <<<return>>> keyword. * {UnnecessarySafeNavigationOperator} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.22> Check for the <safe navigation> operator (<<<?.>>>) applied to constants and literals, or <<<this>>> or <<<super>>>, or constructor calls, all of which can never be null. Example of violations: ------------------------------------------------------------------------------- def myMethod() { "abc"?.bytes // violation [1,2]?.getSize() // violation [abc:123]?.name // violation [:]?.toString() // violation 123?.class // violation 123.45?.getClass() // violation Boolean.FALSE?.class // violation Boolean.TRUE?.class // violation this?.class // violation super?.getClass() // violation new Long(100)?.class // violation } ------------------------------------------------------------------------------- * {UnnecessarySelfAssignment} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Method contains a pointless self-assignment to a variable or property. Either the code is pointless or the equals()/get() method has been overridden to have a side effect, which is a terrible way to code getters and violates the contract of equals(). Examples: ------------------------------------------------------------------------------- x = x // violation def method(y) { y = y // violation } a.b.c = a.b.c // violation x = y // acceptable a.b = a.zz // acceptable a.b = a().b // acceptable ------------------------------------------------------------------------------- * {UnnecessarySemicolon} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Semicolons as line terminators are not required in Groovy: remove them. Do not use a semicolon as a replacement for empty braces on for and while loops; this is a confusing practice. The rule contains a String property called 'excludePattern'. Any source code line matching this pattern will not trigger a violation. The default value is '\\s?\\*.*|/\\*.*|.*//.*|.*\\*/.*' This is to filter out comments. Any source line that even looks like it is a comment is ignored. \s?\*.* == whitespace plus star character plus anything /\*.* == any line that contains the /* sequence .*//.* == any line that contains the // sequence .*\*/.* == any line that contains the */ sequence Example of violations: ------------------------------------------------------------------------------- package my.company.server; // violation import java.lang.String; // violation println(value) ; // violation for (def x : list); // violation // this code is OK println(value); println (otherValue) ------------------------------------------------------------------------------- * {UnnecessarySubstring} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> This rule finds usages of <<<String.substring(int)>>> and <<<String.substring(int, int)>>> that can be replaced by use of the subscript operator. For instance, <<<var.substring(5)>>> can be replaced with <<<var[5..-1]>>>. Note that the String.substring(beginIndex,endIndex) method specifies a range of beginIndex..endIndex-1, while Groovy's String subscript specifies an inclusive range. So, <<<"123456".substring(1, 5)>>> is equivalent to <<<"123456"[1..4]>>>. Example of violations: ------------------------------------------------------------------------------- myVar.substring(5) // can use myVar[5..-1] instead myVar.substring(1, 5) // can use myVar[1..4] instead ------------------------------------------------------------------------------- * {UnnecessaryStringInstantiation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12 (formerly StringInstantiation Rule in the "basic" rule set)> Checks for direct call to the <<<String>>> constructor that accepts a <<<String>>> literal. In almost all cases, this is unnecessary. Use a <<<String>>> literal (e.g., "...") instead of calling the corresponding <<<String>>> constructor (<<<new String("..")>>>) directly. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def s = new String('abc') ------------------------------------------------------------------------------- * {UnnecessaryTernaryExpression} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for ternary expressions where the conditional expression always evaluates to a boolean and the <true> and <false> expressions are merely returning <<<true>>> and <<<false>>> constants. These cases can be replaced by a simple boolean expression. Examples of violations include: ------------------------------------------------------------------------------- x==99 ? true : false // can be replaced by: x==99 x && y ? true : false // can be replaced by: x && y x||y ? false : true // can be replaced by: !(x||y) x >= 1 ? true: false // can be replaced by: x >= 1 x < 99 ? Boolean.TRUE : Boolean.FALSE // can be replaced by: x < 99 !x ? true : false // can be replaced by: !x ------------------------------------------------------------------------------- The rule also checks for ternary expressions where the <true> and <false> expressions are the same constant or variable. Examples include: ------------------------------------------------------------------------------- x ? '123' : '123' // can be replaced by: '123' x ? null : null // can be replaced by: null x ? 23 : 23 // can be replaced by: 23 x ? MAX_VALUE : MAX_VALUE // can be replaced by: MAX_VALUE ready ? minValue : minValue // can be replaced by: minValue ------------------------------------------------------------------------------- * {UnnecessaryTransientModifier} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> The field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect. This may be leftover marking from a previous version of the code in which the class was transient, or it may indicate a misunderstanding of how serialization works. Some Java frameworks change the semantics of the transient keyword. For instance, when using Terracotta the transient keyword may have slightly different semantics. You may need to turn this rule off depending on which Java frameworks are in use. Examples: ------------------------------------------------------------------------------- class MyClass { // class not serializable, violation occurs transient String property } class MySerializableClass implements Serializable { // OK, class is serializable transient String property } ------------------------------------------------------------------------------- * {UnnecessaryToString} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Checks for unnecessary calls to <<<toString()>>>. This includes: * Calls to <<<toString()>>> on a String literal or expression * Calls to <<<toString()>>> for the value assigned to a <<<String>>> field or variable (if <checkAssignments> is <<<true>>>). [] *------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *------------------+----------------------------------------------------------------+------------------------+ | checkAssignments | If <<<true>>>, then check for calls to <<<toString()>>> for | <<<true>>> | | | the value assigned to a <<<String>>> field or variable. | | *------------------+----------------------------------------------------------------+------------------------+ Example of violations: ------------------------------------------------------------------------------- def name = "Joe".toString() // violation - string literal def groupId = ((String)row.get('GroupID')).toString() // violation - string expression class MyClass { String name = nameNode.toString() // violation - field String code = account.getCode().toString() // violation - field void run() { String name = nameNode.toString() // violation - variable String id = account.id.toString() // violation - variable } } ------------------------------------------------------------------------------- ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-naming.apt������������������������������������������������0000644�0001750�0001750�00000057237�12407677434�021702� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Naming Rules -------------------------------------------------- Naming Rules ("<rulesets/naming.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {AbstractClassName} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~ Verifies that the name of an abstract class matches the regular expression specified in the <<regex>> property. If that property is null or empty, then this rule is not applied (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. This rule ignores interfaces and is applied only to abstract classes. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | Specifies the regular expression used to validate the abstract | <<<null>>> | | | class name. If null or empty, then this rule does nothing. | | *---------------------+----------------------------------------------------------------+------------------------+ * {ClassName} Rule ~~~~~~~~~~~~~~~~~ Verifies that the name of a class matches a regular expression. By default it checks that the class name starts with an uppercase letter and is followed by zero or more word characters (letters, numbers or underscores) or dollar signs ($). *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | Specifies the regular expression used to validate the class | /([A-Z]\w*\$?)*/ | | | name. It is required and cannot be null or empty. | | *---------------------+----------------------------------------------------------------+------------------------+ * {ClassNameSameAsFilename} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Reports files containing only one top level class / enum / interface which is named differently than the file. * {ConfusingMethodName} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Checks for very confusing method names. The referenced methods have names that differ only by capitalization. This is very confusing because if the capitalization were identical then one of the methods would override the other. Also, violations are triggered when methods and fields have very similar names. ------------------------------------------------------------------------------- class MyClass { int total int total() { 1 } } ------------------------------------------------------------------------------- * {FactoryMethodName} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.16> A factory method is a method that creates objects, and they are typically named either buildFoo(), makeFoo(), or createFoo(). This rule enforces that only one naming convention is used. It defaults to allowing makeFoo(), but that can be changed using the property <<<regex>>>. The regex is a negative expression; it specifically bans methods named build* or create*. However, methods named build or build* receive some special treatment because of the popular Builder Pattern. If the 'build' method is in a class named *Builder then it does not cause a violation. Builder methods are slightly different than factory methods. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | Specifies the default regular expression used to validate the | /(build.*\|create.*)/ | | | method name. It is required and cannot be null or empty. | | *---------------------+----------------------------------------------------------------+------------------------+ Example of violations: ------------------------------------------------------------------------------- class MyClass { // violation. Factory methods should be named make() def create() { } // violation. Factory methods should be named make() def createSomething() { } // violation. Builder method not in class named *Builder def build() { } // violation. Builder method not in class named *Builder def buildSomething() { } // this is OK because it is called make def make() { } // this is also OK def makeSomething() { } // OK, overriding a parent @Override build() { } } class WidgetBuilder { // OK, the class name ends in Builder def build() { } } ------------------------------------------------------------------------------- * {FieldName} Rule ~~~~~~~~~~~~~~~~~ Verifies that the name of each field matches a regular expression. By default it checks that fields that are not <static final> have field names that start with a lowercase letter and contains only letters or numbers. By default, <static final> field names start with an uppercase letter and contain only uppercase letters, numbers and underscores. <<NOTE:>> This rule checks only regular <fields> of a class, not <properties>. In Groovy, <properties> are fields declared with no access modifier (public, protected, private). Thus, this rule only checks fields that specify an access modifier. For naming of <properties>, see <<<PropertyNameRule>>>. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | Specifies the default regular expression used to validate the | /[a-z][a-zA-Z0-9]*/ | | | field name. It is required and cannot be null or empty. | | *---------------------+----------------------------------------------------------------+------------------------+ | finalRegex | Specifies the regular expression used to validate <<<final>>> | <<<null>>> | | | field names. It is optional. If not set, then <<<final>>> | | | | fields that are non-<<<static>>> are validated using <<regex>>.| | *---------------------+----------------------------------------------------------------+------------------------+ | staticRegex | Specifies the regular expression used to validate <<<static>>> | <<<null>>> | | | field names. It is optional. If not set, then <<<static>>> | | | | fields that are non-<<<final>>> are validated using <<regex>>. | | *---------------------+----------------------------------------------------------------+------------------------+ | staticFinalRegex | Specifies the regular expression used to validate | /[A-Z][A-Z0-9_]*/ | | | <<<static final>>> field names. It is optional. If not set, | | | | then <<<static final>>> fields are validated using | | | | <<finalRegex>>, <<staticRegex>> or <<regex>>. | | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreFieldNames | Specifies one or more (comma-separated) field names that | serialVersionUID | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ The order of precedence for the regular expression properties is: <<staticFinalRegex>>, <<finalRegex>>, <<staticRegex>> and finally <<regex>>. In other words, the first regex in that list matching the modifiers for the field is the one that is applied for the field name validation. * {InterfaceName} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~ Verifies that the name of an interface matches the regular expression specified in the <<regex>> property. If that property is null or empty, then this rule is not applied (i.e., it does nothing). It defaults to null, so this rule must be explicitly configured to be active. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | Specifies the regular expression used to validate the name of | <<<null>>> | | | an interface. If null or empty, then this rule does nothing. | | *---------------------+----------------------------------------------------------------+------------------------+ * {MethodName} Rule ~~~~~~~~~~~~~~~~~~ Verifies that the name of each method matches a regular expression. By default it checks that the method name starts with a lowercase letter. Implicit method names are ignored (i.e., 'main' and 'run' methods automatically created for Groovy scripts). *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | Specifies the regular expression used to validate the method | /[a-z]\w*/ | | | name. It is required and cannot be null or empty. | | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodNames | Specifies one or more (comma-separated) method names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ * {ObjectOverrideMisspelledMethodName} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Verifies that the names of the most commonly overridden methods of <<<Object>>>: <<<equals>>>, <<<hashCode>>> and <<<toString>>>, are correct. Here are some examples of code that produces violations: ------------------------------------------------------------------------------- boolean equal(Object o) {} // violation boolean equal(int other) {} // ok; wrong param type boolean equal(Object o, int other) {} // ok; too many params boolean equaLS(Object o) {} // violation int hashcode() {} // violation int hashCOde() {} // violation int hashcode(int value) {} // ok; not empty params String tostring() {} // violation String toSTring() {} // violation String tostring(int value) {} // ok; not empty params ------------------------------------------------------------------------------- * {PackageName} Rule ~~~~~~~~~~~~~~~~~~~ Verifies that the package name of a class matches a regular expression. By default it checks that the package name consists of only lowercase letters and numbers, separated by periods. *---------------------+----------------------------------------------------------------+---------------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+---------------------------------+ | regex | Specifies the regular expression used to validate the package | /[a-z]+[a-z0-9]*(\.[a-z0-9]+)*/ | | | name. It is required and cannot be null or empty. | | *---------------------+----------------------------------------------------------------+---------------------------------+ | packageNameRequired | Indicates whether a package name declaration is required for | <<<false>>> | | | all classes. | | *---------------------+----------------------------------------------------------------+---------------------------------+ * {PackageNameMatchesFilePath} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.22> A package source file's path should match the package declaration. *---------------------+----------------------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------------------------+------------------------+ | groupId | Specifies the common <group id> part of a package name, that will appear within | <<<null>>> | | | all checked package names. It must also map to the file path for the corresponding| | | | source file. | | | | | | | | For instance, a <groupId> of <"org.sample"> means that for all classes that | | | | specify a package, that package name must include <"org.sample">, and the source | | | | file must exist under an "org/sample" directory. Then, a <<<MyClass>>> class in a| | | | <<<org.sample.util>>> package must be defined in a "MyClass.groovy" file within | | | | a <"org/sample/util"> directory. That directory can be the child of any arbitrary| | | | <root path>, e.g. "src/main/groovy". | | | | | | | | To find the sub-path relevant for the package the rule searches for the first | | | | appearance of <groupId> in the file path. It's <required> to configure this. | | | | | | | | If <<<groupId>>> is null or empty, this rule does nothing. | | *---------------------+----------------------------------------------------------------------------------+------------------------+ * {ParameterName} Rule ~~~~~~~~~~~~~~~~~~~~~ Verifies that the name of each parameter matches a regular expression. This rule applies to method parameters, constructor parameters and closure parameters. By default it checks that parameter names start with a lowercase letter and contains only letters or numbers. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | Specifies the regular expression used to validate the parameter| /[a-z][a-zA-Z0-9]*/ | | | name. It is required and cannot be null or empty. | | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreParameterNames| Specifies one or more (comma-separated) parameter names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ * {PropertyName} Rule ~~~~~~~~~~~~~~~~~~~~ Verifies that the name of each property matches a regular expression. By default it checks that property names (other than <static final>) start with a lowercase letter and contains only letters or numbers. By default, <static final> property names start with an uppercase letter and contain only uppercase letters, numbers and underscores. <<NOTE:>> This rule checks only <properties> of a class, not regular <fields>. In Groovy, <properties> are fields declared with no access modifier (public, protected, private). For naming of regular <fields>, see <<<FieldNameRule>>>. *---------------------+--------------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+--------------------------------------------------------------------+------------------------+ | regex | Specifies the default regular expression used to validate the | /[a-z][a-zA-Z0-9]*/ | | | property name. It is required and cannot be null or empty. | | *---------------------+--------------------------------------------------------------------+------------------------+ | finalRegex | Specifies the regular expression used to validate <<<final>>> | <<<null>>> | | | property names. It is optional. If not set, then <<<final>>> | | | | properties that are non-<<<static>>> are validated using <<regex>>.| | *---------------------+--------------------------------------------------------------------+------------------------+ | staticRegex | Specifies the regular expression used to validate <<<static>>> | <<<null>>> | | | property names. It is optional. If not set, then <<<static>>> | | | | properties that are non-<<<final>>> are validated using <<regex>>. | | *---------------------+--------------------------------------------------------------------+------------------------+ | staticFinalRegex | Specifies the regular expression used to validate | /[A-Z][A-Z0-9_]*/ | | | <<<static final>>> property names. It is optional. If not set, | | | | then <<<static final>>> property are validated using | | | | <<finalRegex>>, <<staticRegex>> or <<regex>>. | | *---------------------+--------------------------------------------------------------------+------------------------+ | ignorePropertyNames | Specifies one or more (comma-separated) property names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+--------------------------------------------------------------------+------------------------+ The order of precedence for the regular expression properties is: <<staticFinalRegex>>, <<finalRegex>>, <<staticRegex>> and finally <<regex>>. In other words, the first regex in that list matching the modifiers for the property is the one that is applied for the field name validation. * {VariableName} Rule ~~~~~~~~~~~~~~~~~~~~ Verifies that the name of each variable matches a regular expression. By default it checks that non-<<<final>>> variable names start with a lowercase letter and contains only letters or numbers. By default, <<<final>>> variable names start with an uppercase letter and contain only uppercase letters, numbers and underscores. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | regex | Specifies the default regular expression used to validate the | /[a-z][a-zA-Z0-9]*/ | | | variable name. It is required and cannot be null or empty. | | *---------------------+----------------------------------------------------------------+------------------------+ | finalRegex | Specifies the regular expression used to validate <<<final>>> | /[A-Z][A-Z0-9_]*/ | | | variable names. It is optional. If not set, then <<regex>> is | | | | used to validate <<<final>>> variable names. | | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreVariableNames | Specifies one or more (comma-separated) variable names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-braces.apt������������������������������������������������0000644�0001750�0001750�00000003263�12006632016�021634� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Braces Rules -------------------------------------------------- Braces Rules ("<rulesets/braces.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {ElseBlockBraces} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks that <else> blocks use braces, even for a single statement. By default, braces are not required for an <else> if it is followed immediately by an <if>. Set the <bracesRequiredForElseIf> property to true to require braces is that situation as well. *-------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *-------------------------+----------------------------------------------------------------+------------------------+ | bracesRequiredForElseIf | Set to <<<true>>> to require braces for an <else> block | <<<false>>> | | | followed immediately by an <if> statement. | | *-------------------------+----------------------------------------------------------------+------------------------+ * {ForStatementBraces} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks that <for> statements use braces, even for a single statement. * {IfStatementBraces} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks that <if> statements use braces, even for a single statement. * {WhileStatementBraces} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks that while statements use braces, even for a single statement. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-enhanced.apt����������������������������������������������0000644�0001750�0001750�00000006467�12414275063�022163� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Enhanced Classpath Rules -------------------------------------------------- Enhanced Classpath Rules ("<rulesets/enhanced.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These rules use a later compilation phase for parsing of the Groovy source code, allowing <<CodeNarc>> to use a richer and more complete Abstract Syntax Tree (AST). The downside is that the later compiler phase requires <<CodeNarc>> to have the application classes being analyzed, as well as any referenced classes, on the classpath. Note that these rules may be reorganized and moved to a other rulesets or packages. If possible, include them individually within your ruleset -- refer to them using the rule name, e.g. "CloneWithoutCloneable", rather that pulling in the entire "<rulesets/enhanced.xml>" ruleset, to protect against future reorganization. * {CloneWithoutCloneable} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> The method clone() should only be declared if the class implements the Cloneable interface. NOTE: This is a {{{./codenarc-enhanced-classpath-rules.html}CodeNarc Enhanced Classpath Rule}}. It requires <<CodeNarc>> to have the application classes being analyzed, as well as any referenced classes, on the classpath. Example of violations: ------------------------------------------------------------------------------- class ValueClass { ValueClass clone() { } } ------------------------------------------------------------------------------- * {JUnitAssertEqualsConstantActualValue} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Reports usages of <<<org.junit.Assert.assertEquals([message,] expected, actual)>>> where the <<<actual>>> parameter is a constant or a literal. Most likely it was intended to be the <<<expected>>> value. NOTE: This is a {{{./codenarc-enhanced-classpath-rules.html}CodeNarc Enhanced Classpath Rule}}. It requires <<CodeNarc>> to have the application classes being analyzed, as well as any referenced classes, on the classpath. Example of violations: ------------------------------------------------------------------------------- assertEquals(result, 2) assertEquals("Message", result, 2) assertEquals(result, 2.3d, 0.5d) assertEquals("Message", result, 2.3d, 0.5d) ------------------------------------------------------------------------------- * {UnsafeImplementationAsMap} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Reports incomplete interface implementations created by map-to-interface coercions. By default, this rule does not apply to test files. NOTE: This is a {{{./codenarc-enhanced-classpath-rules.html}CodeNarc Enhanced Classpath Rule}}. It requires <<CodeNarc>> to have the application classes being analyzed, as well as any referenced classes, on the classpath. Example of violations: ------------------------------------------------------------------------------- [mouseClicked: { ... }] as MouseListener //not all MouseListener methods are implemented which can lead to UnsupportedOperationException-s ------------------------------------------------------------------------------- ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-imports.apt�����������������������������������������������0000644�0001750�0001750�00000005531�12304644616�022104� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Imports Rules -------------------------------------------------- Imports Rules ("<rulesets/imports.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {DuplicateImport} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for a duplicate <import> statements. * {ImportFromSamePackage} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for an <import> of a class that is within the same package as the importing class. * {ImportFromSunPackages} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change. Example of violations: ------------------------------------------------------------------------------- import sun.misc.foo import sun.misc.foo as Foo public class MyClass{} ------------------------------------------------------------------------------- * {MisorderedStaticImports} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Checks for static <import> statements which should never be after nonstatic imports. This rule has one property <<<comesBefore>>>, which defaults to true. If you like your static imports to come after the others, then set this property to false. Examples of violations: ------------------------------------------------------------------------------- import my.something.another import static foo.bar public class MyClass{} ------------------------------------------------------------------------------- * {UnnecessaryGroovyImport} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for an <import> from any package that is already automatically imported for Groovy files. A Groovy file does not need to include an import for classes from <java.lang>, <java.util>, <java.io>, <java.net>, <groovy.lang> and <groovy.util>, as well as the classes <java.math.BigDecimal> and <java.math.BigInteger>. * {UnusedImport} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for <import> statements for classes that are never referenced within the source file. Also checks static imports. Known limitations: * Does not check for unused imports containing wildcards (e.g. <<<import org.codenarc.*>>>) * Misses unused imports if the class/alias name is contained within strings, comments or other (longer) names (i.e., if that string shows up almost anywhere within the source code). * {NoWildcardImports} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Wildcard imports, static or otherwise, should not be used. Example of violations: ------------------------------------------------------------------------------- import my.something.* import static foo.bar.* public class MyClass{} ------------------------------------------------------------------------------- �����������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rule-index.apt��������������������������������������������������0000644�0001750�0001750�00000107354�12470770456�021347� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Rule Index -------------------------------------------------- Rule Index ~~~~~~~~~~ <<CodeNarc>> includes 343 rules. * {{{codenarc-rules-basic.html}Basic}} * {{{./codenarc-rules-basic.html#AssertWithinFinallyBlock}AssertWithinFinallyBlock}} * {{{./codenarc-rules-basic.html#AssignmentInConditional}AssignmentInConditional}} * {{{./codenarc-rules-basic.html#BigDecimalInstantiation}BigDecimalInstantiation}} * {{{./codenarc-rules-basic.html#BitwiseOperatorInConditional}BitwiseOperatorInConditional}} * {{{./codenarc-rules-basic.html#BooleanGetBoolean}BooleanGetBoolean}} * {{{./codenarc-rules-basic.html#BrokenNullCheck}BrokenNullCheck}} * {{{./codenarc-rules-basic.html#BrokenOddnessCheck}BrokenOddnessCheck}} * {{{./codenarc-rules-basic.html#ClassForName}ClassForName}} * {{{./codenarc-rules-basic.html#ComparisonOfTwoConstants}ComparisonOfTwoConstants}} * {{{./codenarc-rules-basic.html#ComparisonWithSelf}ComparisonWithSelf}} * {{{./codenarc-rules-basic.html#ConstantAssertExpression}ConstantAssertExpression}} * {{{./codenarc-rules-basic.html#ConstantIfExpression}ConstantIfExpression}} * {{{./codenarc-rules-basic.html#ConstantTernaryExpression}ConstantTernaryExpression}} * {{{./codenarc-rules-basic.html#DeadCode}DeadCode}} * {{{./codenarc-rules-basic.html#DoubleNegative}DoubleNegative}} * {{{./codenarc-rules-basic.html#DuplicateCaseStatement}DuplicateCaseStatement}} * {{{./codenarc-rules-basic.html#DuplicateMapKey}DuplicateMapKey}} * {{{./codenarc-rules-basic.html#DuplicateSetValue}DuplicateSetValue}} * {{{./codenarc-rules-basic.html#EmptyCatchBlock}EmptyCatchBlock}} * {{{./codenarc-rules-basic.html#EmptyClass}EmptyClass}} * {{{./codenarc-rules-basic.html#EmptyElseBlock}EmptyElseBlock}} * {{{./codenarc-rules-basic.html#EmptyFinallyBlock}EmptyFinallyBlock}} * {{{./codenarc-rules-basic.html#EmptyForStatement}EmptyForStatement}} * {{{./codenarc-rules-basic.html#EmptyIfStatement}EmptyIfStatement}} * {{{./codenarc-rules-basic.html#EmptyInstanceInitializer}EmptyInstanceInitializer}} * {{{./codenarc-rules-basic.html#EmptyMethod}EmptyMethod}} * {{{./codenarc-rules-basic.html#EmptyStaticInitializer}EmptyStaticInitializer}} * {{{./codenarc-rules-basic.html#EmptySwitchStatement}EmptySwitchStatement}} * {{{./codenarc-rules-basic.html#EmptySynchronizedStatement}EmptySynchronizedStatement}} * {{{./codenarc-rules-basic.html#EmptyTryBlock}EmptyTryBlock}} * {{{./codenarc-rules-basic.html#EmptyWhileStatement}EmptyWhileStatement}} * {{{./codenarc-rules-basic.html#EqualsAndHashCode}EqualsAndHashCode}} * {{{./codenarc-rules-basic.html#EqualsOverloaded}EqualsOverloaded}} * {{{./codenarc-rules-basic.html#ExplicitGarbageCollection}ExplicitGarbageCollection}} * {{{./codenarc-rules-basic.html#ForLoopShouldBeWhileLoop}ForLoopShouldBeWhileLoop}} * {{{./codenarc-rules-basic.html#HardCodedWindowsFileSeparator}HardCodedWindowsFileSeparator}} * {{{./codenarc-rules-basic.html#HardCodedWindowsRootDirectory}HardCodedWindowsRootDirectory}} * {{{./codenarc-rules-basic.html#IntegerGetInteger}IntegerGetInteger}} * {{{./codenarc-rules-basic.html#MultipleUnaryOperators}MultipleUnaryOperators}} * {{{./codenarc-rules-basic.html#RandomDoubleCoercedToZero}RandomDoubleCoercedToZero}} * {{{./codenarc-rules-basic.html#RemoveAllOnSelf}RemoveAllOnSelf}} * {{{./codenarc-rules-basic.html#ReturnFromFinallyBlock}ReturnFromFinallyBlock}} * {{{./codenarc-rules-basic.html#ThrowExceptionFromFinallyBlock}ThrowExceptionFromFinallyBlock}} * {{{codenarc-rules-braces.html}Braces}} * {{{./codenarc-rules-braces.html#ElseBlockBraces}ElseBlockBraces}} * {{{./codenarc-rules-braces.html#ForStatementBraces}ForStatementBraces}} * {{{./codenarc-rules-braces.html#IfStatementBraces}IfStatementBraces}} * {{{./codenarc-rules-braces.html#WhileStatementBraces}WhileStatementBraces}} * {{{codenarc-rules-concurrency.html}Concurrency}} * {{{./codenarc-rules-concurrency.html#BusyWait}BusyWait}} * {{{./codenarc-rules-concurrency.html#DoubleCheckedLocking}DoubleCheckedLocking}} * {{{./codenarc-rules-concurrency.html#InconsistentPropertyLocking}InconsistentPropertyLocking}} * {{{./codenarc-rules-concurrency.html#InconsistentPropertySynchronization}InconsistentPropertySynchronization}} * {{{./codenarc-rules-concurrency.html#NestedSynchronization}NestedSynchronization}} * {{{./codenarc-rules-concurrency.html#StaticCalendarField}StaticCalendarField}} * {{{./codenarc-rules-concurrency.html#StaticConnection}StaticConnection}} * {{{./codenarc-rules-concurrency.html#StaticDateFormatField}StaticDateFormatField}} * {{{./codenarc-rules-concurrency.html#StaticMatcherField}StaticMatcherField}} * {{{./codenarc-rules-concurrency.html#StaticSimpleDateFormatField}StaticSimpleDateFormatField}} * {{{./codenarc-rules-concurrency.html#SynchronizedMethod}SynchronizedMethod}} * {{{./codenarc-rules-concurrency.html#SynchronizedOnBoxedPrimitive}SynchronizedOnBoxedPrimitive}} * {{{./codenarc-rules-concurrency.html#SynchronizedOnGetClass}SynchronizedOnGetClass}} * {{{./codenarc-rules-concurrency.html#SynchronizedOnReentrantLock}SynchronizedOnReentrantLock}} * {{{./codenarc-rules-concurrency.html#SynchronizedOnString}SynchronizedOnString}} * {{{./codenarc-rules-concurrency.html#SynchronizedOnThis}SynchronizedOnThis}} * {{{./codenarc-rules-concurrency.html#SynchronizedReadObjectMethod}SynchronizedReadObjectMethod}} * {{{./codenarc-rules-concurrency.html#SystemRunFinalizersOnExit}SystemRunFinalizersOnExit}} * {{{./codenarc-rules-concurrency.html#ThisReferenceEscapesConstructor}ThisReferenceEscapesConstructor}} * {{{./codenarc-rules-concurrency.html#ThreadGroup}ThreadGroup}} * {{{./codenarc-rules-concurrency.html#ThreadLocalNotStaticFinal}ThreadLocalNotStaticFinal}} * {{{./codenarc-rules-concurrency.html#ThreadYield}ThreadYield}} * {{{./codenarc-rules-concurrency.html#UseOfNotifyMethod}UseOfNotifyMethod}} * {{{./codenarc-rules-concurrency.html#VolatileArrayField}VolatileArrayField}} * {{{./codenarc-rules-concurrency.html#VolatileLongOrDoubleField}VolatileLongOrDoubleField}} * {{{./codenarc-rules-concurrency.html#WaitOutsideOfWhileLoop}WaitOutsideOfWhileLoop}} * {{{codenarc-rules-convention.html}Convention}} * {{{./codenarc-rules-convention.html#ConfusingTernary}ConfusingTernary}} * {{{./codenarc-rules-convention.html#CouldBeElvis}CouldBeElvis}} * {{{./codenarc-rules-convention.html#HashtableIsObsolete}HashtableIsObsolete}} * {{{./codenarc-rules-convention.html#IfStatementCouldBeTernary}IfStatementCouldBeTernary}} * {{{./codenarc-rules-convention.html#InvertedIfElse}InvertedIfElse}} * {{{./codenarc-rules-convention.html#LongLiteralWithLowerCaseL}LongLiteralWithLowerCaseL}} * {{{./codenarc-rules-convention.html#NoDef}NoDef}} * {{{./codenarc-rules-convention.html#ParameterReassignment}ParameterReassignment}} * {{{./codenarc-rules-convention.html#TernaryCouldBeElvis}TernaryCouldBeElvis}} * {{{./codenarc-rules-convention.html#VectorIsObsolete}VectorIsObsolete}} * {{{codenarc-rules-design.html}Design}} * {{{./codenarc-rules-design.html#AbstractClassWithPublicConstructor}AbstractClassWithPublicConstructor}} * {{{./codenarc-rules-design.html#AbstractClassWithoutAbstractMethod}AbstractClassWithoutAbstractMethod}} * {{{./codenarc-rules-design.html#BooleanMethodReturnsNull}BooleanMethodReturnsNull}} * {{{./codenarc-rules-design.html#BuilderMethodWithSideEffects}BuilderMethodWithSideEffects}} * {{{./codenarc-rules-design.html#CloneableWithoutClone}CloneableWithoutClone}} * {{{./codenarc-rules-design.html#CloseWithoutCloseable}CloseWithoutCloseable}} * {{{./codenarc-rules-design.html#CompareToWithoutComparable}CompareToWithoutComparable}} * {{{./codenarc-rules-design.html#ConstantsOnlyInterface}ConstantsOnlyInterface}} * {{{./codenarc-rules-design.html#EmptyMethodInAbstractClass}EmptyMethodInAbstractClass}} * {{{./codenarc-rules-design.html#FinalClassWithProtectedMember}FinalClassWithProtectedMember}} * {{{./codenarc-rules-design.html#ImplementationAsType}ImplementationAsType}} * {{{./codenarc-rules-design.html#Instanceof}Instanceof}} * {{{./codenarc-rules-design.html#LocaleSetDefault}LocaleSetDefault}} * {{{./codenarc-rules-design.html#NestedForLoop}NestedForLoop}} * {{{./codenarc-rules-design.html#PrivateFieldCouldBeFinal}PrivateFieldCouldBeFinal}} * {{{./codenarc-rules-design.html#PublicInstanceField}PublicInstanceField}} * {{{./codenarc-rules-design.html#ReturnsNullInsteadOfEmptyArray}ReturnsNullInsteadOfEmptyArray}} * {{{./codenarc-rules-design.html#ReturnsNullInsteadOfEmptyCollection}ReturnsNullInsteadOfEmptyCollection}} * {{{./codenarc-rules-design.html#SimpleDateFormatMissingLocale}SimpleDateFormatMissingLocale}} * {{{./codenarc-rules-design.html#StatelessSingleton}StatelessSingleton}} * {{{./codenarc-rules-design.html#ToStringReturnsNull}ToStringReturnsNull}} * {{{codenarc-rules-dry.html}Dry}} * {{{./codenarc-rules-dry.html#DuplicateListLiteral}DuplicateListLiteral}} * {{{./codenarc-rules-dry.html#DuplicateMapLiteral}DuplicateMapLiteral}} * {{{./codenarc-rules-dry.html#DuplicateNumberLiteral}DuplicateNumberLiteral}} * {{{./codenarc-rules-dry.html#DuplicateStringLiteral}DuplicateStringLiteral}} * {{{codenarc-rules-enhanced.html}Enhanced}} * {{{./codenarc-rules-enhanced.html#CloneWithoutCloneable}CloneWithoutCloneable}} * {{{./codenarc-rules-enhanced.html#JUnitAssertEqualsConstantActualValue}JUnitAssertEqualsConstantActualValue}} * {{{./codenarc-rules-enhanced.html#UnsafeImplementationAsMap}UnsafeImplementationAsMap}} * {{{codenarc-rules-exceptions.html}Exceptions}} * {{{./codenarc-rules-exceptions.html#CatchArrayIndexOutOfBoundsException}CatchArrayIndexOutOfBoundsException}} * {{{./codenarc-rules-exceptions.html#CatchError}CatchError}} * {{{./codenarc-rules-exceptions.html#CatchException}CatchException}} * {{{./codenarc-rules-exceptions.html#CatchIllegalMonitorStateException}CatchIllegalMonitorStateException}} * {{{./codenarc-rules-exceptions.html#CatchIndexOutOfBoundsException}CatchIndexOutOfBoundsException}} * {{{./codenarc-rules-exceptions.html#CatchNullPointerException}CatchNullPointerException}} * {{{./codenarc-rules-exceptions.html#CatchRuntimeException}CatchRuntimeException}} * {{{./codenarc-rules-exceptions.html#CatchThrowable}CatchThrowable}} * {{{./codenarc-rules-exceptions.html#ConfusingClassNamedException}ConfusingClassNamedException}} * {{{./codenarc-rules-exceptions.html#ExceptionExtendsError}ExceptionExtendsError}} * {{{./codenarc-rules-exceptions.html#ExceptionExtendsThrowable}ExceptionExtendsThrowable}} * {{{./codenarc-rules-exceptions.html#ExceptionNotThrown}ExceptionNotThrown}} * {{{./codenarc-rules-exceptions.html#MissingNewInThrowStatement}MissingNewInThrowStatement}} * {{{./codenarc-rules-exceptions.html#ReturnNullFromCatchBlock}ReturnNullFromCatchBlock}} * {{{./codenarc-rules-exceptions.html#SwallowThreadDeath}SwallowThreadDeath}} * {{{./codenarc-rules-exceptions.html#ThrowError}ThrowError}} * {{{./codenarc-rules-exceptions.html#ThrowException}ThrowException}} * {{{./codenarc-rules-exceptions.html#ThrowNullPointerException}ThrowNullPointerException}} * {{{./codenarc-rules-exceptions.html#ThrowRuntimeException}ThrowRuntimeException}} * {{{./codenarc-rules-exceptions.html#ThrowThrowable}ThrowThrowable}} * {{{codenarc-rules-formatting.html}Formatting}} * {{{./codenarc-rules-formatting.html#BlankLineBeforePackage}BlankLineBeforePackage}} * {{{./codenarc-rules-formatting.html#BracesForClass}BracesForClass}} * {{{./codenarc-rules-formatting.html#BracesForForLoop}BracesForForLoop}} * {{{./codenarc-rules-formatting.html#BracesForIfElse}BracesForIfElse}} * {{{./codenarc-rules-formatting.html#BracesForMethod}BracesForMethod}} * {{{./codenarc-rules-formatting.html#BracesForTryCatchFinally}BracesForTryCatchFinally}} * {{{./codenarc-rules-formatting.html#ClassJavadoc}ClassJavadoc}} * {{{./codenarc-rules-formatting.html#ClosureStatementOnOpeningLineOfMultipleLineClosure}ClosureStatementOnOpeningLineOfMultipleLineClosure}} * {{{./codenarc-rules-formatting.html#ConsecutiveBlankLines}ConsecutiveBlankLines}} * {{{./codenarc-rules-formatting.html#FileEndsWithoutNewline}FileEndsWithoutNewline}} * {{{./codenarc-rules-formatting.html#LineLength}LineLength}} * {{{./codenarc-rules-formatting.html#MissingBlankLineAfterImports}MissingBlankLineAfterImports}} * {{{./codenarc-rules-formatting.html#MissingBlankLineAfterPackage}MissingBlankLineAfterPackage}} * {{{./codenarc-rules-formatting.html#SpaceAfterCatch}SpaceAfterCatch}} * {{{./codenarc-rules-formatting.html#SpaceAfterClosingBrace}SpaceAfterClosingBrace}} * {{{./codenarc-rules-formatting.html#SpaceAfterComma}SpaceAfterComma}} * {{{./codenarc-rules-formatting.html#SpaceAfterFor}SpaceAfterFor}} * {{{./codenarc-rules-formatting.html#SpaceAfterIf}SpaceAfterIf}} * {{{./codenarc-rules-formatting.html#SpaceAfterOpeningBrace}SpaceAfterOpeningBrace}} * {{{./codenarc-rules-formatting.html#SpaceAfterSemicolon}SpaceAfterSemicolon}} * {{{./codenarc-rules-formatting.html#SpaceAfterSwitch}SpaceAfterSwitch}} * {{{./codenarc-rules-formatting.html#SpaceAfterWhile}SpaceAfterWhile}} * {{{./codenarc-rules-formatting.html#SpaceAroundClosureArrow}SpaceAroundClosureArrow}} * {{{./codenarc-rules-formatting.html#SpaceAroundMapEntryColon}SpaceAroundMapEntryColon}} * {{{./codenarc-rules-formatting.html#SpaceAroundOperator}SpaceAroundOperator}} * {{{./codenarc-rules-formatting.html#SpaceBeforeClosingBrace}SpaceBeforeClosingBrace}} * {{{./codenarc-rules-formatting.html#SpaceBeforeOpeningBrace}SpaceBeforeOpeningBrace}} * {{{./codenarc-rules-formatting.html#TrailingWhitespace}TrailingWhitespace}} * {{{codenarc-rules-generic.html}Generic}} * {{{./codenarc-rules-generic.html#IllegalClassMember}IllegalClassMember}} * {{{./codenarc-rules-generic.html#IllegalClassReference}IllegalClassReference}} * {{{./codenarc-rules-generic.html#IllegalPackageReference}IllegalPackageReference}} * {{{./codenarc-rules-generic.html#IllegalRegex}IllegalRegex}} * {{{./codenarc-rules-generic.html#IllegalString}IllegalString}} * {{{./codenarc-rules-generic.html#IllegalSubclass}IllegalSubclass}} * {{{./codenarc-rules-generic.html#RequiredRegex}RequiredRegex}} * {{{./codenarc-rules-generic.html#RequiredString}RequiredString}} * {{{./codenarc-rules-generic.html#StatelessClass}StatelessClass}} * {{{codenarc-rules-grails.html}Grails}} * {{{./codenarc-rules-grails.html#GrailsDomainHasEquals}GrailsDomainHasEquals}} * {{{./codenarc-rules-grails.html#GrailsDomainHasToString}GrailsDomainHasToString}} * {{{./codenarc-rules-grails.html#GrailsDomainReservedSqlKeywordName}GrailsDomainReservedSqlKeywordName}} * {{{./codenarc-rules-grails.html#GrailsDomainWithServiceReference}GrailsDomainWithServiceReference}} * {{{./codenarc-rules-grails.html#GrailsDuplicateConstraint}GrailsDuplicateConstraint}} * {{{./codenarc-rules-grails.html#GrailsDuplicateMapping}GrailsDuplicateMapping}} * {{{./codenarc-rules-grails.html#GrailsMassAssignment}GrailsMassAssignment}} * {{{./codenarc-rules-grails.html#GrailsPublicControllerMethod}GrailsPublicControllerMethod}} * {{{./codenarc-rules-grails.html#GrailsServletContextReference}GrailsServletContextReference}} * {{{./codenarc-rules-grails.html#GrailsSessionReference}GrailsSessionReference}} (DEPRECATED) * {{{./codenarc-rules-grails.html#GrailsStatelessService}GrailsStatelessService}} * {{{codenarc-rules-groovyism.html}Groovyism}} * {{{./codenarc-rules-groovyism.html#AssignCollectionSort}AssignCollectionSort}} * {{{./codenarc-rules-groovyism.html#AssignCollectionUnique}AssignCollectionUnique}} * {{{./codenarc-rules-groovyism.html#ClosureAsLastMethodParameter}ClosureAsLastMethodParameter}} * {{{./codenarc-rules-groovyism.html#CollectAllIsDeprecated}CollectAllIsDeprecated}} * {{{./codenarc-rules-groovyism.html#ConfusingMultipleReturns}ConfusingMultipleReturns}} * {{{./codenarc-rules-groovyism.html#ExplicitArrayListInstantiation}ExplicitArrayListInstantiation}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToAndMethod}ExplicitCallToAndMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToCompareToMethod}ExplicitCallToCompareToMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToDivMethod}ExplicitCallToDivMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToEqualsMethod}ExplicitCallToEqualsMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToGetAtMethod}ExplicitCallToGetAtMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToLeftShiftMethod}ExplicitCallToLeftShiftMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToMinusMethod}ExplicitCallToMinusMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToModMethod}ExplicitCallToModMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToMultiplyMethod}ExplicitCallToMultiplyMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToOrMethod}ExplicitCallToOrMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToPlusMethod}ExplicitCallToPlusMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToPowerMethod}ExplicitCallToPowerMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToRightShiftMethod}ExplicitCallToRightShiftMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitCallToXorMethod}ExplicitCallToXorMethod}} * {{{./codenarc-rules-groovyism.html#ExplicitHashMapInstantiation}ExplicitHashMapInstantiation}} * {{{./codenarc-rules-groovyism.html#ExplicitHashSetInstantiation}ExplicitHashSetInstantiation}} * {{{./codenarc-rules-groovyism.html#ExplicitLinkedHashMapInstantiation}ExplicitLinkedHashMapInstantiation}} * {{{./codenarc-rules-groovyism.html#ExplicitLinkedListInstantiation}ExplicitLinkedListInstantiation}} * {{{./codenarc-rules-groovyism.html#ExplicitStackInstantiation}ExplicitStackInstantiation}} * {{{./codenarc-rules-groovyism.html#ExplicitTreeSetInstantiation}ExplicitTreeSetInstantiation}} * {{{./codenarc-rules-groovyism.html#GStringAsMapKey}GStringAsMapKey}} * {{{./codenarc-rules-groovyism.html#GStringExpressionWithinString}GStringExpressionWithinString}} * {{{./codenarc-rules-groovyism.html#GetterMethodCouldBeProperty}GetterMethodCouldBeProperty}} * {{{./codenarc-rules-groovyism.html#GroovyLangImmutable}GroovyLangImmutable}} * {{{./codenarc-rules-groovyism.html#UseCollectMany}UseCollectMany}} * {{{./codenarc-rules-groovyism.html#UseCollectNested}UseCollectNested}} * {{{codenarc-rules-imports.html}Imports}} * {{{./codenarc-rules-imports.html#DuplicateImport}DuplicateImport}} * {{{./codenarc-rules-imports.html#ImportFromSamePackage}ImportFromSamePackage}} * {{{./codenarc-rules-imports.html#ImportFromSunPackages}ImportFromSunPackages}} * {{{./codenarc-rules-imports.html#MisorderedStaticImports}MisorderedStaticImports}} * {{{./codenarc-rules-imports.html#NoWildcardImports}NoWildcardImports}} * {{{./codenarc-rules-imports.html#UnnecessaryGroovyImport}UnnecessaryGroovyImport}} * {{{./codenarc-rules-imports.html#UnusedImport}UnusedImport}} * {{{codenarc-rules-jdbc.html}Jdbc}} * {{{./codenarc-rules-jdbc.html#DirectConnectionManagement}DirectConnectionManagement}} * {{{./codenarc-rules-jdbc.html#JdbcConnectionReference}JdbcConnectionReference}} * {{{./codenarc-rules-jdbc.html#JdbcResultSetReference}JdbcResultSetReference}} * {{{./codenarc-rules-jdbc.html#JdbcStatementReference}JdbcStatementReference}} * {{{codenarc-rules-junit.html}Junit}} * {{{./codenarc-rules-junit.html#ChainedTest}ChainedTest}} * {{{./codenarc-rules-junit.html#CoupledTestCase}CoupledTestCase}} * {{{./codenarc-rules-junit.html#JUnitAssertAlwaysFails}JUnitAssertAlwaysFails}} * {{{./codenarc-rules-junit.html#JUnitAssertAlwaysSucceeds}JUnitAssertAlwaysSucceeds}} * {{{./codenarc-rules-junit.html#JUnitFailWithoutMessage}JUnitFailWithoutMessage}} * {{{./codenarc-rules-junit.html#JUnitLostTest}JUnitLostTest}} * {{{./codenarc-rules-junit.html#JUnitPublicField}JUnitPublicField}} * {{{./codenarc-rules-junit.html#JUnitPublicNonTestMethod}JUnitPublicNonTestMethod}} * {{{./codenarc-rules-junit.html#JUnitPublicProperty}JUnitPublicProperty}} * {{{./codenarc-rules-junit.html#JUnitSetUpCallsSuper}JUnitSetUpCallsSuper}} * {{{./codenarc-rules-junit.html#JUnitStyleAssertions}JUnitStyleAssertions}} * {{{./codenarc-rules-junit.html#JUnitTearDownCallsSuper}JUnitTearDownCallsSuper}} * {{{./codenarc-rules-junit.html#JUnitTestMethodWithoutAssert}JUnitTestMethodWithoutAssert}} * {{{./codenarc-rules-junit.html#JUnitUnnecessarySetUp}JUnitUnnecessarySetUp}} * {{{./codenarc-rules-junit.html#JUnitUnnecessaryTearDown}JUnitUnnecessaryTearDown}} * {{{./codenarc-rules-junit.html#JUnitUnnecessaryThrowsException}JUnitUnnecessaryThrowsException}} * {{{./codenarc-rules-junit.html#SpockIgnoreRestUsed}SpockIgnoreRestUsed}} * {{{./codenarc-rules-junit.html#UnnecessaryFail}UnnecessaryFail}} * {{{./codenarc-rules-junit.html#UseAssertEqualsInsteadOfAssertTrue}UseAssertEqualsInsteadOfAssertTrue}} * {{{./codenarc-rules-junit.html#UseAssertFalseInsteadOfNegation}UseAssertFalseInsteadOfNegation}} * {{{./codenarc-rules-junit.html#UseAssertNullInsteadOfAssertEquals}UseAssertNullInsteadOfAssertEquals}} * {{{./codenarc-rules-junit.html#UseAssertSameInsteadOfAssertTrue}UseAssertSameInsteadOfAssertTrue}} * {{{./codenarc-rules-junit.html#UseAssertTrueInsteadOfAssertEquals}UseAssertTrueInsteadOfAssertEquals}} * {{{./codenarc-rules-junit.html#UseAssertTrueInsteadOfNegation}UseAssertTrueInsteadOfNegation}} * {{{codenarc-rules-logging.html}Logging}} * {{{./codenarc-rules-logging.html#LoggerForDifferentClass}LoggerForDifferentClass}} * {{{./codenarc-rules-logging.html#LoggerWithWrongModifiers}LoggerWithWrongModifiers}} * {{{./codenarc-rules-logging.html#LoggingSwallowsStacktrace}LoggingSwallowsStacktrace}} * {{{./codenarc-rules-logging.html#MultipleLoggers}MultipleLoggers}} * {{{./codenarc-rules-logging.html#PrintStackTrace}PrintStackTrace}} * {{{./codenarc-rules-logging.html#Println}Println}} * {{{./codenarc-rules-logging.html#SystemErrPrint}SystemErrPrint}} * {{{./codenarc-rules-logging.html#SystemOutPrint}SystemOutPrint}} * {{{codenarc-rules-naming.html}Naming}} * {{{./codenarc-rules-naming.html#AbstractClassName}AbstractClassName}} * {{{./codenarc-rules-naming.html#ClassName}ClassName}} * {{{./codenarc-rules-naming.html#ClassNameSameAsFilename}ClassNameSameAsFilename}} * {{{./codenarc-rules-naming.html#ConfusingMethodName}ConfusingMethodName}} * {{{./codenarc-rules-naming.html#FactoryMethodName}FactoryMethodName}} * {{{./codenarc-rules-naming.html#FieldName}FieldName}} * {{{./codenarc-rules-naming.html#InterfaceName}InterfaceName}} * {{{./codenarc-rules-naming.html#MethodName}MethodName}} * {{{./codenarc-rules-naming.html#ObjectOverrideMisspelledMethodName}ObjectOverrideMisspelledMethodName}} * {{{./codenarc-rules-naming.html#PackageName}PackageName}} * {{{./codenarc-rules-naming.html#PackageNameMatchesFilePath}PackageNameMatchesFilePath}} * {{{./codenarc-rules-naming.html#ParameterName}ParameterName}} * {{{./codenarc-rules-naming.html#PropertyName}PropertyName}} * {{{./codenarc-rules-naming.html#VariableName}VariableName}} * {{{codenarc-rules-security.html}Security}} * {{{./codenarc-rules-security.html#FileCreateTempFile}FileCreateTempFile}} * {{{./codenarc-rules-security.html#InsecureRandom}InsecureRandom}} * {{{./codenarc-rules-security.html#JavaIoPackageAccess}JavaIoPackageAccess}} * {{{./codenarc-rules-security.html#NonFinalPublicField}NonFinalPublicField}} * {{{./codenarc-rules-security.html#NonFinalSubclassOfSensitiveInterface}NonFinalSubclassOfSensitiveInterface}} * {{{./codenarc-rules-security.html#ObjectFinalize}ObjectFinalize}} * {{{./codenarc-rules-security.html#PublicFinalizeMethod}PublicFinalizeMethod}} * {{{./codenarc-rules-security.html#SystemExit}SystemExit}} * {{{./codenarc-rules-security.html#UnsafeArrayDeclaration}UnsafeArrayDeclaration}} * {{{codenarc-rules-serialization.html}Serialization}} * {{{./codenarc-rules-serialization.html#EnumCustomSerializationIgnored}EnumCustomSerializationIgnored}} * {{{./codenarc-rules-serialization.html#SerialPersistentFields}SerialPersistentFields}} * {{{./codenarc-rules-serialization.html#SerialVersionUID}SerialVersionUID}} * {{{./codenarc-rules-serialization.html#SerializableClassMustDefineSerialVersionUID}SerializableClassMustDefineSerialVersionUID}} * {{{codenarc-rules-size.html}Size}} * {{{./codenarc-rules-size.html#AbcComplexity}AbcComplexity}} (DEPRECATED: Use the AbcMetric rule instead. Requires the GMetrics jar) * {{{./codenarc-rules-size.html#AbcMetric}AbcMetric}} (Requires the GMetrics jar) * {{{./codenarc-rules-size.html#ClassSize}ClassSize}} * {{{./codenarc-rules-size.html#CrapMetric}CrapMetric}} (Requires the GMetrics jar and a Cobertura coverage file) * {{{./codenarc-rules-size.html#CyclomaticComplexity}CyclomaticComplexity}} (Requires the GMetrics jar) * {{{./codenarc-rules-size.html#MethodCount}MethodCount}} * {{{./codenarc-rules-size.html#MethodSize}MethodSize}} * {{{./codenarc-rules-size.html#NestedBlockDepth}NestedBlockDepth}} * {{{./codenarc-rules-size.html#ParameterCount}ParameterCount}} * {{{codenarc-rules-unnecessary.html}Unnecessary}} * {{{./codenarc-rules-unnecessary.html#AddEmptyString}AddEmptyString}} * {{{./codenarc-rules-unnecessary.html#ConsecutiveLiteralAppends}ConsecutiveLiteralAppends}} * {{{./codenarc-rules-unnecessary.html#ConsecutiveStringConcatenation}ConsecutiveStringConcatenation}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryBigDecimalInstantiation}UnnecessaryBigDecimalInstantiation}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryBigIntegerInstantiation}UnnecessaryBigIntegerInstantiation}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryBooleanExpression}UnnecessaryBooleanExpression}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryBooleanInstantiation}UnnecessaryBooleanInstantiation}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryCallForLastElement}UnnecessaryCallForLastElement}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryCallToSubstring}UnnecessaryCallToSubstring}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryCast}UnnecessaryCast}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryCatchBlock}UnnecessaryCatchBlock}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryCollectCall}UnnecessaryCollectCall}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryCollectionCall}UnnecessaryCollectionCall}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryConstructor}UnnecessaryConstructor}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryDefInFieldDeclaration}UnnecessaryDefInFieldDeclaration}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryDefInMethodDeclaration}UnnecessaryDefInMethodDeclaration}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryDefInVariableDeclaration}UnnecessaryDefInVariableDeclaration}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryDotClass}UnnecessaryDotClass}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryDoubleInstantiation}UnnecessaryDoubleInstantiation}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryElseStatement}UnnecessaryElseStatement}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryFinalOnPrivateMethod}UnnecessaryFinalOnPrivateMethod}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryFloatInstantiation}UnnecessaryFloatInstantiation}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryGString}UnnecessaryGString}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryGetter}UnnecessaryGetter}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryIfStatement}UnnecessaryIfStatement}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryInstanceOfCheck}UnnecessaryInstanceOfCheck}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryInstantiationToGetClass}UnnecessaryInstantiationToGetClass}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryIntegerInstantiation}UnnecessaryIntegerInstantiation}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryLongInstantiation}UnnecessaryLongInstantiation}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryModOne}UnnecessaryModOne}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryNullCheck}UnnecessaryNullCheck}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryNullCheckBeforeInstanceOf}UnnecessaryNullCheckBeforeInstanceOf}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryObjectReferences}UnnecessaryObjectReferences}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryOverridingMethod}UnnecessaryOverridingMethod}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryPackageReference}UnnecessaryPackageReference}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryParenthesesForMethodCallWithClosure}UnnecessaryParenthesesForMethodCallWithClosure}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryPublicModifier}UnnecessaryPublicModifier}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryReturnKeyword}UnnecessaryReturnKeyword}} * {{{./codenarc-rules-unnecessary.html#UnnecessarySafeNavigationOperator}UnnecessarySafeNavigationOperator}} * {{{./codenarc-rules-unnecessary.html#UnnecessarySelfAssignment}UnnecessarySelfAssignment}} * {{{./codenarc-rules-unnecessary.html#UnnecessarySemicolon}UnnecessarySemicolon}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryStringInstantiation}UnnecessaryStringInstantiation}} * {{{./codenarc-rules-unnecessary.html#UnnecessarySubstring}UnnecessarySubstring}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryTernaryExpression}UnnecessaryTernaryExpression}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryToString}UnnecessaryToString}} * {{{./codenarc-rules-unnecessary.html#UnnecessaryTransientModifier}UnnecessaryTransientModifier}} * {{{codenarc-rules-unused.html}Unused}} * {{{./codenarc-rules-unused.html#UnusedArray}UnusedArray}} * {{{./codenarc-rules-unused.html#UnusedMethodParameter}UnusedMethodParameter}} * {{{./codenarc-rules-unused.html#UnusedObject}UnusedObject}} * {{{./codenarc-rules-unused.html#UnusedPrivateField}UnusedPrivateField}} * {{{./codenarc-rules-unused.html#UnusedPrivateMethod}UnusedPrivateMethod}} * {{{./codenarc-rules-unused.html#UnusedPrivateMethodParameter}UnusedPrivateMethodParameter}} * {{{./codenarc-rules-unused.html#UnusedVariable}UnusedVariable}} ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-XmlReportWriter.apt���������������������������������������������0000644�0001750�0001750�00000006320�12006632012�022367� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc XmlReportWriter -------------------------------------------------- XmlReportWriter ~~~~~~~~~~~~~~~~ * Description ~~~~~~~~~~~~~ The <<<org.codenarc.report.XmlReportWriter>>> class (type="xml") produces an XML report of the <<CodeNarc>> results. <<Note:>> This XML format is still being refined and is subject to change. {{{https://sourceforge.net/sendmessage.php?touser=1853503}Contact me}} if you have specific requirements or suggestions. See a {{{./SampleCodeNarcXmlReport.xml}Sample XML Report}}. Also see the {{{http://mrhaki.blogspot.com/}mrhaki}} blog post about {{{http://mrhaki.blogspot.com/2011/01/groovy-goodness-create-codenarc-reports.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+mrhaki+%28Messages+from+mrhaki%29}creating custom CodeNarc HTML reports using XSLT}}. * Option Nested Elements ~~~~~~~~~~~~~~~~~~~~~~~~ The <<option>> element is a child of the <<report>> element and defines a report-specific option for a report. <<<org.codenarc.report.XmlReportWriter>>> supports the following options: *---------------------+----------------------------------------------------------------+------------------------+ | <<Attribute>> | <<Description>> | <<Required>> | *---------------------+----------------------------------------------------------------+------------------------+ | outputFile | The path and filename for the output report file. | No | *---------------------+----------------------------------------------------------------+------------------------+ | title | The title for the output report. | No | *---------------------+----------------------------------------------------------------+------------------------+ | writeToStandardOut | Set to "true" or <<<true>>> to write out the report to | No | | | <stdout> (<<<System.out>>>) instead of writing to a file. | | *---------------------+----------------------------------------------------------------+------------------------+ * Example ~~~~~~~~~ Here is an example Ant XML build file illustrating configuration of <<<org.codenarc.report.XmlReportWriter>>>. Note that the report <<type>> is specified as <<"xml">>. +---------------------------------------------------------------------------------------- <taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/> <target name="runCodeNarc"> <codenarc ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml" maxPriority1Violations="0"> <report type="xml"> <option name="outputFile" value="reports/CodeNarcXmlReport.xml" /> <option name="title" value="My Sample Code" /> </report> <fileset dir="src"> <include name="**/*.groovy"/> </fileset> </codenarc> </target> +---------------------------------------------------------------------------------------- ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-command-line.apt������������������������������������������������0000644�0001750�0001750�00000015301�12403723547�021617� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc Command Line -------------------------------------------------- CodeNarc - Run From Command-Line ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<CodeNarc>> can be run from the command-line as a Java application. The <<<org.codenarc.CodeNarc>>> class provides the application entry-point. * CodeNarc Command-Line Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Usage: <<<java org.codenarc.CodeNarc [OPTIONS]>>> where OPTIONS are zero or more command-line parameters of the form "<<<-NAME[=VALUE]>>>" All command-line parameters are optional. If no parameters are supplied, <<CodeNarc>> runs from the current directory with reasonable defaults, as described below. *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ | <<Parameter>> | <<Description>> | <<Example>> | *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ | -basedir=<DIR> | The base (root) directory for the source code to be analyzed. | -basedir=src/main/groovy | | | Defaults to the current directory ("."). | | *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ | -includes=<PATTERNS> | The comma-separated list of Ant-style file patterns specifying | -includes=**/*.gr | | | files that must be included. Defaults to "**/*.groovy". | | *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ | -excludes=<PATTERNS> | The comma-separated list of Ant-style file patterns specifying | -excludes=**/templates/**,\ | | | files that must be excluded. No files are excluded when omitted. | **/*Test.* | *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ | -rulesetfiles=<FILENAMES> | The path to the Groovy or XML RuleSet definition files, relative | -rulesetfiles=rulesets/imports.xml,\ | | | to the classpath. This can be a single file path, or multiple paths | rulesets/naming.xml | | | separated by commas. Defaults to "rulesets/basic.xml". | | *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ | -report=<REPORT-TYPE[:FILENAME]>| The definition of the report to produce. The option value is of | -report=html | | | the form <<<TYPE[:FILENAME]>>>, where <<<TYPE>>> is one of the | -report=html:MyProject.html | | | predefined type names: "html", "xml", "text", "console" or else the fully-qualified | | | | class name of a class (accessible on the classpath) that implements | -report=xml | | | the <<<org.codenarc.report.ReportWriter>>> interface. And | -report=xml:MyXmlReport.xml | | | <<<FILENAME>>> is the filename (with optional path) of the output | | | | report filename. If the report filename is omitted, the default | -report=org.codenarc.report. HtmlReportWriter | | | filename for the report type is used ("CodeNarcReport.html" for | | | | "html" and "CodeNarcXmlReport.xml" for "xml"). If no report | | | | option is specified, default to a single "html" report with the | | | | default filename. | | *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ | -title=<REPORT TITLE> | The title description for this analysis; used in the output | -title="My Project" | | | report(s), if provided. | | *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ | -help | Display the command-line help. If present, this must be the | -help | | | only command-line parameter. | | *---------------------------------+----------------------------------------------------------------------+--------------------------------------+ * Executing CodeNarc from the Command-Line ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Make sure that the following are included your CLASSPATH: [[1]] The Groovy jar [[2]] The CodeNarc jar [[3]] The Log4J jar [[4]] The directories containing (or relative to) <<CodeNarc>> config files such as "codenarc.properties" or ruleset files. [] The CodeNarc command-line application sets an exit status of zero (0) if the command successfully executes, and an exit status of one (1) if an error occurs executing CodeNarc, or if an invalid command-line option is specified. Here is an example BAT file for running <<CodeNarc>> on Windows. +---------------------------------------------------------------------------------------- @set GROOVY_JAR="%GROOVY_HOME%/embeddable/groovy-all-1.5.6.jar" @java -classpath %GROOVY_JAR%;lib/CodeNarc-0.5.jar;lib/log4j-1.2.14.jar;lib org.codenarc.CodeNarc %* +---------------------------------------------------------------------------------------- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-dry.apt���������������������������������������������������0000644�0001750�0001750�00000016326�12006632012�021173� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - DRY Rules -------------------------------------------------- DRY (Don't Repeat Yourself) Rules ("<rulesets/dry.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These rules check for duplicate code, enforcing the DRY (Don't Repeat Yourself) principle. * {DuplicateListLiteral} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.16> This rule checks for duplicate <List> literals within the current class. This rule only checks for <List>s where values are all constants or literals. Code containing duplicate <List> literals can usually be improved by declaring the <List> as a constant field. By default, the rule does not analyze test files. This rule sets the default value of the <doNotApplyToFilesMatching> property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'. Examples of violations: ------------------------------------------------------------------------------- def var1 = [1, null, Boolean.FALSE, 'x', true] def var2 = [1, null, Boolean.FALSE, 'x', true] // violation def var1 = [1, [3, 4]] def var2 = [1, [3,4]] // violation def var1 = [123, [3, 4, [x:99], 5]] def var2 = [99, [3, 4, [x:99], 5]] // violation [3, 4, [x:99], 5] ------------------------------------------------------------------------------- Examples of non-violations: ------------------------------------------------------------------------------- def name def var1 = [name, 'b', 'c'] def var2 = [name, 'b', 'c'] // not a violation; name is a variable def var1 = [1, 7+5] def var2 = [1, 7+5] // not a violation; contains a non-constant/literal expression ------------------------------------------------------------------------------- ** Notes ~~~~~~~~~ * This rule does not search across several files at once, only in the current file, and only within the current class. * You can suppress the error by annotating a class or method with the <<<@SuppressWarnings('DuplicateListLiteral')>>> annotation. * {DuplicateMapLiteral} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.16> This rule checks for duplicate <Map> literals within the current class. This rule only checks for <Map>s where the keys and values are all constants or literals. Code containing duplicate <Map> literals can usually be improved by declaring the <Map> as a constant field. By default, the rule does not analyze test files. This rule sets the default value of the <doNotApplyToFilesMatching> property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'. Examples of violations: ------------------------------------------------------------------------------- def var1 = [a:1, b:null, c:Boolean.FALSE, d:'x', e:true] def var2 = [a:1, b:null, c:Boolean.FALSE, d:'x', e:true] // violation def var1 = [a:1, b:[x:3,y:4]] def var2 = [a:1, b:[x:3,y:4]] // violation def var1 = [a:1, b:[3,4]] def var2 = [a:1, b:[3,4]] // violation def var1 = [null:1, 'b':2, (Boolean.FALSE):3, (4):4, (true):5] def var2 = [null:1, 'b':2, (Boolean.FALSE):3, (4):4, (true):5] // violation ------------------------------------------------------------------------------- Examples of non-violations: ------------------------------------------------------------------------------- def name def var1 = [(name):1, b:1, c:1] def var2 = [(name):1, b:1, c:1] // not a violation; name is a variable def var1 = [a:1, b:['x', name]] def var2 = [a:1, b:['x', name]] // not a violation; name is a variable def var1 = [a:7+5] def var2 = [a:7+5] // not a violation; contains a non-constant/literal expression ------------------------------------------------------------------------------- ** Notes ~~~~~~~~~ * This rule does not search across several files at once, only in the current file, and only within the current class. * You can suppress the error by annotating a class or method with the <<<@SuppressWarnings('DuplicateMapLiteral')>>> annotation. * {DuplicateNumberLiteral} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule checks for duplicate number literals within the current class. Code containing duplicate <Number> literals can usually be improved by declaring the <Number> as a constant field. By default, the rule does not analyze test files. This rule sets the default value of the <doNotApplyToFilesMatching> property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreNumbers | The optional comma-separated list of numbers that should be | <<<0,1>>> | | | ignored (i.e., not cause a violation). | | *---------------------+----------------------------------------------------------------+------------------------+ ** Notes ~~~~~~~~~ * This rule does not search across several files at once, only in the current file, and only within the current class. * You can suppress the error by annotating a class or method with the <<<@SuppressWarnings('DuplicateNumberLiteral')>>> annotation. * {DuplicateStringLiteral} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule checks for duplicate String literals within the current class. Code containing duplicate <String> literals can usually be improved by declaring the <String> as a constant field. By default, the rule does not analyze test files. This rule sets the default value of the <doNotApplyToFilesMatching> property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreStrings | The optional comma-separated list of Strings that should be | <<<''>>> (empty string)| | | ignored (i.e., not cause a violation). | | *---------------------+----------------------------------------------------------------+------------------------+ ** Notes ~~~~~~~~~ * This rule does not search across several files at once, only in the current file, and only within the current class. * You can suppress the error by annotating a class or method with the <<<@SuppressWarnings('DuplicateStringLiteral')>>> annotation. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-grails.apt������������������������������������������������0000644�0001750�0001750�00000037571�12414275150�021674� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Grails Rules -------------------------------------------------- Grails Rules ("<rulesets/grails.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {GrailsDomainHasEquals} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks that Grails domain classes redefine <<<equals()>>>. Ignores classes annotated with <<<@EqualsAndHashCode>>> or <<<@Canonical>>>. This rule sets the default value of <<<applyToFilesMatching>>> to only match files under the 'grails-app/domain' folder. You can override this with a different regular expression value if appropriate. * {GrailsDomainHasToString} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Checks that Grails domain classes redefine <<<toString()>>>. Ignores classes annotated with <<<@ToString>>> or <<<@Canonical>>>. This rule sets the default value of <<<applyToFilesMatching>>> to only match files under the 'grails-app/domain' folder. You can override this with a different regular expression value if appropriate. * {GrailsDomainReservedSqlKeywordName} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Forbids usage of SQL reserved keywords as class or field names in Grails domain classes. Naming a domain class (or its field) with such a keyword causes SQL schema creation errors and/or redundant table/column name mappings. Note: due to limited type information available during CodeNarc's operation, this rule will report fields of type <<<java.io.Serializable>>>, but not of its implementations. Please specify any implementations used as domain properties in <<<additionalHibernateBasicTypes>>>. *-------------------------------+----------------------------------------------------------------+---------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *-------------------------------+----------------------------------------------------------------+---------------------+ | additionalHibernateBasicTypes | Comma-separated list of simple class names of additional | <<<''>>> | | | classes that Hibernate maps as basic types (creates a column | | | | for a field of such class). Add your custom basic types here. | | *-------------------------------+----------------------------------------------------------------+---------------------+ | additionalReservedSqlKeywords | Comma-separated list of additional reserved SQL keywords (just | <<<''>>> | | | in case the 337 keywords of nowadays SQL-* standards weren't | | | | enough). | | *-------------------------------+----------------------------------------------------------------+---------------------+ * {GrailsDomainWithServiceReference} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Checks that Grails Domain classes do not have Service classes injected. This rule sets the default value of <<<applyToFilesMatching>>> to only match files under the 'grails-app/domain' folder. You can override this with a different regular expression value if appropriate. * {GrailsDuplicateConstraint} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check for duplicate name in a Grails domain class constraints. Duplicate names/entries are legal, but can be confusing and error-prone. NOTE: This rule does not check that the values of the entries are duplicated, only that there are two entries with the same name. Example of violations: ------------------------------------------------------------------------------- class Person { String firstName String lastName static constraints = { firstName nullable:true lastName nullable:true, maxSize:30 firstName nullable:false // violation } } ------------------------------------------------------------------------------- * {GrailsDuplicateMapping} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check for duplicate name in a Grails domain class mapping. Duplicate names/entries are legal, but can be confusing and error-prone. NOTE: This rule does not check that the values of the entries are duplicated, only that there are two entries with the same name. Example of violations: ------------------------------------------------------------------------------- class Person { String firstName String lastName static mapping = { table 'people' firstName column: 'First_Name' lastName column: 'Last_Name' firstName column: 'First_Name' // violation table 'people2' // violation } } ------------------------------------------------------------------------------- * {GrailsMassAssignment} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Untrusted input should not be allowed to set arbitrary object fields without restriction. Example of violations: ------------------------------------------------------------------------------- // Person would be a grails domain object def person = new Person(params) person.save() // or using .properties def person = Person.get(1) person.properties = params person.save() ------------------------------------------------------------------------------- * {GrailsPublicControllerMethod} Rule (disabled) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *-------------------------------------------------------------------------------------------------+ | <<NOTE:>> This rule has been disabled by default (i.e., by setting its <enabled> property to | <false>). Given that Grails 2.x allows and encourages controller actions to be defined as methods | instead of closures, this rule makes no sense for Grails 2.x projects. *-------------------------------------------------------------------------------------------------+ Rule that checks for public methods on Grails controller classes. Static methods are ignored. Grails controller actions and interceptors are defined as properties on the controller class. Public methods on a controller class are unnecessary. They break encapsulation and can be confusing. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodNames | Specifies one or more (comma-separated) method names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ This rule sets the default value of <<<applyToFilesMatching>>> to only match files under the 'grails-app/controllers' folder. You can override this with a different regular expression value if appropriate. This rule also sets the default value of <<<applyToClassNames>>> to only match class names ending in 'Controller'. You can override this with a different class name pattern (String with wildcards) if appropriate. * {GrailsServletContextReference} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rule that checks for references to the <<<servletContext>>> object from within Grails controller and taglib classes. This rule is intended as a "governance" rule to enable monitoring and controlling access to the <<<servletContext>>> from within application source code. Storing objects in the <<<servletContext>>> may inhibit scalability and/or performance and should be carefully considered. Furthermore, access to the <<<servletContext>>> is not synchronized, so reading/writing objects from the <<<servletConext>>> must be manually synchronized, as described in {{{http://www.amazon.com/Definitive-Grails-Second-Experts-Development/dp/1590599950} The Definitive Guide to Grails (2nd edition)}}. Note that this rule does not check for direct access to the <<<servletContext>>> from within GSP (Groovy Server Pages) files. Enabling this rule may make most sense in a team environment where team members exhibit a broad range of skill and experience levels. Appropriate <<<servletContext>>> access can be configured as exceptions to this rule by configuring either the <<<doNotApplyToFilenames>>> or <<<doNotApplyToFilesMatching>>> property of the rule. And, as always, it is easy to just {{{./codenarc-configuring-rules.html#Turning_Off_A_Rule}turn off the rule}} if it does not make sense it your environment. This rule sets the default value of <<<applyToFilesMatching>>> to only match files under the 'grails-app/controllers' or 'grails-app/taglib' folders. You can override this with a different regular expression value if appropriate. * {GrailsSessionReference} Rule (deprecated) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *-------------------------------------------------------------------------------------------------+ | <<NOTE:>> This rule has been <<DEPRECATED>>, and disabled by default (i.e., by setting its | <enabled> property to <false>). Please email the {{{mailto:codenarc-user@lists.sourceforge.net}CodeNarc User Mailing List}} | if you have an opinion for/against deprecation and eventual removal of this rule. *-------------------------------------------------------------------------------------------------+ Rule that checks for references to the <<<session>>> object from within Grails controller and taglib classes. This rule is intended as a "governance" rule to enable monitoring and controlling access to the <<<session>>> from within application source code. Storing objects in the <<<session>>> may inhibit scalability and/or performance and should be carefully considered. Note that this rule does not check for direct access to the <<<session>>> from within GSP (Groovy Server Pages) files. Enabling this rule may make most sense in a team environment where team members exhibit a broad range of skill and experience levels. Appropriate <<<session>>> access can be configured as exceptions to this rule by configuring either the <<<doNotApplyToFilenames>>> or <<<doNotApplyToFilesMatching>>> property of the rule. And, as always, it is easy to just {{{./codenarc-configuring-rules.html#Turning_Off_A_Rule}turn off the rule}} if it does not make sense it your environment. This rule sets the default value of <<<applyToFilesMatching>>> to only match files under the 'grails-app/controllers' or 'grails-app/taglib' folders. You can override this with a different regular expression value if appropriate. * {GrailsStatelessService} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for non-<<<final>>> fields on a Grails service class. Grails service classes are singletons by default, and so they should be reentrant. In most cases, this implies (or at least encourages) that they should be stateless. This rule ignores (i.e., does not cause violations for) the following: * All <<<final>>> fields (either instance or static). Note that fields that are <<<static>>> and non-<<<final>>>, however, do cause a violation. * Non-<<<static>>> properties (i.e., no visibility modifier specified) declared with <<<def>>>. * All classes annotated with the <<<@Immutable>>> transformation. See {{{http://groovy.codehaus.org/Immutable+transformation}http://groovy.codehaus.org/Immutable+transformation}}. * All fields annotated with the <<<@Inject>>> annotation. * All fields with names matching the <ignoreFieldNames> property. * All fields with types matching the <ignoreFieldTypes> property. [] The <<<ignoreFieldNames>>> property of this rule is preconfigured to ignore the standard Grails service configuration field names ('scope', 'transactional') and the standard injected bean names ('dataSource', 'sessionFactory'), as well as all other field names ending with 'Service'. *---------------------+----------------------------------------------------------------+---------------------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+---------------------------------------+ | ignoreFieldNames | Specifies one or more (comma-separated) field names that | <<<'dataSource,scope,sessionFactory, | | | should be ignored (i.e., that should not cause a rule | transactional,*Service'>>> | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+---------------------------------------+ | addToIgnoreFieldNames| Specifies one or more (comma-separated) field names to be | <<<null>>> | | | added to the <<<ignoreFieldNames>>> property value. This is a | | | | special write-only property, and each call to | | | | <<<setAddIgnoreFieldNames()>>> adds to (rather than overwrites)| | | | the list of field names to be ignored. | | *-----------------------+----------------------------------------------------------------+-------------------------------------+ | ignoreFieldTypes | Specifies one or more (comma-separated) field types that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | | | | | *---------------------+----------------------------------------------------------------+---------------------------------------+ This rule sets the default value of <<<applyToFilesMatching>>> to only match files under the 'grails-app/services' folder. You can override this with a different regular expression value if appropriate. This rule also sets the default value of <<<applyToClassNames>>> to only match class names ending in 'Service'. You can override this with a different class name pattern (String with wildcards) if appropriate. ** Notes ~~~~~~~~~~~~ [[1]] The <<<ignoreFieldTypes>>> property matches the field type name as indicated in the field declaration, only including a full package specification IF it is included in the source code. For example, the field declaration <<<BigDecimal value>>> matches an <<<ignoreFieldTypes>>> value of <<<BigDecimal>>>, but not <<<java.lang.BigDecimal>>>. [[2]] There is one exception for the <<<ignoreFieldTypes>>> property: if the field is declared with a modifier/type of <<<def>>>, then the type resolves to <<<java.lang.Object>>>. ���������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-roadmap.apt�����������������������������������������������������0000644�0001750�0001750�00000001564�12006632016�020672� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc Road Map -------------------------------------------------- CodeNarc - Road Map ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suggestions or preferences? Create a {{{https://sourceforge.net/tracker2/?group_id=250145&atid=1126575}Feature Request}}. * Short-Term Goals (Imminent) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * More rules * Performance improvements. * Long-Term Goals ~~~~~~~~~~~~~~~~~ * Even more rules, perhaps including framework-specific rules for Grails (additional), Griffon, Gradle, etc.. * Improve performance * Analyze source code within jar files or zip files, and/or within Subversion, Git or CVS repositories. ** Considering (Optional) ~~~~~~~~~~~~~~~~~~~~~~~~~ * Create Netbeans plugin. * Localization of report text. ��������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-junit.apt�������������������������������������������������0000644�0001750�0001750�00000053745�12470772445�021560� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - JUnit Rules -------------------------------------------------- JUnit Rules ("<rulesets/junit.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {ChainedTest} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.13> A test method that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another. Example of violations: ------------------------------------------------------------------------------- class MyTest extends GroovyTestCase { public void testFoo() { // violations, calls test method on self 5.times { testBar() } 5.times { this.testBar() } // OK, no violation: one arg method is not actually a test method 5.times { testBar(it) } } private static void assertSomething() { testBar() // violation, even if in helper method this.testBar() // violation, even if in helper method } public void testBar() { // ... } } ------------------------------------------------------------------------------- * {CoupledTestCase} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.13> This rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused. Static references to methods on the current test class are ignored. Example of violations: ------------------------------------------------------------------------------- class MyTest extends GroovyTestCase { public void testMethod() { // violation, static method call to other test MyOtherTest.helperMethod() // violation, instantiation of another test class new MyOtherTest() // no violation; same class def input = MyTest.getResourceAsStream('sample.txt') } } ------------------------------------------------------------------------------- * {JUnitAssertAlwaysFails} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rule that checks for JUnit <<<assert()>>> method calls with constant or literal arguments such that the assertion always fails. This includes: * <<<assertTrue(false)>>> * <<<assertTrue(0)>>> * <<<assertTrue('')>>> * <<<assertTrue([])>>> * <<<assertTrue([:])>>> * <<<assertFalse(true)>>> * <<<assertFalse('abc')>>> * <<<assertFalse(99)>>> * <<<assertFalse([123])>>> * <<<assertFalse([a:123)>>> * <<<assertNull(CONSTANT)>>>. * <<<assertNull([])>>>. * <<<assertNull([123])>>>. * <<<assertNull([:])>>>. * <<<assertNull([a:123])>>>. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {JUnitAssertAlwaysSucceeds} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rule that checks for JUnit <<<assert()>>> method calls with constant arguments such that the assertion always succeeds. This includes: * <<<assertTrue(true)>>> * <<<assertTrue(99)>>> * <<<assertTrue('abc')>>> * <<<assertTrue([123])>>> * <<<assertTrue([a:123])>>> * <<<assertFalse(false)>>> * <<<assertFalse('')>>> * <<<assertFalse(0)>>> * <<<assertFalse([])>>> * <<<assertFalse([:)>>> * <<<assertNull(null)>>> This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {JUnitFailWithoutMessage} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects JUnit calling the <<<fail()>>> method without an argument. For better error reporting you should always provide a message. * {JUnitLostTest} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> This rule checks for classes that import JUnit 4 classes and contain a <<<public>>>, instance, <<<void>>>, no-arg method named <test>* that is not annotated with the JUnit 4 <<<@Test>>> annotation. Note: This rule should be disabled for Grails 2.x projects, since the Grails test framework can use AST Transformations to automatically annotate test methods. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. Example of violations: ------------------------------------------------------------------------------- import org.junit.Test class MyTestCase { void testMe() { } // missing @Test annotation } ------------------------------------------------------------------------------- * {JUnitPublicField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Checks for public fields on a JUnit test class. There is usually no reason to have a public field (even a constant) on a test class. Fields within interfaces and fields annotated with @Rule are ignored. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. Example of violations: ------------------------------------------------------------------------------- import org.junit.Test class MyTestCase { public int count // violation public static final MAX_VALUE = 1000 // violation @Test void testMe() { } } ------------------------------------------------------------------------------- * {JUnitPublicNonTestMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rule that checks if a JUnit test class contains public methods other than standard test methods, JUnit framework methods or methods with JUnit annotations. The following public methods are ignored by this rule: * Zero-argument methods with names starting with "test" * The <<<setUp()>>> and <<<tearDown()>>> methods * Methods annotated with <<<@Test>>> * Methods annotated with <<<@Before>>> and <<<@After>>> * Methods annotated with <<<@BeforeClass>>> and <<<@AfterClass>>> * Methods annotated with <<<@Override>>> Public, non-test methods on a test class violate conventional usage of test classes, and they typically break encapsulation unnecessarily. Public, non-test methods may also hide unintentional <'Lost Tests'>. For instance, the test method declaration may (unintentionally) include methods parameters, and thus be ignored by JUnit. Or the method may (unintentionally) not follow the "test.." naming convention and not have the @Test annotation, and thus be ignored by JUnit. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {JUnitPublicProperty} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Checks for public properties defined on JUnit test classes. There is typically no need to expose a public property (with public <getter> and <setter> methods) on a test class. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | ignorePropertyNames | Specifies one or more (comma-separated) property names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ Example of violations: ------------------------------------------------------------------------------- import org.junit.Test class MyTestCase { static String id // violation def helper // violation String name // violation @Test void testMe() { } } ------------------------------------------------------------------------------- * {JUnitSetUpCallsSuper} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rule that checks that if the JUnit <<<setUp>>> method is defined, that it includes a call to <<<super.setUp()>>>. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {JUnitStyleAssertions} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects calling JUnit style assertions like <<<assertEquals>>>, <<<assertTrue>>>, <<<assertFalse>>>, <<<assertNull>>>, <<<assertNotNull>>>. Groovy 1.7 ships with a feature called the "power assert", which is an assert statement with better error reporting. This is preferable to the JUnit assertions. * {JUnitTearDownCallsSuper} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rule that checks that if the JUnit <<<tearDown>>> method is defined, that it includes a call to <<<super.tearDown()>>>. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {JUnitTestMethodWithoutAssert} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> This rule searches for test methods that do not contain assert statements. Either the test method is missing assert statements, which is an error, or the test method contains custom assert statements that do not follow a proper assert naming convention. Test methods are defined as public void methods that begin with the work test or have a @Test annotation. By default this rule applies to the default test class names, but this can be changed using the rule's applyToClassNames property. An assertion is defined as either using the <<<assert>>> keyword or invoking a method that starts with the work assert, like assertEquals, assertNull, or assertMyClassIsSimilar. Also, any method named <<<should.*>>> also counts as an assertion so that <<<shouldFail>>> methods do not trigger an assertion, any method that starts with <<<fail>> counts as an assertion, and any method that starts with <<<verify>>> counts as an assertion. Since version 0.23 CodeNarc has support for JUnit's ExpectedException. What counts as an assertion method can be overridden using the assertMethodPatterns property of the rule. The default value is this comma separated list of regular expressions: ------------------------------------------------------------------------------- String assertMethodPatterns = 'assert.*,should.*,fail.*,verify.*,expect.*' ------------------------------------------------------------------------------- If you'd like to add any method starting with 'ensure' to the ignores then you would set the value to this: ------------------------------------------------------------------------------- 'assert.*,should.*,fail.*,verify.*,ensure.*' ------------------------------------------------------------------------------- * {JUnitUnnecessarySetUp} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rule that checks checks for JUnit <<<setUp()>>> methods that contain only a call to <<<super.setUp()>>>. The method is then unnecessary. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. Here is an example of a violation: ------------------------------------------------------------------------------- class MyTest extends TestCase { void setUp() { // violation super.setUp() } } ------------------------------------------------------------------------------- * {JUnitUnnecessaryTearDown} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rule that checks checks for JUnit <<<tearDown()>>> methods that contain only a call to <<<super.tearDown()>>>. The method is then unnecessary. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. Here is an example of a violation: ------------------------------------------------------------------------------- class MyTest extends TestCase { void tearDown() { // violation super.tearDown() } } ------------------------------------------------------------------------------- * {JUnitUnnecessaryThrowsException} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Check for <<<throws>>> clauses on JUnit test methods. That is not necessary in Groovy. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. Example of violations: ------------------------------------------------------------------------------- @Test void shouldDoStuff() throws Exception { } // violation @BeforeClass void initialize() throws Exception { } // violation @Before void setUp() throws RuntimeException { } // violation @After void tearDown() throws Exception { } // violation @AfterClass void cleanUp() throws Exception { } // violation @Ignore void ignored() throws Exception { } // violation class MyTest extends GroovyTestCase { void test1() throws Exception { } // violation public void test2() throws IOException { } // violation } ------------------------------------------------------------------------------- * {SpockIgnoreRestUsed} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.14> If Spock's <<<@IgnoreRest>>> annotation appears on any method, all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed. The <specificationClassNames> and <specificationSuperclassNames> properties determine which classes are considered Spock <Specification> classes. *-----------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *-----------------------------+----------------------------------------------------------------+------------------------+ | specificationClassNames | Specifies one or more (comma-separated) class names that | <<<null>>> | | | should be treated as Spock Specification classes. The class | | | | names may optionally contain wildcards (*,?), e.g. "*Spec". | | *-----------------------------+----------------------------------------------------------------+------------------------+ | specificationSuperclassNames| Specifies one or more (comma-separated) class names that should| "*Specification" | | | be treated as Spock Specification superclasses. In other words,| | | | a class that extends a matching class name is considered a | | | | Spock Specification . The class names may optionally contain | | | | wildcards (*,?), e.g. "*Spec". | | *-----------------------------+----------------------------------------------------------------+------------------------+ Example of violations: ------------------------------------------------------------------------------- public class MySpec extends spock.lang.Specification { @spock.lang.IgnoreRest def "my first feature"() { expect: false } def "my second feature"() { given: def a = 2 when: a *= 2 then: a == 4 } } ------------------------------------------------------------------------------- * {UnnecessaryFail} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.13> In a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. Example of violations: ------------------------------------------------------------------------------- public void testSomething() { try { something() } catch (Exception e) { fail(e.message) } try { something() } catch (Exception e) { fail() } } ------------------------------------------------------------------------------- * {UseAssertEqualsInsteadOfAssertTrue} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like <<<assertEquals>>>. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {UseAssertFalseInsteadOfNegation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> In unit tests, if a condition is expected to be false then there is no sense using <<<assertTrue>>> with the negation operator. For instance, <<<assertTrue(!condition)>>> can always be simplified to <<<assertFalse(condition)>>>. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {UseAssertTrueInsteadOfAssertEqualsRule} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects JUnit calling <<<assertEquals>>> where the first parameter is a boolean. These assertions should be made by more specific methods, like <<<assertTrue>>> or <<<assertFalse>>>. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. *---------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------+----------------------------------------------------------------+------------------------+ | checkAssertStatements | If <<<true>>>, then also check assert statements, e.g. | <<<false>>> | | | <<<assert x == true>>>. | | *---------------------------+----------------------------------------------------------------+------------------------+ All of the following examples can be simplified to assertTrue or remove the true literal: ------------------------------------------------------------------------------- assertEquals(true, foo()) assertEquals("message", true, foo()) assertEquals(foo(), true) assertEquals("message", foo(), true) assertEquals(false, foo()) assertEquals("message", false, foo()) assertEquals(foo(), false) assertEquals("message", foo(), false) assert true == foo() // violation only if checkAssertStatements == true assert foo() == true : "message" // violation only if checkAssertStatements == true assert false == foo() // violation only if checkAssertStatements == true assert foo() == false : "message" // violation only if checkAssertStatements == true ------------------------------------------------------------------------------- * {UseAssertTrueInsteadOfNegation} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> In unit tests, if a condition is expected to be true then there is no sense using <<<assertFalse>>> with the negation operator. For instance, <<<assertFalse(!condition)>>> can always be simplified to <<<assertTrue(condition)>>>. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {UseAssertNullInsteadOfAssertEquals} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects JUnit calling <<<assertEquals>>> where the first or second parameter is <<<null>>>. These assertion should be made against the <<<assertNull>>> method instead. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. * {UseAssertSameInsteadOfAssertTrue} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> This rule detects JUnit calling <<<assertTrue>>> or <<<assertFalse>>> where the first or second parameter is an <<<Object#is()>>> call testing for reference equality. These assertion should be made against the <<<assertSame>>> or <<<assertNotSame>>> method instead. This rule sets the default value of the <applyToClassNames> property to only match class names ending in 'Test', 'Tests' or 'TestCase'. ���������������������������CodeNarc-0.23/src/site/apt/codenarc-developer-guide.apt���������������������������������������������0000644�0001750�0001750�00000010000�12006632016�022310� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Developer Guide -------------------------------------------------- CodeNarc - Developer Guide ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<Contents>> * {{{The_codenarc_Command-line_Script}The codenarc Command-line Script}} * {{{New_Rule_Checklist}New Rule Checklist}} * {{{Before_You_Submit_a_Patch_or_Check-In_Code}Before You Submit a Patch or Check-In Code}} [] * {The codenarc Command-line Script} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There is a <<<codenarc.groovy>>> command-line script in the root directory of the project. It is intended to streamline common development tasks. Currently, it supports a <<<create-rule>>> task for creating new <<CodeNarc>> rules. ** codenarc create-rule ~~~~~~~~~~~~~~~~~~~~~~~~ The <<<create-rule>>> task performs the following steps: * Prompt for the rule name * Prompt for the existing ruleset (category) name to which the rule is added * Create a new rule class file in the proper package (under src/main/groovy) * Create a new rule test class file (under src/test/groovy) * Add placeholder description messages for the new rule to "codenarc-base-messages.properties" * Add the new rule to the chosen ruleset XML file <<RUNNING>> On <<Unix/Mac>>, you can run the following from the project root directory: <<<./codenarc create-rule>>> On <<Windows>>, you can run: <<<codenarc create-rule>>>. (If <<Windows>> is not configured to automatically run *.groovy files, just can run <<<groovy codenarc create-rule>>>) <<AFTER YOU RUN>> <<<codenarc create-rule>>> After you run <<<codenarc create-rule>>>, finish up the rule implementation, including the following: [[1]] Edit the generated rule class and associated test class to add the proper implementation. [[2]] Modify the description messages for the new rule in "codenarc-base-messages.properties". Move the message entries under the proper ruleset/category section within the file. [[4]] Add description to "src/main/site/apt/codenarc-rules-XX.apt" document in the site folder. [[5]] Run <<<mvn site>>> from the command-line. Make sure all of the tests pass and review the new rule description on the appropriate ruleset page on the project site. * {New Rule Checklist} ~~~~~~~~~~~~~~~~~~~~~~~ Perform the following steps when creating a new rule. See {{{The_codenarc_Command-line_Script}The codenarc Command-line Script}} for information on the command-line script that automates a good bit of the boilerplate, as indicated below. [[1]] Implement the new <Rule> class. This is typically a subclass of <<<AbstractAstVisitorRule>>>. [1] [[2]] Implement the associated <Rule> test class. This is typically a subclass of <<<AbstractRuleTestCase>>>. [1] [[3]] Add the new rule class name to the appropriate <RuleSet> file under "src/main/resources/rulesets". [1] [[4]] Add the new rule description entries to "src/main/resources/codenarc-base-messages.properties". This includes both "<RuleName>.description" and "<RuleName>.description.html" property entries. [1] [[5]] Run <<<LoadAllPredefinedRuleSetsTest>>>. [[6]] Add a description of the new rule to the appropriate "src/main/site/apt/codenarc-rules-XX.apt" document. * {Before You Submit a Patch or Check-In Code} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Please do the following before submitting a patch or checking in code: * Run the full <<CodeNarc>> test suite. This includes a test called <<<RunCodeNarcAgainstProjectSourceCodeTest>>> that runs <<CodeNarc>> against its own source code (including any code that you have added or changed). ** NOTES ~~~~~~~~~~ * [1] These files are created (skeletons) or updated automatically if you run the <<<codenarc create-rule>>> script to create the rule. See {{{The_codenarc_Command-line_Script}The codenarc Command-line Script}} CodeNarc-0.23/src/site/apt/codenarc-rules-logging.apt�����������������������������������������������0000644�0001750�0001750�00000013575�12054462210�022032� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Logging Rules -------------------------------------------------- Logging Rules ("<rulesets/logging.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {LoggerForDifferentClass} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Checks for instantiating a logger for a class other than the current class. Checks for logger instantiations for <<Log4J>>, <<SLF4J>>, <<Logback>>, <<Apache Commons Logging>> and <<Java Logging API (java.util.logging)>>. This rule contains a parameter <<<allowDerivedClasses>>>. When set, a logger may be created about this.getClass(). Limitations: * Only checks Loggers instantiated within a class field or property (not variables or expressions within a method) * For <<Log4J>>: Does not catch Logger instantiations if you specify the full package name for the <<<Logger>>> class: e.g. <<<org.apache.log4.Logger.getLogger(..)>>> * For <<SLF4J>> and <<Logback>>: Does not catch Log instantiations if you specify the full package name for the <<<LoggerFactory>>> class: e.g. <<<org.slf4j.LoggerFactory.getLogger(..)>>> * For <<Commons Logging>>: Does not catch Log instantiations if you specify the full package name for the <<<LogFactory>>> class: e.g. <<<org.apache.commons.logging.LogFactory.getLog(..)>>> * For <<Java Logging API>>: Does not catch Logger instantiations if you specify the full package name for the <<<Logger>>> class: e.g. <<<java.util.logging.Logger.getLogger(..)>>> [] Here are examples of <<Log4J>> or <<Java Logging API>> code that cause violations: ------------------------------------------------------------------------------- class MyClass { private static final LOG = Logger.getLogger(SomeOtherClass) // violation def log1 = Logger.getLogger(SomeOtherClass.class) // violation def log2 = Logger.getLogger(SomeOtherClass.class.name) // violation } ------------------------------------------------------------------------------- Here are examples of <<Commons Logging>> code that cause violations: ------------------------------------------------------------------------------- class MyClass { private static final LOG = LogFactory.getLog(SomeOtherClass) // violation Log log1 = LogFactory.getLog(SomeOtherClass.class) // violation def log2 = LogFactory.getLog(SomeOtherClass.class.getName()) // violation } ------------------------------------------------------------------------------- Here are examples of code that does NOT cause violations: ------------------------------------------------------------------------------- // Log4J or Java Logging API class MyClass { private static final LOG = Logger.getLogger(MyClass) // ok def log2 = Logger.getLogger(MyClass.class) // ok private static log3 = Logger.getLogger(MyClass.getClass().getName()) // ok private static log4 = Logger.getLogger(MyClass.getClass().name) // ok private static log5 = Logger.getLogger(MyClass.class.getName()) // ok private static log6 = Logger.getLogger(MyClass.class.name) // ok } // Commons Logging class MyClass { private static final LOG = LogFactory.getLog(MyClass) // ok def log2 = LogFactory.getLog(MyClass.class) // ok private static log3 = LogFactory.getLog(MyClass.getClass().getName()) // ok private static log4 = LogFactory.getLog(MyClass.getClass().name) // ok private static log5 = LogFactory.getLog(MyClass.class.getName()) // ok private static log6 = LogFactory.getLog(MyClass.class.name) // ok } ------------------------------------------------------------------------------- * {LoggingSwallowsStacktrace} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> If you are logging an exception then the proper API is to call error(Object, Throwable), which will log the message and the exception stack trace. If you call error(Object) then the stacktrace may not be logged. * {LoggerWithWrongModifiers} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Logger objects should be declared private, static and final. This rule has a property: <<<allowProtectedLogger>>>, which defaults to false. Set it to true if you believe subclasses should have access to a Logger in a parent class and that Logger should be declared protected or public. This rule has a property: <<<allowNonStaticLogger>>>, which defaults to false. Set it to true if you believe a logger should be allowed to be non-static. * {MultipleLoggers} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> This rule catches classes that have more than one logger object defined. Typically, a class has zero or one logger objects. * {Println} Rule ~~~~~~~~~~~~~~~ Checks for calls to <<<this.print()>>>, <<<this.println()>>> or <<<this.printf()>>>. Consider using a standard logging facility instead. * {PrintStackTrace} Rule ~~~~~~~~~~~~~~~~~~~~~~~~ Checks for calls to <<<Throwable.printStackTrace()>>> or <<<StackTraceUtils.printSanitizedStackTrace(Throwable)>>>. Consider using a standard logging facility instead. * {SystemErrPrint} Rule ~~~~~~~~~~~~~~~~~~~~~~ Checks for calls to <<<System.err.print()>>>, <<<System.err.println()>>> or <<<System.err.printf()>>>. Consider using a standard logging facility instead. * {SystemOutPrint} Rule ~~~~~~~~~~~~~~~~~~~~~~ Checks for calls to <<<System.out.print()>>>, <<<System.out.println()>>> or <<<System.out.printf()>>>. Consider using a standard logging facility instead. �����������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-serialization.apt�����������������������������������������0000644�0001750�0001750�00000011041�12143501116�023241� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Serialization Rules -------------------------------------------------- Serialization Rules ("<rulesets/serialization.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {EnumCustomSerializationIgnored} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Checks for enums that define <<<writeObject()>>> or <<<writeReplace()>>> methods, or declare <<<serialPersistentFields>>> or <<<serialVersionUID>>> fields, all of which are ignored for enums. From the javadoc for <<<ObjectOutputStream>>>: <The process by which enum constants are serialized cannot be customized; any class-specific writeObject and writeReplace methods defined by enum types are ignored during serialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored--all enum types have a fixed serialVersionUID of 0L.> Example of violations: ------------------------------------------------------------------------------- enum MyEnum { ONE, TWO, THREE private static final long serialVersionUID = 1234567L // violation private static final ObjectStreamField[] serialPersistentFields = // violation { new ObjectStreamField("name", String.class) } String name; Object writeReplace() throws ObjectStreamException { .. } // violation private void writeObject(ObjectOutputStream stream) { .. } // violation } ------------------------------------------------------------------------------- * {SerialPersistentFields} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> To use a <<Serializable>> object's <<<serialPersistentFields>>> correctly, it must be declared <<<private>>>, <<<static>>>, and <<<final>>>. The Java Object Serialization Specification allows developers to manually define <<<Serializable>>> fields for a class by specifying them in the <<<serialPersistentFields>>> array. This feature will only work if <<<serialPersistentFields>>> is declared as <<<private>>>, <<<static>>>, and <<<final>>>. Also, specific to Groovy, the field must be of type <<<ObjectStreamField[]>>>, and cannot be <<<Object>>>. References: * Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 485 * Sun Microsystems, Inc. Java Sun Tutorial [] Example of violations: ------------------------------------------------------------------------------- class MyClass implements Serializable { public ObjectStreamField[] serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } // the JVM sees the field type as Object, which won't work class MyOtherClass implements Serializable { private static final serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } ------------------------------------------------------------------------------- * {SerialVersionUID} Rule ~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> A <<serialVersionUID>> is normally intended to be used with Serialization. It needs to be of type <<<long>>>, <<<static>>>, and <<<final>>>. Also, it should be declared <<<private>>>. Providing no modifier creates a <Property> and Groovy generates a <getter>, which is probably not intended. From API javadoc for <<<java.io.Serializable>>>: <It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.> * {SerializableClassMustDefineSerialVersionUID} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Classes that implement <<<Serializable>>> should define a <<<serialVersionUID>>>. Deserialization uses this number to ensure that a loaded class corresponds exactly to a serialized object. If you don't define serialVersionUID, the system will make one by hashing most of your class's features. Then if you change anything, the UID will change and Java won't let you reload old data. An example of a missing serialVersionUID: ------------------------------------------------------------------------------- class MyClass imlements Serializable { // missing serialVersionUID } ------------------------------------------------------------------------------- �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-TextReportWriter.apt��������������������������������������������0000644�0001750�0001750�00000010774�12405405033�022567� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ---------------------------------------------------------- CodeNarc TextReportWriter and IdeTextReportWriter ---------------------------------------------------------- TextReportWriter and IdeTextReportWriter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Description ~~~~~~~~~~~~~ The <<<org.codenarc.report.TextReportWriter>>> class (type="text") produces a simple text report of the <<CodeNarc>> results. See a {{{./SampleCodeNarcTextReport.txt}Sample Report}}. The <<<org.codenarc.report.IdeTextReportWriter>>> class (type="ide") also produces a text report of the <<CodeNarc>> results, and includes IDE-compatible (Eclipse, Idea) hyperlinks to source code for violations. * Option Nested Elements ~~~~~~~~~~~~~~~~~~~~~~~~ The <<option>> element is a child of the <<report>> element and defines a report-specific option for a report. The <<<TextReportWriter>>> and <<<IdeTextReportWriter>>> classes supports the following options: *---------------------+----------------------------------------------------------------+------------------------+ | <<Attribute>> | <<Description>> | <<Required>> | *---------------------+----------------------------------------------------------------+------------------------+ | maxPriority | The maximum priority level for violations in the report. For | 3 | | | instance, setting <maxPriority> to 2 will result in the report | | | | containing only priority 1 and 2 violations (and omitting | | | | violations with priority 3). | | *---------------------+----------------------------------------------------------------+------------------------+ | outputFile | The path and filename for the output report file. | No | *---------------------+----------------------------------------------------------------+------------------------+ | title | The title for the output report. | No | *---------------------+----------------------------------------------------------------+------------------------+ | writeToStandardOut | Set to "true" or <<<true>>> to write out the report to | No | | | <stdout> (<<<System.out>>>) instead of writing to a file. | | *---------------------+----------------------------------------------------------------+------------------------+ * Examples ~~~~~~~~~~ Here is an example Ant XML build file illustrating configuration of <<<org.codenarc.report.TextReportWriter>>>. Note that the report <<type>> is specified as <<"text">>. +---------------------------------------------------------------------------------------- <taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/> <target name="runCodeNarc"> <codenarc ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml" maxPriority1Violations="0"> <report type="text"> <option name="outputFile" value="reports/CodeNarcReport.txt" /> <option name="title" value="My Sample Code" /> </report> <fileset dir="src"> <include name="**/*.groovy"/> </fileset> </codenarc> </target> +---------------------------------------------------------------------------------------- Here is an example Ant XML build file illustrating configuration of <<<org.codenarc.report.IdeTextReportWriter>>>. Note that the report <<type>> is specified as <<"ide">>. The <<"ide">> report type will automatically write the report to <stdout>. +---------------------------------------------------------------------------------------- <taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/> <target name="runCodeNarc"> <codenarc ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml" maxPriority1Violations="0"> <report type="ide"> <option name="title" value="My Sample Code" /> </report> <fileset dir="src"> <include name="**/*.groovy"/> </fileset> </codenarc> </target> +---------------------------------------------------------------------------------------- ����CodeNarc-0.23/src/site/apt/codenarc-rules-unused.apt������������������������������������������������0000644�0001750�0001750�00000021621�12061230330�021670� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Unused Rules -------------------------------------------------- Unused Rules ("<rulesets/unused.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {UnusedArray} Rule ~~~~~~~~~~~~~~~~~~~ Checks for array allocations that are not assigned or used, unless it is the last statement within a block (because it may be the intentional return value). Examples include: ------------------------------------------------------------------------------- int myMethod() { new String[3] // unused return -1 } String[] myMethod() { new String[3] // OK (last statement in block) } def closure = { doStuff() new Date[3] // unused doOtherStuff() } def closure = { new Date[3] } // OK (last statement in block) ------------------------------------------------------------------------------- * {UnusedObject} Rule ~~~~~~~~~~~~~~~~~~~~ Checks for object allocations that are not assigned or used, unless it is the last statement within a block (because it may be the intentional return value). Examples include: By default, this rule does not analyze test files. This rule sets the default value of the <doNotApplyToFilesMatching> property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'. Invoking constructors without using the result is a common pattern in tests. ------------------------------------------------------------------------------- int myMethod() { new BigDecimal("23.45") // unused return -1 } BigDecimal myMethod() { new BigDecimal("23.45") // OK (last statement in block) } def closure = { doStuff() new Date() // unused doOtherStuff() } def closure = { new Date() } // OK (last statement in block) ------------------------------------------------------------------------------- * {UnusedPrivateField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for private fields that are not referenced within the same class. Note that the <<<private>>> modifier is not currently "respected" by Groovy code (i.e., Groovy can access <<<private>>> members within other classes). By default, fields named <<<serialVersionUID>>> are ignored. The rule has a property named ignoreFieldNames, which can be set to ignore other field names as well. For instance, to ignore fields named 'fieldx', set the property to the 'fieldx, serialVersionUID' *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreFieldNames | Specifies one or more (comma-separated) field names that | serialVersionUID | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ Known limitations: * Does not recognize field access when field name is a GString (e.g. <<<this."${fieldName}">>>) * Does not recognize access of private field of another instance (i.e. other than <<<this>>>) * {UnusedPrivateMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for private methods that are not referenced within the same class. Note that the <<<private>>> modifier is not currently "respected" by Groovy code (i.e., Groovy can access <<<private>>> members within other classes). Known limitations: * Does not recognize method reference through property access (e.g. <<<getName()>>> accessed as <<<x.name>>>) * Does not recognize method invocations when method name is a GString (e.g. <<<this."${methodName}"()>>>) * Does not recognize invoking private method of another instance (i.e. other than <<<this>>>) * Does not differentiate between multiple private methods with the same name but different parameters (i.e., overloaded) * Does not check for unused constructors * {UnusedPrivateMethodParameter} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Checks for parameters to private methods that are not referenced within the method body. Note that the <<<private>>> modifier is not currently "respected" by Groovy code (i.e., Groovy can access <<<private>>> members within other classes). Known limitations: * Does not recognize parameter references within an inner class. See {{{https://sourceforge.net/tracker/index.php?func=detail&aid=3155974&group_id=250145&atid=1126573}CodeNarc bug #3155974}}. * Does not recognize parameter references when parameter name is a GString (e.g. <<<println "${parameterName}">>>) <Since CodeNarc 0.14> * You can specify an ignore list using the 'ignoreRegex' property. By default, a parameter named 'ignore' or 'ignored' does not trigger a violation (the regex value is 'ignore|ignored'). You can add your own ignore list using this property. * {UnusedMethodParameter} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> This rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override. * This rule ignores <<<main()>>> methods. In Groovy, the <<<main()>> method can either specify a <<<void>>> return type or else omit a return type (be dynamically typed). The <<<main()>> method must have exactly one parameter. That parameter can either be typed as <<<String[]>>> or else the type can be omitted (be dynamically typed). And the <<<main()>> method must be <<<static>>>. * You can specify an ignore list of parameter names using the 'ignoreRegex' property. By default, a parameter named 'ignore' or 'ignored' does not trigger a violation (the regex value is 'ignore|ignored'). You can add your own ignore list using this property. * You can specify a class name pattern to ignore using the 'ignoreClassRegex' property. By default classes named '*.Category' are ignored because they are category classes and have unused parameters in static methods. Example of violations: ------------------------------------------------------------------------------- class MyClass { def method(def param) { // param is unused } } ------------------------------------------------------------------------------- Example of code that does not cause violations: ------------------------------------------------------------------------------- class MyClass { @Override def otherMethod(def param) { // this is OK because it overrides a super class } } class MyCategory { // Category classes are ignored by default void myMethod1(String string, int value) { } void myMethod1(String string, int value, name) { } } class MainClass1 { // main() methods are ignored public static void main(String[] args) { } } class MainClass2 { // This is also a valid Groovy main() method static main(args) { } } ------------------------------------------------------------------------------- * {UnusedVariable} Rule ~~~~~~~~~~~~~~~~~~~~~~~ Checks for variables that are never referenced. The rule has a property named ignoreVariableNames, which can be set to ignore some variable names. For instance, to ignore fields named 'unused', set the property to 'unused'. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreVariableNames | Specifies one or more (comma-separated) variable names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ Known limitations: * Incorrectly considers a variable referenced if another variable with the same name is referenced elsewhere (in another scope/block). ���������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-ant-task.apt����������������������������������������������������0000644�0001750�0001750�00000015302�12405402714�020767� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc Ant Task -------------------------------------------------- CodeNarc - Ant Task ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Description ~~~~~~~~~~~~~ The <<CodeNarc>> Ant Task is implemented by the <<<org.codenarc.ant.CodeNarcTask>>> class. * Parameters ~~~~~~~~~~~~ *------------------------+----------------------------------------------------------------+------------------------+ | <<Attribute>> | <<Description>> | <<Required>> | *------------------------+----------------------------------------------------------------+------------------------+ | ruleSetFiles | The paths to the Groovy or XML RuleSet definition files. This | YES | | | can be a single file path, or multiple paths separated by | | | | commas. By default, the paths specified are relative to the | | | | classpath. But each path may be optionally prefixed by any | | | | of the valid java.net.URL prefixes, such as "file:" (to load | | | | from a relative or absolute filesystem path), or "http:". | | *------------------------+----------------------------------------------------------------+------------------------+ | maxPriority1Violations | The maximum number of priority 1 violations allowed before | NO | | | failing the build (throwing a <<<BuildException>>>). | | *------------------------+----------------------------------------------------------------+------------------------+ | maxPriority2Violations | The maximum number of priority 2 violations allowed before | NO | | | failing the build (throwing a <<<BuildException>>>). | | *------------------------+----------------------------------------------------------------+------------------------+ | maxPriority3Violations | The maximum number of priority 3 violations allowed before | NO | | | failing the build (throwing a <<<BuildException>>>). | | *------------------------+----------------------------------------------------------------+------------------------+ * Report Nested Element ~~~~~~~~~~~~~~~~~~~~~~~ The <<report>> nested element defines the format and output file for the analysis report. *----------------------+----------------------------------------------------------------+------------------------+ | <<Attribute>> | <<Description>> | <<Required>> | *----------------------+----------------------------------------------------------------+------------------------+ | type | The type of the output report. Must be either one of the | Yes | | | predefined type names: "html", "xml", "text", "console", "ide" | | | | or else the fully-qualified class name | | | | of a class (accessible on the classpath) that implements the | | | | <<<org.codenarc.report.ReportWriter>>> interface. | | *----------------------+----------------------------------------------------------------+------------------------+ | toFile <(Deprecated)>| The path and filename for the output report file. | No | | | This is deprecated. Use the \<option\> nested element instead. | | *----------------------+----------------------------------------------------------------+------------------------+ | title <(Deprecated)> | The title for the output report. | No | | | This is deprecated. Use the \<option\> nested element instead. | | *----------------------+----------------------------------------------------------------+------------------------+ Notes: * The "ide" report <type> creates an <<<IdeTextReportWriter>>> and sets its <writeToStandardOut> property to <<<true>>>. The generated report includes IDE-compatible (Eclipse, Idea) hyperlinks to source code for violations. * The "console" report <type> creates a <<<TextReportWriter>>> and sets its <writeToStandardOut> property to <<<true>>>. ** Option Nested Element ~~~~~~~~~~~~~~~~~~~~~~~~ The <<\<option\>>> element is a child of the <<\<report\>>> element and defines a report-specific option for a report. You specify the option <<name> and <<value>> as attributes within the <<\<option\>>> element. See the {{{Example}Example}} below. * Fileset Nested Element ~~~~~~~~~~~~~~~~~~~~~~~ At least one <<fileset>> nested element is required, and is used to specify the source files that <<CodeNarc>> should analyze. This is the standard Ant <FileSet>, and is quite powerful and flexible. See the {{{http://ant.apache.org/manual/index.html}Apache Ant Manual}} for more information on <FileSets>. * {Example} ~~~~~~~~~~~ Here is an example Ant XML build file. +---------------------------------------------------------------------------------------- <taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/> <target name="runCodeNarc"> <codenarc ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml" maxPriority1Violations="0"> <report type="html"> <option name="outputFile" value="reports/CodeNarcAntReport.html" /> <option name="title" value="My Sample Code" /> </report> <fileset dir="src"> <include name="**/*.groovy"/> </fileset> </codenarc> </target> +---------------------------------------------------------------------------------------- Things to note: * Three <RuleSet> files are specified (<basic>, <exceptions> and <imports>). * The <fileset> specifies that all ".groovy" files are analyzed. * Remember that you need the <<log4j>> jar (and a "log4j.properties" file) on the classpath. * Logging and Troubleshooting ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Be sure to have a "log4j.properties" or "log4j.xml" file on the classpath so that any errors are logged. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-concurrency.apt�������������������������������������������0000644�0001750�0001750�00000107445�12137611550�022743� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Concurrency Rules -------------------------------------------------- Concurrency Rules ("<rulesets/concurrency.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {BusyWait} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Busy waiting (forcing a <<<Thread.sleep()>>> while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the <<<java.util.concurrent>>> package. Example of violations: ------------------------------------------------------------------------------- while (x) { Thread.sleep(1000) } while (x) { Thread.sleep(1000) { /* interruption handler */} } for (int x = 10; x; x--) { sleep(1000) // sleep is added to Object in Groovy } // here is the proper way to wait: countDownLatch.await() // this is weird code to write, but does not cause a violation for (def x : collections) { sleep(1000) } while (x) { // you should use a lock here, but technically you are // not just busy waiting because you are doing other work doSomething() sleep(1000) } ------------------------------------------------------------------------------- * {DoubleCheckedLocking} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> This rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern. A full explanation of why double checked locking is broken in Java is available on Wikipedia: {{{http://en.wikipedia.org/wiki/Double-checked_locking}}} Example of violations: ------------------------------------------------------------------------------- if (object == null) { synchronized(this) { if (object == null) { // createObject() could be called twice depending // on the Thread Scheduler. object = createObject() } } } // there are several idioms to fix this problem. def result = object; if (result == null) { synchronized(this) { result = object; if (result == null) object = result = createObject() } } // and a better solution for a singleton: class myClass { private static class ObjectHolder { public static Object object = createObject() } public static Object getObject() { return ObjectHolder.object; } } ------------------------------------------------------------------------------- * {InconsistentPropertyLocking} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Class contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all. This may result in incorrect behavior at runtime, as callers of the get and set methods will not necessarily lock correctly and my see an inconsistent state for the object. The get and set method should both be guarded by @WithReadLock/@WithWriteLock or neither should be guarded. Example of violations: ------------------------------------------------------------------------------- class Person { String name Date birthday boolean deceased boolean parent @WithWriteLock setName(String name) { this.name = name } // violation, get method should be locked String getName() { name } // violation, set method should be locked void setBirthday(Date birthday) { this.birthday = birthday } @WithReadLock String getBirthday() { birthday } // violation, set method should be locked void setDeceased(boolean deceased) { this.deceased = deceased } @WithReadLock boolean isDeceased() { deceased } @WithWriteLock void setParent(boolean parent) { this.parent = parent } // violation, get method should be locked boolean isParent() { parent } } ------------------------------------------------------------------------------- * {InconsistentPropertySynchronization} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Class contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not. This may result in incorrect behavior at runtime, as callers of the get and set methods will not necessarily see a consistent state for the object. The get and set method should both be synchronized or neither should be synchronized. Example of violations: ------------------------------------------------------------------------------- class Person { String name Date birthday boolean deceased boolean parent int weight synchronized setName(String name) { this.name = name } // violation, get method should be synchronized String getName() { name } // violation, set method should be synchronized void setBirthday(Date birthday) { this.birthday = birthday } synchronized String getBirthday() { birthday } // violation, set method should be synchronized void setDeceased(boolean deceased) { this.deceased = deceased } synchronized boolean isDeceased() { deceased } synchronized void setParent(boolean parent) { this.parent = parent } // violation, get method should be synchronized boolean isParent() { parent } // violation get method should be synchronized @groovy.transform.Synchronized void setWeight(int value) { weight = value } } ------------------------------------------------------------------------------- * {NestedSynchronization} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This rule reports occurrences of nested <<<synchronized>>> statements. Nested <<<synchronized>>> statements should be avoided. Nested <<<synchronized>>> statements are either useless (if the lock objects are identical) or prone to deadlock. Note that a <closure> or an <anonymous inner class> carries its own context (scope). A <<<synchronized>>> statement within a <closure> or an <anonymous inner class> defined within an outer <<<synchronized>>> statement does not cause a violation (though nested <<<synchronized>>> statements within either of those will). Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def myMethod() { synchronized(this) { // do something ... synchronized(this) { // do something else ... } } } ------------------------------------------------------------------------------- * {StaticCalendarField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> <<<Calendar>>> objects should not be used as <<<static>>> fields. Calendars are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. Under 1.4 problems seem to surface less often than under Java 5 where you will probably see random <<<ArrayIndexOutOfBoundsException>>> or <<<IndexOutOfBoundsException>>> in <<<sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate()>>>. You may also experience serialization problems. Using an instance field or a <<<ThreadLocal>>> is recommended. For more information on this see Sun Bug #6231579 and Sun Bug #6178997. Examples: ------------------------------------------------------------------------------- // Violations class MyClass { static Calendar calendar1 static java.util.Calendar calendar2 static final CAL1 = Calendar.getInstance() static final CAL2 = Calendar.getInstance(Locale.FRANCE) static def cal3 = Calendar.getInstance(timezone) static Object cal4 = Calendar.getInstance(timezone, locale) } // These usages are OK class MyCorrectClass { private final Calendar calendar1 static ThreadLocal<Calendar> calendar2 } ------------------------------------------------------------------------------- * {StaticConnection} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Creates violations when a <<<java.sql.Connection>>> object is used as a <<<static>>> field. Database connections stored in <<<static>>> fields will be shared between threads, which is unsafe and can lead to race conditions. A transactional resource object such as database connection can only be associated with one transaction at a time. For this reason, a connection should not be shared between threads and should not be stored in a static field. See Section 4.2.3 of the <J2EE Specification> for more details. References: * Standards Mapping - Security Technical Implementation Guide Version 3 - (STIG 3) APP3630.1 CAT II * Standards Mapping - Common Weakness Enumeration - (CWE) CWE ID 362, CWE ID 567 * Standards Mapping - SANS Top 25 2009 - (SANS 2009) Insecure Interaction - CWE ID 362 * Standards Mapping - SANS Top 25 2010 - (SANS 2010) Insecure Interaction - CWE ID 362 * Java 2 Platform Enterprise Edition Specification, v1.4 Sun Microsystems * {StaticDateFormatField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> <<<DateFormat>>> objects should not be used as <<<static>>> fields. DateFormats are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. Under 1.4 problems seem to surface less often than under Java 5 where you will probably see random <<<ArrayIndexOutOfBoundsException>>> or <<<IndexOutOfBoundsException>>> in <<<sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate()>>>. You may also experience serialization problems. Using an instance field or a <<<ThreadLocal>>> is recommended. For more information on this see Sun Bug #6231579 and Sun Bug #6178997. Examples: ------------------------------------------------------------------------------- // Violations class MyClass { static DateFormat dateFormat1 static java.text.DateFormat dateFormat2 static final DATE1 = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE) static final def DATE2 = DateFormat.getDateInstance(DateFormat.LONG) static Object date3 = DateFormat.getDateInstance() static final DATETIME1 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.FRANCE) static final def DATETIME2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT) static final Object DATETIME3 = DateFormat.getDateTimeInstance() static final TIME1 = DateFormat.getTimeInstance(DateFormat.LONG, Locale.FRANCE) static final def TIME2 = DateFormat.getTimeInstance(DateFormat.LONG) static final Object TIME3 = DateFormat.getTimeInstance() } // These usages are OK class MyCorrectClass { private DateFormat calendar1 static ThreadLocal<DateFormat> calendar2 } ------------------------------------------------------------------------------- * {StaticMatcherField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Matcher objects should not be used as static fields. Calendars are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. Example of violations: ------------------------------------------------------------------------------- // two violations class MyClass { static Matcher matcher1 static java.util.regex.Matcher matcher2 } // these usages are OK class MyCorrectClass { private Matcher matcher1 static ThreadLocal<Matcher> matcher2 } ------------------------------------------------------------------------------- * {StaticSimpleDateFormatField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> <<<SimpleDateFormat>>> objects should not be used as <<<static>>> fields. SimpleDateFormats are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. Under 1.4 problems seem to surface less often than under Java 5 where you will probably see random <<<ArrayIndexOutOfBoundsException>>> or <<<IndexOutOfBoundsException>>> in <<<sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate()>>>. You may also experience serialization problems. Using an instance field or a <<<ThreadLocal>>> is recommended. For more information on this see Sun Bug #6231579 and Sun Bug #6178997. Examples: ------------------------------------------------------------------------------- // Violations class MyClass { static SimpleDateFormat dateFormat1 static java.text.SimpleDateFormat dateFormat2 static final DATE1 = new SimpleDateFormat() static final DATE2 = new SimpleDateFormat('MM/dd') static final DATE3 = new SimpleDateFormat('MM/dd', DateFormatSymbols.instance) static date4 = new SimpleDateFormat('MM/dd', Locale.FRANCE) static date5 = new java.text.SimpleDateFormat('MM/dd') } // These usages are OK class MyCorrectClass { private SimpleDateFormat calendar1 static ThreadLocal<SimpleDateFormat> calendar2 } ------------------------------------------------------------------------------- * {SynchronizedMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This rule reports uses of the <<<synchronized>>> keyword on methods. Synchronized methods are the same as synchronizing on 'this', which effectively make your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- synchronized def myMethod() { // do stuff ... } ------------------------------------------------------------------------------- * {SynchronizedOnGetClass} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Checks for synchronization on <<<getClass()>>> rather than class literal. This instance method synchronizes on <<<this.getClass()>>>. If this class is subclassed, subclasses will synchronize on the class object for the subclass, which isn't likely what was intended. * {SynchronizedOnBoxedPrimitive} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> The code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock. Example of violations: ------------------------------------------------------------------------------- class MyClass { Byte byte1 = 100 Short short1 = 1 Double double1 = 1 Integer integer1 = 1 Long long1 = 1 Float float1 = 1 Character char1 = 1 byte byte2 = getValue() short short2 = getValue() double double2 = getValue() int integer2 = getValue() long long2 = getValue() float float2 = getValue() char char2 = getValue() def byte3 = new Byte((byte)100) def short3 = new Short((short)1) def double3 = new Double((double)1) def integer3 = new Integer(1) def long3 = new Long(1) def float3 = new Float(1) def char3 = new Character((char)'1') def byte4 = 1 as byte def short4 = 1 as short def double4 = 1 as double def integer4 = 1 as int def long4 = 1 as long def float4 = 1 as float def char4 = 1 as char def byte5 = 1 as Byte def short5 = 1 as Short def double5 = 1 as Double def integer5 = 1 as Integer def long5 = 1 as Long def float5 = 1 as Float def char5 = 1 as Character def byte6 = (byte)1 def short6 = (short)1 def double6 = (double)1 def integer6 = (int)1 def long6 = (long)1 def float6 = (float)1 def char6 = (char)1 def method() { // all of these synchronization blocks produce violations synchronized(byte1) {} synchronized(short1) {} synchronized(double1) {} synchronized(integer1) {} synchronized(long1) {} synchronized(float1) {} synchronized(char1) {} synchronized(byte2) {} synchronized(short2) {} synchronized(double2) {} synchronized(integer2) {} synchronized(long2) {} synchronized(float2) {} synchronized(char2) {} synchronized(byte3) {} synchronized(short3) {} synchronized(double3) {} synchronized(integer3) {} synchronized(long3) {} synchronized(float3) {} synchronized(char3) {} synchronized(byte4) {} synchronized(short4) {} synchronized(double4) {} synchronized(integer4) {} synchronized(long4) {} synchronized(float4) {} synchronized(char4) {} synchronized(byte5) {} synchronized(short5) {} synchronized(double5) {} synchronized(integer5) {} synchronized(long5) {} synchronized(float5) {} synchronized(char5) {} synchronized(byte6) {} synchronized(short6) {} synchronized(double6) {} synchronized(integer6) {} synchronized(long6) {} synchronized(float6) {} synchronized(char6) {} } } ------------------------------------------------------------------------------- And here is an in-depth example of how it works within inner classes and such: ------------------------------------------------------------------------------- class MyClass { final String lock = false def method() { // violation synchronized(lock) { } } } class MyClass { final String lock = false class MyInnerClass { def method() { // violation synchronized(lock) { } } } } class MyClass { // implicit typing final def lock = true def method() { // violation synchronized(lock) { } } } class MyClass { // implicit typing final def lock = new Object[0] // correct idiom def method() { return new Runnable() { final def lock = false // shadows parent from inner class public void run() { // violation synchronized(stringLock) { } } } } } class MyClass { // implicit typing final def lock = new Object[0] // correct idiom class MyInnerClass { final def lock = true // shadows parent from inner class def method() { // violation synchronized(stringLock) { } } } } ------------------------------------------------------------------------------- * {SynchronizedOnString} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Synchronization on a String field can lead to deadlock. Constant Strings are interned and shared across all other classes loaded by the JVM. Thus, this could is locking on something that other code might also be locking. This could result in very strange and hard to diagnose blocking and deadlock behavior. See {{{http://www.javalobby.org/java/forums/t96352.html and http://jira.codehaus.org/browse/JETTY-352}JETTY-352}}. Examples: ------------------------------------------------------------------------------- class MyClass { final String stringLock = "stringLock" def method() { // violation synchronized(stringLock) { } } } class MyClass { final String stringLock = "stringLock" class MyInnerClass { def method() { synchronized(stringLock) { } } } } class MyClass { // implicit typing final def stringLock = "stringLock" def method() { // violation synchronized(stringLock) { } } } class MyClass { // implicit typing final def lock = new Object[0] // correct idiom def method() { return new Runnable() { final def lock = "" // shadows parent from inner class public void run() { // violation synchronized(stringLock) { } } } } } class MyClass { // implicit typing final def lock = new Object[0] // correct idiom class MyInnerClass { final def lock = "" // shadows parent from inner class def method() { // violation synchronized(stringLock) { } } } } ------------------------------------------------------------------------------- * {SynchronizedOnThis} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This rule reports uses of the <<<synchronized>>> blocks where the synchronization reference is 'this'. Doing this effectively makes your synchronization policy public and modifiable by other objects. To avoid possibilities of deadlock, it is better to synchronize on internal objects. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def method3() { synchronized(this) { // do stuff ... } } ------------------------------------------------------------------------------- * {SynchronizedReadObjectMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Catches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style. Examples: ------------------------------------------------------------------------------- class MyClass implements Serializable { private synchronized void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { // violation, no need to synchronized } } class MyClass implements Serializable { private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { synchronized(lock) { // violation, no need to synchronized } } } // OK, class not Serializable class MyClass { private synchronized void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { } } // OK, class not Serializable class MyClass { private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { synchronized(lock) { } } } class MyClass implements Serializable { private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { // OK, this block is more than just a simple sync statement synchronized(lock) { } doSomething() } } ------------------------------------------------------------------------------- * {SynchronizedOnReentrantLock} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Synchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method. This rule take from Alex Miller's {{{http://www.slideshare.net/alexmiller/java-concurrency-gotchas-3666977}Java Concurrency in Practice}} slides. Here is the proper usage of ReentrantLock: ------------------------------------------------------------------------------- import java.util.concurrent.locks.ReentrantLock; final lock = new ReentrantLock(); def method() { //Trying to enter the critical section lock.lock(); // will wait until this thread gets the lock try { // critical section } finally { //releasing the lock so that other threads can get notifies lock.unlock(); } } ------------------------------------------------------------------------------- Example of violations: ------------------------------------------------------------------------------- class MyClass { final ReentrantLock lock = new ReentrantLock() def method() { // violation synchronized(lock) { } } } class MyClass { final ReentrantLock lock = new ReentrantLock() class MyInnerClass { def method() { synchronized(lock) { } } } } class MyClass { // implicit typing final def lock = new ReentrantLock() def method() { // violation synchronized(lock) { } } } class MyClass { // implicit typing final def lock = new Object[0] // correct idiom def method() { return new Runnable() { final def lock = new ReentrantLock() // shadows parent from inner class public void run() { // violation synchronized(lock) { } } } } } class MyClass { // implicit typing final def lock = new Object[0] // correct idiom class MyInnerClass { final def lock = new ReentrantLock() // shadows parent from inner class def method() { // violation synchronized(lock) { } } } } ------------------------------------------------------------------------------- * {SystemRunFinalizersOnExit} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This rule reports uses of the <<<System.runFinalizersOnExit()>>> method. Method calls to <<<System.runFinalizersOnExit()>>> should not be allowed. This method is inherently non-thread-safe, may result in data corruption, deadlock, and may affect parts of the program far removed from it's call point. It is deprecated, and it's use strongly discouraged. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def method() { System.runFinalizersOnExit(true) } ------------------------------------------------------------------------------- * {ThisReferenceEscapesConstructor} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.19> Reports constructors passing the 'this' reference to other methods. This equals exposing a half-baked objects and can lead to race conditions during initialization. For reference, see {{{http://www.slideshare.net/alexmiller/java-concurrency-gotchas-3666977/38}Java Concurrency in Practice}} by Alex Miller and {{{http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html}Java theory and practice: Safe construction techniques}} by Brian Goetz. Example of violations: ------------------------------------------------------------------------------- class EventListener { EventListener(EventPublisher publisher) { publisher.register(this) new WorkThread(publisher, this).start() new AnotherWorkThread(listener: this) } } ------------------------------------------------------------------------------- * {ThreadGroup} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Avoid using <<<ThreadGroup>>>; although it is intended to be used in a threaded environment it contains methods that are not thread safe. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- new ThreadGroup("...") new ThreadGroup(tg, "my thread group") Thread.currentThread().getThreadGroup() System.getSecurityManager().getThreadGroup() ------------------------------------------------------------------------------- * {ThreadLocalNotStaticFinal} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This rule reports definition of the <<<ThreadLocal>>> fields that are not <<<static>>> and <<<final>>>. <ThreadLocal> fields should be <<<static>>> and <<<final>>>. In the most common case a <<<java.lang.ThreadLocal>>> instance associates state with a thread. A non-<<<static>>> non-<<<final>>> <<<java.lang.ThreadLocal>>> field associates state with an instance-thread combination. This is seldom necessary and often a bug which can cause memory leaks and possibly incorrect behavior. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- private static ThreadLocal local1 = new ThreadLocal() private final ThreadLocal local2 = new ThreadLocal() protected ThreadLocal local3 = new ThreadLocal() ThreadLocal local4 = new ThreadLocal() ------------------------------------------------------------------------------- * {ThreadYield} Rule ~~~~~~~~~~~~~~~~~~~ This rule reports uses of the <<<Thread.yield()>>> method. Method calls to <<<Thread.yield()>>> should not be allowed. This method has no useful guaranteed semantics, and is often used by inexperienced programmers to mask race conditions. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def method() { Thread.yield() } ------------------------------------------------------------------------------- * {UseOfNotifyMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Checks for code that calls <<<notify()>>> rather than <<<notifyAll()>>>. Java monitors are often used for multiple conditions. Calling <<<notify()>>> only wakes up one thread, meaning that the awakened thread might not be the one waiting for the condition that the caller just satisfied. Also see {{{http://www.javaconcurrencyinpractice.com/}<<Java_Concurrency_in_Practice>>}}, Brian Goetz, p 303. * {VolatileArrayField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.13> Volatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not. This rule take from Alex Miller's <Java Concurrency in Practice> slides, available at {{http://www.slideshare.net/alexmiller/java-concurrency-gotchas-3666977}}. Example of violations: ------------------------------------------------------------------------------- class MyClass { private volatile Object[] field1 = value() volatile field2 = value as Object[] volatile field3 = (Object[])foo } ------------------------------------------------------------------------------- * {VolatileLongOrDoubleField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This rule reports on <<<long>>> or <<<double>>> fields that are declared <<<volatile>>>. Long or double fields should not be declared as <<<volatile>>>. Java specifies that reads and writes from such fields are atomic, but many JVM's have violated this specification. Unless you are certain of your JVM, it is better to synchronize access to such fields rather than declare them <<<volatile>>>. This rule flags fields marked <<<volatile>>> when their type is <<<double>>> or <<<long>>> or the name of their type is "Double" or "Long". Here is an example of code that produces a violation: ------------------------------------------------------------------------------- def method() { private volatile double d private volatile long f } ------------------------------------------------------------------------------- * {WaitOutsideOfWhileLoop} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.13> Calls to <<<Object.wait()>>> must be within a <<<while>>> loop. This ensures that the awaited condition has not already been satisfied by another thread before the <<<wait()>>> is invoked. It also ensures that the proper thread was resumed and guards against incorrect notification. See [1] and [3]. As a more modern and flexible alternative, consider using the Java <concurrency utilities> instead of <<<wait()>>> and <<<notify()>>>. See discussion in <Effective Java> [2]. Example of violation: ------------------------------------------------------------------------------- class MyClass { private data void processData() synchronized(data) { if (!data.isReady()) { data.wait() } data.calculateStatistics() } } } ------------------------------------------------------------------------------- Example of correct usage: ------------------------------------------------------------------------------- class MyClass { private data void processData() synchronized(data) { while (!data.isReady()) { data.wait() } data.calculateStatistics() } } } ------------------------------------------------------------------------------- ** References * [1] <<Effective Java, Programming Language Guide>>, by Joshua Bloch. Addison Wesley (2001). Chapter 50 (1st edition) is entitled "Never invoke wait outside a loop." * [2] <<Effective Java>>, 2nd edition, by Joshua Bloch, Addison Wesley (2008). Item #69: <Prefer concurrency utilities to wait and notify>. * [3] Software Engineering Institute - Secure Coding {{{https://www.securecoding.cert.org/confluence/display/java/THI03-J.+Always+invoke+wait()+and+await()+methods+inside+a+loop}discussion of this issue}} ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-run-as-a-test.apt�����������������������������������������������0000644�0001750�0001750�00000005127�12414275156�021661� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Run as a Test -------------------------------------------------- CodeNarc - Run as an Automated Test ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<CodeNarc>> can be run as part of an automated test suite, for instance using <<JUnit>> or <<TestNG>>. This approach uses the <<<org.codenarc.ant.CodeNarcTask>>> class and Groovy's built-in support for <<Apache Ant>>. <<NOTE:>> This approach may not play well with having <<CodeNarc>> also configured to run as part of your "regular" Ant build, especially if you have a classpath defined for your Ant build which is different that your runtime classpath for running your tests (which is likely). * Automated Test That Runs CodeNarc ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is an example <<JUnit>> test (JUnit 3.x) that runs <<CodeNarc>>. +---------------------------------------------------------------------------------------- private static final GROOVY_FILES = '**/*.groovy' private static final RULESET_FILES = [ 'rulesets/basic.xml', 'rulesets/imports.xml'].join(',') void testRunCodeNarc() { def ant = new AntBuilder() ant.taskdef(name:'codenarc', classname:'org.codenarc.ant.CodeNarcTask') ant.codenarc(ruleSetFiles:RULESET_FILES, maxPriority1Violations:0, maxPriority2Violations:0) { fileset(dir:'src/main/groovy') { include(name:GROOVY_FILES) } fileset(dir:'src/test/groovy') { include(name:GROOVY_FILES) } report(type:'ide') } } +---------------------------------------------------------------------------------------- Things to note: * This approach uses the <<<AntBuilder>>> class provided with Groovy. * The <<CodeNarc>> jar must be on the classpath. Any external resources that you reference must also be on the classpath, including any custom <RuleSet> files. * The <maxPriority1Violations> and <maxPriority2Violations> properties are configured to fail the test if any priority 1 or 2 violations are found. * An <ide> report is configured. This will to write (only) to <standard out>, and will include hyperlinks to the lines within the source code that contained the violations . The report shows the total number of violations (at each priority) and also list the violations by file. [] See the {{{./codenarc-ant-task.html}CodeNarc Ant Task}} for more information on configuring the Ant task. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-jdbc.apt��������������������������������������������������0000644�0001750�0001750�00000006042�12006632012�021271� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - JDBC Rules -------------------------------------------------- JDBC Rules ("<rulesets/jdbc.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {DirectConnectionManagement} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> The J2EE standard requires that applications use the container's resource management facilities to obtain connections to resources. Every major web application container provides pooled database connection management as part of its resource management framework. Duplicating this functionality in an application is difficult and error prone, which is part of the reason it is forbidden under the J2EE standard. For more information see: {{https://www.fortify.com/vulncat/en/vulncat/java/j2ee_badpractices_getconnection.html}} Example of violations: ------------------------------------------------------------------------------- DriverManager.getConnection() java.sql.DriverManager.getConnection() ------------------------------------------------------------------------------- * {JdbcConnectionReference} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> Checks for direct use of <<<java.sql.Connection>>>, which is discouraged and almost never necessary in application code. For a more <Groovy> alternative, see {{http://groovy.codehaus.org/Database+features}} for information on the <<Groovy Sql>> abstraction layer for JDBC/SQL. Note: If a violation is triggered from an <<import>> statement, then you may get multiple violations per import if there are multiple classes in the source file. In that case, the imports are processed once per class. * {JdbcResultSetReference} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> Checks for direct use of <<<java.sql.ResultSet>>>, which is not necessary if using the Groovy <<Sql>> facility or an ORM framework such as <Hibernate>. See {{http://groovy.codehaus.org/Database+features}} for information on the <<Groovy Sql>> abstraction layer for JDBC/SQL. Note: If a violation is triggered from an <<import>> statement, then you may get multiple violations per import if there are multiple classes in the source file. In that case, the imports are processed once per class. * {JdbcStatementReference} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.15> Checks for direct use of <<<java.sql.Statement>>>, <<<java.sql.PreparedStatement>>>, or <<<java.sql.CallableStatement>>>, which is not necessary if using the Groovy <<Sql>> facility or an ORM framework such as <Hibernate>. See {{http://groovy.codehaus.org/Database+features}} for information on the <<Groovy Sql>> abstraction layer for JDBC/SQL. Note: If a violation is triggered from an <<import>> statement, then you may get multiple violations per import if there are multiple classes in the source file. In that case, the imports are processed once per class. ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-convention.apt��������������������������������������������0000644�0001750�0001750�00000021202�12414302664�022556� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Convention Rules -------------------------------------------------- Convention Rules ("<rulesets/convention.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {ConfusingTernary} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> In a ternary expression avoid negation in the test. For example, rephrase: <<<(x != y) ? diff : same>>> as: <<<(x == y) ? same : diff>>>. Consistent use of this rule makes the code easier to read. Also, this resolves trivial ordering problems, such as "does the error case go first?" or "does the common case go first?". Example: ------------------------------------------------------------------------------- (x != y) ? diff : same // triggers violation (!x) ? diff : same // triggers violation (x == y) ? same : diff // OK (x) ? same : diff // OK // this is OK, because of GroovyTruth there is no inverse of != null (x != null) ? diff : same // this is OK, because of GroovyTruth there is no inverse of != true (x != true) ? diff : same // this is OK, because of GroovyTruth there is no inverse of != false (x != false) ? diff : same ------------------------------------------------------------------------------- * {CouldBeElvis} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.15> Catch an if block that could be written as an elvis expression. Example of violations: ------------------------------------------------------------------------------- if (!x) { // violation x = 'some value' } if (!x) // violation x = "some value" if (!params.max) { // violation params.max = 10 } x ?: 'some value' // OK ------------------------------------------------------------------------------- * {HashtableIsObsolete} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.17> Checks for references to the (<effectively>) obsolete <<<java.util.Hashtable>>> class. Use the <<Java Collections Framework>> classes instead, including <<<HashMap>>> or <<<ConcurrentHashMap>>>. See the JDK javadoc. Example of violations: ------------------------------------------------------------------------------- def myMap = new Hashtable() // violation ------------------------------------------------------------------------------- * {IfStatementCouldBeTernary} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.18> Checks for: * An <<<if>>> statement where both the <<<if>>> and <<<else>>> blocks contain only a single <<<return>>> statement returning a constant or literal value. * A block where the second-to-last statement in a block is an <<<if>>> statement with no <<<else>>>, where the block contains a single <<<return>>> statement, and the last statement in the block is a <<<return>>> statement, and both <<<return>>> statements return a constant or literal value. This check is disabled by setting <<<checkLastStatementImplicitElse>>> to <<<false>>>. Example of violations: ------------------------------------------------------------------------------- if (condition) { return 44 } else { return 'yes' } // violation if (check()) { return [1, 2] } else { return "count=$count" } // violation if (condition) // violation return null else return [a:1] def method1() { if (condition) { // violation return 44 } return 'yes' } ------------------------------------------------------------------------------- * {InvertedIfElse} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> An inverted <if-else> statement is one in which there is a single <<<if>>> statement with a single <<<else>>> branch and the boolean test of the <<<if>>> is negated. For instance <<<if (!x) false else true>>>. It is usually clearer to write this as <<<if (x) true else false>>>. * {LongLiteralWithLowerCaseL} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> In Java and Groovy, you can specify long literals with the L or l character, for instance 55L or 24l. It is best practice to always use an uppercase L and never a lowercase l. This is because 11l rendered in some fonts may look like 111 instead of 11L. Example of violations: ------------------------------------------------------------------------------- def x = 1l def y = 55l ------------------------------------------------------------------------------- * {NoDef} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.22> Do not allow using the <<<def>>> keyword in code. Use a specific type instead. *-------------------------------+----------------------------------------------------------------+---------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *-------------------------------+----------------------------------------------------------------+---------------------+ | excludeRegex | Regular expression describing names of attributes, parameters | <<<>>> | | | or methods that could be precede by the <<<def>>> keyword. | | *-------------------------------+----------------------------------------------------------------+---------------------+ <<NOTE:>> This rule applies to the text contents of a <file> rather than a specific <class>, so it does not support the <applyToClassNames> and <doNotApplyToClassNames> configuration properties. * {ParameterReassignment} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.17> Checks for a method or closure parameter being reassigned to a new value within the body of the method/closure, which is a confusing and questionable practice. Use a temporary variable instead. Example of violations: ------------------------------------------------------------------------------- void myMethod(int a, String b) { println a b = 'new value' // violation } def myClosure1 = { int a, b -> a = 123 // violation } ------------------------------------------------------------------------------- * {TernaryCouldBeElvis} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.17> Checks for ternary expressions where the <boolean> and <true> expressions are the same. These can be simplified to an <Elvis> expression. Example of violations: ------------------------------------------------------------------------------- x ? x : false // violation; can simplify to x ?: false foo() ? foo() : bar() // violation; can simplify to foo() ?: bar() foo(1) ? foo(1) : 123 // violation; can simplify to foo(1) ?: 123 (x == y) ? same : diff // OK x ? y : z // OK x ? x + 1 : x + 2 // OK x ? 1 : 0 // OK x ? !x : x // OK !x ? x : null // OK foo() ? bar() : 123 // OK foo() ? foo(99) : 123 // OK foo(x) ? foo() : 123 // OK foo(1) ? foo(2) : 123 // OK ------------------------------------------------------------------------------- NOTE: If the <boolean> and <true> expressions are the same method call, and that method call has <side-effects>, then converting it to a <Elvis> expression may produce <different> behavior. The method will only be called <once>, rather than <twice>. But relying on those <side-effects> as part of a ternary expression behavior is confusing, error-prone and just a bad idea. In any case, that code should be refactored to move the reliance on the side-effects out of the ternary expression. * {VectorIsObsolete} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.17> Checks for references to the (<effectively>) obsolete <<<java.util.Vector>>> class. Use the <<Java Collections Framework>> classes instead, including <<<ArrayList>>> or <<<Collections.synchronizedList()>>>. See the JDK javadoc. Example of violations: ------------------------------------------------------------------------------- def myList = new Vector() // violation ------------------------------------------------------------------------------- ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-size.apt��������������������������������������������������0000644�0001750�0001750�00000072260�12444433061�021357� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Size and Complexity Rules -------------------------------------------------- Size and Complexity Rules ("<rulesets/size.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {AbcComplexity} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *-------------------------------------------------------------------------------------------------+ | <<NOTE:>> This rule has been <<DEPRECATED>>, and disabled by default (i.e., by setting its <enabled> | property to <false>). Use the {{{AbcMetric}AbcMetric}} rule instead. *-------------------------------------------------------------------------------------------------+ Calculates the <ABC> metric for methods/classes and checks against configured threshold values. The <<maxMethodComplexity>> property holds the threshold value for the ABC complexity value (score) for each method. If this value is non-zero, a method with a complexity value greater than this value is considered a violation. The <<maxClassAverageMethodComplexity>> property holds the threshold value for the average ABC complexity value (score) for each class. If this value is non-zero, a class with an average complexity value greater than this value is considered a violation. This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), then that Closure is analyzed and checked just like a method. *---------------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxMethodComplexity | The maximum <ABC complexity> value (score) allowed for a single| 60 | | | method (or "closure field"). If zero or <null>, then do not | | | | check method-level complexity. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxClassAverageMethodComplexity | The maximum <ABC complexity> average value (score) allowed for | 60 | | | a class, calculated as the average complexity of its methods or| | | | "closure fields". If zero or <null>, then do not check | | | | class-level average complexity. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxClassComplexity | The maximum <ABC complexity> value (score) allowed for a class,| 0 | | | calculated as the total complexity of its methods or | | | | "closure fields". If zero or <null>, then do not check | | | | class-level complexity. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodNames | Specifies one or more (comma-separated) method names that | <<<null>>> | | | that should not cause a rule violation. The names may | | | | optionally contain wildcards (*,?). Note that the ignored | | | | methods still contribute to the class complexity value. | | *---------------------------------+----------------------------------------------------------------+------------------------+ ** ABC Size/Complexity Metric Calculation Rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The <ABC complexity> value (score) is calculated as follows: The <ABC> metric measures size/complexity by counting the number of Assignments (A), Branches (B) and Conditions (C) and assigns a single numerical score calculated as: <<< |ABC| = sqrt((A*A)+(B*B)+(C*C)) >>> The <ABC Metric> calculation rules for Groovy: * Add one to the <assignment> count for each occurrence of an assignment operator, excluding constant declarations: = *= /= %= += <<= >>= &= |= ^= >>>= * Add one to the <assignment> count for each occurrence of an increment or decrement operator (prefix or postfix): ++ -- * Add one to the <branch> count for each function call or class method call. * Add one to the <branch> count for each occurrence of the new operator. * Add one to the <condition> count for each use of a conditional operator: == != <= >= < > <=> =~ ==~ * Add one to the <condition> count for each use of the following keywords: else case default try catch ? * Add one to the <condition> count for each unary conditional expression. ** Notes ~~~~~~~~~ * See the {{{http://www.softwarerenovation.com/ABCMetric.pdf}ABC Metric specification}} * See the {{{http://jakescruggs.blogspot.com/2008/08/whats-good-flog-score.html}Blog post}} describing guidelines for interpreting an ABC score * This {{{https://servicios.excentia.es/confluence/display/QAX/SONAR+ABC+Metric+Plugin}(Spanish) blog post}} about the eXcentia Sonar ABC Metric Plugin (for Java) includes a table of risk classifications for ABC scores for both methods and classes. * See the {{{http://gmetrics.sourceforge.net/gmetrics-AbcMetric.html}GMetrics ABC metric}}. This includes a discussion of guidelines for interpreting <ABC> scores. * This rule requires Groovy 1.6 (or later). * This rule requires the GMetrics jar on the classpath. See {{{http://gmetrics.sourceforge.net/}GMetrics}}. * {AbcMetric} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Calculates the <ABC> size metric for methods/classes and checks against configured threshold values. The <<maxMethodAbcScore>> property holds the threshold value for the ABC score for each method. If this value is non-zero, a method with an ABC score greater than this value is considered a violation. The value does not have to be an integer (e.g., 1.7 is allowed). The <<maxClassAverageMethodAbcScore>> property holds the threshold value for the average ABC score for each class. If this value is non-zero, a class with an average ABC score value greater than this value is considered a violation. The value does not have to be an integer. The <<maxClassAbcScore>> property holds the threshold value for the total ABC score value for each class. If this value is non-zero, a class with a total ABC score greater than this value is considered a violation. The value does not have to be an integer. This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), then that Closure is analyzed and checked just like a method. *---------------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxMethodAbcScore | The maximum <ABC> score allowed for a single | 60 | | | method (or "closure field"). If zero or <null>, then do not | | | | check method-level scores. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxClassAverageMethodAbcScore | The maximum average <ABC> score allowed for | 60 | | | a class, calculated as the average score of its methods or | | | | "closure fields". If zero or <null>, then do not check | | | | class-level average scores. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxClassAbcScore | The maximum <ABC> score allowed for a class, | 0 | | | calculated as the total ABC score of its methods or | | | | "closure fields". If zero or <null>, then do not check | | | | class-level scores. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodNames | Specifies one or more (comma-separated) method names that | <<<null>>> | | | that should not cause a rule violation. The names may | | | | optionally contain wildcards (*,?). Note that the ignored | | | | methods still contribute to the class complexity value. | | *---------------------------------+----------------------------------------------------------------+------------------------+ ** ABC Size Metric Calculation Rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The <ABC> score is calculated as follows: The <ABC> metric measures size by counting the number of Assignments (A), Branches (B) and Conditions (C) and assigns a single numerical score calculated as: <<< |ABC| = sqrt((A*A)+(B*B)+(C*C)) >>> The <ABC Metric> calculation rules for Groovy: * Add one to the <assignment> count for each occurrence of an assignment operator, excluding constant declarations: = *= /= %= += <<= >>= &= |= ^= >>>= * Add one to the <assignment> count for each occurrence of an increment or decrement operator (prefix or postfix): ++ -- * Add one to the <branch> count for each function call or class method call. * Add one to the <branch> count for each occurrence of the new operator. * Add one to the <condition> count for each use of a conditional operator: == != <= >= < > <=> =~ ==~ * Add one to the <condition> count for each use of the following keywords: else case default try catch ? * Add one to the <condition> count for each unary conditional expression. ** Notes ~~~~~~~~~ * See the {{{http://www.softwarerenovation.com/ABCMetric.pdf}ABC Metric specification}} * See the {{{http://jakescruggs.blogspot.com/2008/08/whats-good-flog-score.html}Blog post}} describing guidelines for interpreting an ABC score * This {{{https://servicios.excentia.es/confluence/display/QAX/SONAR+ABC+Metric+Plugin}(Spanish) blog post}} about the eXcentia Sonar ABC Metric Plugin (for Java) includes a table of risk classifications for ABC scores for both methods and classes. * See the {{{http://gmetrics.sourceforge.net/gmetrics-AbcMetric.html}GMetrics ABC metric}}. This includes a discussion of guidelines for interpreting <ABC> scores. * This rule requires Groovy 1.6 (or later). * This rule requires the GMetrics jar on the classpath. See {{{http://gmetrics.sourceforge.net/}GMetrics}}. * {ClassSize} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks if the size of a class exceeds the number of lines specified by the <<maxLines>> property. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | maxLines | The maximum number of lines allowed in a class definition. | 1000 | *---------------------+----------------------------------------------------------------+------------------------+ * {CrapMetric} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Calculates the {{{http://www.artima.com/weblogs/viewpost.jsp?thread=210575}C.R.A.P.}} (Change Risk Anti-Patterns) metric score for methods/classes and checks against configured threshold values. The <CRAP> metric score is based on the <cyclomatic complexity> and test coverage for individual methods. A method with a <CRAP> value greater than the <<maxMethodCrapScore>> property causes a violation. Likewise, a class that has an (average method) <CRAP> value greater than the <<maxClassAverageMethodCrapScore>> property causes a violation. <<NOTE:>> This rule requires the <<GMetrics>>[3] jar, version 0.5 (or later), on the classpath, as well as a <<Cobertura>>[4]-[6] XML coverage file. If either of these prerequisites is not available, this rule logs a warning messages and exits (i.e., does nothing). The <<maxMethodCrapScore>> property holds the threshold value for the CRAP value for each method. If this value is non-zero, a method with a cyclomatic complexity value greater than this value is considered a violation. The <<maxClassAverageMethodCrapScore>> property holds the threshold value for the average CRAP value for each class. If this value is non-zero, a class with an average cyclomatic complexity value greater than this value is considered a violation. NOTE: This rule does NOT treat <closure fields> as methods (unlike some of the other size/complexity rules). *---------------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------------+----------------------------------------------------------------+------------------------+ | coberturaXmlFile | The path to the Cobertura XML coverage file for the Groovy code| <<<null>>> | | | By default, the path is relative to the classpath. But the path| | | | may be optionally prefixed by any of the valid java.net.URL | | | | prefixes, such as "file:" (to load from a relative or absolute | | | | path on the filesystem), or "http:". This property is REQUIRED.| | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxMethodCrapScore | The maximum <CRAP> metric value allowed for a single method. | 30 | | | If zero or <null>, then do not check method-level complexity. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxClassAverageMethodCrapScore | The maximum <CRAP> average metric value allowed for a class, | 30 | | | calculated as the average CRAP value of its methods. If zero or| | | | <null>, then do not check the average class-level CRAP value. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxClassCrapScore | The maximum total <CRAP> metric value allowed for a class, | 0 | | | calculated as the total CRAP value of its methods. If | | | | zero or <null>, then do not check class-level CRAP value. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodNames | Specifies one or more (comma-separated) method names that | <<<null>>> | | | that should not cause a rule violation. The names may | | | | optionally contain wildcards (*,?). Note that the ignored | | | | methods still contribute to the class complexity value. | | *---------------------------------+----------------------------------------------------------------+------------------------+ * CRAP Formula ~~~~~~~~~~~~~~~ Given a Groovy method m, C.R.A.P. for m is calculated as follows: +---------------------------------------------------------------------------------------- C.R.A.P.(m) = comp(m)^2 * (1 - cov(m)/100)^3 + comp(m) +---------------------------------------------------------------------------------------- Where <<comp(m)>> is the <cyclomatic complexity> of method m, and <<cov(m)>> is the test code coverage provided by automated tests. * References ~~~~~~~~~~~~ * <<[1]>> The original 2007 {{{http://www.artima.com/weblogs/viewpost.jsp?thread=210575}blog post}} that defined the <<CRAP>> metric. * <<[2]>> A 2011 {{{http://googletesting.blogspot.com/2011/02/this-code-is-crap.html}blog post}} from Alberto Savoia (the co-creator of the <<CRAP>> metric with Bob Evans), describing the formula, the motivation, and the <<CRAP4J>> tool for calculating <<CRAP>> score for Java code. * <<[3]>> The {{{http://gmetrics.sourceforge.net/gmetrics-CrapMetric.html}GMetrics CRAP Metric}}. * <<[4]>> {{{http://cobertura.sourceforge.net/}Cobertura}} -- <Cobertura is a free Java tool that calculates the percentage of code accessed by tests. It can be used to identify which parts of your Java program are lacking test coverage.> * <<[5]>> {{{http://cobertura.sourceforge.net/anttaskreference.html}Cobertura Ant Task Reference}} * <<[6]>> {{{http://mojo.codehaus.org/cobertura-maven-plugin/index.html}Cobertura Maven Plugin}} * {CyclomaticComplexity} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Calculates the <Cyclomatic Complexity> for methods/classes and checks against configured threshold values. The <<maxMethodComplexity>> property holds the threshold value for the cyclomatic complexity value for each method. If this value is non-zero, a method with a cyclomatic complexity value greater than this value is considered a violation. The <<maxClassAverageMethodComplexity>> property holds the threshold value for the average cyclomatic complexity value for each class. If this value is non-zero, a class with an average cyclomatic complexity value greater than this value is considered a violation. This rule treats "closure fields" as methods. If a class field is initialized to a Closure (ClosureExpression), then that Closure is analyzed and checked just like a method. *---------------------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxMethodComplexity | The maximum <cyclomatic complexity> value allowed for a single | 20 | | | method (or "closure field"). If zero or <null>, then do not | | | | check method-level complexity. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxClassAverageMethodComplexity | The maximum average <cyclomatic complexity> value allowed for a| 20 | | | class, calculated as the average complexity of its methods or | | | | "closure fields". If zero or <null>, then do not check | | | | average class-level complexity. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | maxClassComplexity | The maximum total <cyclomatic complexity> value allowed for a | 0 | | | class, calculated as the total complexity of its methods or | | | | "closure fields". If zero or <null>, then do not check | | | | total class-level complexity. | | *---------------------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodNames | Specifies one or more (comma-separated) method names that | <<<null>>> | | | that should not cause a rule violation. The names may | | | | optionally contain wildcards (*,?). Note that the ignored | | | | methods still contribute to the class complexity value. | | *---------------------------------+----------------------------------------------------------------+------------------------+ ** Cyclomatic Complexity Metric Calculation Rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The <cyclomatic complexity> value is calculated as follows: <Start with a initial (default) value of one (1). Add one (1) for each occurrence of each of the following:> * <<<if>>> statement * <<<while>>> statement * <<<for>>> statement * <<<case>>> statement * <<<catch>>> statement * <<<&&>>> and <<<||>>> boolean operations * <<<?:>>> ternary operator and <<<?:>>> <Elvis> operator. * <<<?.>>> null-check operator ** Notes ~~~~~~~~~ * See the {{{http://en.wikipedia.org/wiki/Cyclomatic_complexity}Cyclomatic Complexity Wikipedia entry}} * See the {{{http://www.literateprogramming.com/mccabe.pdf}original paper describing Cyclomatic Complexity}} * See the {{{http://gmetrics.sourceforge.net/gmetrics-CyclomaticComplexityMetric.html}GMetrics Cyclomatic Complexity metric}}. This includes a discussion of guidelines for interpreting <cyclomatic complexity> values. * This rule requires Groovy 1.6 (or later). * This rule requires the GMetrics jar on the classpath. See {{{http://gmetrics.sourceforge.net/}GMetrics}}. * {MethodCount} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Checks if the number of methods within a class exceeds the number of lines specified by the <<maxMethod>> property. A class with too many methods is probably a good suspect for refactoring, in order to reduce its complexity and find a way to have more fine grained objects. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | maxMethods | The maximum number of methods allowed in a class definition. | 30 | *---------------------+----------------------------------------------------------------+------------------------+ * {MethodSize} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks if the size of a method exceeds the number of lines specified by the <<maxLines>> property. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | maxLines | The maximum number of lines allowed in a method definition. | 100 | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreMethodNames | Specifies one or more (comma-separated) method names that | <<<null>>> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ Known Limitations: * Annotations on a method are included in the size (line count) for that method. * {NestedBlockDepthRule} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for blocks or closures nested more deeply than a configured maximum number. Blocks include <<<if>>>, <<<for>>>, <<<while>>>, <<<switch>>>, <<<try>>>, <<<catch>>>, <<<finally>>> and <<<synchronized>>> blocks/statements, as well as closures. Methods calls, constructor calls, and property access through Builder objects are ignore. For instance, this code does not cause a violation: ------------------------------------------------------------------------------- myBuilder.root { foo { bar { baz { quix { qux { quaxz { } } } } } } } ------------------------------------------------------------------------------- *---------------------+-----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+-----------------------------------------------------------------+------------------------+ | maxNestedBlockDepth | The maximum number of nesting levels. A block or closure nested | 5 | | | deeper than that number of levels is considered a violation. | | *---------------------+-----------------------------------------------------------------+------------------------+ | ignoreRegex | Determines what is a builder call. For instance, closures | .*(b|B)uilder | | | nested on a method named createBuilder, a property named | | | | myBuilder, or a constructor call to object MyBuilder() do | | | | not produce violations. | | *---------------------+-----------------------------------------------------------------+------------------------+ * {ParameterCount} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.23> Checks if the number of parameters in method/constructor exceeds the number of parameters specified by the maxParameters property. Example of violations: ------------------------------------------------------------------------------- void someMethod(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) { // violation } class SampleClass { SampleClass(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) { // violation } } ------------------------------------------------------------------------------- *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | maxParameters | The maximum number of parameters in method/constructor | 5 | *---------------------+----------------------------------------------------------------+------------------------+������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-HtmlReportWriter.apt��������������������������������������������0000644�0001750�0001750�00000010424�12450013623�022537� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc HtmlReportWriter -------------------------------------------------- HtmlReportWriter ~~~~~~~~~~~~~~~~~ * Description ~~~~~~~~~~~~~ The <<<org.codenarc.report.HtmlReportWriter>>> class (type="html") produces an HTML report containing a table with summary results by package and a separate section for each package containing violations, and then a table of the rules applied, along with their descriptions. See a {{{SampleCodeNarcHtmlReport.html}Sample Report}}. Alternatively, see the {{{http://mrhaki.blogspot.com/}mrhaki}} blog post about {{{http://mrhaki.blogspot.com/2011/01/groovy-goodness-create-codenarc-reports.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+mrhaki+%28Messages+from+mrhaki%29}creating custom CodeNarc HTML reports using XSLT}}. * Option Nested Elements ~~~~~~~~~~~~~~~~~~~~~~~~ The <<option>> element is a child of the <<report>> element and defines a report-specific option for a report. <<<org.codenarc.report.HtmlReportWriter>>> supports the following options: *-------------------------+----------------------------------------------------------------+------------------------+ | <<Attribute>> | <<Description>> | <<Required>> | *-------------------------+----------------------------------------------------------------+------------------------+ | maxPriority | The maximum priority level for violations in the report. For | 3 | | | instance, setting <maxPriority> to 2 will result in the report | | | | containing only priority 1 and 2 violations (and omitting | | | | violations with priority 3). | | *-------------------------+----------------------------------------------------------------+------------------------+ | outputFile | The path and filename for the output report file. | No | *-------------------------+----------------------------------------------------------------+------------------------+ | title | The title for the output report. | No | *-------------------------+----------------------------------------------------------------+------------------------+ | writeToStandardOut | Set to <<<true>>> to write out the report to | No | | | <stdout> (<<<System.out>>>) instead of writing to a file. | | *-------------------------+----------------------------------------------------------------+------------------------+ | includeSummaryByPackage | Set to <<<false>>> to exclude the violation summary for each | | | | package within the "Summary" section of the report. It | | | | defaults to <<<true>>>. | | *-------------------------+----------------------------------------------------------------+------------------------+ * Example ~~~~~~~~~ Here is an example Ant XML build file illustrating configuration of <<<org.codenarc.report.HtmlReportWriter>>>. Note that the report <<type>> is specified as <<"html">>. +---------------------------------------------------------------------------------------- <taskdef name="codenarc" classname="org.codenarc.ant.CodeNarcTask"/> <target name="runCodeNarc"> <codenarc ruleSetFiles="rulesets/basic.xml,rulesets/exceptions.xml,rulesets/imports.xml" maxPriority1Violations="0"> <report type="html"> <option name="outputFile" value="reports/CodeNarcAntReport.html" /> <option name="title" value="My Sample Code" /> </report> <fileset dir="src"> <include name="**/*.groovy"/> </fileset> </codenarc> </target> +---------------------------------------------------------------------------------------- ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-rules-design.apt������������������������������������������������0000644�0001750�0001750�00000044111�12440206573�021652� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Design Rules -------------------------------------------------- Design Rules ("<rulesets/design.xml>") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {AbstractClassWithPublicConstructor} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.14> Checks for <<<abstract>>> classes that define a <<<public>>> constructor, which is useless and confusing. The following code produces a violation: ------------------------------------------------------------------------------- abstract class MyClass { MyClass() { } } ------------------------------------------------------------------------------- * {AbstractClassWithoutAbstractMethod} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> The abstract class does not contain any abstract methods. An abstract class suggests an incomplete implementation, which is to be completed by subclasses implementing the abstract methods. If the class is intended to be used as a base class only (not to be instantiated directly) a protected constructor can be provided prevent direct instantiation. Example: ------------------------------------------------------------------------------- public abstract class MyBaseClass { void method1() { } void method2() { } // consider using abstract methods or removing // the abstract modifier and adding protected constructors } ------------------------------------------------------------------------------- The following examples all pass: ------------------------------------------------------------------------------- abstract class MyClass extends AbstractParent { // OK because parent is named Abstract.* } abstract class MyClass extends BaseParent{ // OK because parent is named Base.* } ------------------------------------------------------------------------------- * {BooleanMethodReturnsNull} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> Checks for a method with <<<Boolean>>> return type that returns an explicit <<<null>>>. A method that returns either <<<Boolean.TRUE>>>, <<<Boolean.FALSE>>> or <<<null>>> is an accident waiting to happen. This method can be invoked as though it returned a value of type <<<boolean>>>, and the compiler will insert automatic <unboxing> of the <<<Boolean>>> value. If a <<<null>>> value is returned, this will result in a <<<NullPointerException>>>. * {BuilderMethodWithSideEffects} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.16> A builder method is defined as one that creates objects. As such, they should never be of void return type. If a method is named build, create, or make, then it should always return a value. This rule has one property: <<<methodNameRegex>>>. The default value is (make.*|create.*|build.*). Update this property if you have some other naming convention for your builder methods. Example of violations: ------------------------------------------------------------------------------- class MyClass { void make() { /* ... */ } void makeSomething() { /* ... */ } void create() { /* ... */ } void createSomething() { /* ... */ } void build() { /* ... */ } void buildSomething() { /* ... */ } } ------------------------------------------------------------------------------- * {CloneableWithoutClone} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for classes that implement the <<<java.lang.Cloneable>>> interface without implementing the <<<clone()>>> method. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- class BadClass implements Cloneable { def someMethod() } ------------------------------------------------------------------------------- * {CloseWithoutCloseable} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> If a class defines a "void close()" then that class should implement java.io.Closeable. * {CompareToWithoutComparable} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> If you implement a compareTo method then you should also implement the <<<Comparable>>> interface. If you don't then you could possibly get an exception if the Groovy == operator is invoked on your object. This is an issue fixed in Groovy 1.8 but present in previous versions. Here is an example of code that produces a violation: ------------------------------------------------------------------------------- class BadClass { int compareTo(Object o) { ... } } ------------------------------------------------------------------------------- * {ConstantsOnlyInterface} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> An interface should be used only to model a behaviour of a class: using an interface as a container of constants is a poor usage pattern. Example: ------------------------------------------------------------------------------- public interface ConstantsInterface { public static final int CONSTANT_1 = 0 public static final String CONSTANT_2 = "1" } ------------------------------------------------------------------------------- * {EmptyMethodInAbstractClass} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> An empty method in an abstract class should be abstract instead, as developer may rely on this empty implementation rather than code the appropriate one. ------------------------------------------------------------------------------- abstract class MyClass { def couldBeAbstract_1() { return null // Should be abstract method } void couldBeAbstract_2() { // Should be abstract method } } ------------------------------------------------------------------------------- * {FinalClassWithProtectedMember} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> This rule finds classes marked final that contain <<<protected>>> members. If a class is <<<final>>> then it may not be subclassed, and there is therefore no point in having a member with <<<protected>>> visibility. Either the class should not be <<<final>>> or the member should be private or protected. * {ImplementationAsType} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Checks for use of the following concrete classes when specifying the type of a method parameter, closure parameter, constructor parameter, method return type or field type. The corresponding interfaces should be used to specify the type instead. * java.util.ArrayList * java.util.GregorianCalendar * java.util.HashMap * java.util.HashSet * java.util.Hashtable * java.util.LinkedHashMap * java.util.LinkedHashSet * java.util.LinkedList * java.util.TreeMap * java.util.TreeSet * java.util.Vector * java.util.concurrent.ArrayBlockingQueue * java.util.concurrent.ConcurrentHashMap * java.util.concurrent.ConcurrentLinkedQueue * java.util.concurrent.CopyOnWriteArrayList * java.util.concurrent.CopyOnWriteArraySet * java.util.concurrent.DelayQueue * java.util.concurrent.LinkedBlockingQueue * java.util.concurrent.PriorityBlockingQueue * java.util.concurrent.PriorityQueue * java.util.concurrent.SynchronousQueue Here are examples of code that produces violations: ------------------------------------------------------------------------------- // Method parameter void myMethod(ArrayList list) { // violation ... } // Constructor parameter class MyClass { MyClass(java.util.HashSet set) { // violation ... } } // Closure parameter def closure = { PriorityQueue queue -> ... } // violation // Method return type GregorianCalendar calculateDate(int num) { // violation ... } // Field type class MyClass { Hashtable map // violation } ------------------------------------------------------------------------------- * {Instanceof} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.22> Checks for use of the <<<instanceof>>> operator. Prefer using <polymorphism> instead. Use the <<<ignoreTypeNames>>> property to configure ignored type names (the class name specified as the right-hand expression of the <<<instanceof>>>). It defaults to ignoring <<<instanceof>>> checks against exception classes. Here are a couple references that discuss the problems with using <<<instanceof>>> and the preference for using <polymorphism> instead: * {{{http://www.javapractices.com/topic/TopicAction.do?Id=31}Beware of instanceof operator}} * {{{http://stackoverflow.com/questions/4192837/how-does-one-use-polymorphism-instead-of-instanceof-and-why}How does one use polymorphism instead of instanceof? (And why?)}} By default, the rule does not analyze test files. This rule sets the default value of the <doNotApplyToFilesMatching> property to ignore file names ending in 'Test.groovy', 'Tests.groovy' or 'TestCase.groovy'. *-------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *-------------------+----------------------------------------------------------------+------------------------+ | ignoreTypeNames | Specifies one or more (comma-separated) class names that | *Exceptions | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *-------------------+----------------------------------------------------------------+------------------------+ Example of violations: ------------------------------------------------------------------------------- class MyClass { boolean isRunnable = this instanceof Runnable // violation } ------------------------------------------------------------------------------- * {LocaleSetDefault} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.20> Checks for calls to <<<Locale.setDefault()>>>, or <<<Locale.default = Xxx>>>, which sets the Locale across the entire JVM. That can impact other applications on the same web server, for instance. From the java.util.Locale javadoc for <<<setDefault>>>: <Since changing the default locale may affect many different areas of functionality, this method should only be used if the caller is prepared to reinitialize locale-sensitive code running within the same Java Virtual Machine.> Example of violations: ------------------------------------------------------------------------------- Locale.setDefault(Locale.UK) // violation java.util.Locale.setDefault(Locale.FRANCE) // violation Locale.setDefault(Locale.Category.DISPLAY, Locale.JAPAN) // violation Locale.default = Locale.UK // violation ------------------------------------------------------------------------------- * {NestedForLoop} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.23> Reports classes with nested for loops. Example of violations: ------------------------------------------------------------------------------- for (int i = 0; i < 100; ++i) { for (int j = 0; j < 100; ++j) { // violation println i + j } } for (int i = 0; i < 100; ++i) { for (int j = 0; j < 100; ++j) { // violation println i + j } for (int j = 0; j < 100; ++j) { // violation println i + j } } for (int i = 0; i < 100; ++i) { for (int j = 0; j < 100; ++j) { // violation for (int k = 0; k < 100; ++k) { // violation println i + j + k } } } ------------------------------------------------------------------------------- * {PrivateFieldCouldBeFinal} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.17> This rule finds <<<private>>> fields that are only set within a <constructor> or <field initializer>. Such fields can safely be made <<<final>>>. *---------------------+----------------------------------------------------------------+------------------------+ | <<Property>> | <<Description>> | <<Default Value>> | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreFieldNames | Specifies one or more (comma-separated) field names that | <null> | | | should be ignored (i.e., that should not cause a rule | | | | violation). The names may optionally contain wildcards (*,?). | | *---------------------+----------------------------------------------------------------+------------------------+ | ignoreJpaEntities | Specifies whether fields defined inside classes annotated | false | | | with @Entity or @MappedSuperclass JPA annotations should be | | | | ignored (i.e., that should not cause a rule violation). | | *---------------------+----------------------------------------------------------------+------------------------+ * {PublicInstanceField} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> Using public fields is considered to be a bad design. Use properties instead. Example of violations: ------------------------------------------------------------------------------- class Person { public String name } ------------------------------------------------------------------------------- * {ReturnsNullInsteadOfEmptyArray} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> If you have a method or closure that returns an array, then when there are no results return a zero-length (empty) array rather than <<<null>>>. It is often a better design to return a zero-length array rather than a <<<null>>> reference to indicate that there are no results (i.e., an <empty> list of results). This way, no explicit check for <<<null>>> is needed by clients of the method. * {ReturnsNullInsteadOfEmptyCollection} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.11> If you have a method or closure that returns a collection, then when there are no results return a zero-length (empty) collection rather than <<<null>>>. It is often a better design to return a zero-length collection rather than a <<<null>>> reference to indicate that there are no results (i.e., an <empty> list of results). This way, no explicit check for <<<null>>> is needed by clients of the method. * {SimpleDateFormatMissingLocale} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.12> Be sure to specify a <<<Locale>>> when creating a new instance of <<<SimpleDateFormat>>>; the class is locale-sensitive. If you instantiate <<<SimpleDateFormat>>> without a <<<Locale>>> parameter, it will format the date and time according to the default <<<Locale>>>. Both the pattern and the <<<Locale>>> determine the format. For the same pattern, <<<SimpleDateFormat>>> may format a date and time differently if the Locale varies. ------------------------------------------------------------------------------- // violation, missing locale new SimpleDateFormat('pattern') // OK, includes locale new SimpleDateFormat('pattern', Locale.US) // OK, includes a variable that perhaps is a locale new SimpleDateFormat('pattern', locale) ------------------------------------------------------------------------------- * {StatelessSingleton} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <New in CodeNarc 0.14> There is no point in creating a stateless Singleton because there is nothing within the class that needs guarding and no side effects to calling the constructor. Just create new instances of the object or write a Utility class with static methods. In the long term, Singletons can cause strong coupling and hard to change systems. If the class has any fields at all, other than a self reference, then it is not considered stateless. A self reference is a field of the same type as the enclosing type, or a field named instance or _instance. The field name self reference is a property named instanceRegex that defaults to the value 'instance|_instance' Example of violations: ------------------------------------------------------------------------------- @groovy.lang.Singleton class Service { // violation: the class has no fields but is marked Singleton void processItem(item){ } } class Service { // violation: the class has no fields other than 'instance' but is marked Singleton static instance void processItem(item){ } } class Service { // violation static Service service void processItem(item){ } } ------------------------------------------------------------------------------- * {ToStringReturnsNull} Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <Since CodeNarc 0.21> Checks for <<<toString()>>> methods that return <<<null>>>. This is unconventional and could cause unexpected <<<NullPointerExceptions>>> from normal or implicit use of <<<toString()>>>. Example of violations: ------------------------------------------------------------------------------- class MyClass { String toString() { if (foo()) { return 'MyClass' } else { return null // violation } } } class MyClass { String toString() { calculateStuff() null // violation } } class MyClass { String toString() { // violation - implicit return of null } } ------------------------------------------------------------------------------- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-other-tools-frameworks.apt��������������������������������������0000644�0001750�0001750�00000005154�12405430413�023703� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ------------------------------------------------------- CodeNarc - Integration with Other Tools / Frameworks ------------------------------------------------------- CodeNarc - Integration with Other Tools / Frameworks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * IDEs ~~~~~~~~~~~~~~~~~~~~~~~~~ * {{{http://www.jetbrains.com/idea/}IntelliJ IDEA}} - See the {{{http://plugins.jetbrains.com/plugin/?idea&id=5925}IDEA CodeNarc Plugin}}. * {{{http://eclipse.org/}Eclipse}} - See the {{{http://codenarceclipse.sourceforge.net/}Eclipse CodeNarc Plugin}}. * Application Frameworks ~~~~~~~~~~~~~~~~~~~~~~~~~ * {{{http://grails.org/}Grails}} - See the {{{http://www.grails.org/plugin/codenarc/}Grails CodeNarc Plugin}}. * {{{http://griffon.codehaus.org/}Griffon}} - See the {{{http://docs.codehaus.org/display/GRIFFON/Codenarc+Plugin/}Griffon CodeNarc Plugin}} * Build and Code Quality Tools ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * {{{http://www.gradle.org/}Gradle}} build system - See the {{{http://gradle.org/docs/current/userguide/codenarc_plugin.html}Gradle CodeNarc Plugin}}. * {{{http://maven.apache.org/}Maven}} - See the {{{http://mojo.codehaus.org/codenarc-maven-plugin/index.html}Maven CodeNarc Plugin}} * {{{http://hudson-ci.org/}Hudson}} - The {{{http://wiki.hudson-ci.org/display/HUDSON/Violations}Hudson Violations Plugin}} includes reporting and trending of CodeNarc violations. Also see this {{{http://blogs.techworld.com/monitoring-the-pulse-of-it/2010/08/grails-hudson-part-1-codenarc/}blog post}}. COMING SOON. * {{{http://www.sonarsource.org/}Sonar}} - The {{{http://docs.codehaus.org/display/SONAR/Groovy+Plugin}Sonar Groovy Plugin}} uses CodeNarc for its static analysis of Groovy source code. * Customizing ClassLoader for Loading Rule Scripts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<Grails>> (and possibly other tools integrating with <<CodeNarc>>) can benefit from using the current thread context <<<ClassLoader>>> for loading rule script files, rather than the default base <<<ClassLoader>>>. Setting the <"codenarc.useCurrentThreadContextClassLoader"> system property to <"true"> uses the current thread context <<<ClassLoader>>> for loading rule script files. That enables <<Grails>> to load rule script files from within the <<Grails>> project, and allows those rule scripts to reference local classes. See {{{https://jira.grails.org/browse/GPCODENARC-32}GPCODENARC-32}}. The {{{http://www.grails.org/plugin/codenarc/}Grails CodeNarc Plugin}} automatically sets that system property. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/site/apt/codenarc-configuring-rules.apt�������������������������������������������0000644�0001750�0001750�00000044637�12414275173�022733� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -------------------------------------------------- CodeNarc - Configuring Rules -------------------------------------------------- CodeNarc - Configuring Rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<Contents>> * {{{Configuring_Rules_Within_a_RuleSet_File}Configuring Rules Within a RuleSet File}} * {{{Configuring_Rules_Using_a_Properties_File}Configuring Rules Using a Properties File}} * {{{Standard_Properties_for_Configuring_Rules}Standard Properties for Configuring Rules}} * {{{Turning_Off_A_Rule}Turning Off A Rule}} * {{{Suppressing_A_Rule_From_Within_Source_Code}Suppressing A Rule From Within Source Code}} * {{{Customizing_Rule_Descriptions_Shown_in_the_HTML_Report}Customizing Rule Descriptions Shown in the HTML Report}} [] You can configure rules within the <RuleSet> file or within the "codenarc.properties" file. Both of these approaches are described in the sections below. <<NOTE>>: Keep in mind that <RuleSet> files can be nested (to any depth). That, along with the "codenarc.properties" file support, allows multiple layers of rule configuration. The hierarchical layering of configuration can come in handy within organizations comprised of multiple teams or projects. For instance, you can define an organization <RuleSet> file. Then each team can define its own <RuleSet> file and/or a "codenarc.properties" file, customizing the rules from the top-level file. * {Configuring Rules Within a RuleSet File} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{./codenarc-custom-ruleset.html}Creating a RuleSet}} describes how to create a new <RuleSet> and configure the rules within it. Here is an example of a Groovy <RuleSet> file that configures all three rules that it contains: +---------------------------------------------------------------------------------------- ruleset { CyclomaticComplexity { maxMethodComplexity = 1 } ConfusingTernary(priority:3) StatelessClass { name = 'StatelessDao' applyToClassNames = '*Dao' } } +---------------------------------------------------------------------------------------- Here is another example of a Groovy <RuleSet> file. This one includes another <RuleSet>, and configures a couple of the rules that it contains: +---------------------------------------------------------------------------------------- ruleset { ruleset('rulesets/basic.xml') { CatchThrowable { priority = 1 } EqualsAndHashCode priority:3 } } +---------------------------------------------------------------------------------------- If you have an XML <RuleSet>, then you can configure rules when you include a whole <RuleSet> using <<<\<ruleset-ref\>>>>, as in the following example: +---------------------------------------------------------------------------------------- <ruleset-ref path='rulesets/size.xml'> <rule-config name='ClassSize'> <property name='maxLines' value='500'/> </rule-config> </ruleset-ref> +---------------------------------------------------------------------------------------- Or you can configure <Rules> that you include individually using <<<\<rule\>>>>, as in the following example: +---------------------------------------------------------------------------------------- <rule class='org.codenarc.rule.naming.VariableNameRule'> <property name="finalRegex" value="F_[A-Z0-9]*"/> <property name='priority' value='1'/> </rule> +---------------------------------------------------------------------------------------- * {Configuring Rules Using a Properties File} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <<CodeNarc>> reads the properties file named "codenarc.properties", if found on the classpath, and applies the property values to any matching <Rules>. You can optionally override the location of the properties file by setting the "codenarc.properties.file" system property to the path or URL of the properties file. That can include a "file:" URL to load from a relative or absolute path on the filesystem (e.g., "file:relative/path/override-codenarc.properties"). If the properties file is not found, then do nothing. For each properties entry of the form <[rule-name].[property-name]=[property-value]>, the named property for the rule matching <rule-name> is set to the specified <property-value>. Properties entries not of this form or specifying rule names not within the current <RuleSet> are ignored. The following example "codenarc.properties" file configures several rules. Note that Fields with <<<Integer>>>, <<<String>>> and <<<Boolean>>> values are configured. +---------------------------------------------------------------------------------------- # Sample RuleSet configuration # Entries should be of the form: [rule-name].[property-name]=[property-value] CatchThrowable.doNotApplyToClassNames=BaseController,AbstractTest CatchThrowable.priority = 1 ReturnFromFinallyBlock.priority = 1 # Turn off this rule AbstractClassName.enabled=false # Unset special naming for final fields -- use base 'regex' value for all names FieldName.finalRegex= # Make sure all field names are prefixed with '_' FieldName.regex=_[a-z][a-zA-Z0-9]* +---------------------------------------------------------------------------------------- Note that you cannot add new rules using the "codenarc.properties" file, though you can disable (turn off) rules. * {Standard Properties for Configuring Rules} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The rules included with <<CodeNarc>> (as well as any subclasses of <<<AbstractRule>>>) provide several standard properties that can be used to configure how rules are applied to source files. ** Applying Rules Based on Class Name and/or Package Name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The <<<applyToClassNames>>> and <<<doNotApplyToClassNames>>> properties enable filtering the classes to which the rule is applied. If <<<applyToClassNames>>> is not empty or null, then the rule is only applied to classes matching one of the specified class names. Likewise, if <<<doNotApplyToClassNames>>> is not empty or null, then the rule is NOT applied to classes matching any of the specified class names. Both of these properties can specify either a single class name or a comma-separated list of names. The names may optionally contain wildcard characters ('*' or '?'). The wildcard character '*' matches a sequence of zero or more characters in the input string. The wildcard character '?' matches exactly one character in the input string. Each class name(s) can be either a fully-qualified class name (including the package) or else a class name without a package. For instance, in the following example "codenarc.properties" excerpt, the <CatchThrowable> rule is NOT applied to classes named "BaseController" or "AbstractTest", no matter what package they are in (if any). The <FieldName> rule, on the other hand, is only applied to the <<<org.codenarc.CodeNarc>>> class or any of the classes within <<<org.codenarc.extra>>> package. +---------------------------------------------------------------------------------------- CatchThrowable.doNotApplyToClassNames=BaseController,AbstractTest FieldName.applyToClassNames=org.codenarc.CodeNarc,org.codenarc.extra.* +---------------------------------------------------------------------------------------- Both properties default to <<<null>>>. These properties are available only to subclasses of <<<AbstractAstVisitorRule>>>, but this includes almost all of the rules provided with <<CodeNarc>> -- i.e., all of the rules that deal with the Groovy AST (Abstract Syntax Tree) of a source file. This includes any rule that processes source code elements such as a package, class, method, field, parameter, etc.. ** Applying Rules Based on File Path or Name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *** Matching Either Filename or Pathname, With Optional Wildcards ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The <<<applyToFileNames>>> and <<<doNotApplyToFileNames>>> properties enable filtering the files to which the rule is applied by specifying a comma-separated list of filenames (with optional path) of source files. If <<<applyToFileNames>>> is not empty or null, then the rule is only applied to source files matching one of the specified filenames. Likewise, if <<<doNotApplyToFilesMatching>>> is not empty or null, then the rule is NOT applied to source files matching any of the specified filenames. Both properties may optionally specify a path (i.e., if the value contains at least one '/' path separator). In that case, the value is matched against the full pathname of each source file. If no path is specified, then only the filename of each source file is compared (i.e., its path is ignored). Both properties may optionally contain wildcard characters ('*' or '?'). The wildcard character '*' matches a sequence of zero or more characters in the input string. The wildcard character '?' matches exactly one character in the input string. Both properties default to <<<null>>>. *** Matching File Pathnames Against a Regular Expression ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The <<<applyToFilesMatching>>> and <<<doNotApplyToFilesMatching>>> properties enable filtering the files to which the rule is applied by matching a regular expression against the <<full pathname>> of each source file. If <<<applyToFilesMatching>>> is not empty or null, then the rule is only applied to source files with matching paths. Likewise, if <<<doNotApplyToFilesMatching>>> is not empty or null, then the rule is NOT applied to source files with matching paths. Both properties default to <<<null>>>. * <<NOTE:>> File separator characters within pathnames are normalized to forward slashes (/). On Windows, for instance, that means that the path "c:\dir\file.txt" is normalized to "c:/dir/file.txt". If your regular expressions contain file separator characters, be sure that they are all the standard '/', no matter what operating system. [] ** Other Standard Rule Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The <<<enabled>>> boolean property allows a rule to be completely turned off (by setting it to <<<false>>>). It defaults to <<<true>>>. The <<<violationMessage>>> property enables overriding the rule violation message. If not null, this is used as the message for all violations of this rule, overriding any message generated by the rule itself. This property defaults to <<<null>>>. Note that setting this to an empty string "hides" the message, if any, generated by the actual rule. The <<<description>>> property enables overriding the rule description text. If not null, this value is used as the description text for this rule, overriding any description text found in the i18n resource bundles. This property defaults to <<<null>>>. Also see {{{Include_Substitutable_Message_Parameters_in_a_Rule_Description}Include Substitutable Message Parameters in a Rule Description}} You can also override the default <<<name>>> or <<<priority>>> properties for each rule. * {Turning Off A Rule} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can turn off a rule by filtering the containing ruleset to exclude the rule. See {{{./codenarc-creating-ruleset.html#Filtering_Rules_Within_a_RuleSet}Filtering Rules Within a RuleSet}}. Alternately, as mentioned above, you can turn off (disable) a rule by setting its <<<enabled>>> boolean property to <<<false>>> (assuming it is a subclass of <<<AbstractRule>>>), as shown in the following "codenarc.properties" excerpt. +---------------------------------------------------------------------------------------- # Turn off this rule AbstractClassName.enabled=false +---------------------------------------------------------------------------------------- And here is an example of disabling a rule within a Groovy <RuleSet> by setting its <<<enabled>>> attribute to <<<false>>>. +---------------------------------------------------------------------------------------- ruleset { ruleset('rulesets/basic.xml') { CatchThrowable(enabled:false) } } +---------------------------------------------------------------------------------------- * {Suppressing A Rule From Within Source Code} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can use the <<<@SuppressWarnings>>> annotation on a <class>, <method>, <constructor>, <field> or <property> to suppress one or more <<CodeNarc>> rules within its source code. Specify one or more rule name as the parameter of the <<<@SuppressWarnings>>> annotation. Note that this is the rule <name>, not the <class> name (i.e., without the "Rule" suffix). Specify multiple rule names by passing a <List> of rule names as a single parameter, e.g. <<<@SuppressWarnings(['IfStatementBraces', 'ThrowException'])>>> NOTE: The <<<@SuppressWarnings>>> annotation only works for rule classes that subclass <<<AbstractAstVisitorRule>>>. For example, the following code suppresses (prevents) violations of the <<DuplicateStringLiteral>> rule within the <<<MyClass>>> class, as well as suppressing the <IfStatementBraces> and <ThrowException> rules within its <<<getCount()>>> method. +---------------------------------------------------------------------------------------- @SuppressWarnings('DuplicateStringLiteral') class MyClass { def y = 'x' def z = 'x' @SuppressWarnings(['IfStatementBraces', 'ThrowException']) int getCount() { if (!ready) throw new Exception('Not ready') } } +---------------------------------------------------------------------------------------- * {Customizing Rule Descriptions Shown in the HTML Report} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The descriptions for rules used in a <<CodeNarc>> report are shown at the bottom of the resulting HTML report. Those rule descriptions are retrieved from a <ResourceBundle>. This <ResourceBundle> consists of a base (parent) bundle, provided with the <<CodeNarc>> distribution, and an optional custom (child) bundle, which may be provided by the user. Because this is based on the standard Java <ResourceBundle> facility, you can customize (override) or translate these descriptions by providing your own locale-specific message properties file on the classpath. For example, a German one would be named "codenarc-messages_de.properties". The rule description message key is of the form "<<\<rule-name\>.description.html>>". Examples include "BooleanInstantiation.description.html" and "CatchThrowable.description.html". (Note that the rule description included in the XML report is specified by the key <<\<rule-name\>.description>>). See the javadoc for the <<<java.util.ResourceBundle>>> class for more information. ** {Include Substitutable Message Parameters in a Rule Description} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can optionally include message parameters within a rule description, whether that description is specified in a ResourceBundle properties file or through the <<<description>>> property of the rule. Use the standard Groovy template parameter syntax: <<<$\{..\}>>>. You can reference rule property values through the "rule" object within the template parameter closure. For example, this description includes the rule <<<priority>>> within the rule description: <<<"Description for rule with priority $\{rule.priority\}">>>. ** The Base Messages Resource Bundle ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The base <ResourceBundle> provided with the <<CodeNarc>> distribution has a basename of "codenarc-base-messages". The rules provided with <<CodeNarc>> all have associated descriptions within the "codenarc-base-messages.properties" file. You can provide a locale-specific variant of this file on the classpath if you wish, but in most scenarios, the recommended approach for customizing rule descriptions is to provide a custom messages bundle file, as described below. ** The Custom Messages Resource Bundle ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can optionally provide descriptions for new rules or override existing rule descriptions by placing a "codenarc-messages.properties" file on the classpath. This is also a <ResourceBundle> file, so it can have locale-specific variants, if needed. If this bundle (file) is present, it is searched first. If the desired message key is not found, only then is the base message bundle checked. You can provide rule description entries within this file for custom rules that you create. You can also include rule description entries for existing rules, in which case the descriptions in this file override the default descriptions. ** Customizing the Name and Description for an Existing Rule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You may wish to customize both the <name> and the description for an existing rule. For example, you may want to have multiple instances of a generic rule, each configured differently. Or you may just want to make the rule name more clearly denote its specific purpose. For example, in the following excerpt from a <RuleSet> file, because the <name> property is customized for the <<IllegalRegexRule>>, the new rule name "AuthorTagNotAllowed" will show up at the bottom of the HTML report, instead of the default rule name "IllegalRegex". +---------------------------------------------------------------------------------------- <rule class='org.codenarc.rule.generic.IllegalRegexRule'> <property name="name" value="AuthorTagNotAllowed"/> <property name='regex' value='\@author'/> </rule> +---------------------------------------------------------------------------------------- The rule description must be added to the custom messages resource bundle file ("codenarc-messages.properties"). The message key will be "AuthorTagNotAllowed.description.html" to set the description used in the HTML report, and "AuthorTagNotAllowed.description" for the description used in the XML report. �������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/�����������������������������������������������������������������������������0000755�0001750�0001750�00000000000�12464300516�014213� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�016224� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/resource/����������������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�020053� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/resource/SampleResource.txt����������������������������������������0000644�0001750�0001750�00000000013�12006632012�023527� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������abcdef12345���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/����������������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�020072� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/CustomRuleSet.groovy��������������������������������������0000644�0001750�0001750�00000000750�12311373552�024123� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ruleset { description 'A custom Groovy RuleSet (see CodeNarcTask_CustomRuleSetTest)' CyclomaticComplexity { maxMethodComplexity = 1 } ClassName MethodName ConfusingTernary(priority:3) StatelessClass { name = 'StatelessDao' applyToClassNames = '*Dao' } // Old style rule(org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule) { priority = 3 } ruleset('rulesets/dry.xml') } ������������������������CodeNarc-0.23/src/test/resources/rulesets/RuleSet1.xml����������������������������������������������0000644�0001750�0001750�00000000547�12052043632�022263� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ruleset xmlns="http://codenarc.org/ruleset/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd" xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd"> <rule class='org.codenarc.rule.FakePathRule'/> </ruleset> ���������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/GroovyRuleSet_Bad.txt�������������������������������������0000644�0001750�0001750�00000000434�12006632016�024167� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Example Groovy RuleSet for testing import org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule ruleset { description 'A sample Groovy RuleSet' rule(ThrowExceptionFromFinallyBlockRule) { priority = 3 noSuchProperty = 'abc' } }������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/RuleSet4.xml����������������������������������������������0000644�0001750�0001750�00000001003�12006632016�022251� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ruleset xmlns="http://codenarc.org/ruleset/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd" xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd"> <rule class='org.codenarc.rule.exceptions.CatchThrowableRule'/> <rule class='org.codenarc.rule.basic.EmptyIfStatementRule'/> <rule class='org.codenarc.rule.basic.EmptyTryBlockRule'/> </ruleset>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/NestedRuleSet1.xml����������������������������������������0000644�0001750�0001750�00000001151�12006632014�023413� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ruleset xmlns="http://codenarc.org/ruleset/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd" xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd"> <ruleset-ref path='rulesets/RuleSet1.xml'/> <rule class='org.codenarc.rule.exceptions.CatchThrowableRule'> <property name='priority' value='1'/> </rule> <rule class='org.codenarc.rule.basic.EmptyIfStatementRule'> <property name='priority' value='1'/> </rule> </ruleset>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/GroovyRuleSet1.groovy�������������������������������������0000644�0001750�0001750�00000000660�12311373552�024217� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Example Groovy RuleSet for testing import org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule ruleset { description 'A sample Groovy RuleSet' ruleset('rulesets/RuleSet4.xml') { 'CatchThrowable' { priority = 1 enabled = false } include 'CatchThrowable' } rule(ThrowExceptionFromFinallyBlockRule) { priority = 3 } } ��������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/RuleSet3.xml����������������������������������������������0000644�0001750�0001750�00000000643�12006632020�022254� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ruleset xmlns="http://codenarc.org/ruleset/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd" xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd"> <rule class='org.codenarc.rule.StubRule'> <property name='name' value='Stub'/> </rule> </ruleset> ���������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/RuleSet2.xml����������������������������������������������0000644�0001750�0001750�00000001201�12006632016�022247� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<ruleset xmlns="http://codenarc.org/ruleset/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd" xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd"> <rule class='org.codenarc.rule.StubRule'> <property name='name' value='XXXX'/> </rule> <rule class='org.codenarc.rule.exceptions.CatchThrowableRule'> <property name='name' value='YYYY'/> <property name='priority' value='1'/> </rule> <rule-script path='rule/DoNothingRule.txt'/> </ruleset>�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/GroovyRuleSet2.txt����������������������������������������0000644�0001750�0001750�00000000537�12006632016�023507� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Example Groovy RuleSet for testing import org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule ruleset { ruleset('rulesets/GroovyRuleSet1.txt') { 'CatchThrowable' { priority = 3 } } rule(org.codenarc.rule.generic.StatelessClassRule) { addToIgnoreFieldNames = '*Test*' } }�����������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rulesets/GroovyRuleSet1.txt����������������������������������������0000644�0001750�0001750�00000000655�12006632012�023503� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Example Groovy RuleSet for testing import org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule ruleset { description 'A sample Groovy RuleSet' ruleset('rulesets/RuleSet4.xml') { 'CatchThrowable' { priority = 1 enabled = false } include 'CatchThrowable' } rule(ThrowExceptionFromFinallyBlockRule) { priority = 3 } }�����������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/RunCodeNarcAgainstGrails.ruleset�����������������������������������0000644�0001750�0001750�00000001225�12006632014�024437� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ruleset { description 'RuleSet for running CodeNarc against the Grails source code. See RunCodeNarcAgainstGrails' ruleset("rulesets/basic.xml") ruleset("rulesets/concurrency.xml") ruleset("rulesets/imports.xml") ruleset("rulesets/junit.xml") { exclude 'JUnitStyleAssertions' } ruleset("rulesets/size.xml") { exclude 'CrapMetric' } ruleset("rulesets/unused.xml") ruleset("rulesets/unnecessary.xml") { exclude 'UnnecessaryGString' exclude 'UnnecessaryPublicModifier' exclude 'UnnecessaryReturnKeyword' exclude 'UnnecessarySemicolon' } }���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/����������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021302� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir1/��������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022653� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy�������������������������0000644�0001750�0001750�00000001370�12311373552�026317� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 sourcewithdirs.subdir1 /** * Source file for testing * * @author Chris Mair */ class Subdir1File1 { } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir1/Subdir1File2.groovy�������������������������0000644�0001750�0001750�00000001370�12311373552�026320� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 sourcewithdirs.subdir1 /** * Source file for testing * * @author Chris Mair */ class Subdir1File2 { } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/SourceFile1.groovy����������������������������������0000644�0001750�0001750�00000001357�12311373552�024702� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 sourcewithdirs /** * Source file for testing * * @author Chris Mair */ class SourceFile1 { } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir2/��������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022654� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy�������������������������0000644�0001750�0001750�00000001370�12311373552�026321� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 sourcewithdirs.subdir2 /** * Source file for testing * * @author Chris Mair */ class Subdir2File1 { } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir2/subdir2b/�����������������������������������0000755�0001750�0001750�00000000000�12623571301�024370� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir2/subdir2b/NotAGroovyFile.txt�����������������0000644�0001750�0001750�00000000000�12005770252�027766� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir2/subdir2a/�����������������������������������0000755�0001750�0001750�00000000000�12623571301�024367� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy���������������0000644�0001750�0001750�00000001402�12311373552�030171� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 sourcewithdirs.subdir2.subdir2a /** * Source file for testing * * @author Chris Mair */ class Subdir2aFile1 { } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/log4j.properties���������������������������������������������������0000644�0001750�0001750�00000000515�11135771644�021373� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Set root logger level to INFO and only append to the CONSOLE. log4j.rootLogger=INFO, CONSOLE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender # CONSOLE uses PatternLayout. log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %c{1} [%t] %p - %m%n �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/RunCodeNarcAgainstProjectSourceCode.ruleset������������������������0000644�0001750�0001750�00000005726�12444433061�026621� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import org.codenarc.rule.generic.RequiredStringRule final TEST_FILES = ".*(Test|Tests|TestCase)\\.groovy" ruleset { description 'RuleSet for running CodeNarc against the project source code. See RunCodeNarcAgainstProjectSourceCodeTest' ruleset('rulesets/basic.xml') ruleset('rulesets/braces.xml') ruleset('rulesets/convention.xml') { exclude 'NoDef' } ruleset('rulesets/design.xml') { Instanceof(enabled:false) PublicInstanceField(doNotApplyToClassNames:'*Test') //Tests are guarded by JUnitPublicField } ruleset('rulesets/dry.xml') { include 'DuplicateMapLiteral' } ruleset('rulesets/exceptions.xml') ruleset('rulesets/groovyism.xml') { GStringExpressionWithinString(doNotApplyToClassNames:'*Test') } ruleset('rulesets/formatting.xml') { exclude 'MissingBlankLineAfterImports' exclude 'SpaceAfterCatch' exclude 'SpaceAfterFor' exclude 'SpaceAfterIf' exclude 'SpaceAfterSwitch' exclude 'SpaceAfterWhile' exclude 'SpaceAroundMapEntryColon' exclude 'TrailingWhitespace' } ruleset('rulesets/imports.xml') { exclude 'NoWildcardImports' } ruleset('rulesets/junit.xml') { exclude 'JUnitStyleAssertions' } ruleset('rulesets/logging.xml') ruleset('rulesets/naming.xml') { PackageNameMatchesFilePath(groupId:'org.codenarc') } ruleset('rulesets/size.xml') { exclude 'CrapMetric' } ruleset('rulesets/unnecessary.xml') { exclude 'UnnecessaryGetter' exclude 'UnnecessaryObjectReferences' exclude 'UnnecessaryReturnKeyword' } ruleset('rulesets/unused.xml') //------------------------------------------------------------------------------------ // Custom rules //------------------------------------------------------------------------------------ // Ensure that Rule and AstVisitor classes do not contain unnecessary public methods IllegalClassMember { name = 'UnnecessaryPublicMethodsInRuleClasses' applyToClassNames = 'Rule, *AstVisitor' doNotApplyToClassNames = 'AstVisitor, FieldReferenceAstVisitor' doNotApplyToFilesMatching = TEST_FILES illegalMethodModifiers = 'public' ignoreMethodsWithAnnotationNames = 'Override' ignoreMethodNames = 'visit*, handleClosure' description = 'Checks that Rule and AstVisitor classes do not contain unnecessary public methods' } // Ensure that each source file contains the Apache License header rule(RequiredStringRule) { name = 'ApacheLicenseRequired' string = 'Licensed under the Apache License, Version 2.0 (the "License");' violationMessage = 'The Apache License 2.0 comment is missing from the source file' description = 'Checks that all source files contain the Apache License 2.0 comment' } } ������������������������������������������CodeNarc-0.23/src/test/resources/RunCodeNarcAgainstProjectSourceCode.properties���������������������0000644�0001750�0001750�00000002236�12403444173�027324� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# CodeNarc properties for RunCodeNarcAgainstProjectSourceCodeTest AbcComplexity.doNotApplyToClassNames = HtmlReportWriter CatchThrowable.doNotApplyToClassNames = CodeNarc, AbstractRule, AntFileSetSourceAnalyzer, TestUtil JUnitPublicProperty.ignorePropertyNames = skipTestThat*, className, violationMessage MethodCount.doNotApplyToClassNames = *Test, *TestCase MisorderedStaticImports.doNotApplyToFileNames = *Test.groovy, *TestCase.groovy NestedBlockDepth.maxNestedBlockDepth = 3 NestedBlockDepth.doNotApplyToClassNames = HtmlReportWriter, XmlReportWriter, RuleSetBuilderTest Println.doNotApplyToClassNames = TextReportWriter, *Test, *TestCase, CodeNarcRunner, Generate* PrivateFieldCouldBeFinal.doNotApplyToClassNames = *Test UnusedObject.doNotApplyToClassNames = *Test LoggerWithWrongModifiers.allowProtectedLogger = true LoggerWithWrongModifiers.allowNonStaticLogger = true LineLength.length = 236 ClassSize.maxLines = 1250 # our factory methods are named create*, not make* FactoryMethodName.regex = (build.*|make.*) SpaceAfterClosingBrace.checkClosureMapEntryValue = false SpaceBeforeOpeningBrace.checkClosureMapEntryValue = false������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/codenarc-messages.properties���������������������������������������0000644�0001750�0001750�00000000377�12006632014�023726� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Custom Messages ResourceBundle file for testing. See HtmlReportWriterTest # WARNING: Do not changes the values within this file MyRuleXX.description=My Rule XX MyRuleXX.description.html=HTML Rule XX MyRuleYY.description = My Rule YY abc=123 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rule/��������������������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�017173� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rule/NotARule.txt��������������������������������������������������0000644�0001750�0001750�00000000110�12006632014�021407� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������class NotARule { String name = 'DoNothing' int priority = 2 }��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rule/BracesTestNewLine.txt�����������������������������������������0000644�0001750�0001750�00000001325�12006632016�023252� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /** * Comment */ class First { def x First() {} void method1() {} } @SuppressWarnings('bar') public class Second { public Second() { try { def range = 2..3 range.each(){print it} } catch (Exception e) { } finally { } for (i in 0..3) { } } private int method2() { if(1==1) { } else if (2==2) { } else { } if (3==3) { } while(1==1) { print "" } return 2 } } public interface Third { public static final Y }�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rule/BracesTestSameLine.txt����������������������������������������0000644�0001750�0001750�00000001114�12006632016�023402� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /** * Comment */ @SuppressWarnings('foo') class First{ def x First(){} void method1(){} } public class Second{ public Second(){ try{ def range = 2..3 range.each(){print it} }catch (Exception e){ }finally{ } for (i in 0..3){ } } private int method2(){ if(1==1) { } else if(2==2) { } else{ } if (3==3){ } while(1==1){ print "" } return 2 } } public interface Third{ public static final Y }����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rule/DoNothingRule.txt���������������������������������������������0000644�0001750�0001750�00000000416�12006632014�022450� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode class DoNothingRule extends AbstractRule { String name = 'DoNothing' int priority = 2 void applyTo(SourceCode sourceCode, List violations) { // Do nothing } }��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/rule/DoesNotCompileRule.txt����������������������������������������0000644�0001750�0001750�00000000452�12006632020�023440� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import org.codenarc.rule.AbstractRule import org.codenarc.source.SourceCode class DoesNotCompileRule extends AbstractRule { String name = 'DoNothing' int priority = 2 void applyTo(SourceCode sourceCode, List violations) { &^%$%^ This definitely won't compile } }����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/SampleInvalidFile.txt����������������������������������������������0000644�0001750�0001750�00000000005�12006632012�022300� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������%^&^%���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/source/������������������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�017524� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/source/SourceFile1.groovy������������������������������������������0000644�0001750�0001750�00000001347�12311373552�023123� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 source /** * Source file for testing * * @author Chris Mair */ class SourceFile1 { } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/source/SourceFile2.groovy������������������������������������������0000644�0001750�0001750�00000001742�12311373552�023123� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 source /** * Source file for testing * * @author Chris Mair */ class SourceFile2 { static final METHOD_NAME = 'calculateValue' static someVariable = "${METHOD_NAME}"() // GString method name static otherVariable = "calculateValue"() // String method name static String calculateValue() { 23 } } ������������������������������CodeNarc-0.23/src/test/resources/source/SomeOtherFile.txt�������������������������������������������0000644�0001750�0001750�00000000000�12005770252�022760� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/override-codenarc.properties���������������������������������������0000644�0001750�0001750�00000000467�12006632014�023736� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Test-only properties - Used by PropertiesFileRuleSetConfigurerTest # PropertiesFileRuleSetConfigurerTest rule1.priority=2 rule2.violationMessage = override rule2.name = rule99 other.priority = 1 rule2.other.form = ignore this # CodeNarcTaskTest TestPath.priority=3 #TestPath.description=problem���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/RunCodeNarcAgainstExternalProject.ruleset��������������������������0000644�0001750�0001750�00000002741�12414302051�026331� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import org.codenarc.rule.generic.RequiredStringRule ruleset { description 'RuleSet for running CodeNarc against the project source code. See RunCodeNarcAgainstProjectSourceCodeTest' ruleset('rulesets/basic.xml') ruleset('rulesets/braces.xml') ruleset('rulesets/convention.xml') { exclude 'NoDef' } ruleset('rulesets/design.xml') ruleset('rulesets/dry.xml') { include 'DuplicateMapLiteral' } ruleset('rulesets/exceptions.xml') ruleset('rulesets/groovyism.xml') ruleset('rulesets/formatting.xml') ruleset('rulesets/imports.xml') ruleset('rulesets/junit.xml') { exclude 'JUnitStyleAssertions' } ruleset('rulesets/logging.xml') ruleset('rulesets/naming.xml') ruleset('rulesets/size.xml') { exclude 'CrapMetric' } ruleset('rulesets/unnecessary.xml') { exclude 'UnnecessaryGetter' exclude 'UnnecessaryObjectReferences' exclude 'UnnecessaryReturnKeyword' } ruleset('rulesets/unused.xml') // Ensure that each source file contains the Apache License header rule(RequiredStringRule) { name = 'ApacheLicenseRequired' string = 'Licensed under the Apache License, Version 2.0 (the "License");' violationMessage = 'The Apache License 2.0 comment is missing from the source file' description = 'Checks that all source files contain the Apache License 2.0 comment' } }�������������������������������CodeNarc-0.23/src/test/resources/coverage/����������������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�020017� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/coverage/Cobertura-example.xml�������������������������������������0000644�0001750�0001750�00000004027�12006632014�024115� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0"?> <!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd"> <coverage line-rate="0.945" branch-rate="0.785" lines-covered="2506" lines-valid="2651" branches-covered="873" branches-valid="1112" complexity="1.631578947368421" version="1.9.4.1" timestamp="1321536573337"> <sources> <source>MyProject/src/main/groovy</source> </sources> <packages> <package name="com.example.service" line-rate="0.85" branch-rate="0.65" complexity="0.0"> <classes> <class name="com.example.service.Email" filename="com/example/service/Email.groovy" line-rate="0.66" branch-rate="0.61" complexity="0.0"> <methods> <method name="toString" signature="()Ljava/lang/String;" line-rate="0.5" branch-rate="0.91"> <lines> <line number="26" hits="1538" branch="false"/> <line number="27" hits="780" branch="true" condition-coverage="25% (1/4)"> <conditions> <condition number="0" type="jump" coverage="50%"/> <condition number="1" type="jump" coverage="0%"/> </conditions> </line> <line number="27" hits="1538" branch="false"/> </lines> </method> </methods> <lines> <line number="26" hits="1538" branch="false"/> <line number="27" hits="13" branch="true" condition-coverage="100% (1/2)"> <conditions> <condition number="0" type="jump" coverage="50%"/> </conditions> </line> </lines> </class> </classes> </package> </packages> </coverage> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/SampleFile.groovy��������������������������������������������������0000644�0001750�0001750�00000000030�12311373552�021507� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������class SampleFile { } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/resources/codenarc.properties������������������������������������������������0000644�0001750�0001750�00000001034�12006632012�022106� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Test-only properties - Used by PropertiesFileRuleSetConfigurerTest, CodeNarcTaskTest and CodeNarcTaskAllRuleSetsTest # PropertiesFileRuleSetConfigurerTest rule1.priority=3 rule2.violationMessage = violation rule2.name = rule99 other.priority = 1 rule2.other.form = ignore this # CodeNarcTaskTest TestPath.priority=3 #TestPath.description=problem # CodeNarcTaskAllRuleSetsTest StatelessClass.enabled = false DuplicateNumberLiteral.enabled = false DuplicateStringLiteral.enabled = false UnnecessaryGetter.enabled = false����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/����������������������������������������������������������������������0000755�0001750�0001750�00000000000�12303254654�015543� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/������������������������������������������������������������������0000755�0001750�0001750�00000000000�12303254654�016332� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/���������������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�020104� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/CodeNarcTest.groovy��������������������������������������0000644�0001750�0001750�00000023654�12403722210�023674� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc import org.codenarc.analyzer.FilesystemSourceAnalyzer import org.codenarc.report.HtmlReportWriter import org.codenarc.report.XmlReportWriter import org.codenarc.test.AbstractTestCase import org.junit.After import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.captureSystemOut import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for CodeNarc command-line runner * * @author Chris Mair */ class CodeNarcTest extends AbstractTestCase { private static final BASE_DIR = 'src/test/resources' private static final BASIC_RULESET = 'rulesets/basic.xml' private static final RULESET1 = 'rulesets/RuleSet1.xml' private static final INCLUDES = 'sourcewithdirs/**/*.groovy' private static final EXCLUDES = '**/*File2.groovy' private static final TITLE = 'My Title' private static final HTML_REPORT_FILE = new File('CodeNarcTest-Report.html').absolutePath private static final HTML_REPORT_STR = "html:$HTML_REPORT_FILE" private static final XML_REPORT_FILE = 'CodeNarcTest-Report.xml' private static final XML_REPORT_STR = "xml:$XML_REPORT_FILE" private codeNarc private outputFile private int exitCode @Test void testParseArgs_InvalidOptionName() { shouldFailWithMessageContaining('unknown') { parseArgs('-unknown=abc') } } @Test void testParseArgs_InvalidOption_NoHyphen() { shouldFailWithMessageContaining('bad') { parseArgs('bad=abc') } } @Test void testParseArgs_InvalidOption_NoEquals() { shouldFailWithMessageContaining('badstuff') { parseArgs('badstuff') } } @Test void testParseArgs_SingleRuleSetFile() { parseArgs("-rulesetfiles=$RULESET1") assert codeNarc.ruleSetFiles == RULESET1 } @Test void testParseArgs_BaseDir() { parseArgs("-basedir=$BASE_DIR") assert codeNarc.baseDir == BASE_DIR } @Test void testParseArgs_Includes() { parseArgs("-includes=$INCLUDES") assert codeNarc.includes == INCLUDES } @Test void testParseArgs_Excludes() { parseArgs("-excludes=$EXCLUDES") assert codeNarc.excludes == EXCLUDES } @Test void testParseArgs_Title() { parseArgs("-title=$TITLE") assert codeNarc.title == TITLE } @Test void testParseArgs_SingleHtmlReport() { parseArgs("-report=$HTML_REPORT_STR") assert codeNarc.reports.size() == 1 assert codeNarc.reports[0].class == HtmlReportWriter assert codeNarc.reports[0].outputFile == HTML_REPORT_FILE } @Test void testParseArgs_SingleXmlReport() { parseArgs("-report=$XML_REPORT_STR") assert codeNarc.reports.size() == 1 assert codeNarc.reports[0].class == XmlReportWriter assert codeNarc.reports[0].outputFile == XML_REPORT_FILE } @Test void testParseArgs_SingleReportSpecifyingFullReportWriterClassName() { def reportString = "org.codenarc.report.HtmlReportWriter:$HTML_REPORT_FILE" parseArgs("-report=$reportString") assert codeNarc.reports.size() == 1 assert codeNarc.reports[0].class == HtmlReportWriter assert codeNarc.reports[0].outputFile == HTML_REPORT_FILE } @Test void testParseArgs_ThreeReports() { parseArgs("-report=$HTML_REPORT_STR", '-report=html', "-report=$XML_REPORT_STR") assert codeNarc.reports.size() == 3 assert codeNarc.reports[0].class == HtmlReportWriter assert codeNarc.reports[0].outputFile == HTML_REPORT_FILE assert codeNarc.reports[1].class == HtmlReportWriter assert codeNarc.reports[1].outputFile == null assert codeNarc.reports[2].class == XmlReportWriter assert codeNarc.reports[2].outputFile == XML_REPORT_FILE } @Test void testParseArgs_InvalidReportType() { shouldFailWithMessageContaining('pdf') { parseArgs('-report=pdf') } shouldFailWithMessageContaining('pdf') { parseArgs('-report=pdf:MyReport.pdf') } } @Test void testSetDefaultsIfNecessary_ValuesNotSet() { codeNarc.setDefaultsIfNecessary() assert codeNarc.includes == '**/*.groovy' assert codeNarc.ruleSetFiles == BASIC_RULESET assertReport(codeNarc.reports[0], HtmlReportWriter, null, null) assert codeNarc.baseDir == '.' } @Test void testSetDefaultsIfNecessary_TitleSet() { codeNarc.title = 'abc' codeNarc.setDefaultsIfNecessary() assertReport(codeNarc.reports[0], HtmlReportWriter, null, 'abc') } @Test void testSetDefaultsIfNecessary_ValuesAlreadySet() { codeNarc.includes = 'aaa' codeNarc.ruleSetFiles = 'bbb' codeNarc.reports = ['ccc'] // just need a non-empty list codeNarc.baseDir = 'ddd' codeNarc.setDefaultsIfNecessary() assert codeNarc.includes == 'aaa' assert codeNarc.ruleSetFiles == 'bbb' assert codeNarc.reports == ['ccc'] assert codeNarc.baseDir == 'ddd' } @Test void testExecute() { final ARGS = [ "-report=$HTML_REPORT_STR", "-basedir=$BASE_DIR", "-includes=$INCLUDES", "-title=$TITLE", "-excludes=$EXCLUDES", "-rulesetfiles=$RULESET1"] as String[] def codeNarcRunner = [execute: { }] codeNarc.createCodeNarcRunner = { codeNarcRunner } codeNarc.execute(ARGS) assert codeNarc.ruleSetFiles == RULESET1 assert codeNarc.includes == INCLUDES assert codeNarc.excludes == EXCLUDES def sourceAnalyzer = codeNarcRunner.sourceAnalyzer assert sourceAnalyzer.class == FilesystemSourceAnalyzer assert sourceAnalyzer.baseDirectory == BASE_DIR assert sourceAnalyzer.includes == INCLUDES assert sourceAnalyzer.excludes == EXCLUDES assert codeNarcRunner.ruleSetFiles == RULESET1 assert codeNarcRunner.reportWriters.size == 1 def reportWriter = codeNarcRunner.reportWriters[0] assertReport(reportWriter, HtmlReportWriter, HTML_REPORT_FILE, TITLE) assert exitCode == 0 } @Test void testExecute_NoArgs() { final ARGS = [] as String[] def codeNarcRunner = [execute: { }] codeNarc.createCodeNarcRunner = { codeNarcRunner } codeNarc.execute(ARGS) assert codeNarc.ruleSetFiles == BASIC_RULESET assert codeNarc.includes == '**/*.groovy' assert codeNarc.excludes == null assert codeNarcRunner.sourceAnalyzer.class == FilesystemSourceAnalyzer assert codeNarcRunner.sourceAnalyzer.baseDirectory == '.' assert codeNarcRunner.ruleSetFiles == BASIC_RULESET assert codeNarcRunner.reportWriters.size == 1 def reportWriter = codeNarcRunner.reportWriters[0] assertReport(reportWriter, HtmlReportWriter, null, null) assert exitCode == 0 } @Test void testMain() { final ARGS = [ "-report=$HTML_REPORT_STR", "-basedir=$BASE_DIR", "-includes=$INCLUDES", "-title=$TITLE", "-excludes=$EXCLUDES", "-rulesetfiles=$RULESET1"] as String[] CodeNarc.main(ARGS) assert outputFile.exists() assert exitCode == 0 } @Test void testMain_Help() { final ARGS = ['-help'] as String[] def stdout = captureSystemOut { CodeNarc.main(ARGS) } log("stdout=[$stdout]") assert !stdout.contains('ERROR') assert stdout.contains(CodeNarc.HELP) assert !outputFile.exists() assert exitCode == 0 } @Test void testMain_BadOptionFormat() { final ARGS = ["-report=$HTML_REPORT_STR", '&^%#BAD%$#'] as String[] def stdout = captureSystemOut { CodeNarc.main(ARGS) } log("stdout=[$stdout]") assert stdout.contains(ARGS[1]) assert stdout.contains(CodeNarc.HELP) assert !outputFile.exists() assert exitCode == 1 } @Test void testMain_UnknownOption() { final ARGS = ['-unknown=23', "-report=$HTML_REPORT_STR"] as String[] def stdout = captureSystemOut { CodeNarc.main(ARGS) } log("stdout=[$stdout]") assert stdout.contains(ARGS[0]) assert stdout.contains(CodeNarc.HELP) assert !outputFile.exists() assert exitCode == 1 } //-------------------------------------------------------------------------- // Test setUp/tearDown and helper methods //-------------------------------------------------------------------------- @Before void setUp() { codeNarc = new CodeNarc() codeNarc.systemExit = { code -> exitCode = code } outputFile = new File(HTML_REPORT_FILE) } @After void tearDown() { outputFile.delete() } private void parseArgs(Object[] args) { def argsAsArray = args as String[] codeNarc.parseArgs(argsAsArray) } private void assertReport(report, Class reportClass, String toFile, String title) { assert report.class == reportClass assert report.outputFile == toFile assert report.title == title } } ������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/�������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021567� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/PropertiesFileRuleSetConfigurerTest.groovy�������0000644�0001750�0001750�00000006065�12041642704�032171� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.StubRule import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for PropertiesFileRuleSetConfigurer * * @author Chris Mair */ class PropertiesFileRuleSetConfigurerTest extends AbstractTestCase { private ruleSet private rule1 = new StubRule(name:'rule1', priority:1, violationMessage:'abc') private rule2 = new StubRule(name:'rule2', priority:2, violationMessage:'def') private configurer @Test void testConfigure() { configurer.configure(ruleSet) assert ruleMap() == [rule1:[3, 'abc'], rule99:[2, 'violation']], ruleMap() } @Test void testConfigure_OverridePropertiesFilenameThroughSystemProperty() { System.setProperty(CODENARC_PROPERTIES_FILE_PROP, 'override-codenarc.properties') configurer.configure(ruleSet) assert ruleMap() == [rule1:[2, 'abc'], rule99:[2, 'override']], ruleMap() System.setProperty(CODENARC_PROPERTIES_FILE_PROP, '') } @Test void testConfigure_OverridePropertiesFilenameThroughSystemProperty_FileUrl() { System.setProperty(CODENARC_PROPERTIES_FILE_PROP, 'file:src/test/resources/override-codenarc.properties') configurer.configure(ruleSet) assert ruleMap() == [rule1:[2, 'abc'], rule99:[2, 'override']], ruleMap() System.setProperty(CODENARC_PROPERTIES_FILE_PROP, '') } @Test void testConfigure_PropertiesFileDoesNotExist() { configurer.defaultPropertiesFilename = 'DoesNotExist.properties' configurer.configure(ruleSet) assert ruleMap() == [rule1:[1, 'abc'], rule2:[2, 'def']] } @Test void testConfigure_EmptyRuleSet() { ruleSet = new ListRuleSet([]) configurer.configure(ruleSet) assert ruleMap() == [:], ruleMap() } @Test void testConfigure_NullRuleSet() { shouldFailWithMessageContaining('ruleSet') { configurer.configure(null) } } @Before void setUpPropertiesFileRuleSetConfigurerTest() { configurer = new PropertiesFileRuleSetConfigurer() ruleSet = new ListRuleSet([rule1, rule2]) } private ruleMap() { def map = [:] ruleSet.rules.each { rule -> map[rule.name] = [rule.priority, rule.violationMessage] } map } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/XmlReaderRuleSetSchemaValidationTest.groovy������0000644�0001750�0001750�00000015044�12323251266�032227� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * XML Schema validation tests for XmlReaderRuleSet class * * @author Chris Mair */ class XmlReaderRuleSetSchemaValidationTest extends AbstractTestCase { private static final NAMESPACE = ''' xmlns="http://codenarc.org/ruleset/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd" xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd" ''' @Test void testIllegalTopLevelElement() { final XML = '<ruleset2></ruleset2>' assertSchemaValidationError(XML, 'ruleset2') } @Test void testNoNamespaceDeclaration() { final XML = """ <ruleset> <rule class='org.codenarc.rule.StubRule'/> </ruleset>""" assertSchemaValidationError(XML, 'ruleset') } @Test void testIllegalRuleSetChildElement() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.StubRule'/> <other stuff='12345'/> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleChildElement() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.StubRule'> <property name='name' value='YYYY'/> <other name='priority' value='1'/> </rule> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleAttribute() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.StubRule' other='12345'/> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleScriptChildElement() { final XML = """ <ruleset $NAMESPACE> <rule-script path='rule/MyRule.groovy'> <property name='name' value='YYYY'/> <other name='priority' value='1'/> </rule> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleScriptAttribute() { final XML = """ <ruleset $NAMESPACE> <rule-script path='rule/MyRule.groovy' other='12345'/> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalPropertyAttribute() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.StubRule'> <property other='name' value='YYYY'/> </rule> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleSetRefChildElement() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet1.xml'> <other name='12345'/> </ruleset-ref> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleSetRefAttribute() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet1.xml' other='12345'/> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalIncludeAttribute() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet1.xml'> <include other='12345'/> </ruleset-ref> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalExcludeAttribute() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet1.xml'> <exclude name='123' other='12345'/> </ruleset-ref> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleConfigAttribute() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet1.xml'> <rule-config name='123' other='12345'/> </ruleset-ref> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleConfigChildElement() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet1.xml'> <rule-config name='123'> <other name='12345'/> </rule-config> </ruleset-ref> </ruleset>""" assertSchemaValidationError(XML, 'other') } @Test void testIllegalRuleConfigPropertyAttribute() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet1.xml'> <rule-config name='123'> <property name='123' other='name' value='YYYY'/> </rule-config> </ruleset-ref> </ruleset>""" assertSchemaValidationError(XML, 'other') } //-------------------------------------------------------------------------- // Internal Helper Methods //-------------------------------------------------------------------------- private XmlReaderRuleSet assertSchemaValidationError(String xml, String expectedText) { def reader = new StringReader(xml) shouldFailWithMessageContaining(expectedText) { new XmlReaderRuleSet(reader) } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/FilteredRuleSetTest.groovy�����������������������0000644�0001750�0001750�00000010227�12323251057�026742� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.StubRule import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for FilteredRuleSet * * @author Chris Mair */ class FilteredRuleSetTest extends AbstractTestCase { private static final RULE1 = new StubRule(name:'Rule1') private static final RULE2 = new StubRule(name:'Rule2') private static final RULE3 = new StubRule(name:'Rule3') private innerRuleSet private filteredRuleSet @Test void testConstructor_NullRuleSet() { shouldFailWithMessageContaining('ruleSet') { new FilteredRuleSet(null) } } @Test void testGetRules() { assert filteredRuleSet.getRules() == [RULE1, RULE2, RULE3] } @Test void testAddInclude_Null() { shouldFailWithMessageContaining('include') { filteredRuleSet.addInclude(null) } } @Test void testAddInclude_Empty() { shouldFailWithMessageContaining('include') { filteredRuleSet.addInclude('') } } @Test void testAddExclude_Null() { shouldFailWithMessageContaining('exclude') { filteredRuleSet.addExclude(null) } } @Test void testAddExclude_Empty() { shouldFailWithMessageContaining('exclude') { filteredRuleSet.addExclude('') } } @Test void testOneInclude() { filteredRuleSet.addInclude('Rule2') assert filteredRuleSet.getRules() == [RULE2] } @Test void testTwoIncludes() { filteredRuleSet.addInclude('Rule1') filteredRuleSet.addInclude('Rule3') assert filteredRuleSet.getRules() == [RULE1, RULE3] } @Test void testIncludes_Wildcards() { filteredRuleSet.addInclude('Ru?e1') filteredRuleSet.addInclude('*3') assert filteredRuleSet.getRules() == [RULE1, RULE3] } @Test void testOneExclude() { filteredRuleSet.addExclude('Rule2') assert filteredRuleSet.getRules() == [RULE1, RULE3] } @Test void testTwoExclude() { filteredRuleSet.addExclude('Rule2') filteredRuleSet.addExclude('Rule3') assert filteredRuleSet.getRules() == [RULE1] } @Test void testExcludes_Wildcards() { filteredRuleSet.addExclude('*2') filteredRuleSet.addExclude('R?l?3') assert filteredRuleSet.getRules() == [RULE1] } @Test void testBothIncludesAndExcludes() { filteredRuleSet.addInclude('Rule1') filteredRuleSet.addInclude('Rule2') filteredRuleSet.addExclude('Rule2') // Exclude takes precedence filteredRuleSet.addExclude('Rule3') assert filteredRuleSet.getRules() == [RULE1] } @Test void testBothIncludesAndExcludes_Wildcards() { filteredRuleSet.addInclude('R?le1') filteredRuleSet.addInclude('Rule2') filteredRuleSet.addExclude('*2') // Exclude takes precedence filteredRuleSet.addExclude('??le3') assert filteredRuleSet.getRules() == [RULE1] } @Test void testInternalRulesListIsImmutable() { def rules = filteredRuleSet.rules shouldFail(UnsupportedOperationException) { rules.add(123) } } @Before void setUpFilteredRuleSetTest() { innerRuleSet = new ListRuleSet([RULE1, RULE2, RULE3]) filteredRuleSet = new FilteredRuleSet(innerRuleSet) } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/GroovyDslRuleSetTest.groovy����������������������0000644�0001750�0001750�00000007025�12323251166�027137� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.* /** * Tests for GroovyDslRuleSet * * @author Chris Mair */ class GroovyDslRuleSetTest extends AbstractTestCase { @Test void testNullPath() { shouldFailWithMessageContaining('path') { new GroovyDslRuleSet(null) } } @Test void testEmptyPath() { shouldFailWithMessageContaining('path') { new GroovyDslRuleSet('') } } @Test void testFileDoesNotExist() { def errorMessage = shouldFail { new GroovyDslRuleSet('DoesNotExist.xml') } assertContainsAll(errorMessage, ['DoesNotExist.xml', 'does not exist']) } @Test void testLoadGroovyRuleSet_SetNonExistentRuleProperty() { shouldFailWithMessageContaining('noSuchProperty') { new GroovyDslRuleSet('rulesets/GroovyRuleSet_Bad.txt') } } @Test void testLoadGroovyRuleSet() { final PATH = 'rulesets/GroovyRuleSet1.txt' // groovy files are not on classpath; have to use *.txt def groovyDslRuleSet = new GroovyDslRuleSet(PATH) def rules = groovyDslRuleSet.rules log("rules=$rules") assert rules*.name == ['CatchThrowable', 'ThrowExceptionFromFinallyBlock'] assert rules[0].priority == 1 assert !rules[0].enabled assert rules[1].priority == 3 } @Test void testLoadGroovyRuleSet_RelativeFileUrl() { final PATH = 'file:src/test/resources/rulesets/GroovyRuleSet1.groovy' def groovyDslRuleSet = new GroovyDslRuleSet(PATH) def rules = groovyDslRuleSet.rules log("rules=$rules") assert rules*.name == ['CatchThrowable', 'ThrowExceptionFromFinallyBlock'] assert rules[0].priority == 1 assert !rules[0].enabled assert rules[1].priority == 3 } @Test void testLoadGroovyRuleSet_ConfigFileDoesNotCompile() { def file = File.createTempFile('codenarctest', '.groovy') file.deleteOnExit() file.text = ''' // OH HAI, I IZ DEFINITLY NOT COMPILING +++++++++ ''' def msg = shouldFail(IllegalStateException) { new GroovyDslRuleSet('file:' + file.absolutePath) } assert msg.contains('error occurred compiling') assert msg.contains(file.absolutePath) assert msg.contains('unexpected token: ++ @ line 3, column 3') file.delete() } @Test void testLoadNestedGroovyRuleSet() { final PATH = 'rulesets/GroovyRuleSet2.txt' def groovyDslRuleSet = new GroovyDslRuleSet(PATH) def rules = groovyDslRuleSet.rules log("rules=$rules") assert rules*.name == ['CatchThrowable', 'ThrowExceptionFromFinallyBlock', 'StatelessClass'] assert rules[0].priority == 3 assert !rules[0].enabled assert rules[1].priority == 3 } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/ListRuleSetTest.groovy���������������������������0000644�0001750�0001750�00000003252�12323251206�026113� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.Rule import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for ListRuleSet * * @author Chris Mair */ class ListRuleSetTest extends AbstractTestCase { private static final RULE = [:] as Rule @Test void testWithRules() { def ruleSet = new ListRuleSet([RULE]) assert ruleSet.getRules() == [RULE] } @Test void testRulesListIsImmutable() { def list = [RULE] def ruleSet = new ListRuleSet(list) list.clear() def r = ruleSet.getRules() assert r == [RULE] shouldFail(UnsupportedOperationException) { r.clear() } } @Test void testWithNull() { shouldFailWithMessageContaining('rules') { new ListRuleSet(null) } } @Test void testWithNonRules() { shouldFail { new ListRuleSet([RULE, 23]) } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/CompositeRuleSetTest.groovy����������������������0000644�0001750�0001750�00000005030�12323251010�027127� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.Rule import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for CompositeRuleSet * * @author Chris Mair */ class CompositeRuleSetTest extends AbstractTestCase { private static final RULE1 = [:] as Rule private static final RULE2 = [:] as Rule private compositeRuleSet @Test void testDefaultsToEmpyRuleSet() { assert compositeRuleSet.getRules() == [] } @Test void testAddRuleSet_Null() { shouldFailWithMessageContaining('ruleSet') { compositeRuleSet.addRuleSet((RuleSet)null) } } @Test void testAddRuleSet_OneRuleSet() { def ruleSet = new ListRuleSet([RULE1]) compositeRuleSet.addRuleSet(ruleSet) assert compositeRuleSet.getRules() == [RULE1] } @Test void testAddRuleSet_TwoRuleSets() { def ruleSet1 = new ListRuleSet([RULE1]) def ruleSet2 = new ListRuleSet([RULE2]) compositeRuleSet.addRuleSet(ruleSet1) compositeRuleSet.addRuleSet(ruleSet2) assert compositeRuleSet.getRules() == [RULE1, RULE2] } @Test void testAddRule_Null() { shouldFailWithMessageContaining('rule') { compositeRuleSet.addRule((Rule)null) } } @Test void testAddRule() { compositeRuleSet.addRule(RULE1) compositeRuleSet.addRule(RULE2) assert compositeRuleSet.getRules() == [RULE1, RULE2] } @Test void testInternalRulesListIsImmutable() { def rules = compositeRuleSet.rules shouldFail(UnsupportedOperationException) { rules.add(123) } } @Before void setUpCompositeRuleSetTest() { compositeRuleSet = new CompositeRuleSet() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/XmlFileRuleSetTest.groovy������������������������0000644�0001750�0001750�00000005237�12052043632�026546� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.StubRule import org.codenarc.rule.exceptions.CatchThrowableRule import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.* import org.codenarc.rule.FakePathRule /** * Tests for XmlFileRuleSet * * @author Chris Mair */ class XmlFileRuleSetTest extends AbstractTestCase { @Test void testNullPath() { shouldFailWithMessageContaining('path') { new XmlFileRuleSet(null) } } @Test void testEmptyPath() { shouldFailWithMessageContaining('path') { new XmlFileRuleSet('') } } @Test void testFileDoesNotExist() { def errorMessage = shouldFail { new XmlFileRuleSet('DoesNotExist.xml') } assertContainsAll(errorMessage, ['DoesNotExist.xml', 'does not exist']) } @Test void testOneRule() { final PATH = 'rulesets/RuleSet1.xml' def ruleSet = new XmlFileRuleSet(PATH) def rules = ruleSet.rules assert rules*.class == [FakePathRule] } @Test void testMultipleRulesWithProperties() { final PATH = 'rulesets/RuleSet2.xml' def ruleSet = new XmlFileRuleSet(PATH) def rules = ruleSet.rules assert rules[0].class == StubRule assert rules[1].class == CatchThrowableRule assert rules[2].class.name == 'DoNothingRule' // Rule script, so class is dynamic assert rules*.name == ['XXXX', 'YYYY', 'DoNothing'] assert rules*.priority == [0, 1, 2] } @Test void testFileUrl() { final PATH = 'file:src/test/resources/rulesets/RuleSet1.xml' def ruleSet = new XmlFileRuleSet(PATH) def rules = ruleSet.rules assert rules*.class == [FakePathRule] } @Test void testRulesListIsImmutable() { final PATH = 'rulesets/RuleSet1.xml' def ruleSet = new XmlFileRuleSet(PATH) def rules = ruleSet.rules shouldFail(UnsupportedOperationException) { rules.clear() } } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/LoadAllPredefinedRuleSetsTest.groovy�������������0000644�0001750�0001750�00000005463�12311370173�030671� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import javax.xml.parsers.DocumentBuilder import javax.xml.parsers.DocumentBuilderFactory /** * Load all predefined RuleSet files using XmlFileRuleSet * * @author Chris Mair */ class LoadAllPredefinedRuleSetsTest extends AbstractTestCase { private static final BASE_MESSAGES_BUNDLE = 'codenarc-base-messages' private messages @Test void testPredefinedRulesHaveDescriptions() { forEachRule { rule -> assert messages.getString(rule.name + '.description') assert messages.getString(rule.name + '.description.html') } } @SuppressWarnings('CatchThrowable') @Test void testPredefinedRulesHaveValidHtmlDescriptions() { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance() factory.validating = false factory.namespaceAware = true DocumentBuilder builder = factory.newDocumentBuilder() def errors = [] forEachRule { rule -> String propertyName = rule.name + '.description.html' def htmlSnippet = messages.getString(propertyName) //builder.setErrorHandler(new SimpleErrorHandler()); ByteArrayInputStream bs = new ByteArrayInputStream(('<root>' + htmlSnippet + '</root>').bytes) try { builder.parse(bs) } catch (Throwable t) { errors.add("""An error occurred parsing the property $propertyName Value: $htmlSnippet Error: $t.message """) } } if (errors) { fail(errors.join('\n')) } } private forEachRule(Closure assertion) { RuleSets.ALL_RULESET_FILES.each { ruleSetPath -> def ruleSet = new XmlFileRuleSet(ruleSetPath) def rules = ruleSet.rules log("[$ruleSetPath] rules=$rules") assert rules rules.each(assertion) } } @Before void setUpLoadAllPredefinedRuleSetsTest() { messages = ResourceBundle.getBundle(BASE_MESSAGES_BUNDLE) } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/RuleSetBuilderTest.groovy������������������������0000644�0001750�0001750�00000030074�12462041001�026562� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.exceptions.CatchThrowableRule import org.codenarc.rule.generic.IllegalRegexRule import org.codenarc.rule.naming.ClassNameRule import org.codenarc.ruleregistry.RuleRegistry import org.codenarc.ruleregistry.RuleRegistryHolder import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for RuleSetBuilder * * @author Chris Mair */ class RuleSetBuilderTest extends AbstractTestCase { private static final RULESET_XML_FILE1 = 'rulesets/RuleSet1.xml' private static final RULESET_XML_FILE2 = 'rulesets/RuleSet4.xml' private static final RULESET_GROOVY_FILE1 = 'rulesets/GroovyRuleSet1.txt' private static final RULE_SCRIPT_FILE = 'rule/DoNothingRule.txt' private ruleSetBuilder @Test void testRuleset_NullFilename() { shouldFailWithMessageContaining('path') { ruleSetBuilder.ruleset { ruleset(null) } } } @Test void testRuleset_XmlFile_RuleSetFileDoesNotExist() { shouldFailWithMessageContaining('DoesNotExist.xml') { ruleSetBuilder.ruleset { ruleset('DoesNotExist.xml') } } } @Test void testRuleset_XmlFile_GroovyRuleSetFileDoesNotExist() { shouldFailWithMessageContaining('DoesNotExist.groovy') { ruleSetBuilder.ruleset { ruleset('DoesNotExist.groovy') } } } @Test void testRuleset_XmlFile_NoClosure() { ruleSetBuilder.ruleset { ruleset(RULESET_XML_FILE1) } assertRuleNames('TestPath') } @Test void testRuleset_XmlFile_Exclude() { ruleSetBuilder.ruleset { ruleset(RULESET_XML_FILE1) { exclude 'TestPath' } } assertRuleNames() } @Test void testRuleset_XmlFile_Include() { ruleSetBuilder.ruleset { ruleset(RULESET_XML_FILE2) { include 'CatchThrowable' include 'EmptyTryBlock' } } assertRuleNames('CatchThrowable', 'EmptyTryBlock') } @Test void testRuleset_XmlFile_ConfigureRuleUsingMap() { ruleSetBuilder.ruleset { ruleset(RULESET_XML_FILE2) { 'CatchThrowable' priority:1, enabled:false exclude 'Empty*' } } assertRuleNames('CatchThrowable') assertRuleProperties('CatchThrowable', [priority:1, enabled:false]) } @Test void testRuleset_XmlFile_ConfigureRuleUsingMap_RuleNotFound() { shouldFailWithMessageContaining('NotFound') { ruleSetBuilder.ruleset { ruleset(RULESET_XML_FILE2) { 'NotFound' priority:1, enabled:false } } } } @Test void testRuleset_XmlFile_ConfigureRuleUsingClosure() { ruleSetBuilder.ruleset { ruleset(RULESET_XML_FILE2) { 'CatchThrowable' { priority = 1 enabled = false } include 'CatchThrowable' } } assertRuleNames('CatchThrowable') assertRuleProperties('CatchThrowable', [priority:1, enabled:false]) } @Test void testRuleset_XmlFile_ConfigureRuleUsingClosure_RuleNotFound() { shouldFailWithMessageContaining('NotFound') { ruleSetBuilder.ruleset { ruleset(RULESET_XML_FILE2) { 'NotFound' { priority = 1 enabled = false } } } } } @Test void testRuleset_XmlFile_ConfigureRuleUsingClosure_RuleWasMovedToAnotherRuleSet() { shouldFailWithMessageContaining('design') { ruleSetBuilder.ruleset { ruleset(RULESET_XML_FILE2) { BooleanMethodReturnsNull(enabled:false) } } } } @Test void testRuleset_GroovyFile_NoClosure() { ruleSetBuilder.ruleset { ruleset(RULESET_GROOVY_FILE1) } assertRuleNames('CatchThrowable', 'ThrowExceptionFromFinallyBlock') } @Test void testRuleset_GroovyFile_ConfigureRuleUsingClosure() { ruleSetBuilder.ruleset { ruleset(RULESET_GROOVY_FILE1) { 'CatchThrowable' { priority = 1 enabled = false } include 'CatchThrowable' } } assertRuleNames('CatchThrowable') assertRuleProperties('CatchThrowable', [priority:1, enabled:false]) } @Test void testRule_Class_NoClosure() { ruleSetBuilder.ruleset { rule CatchThrowableRule } assertRuleNames('CatchThrowable') } @Test void testRule_Class_NoClosure_NullRuleClass() { shouldFailWithMessageContaining('ruleClass') { ruleSetBuilder.ruleset { rule((Class)null) } } } @Test void testRule_Class_NoClosure_ClassDoesNotImplementRuleInterface() { shouldFailWithMessageContaining('ruleClass') { ruleSetBuilder.ruleset { rule(this.class) } } } @Test void testRule_Class_Closure() { ruleSetBuilder.ruleset { rule(CatchThrowableRule) { priority = 1 enabled = false } } assertRuleNames('CatchThrowable') assertRuleProperties('CatchThrowable', [priority:1, enabled:false]) } @Test void testRule_Class_Map() { ruleSetBuilder.ruleset { rule(CatchThrowableRule, [priority:1, enabled:false]) } assertRuleNames('CatchThrowable') assertRuleProperties('CatchThrowable', [priority:1, enabled:false]) } @Test void testRule_Class_Closure_SetNonExistentProperty() { shouldFailWithMessageContaining('doesNotExist') { ruleSetBuilder.ruleset { rule(IllegalRegexRule) { doesNotExist = 1 } } } } @Test void testRule_Class_Closure_NullRuleClass() { shouldFailWithMessageContaining('ruleClass') { ruleSetBuilder.ruleset { rule((Class)null) { priority = 1 } } } } @Test void testRule_Class_Closure_ClassDoesNotImplementRuleInterface() { shouldFailWithMessageContaining('ruleClass') { ruleSetBuilder.ruleset { rule(this.class) { priority = 1 } } } } @Test void testRule_Script_NoClosure() { ruleSetBuilder.ruleset { rule RULE_SCRIPT_FILE } assertRuleNames('DoNothing') } @Test void testRule_Script_NoClosure_ClassDoesNotImplementRuleInterface() { shouldFailWithMessageContaining('ruleClass') { ruleSetBuilder.ruleset { rule('rule/NotARule.txt') } } } @Test void testRule_Script_Closure() { ruleSetBuilder.ruleset { def scriptPath = RULE_SCRIPT_FILE rule(scriptPath) { priority = 1 enabled = false } } assertRuleNames('DoNothing') assertRuleProperties('DoNothing', [priority:1, enabled:false]) } @Test void testRuleNameOnly_EmptyParentheses() { RuleRegistryHolder.ruleRegistry = [getRuleClass:{ ClassNameRule }] as RuleRegistry ruleSetBuilder.ruleset { ClassName() } assertRuleNames('ClassName') } @Test void testRuleNameOnly_ParenthesesWithMap() { RuleRegistryHolder.ruleRegistry = [getRuleClass:{ ClassNameRule }] as RuleRegistry ruleSetBuilder.ruleset { ClassName(priority:1) } assertRuleProperties('ClassName', [priority:1, enabled:true]) } @Test void testRuleNameOnly_NoParenthesesOrClosure() { RuleRegistryHolder.ruleRegistry = [getRuleClass:{ ClassNameRule }] as RuleRegistry ruleSetBuilder.ruleset { ClassName } assertRuleNames('ClassName') } @Test void testRuleNameOnly_NoSuchRuleName() { RuleRegistryHolder.ruleRegistry = null shouldFailWithMessageContaining('ClassName') { ruleSetBuilder.ruleset { ClassName() } } } @Test void testRuleNameOnly_NoParentheses_NoSuchRuleName() { RuleRegistryHolder.ruleRegistry = null shouldFailWithMessageContaining('ClassName') { ruleSetBuilder.ruleset { ClassName } } } @Test void testRuleNameOnly_RuleWasMovedToAnotherRuleSet() { RuleRegistryHolder.ruleRegistry = null shouldFailWithMessageContaining('design') { ruleSetBuilder.ruleset { BooleanMethodReturnsNull() } } } @Test void testRuleNameOnly_NoParentheses_Closure_RuleWasMovedToAnotherRuleSet() { RuleRegistryHolder.ruleRegistry = null shouldFailWithMessageContaining('design') { ruleSetBuilder.ruleset { BooleanMethodReturnsNull { } } } } @Test void testRuleNameOnly_NoParentheses_NoClosure_RuleWasMovedToAnotherRuleSet() { RuleRegistryHolder.ruleRegistry = null shouldFailWithMessageContaining('design') { def closure = { BooleanMethodReturnsNull } closure.resolveStrategy = Closure.DELEGATE_ONLY ruleSetBuilder.ruleset(closure) } } @Test void testRuleNameOnly_Closure() { RuleRegistryHolder.ruleRegistry = [getRuleClass:{ ClassNameRule }] as RuleRegistry ruleSetBuilder.ruleset { ClassName { priority = 1 enabled = false } def myVariable = 27 println "some arbitrary Groovy code: $myVariable" } assertRuleNames('ClassName') assertRuleProperties('ClassName', [priority:1, enabled:false]) } @SuppressWarnings('JUnitTestMethodWithoutAssert') @Test void testDescription() { // lack of exception indicated success ruleSetBuilder.ruleset { description 'abc' } } @Before void setUpRuleSetBuilderTest() { ruleSetBuilder = new RuleSetBuilder() } private RuleSet getRuleSet() { ruleSetBuilder.getRuleSet() } private void assertRuleNames(String[] names) { assert getRuleSet().rules*.name == names } private void assertRuleProperties(String ruleName, Map properties) { def rule = findRule(ruleName) properties.each { key, value -> assert rule[key] == value } } private findRule(String name) { getRuleSet().rules.find { rule -> rule.name == name } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/MovedRulesTest.groovy����������������������������0000644�0001750�0001750�00000005745�12041642704�025776� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.ruleset import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.assertContainsAllInOrder /** * Tests for MovedRules * * @author Chris Mair */ class MovedRulesTest extends AbstractTestCase { @Test void testGetMovedOrRenamedMessageForRuleName_RuleRenamed() { def message = MovedRules.getMovedOrRenamedMessageForRuleName('HardcodedWindowsRootDirectory') log(message) assertContainsAllInOrder(message, ['HardcodedWindowsRootDirectory', 'renamed to', 'HardCodedWindowsRootDirectory']) } @Test void testGetMovedOrRenamedMessageForRuleName_RuleMoved_Unnecessary() { def message = MovedRules.getMovedOrRenamedMessageForRuleName('AddEmptyString') log(message) assertContainsAllInOrder(message, ['AddEmptyString', 'moved to', 'unnecessary', 'ruleset']) } @Test void testGetMovedOrRenamedMessageForRuleName_RuleMoved_Groovyism() { def message = MovedRules.getMovedOrRenamedMessageForRuleName('AssignCollectionSort') log(message) assertContainsAllInOrder(message, ['AssignCollectionSort', 'moved to', 'groovyism', 'ruleset']) } @Test void testGetMovedOrRenamedMessageForRuleName_RuleMoved_Design() { def message = MovedRules.getMovedOrRenamedMessageForRuleName('BooleanMethodReturnsNull') log(message) assertContainsAllInOrder(message, ['BooleanMethodReturnsNull', 'moved to', 'design', 'ruleset']) } @Test void testGetMovedOrRenamedMessageForRuleName_RuleMoved_Convention() { def message = MovedRules.getMovedOrRenamedMessageForRuleName('ConfusingTernary') log(message) assertContainsAllInOrder(message, ['ConfusingTernary', 'moved to', 'convention', 'ruleset']) } @Test void testGetMovedOrRenamedMessageForRuleName_NoSuchRuleName_ReturnsEmptyString() { assert MovedRules.getMovedOrRenamedMessageForRuleName('xxx') == '' } @Test void testGetMovedOrRenamedMessageForRuleName_NullRuleName_ReturnsEmptyString() { assert MovedRules.getMovedOrRenamedMessageForRuleName(null) == '' } @Test void testGetMovedOrRenamedMessageForRuleName_EmptyRuleName_ReturnsEmptyString() { assert MovedRules.getMovedOrRenamedMessageForRuleName('') == '' } } ���������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/XmlReaderRuleSetTest.groovy����������������������0000644�0001750�0001750�00000030617�12323251321�027066� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.Rule import org.codenarc.rule.StubRule import org.codenarc.rule.FakePathRule import org.codenarc.rule.basic.EmptyIfStatementRule import org.codenarc.rule.exceptions.CatchThrowableRule import org.codenarc.rule.imports.DuplicateImportRule import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.* /** * Tests for XmlReaderRuleSet * * @author Chris Mair */ class XmlReaderRuleSetTest extends AbstractTestCase { private static final NAMESPACE = ''' xmlns="http://codenarc.org/ruleset/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd" xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd" ''' private List rules @Test void testNullReader() { shouldFailWithMessageContaining('reader') { new XmlReaderRuleSet(null) } } @Test void testEmptyReader() { def reader = new StringReader('') shouldFail { new XmlReaderRuleSet(reader) } } @Test void testNoRules() { final XML = "<ruleset $NAMESPACE></ruleset>" parseXmlRuleSet(XML) assert rules == [] } @Test void testOneRuleScript() { // Load ".txt" file so that it gets copied as resource in Idea final XML = """ <ruleset $NAMESPACE> <rule-script path='rule/DoNothingRule.txt'/> </ruleset>""" parseXmlRuleSet(XML) assertEqualSets(rules*.class.name, ['DoNothingRule']) } @Test void testOneRuleScriptWithProperties() { final XML = """ <ruleset $NAMESPACE> <rule-script path='rule/DoNothingRule.txt'> <property name='name' value='YYYY'/> <property name='priority' value=' 1 '/> </rule-script> </ruleset>""" parseXmlRuleSet(XML) assertEqualSets(rules*.class.name, ['DoNothingRule']) assert rules*.name == ['YYYY'] assert rules*.priority == [1] } @Test void testRuleScriptFileNotFound() { final XML = """ <ruleset $NAMESPACE> <rule-script path='rule/DoesNotExist.groovy'/> </ruleset>""" shouldFailWithMessageContaining('DoesNotExist.groovy') { parseXmlRuleSet(XML) } } @Test void testRuleScriptCompileError() { final XML = """ <ruleset $NAMESPACE> <rule-script path='rule/DoesNotCompileRule.txt'/> </ruleset>""" shouldFail { parseXmlRuleSet(XML) } } @Test void testRuleScriptNotARule() { final XML = """ <ruleset $NAMESPACE> <rule-script path='rule/NotARule.txt'/> </ruleset>""" shouldFailWithMessageContaining('NotARule') { parseXmlRuleSet(XML) } } @Test void testOneRule() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.StubRule'/> </ruleset>""" parseXmlRuleSet(XML) assertRuleClasses([StubRule]) } @Test void testTwoRules() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.StubRule'/> <rule class='org.codenarc.rule.exceptions.CatchThrowableRule'/> </ruleset>""" parseXmlRuleSet(XML) assertRuleClasses([StubRule, CatchThrowableRule]) } @Test void testTwoRulesWithProperties() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.StubRule'> <property name='name' value='XXXX'/> <property name='enabled' value=' false '/> </rule> <rule class='org.codenarc.rule.exceptions.CatchThrowableRule'> <property name='name' value='YYYY'/> <property name='priority' value=' 1 '/> </rule> </ruleset>""" parseXmlRuleSet(XML) assertRuleClasses([StubRule, CatchThrowableRule]) assert rules*.name == ['XXXX', 'YYYY'] assert rules*.priority == [0, 1] assert rules*.enabled == [false, true] } @Test void testGroovyRuleSet() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/GroovyRuleSet1.txt'/> </ruleset>""" parseXmlRuleSet(XML) assertRuleNames(['CatchThrowable', 'ThrowExceptionFromFinallyBlock']) } @Test void testNestedRuleSet() { final XML = """ <ruleset $NAMESPACE> <description>Sample rule set</description> <ruleset-ref path='rulesets/RuleSet1.xml'/> <rule class='org.codenarc.rule.exceptions.CatchThrowableRule'> <property name='priority' value='1'/> </rule> <rule-script path='rule/DoNothingRule.txt'/> </ruleset>""" parseXmlRuleSet(XML) assertRuleNames(['CatchThrowable', 'TestPath', 'DoNothing']) assert rules[0].priority == 1 } @Test void testDeeplyNestedRuleSet() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet3.xml'/> <ruleset-ref path='rulesets/NestedRuleSet1.xml'/> <rule class='org.codenarc.rule.imports.DuplicateImportRule'> <property name='priority' value='1'/> </rule> </ruleset>""" parseXmlRuleSet(XML) assertRuleClasses([StubRule, DuplicateImportRule, CatchThrowableRule, FakePathRule, EmptyIfStatementRule]) assert findRule('DuplicateImport').priority == 1 assert findRule('EmptyIfStatement').priority == 1 assert findRule('CatchThrowable').priority == 1 } @Test void testNestedRuleSet_Excludes() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/NestedRuleSet1.xml'> <exclude name='TestPath'/> <exclude name='EmptyIf*'/> </ruleset-ref> <rule class='org.codenarc.rule.imports.DuplicateImportRule'/> </ruleset>""" parseXmlRuleSet(XML) assertRuleClasses([DuplicateImportRule, CatchThrowableRule]) } @Test void testNestedRuleSet_IncludesAndExcludes() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet3.xml'> <exclude name='Stub'/> </ruleset-ref> <ruleset-ref path='rulesets/NestedRuleSet1.xml'> <include name='TestPath'/> <include name='EmptyIfStatement'/> </ruleset-ref> <ruleset-ref path='rulesets/GroovyRuleSet1.txt'> <include name='Cat*Throwable'/> </ruleset-ref> <rule class='org.codenarc.rule.imports.DuplicateImportRule'> <property name='priority' value='1'/> </rule> </ruleset>""" parseXmlRuleSet(XML) assertRuleClasses([DuplicateImportRule, FakePathRule, EmptyIfStatementRule, CatchThrowableRule]) } @Test void testNestedRuleSet_IncludesExcludesAndConfig() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/RuleSet3.xml'> <include name='Stub'/> </ruleset-ref> <ruleset-ref path='rulesets/NestedRuleSet1.xml'> <rule-config name='CatchThrowable'> <property name='priority' value='3'/> </rule-config> <exclude name='TestPath'/> </ruleset-ref> <rule class='org.codenarc.rule.imports.DuplicateImportRule'> <property name='priority' value='1'/> </rule> </ruleset>""" parseXmlRuleSet(XML) assertRuleClasses([StubRule, DuplicateImportRule, CatchThrowableRule, EmptyIfStatementRule]) assert findRule('CatchThrowable').priority == 3 } @Test void testRuleClassNotFound() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.DoesNotExist'/> </ruleset>""" shouldFail(ClassNotFoundException) { parseXmlRuleSet(XML) } } @Test void testRuleClassNotARule() { final XML = """ <ruleset $NAMESPACE> <rule class='java.lang.Object'/> </ruleset>""" shouldFailWithMessageContaining('java.lang.Object') { parseXmlRuleSet(XML) } } @Test void testNestedRuleSet_RuleSetFileNotFound() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/DoesNotExist.xml'/> </ruleset>""" shouldFailWithMessageContaining('DoesNotExist.xml') { parseXmlRuleSet(XML) } } @Test void testNestedRuleSet_ConfigRuleDoesNotExist() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/NestedRuleSet1.xml'> <rule-config name='DoesNotExist'> <property name='priority' value='3'/> </rule-config> </ruleset-ref> </ruleset>""" shouldFailWithMessageContaining('DoesNotExist') { parseXmlRuleSet(XML) } } @Test void testNestedRuleSet_ConfigRuleWasRenamed() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/NestedRuleSet1.xml'> <rule-config name='HardcodedWindowsRootDirectory'> <property name='priority' value='3'/> </rule-config> </ruleset-ref> </ruleset>""" shouldFailWithMessageContaining('HardCodedWindowsRootDirectory') { parseXmlRuleSet(XML) } } @Test void testNestedRuleSet_ConfigRulePropertyDoesNotExist() { final XML = """ <ruleset $NAMESPACE> <ruleset-ref path='rulesets/NestedRuleSet1.xml'> <rule-config name='CatchThrowable'> <property name='DoesNotExist' value='123456789'/> </rule-config> </ruleset-ref> </ruleset>""" shouldFailWithMessageContaining('DoesNotExist') { parseXmlRuleSet(XML) } } @Test void testRulesListIsImmutable() { final XML = """ <ruleset $NAMESPACE> <rule class='org.codenarc.rule.StubRule'/> </ruleset>""" parseXmlRuleSet(XML) shouldFail(UnsupportedOperationException) { rules.clear() } } //-------------------------------------------------------------------------- // Internal Helper Methods //-------------------------------------------------------------------------- private void parseXmlRuleSet(String xml) { def reader = new StringReader(xml) def ruleSet = new XmlReaderRuleSet(reader) rules = ruleSet.rules log("rules=$rules") } private void assertRuleClasses(List classes) { assertEqualSets(rules*.class, classes) } private void assertRuleNames(List ruleNames) { assertEqualSets(rules*.name, ruleNames) } private Rule findRule(String name) { rules.find { it.name == name } } } �����������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleset/RuleSetUtilTest.groovy���������������������������0000644�0001750�0001750�00000006260�12403164261�026122� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.ruleset import org.codenarc.rule.Rule import org.codenarc.rule.exceptions.CatchThrowableRule import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for RuleSetUtil * * @author Chris Mair */ class RuleSetUtilTest extends AbstractTestCase { private static final RULESET_XML_FILE = 'rulesets/RuleSet1.xml' private static final RULESET_GROOVY_FILE = 'rulesets/GroovyRuleSet1.txt' private static final RULE_SCRIPT_FILE = 'rule/DoNothingRule.txt' private static final RULE_SCRIPT_FILE_URL = 'file:src/test/resources/rule/DoNothingRule.txt' @Test void testAssertClassImplementsRuleInterface_RuleClass() { RuleSetUtil.assertClassImplementsRuleInterface(CatchThrowableRule) } @Test void testAssertClassImplementsRuleInterface_NotARuleClass() { shouldFailWithMessageContaining('Rule interface') { RuleSetUtil.assertClassImplementsRuleInterface(this.class) } } @Test void testAssertClassImplementsRuleInterface_Null() { shouldFailWithMessageContaining('ruleClass') { RuleSetUtil.assertClassImplementsRuleInterface(null) } } @Test void testLoadRuleSetFile() { assert RuleSetUtil.loadRuleSetFile(RULESET_GROOVY_FILE).class == GroovyDslRuleSet assert RuleSetUtil.loadRuleSetFile(RULESET_XML_FILE).class == XmlFileRuleSet } @Test void testLoadRuleScriptFile() { def rule = RuleSetUtil.loadRuleScriptFile(RULE_SCRIPT_FILE) assert rule instanceof Rule assert rule.name == 'DoNothing' } @Test void testLoadRuleScriptFile_FileUrl() { def rule = RuleSetUtil.loadRuleScriptFile(RULE_SCRIPT_FILE_URL) assert rule instanceof Rule assert rule.name == 'DoNothing' } @Test void testLoadRuleScriptFile_useCurrentThreadContextClassLoader() { System.setProperty(RuleSetUtil.CLASS_LOADER_SYS_PROP, 'true') def rule = RuleSetUtil.loadRuleScriptFile(RULE_SCRIPT_FILE) assert rule instanceof Rule assert rule.name == 'DoNothing' } @Test void testLoadRuleScriptFile_NotARule() { shouldFailWithMessageContaining('Rule') { RuleSetUtil.loadRuleScriptFile('rule/NotARule.txt') } } @Test void testLoadRuleScriptFile_FileNotFound() { shouldFailWithMessageContaining('DoesNotExist.txt') { RuleSetUtil.loadRuleScriptFile('DoesNotExist.txt') } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/����������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021061� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/AstUtilTest.groovy����������������������������������0000644�0001750�0001750�00000030530�12467260331�024562� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.util import org.apache.log4j.Logger import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.ClassCodeVisitorSupport import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.MethodNode import org.codehaus.groovy.ast.expr.DeclarationExpression import org.codehaus.groovy.ast.expr.GStringExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.stmt.BlockStatement import org.codehaus.groovy.ast.stmt.ExpressionStatement import org.codehaus.groovy.ast.stmt.IfStatement import org.codehaus.groovy.ast.stmt.Statement import org.codehaus.groovy.control.SourceUnit import org.codenarc.source.SourceString import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test /** * Tests for AstUtil * * @author Chris Mair */ class AstUtilTest extends AbstractTestCase { private static final SOURCE = ''' class MyClass { def otherMethod() { object.print() if (true) { } ant.delete(dir:appBase, failonerror:false) "stringMethodName"(123) gstringMethodName = 'anotherMethod' "$gstringMethodName"(234) int myVariable = 99 multilineMethodCall(1, 2, 3) } @Before setUp() { } @First @Second def twoAnnotationsMethod() { } } enum MyEnum { READ, WRITE def doStuff() { println methodCallWithinEnum(true, 'abc', 123); doStuff() } } // outside of class -- script def scriptMethod() { 456 } ''' private visitor private sourceCode @Test void testIsFromGeneratedSourceCode() { def scriptClassNode = visitor.classNodes.find { classNode -> classNode.name == 'None' } assert AstUtil.isFromGeneratedSourceCode(scriptClassNode) assert !AstUtil.isFromGeneratedSourceCode(methodNamed('print')) } @Test void testGetNodeTest() { assert AstUtil.getNodeText(methodNamed('methodCallWithinEnum'), sourceCode) == "methodCallWithinEnum(true, 'abc', 123)" assert AstUtil.getNodeText(methodNamed('multilineMethodCall'), sourceCode) == 'multilineMethodCall(1,' } @Test void testGetMethodArguments_ConstructorWithinEnum() { def methodCall = methodNamed('methodCallWithinEnum') def args = AstUtil.getMethodArguments(methodCall) assert args.size() == 3 } @Test void testGetMethodArguments_NoArgument() { def methodCall = methodNamed('print') def args = AstUtil.getMethodArguments(methodCall) assert args.size() == 0 } @Test void testGetMethodArguments_SingleArgument() { def methodCall = methodNamed('stringMethodName') def args = AstUtil.getMethodArguments(methodCall) assert args.size() == 1 assert args[0].value == 123 } @Test void testGetMethodArguments_NamedArguments() { def methodCall = methodNamed('delete') def args = AstUtil.getMethodArguments(methodCall) assert args.size() == 1 assert args[0].mapEntryExpressions[1].keyExpression.value == 'failonerror' assert !args[0].mapEntryExpressions[1].valueExpression.value } @Test void testIsMethodCall_ExactMatch() { def statement = expressionStatementForMethodNamed('print') assert AstUtil.isMethodCall(statement, 'object', 'print', 0) assert AstUtil.isMethodCall(statement.expression, 'object', 'print', 0) assert AstUtil.isMethodCall(statement.expression, 'object', 'print') } @Test void testIsMethodCall_WrongMethodName() { def statement = expressionStatementForMethodNamed('print') assert !AstUtil.isMethodCall(statement, 'object', 'print2', 0) assert !AstUtil.isMethodCall(statement.expression, 'object', 'print2', 0) assert !AstUtil.isMethodCall(statement.expression, 'object', 'print2') } @Test void testIsMethodCall_WrongMethodObjectName() { def statement = expressionStatementForMethodNamed('print') assert !AstUtil.isMethodCall(statement, 'object2', 'print', 0) assert !AstUtil.isMethodCall(statement.expression, 'object2', 'print', 0) assert !AstUtil.isMethodCall(statement.expression, 'object2', 'print') } @Test void testIsMethodCall_WrongNumberOfArguments() { def statement = expressionStatementForMethodNamed('print') assert !AstUtil.isMethodCall(statement, 'object', 'print', 1) assert !AstUtil.isMethodCall(statement.expression, 'object', 'print', 1) assert AstUtil.isMethodCall(statement.expression, 'object', 'print') } @Test void testIsMethodCall_NamedArgumentList() { def methodCall = visitor.methodCallExpressions.find { mc -> mc.method.value == 'delete' } assert AstUtil.isMethodCall(methodCall, 'ant', 'delete', 1) assert !AstUtil.isMethodCall(methodCall, 'ant', 'delete', 2) assert AstUtil.isMethodCall(methodCall, 'ant', 'delete') } @Test void testIsMethodCall_StringLiteralMethodName() { def methodCall = methodNamed('stringMethodName') assert AstUtil.isMethodCall(methodCall, 'this', 'stringMethodName', 1) assert !AstUtil.isMethodCall(methodCall, 'this', 'stringMethodName', 2) assert AstUtil.isMethodCall(methodCall, 'this', 'stringMethodName') } @Test void testIsMethodCall_GStringMethodName() { def methodCall = visitor.methodCallExpressions.find { mc -> log(mc.method); mc.method instanceof GStringExpression } assert !AstUtil.isMethodCall(methodCall, 'this', 'anotherMethod', 1) assert !AstUtil.isMethodCall(methodCall, 'this', 'anotherMethod', 2) assert !AstUtil.isMethodCall(methodCall, 'this', 'anotherMethod') } @Test void testIsMethodCall_NotAMethodCall() { def statement = visitor.statements.find { st -> st instanceof BlockStatement } assert !AstUtil.isMethodCall(statement, 'object', 'print', 0) } @Test void testIsMethodNamed() { def methodCall = methodNamed('print') assert AstUtil.isMethodNamed(methodCall, 'print') assert !AstUtil.isMethodNamed(methodCall, 'other') } @Test void testIsMethodNamed_GStringMethodName() { def methodCall = visitor.methodCallExpressions.find { mc -> mc.method instanceof GStringExpression } assert !AstUtil.isMethodNamed(methodCall, 'print') } @Test void testIsBlock_Block() { applyVisitor(SOURCE) def statement = visitor.statements.find { st -> st instanceof BlockStatement } assert AstUtil.isBlock(statement) } @Test void testIsBlock_NotABlock() { def statement = visitor.statements.find { st -> st instanceof ExpressionStatement } assert !AstUtil.isBlock(statement) } @Test void testIsEmptyBlock_NonEmptyBlock() { def statement = expressionStatementForMethodNamed('setUp') assert !AstUtil.isEmptyBlock(statement) } @Test void testIsEmptyBlock_EmptyBlock() { def statement = visitor.statements.find { st -> st instanceof IfStatement } assert AstUtil.isEmptyBlock(statement.ifBlock) } @Test void testIsEmptyBlock_NotABlock() { def statement = visitor.statements.find { st -> st instanceof ExpressionStatement } assert !AstUtil.isEmptyBlock(statement) } @Test void testGetAnnotation() { assert AstUtil.getAnnotation(visitor.methodNodes['otherMethod'], 'doesNotExist') == null assert AstUtil.getAnnotation(visitor.methodNodes['setUp'], 'doesNotExist') == null assert AstUtil.getAnnotation(visitor.methodNodes['setUp'], 'Before') instanceof AnnotationNode } @Test void testHasAnnotation() { assert !AstUtil.hasAnnotation(visitor.methodNodes['setUp'], 'doesNotExist') assert AstUtil.hasAnnotation(visitor.methodNodes['setUp'], 'Before') } @Test void testHasAnyAnnotation() { assert !AstUtil.hasAnyAnnotation(visitor.methodNodes['twoAnnotationsMethod'], 'doesNotExist') assert AstUtil.hasAnyAnnotation(visitor.methodNodes['twoAnnotationsMethod'], 'First') assert AstUtil.hasAnyAnnotation(visitor.methodNodes['twoAnnotationsMethod'], 'doesNotExist', 'First') assert AstUtil.hasAnyAnnotation(visitor.methodNodes['twoAnnotationsMethod'], 'doesNotExist', 'First', 'Second') } @Test void testGetVariableExpressions_SingleDeclaration() { log("declarationExpressions=${visitor.declarationExpressions}") def variableExpressions = AstUtil.getVariableExpressions(visitor.declarationExpressions[0]) log("variableExpressions=$variableExpressions") assert variableExpressions.size() == 1 assert variableExpressions.name == ['myVariable'] } @Test void testGetVariableExpressions_MultipleDeclarations() { final NEW_SOURCE = ''' class MyClass { def otherMethod() { String name1, name2 = 'abc' } } ''' applyVisitor(NEW_SOURCE) def names = [] visitor.declarationExpressions.collect { declarationExpression -> names += AstUtil.getVariableExpressions(declarationExpression).name } assert names.contains('name1') && names.contains('name2') } @Before void setUpAstUtilTest() { visitor = new AstUtilTestVisitor() applyVisitor(SOURCE) } private void applyVisitor(String source) { sourceCode = new SourceString(source) def ast = sourceCode.ast ast.classes.each { classNode -> visitor.visitClass(classNode) } } private ExpressionStatement expressionStatementForMethodNamed(String methodName) { return visitor.statements.find { st -> st instanceof ExpressionStatement && st.expression instanceof MethodCallExpression && st.expression.methodAsString == methodName } } private MethodCallExpression methodNamed(String name) { def methodCall = visitor.methodCallExpressions.find { mc -> if (mc.method instanceof GStringExpression) { return mc.text.startsWith(name) } mc.method.value == name } methodCall } } class AstUtilTestVisitor extends ClassCodeVisitorSupport { static final LOG = Logger.getLogger(AstUtilTestVisitor) def methodNodes = [:] def methodCallExpressions = [] def statements = [] def declarationExpressions = [] def classNodes = [] @Override void visitClass(ClassNode node) { classNodes << node super.visitClass(node) } void visitMethod(MethodNode methodNode) { methodNodes[methodNode.name] = methodNode super.visitMethod(methodNode) } void visitStatement(Statement statement) { this.statements << statement super.visitStatement(statement) } void visitMethodCallExpression(MethodCallExpression methodCallExpression) { this.methodCallExpressions << methodCallExpression super.visitMethodCallExpression(methodCallExpression) } void visitDeclarationExpression(DeclarationExpression declarationExpression) { declarationExpressions << declarationExpression super.visitDeclarationExpression(declarationExpression) } protected SourceUnit getSourceUnit() { source } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/ImportUtilTest.groovy�������������������������������0000644�0001750�0001750�00000011402�12311373552�025300� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.util import org.codenarc.source.SourceString import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for ImportUtil * * @author Chris Mair */ class ImportUtilTest extends AbstractTestCase { @Test void testSourceLineAndNumberForImport() { final SOURCE = ''' import a.b.MyClass import a.b.MyClass as Boo // some comment import a.pkg1.MyOtherClass as MOC import a.b.MyOtherClass; import a.b.MyOtherClass as Moo; ''' def sourceCode = new SourceString(SOURCE) def ast = sourceCode.ast assertImport(sourceCode, ast, [sourceLine:'import a.b.MyClass', lineNumber:2]) assertImport(sourceCode, ast, [sourceLine:'import a.b.MyClass as Boo', lineNumber:3]) assertImport(sourceCode, ast, [sourceLine:'import a.pkg1.MyOtherClass as MOC', lineNumber:5]) assertImport(sourceCode, ast, [sourceLine:'import a.b.MyOtherClass;', lineNumber:6]) assertImport(sourceCode, ast, [sourceLine:'import a.b.MyOtherClass as Moo;', lineNumber:7]) // Not found in source code; AST still contains import nodes def otherSourceCode = new SourceString('def v = 1') assertImport(otherSourceCode, ast, [sourceLine:'import a.b.MyClass as MyClass', lineNumber:2]) } @Test void testSourceLineAndNumberForImport_ClassNameAndAlias() { final SOURCE = ''' import a.b.MyClass import a.b.MyClass as Boo // some comment import a.pkg1.MyOtherClass as MOC ''' def sourceCode = new SourceString(SOURCE) assert ImportUtil.sourceLineAndNumberForImport(sourceCode, 'a.b.MyClass', 'MyClass') == [sourceLine:'import a.b.MyClass', lineNumber:2] assert ImportUtil.sourceLineAndNumberForImport(sourceCode, 'a.b.MyClass', 'Boo') == [sourceLine:'import a.b.MyClass as Boo', lineNumber:3] assert ImportUtil.sourceLineAndNumberForImport(sourceCode, 'a.pkg1.MyOtherClass', 'MOC') == [sourceLine:'import a.pkg1.MyOtherClass as MOC', lineNumber:5] // Not found in source code; AST still contains import nodes def otherSourceCode = new SourceString('def v = 1') assert ImportUtil.sourceLineAndNumberForImport(otherSourceCode, 'a.b.MyClass', 'MyClass') == [sourceLine:'import a.b.MyClass as MyClass', lineNumber:null] } @Test void testSourceLineAndNumberForImport_StaticImport() { final SOURCE = ''' import static java.io.DataInputStream.* import static java.lang.Integer.MAX_VALUE ''' def sourceCode = new SourceString(SOURCE) def ast = sourceCode.ast assertStaticImport(sourceCode, ast, [sourceLine:'import static java.io.DataInputStream.*', lineNumber:2]) assertStaticImport(sourceCode, ast, [sourceLine:'import static java.lang.Integer.MAX_VALUE', lineNumber:3]) } @Test void testSourceLineAndNumberForImport_SimilarlyNamedImports() { final SOURCE = ''' import static com.example.FaultMessages.* import com.example.FaultCode.* import com.example.Fault ''' def sourceCode = new SourceString(SOURCE) assert ImportUtil.sourceLineAndNumberForImport(sourceCode, 'com.example.Fault', 'Fault') == [sourceLine:'import com.example.Fault', lineNumber:4] } private void assertImport(sourceCode, ast, Map expectedImportInfo) { assert ast.imports.find { imp -> def importInfo = ImportUtil.sourceLineAndNumberForImport(sourceCode, imp) if (importInfo.lineNumber == expectedImportInfo.lineNumber) { log(importInfo) } importInfo == expectedImportInfo }, expectedImportInfo.toString() } private void assertStaticImport(sourceCode, ast, Map importInfo) { def allStaticImports = ast.staticImports + ast.staticStarImports assert allStaticImports.find { name, imp -> ImportUtil.sourceLineAndNumberForImport(sourceCode, imp) == importInfo } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/PathUtilTest.groovy���������������������������������0000644�0001750�0001750�00000004627�12050572320�024727� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.util import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for PathUtil * * @author Chris Mair */ class PathUtilTest extends AbstractTestCase { @Test void testGetName() { assert PathUtil.getName(null) == null assert PathUtil.getName('') == null assert PathUtil.getName('abc') == 'abc' assert PathUtil.getName('/abc') == 'abc' assert PathUtil.getName('/dir/abc') == 'abc' assert PathUtil.getName('\\abc') == 'abc' } @Test void testGetParentPath() { assert PathUtil.getParentPath(null) == null assert PathUtil.getParentPath('') == null assert PathUtil.getParentPath('abc') == null assert PathUtil.getParentPath('a/') == null assert PathUtil.getParentPath('abc\\def\\') == 'abc' assert PathUtil.getParentPath('a/b') == 'a' assert PathUtil.getParentPath('abc/def/ghi') == 'abc/def' assert PathUtil.getParentPath('a\\b\\c\\d\\e\\f') == 'a/b/c/d/e' } @Test void testRemovePathPrefix() { assert PathUtil.removePathPrefix(null, 'abc/def') == 'abc/def' assert PathUtil.removePathPrefix('xxx', 'abc/def') == 'abc/def' assert PathUtil.removePathPrefix('abc', 'abcdef') == 'def' assert PathUtil.removePathPrefix('abc', 'abc/def') == 'def' assert PathUtil.removePathPrefix('abc/', 'abc/def') == 'def' } @Test void testNormalizePath() { assert PathUtil.normalizePath(null) == null assert PathUtil.normalizePath('') == '' assert PathUtil.normalizePath('abc') == 'abc' assert PathUtil.normalizePath('abc/def') == 'abc/def' assert PathUtil.normalizePath('abc\\def\\ghi') == 'abc/def/ghi' } } ���������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/PropertyUtilTest.groovy�����������������������������0000644�0001750�0001750�00000007247�12403442715�025666� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.util import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail /** * Tests for PropertyUtil * * @author Chris Mair */ class PropertyUtilTest extends AbstractTestCase { private object @Test void testSetPropertyFromString_String() { PropertyUtil.setPropertyFromString(object, 'stringField', 'AbcdefGHI') assert object.getStringField() == 'AbcdefGHI' } @Test void testSetPropertyFromString_int() { PropertyUtil.setPropertyFromString(object, 'intField', '23456') assert object.getIntField() == 23456 } @Test void testSetPropertyFromString_int_Whitespace() { PropertyUtil.setPropertyFromString(object, 'intField', ' 23456 ') assert object.getIntField() == 23456 } @Test void testSetPropertyFromString_long() { PropertyUtil.setPropertyFromString(object, 'longField', '9999999999') assert object.getLongField() == 9999999999 } @Test void testSetPropertyFromString_long_Whitespace() { PropertyUtil.setPropertyFromString(object, 'longField', '\t9999999999 ') assert object.getLongField() == 9999999999 } @Test void testSetPropertyFromString_BigDecimal() { PropertyUtil.setPropertyFromString(object, 'bigDecimalField', '1234.567') assert object.getBigDecimalField() == 1234.567 } @Test void testSetPropertyFromString_BigDecimal_Whitespace() { PropertyUtil.setPropertyFromString(object, 'bigDecimalField', '\t30 ') assert object.getBigDecimalField() == 30 } @Test void testSetPropertyFromString_boolean() { PropertyUtil.setPropertyFromString(object, 'booleanField', 'true') assert object.getBooleanField() PropertyUtil.setPropertyFromString(object, 'booleanField', 'false') assert !object.getBooleanField() } @Test void testSetPropertyFromString_boolean_Whitespace() { PropertyUtil.setPropertyFromString(object, 'booleanField', ' true ') assert object.getBooleanField() PropertyUtil.setPropertyFromString(object, 'booleanField', ' false\t') assert !object.getBooleanField() } @Test void testSetPropertyFromString_intFromSuperclass() { PropertyUtil.setPropertyFromString(object, 'superclassIntField', '23456') assert object.getSuperclassIntField() == 23456 } @Test void testSetPropertyFromString_NoSuchField() { shouldFail(NoSuchFieldException) { PropertyUtil.setPropertyFromString(object, 'XXX', '23456') } } @Before void setUpPropertyUtilTest() { object = new FakePropertyUtilClass() } } class FakePropertyUtilClass extends FakePropertyUtilSuperclass { String stringField int intField long longField boolean booleanField BigDecimal bigDecimalField } class FakePropertyUtilSuperclass { int superclassIntField } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/WildcardPatternTest.groovy��������������������������0000644�0001750�0001750�00000011426�12041642704�026263� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.util import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for WildcardPattern * * @author Chris Mair */ class WildcardPatternTest extends AbstractTestCase { @Test void testMatches_DefaultMatches_True() { assert new WildcardPattern(null, true).matches('') assert new WildcardPattern(null, true).matches('abc') assert new WildcardPattern('', true).matches('') assert new WildcardPattern('', true).matches('abc') assert new WildcardPattern('a', true).matches('a') assert !new WildcardPattern('a', true).matches('b') } @Test void testMatches_DefaultMatches_False() { assert new WildcardPattern('a', false).matches('a') assert !new WildcardPattern('a', false).matches('b') assert !new WildcardPattern(null, false).matches('') assert !new WildcardPattern(null, false).matches('abc') assert !new WildcardPattern('', false).matches('') assert !new WildcardPattern('', false).matches('abc') } @Test void testMatches() { assert new WildcardPattern('').matches('') assert new WildcardPattern('').matches('abc') assert new WildcardPattern('a').matches('a') assert new WildcardPattern('a@b.c').matches('a@b.c') assert new WildcardPattern('!@#$%^&.()-_+=~`{}[]:;+<>').matches('!@#$%^&.()-_+=~`{}[]:;+<>') assert new WildcardPattern('abc+def').matches('abc+def') assert new WildcardPattern('a*def').matches('abcdef') assert new WildcardPattern('a?c+de?').matches('abc+def') assert new WildcardPattern('*?cd*').matches('abcdef') assert new WildcardPattern('a/*/c*.groovy').matches('a/b/c.groovy') assert new WildcardPattern('a/*/c*.groovy').matches('a/b/cdef.groovy') assert new WildcardPattern('**/c*.groovy').matches('a/b/cdef.groovy') assert new WildcardPattern('a**/c*.groovy').matches('a/b/cdef.groovy') assert !new WildcardPattern('a').matches('b') assert !new WildcardPattern('a??cdef').matches('abcdef') assert !new WildcardPattern('a?cdef').matches('a/cdef') assert !new WildcardPattern('a*fg').matches('abcdef') assert !new WildcardPattern('a*c*.groovy').matches('a/b/c.groovy') assert !new WildcardPattern('a/*/c*.groovy').matches('a/b1/b2/cdef.groovy') assert !new WildcardPattern('**/c*.groovy').matches('a/b/c/def.groovy') } @Test void testMatches_TrimsPatternStrings() { assert new WildcardPattern(' abc ').matches('abc') assert new WildcardPattern('\ta ?c ').matches('a bc') } @Test void testMatches_CommaSeparatedListOfPatterns() { assert new WildcardPattern('a,b').matches('a') assert new WildcardPattern('x,a@b.c').matches('a@b.c') assert new WildcardPattern('a*de+f,xx').matches('abcde+f') assert new WildcardPattern('xx,a?cde?').matches('abcdef') assert new WildcardPattern('xx,yy,*?cd*').matches('abcdef') assert new WildcardPattern('a/*/c*.groovy,xx,yy').matches('a/b/c.groovy') assert new WildcardPattern('xx,**/c*.groovy').matches('a/b/cdef.groovy') assert new WildcardPattern('a**/c*.groovy,xx').matches('a/b/cdef.groovy') assert !new WildcardPattern('a,c').matches('b') assert !new WildcardPattern('x,a??cdef').matches('abcdef') assert !new WildcardPattern('a?cdef,xx,yy').matches('a/cdef') assert !new WildcardPattern('a*fg,xx').matches('abc+def') assert !new WildcardPattern('xx,yy,a*c*.groovy').matches('a/b/c.groovy') assert !new WildcardPattern('xx,a/*/c*.groovy').matches('a/b1/b2/cdef.groovy') assert !new WildcardPattern('**/c*.groovy,xx').matches('a/b/c/def.groovy') } @Test void testMatches_CommaSeparatedListOfPatterns_TrimsPatternStrings() { assert new WildcardPattern(' a , b ').matches('a') assert new WildcardPattern(' a , b\t, c ').matches('b') assert new WildcardPattern(' a , b\t, c?d ').matches('cdd') assert new WildcardPattern(' a , b*g, c?d ').matches('bcdefg') } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/SourceCodeUtilTest.groovy���������������������������0000644�0001750�0001750�00000010237�12323244661�026067� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.util import org.codehaus.groovy.ast.ClassCodeVisitorSupport import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.control.SourceUnit import org.codenarc.source.SourceCode import org.codenarc.source.SourceString import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail /** * @author Marcin Erdmann */ class SourceCodeUtilTest extends AbstractTestCase { private static final String SOURCE = ''' [1, 2, 3].each { println it } [1, 2, 3].any { it > 3 } ''' private SourceCode sourceCode private SourceCodeUtilTestVisitor visitor @Before void setUpSourceCodeUtilTest() { sourceCode = new SourceString(SOURCE) } private applyVisitor() { visitor = new SourceCodeUtilTestVisitor() visitor.visitClass(sourceCode.ast.scriptClassDummy) } @Test void testSourceLinesBetweenForSingleLine() { assert SourceCodeUtil.sourceLinesBetween(sourceCode, 2, 19, 2, 23) == ['each'] assert SourceCodeUtil.sourceLinesBetween(sourceCode, 2, 9, 2, 18) == ['[1, 2, 3]'] } @Test void testSourceLinesBetweenForMultiLine() { def lines = SourceCodeUtil.sourceLinesBetween(sourceCode, 3, 23, 5, 10) assert lines.size() == 3 assert lines[0] == '{' assert lines[1] == ' it > 3' assert lines[2] == ' }' } @Test void testIfExceptionIsThrownWhenParamsAreWrong() { assert shouldFail(IllegalArgumentException) { SourceCodeUtil.sourceLinesBetween(sourceCode, 0, 1, 1, 1) } == 'Start and end indexes are one based and have to be greater than zero' assert shouldFail(IllegalArgumentException) { SourceCodeUtil.sourceLinesBetween(sourceCode, 1, 4, 1, 2) } == 'End line/column has to be after start line/column' assert shouldFail(IllegalArgumentException) { SourceCodeUtil.sourceLinesBetween(sourceCode, 3, 1, 2, 5) } == 'End line/column has to be after start line/column' } @Test void testNodeSourceLines() { applyVisitor() def lines = SourceCodeUtil.nodeSourceLines(sourceCode, visitor.methodCalls['each']) assert lines == ['[1, 2, 3].each { println it }'] lines = SourceCodeUtil.nodeSourceLines(sourceCode, visitor.methodCalls['any']) assert lines.size() == 3 assert lines[0] == '[1, 2, 3].any {' assert lines[1] == ' it > 3' assert lines[2] == ' }' } @Test void testSourceLinesBetweenNodes() { applyVisitor() def lines = SourceCodeUtil.sourceLinesBetweenNodes(sourceCode, visitor.methodCalls['each'].method, visitor.methodCalls['any']) assert lines.size() == 2 assert lines[0] == ' { println it }' assert lines[1] == ' ' lines = SourceCodeUtil.sourceLinesBetweenNodes(sourceCode, visitor.methodCalls['each'], visitor.methodCalls['any']) assert lines.size() == 2 assert lines[0] == '' assert lines[1] == ' ' } } class SourceCodeUtilTestVisitor extends ClassCodeVisitorSupport { final SourceUnit sourceUnit = null def methodCalls = [:] @Override void visitMethodCallExpression(MethodCallExpression call) { super.visitMethodCallExpression(call) methodCalls[call.methodAsString] = call } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/io/�������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021470� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/io/UrlResourceTest.groovy���������������������������0000644�0001750�0001750�00000006665�12464275572�026104� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.util.io import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for UrlResource * * @author Chris Mair */ class UrlResourceTest extends AbstractTestCase { private static final TEXT_FILE = 'src/test/resources/resource/SampleResource.txt' private static final RELATIVE_FILE_URL = 'file:' + TEXT_FILE private static final URL_DOEST_NOT_EXIST = 'file:bad/DoesNotExist.txt' private static final TEXT_FILE_CONTENTS = 'abcdef12345' @Test void testConstructor_NullOrEmpty() { shouldFailWithMessageContaining('path') { new UrlResource(null) } shouldFailWithMessageContaining('path') { new UrlResource('') } } @Test void testGetPath() { def resource = new UrlResource(TEXT_FILE) assert resource.getPath() == TEXT_FILE } @Test void testGetInputStream_File_AbsolutePath() { def file = new File(TEXT_FILE) def urlName = 'file:' + file.absolutePath log("urlName=$urlName") def resource = new UrlResource(urlName) def inputStream = resource.getInputStream() assert inputStream.text == TEXT_FILE_CONTENTS } @Test void testGetInputStream_File_RelativePath() { def resource = new UrlResource(RELATIVE_FILE_URL) def inputStream = resource.getInputStream() assert inputStream.text == TEXT_FILE_CONTENTS } // Can't assume always-on internet access // void testGetInputStream_Http() { // def resource = new UrlResource('http://google.com') // def inputStream = resource.getInputStream() // assert inputStream.text.contains('Google') // } @Test void testGetInputStream_MalformedUrlName() { def resource = new UrlResource('DoesNotExist.txt') shouldFail(MalformedURLException) { resource.getInputStream() } } @Test void testGetInputStream_ResourceDoesNotExist() { def resource = new UrlResource('file:///DoesNotExist.txt') shouldFail(IOException) { resource.getInputStream() } } @Test void testGetInputStream_TwiceOnTheSameResource() { def resource = new UrlResource(RELATIVE_FILE_URL) def inputStream = resource.getInputStream() assert inputStream.text == TEXT_FILE_CONTENTS assert resource.getInputStream().text == TEXT_FILE_CONTENTS } @Test void testExists_DoesExist() { def resource = new UrlResource(RELATIVE_FILE_URL) assert resource.exists() } @Test void testExists_DoesNotExist() { def resource = new UrlResource(URL_DOEST_NOT_EXIST) assert !resource.exists() } } ���������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/io/DefaultResourceFactoryTest.groovy����������������0000644�0001750�0001750�00000004351�12041642704�030226� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.util.io import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for DefaultResourceFactory * * @author Chris Mair */ class DefaultResourceFactoryTest extends AbstractTestCase { private static final PATH = 'src/test/resources/resource/SampleResource.txt' private resourceFactory @Test void testConstructor_NullOrEmpty() { shouldFailWithMessageContaining('path') { resourceFactory.getResource(null) } shouldFailWithMessageContaining('path') { resourceFactory.getResource('') } } @Test void testGetResource_NoPrefix() { assertResourceTypeAndLocation(PATH, ClassPathResource) } @Test void testGetResource_HttpPrefix() { assertResourceTypeAndLocation('http://codenarc.org', UrlResource) } @Test void testGetResource_FtpPrefix() { assertResourceTypeAndLocation('ftp://codenarc.org', UrlResource) } @Test void testGetResource_ClassPathPrefix() { assertResourceTypeAndLocation('classpath:' + PATH, ClassPathResource, PATH) } private void assertResourceTypeAndLocation(String path, Class resourceClass, String expectedResourcePath=path) { def resource = resourceFactory.getResource(path) assert resource.class == resourceClass assert resource.getPath() == expectedResourcePath } @Before void setUpDefaultResourceFactoryTest() { resourceFactory = new DefaultResourceFactory() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/io/ClassPathResourceTest.groovy���������������������0000644�0001750�0001750�00000006140�12041642704�027172� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.util.io import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for ClassPathResource * * @author Chris Mair */ class ClassPathResourceTest extends AbstractTestCase { private static final TEXT_FILE = 'resource/SampleResource.txt' private static final FILE_DOES_NOT_EXIST = 'bad/DoesNotExist.txt' private static final TEXT_FILE_CONTENTS = 'abcdef12345' @Test void testConstructor_NullOrEmpty() { shouldFailWithMessageContaining('path') { new ClassPathResource(null) } shouldFailWithMessageContaining('path') { new ClassPathResource('') } } @Test void testGetPath() { def resource = new ClassPathResource(TEXT_FILE) assert resource.getPath() == TEXT_FILE } @Test void testGetInputStream() { def resource = new ClassPathResource(TEXT_FILE) def inputStream = resource.getInputStream() assert inputStream.text == TEXT_FILE_CONTENTS } @Test void testGetInputStream_FileDoesNotExist() { def resource = new ClassPathResource('DoesNotExist.txt') shouldFail(IOException) { resource.getInputStream() } } @Test void testGetInputStream_TwiceOnTheSameResource() { def resource = new ClassPathResource(TEXT_FILE) def inputStream = resource.getInputStream() assert inputStream.text == TEXT_FILE_CONTENTS assert resource.getInputStream().text == TEXT_FILE_CONTENTS } @Test void testGetInputStream_Static() { assert ClassPathResource.getInputStream(TEXT_FILE).text == TEXT_FILE_CONTENTS } @Test void testGetInputStream_Static_FileDoesNotExist() { shouldFail(IOException) { ClassPathResource.getInputStream('DoesNotExist.txt') } } @Test void testGetInputStream_Static_NullOrEmpty() { shouldFailWithMessageContaining('path') { ClassPathResource.getInputStream(null) } shouldFailWithMessageContaining('path') { ClassPathResource.getInputStream('') } } @Test void testExists_DoesExist() { def resource = new ClassPathResource(TEXT_FILE) assert resource.exists() } @Test void testExists_DoesNotExist() { def resource = new ClassPathResource(FILE_DOES_NOT_EXIST) assert !resource.exists() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/util/ModifiersUtilTest.groovy����������������������������0000644�0001750�0001750�00000015633�12463442131�025757� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.util import org.codehaus.groovy.ast.MethodNode import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for ModifiersUtil * * @author Chris Mair */ class ModifiersUtilTest extends AbstractTestCase { private static final ACC_PUBLIC = MethodNode.ACC_PUBLIC private static final ACC_PROTECTED = MethodNode.ACC_PROTECTED private static final ACC_PRIVATE = MethodNode.ACC_PRIVATE private static final ACC_STATIC = MethodNode.ACC_STATIC private static final ACC_FINAL = MethodNode.ACC_FINAL private static final ACC_VOLATILE = MethodNode.ACC_VOLATILE private static final ACC_TRANSIENT = MethodNode.ACC_TRANSIENT // Tests for matchesAnyModifiers @Test void testMatchesAnyModifiers() { assert ModifiersUtil.matchesAnyModifiers(null, []) assert ModifiersUtil.matchesAnyModifiers(null, [ACC_PUBLIC]) // exact assert ModifiersUtil.matchesAnyModifiers(ACC_PUBLIC, [ACC_PUBLIC]) assert ModifiersUtil.matchesAnyModifiers(ACC_PUBLIC, [ACC_PUBLIC, ACC_PRIVATE]) assert ModifiersUtil.matchesAnyModifiers(ACC_PRIVATE, [ACC_PUBLIC, ACC_PRIVATE]) assert ModifiersUtil.matchesAnyModifiers(ACC_PUBLIC | ACC_FINAL, [ACC_PUBLIC | ACC_STATIC , ACC_PUBLIC | ACC_FINAL, ACC_STATIC]) // partial assert ModifiersUtil.matchesAnyModifiers(ACC_PUBLIC | ACC_FINAL, [ACC_PUBLIC, ACC_STATIC]) assert ModifiersUtil.matchesAnyModifiers(ACC_PUBLIC | ACC_FINAL, [ACC_PROTECTED, ACC_FINAL]) assert !ModifiersUtil.matchesAnyModifiers(0, []) assert ModifiersUtil.matchesAnyModifiers(0, [ACC_PUBLIC]) assert !ModifiersUtil.matchesAnyModifiers(ACC_PUBLIC, [ACC_PRIVATE]) assert !ModifiersUtil.matchesAnyModifiers(ACC_PUBLIC | ACC_FINAL, [ACC_PUBLIC | ACC_STATIC, ACC_FINAL | ACC_PROTECTED]) assert !ModifiersUtil.matchesAnyModifiers(ACC_PUBLIC | ACC_FINAL, [ACC_PUBLIC | ACC_FINAL | ACC_STATIC]) } // Tests for matchesModifiers @Test void testMatchesModifiers() { assert ModifiersUtil.matchesModifiers(null, null) assert ModifiersUtil.matchesModifiers(0, null) assert ModifiersUtil.matchesModifiers(null, 0) assert ModifiersUtil.matchesModifiers(0, 0) assert ModifiersUtil.matchesModifiers(ACC_PUBLIC, 0) assert ModifiersUtil.matchesModifiers(ACC_PUBLIC, null) assert ModifiersUtil.matchesModifiers(ACC_PUBLIC, ACC_PUBLIC) assert ModifiersUtil.matchesModifiers(ACC_PUBLIC | ACC_FINAL, ACC_PUBLIC) assert ModifiersUtil.matchesModifiers(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, ACC_PRIVATE) assert ModifiersUtil.matchesModifiers(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, ACC_PRIVATE | ACC_STATIC) assert ModifiersUtil.matchesModifiers(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, ACC_PRIVATE | ACC_STATIC | ACC_FINAL) assert !ModifiersUtil.matchesModifiers(ACC_PUBLIC, ACC_PRIVATE) assert !ModifiersUtil.matchesModifiers(ACC_PUBLIC | ACC_FINAL, ACC_PROTECTED) assert !ModifiersUtil.matchesModifiers(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, ACC_PROTECTED) assert !ModifiersUtil.matchesModifiers(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, ACC_PRIVATE | ACC_VOLATILE) } // Tests for parseModifiersList(String) @Test void testParseModifiersList() { assert ModifiersUtil.parseModifiersList(null) == [] assert ModifiersUtil.parseModifiersList('') == [] assert ModifiersUtil.parseModifiersList('public') == [ACC_PUBLIC] assert ModifiersUtil.parseModifiersList('protected, private final') == [ACC_PROTECTED, ACC_PRIVATE | ACC_FINAL] assert ModifiersUtil.parseModifiersList('private static, protected, final') == [ACC_PRIVATE | ACC_STATIC, ACC_PROTECTED, ACC_FINAL] assert ModifiersUtil.parseModifiersList('protected static') == [ACC_PROTECTED | ACC_STATIC] assert ModifiersUtil.parseModifiersList('private static final, volatile public') == [ACC_PRIVATE | ACC_STATIC | ACC_FINAL, ACC_PUBLIC | ACC_VOLATILE] } @Test void testParseModifiersList_IgnoresExtraWhitespace() { assert ModifiersUtil.parseModifiersList('\tprotected ') == [ACC_PROTECTED] assert ModifiersUtil.parseModifiersList(' private, static \t final') == [ACC_PRIVATE, ACC_STATIC | ACC_FINAL] } @Test void testParseModifiersList_IllegalModifier() { shouldFailWithMessageContaining('xxx') { ModifiersUtil.parseModifiersList('xxx') } shouldFailWithMessageContaining('xxx') { ModifiersUtil.parseModifiersList('protected xxx') } shouldFailWithMessageContaining('xxx') { ModifiersUtil.parseModifiersList('protected, private xxx') } } // Tests for parseModifiers(String) @Test void testParseModifiers() { assert ModifiersUtil.parseModifiers(null) == 0 assert ModifiersUtil.parseModifiers('') == 0 assert ModifiersUtil.parseModifiers('public') == ACC_PUBLIC assert ModifiersUtil.parseModifiers('protected') == ACC_PROTECTED assert ModifiersUtil.parseModifiers('private') == ACC_PRIVATE assert ModifiersUtil.parseModifiers('static') == ACC_STATIC assert ModifiersUtil.parseModifiers('final') == ACC_FINAL assert ModifiersUtil.parseModifiers('volatile') == ACC_VOLATILE assert ModifiersUtil.parseModifiers('transient') == ACC_TRANSIENT assert ModifiersUtil.parseModifiers('protected static') == (ACC_PROTECTED | ACC_STATIC) assert ModifiersUtil.parseModifiers('private static final') == (ACC_PRIVATE | ACC_STATIC | ACC_FINAL) assert ModifiersUtil.parseModifiers('volatile public') == (ACC_PUBLIC | ACC_VOLATILE) } @Test void testParseModifiers_IgnoresExtraWhitespace() { assert ModifiersUtil.parseModifiers('\tprotected ') == ACC_PROTECTED assert ModifiersUtil.parseModifiers(' private static \t final') == (ACC_PRIVATE | ACC_STATIC | ACC_FINAL) } @Test void testParseModifiers_IllegalModifier() { shouldFailWithMessageContaining('xxx') { ModifiersUtil.parseModifiers('xxx') } shouldFailWithMessageContaining('xxx') { ModifiersUtil.parseModifiers('protected xxx') } } } �����������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/CodeNarcRunnerTest.groovy��������������������������������0000644�0001750�0001750�00000011600�12376110455�025065� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc import org.codenarc.analyzer.SourceAnalyzer import org.codenarc.report.HtmlReportWriter import org.codenarc.report.ReportWriter import org.codenarc.results.FileResults import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining import org.codenarc.rule.FakePathRule /** * Tests for CodeNarcRunner * * @author Chris Mair */ class CodeNarcRunnerTest extends AbstractTestCase { private static final XML_RULESET1 = 'rulesets/RuleSet1.xml' private static final GROOVY_RULESET1 = 'rulesets/GroovyRuleSet1.txt' private static final RULESET_FILES = 'rulesets/RuleSet1.xml,rulesets/GroovyRuleSet2.txt' private static final RULESET_FILES_WITH_SPACES = 'rulesets/RuleSet1.xml , rulesets/GroovyRuleSet2.txt, rulesets/RuleSet3.xml ' private static final REPORT_FILE = 'CodeNarcTest-Report.html' private static final RESULTS = new FileResults('path', []) private static final SOURCE_DIRS = ['abc'] private codeNarcRunner @Test void testExecute_NoRuleSetFiles() { shouldFailWithMessageContaining('ruleSetFiles') { codeNarcRunner.execute() } } @Test void testExecute_NoSourceAnalyzer() { codeNarcRunner.ruleSetFiles = XML_RULESET1 codeNarcRunner.reportWriters << new HtmlReportWriter(outputFile:REPORT_FILE) shouldFailWithMessageContaining('sourceAnalyzer') { codeNarcRunner.execute() } } @Test void testExecute() { def ruleSet def sourceAnalyzer = [analyze: { rs -> ruleSet = rs; RESULTS }, getSourceDirectories: { SOURCE_DIRS }] as SourceAnalyzer codeNarcRunner.sourceAnalyzer = sourceAnalyzer def analysisContext, results def reportWriter = [writeReport: { ac, res -> analysisContext = ac; results = res }] as ReportWriter codeNarcRunner.reportWriters << reportWriter codeNarcRunner.ruleSetFiles = XML_RULESET1 assert codeNarcRunner.execute() == RESULTS assert ruleSet.rules*.class == [FakePathRule] assert analysisContext.ruleSet == ruleSet assert analysisContext.sourceDirectories == SOURCE_DIRS assert results == RESULTS } @Test void testExecute_NoReportWriters() { def sourceAnalyzer = [analyze: { RESULTS }, getSourceDirectories: { SOURCE_DIRS }] as SourceAnalyzer codeNarcRunner.sourceAnalyzer = sourceAnalyzer codeNarcRunner.ruleSetFiles = XML_RULESET1 assert codeNarcRunner.execute() == RESULTS } @Test void testCreateRuleSet_OneXmlRuleSet() { codeNarcRunner.ruleSetFiles = XML_RULESET1 def ruleSet = codeNarcRunner.createRuleSet() assert ruleSet.rules*.name == ['TestPath'] } @Test void testCreateRuleSet_OneGroovyRuleSet() { codeNarcRunner.ruleSetFiles = GROOVY_RULESET1 def ruleSet = codeNarcRunner.createRuleSet() assert ruleSet.rules*.name == ['CatchThrowable', 'ThrowExceptionFromFinallyBlock'] } @Test void testCreateRuleSet_MultipleRuleSets() { codeNarcRunner.ruleSetFiles = RULESET_FILES def ruleSet = codeNarcRunner.createRuleSet() assert ruleSet.rules*.name == ['TestPath', 'CatchThrowable', 'ThrowExceptionFromFinallyBlock', 'StatelessClass'] } @Test void testCreateRuleSet_MultipleRuleSets_WithSpaces() { codeNarcRunner.ruleSetFiles = RULESET_FILES_WITH_SPACES def ruleSet = codeNarcRunner.createRuleSet() assert ruleSet.rules*.name == ['TestPath', 'CatchThrowable', 'ThrowExceptionFromFinallyBlock', 'StatelessClass', 'Stub'] } @Test void testCreateRuleSet_RuleSetFileDoesNotExist() { codeNarcRunner.ruleSetFiles = 'rulesets/NoSuchRuleSet.txt' shouldFail(FileNotFoundException) { codeNarcRunner.createRuleSet() } } //-------------------------------------------------------------------------- // Test setUp/tearDown and helper methods //-------------------------------------------------------------------------- @Before void setUpCodeNarcRunnerTest() { codeNarcRunner = new CodeNarcRunner() } } ��������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleregistry/��������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022644� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleregistry/PropertiesFileRuleRegistryTest.groovy�������0000644�0001750�0001750�00000003006�12041642704�032267� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.ruleregistry import org.codenarc.rule.naming.ClassNameRule import org.codenarc.rule.naming.MethodNameRule import org.codenarc.rule.unused.UnusedPrivateFieldRule import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for PropertiesFileRuleRegistry * * @author Chris Mair */ class PropertiesFileRuleRegistryTest extends AbstractTestCase { private registry = new PropertiesFileRuleRegistry() @Test void testGetRuleClass_LoadsRulesFromPropertiesFile() { assert registry.getRuleClass('ClassName') == ClassNameRule assert registry.getRuleClass('MethodName') == MethodNameRule assert registry.getRuleClass('UnusedPrivateField') == UnusedPrivateFieldRule } @Test void testGetRuleClass_ReturnsNullForNoMatchingRule() { assert registry.getRuleClass('NoSuchRule') == null } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/ruleregistry/RuleRegistryInitializerTest.groovy����������0000644�0001750�0001750�00000002272�12041642704�031622� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.ruleregistry import org.codenarc.rule.naming.ClassNameRule import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for RuleRegistryInitializer * * @author Chris Mair */ class RuleRegistryInitializerTest extends AbstractTestCase { @Test void testInitializeRuleRegistry() { def ruleRegistryInitializer = new RuleRegistryInitializer() ruleRegistryInitializer.initializeRuleRegistry() assert RuleRegistryHolder.ruleRegistry.getRuleClass('ClassName') == ClassNameRule } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/test/����������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021063� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/test/RunCodeNarcAgainstProjectSourceCodeTest.groovy������0000644�0001750�0001750�00000003602�12405331673�032154� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.test import org.junit.After import org.junit.Test /** * Test that runs CodeNarc against the project source code * * @author Chris Mair * @author Hamlet D'Arcy */ class RunCodeNarcAgainstProjectSourceCodeTest extends AbstractTestCase { private static final GROOVY_FILES = '**/*.groovy' private static final RULESET_FILES = 'RunCodeNarcAgainstProjectSourceCode.ruleset' @SuppressWarnings('JUnitTestMethodWithoutAssert') @Test void testRunCodeNarc() { System.setProperty(CODENARC_PROPERTIES_FILE_PROP, 'RunCodeNarcAgainstProjectSourceCode.properties') def ant = new AntBuilder() ant.taskdef(name:'codenarc', classname:'org.codenarc.ant.CodeNarcTask') ant.codenarc(ruleSetFiles:RULESET_FILES, maxPriority1Violations:0, maxPriority2Violations:0, maxPriority3Violations:0) { fileset(dir:'src/main/groovy') { include(name:GROOVY_FILES) } fileset(dir:'src/test/groovy') { include(name:GROOVY_FILES) } report(type:'ide') } } @After void tearDownRunCodeNarcAgainstProjectSourceCodeTest() { System.setProperty(CODENARC_PROPERTIES_FILE_PROP, '') } } ������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/test/SiteDocumentationTest.groovy������������������������0000644�0001750�0001750�00000003715�12140054270�026631� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.test import org.junit.Test /** * Tests that the "site" documentation is up to date. * * @author Hamlet D'Arcy */ class SiteDocumentationTest extends AbstractTestCase { @Test void testDocumentation() { new File('src/main/resources/rulesets').eachFileMatch(~/.*\.xml/) { File ruleset -> def ruleSetName = ruleset.name[0..-5] def docFile = "src/site/apt/codenarc-rules-${ruleSetName}.apt" def documentation = new File(docFile).text def violations = new XmlSlurper().parse(ruleset).rule.collect { it.@class.text() }.collect { String className -> def ruleInstance = this.class.getClassLoader().loadClass(className).newInstance() ruleInstance.name }.collect { ruleName -> documentation.contains(ruleName) ? null : ruleName }.removeAll { } { it == null } if (violations) { fail(""" It's really great that you wrote a new rule for the $ruleSetName ruleset. The universe AND the CodeNarc team thanks you. But you still have a little documentation to write. Open this file: $docFile And document the following rules: $violations """) } } } } ���������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/analyzer/������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021731� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/analyzer/AbstractSourceAnalyzerTest.groovy���������������0000644�0001750�0001750�00000003406�12253152112�030467� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.analyzer import org.codehaus.groovy.control.Phases import org.codenarc.rule.MockRule import org.codenarc.rule.Rule import org.codenarc.ruleset.ListRuleSet import org.codenarc.source.SourceCode import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for AbstractSourceAnalyzer */ class AbstractSourceAnalyzerTest extends AbstractTestCase { private AbstractSourceAnalyzer analyzer = new StringSourceAnalyzer('class MyClass {}') @Test void testProvidesRulesWithSourceCodeOfRequiredAstCompilationPhase() { def results = analyzer.analyze(new ListRuleSet([ astCompilerPhaseAssertingRule(Phases.CONVERSION), astCompilerPhaseAssertingRule(Phases.SEMANTIC_ANALYSIS), astCompilerPhaseAssertingRule(Phases.CANONICALIZATION) ])) assert results.violations.isEmpty() } private Rule astCompilerPhaseAssertingRule(int compilerPhase) { return new MockRule( compilerPhase: compilerPhase, applyTo: { SourceCode source -> assert source.astCompilerPhase == compilerPhase [] } ) } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/analyzer/SourceStringAnalyzerTest.groovy�����������������0000644�0001750�0001750�00000002436�12311451726�030204� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.analyzer import org.codenarc.results.Results import org.codenarc.rule.naming.ClassNameRule import org.codenarc.ruleset.ListRuleSet import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Test for SourceStringAnalyzer. * @author Hamlet D'Arcy */ class SourceStringAnalyzerTest extends AbstractTestCase { @Test void testRunAgainstString() { def source = ''' class badName { } ''' def ruleSet = new ListRuleSet([new ClassNameRule()]) Results results = new StringSourceAnalyzer(source).analyze(ruleSet) log(results.violations) assert results.violations*.rule.name == ['ClassName'] } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/analyzer/StringSourceAnalyzerTest.groovy�����������������0000644�0001750�0001750�00000005216�12224267574�030214� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.analyzer import org.codenarc.rule.MockRule import org.codenarc.rule.Violation import org.codenarc.rule.design.PublicInstanceFieldRule import org.codenarc.rule.unnecessary.UnnecessaryDefInFieldDeclarationRule import org.codenarc.ruleset.ListRuleSet import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for StringSourceAnalyzer */ class StringSourceAnalyzerTest extends AbstractTestCase { @Test void testSuppressWarningsOnPackage() { final SOURCE = ''' @SuppressWarnings('rule1') package foo class Person { } ''' def analyzer = new StringSourceAnalyzer(SOURCE) def results = analyzer.analyze(new ListRuleSet( [ new MockRule(name: 'rule1', applyTo: { fail('Rule should be suppressed') }), new MockRule(name: 'rule2', applyTo: { [new Violation()] }) ] )) assert results.violations.size() == 1 } @Test void testTwoRules() { final SOURCE = ''' class Person { } ''' def analyzer = new StringSourceAnalyzer(SOURCE) def results = analyzer.analyze(new ListRuleSet( [ new MockRule(name: 'rule1', applyTo: { [new Violation()] }), new MockRule(name: 'rule2', applyTo: { [new Violation()] }) ] )) assert results.violations.size() == 2 } @Test void testFieldRules() { final SOURCE = ''' class Person { def String name // should cause violation public String address // should cause violation } ''' def analyzer = new StringSourceAnalyzer(SOURCE) def results = analyzer.analyze(new ListRuleSet( [ new UnnecessaryDefInFieldDeclarationRule(), new PublicInstanceFieldRule(), ] )) assert results.violations.size() == 2 } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/analyzer/SuppressionAnalyzerTest.groovy������������������0000644�0001750�0001750�00000026660�12224267630�030116� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.analyzer import org.codenarc.rule.MockRule import org.codenarc.rule.Violation import org.codenarc.source.SourceString import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for SuppressionAnalyzer */ class SuppressionAnalyzerTest extends AbstractTestCase { @Test void testNone() { def analyzer = new SuppressionAnalyzer(new SourceString(''' println 4 ''')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule1')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule2')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule3')) } @Test void testPackage() { def analyzer = new SuppressionAnalyzer(new SourceString(''' @SuppressWarnings('Rule1') @SuppressWarnings(['Rule2', 'Rule3']) package foo println 4 ''')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule1')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule2')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule3')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule4')) } @Test void testImport() { def analyzer = new SuppressionAnalyzer(new SourceString(''' @SuppressWarnings('Rule1') @SuppressWarnings(['Rule2', 'Rule3']) import java.lang.Integer @SuppressWarnings('Rule4') import java.lang.Float @SuppressWarnings(['Rule5', 'Rule6']) import java.lang.String println 4 ''')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule1')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule2')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule3')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule4')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule5')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule6')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule7')) } @Test void testStarImport() { def analyzer = new SuppressionAnalyzer(new SourceString(''' @SuppressWarnings('Rule1') @SuppressWarnings(['Rule2', 'Rule3']) import java.lang.* @SuppressWarnings('Rule4') import java.io.* @SuppressWarnings(['Rule5', 'Rule6']) import java.util.* println 4 ''')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule1')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule2')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule3')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule4')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule5')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule6')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule7')) } @Test void testStaticStarImport() { def analyzer = new SuppressionAnalyzer(new SourceString(''' @SuppressWarnings('Rule1') @SuppressWarnings(['Rule2', 'Rule3']) import static java.lang.* @SuppressWarnings('Rule4') import static java.io.* @SuppressWarnings(['Rule5', 'Rule6']) import static java.util.* println 4 ''')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule1')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule2')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule3')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule4')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule5')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule6')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule7')) } @Test void testSingleClass() { def analyzer = new SuppressionAnalyzer(new SourceString(''' @SuppressWarnings('Rule1') @SuppressWarnings(['Rule2', 'Rule3']) class MyClass { } ''')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule1')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule2')) assert analyzer.isRuleSuppressed(new MockRule(name: 'Rule3')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule4')) } @Test void testTwoClassesClass() { def analyzer = new SuppressionAnalyzer(new SourceString(''' @SuppressWarnings('Rule1') @SuppressWarnings(['Rule2', 'Rule3']) class MyClass { } class MyClass2 { } ''')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule1')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule2')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule3')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule4')) assert !analyzer.isViolationSuppressed(violationFor('Rule1', -1)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 0)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 1)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 2)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 3)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 4)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 5)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 6)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 7)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 8)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 9)) } @Test void testFields() { def analyzer = new SuppressionAnalyzer(new SourceString(''' class MyClass { @SuppressWarnings('Rule1') private String myField = """ ... multiline content """ } ''')) assert !analyzer.isViolationSuppressed(violationFor('Rule1', -1)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 0)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 1)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 2)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 3)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 4)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 5)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 6)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 7)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 8)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 9)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 10)) } @Test void testProperties() { def analyzer = new SuppressionAnalyzer(new SourceString(''' class MyClass { @SuppressWarnings('Rule1') def myProperty = """ ... multiline content """ } ''')) assert !analyzer.isViolationSuppressed(violationFor('Rule1', -1)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 0)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 1)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 2)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 3)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 4)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 5)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 6)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 7)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 8)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 9)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 10)) } @Test void testMethods() { def analyzer = new SuppressionAnalyzer(new SourceString(''' class MyClass { @SuppressWarnings('Rule1') private String myMethod() { """ ... multiline content """ } @SuppressWarnings('Rule1') private String myMethod2() { """ ... multiline content """ } } ''')) assert !analyzer.isViolationSuppressed(violationFor('Rule1', -1)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 0)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 1)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 2)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 3)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 4)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 5)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 6)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 7)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 8)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 9)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 10)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 11)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 12)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 13)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 14)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 15)) assert analyzer.isViolationSuppressed(violationFor('Rule1', 16)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 17)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 18)) assert !analyzer.isViolationSuppressed(violationFor('Rule1', 19)) } @Test void testCompilationFails() { def analyzer = new SuppressionAnalyzer(new SourceString(''' class XYZ ^&**( ''')) assert !analyzer.isRuleSuppressed(new MockRule(name: 'Rule1')) } private static Violation violationFor(String ruleName, int lineNumber) { new Violation(rule: new MockRule(name: ruleName), lineNumber: lineNumber) } } ��������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/analyzer/DirectorySourceAnalyzerTest.groovy��������������0000644�0001750�0001750�00000022752�12323245122�030677� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.analyzer import org.codenarc.results.DirectoryResults import org.codenarc.results.FileResults import org.codenarc.results.Results import org.codenarc.ruleset.ListRuleSet import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.assertEqualSets import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining import org.codenarc.rule.FakePathRule import org.codenarc.rule.FakeCountRule /** * Tests for DirectorySourceAnalyzer. * * @author Chris Mair */ class DirectorySourceAnalyzerTest extends AbstractTestCase { private static final BASE_DIR = '/usr' private analyzer private ruleSet private testCountRule @Test void testAnalyze_NullRuleSet() { analyzer.baseDirectory = BASE_DIR shouldFailWithMessageContaining('ruleSet') { analyzer.analyze(null) } } @Test void testAnalyze_BaseDirectoryNullAndSourceDirectoriesNull() { shouldFailWithMessageContaining(['baseDirectory', 'sourceDirectories']) { analyzer.analyze(ruleSet) } } @Test void testAnalyze_BaseDirectoryEmptyAndSourceDirectoriesEmpty() { analyzer.baseDirectory = '' analyzer.sourceDirectories = [] shouldFailWithMessageContaining(['baseDirectory', 'sourceDirectories']) { analyzer.analyze(ruleSet) } } @Test void testAnalyze_BaseDirectory_FilesOnly() { final DIR = 'src/test/resources/source' analyzer.baseDirectory = DIR def ruleSet = new ListRuleSet([new FakePathRule()]) def results = analyzer.analyze(ruleSet) log("results=$results") def paths = resultsPaths(results) log("paths=$paths") assertEqualSets(paths, ['SourceFile1.groovy', 'SourceFile2.groovy']) def fullPaths = results.violations*.message assertEqualSets(fullPaths, [ 'src/test/resources/source/SourceFile1.groovy', 'src/test/resources/source/SourceFile2.groovy' ]) assert results.getNumberOfFilesWithViolations(3) == 2 assert results.totalNumberOfFiles == 2 } @Test void testAnalyze_BaseDirectory() { final DIR = 'src/test/resources/sourcewithdirs' analyzer.baseDirectory = DIR def results = analyzer.analyze(ruleSet) log("results=$results") def fullPaths = results.violations*.message assertEqualSets(fullPaths, [ 'src/test/resources/sourcewithdirs/SourceFile1.groovy', 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', 'src/test/resources/sourcewithdirs/subdir1/Subdir1File2.groovy', 'src/test/resources/sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy', 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy' ]) assert testCountRule.count == 5 assert results.getNumberOfFilesWithViolations(3) == 5 assert results.totalNumberOfFiles == 5 // Verify that the directory structure is properly reflected within the results assert childResultsClasses(results) == [DirectoryResults] def top = results.children[0] assertEqualSets(childResultsClasses(top), [FileResults, DirectoryResults, DirectoryResults]) // Different ordering on different operating systems // assert childResultsClasses(top.children[1]) == [FileResults, FileResults] // assert childResultsClasses(top.children[2]) == [DirectoryResults, FileResults] // assert childResultsClasses(top.children[2].children[0]) == [FileResults] } @Test void testAnalyze_SourceDirectories() { final DIR1 = 'src/test/resources/source' final DIR2 = 'src/test/resources/sourcewithdirs' analyzer.sourceDirectories = [DIR1, DIR2] def results = analyzer.analyze(ruleSet) log("results=$results") def fullPaths = results.violations*.message log("fullPaths=$fullPaths") assertEqualSets(fullPaths, [ 'src/test/resources/source/SourceFile1.groovy', 'src/test/resources/source/SourceFile2.groovy', 'src/test/resources/sourcewithdirs/SourceFile1.groovy', 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', 'src/test/resources/sourcewithdirs/subdir1/Subdir1File2.groovy', 'src/test/resources/sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy', 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy' ]) assert testCountRule.count == 7 assert results.totalNumberOfFiles == 7 assert results.getNumberOfFilesWithViolations(3) == 7 } @Test void testAnalyze_BaseDirectoryAndSourceDirectories() { final SOURCE_DIRS = ['source', 'sourcewithdirs'] analyzer.baseDirectory = 'src/test/resources' analyzer.sourceDirectories = SOURCE_DIRS def results = analyzer.analyze(ruleSet) def paths = resultsPaths(results) log("paths=$paths") assertEqualSets(paths, [ 'source', 'source/SourceFile1.groovy', 'source/SourceFile2.groovy', 'sourcewithdirs', 'sourcewithdirs/SourceFile1.groovy', 'sourcewithdirs/subdir1', 'sourcewithdirs/subdir1/Subdir1File1.groovy', 'sourcewithdirs/subdir1/Subdir1File2.groovy', 'sourcewithdirs/subdir2', 'sourcewithdirs/subdir2/subdir2a', 'sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy', 'sourcewithdirs/subdir2/Subdir2File1.groovy' ]) assert testCountRule.count == 7 assertEqualSets(childResultsClasses(results), [DirectoryResults, DirectoryResults, DirectoryResults]) assert results.totalNumberOfFiles == 7 assert results.getNumberOfFilesWithViolations(3) == 7 } @Test void testAnalyze_BaseDirectory_NoViolations() { final DIR = 'src/test/resources/sourcewithdirs' analyzer.baseDirectory = DIR ruleSet = new ListRuleSet([testCountRule]) def results = analyzer.analyze(ruleSet) log("results=$results") def paths = resultsPaths(results) log("paths=$paths") assertEqualSets(paths, ['subdir1', 'subdir2', 'subdir2/subdir2a']) assert testCountRule.count == 5 assert results.getNumberOfFilesWithViolations(3) == 0 assert results.totalNumberOfFiles == 5 } @Test void testAnalyze_BaseDirectory_ApplyToFilesMatching() { final DIR = 'src/test/resources/sourcewithdirs' analyzer.baseDirectory = DIR analyzer.applyToFilesMatching = /.*ubdir.*\.groovy/ analyzer.doNotApplyToFilesMatching = /.*File2.*/ def results = analyzer.analyze(ruleSet) log("results=$results") def fullPaths = results.violations*.message assertEqualSets(fullPaths, [ 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', 'src/test/resources/sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy', 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy' ]) assert testCountRule.count == 3 assert results.getNumberOfFilesWithViolations(3) == 3 assert results.totalNumberOfFiles == 3 } @Test void testAnalyze_BaseDirectory_ApplyToFileNames() { final DIR = 'src/test/resources/sourcewithdirs' analyzer.baseDirectory = DIR analyzer.applyToFileNames = 'Subdir1File1.groovy,Subdir2a*1.groovy,Sub?ir2File1.groovy' analyzer.doNotApplyToFileNames = 'Subdir2aFile1.groovy' def results = analyzer.analyze(ruleSet) log("results=$results") def fullPaths = results.violations*.message assertEqualSets(fullPaths, [ 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy' ]) assert testCountRule.count == 2 assert results.getNumberOfFilesWithViolations(3) == 2 assert results.totalNumberOfFiles == 2 } @Before void setUpDirectorySourceAnalyzerTest() { analyzer = new DirectorySourceAnalyzer() testCountRule = new FakeCountRule() ruleSet = new ListRuleSet([new FakePathRule(), testCountRule]) } private List resultsPaths(Results results, List paths=[]) { if (results.path) { paths << results.path } results.children.each { child -> resultsPaths(child, paths) } paths } private List childResultsClasses(Results results) { results.children*.getClass() } } ����������������������CodeNarc-0.23/src/test/groovy/org/codenarc/analyzer/FilesystemSourceAnalyzerTest.groovy�������������0000644�0001750�0001750�00000017007�12145306710�031057� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.analyzer import org.codenarc.results.DirectoryResults import org.codenarc.results.FileResults import org.codenarc.results.Results import org.codenarc.rule.FakeCountRule import org.codenarc.ruleset.ListRuleSet import org.codenarc.source.SourceString import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.assertEqualSets import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining import org.codenarc.rule.FakePathRule /** * Tests for FilesystemSourceAnalyzer. * * @author Chris Mair */ class FilesystemSourceAnalyzerTest extends AbstractTestCase { private static final BASE_DIR = 'src/test/resources/sourcewithdirs' private analyzer private ruleSet private testCountRule @Test void testAnalyze_NullRuleSet() { analyzer.baseDirectory = BASE_DIR shouldFailWithMessageContaining('ruleSet') { analyzer.analyze(null) } } @Test void testAnalyze_BaseDirectoryNull() { shouldFailWithMessageContaining('baseDirectory') { analyzer.analyze(ruleSet) } } @Test void testAnalyze_BaseDirectoryEmpty() { analyzer.baseDirectory = '' shouldFailWithMessageContaining('baseDirectory') { analyzer.analyze(ruleSet) } } @Test void testAnalyze_FilesOnly() { final DIR = 'src/test/resources/source' analyzer.baseDirectory = DIR ruleSet = new ListRuleSet([new FakePathRule()]) // override def results = analyzer.analyze(ruleSet) log("results=$results") def paths = resultsPaths(results) log("paths=$paths") assertEqualSets(paths, ['SourceFile1.groovy', 'SourceFile2.groovy']) def fullPaths = results.violations*.message assertEqualSets(fullPaths, [ 'src/test/resources/source/SourceFile1.groovy', 'src/test/resources/source/SourceFile2.groovy' ]) assert results.getNumberOfFilesWithViolations(3) == 2 assert results.totalNumberOfFiles == 2 } @Test void testAnalyze() { analyzer.baseDirectory = BASE_DIR def results = analyzer.analyze(ruleSet) log("results=$results") def fullPaths = results.violations*.message assertEqualSets(fullPaths, [ 'src/test/resources/sourcewithdirs/SourceFile1.groovy', 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', 'src/test/resources/sourcewithdirs/subdir1/Subdir1File2.groovy', 'src/test/resources/sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy', 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy' ]) assert testCountRule.count == 5 assert results.getNumberOfFilesWithViolations(3) == 5 assert results.totalNumberOfFiles == 5 // Verify that the directory structure is properly reflected within the results assert childResultsClasses(results) == [DirectoryResults] def top = results.children[0] assertEqualSets(childResultsClasses(top), [FileResults, DirectoryResults, DirectoryResults]) } @Test void testAnalyze_NoViolations() { analyzer.baseDirectory = BASE_DIR ruleSet = new ListRuleSet([testCountRule]) def results = analyzer.analyze(ruleSet) log("results=$results") def paths = resultsPaths(results) assertEqualSets(paths, ['subdir1', 'subdir2', 'subdir2/subdir2a']) assert testCountRule.count == 5 assert results.getNumberOfFilesWithViolations(3) == 0 assert results.totalNumberOfFiles == 5 } @Test void testAnalyze_IncludesAndExcludes() { analyzer.baseDirectory = BASE_DIR analyzer.includes = '**ubdir*.groovy' analyzer.excludes = '**/*File2*' def results = analyzer.analyze(ruleSet) log("results=$results") def fullPaths = results.violations*.message assertEqualSets(fullPaths, [ 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', 'src/test/resources/sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy', 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy' ]) assert testCountRule.count == 3 assert results.getNumberOfFilesWithViolations(3) == 3 assert results.totalNumberOfFiles == 3 } @Test void testAnalyze_IncludesAndExcludes_Lists() { analyzer.baseDirectory = BASE_DIR analyzer.includes = '**/Subdir1File1.groovy,**/Subdir2a*1.groovy,**/Sub?ir2File1.groovy' analyzer.excludes = '**/Subdir2aFile1.groovy,**/DoesNotExist.*' def results = analyzer.analyze(ruleSet) log("results=$results") def fullPaths = results.violations*.message assert fullPaths.containsAll([ 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy' ]) assert fullPaths.size() == 2 assert testCountRule.count == 2 assert results.getNumberOfFilesWithViolations(3) == 2 assert results.totalNumberOfFiles == 2 } @Test void testGetSourceDirectories_ReturnsListWithBaseDirectory() { analyzer.baseDirectory = BASE_DIR assert analyzer.sourceDirectories == [BASE_DIR] } @Test void testMatches() { def source = new SourceString('def x', 'dir/file.txt') assertMatches(source, null, null, true) assertMatches(source, '', null, true) assertMatches(source, '**/file.txt', null, true) assertMatches(source, '**/file.txt', 'other', true) assertMatches(source, null, 'other', true) assertMatches(source, '**/file.txt', '**/file.txt', false) assertMatches(source, null, '**/file.txt', false) assertMatches(source, '**/OTHER.*', '', false) } @Before void setUpFilesystemSourceAnalyzerTest() { analyzer = new FilesystemSourceAnalyzer() testCountRule = new FakeCountRule() ruleSet = new ListRuleSet([new FakePathRule(), testCountRule]) } private void assertMatches(source, includes, excludes, shouldMatch) { analyzer.includes = includes analyzer.excludes = excludes analyzer.initializeWildcardPatterns() assert analyzer.matches(source) == shouldMatch } private List resultsPaths(Results results, List paths=[]) { if (results.path) { paths << results.path } results.children.each { child -> resultsPaths(child, paths) } log("resultsPaths=$paths") paths } private List childResultsClasses(Results results) { results.children*.getClass() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/����������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021053� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/����������������������������������������0000755�0001750�0001750�00000000000�12623571301�023412� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessarySelfAssignmentRuleTest.groovy0000644�0001750�0001750�00000005122�12041642704�033513� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessarySelfAssignmentRule * * @author Hamlet D'Arcy */ class UnnecessarySelfAssignmentRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessarySelfAssignment' } @Test void testSuccessScenario() { final SOURCE = ''' x = y // acceptable a.b = a.zz // acceptable a.b = a().b // acceptable a.b.c = a?.b?.c // acceptable ''' assertNoViolations(SOURCE) } @Test void testVariableAssignment() { final SOURCE = ''' x = x // violation ''' assertSingleViolation(SOURCE, 2, 'x = x', 'Assignment a variable to itself should be unnecessary. Remove this dead code') } @Test void testParameterAssignment() { final SOURCE = ''' def method(y) { y = y // violation } ''' assertSingleViolation(SOURCE, 3, 'y = y', 'Assignment a variable to itself should be unnecessary. Remove this dead code') } @Test void testPropertyAssignment() { final SOURCE = ''' a.b = a.b // violation ''' assertSingleViolation(SOURCE, 2, 'a.b = a.b', 'Assignment a variable to itself should be unnecessary. Remove this dead code') } @Test void testPropertyAssignment2() { final SOURCE = ''' a.b.c = a.b.c // violation ''' assertSingleViolation(SOURCE, 2, 'a.b.c = a.b.c', 'Assignment a variable to itself should be unnecessary. Remove this dead code') } protected Rule createRule() { new UnnecessarySelfAssignmentRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/AddEmptyStringRuleTest.groovy�����������0000644�0001750�0001750�00000004343�12041642704�031253� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AddEmptyStringRule * * @author Hamlet D'Arcy */ class AddEmptyStringRuleTest extends AbstractRuleTestCase { private static final VIOLATION_MESSAGE = 'Concatenating an empty string is an inefficient way to convert an object to a String. Consider using toString() or String.valueOf(Object)' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AddEmptyString' } @Test void testSuccessScenario() { final SOURCE = ''' def c = 456.toString() def d = property?.toString() ?: "" ''' assertNoViolations(SOURCE) } @Test void testSimpleCase() { final SOURCE = ''' def a = '' + 123 ''' assertSingleViolation(SOURCE, 2, "'' + 123", VIOLATION_MESSAGE) } @Test void testMethodParameters() { final SOURCE = ''' def b = method('' + property) ''' assertSingleViolation(SOURCE, 2, "method('' + property)", VIOLATION_MESSAGE) } @Test void testAddingEmptyStringWithinAClosure() { final SOURCE = ''' class MyClass { def myClosure = { out << "" + count } } ''' assertSingleViolation(SOURCE, 4, 'out << "" + count', VIOLATION_MESSAGE) } protected Rule createRule() { new AddEmptyStringRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryCallToSubstringRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryCallToSubstringRuleTest.groov0000644�0001750�0001750�00000003207�12041642704�033461� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryCallToSubstringRule * * @author Hamlet D'Arcy */ class UnnecessaryCallToSubstringRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryCallToSubstring' } @Test void testSuccessScenario() { final SOURCE = ''' prop.substring(1) prop.substring(0, 1) ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' prop.substring(0) ''' assertSingleViolation(SOURCE, 2, 'prop.substring(0)', 'Invoking the String method substring(0) always returns the original value. Method possibly missing 2nd parameter') } protected Rule createRule() { new UnnecessaryCallToSubstringRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryNullCheckRuleTest.groovy�����0000644�0001750�0001750�00000013271�12311370173�032443� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryNullCheckRule * * @author Hamlet D'Arcy */ class UnnecessaryNullCheckRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryNullCheck' } @Test void testSuccessScenario() { final SOURCE = ''' // null check it OK if (obj != null) { } // null safe dereference in if is OK if (obj?.method()) { } // null safe dereference in ternary is OK (obj?.prop && obj?.prop2) ? x : y // obj is reused in a parameter list, so OK if (obj != null && obj.method() && isValid(obj)) { } // ok if changed if (obj != null && obj.method().method2()) { } if (obj != null && obj.prop1.prop2) { } // ok, different properties if (obj.prop1 && obj.prop2 != null) { } if (obj.method1() && obj.method2() != null) { } // ok, this is qualified if (this.x == null) {} ''' assertNoViolations(SOURCE) } @Test void testNullCheckWithMethodCall() { final SOURCE = ''' if (obj != null && obj.method()) { } ''' assertSingleViolation(SOURCE, 2, 'if (obj != null && obj.method())', 'The expression ((obj != null) && obj.method()) can be simplified to (obj?.method())') } @Test void testNullCheckWithProperty() { final SOURCE = ''' if (obj != null && obj.prop) { } ''' assertSingleViolation(SOURCE, 2, 'if (obj != null && obj.prop)', 'The expression ((obj != null) && obj.prop) can be simplified to (obj?.prop)') } @Test void testPointlessNullCheckOnMethod() { final SOURCE = ''' if (obj.method() && obj != null) { } ''' assertSingleViolation(SOURCE, 2, 'if (obj.method() && obj != null)', 'The expression (obj.method() && (obj != null)) can be simplified to (obj.method())') } @Test void testPointlessNullCheckOnProperty() { final SOURCE = ''' if (obj.prop && obj != null) { } ''' assertSingleViolation(SOURCE, 2, 'if (obj.prop && obj != null)', 'The expression (obj.prop && (obj != null)) can be simplified to (obj.prop)') } @Test void testPointlessNullCheckInClosureWithinClass() { final SOURCE = ''' class MyController extends AbstractController { def edit = { if (value != null && value.equalsIgnoreCase(YES)) { editView = "/editCustomMessage" } } } ''' assertSingleViolation(SOURCE, 4, 'if (value != null && value.equalsIgnoreCase(YES)) {', 'value?.equalsIgnoreCase(YES)') } @Test void testPointlessNullCheckAgainstThis() { final SOURCE = ''' if (this == null) { } if (null == this) { } ''' assertTwoViolations(SOURCE, 2, '(this == null)', 'Testing the this reference for null will always return false', 3, '(null == this)', 'Testing the this reference for null will always return false') } @Test void testPointlessNullCheckAgainstSuper() { final SOURCE = ''' if (super == null) { } if (null == super) { } ''' assertTwoViolations(SOURCE, 2, '(super == null)', 'Testing the super reference for null will always return false', 3, '(null == super)', 'Testing the super reference for null will always return false') } @Test void testPointlessNotNullCheckAgainstSuper() { final SOURCE = ''' if (super != null) { } if (null != super) { } ''' assertTwoViolations(SOURCE, 2, '(super != null)', 'Testing the super reference for not null will always return true', 3, '(null != super)', 'Testing the super reference for not null will always return true') } // todo: enable this test // void ignore_testNullCheckWithMethodCallAndAdditionalConditional() { // final SOURCE = ''' // if (x.isValid() && obj != null && obj.method()) { } // ''' // assertSingleViolation(SOURCE, 2, 'if (x.isValid() && obj != null && obj.method())', '...') // } //todo: enable this test // void ignore_testNullCheckWithPropertyAndMethod() { // final SOURCE = ''' // (obj != null && obj.prop && obj.method()) ? x : y // ''' // assertSingleViolation(SOURCE, 2, 'if (obj != null && obj.prop)', '...') // } protected Rule createRule() { new UnnecessaryNullCheckRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000157�00000000000�011606� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInVariableDeclarationRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInVariableDeclarationRuleT0000644�0001750�0001750�00000017324�12436200235�033336� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryDefInVariableDeclarationRule * * @author René Scheibe */ class UnnecessaryDefInVariableDeclarationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryDefInVariableDeclaration' } /* * Success scenarios */ @Test void testSuccessScenario_modifiers() { final SOURCE = ''' final SOURCE = \'\'\' def closure = { new Date() } \'\'\' final variable0 = 'example' def variable1 = 'example' private variable2 = 'example' protected variable3 = 'example' public variable4 = 'example' final variable5 = 'example' volatile variable6 = 'example' transient variable7 = 'example' class Test { static variable = 'example' } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_variableNamesContainingModifierNames() { final SOURCE = ''' def privateVariable = 'example' def protectedVariable = 'example' def publicVariable = 'example' def finalVariable = 'example' def volatileVariable = 'example' def transientVariable = 'example' class Test { def staticVariable = 'example' } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_types() { final SOURCE = ''' Object variable1 = 'example' String variable2 = 'example' int variable3 = 1 ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_misc() { final SOURCE = ''' def variable1 = variable2 = 'example' def variable3 = true ? 1 : 2 ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_Enum() { final SOURCE = ''' enum MavenScope { COMPILE, RUNTIME, TEST, PROVIDED, SYSTEM } ''' assertNoViolations(SOURCE) } @Test void testThatFieldsAreNotChecked() { final SOURCE = ''' class MyClass { def private variable1 def private variable2 = 'example' } ''' assertNoViolations SOURCE } /* * Violations */ @Test void testViolation_defAndPrivate() { final SOURCE = ''' def private variable1 def private variable2 = 'example' ''' assertTwoViolations(SOURCE, 2, 'def private variable1', 'The def keyword is unneeded when a variable is marked private', 3, 'def private variable2', 'The def keyword is unneeded when a variable is marked private') } @Test void testViolation_defAndProtected() { final SOURCE = ''' def protected variable1 def protected variable2 = 'example' ''' assertTwoViolations(SOURCE, 2, 'def protected variable1', 'The def keyword is unneeded when a variable is marked protected', 3, 'def protected variable2', 'The def keyword is unneeded when a variable is marked protected') } @Test void testViolation_defAndPublic() { final SOURCE = ''' def public variable1 def public variable2 = 'example' ''' assertTwoViolations(SOURCE, 2, 'def public variable1', 'The def keyword is unneeded when a variable is marked public', 3, 'def public variable2', 'The def keyword is unneeded when a variable is marked public') } @Test void testViolation_defAndFinal() { final SOURCE = ''' def final variable1 def final variable2 = 'example' ''' assertTwoViolations(SOURCE, 2, 'def final variable1', 'The def keyword is unneeded when a variable is marked final', 3, 'def final variable2', 'The def keyword is unneeded when a variable is marked final') } @Test void testViolation_defAndVolatile() { final SOURCE = ''' def volatile variable1 def volatile variable2 = 'example' ''' assertTwoViolations(SOURCE, 2, 'def volatile variable1', 'The def keyword is unneeded when a variable is marked volatile', 3, 'def volatile variable2', 'The def keyword is unneeded when a variable is marked volatile') } @Test void testViolation_defAndTransient() { final SOURCE = ''' def transient variable1 def transient variable2 = 'example' ''' assertTwoViolations(SOURCE, 2, 'def transient variable1', 'The def keyword is unneeded when a variable is marked transient', 3, 'def transient variable2', 'The def keyword is unneeded when a variable is marked transient') } @Test void testViolation_defAndObjectType() { final SOURCE = ''' def Object variable1 def Object variable2 = 'example' ''' assertTwoViolations(SOURCE, 2, 'def Object variable1', 'The def keyword is unneeded when a variable is of type Object', 3, 'def Object variable2', 'The def keyword is unneeded when a variable is of type Object') } @Test void testViolation_variableDeclarationAcrossMultipleLines() { final SOURCE = ''' def public int a = 1 ''' assertSingleViolation(SOURCE, 2, 'def', 'The def keyword is unneeded when a variable is marked public') } @Test void testViolation_variableTypeDeclared() { final SOURCE = ''' def String foo ''' assertSingleViolation(SOURCE, 2, 'def String foo', 'The def keyword is unneeded when a variable is declared with a type') } @Test void testViolation_multipleVariablesOnSingleLine() { final SOURCE = ''' def variable1 = 'good'; def public variable2 = 'bad' def public variable3 = 'bad'; def variable4 = 'good' ''' assertTwoViolations(SOURCE, 2, "def public variable2 = 'bad'", 'The def keyword is unneeded when a variable is marked public', 3, "def public variable3 = 'bad'", 'The def keyword is unneeded when a variable is marked public') } protected Rule createRule() { new UnnecessaryDefInVariableDeclarationRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryOverridingMethodRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryOverridingMethodRuleTest.groo0000644�0001750�0001750�00000005163�12041642704�033470� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryOverridingMethodRule * * @author 'Sven Lange' */ class UnnecessaryOverridingMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryOverridingMethod' } @Test void testSuccessScenario() { final SOURCE = ''' class MyLabel extends javax.swing.JLabel { void setVisible(boolean value, int value2) { super.setVisible(value) } void setVisible(String value) { proxy.setVisible(value) } void setVisible(boolean value, String value2) { super.setVisible(value2, value) } void someMethod(value) { super.someMethod(value()) } } ''' assertNoViolations(SOURCE) } @Test void testOneParameterViolation() { final SOURCE = ''' class MyLabel extends javax.swing.JLabel { void setVisible(boolean value) { super.setVisible(value) } } ''' assertSingleViolation(SOURCE, 4, 'setVisible(boolean value)') } @Test void testThreeParameterViolation() { final SOURCE = ''' class MyLabel extends javax.swing.JLabel { void setVisible(boolean value1, boolean value2, boolean value3) { super.setVisible(value1, value2, value3) } } ''' assertSingleViolation(SOURCE, 4, 'void setVisible(boolean value1, boolean value2, boolean value3)') } protected Rule createRule() { new UnnecessaryOverridingMethodRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000153�00000000000�011602� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryBooleanInstantiationRuleTest.groovy����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryBooleanInstantiationRuleTest.0000644�0001750�0001750�00000006466�12041642704�033463� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryBooleanInstantiationRule * * @author Chris Mair */ class UnnecessaryBooleanInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryBooleanInstantiation' } @Test void testApplyTo_NewBoolean() { final SOURCE = ''' class MyClass { def b1 = new Boolean(true) def exception = new Exception('bad') def b2 = new java.lang.Boolean(false) } ''' assertTwoViolations(SOURCE, 3, 'new Boolean(true)', 'There is typically no need to instantiate Boolean instances.', 5, 'new java.lang.Boolean(false)', 'There is typically no need to instantiate Boolean instances.') } @Test void testApplyTo_NewBoolean_NotWithinClass() { final SOURCE = ''' def b1 = new java.lang.Boolean(true) def name2 = "abc" void calculate() { String name = 'defghi' def b1 = new Boolean(true) def str = new StringBuffer() } ''' assertTwoViolations(SOURCE, 2, 'new java.lang.Boolean(true)', 6, 'new Boolean(true)') } @Test void testApplyTo_BooleanValueOf() { final SOURCE = ''' class MyClass { def myClosure = { def b1 = Boolean.valueOf(true) def b2 = Boolean.valueOf(otherVariable) def b3 = Boolean.valueOf(false) } } ''' assertTwoViolations(SOURCE, 4, 'Boolean.valueOf(true)', 'Call to Boolean.valueOf(true) is unnecessary and can probably be replaced with simply true', 6, 'Boolean.valueOf(false)', 'Call to Boolean.valueOf(false) is unnecessary and can probably be replaced with simply false') } @Test void testApplyTo_WithinEnum() { final SOURCE = ''' enum MyEnum { NONE, READ, WRITE } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { def b = Boolean.valueOf(myVariable) } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryBooleanInstantiationRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryTransientModifierRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryTransientModifierRuleTest.gro0000644�0001750�0001750�00000005360�12041642704�033465� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryTransientModifierRule * * @author Hamlet D'Arcy */ class UnnecessaryTransientModifierRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryTransientModifier' } @Test void testSuccessScenario() { final SOURCE = ''' class MySerializableClass implements Serializable { // OK, class is serializable transient String property } class MyClass { class InnerClass implements Serializable { // class not serializable, violation occurs transient String property } } ''' assertNoViolations(SOURCE) } @Test void testTransientPropertyInClassThatIsNotSerializable() { final SOURCE = ''' class MyClass { // class not serializable, violation occurs transient String property } ''' assertSingleViolation(SOURCE, 4, 'transient String property', 'Violation in class MyClass. The field \'property\' is marked transient, but MyClass does not implement Serializable') } @Test void testTransientPropertyInInnerClassThatIsNotSerializable() { final SOURCE = ''' class MyClass { class InnerClass { // class not serializable, violation occurs transient String property } } ''' assertSingleViolation(SOURCE, 5, 'transient String property', 'Violation in class MyClass$InnerClass. The field \'property\' is marked transient, but MyClass$InnerClass does not implement Serializable') } protected Rule createRule() { new UnnecessaryTransientModifierRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryToStringRuleTest.groovy������0000644�0001750�0001750�00000010540�12325340400�032333� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for UnnecessaryToStringRule * * @author Chris Mair */ class UnnecessaryToStringRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnnecessaryToString' assert rule.checkAssignments } @Test void testNoViolations() { final SOURCE = ''' def name = nameNode.toString() def id = idNode.lastChild.toString() def code = "$id-1234".toString() // GString ''' assertNoViolations(SOURCE) } @Test void testStringExpression_ToString_Violation() { final SOURCE = ''' class MyClass { def name = "Joe".toString() void run() { def id = '123'.toString() def groupId = ((String)currentRow.get('GroupID')).toString() } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'def name = "Joe".toString()', messageText:'Calling toString() on the String expression in class MyClass is unnecessary'], [lineNumber:6, sourceLineText:"def id = '123'.toString()", messageText:'Calling toString() on the String expression in class MyClass is unnecessary'], [lineNumber:7, sourceLineText:"def groupId = ((String)currentRow.get('GroupID')).toString()", messageText:'Calling toString() on the String expression in class MyClass is unnecessary'] ) } @Test void testAssignmentToStringField_ToString_Violation() { final SOURCE = ''' class MyClass { String name = nameNode.toString() String id = account.id.toString() String code = account.getCode().toString() } ''' def message = 'Calling toString() when assigning to String field "%s" in class MyClass is unnecessary' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'String name = nameNode.toString()', messageText:String.format(message, 'name')], [lineNumber:4, sourceLineText:'String id = account.id.toString()', messageText:String.format(message, 'id')], [lineNumber:5, sourceLineText:'String code = account.getCode().toString()', messageText:String.format(message, 'code')] ) } @Test void testAssignmentToStringVariable_ToString_Violation() { final SOURCE = ''' String name = nameNode.toString() String id = account.id.toString() String code = account.getCode().toString() ''' def message = 'Calling toString() when assigning to String variable "%s" in class None is unnecessary' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'String name = nameNode.toString()', messageText:String.format(message, 'name')], [lineNumber:3, sourceLineText:'String id = account.id.toString()', messageText:String.format(message, 'id')], [lineNumber:4, sourceLineText:'String code = account.getCode().toString()', messageText:String.format(message, 'code')] ) } @Test void testAssignmentToStringVariableOrField_ToString_CheckAssignmentsIsFalse_NoViolations() { final SOURCE = ''' class MyClass { String name = nameNode.toString() void run() { String id = account.id.toString() String code = account.getCode().toString() } } ''' rule.checkAssignments = false assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryToStringRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryCollectCallRuleTest.groovy���0000644�0001750�0001750�00000006536�12041642704�032764� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryCollectCallRule * * @author Hamlet D'Arcy */ class UnnecessaryCollectCallRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryCollectCall' } @Test void testSuccessScenario() { final SOURCE = ''' // OK, is not method call in closure [1, 2, 3].collect { it * it } // OK, is not collect call [1, 2, 3].mapMethod { it.multiply(5) } // OK, is not one argument/closure call [1, 2, 3].collect(5) // OK is not single statement closure [1, 2, 3].collect { println it; it.multiply(5) } // OK is not single parameter closure [1, 2, 3].collect { a, b -> a.multiply(b) } // OK method call references closure parameters [1, 2, 3].collect { it.multiply(it) } // OK, chained methods, too complex to analyze (maybe implement later?) [1, 2, 3].collect { it.multiply(2).multiply(it ) } ["1", "2", "3"].collect { it.bytes.foo(it) } [1, 2, 3].collect { it.multiply(2).multiply(4) } // should be written this way: [1, 2, 3]*.multiply(2) ["1", "2", "3"]*.bytes ''' assertNoViolations(SOURCE) } @Test void testSimpleCaseImplicitItParameter() { final SOURCE = ''' assert [1, 2, 3].collect { it.multiply(2) } ''' assertSingleViolation(SOURCE, 2, '[1, 2, 3].collect', 'The call to collect could probably be rewritten as a spread expression: [1, 2, 3]*.multiply(2)') } @Test void testSimpleCaseNamedParameter() { final SOURCE = ''' assert [1, 2, 3].collect { x -> x.multiply(2) } ''' assertSingleViolation(SOURCE, 2, '[1, 2, 3].collect', 'The call to collect could probably be rewritten as a spread expression: [1, 2, 3]*.multiply(2)') } @Test void testPropertyExpression() { final SOURCE = ''' ["1", "2", "3"].collect { it.bytes } ''' assertSingleViolation(SOURCE, 2, '["1", "2", "3"].collect', 'The call to collect could probably be rewritten as a spread expression: [1, 2, 3]*.bytes') } protected Rule createRule() { new UnnecessaryCollectCallRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessarySemicolonRuleTest.groovy�����0000644�0001750�0001750�00000010234�12041642704�032521� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessarySemicolonRule * * @author Hamlet D'Arcy */ class UnnecessarySemicolonRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessarySemicolon' } @Test void testSuccessScenario() { final SOURCE = ''' /* * * (the "License"); * (the "License"); * (the "License"); * you may not use this file except in compliance with the License. * */ //comment is not a violation; package foo import java.lang.String println(value) println(value); println (otherValue) println(value); // comment so no violation @SuppressWarnings('UnnecessarySemicolon') def method() { ; } @SuppressWarnings('UnnecessarySemicolon') class A { String a = 'text'; } ''' assert !manuallyApplyRule(SOURCE) } @Test void testSimpleString() { final SOURCE = """ def string = 'hello world'; """ assertSingleViolation SOURCE, 2, "def string = 'hello world';" } @Test void testSemiColonInMultilineString() { final SOURCE = """ def javascript = ''' // this next semicolon is ignored window.alert("some embedded javascript..."); // this next semicolon is not ignored! '''; """ assertSingleViolation SOURCE, 6, ' \'\'\';' } @Test void testSemiColonInGStringString() { final SOURCE = ''' def var = 'yo yo yo' def javascript = """ // this next semicolon is ignored window.alert($var); // this next semicolon is not ignored! """; ''' assertSingleViolation SOURCE, 7, ' """;' } @Test void testPackage() { final SOURCE = ''' package my.company.server; ''' assertSingleViolation(SOURCE, 2, 'package my.company.server;', 'Semi-colons as line endings can be removed safely') } @Test void testLoop() { final SOURCE = ''' for (def x : list); ''' assertSingleViolation(SOURCE, 2, 'for (def x : list);', 'Semi-colons as line endings can be removed safely') } @Test void testMethodCall() { final SOURCE = ''' println(value) ; ''' assertSingleViolation(SOURCE, 2, 'println(value) ;', 'Semi-colons as line endings can be removed safely') } @SuppressWarnings('UnnecessarySemicolon') @Test void testImport() { final SOURCE = ''' import java.lang.String; ''' assertSingleViolation(SOURCE, 2, 'import java.lang.String;', 'Semi-colons as line endings can be removed safely') } @Test void testClass() { final SOURCE = ''' class A { int a() { return 1; } } ''' assertSingleViolation(SOURCE, 4, 'return 1;', 'Semi-colons as line endings can be removed safely') } protected Rule createRule() { new UnnecessarySemicolonRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryTernaryExpressionRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryTernaryExpressionRuleTest.gro0000644�0001750�0001750�00000016316�12041642704�033546� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryTernaryExpressionRule * * @author Chris Mair */ class UnnecessaryTernaryExpressionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryTernaryExpression' } @Test void testApplyTo_TrueAndFalse_IsAViolation() { final SOURCE = ''' def x = !ready ? true : false def y = !ready ? Boolean.TRUE : Boolean.FALSE ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def x = !ready ? true : false'], [lineNumber:3, sourceLineText:'def y = !ready ? Boolean.TRUE : Boolean.FALSE']) } @Test void testApplyTo_TrueAndFalse_MixedUseOfBooleanClassConstants_IsAViolation() { final SOURCE = ''' def x = !ready ? Boolean.TRUE : false def y = !ready ? true : Boolean.FALSE ''' assertTwoViolations(SOURCE, 2, 'def x = !ready ? Boolean.TRUE : false', 3, 'def y = !ready ? true : Boolean.FALSE') } @Test void testApplyTo_FalseAndTrue_IsAViolation() { final SOURCE = ''' def x = !ready ? false : true def y = !ready ? Boolean.FALSE : Boolean.TRUE ''' assertTwoViolations(SOURCE, 2, 'def x = !ready ? false : true', 3, 'def y = !ready ? Boolean.FALSE : Boolean.TRUE') } @Test void testApplyTo_ConditionalExpressionIsABoolean_IsAViolation() { final SOURCE = ''' def x x = !ready ? true : false x = !(y + z) ? Boolean.TRUE : Boolean.FALSE x = (y == 99) ? false : true x = (y < 99) ? false : Boolean.TRUE x = (y <= 99) ? false : true x = (y > 99) ? true : false x = (y >= 99) ? false : true x = (y != 99) ? true : false x = (y ==~ /../) ? true : false x = (y && z) ? true : false x = (y || z) ? true : false x = (y || calculate(99)) ? true : false x = (addTax(5) + 5 || calculate(99) && ready) ? true : false ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'x = !ready ? true : false'], [lineNumber:4, sourceLineText:'x = !(y + z) ? Boolean.TRUE : Boolean.FALSE'], [lineNumber:5, sourceLineText:'x = (y == 99) ? false : true'], [lineNumber:6, sourceLineText:'x = (y < 99) ? false : Boolean.TRUE'], [lineNumber:7, sourceLineText:'x = (y <= 99) ? false : true'], [lineNumber:8, sourceLineText:'x = (y > 99) ? true : false'], [lineNumber:9, sourceLineText:'x = (y >= 99) ? false : true'], [lineNumber:10, sourceLineText:'x = (y != 99) ? true : false'], [lineNumber:11, sourceLineText:'x = (y ==~ /../) ? true : false'], [lineNumber:12, sourceLineText:'x = (y && z) ? true : false'], [lineNumber:13, sourceLineText:'x = (y || z) ? true : false'], [lineNumber:14, sourceLineText:'x = (y || calculate(99)) ? true : false'], [lineNumber:15, sourceLineText:'x = (addTax(5) + 5 || calculate(99) && ready) ? true : false'] ) } @Test void testApplyTo_TrueAndFalseExpressionsAreTheSameLiteral_IsAViolation() { final SOURCE = ''' def x = ready ? 123 : 123 def y = !ready ? "abc" : "abc" ''' assertTwoViolations(SOURCE, 2, 'def x = ready ? 123 : 123', 3, 'def y = !ready ? "abc" : "abc"') } @Test void testApplyTo_TrueAndFalseExpressionsAreBothTrueOrBothFalse_IsAViolation() { final SOURCE = ''' def x = ready ? true : true def y = ready ? false : false ''' assertTwoViolations(SOURCE, 2, 'def x = ready ? true : true', 3, 'def y = ready ? false : false') } @Test void testApplyTo_TrueAndFalseExpressionsAreBothNull_IsAViolation() { final SOURCE = ''' def x = ready ? null : null ''' assertSingleViolation(SOURCE, 2, 'def x = ready ? null : null') } @Test void testApplyTo_TrueAndFalseExpressionsAreBothEmptyString_IsAViolation() { final SOURCE = ''' def x = ready ? '' : "" ''' assertSingleViolation(SOURCE, 2, /def x = ready ? '' : ""/) } @Test void testApplyTo_TrueAndFalseExpressionsAreTheSameVariable_IsAViolation() { final SOURCE = ''' def x = ready ? MAX_VALUE : MAX_VALUE def y = !ready ? result : result ''' assertTwoViolations(SOURCE, 2, 'def x = ready ? MAX_VALUE : MAX_VALUE', 3, 'def y = !ready ? result : result') } @Test void testApplyTo_TrueAndFalseExpressionsAreTheSameMethodCall_NotAViolation() { final SOURCE = ''' def x = !ready ? process('abc') : process('abc') def y = !ready ? increment(x) : increment(x) ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ComplexExpressions_NotAViolation() { final SOURCE = ''' transactionTypes.equals('ALL') ? myService.findAllWidgetsByPlan{ plan -> valueOne } : myService.findAllWidgetsByPlan{ plan -> valueTwo } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ConditionalExpressionIsNotABoolean_NoViolations() { final SOURCE = ''' def x x = ready ? true : false x = doSomething(23) ? true : false x = null ? true : false x = 23 + 7 ? true : false x = y + 'x' ? true : false x = 'abc' =~ /./ ? true : false x = y <=> 99 ? true : false ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NotTrueAndFalse_NoViolations() { final SOURCE = ''' def x x = !ready ? 1 : 0 x = !ready ? true : 0 x = !ready ? 1 : false x = !ready ? MY_TRUE : Boolean.FALSE x = !ready ? Boolean.TRUE : x+1 x = !ready ? increment(y) : increment(z) x = !ready ? 99 : 98+1 x = !ready ? MIN_VALUE : MAX_VALUE x = !ready ? MAX_VALUE + 1 : MAX_VALUE ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryTernaryExpressionRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryCollectionCallRuleTest.groovy0000644�0001750�0001750�00000004240�12311370173�033456� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryCollectionCallRule * * @author Hamlet D'Arcy */ class UnnecessaryCollectionCallRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryCollectionCall' } @Test void testNoViolations() { final SOURCE = ''' def x = [1, 2, 3] x.containsAll(y) x.containsAll(y, z) x.containsAll() x.retainAll(y) x.retainAll(y, z) x.retainAll() ''' assertNoViolations(SOURCE) } @Test void testScriptFailure() { final SOURCE = ''' def x = [1, 2, 3] x.containsAll(x) x.retainAll(x) ''' assertTwoViolations(SOURCE, 3, 'x.containsAll(x)', 4, 'x.retainAll(x)') } @Test void testClassFailure() { final SOURCE = ''' class MyClass { def x = [1, 2, 3] def foo() { x.containsAll(x) x.retainAll(x) } } ''' assertTwoViolations(SOURCE, 6, 'x.containsAll(x)', 7, 'x.retainAll(x)') } protected Rule createRule() { new UnnecessaryCollectionCallRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryObjectReferencesRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryObjectReferencesRuleTest.groo0000644�0001750�0001750�00000014757�12041642704�033440� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryObjectReferencesRule * * @author Hamlet D'Arcy */ class UnnecessaryObjectReferencesRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryObjectReferences' } @Test void testSuccessScenario() { final SOURCE = ''' // 'this' reference ignored firstName = 'Hamlet' lastName = "D'Arcy" employer = 'Canoo' street = 'Kirschgaraten 5' city = 'Basel' zipCode = '4051' this.firstName = 'Hamlet' this.lastName = "D'Arcy" this.employer = 'Canoo' this.street = 'Kirschgaraten 5' this.city = 'Basel' this.zipCode = '4051' method1() method2() method4() method6() method5() this.method1() this.method2() this.method4() this.method6() this.method5() method1() // only 5 references def p = new Person() p.firstName = 'Hamlet' p.lastName = "D'Arcy" p.employer = 'Canoo' p.street = 'Kirschgaraten 5' p.city = 'Basel' def p1 = new Person().with { firstName = 'Hamlet' lastName = "D'Arcy" employer = 'Canoo' street = 'Kirschgaraten 5' city = 'Basel' zipCode = '4051' } def p2 = new Person().identity { firstName = 'Hamlet' lastName = "D'Arcy" employer = 'Canoo' street = 'Kirschgaraten 5' city = 'Basel' zipCode = '4051' } ''' assertNoViolations(SOURCE) } @Test void testExcessivePropertyAccess() { final SOURCE = ''' class Person { String firstName String lastName String employer String street String city String zipCode } def p1 = new Person() p1.firstName = 'Hamlet' p1.lastName = "D'Arcy" p1.employer = 'Canoo' p1.street = 'Kirschgaraten 5' p1.city = 'Basel' p1.zipCode = '4051' def p2 = new Person() p2.firstName = 'Hamlet' p2.lastName = "D'Arcy" p2.employer = 'Canoo' p2.street = 'Kirschgaraten 5' p2.city = 'Basel' p2.zipCode = '4051' ''' assertTwoViolations(SOURCE, 17, "p1.zipCode = '4051'", 25, "p2.zipCode = '4051'") } @Test void testOverridingProperty() { rule.maxReferencesAllowed = 2 final SOURCE = ''' class Person { String firstName String lastName String employer String street String city String zipCode } def p1 = new Person() p1.firstName = 'Hamlet' p1.lastName = "D'Arcy" p1.employer = 'Canoo' ''' assertSingleViolation(SOURCE, 14, "p1.employer = 'Canoo'", 'The code could be more concise by using a with() or identity() block') } @Test void testExcessiveSetters() { final SOURCE = ''' class Person { String firstName String lastName String employer String street String city String zipCode } def p2 = new Person() p2.setFirstName('Hamlet') p2.setLastName("D'Arcy") p2.setEmployer('Canoo') p2.setStreet('Kirschgaraten 5') p2.setCity('Basel') p2.setZipCode('4051') ''' assertSingleViolation(SOURCE, 17, "p2.setZipCode('4051')", 'The code could be more concise by using a with() or identity() block') } @Test void testReferencesAcrossMethods() { final SOURCE = ''' class MyClass { def method1() { obj.method('param') } def method2() { obj.method('param') } def method3() { obj.method('param') } } ''' rule.maxReferencesAllowed = 2 assertNoViolations(SOURCE) } @Test void testReferencesAcrossFields() { final SOURCE = ''' class MyClass { static mappings = [ 0: {IdefixDto idefixDto, def value -> idefixDto.ian = value}, 1: {IdefixDto idefixDto, def value -> idefixDto.iaPosition = value}, 2: {IdefixDto idefixDto, def value -> idefixDto.filiale = value}, 3: {IdefixDto idefixDto, def value -> idefixDto.fiAuftragsId = value}, ] } ''' rule.maxReferencesAllowed = 2 assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryObjectReferencesRule() } } �����������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryLongInstantiationRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryLongInstantiationRuleTest.gro0000644�0001750�0001750�00000003505�12041642704�033502� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryLongInstantiationRule * * @author Hamlet D'Arcy */ class UnnecessaryLongInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryLongInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' assert 42L == foo() assert 42L == new Long([] as char[]) assert 42L == new Long("42", 10) ''' assertNoViolations(SOURCE) } @Test void testStringConstructor() { final SOURCE = ''' new Long("42") ''' assertSingleViolation(SOURCE, 2, 'new Long("42")', 'Can be rewritten as 42L') } @Test void testLongConstructor() { final SOURCE = ''' new Long(42L) ''' assertSingleViolation(SOURCE, 2, 'new Long(42L)', 'Can be rewritten as 42L') } protected Rule createRule() { new UnnecessaryLongInstantiationRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDotClassRuleTest.groovy������0000644�0001750�0001750�00000004414�12322567454�032322� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryDotClassRule * * @author Dean Del Ponte */ class UnnecessaryDotClassRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryDotClass' } @Test void testNoViolations() { final SOURCE = ''' def x = String def y = x.class def z = x.getClass() def a = String.class() assert codeNarcRunner.sourceAnalyzer.class == AntFileSetSourceAnalyzer ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' def x = String.class def theClass = com.foo.Bar.class ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def x = String.class', messageText:'String.class can be rewritten as String'], [lineNumber:3, sourceLineText:'def theClass = com.foo.Bar.class', messageText:'com.foo.Bar.class can be rewritten as com.foo.Bar']) } @Test void testNoDuplicateViolation() { final SOURCE = ''' class MyClass { static final Logger LOG = Logger.getLogger(MyClass.class); } ''' assertSingleViolation(SOURCE, 3, 'static final Logger LOG = Logger.getLogger(MyClass.class);', 'MyClass.class can be rewritten as MyClass') } protected Rule createRule() { new UnnecessaryDotClassRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessarySubstringRuleTest.groovy�����0000644�0001750�0001750�00000004163�12041642704�032555� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessarySubstringRule * * @author Hamlet D'Arcy */ class UnnecessarySubstringRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessarySubstring' } @Test void testSuccessScenario() { final SOURCE = ''' myVar[5..-1] myVar[1..5] myVar.substring() // not enough parms myVar.substring(1, 2, 3) // too many parms Integer.substring(1) // clearly a static call Integer.substring(1, 2) // clearly a static call myVar.substring(begin: 5) ''' assertNoViolations(SOURCE) } @Test void testOneParmSubstring() { final SOURCE = ''' myVar.substring(5) ''' assertSingleViolation(SOURCE, 2, 'myVar.substring(5)', 'The String.substring(int) method can be replaced with the subscript operator') } @Test void testTwoParmSubstring() { final SOURCE = ''' myVar.substring(1, 5) ''' assertSingleViolation(SOURCE, 2, 'myVar.substring(1, 5)', 'The String.substring(int, int) method can be replaced with the subscript operator') } protected Rule createRule() { new UnnecessarySubstringRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/ConsecutiveLiteralAppendsRuleTest.groovy0000644�0001750�0001750�00000005135�12041642704�033474� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConsecutiveLiteralAppendsRule * * @author Hamlet D'Arcy */ class ConsecutiveLiteralAppendsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ConsecutiveLiteralAppends' } @Test void testSuccessScenario() { final SOURCE = ''' // usage not chained invocation writer.append('Hello') writer.append('World') writer.append(null).append(5) // nulls cannot be joined writer.append().append('Hello') // no arg append is unknown writer.append('a', 'b').append('Hello') // two arg append is unknown ''' assertNoViolations(SOURCE) } @Test void testStrings() { final SOURCE = ''' writer.append('foo').append('bar') // strings can be joined ''' assertSingleViolation(SOURCE, 2, 'writer.append', "Consecutive calls to append method with literal parameters can be joined into append('foobar')") } @Test void testStringAndNumber() { final SOURCE = ''' writer.append('foo').append(5) // string and number can be joined ''' assertSingleViolation(SOURCE, 2, 'writer.append', "Consecutive calls to append method with literal parameters can be joined into append('foo5')") } @Test void testGString() { final SOURCE = ''' writer.append('Hello').append("$World") // GString can be joined ''' assertSingleViolation(SOURCE, 2, 'writer.append', 'Consecutive calls to append method with literal parameters can be joined into one append() call') } protected Rule createRule() { new ConsecutiveLiteralAppendsRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryCastRuleTest.groovy����������0000644�0001750�0001750�00000005275�12322626034�031474� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for UnnecessaryCastRule * * @author Chris Mair */ class UnnecessaryCastRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnnecessaryCast' } @Test void testNoViolations() { final SOURCE = ''' int count = (int) 123L String id = (String) 123L def theClass = ((BigDecimal)123L).class ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' int count = (int)123 def longValue = (long)123456L def bigDecimal = (BigDecimal)1234.56 String name = (String) "Joe" def list = (List)[1, 2, 3] def map = (Map)[a:1] def theClass = ((BigDecimal)123.45).class ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'int count = (int)123', messageText:'The cast (int) 123 in class None is unnecessary'], [lineNumber:3, sourceLineText:'def longValue = (long)123456L', messageText:'The cast (long) 123456 in class None is unnecessary'], [lineNumber:4, sourceLineText:'def bigDecimal = (BigDecimal)1234.56', messageText:'The cast (BigDecimal) 1234.56 in class None is unnecessary'], [lineNumber:5, sourceLineText:'String name = (String) "Joe"', messageText:'The cast (String) Joe in class None is unnecessary'], [lineNumber:6, sourceLineText:'def list = (List)[1, 2, 3]', messageText:'The cast (List) [1, 2, 3] in class None is unnecessary'], [lineNumber:7, sourceLineText:'def map = (Map)[a:1]', messageText:'The cast (Map) [a:1] in class None is unnecessary'], [lineNumber:8, sourceLineText:'def theClass = ((BigDecimal)123.45).class', messageText:'The cast (BigDecimal) 123.45 in class None is unnecessary'], ) } protected Rule createRule() { new UnnecessaryCastRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryIfStatementRuleTest.groovy���0000644�0001750�0001750�00000017655�12253076636�033044� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryIfStatementRule * * @author Chris Mair */ class UnnecessaryIfStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryIfStatement' assert rule.checkLastStatementImplicitElse } // Tests for explicit return of true/false @Test void testApplyTo_ReturnTrueAndFalse_IsAViolation() { final SOURCE = ''' if (expression1) return true else return false if (expression2) return Boolean.TRUE else return Boolean.FALSE if (expression3) return Boolean.TRUE else return false if (expression4) return true else return Boolean.FALSE ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (expression1)'], [lineNumber:3, sourceLineText:'if (expression2)'], [lineNumber:4, sourceLineText:'if (expression3)'], [lineNumber:5, sourceLineText:'if (expression4)']) } @Test void testApplyTo_ReturnFalseAndTrue_IsAViolation() { final SOURCE = ''' if (expression1) return false else return true if (expression2) return Boolean.FALSE else return Boolean.TRUE ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (expression1)'], [lineNumber:3, sourceLineText:'if (expression2)'] ) } @Test void testApplyTo_ReturnTrueFalse_WithBraces_IsAViolation() { final SOURCE = ''' if (expression1) { return true } else { return false } if (expression2) return Boolean.FALSE else { return Boolean.TRUE } if (expression3) { return false } else return true ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (expression1)'], [lineNumber:3, sourceLineText:'if (expression2)'], [lineNumber:4, sourceLineText:'if (expression3)']) } @Test void testApplyTo_MultipleStatementBlocks_NotAViolation() { final SOURCE = ''' if (expression1) { println 123; return true } else { return false } if (expression2) return Boolean.FALSE else { doSomething(); return Boolean.TRUE } if (expression3) { x = 98.6 return false } else return true ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReturnOtherValues_NotAViolation() { final SOURCE = ''' if (someExpression) return 67 else return false if (someExpression) return true else return 88 if (someExpression) return Boolean.TRUE else return "false" if (someExpression) return "true" else return Boolean.FALSE ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoElseBlock_NotAViolation() { final SOURCE = ''' if (someExpression) return true if (someExpression) return true else { } ''' assertNoViolations(SOURCE) } private static final SOURCE_FALLS_THROUGH_TO_RETURN = ''' def method1() { if (expression1) { return true } return false } def closure1 = { if (expression2) return Boolean.FALSE return Boolean.TRUE } ''' @Test void testApplyTo_IfReturn_FallsThroughToReturn_IsAViolation() { assertViolations(SOURCE_FALLS_THROUGH_TO_RETURN, [lineNumber:3, sourceLineText:'if (expression1)'], [lineNumber:9, sourceLineText:'if (expression2)']) } @Test void testApplyTo_IfReturn_FallsThroughToReturn_checkLastStatementImplicitElse_False_NoViolation() { rule.checkLastStatementImplicitElse = false assertNoViolations(SOURCE_FALLS_THROUGH_TO_RETURN) } // Tests for implicit return of true/false (last statement in a block) @Test void testApplyTo_ImplicitReturnAtEndOfMethod_TrueAndFalse_IsAViolation() { final SOURCE = ''' def isSpellingCorrect(word) { File file = new File("...") def found = false file.eachLine { if (it == word) found = true } if (found) { true } else false } ''' assertSingleViolation(SOURCE, 8, 'if (found) { true } else false') } // Tests for if/else blocks that are merely constant or literal expressions (not at the end of a block) @Test void testApplyTo_NotLastStatement_IfBlockIsOnlyAConstantExpression_IsAViolation() { final SOURCE = ''' def myClosure = { doStuff() if (ready) { 'abc' } doOtherStuff() if (ready) 123 doSomeOtherStuff() } ''' assertTwoViolations(SOURCE, 4, 'if (ready) {', 'if block', 8, 'if (ready) 123', 'if block') } @Test void testApplyTo_NotLastStatement_ElseBlockIsOnlyAConstantExpression_IsAViolation() { final SOURCE = ''' String myMethod() { doStuff() if (ready) { doStuff() } else [a:123, b:456] doOtherStuff() } ''' assertSingleViolation(SOURCE, 6, '} else [a:123, b:456]', 'else block') } @Test void testApplyTo_NotLastStatement_IfAndElseBlocksAreOnlyAConstantExpressions_IsAViolation() { final SOURCE = ''' Object myMethod() { doStuff() if (ready) { [1, 2, 3] } else { Boolean.FALSE } doOtherStuff() } ''' assertTwoViolations(SOURCE, 4, 'if (ready) {', 'if block', 6, '} else {', 'else block') } @Test void testApplyTo_IfElseStatement_LastStatement_IfBlockAndElseBlocksAreOnlyConstantExpressions_NotAViolation() { final SOURCE = ''' String myMethod() { doStuff() if (ready) 'abc'; else 'xyz' } ''' assertNoViolations(SOURCE) } // Tests for if statements that do not apply for this rule @Test void testApplyTo_MethodCalls_NotAViolation() { final SOURCE = ''' if (someExpression) doStep1(); else doStep2() if (someExpression) { doStep1() } else { doStep2() } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_EmptyBlocks_NotAViolation() { final SOURCE = ''' if (someExpression) {} if (someExpression) { doSomething() } else { } try { } finally { } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryIfStatementRule() } } �����������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryReturnKeywordRuleTest.groovy�0000644�0001750�0001750�00000004227�12041642704�033422� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryReturnKeywordRule * * @author Hamlet D'Arcy */ class UnnecessaryReturnKeywordRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryReturnKeyword' } @Test void testSuccessScenario() { final SOURCE = ''' def x = { y++; it } def x = { it } def method1(it) { y++ it } def method2(it) { it } def method3() { return { 5 } } ''' assertNoViolations(SOURCE) } @Test void testInClosures() { final SOURCE = ''' def x = { y++; return it } def x = { return it } ''' assertTwoViolations(SOURCE, 2, 'return it', 3, 'return it') } @Test void testInMethods() { final SOURCE = ''' def method1(it) { y++ return it } def method2(it) { return it } ''' assertTwoViolations(SOURCE, 4, 'return it', 7, 'return it') } protected Rule createRule() { new UnnecessaryReturnKeywordRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryElseStatementRuleTest.groovy�0000644�0001750�0001750�00000014433�12041642704�033353� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryElseStatementRule * * @author Victor Savkin */ class UnnecessaryElseStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryElseStatement' } @Test void testShouldNotAddViolationsForCodeWithoutIfStatement() { final SOURCE = ''' while(true){ println 'inside' } ''' assertNoViolations SOURCE } @Test void testShouldNotAddViolationsForIfStatementWithoutElse() { final SOURCE = ''' if(value){ return true } ''' assertNoViolations SOURCE } @Test void testShouldNotAddViolationsForIfStatementThatDoesNotHaveReturn() { final SOURCE = ''' if(value){ println true } else { println false } ''' assertNoViolations SOURCE } @Test void testShouldNoViolationsForIfStatementWhereNotEveryBranchEndsWithReturn() { final SOURCE = ''' if(value){ if(value2){ return true } } else { println false } ''' assertNoViolations SOURCE } @Test void testIfElseIf_NoViolations() { final SOURCE = ''' if (foo) { return bar } else if (baz) { return qux } ''' assertNoViolations(SOURCE) } @Test void testIfElseIf() { final SOURCE = ''' if (foo) { bar++ } else if (baz) { return qux } else { fap } ''' assertNoViolations(SOURCE) } @Test void testNesting() { final SOURCE = ''' if (foo) { bar++ } else if (baz) { return qux } else { if (foo) { return bar } else { return quif } } ''' assertSingleViolation(SOURCE, 9, '} else {') } @Test void testShouldAddViolationForIfStatementHavingOnlyReturnStatement() { final SOURCE = ''' if(value) return true else println false ''' assertSingleViolation SOURCE, 5, 'println false', 'When an if statement block ends with a return statement the else is unnecessary' } @Test void testShouldAddViolationForIfStatementHavingBlockWithReturnStatement() { final SOURCE = ''' if(value){ return true }else{ println false } ''' assertSingleViolation SOURCE, 4, '}else{', 'When an if statement block ends with a return statement the else is unnecessary' } @Test void testShouldAddViolationForIfStatementEndingWithReturnStatement() { final SOURCE = ''' if(value){ def a = 2 + 2 return } else { println false } ''' assertSingleViolation SOURCE, 5, '} else {', 'When an if statement block ends with a return statement the else is unnecessary' } @Test void testShouldAddViolationForIfStatementWithAllBranchesEndingWithReturnStatements() { final SOURCE = ''' if(value){ if(value2){ return true } while(false){ } return false } else { println false } ''' assertSingleViolation SOURCE, 9, '} else {', 'When an if statement block ends with a return statement the else is unnecessary' } @Test void testShouldAddViolationForIfStatementContainingUnconditionalReturnStatement() { final SOURCE = ''' if(value){ def a = value1 return true def b = value2 } else { println false } ''' assertSingleViolation SOURCE, 6, '} else {', 'When an if statement block ends with a return statement the else is unnecessary' } @Test void testShouldAddTwoViolationForTwoEmbeddedIfStatementsEndingWithReturn() { final SOURCE = ''' if(value){ if(value2){ return true } else { return false } } else { println false } ''' assertTwoViolations SOURCE, 5, '} else {', 8, '} else {' } @Test void testShouldAddTwoViolationForTwoEmbeddedIfStatementsContainingUnconditionalReturn() { final SOURCE = ''' if(value){ def a = value1 if(true){ return true } else { return false } def b = value2 } else { println false } ''' assertTwoViolations SOURCE, 6, '} else {', 10, '} else {' } protected Rule createRule() { new UnnecessaryElseStatementRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000156�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryBigIntegerInstantiationRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryBigIntegerInstantiationRuleTe0000644�0001750�0001750�00000003245�12041642704�033466� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryBigIntegerInstantiationRule * * @author Hamlet D'Arcy */ class UnnecessaryBigIntegerInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryBigIntegerInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' assert 42G == foo() assert 42G == new BigInteger([] as byte[]) assert 42G == new BigInteger("42", 10) ''' assertNoViolations(SOURCE) } @Test void testStringConstructor() { final SOURCE = ''' new BigInteger("42") ''' assertSingleViolation(SOURCE, 2, 'new BigInteger("42")', 'Can be rewritten as 42G') } protected Rule createRule() { new UnnecessaryBigIntegerInstantiationRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000152�00000000000�011601� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryStringInstantiationRuleTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryStringInstantiationRuleTest.g0000644�0001750�0001750�00000005453�12041642704�033514� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryStringInstantiationRule * * @author Chris Mair */ class UnnecessaryStringInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryStringInstantiation' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def b1 = new String(xyz) def exception = new Exception('bad') def b2 = new String('abc') def b3 = new java.lang.String("abc") def b4 = new String('abc'.bytes) def b5 = new String( [1,2,3] as char[]) } ''' assertTwoViolations(SOURCE, 5, "new String('abc')", 6, 'new java.lang.String("abc")') } @Test void testApplyTo_WithinClosure() { final SOURCE = ''' class MyClass { def myClosure = { def b2 = new String('abc') } } ''' assertSingleViolation(SOURCE, 4, "new String('abc')", 'There is typically no need to call the String constructor') } @Test void testApplyTo_Violation_NotWithinClass() { final SOURCE = ''' def b1 = new java.lang.String('abc') def name2 = "abc" void calculate() { String name = 'defghi' def b1 = new String(""" xxx """) def str = new StringBuffer() } ''' assertTwoViolations(SOURCE, 2, "new java.lang.String('abc')", 6, 'new String(') } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { def b = new String(myBytes) } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryStringInstantiationRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000153�00000000000�011602� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryFinalOnPrivateMethodRuleTest.groovy����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryFinalOnPrivateMethodRuleTest.0000644�0001750�0001750�00000003207�12041642704�033347� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryFinalOnPrivateMethodRule * * @author Hamlet D'Arcy */ class UnnecessaryFinalOnPrivateMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryFinalOnPrivateMethod' } @Test void testSuccessScenario() { final SOURCE = ''' final method1() {} private method2() {} protected final method2() {} ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' private final method() {} ''' assertSingleViolation(SOURCE, 2, 'private final method()', "The 'method' method is both private and final") } protected Rule createRule() { new UnnecessaryFinalOnPrivateMethodRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000156�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryBigDecimalInstantiationRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryBigDecimalInstantiationRuleTe0000644�0001750�0001750�00000005367�12041642704�033436� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryBigDecimalInstantiationRule * * @author Hamlet D'Arcy */ class UnnecessaryBigDecimalInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryBigDecimalInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' assert 42G == foo() assert 42G == new BigDecimal([] as char[]) assert 42.10 == new BigDecimal("42.10", 10) ''' assertNoViolations(SOURCE) } @Test void testStringConstructor_Decimal() { final SOURCE = ''' new BigDecimal("42.10") ''' assertSingleViolation(SOURCE, 2, 'new BigDecimal("42.10")', 'Can be rewritten as 42.10 or 42.10G') } @Test void testStringConstructor_Integer() { final SOURCE = ''' new BigDecimal("42") ''' assertNoViolations(SOURCE) } @Test void testDoubleConstructor() { final SOURCE = ''' new BigDecimal(42.10d) ''' assertSingleViolation(SOURCE, 2, 'new BigDecimal(42.10d)', 'Can be rewritten as 42.1 or 42.1G') } @Test void testIntConstructor() { final SOURCE = ''' new BigDecimal(42i) new BigDecimal(42) ''' assertNoViolations(SOURCE) } @Test void testLongConstructor() { final SOURCE = ''' new BigDecimal(42L) ''' assertNoViolations(SOURCE) } @Test void testStaticField() { final SOURCE = ''' class MyClass { static final BigDecimal ZERO = new BigDecimal('0.5') } ''' assertSingleViolation(SOURCE, 3, "static final BigDecimal ZERO = new BigDecimal('0.5')") } protected Rule createRule() { new UnnecessaryBigDecimalInstantiationRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryGStringRuleTest.groovy�������0000644�0001750�0001750�00000006272�12041642704�032155� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryGStringRule * * @author 'Hamlet D'Arcy' */ class UnnecessaryGStringRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryGString' } @Test void testSimpleCase() { final SOURCE = ''' def docFile = "src/site/apt/codenarc-rules-${ruleSetName}.apt" ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario() { final SOURCE = ''' // OK def g = """ I am a \\$ string """ ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario0() { final SOURCE = ''' def h = """ I am a $string """ ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario1() { final SOURCE = ''' def i = 'i am a string' ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario2() { final SOURCE = """ def j = '''i am a string ''' """ assertNoViolations(SOURCE) } @Test void testSuccessScenario3() { final SOURCE = ''' def c = "I am a ' string" // OK def d = """I am a ' string""" // OK def e = """I am a ' string""" // OK def f = "I am a \\$ string" // OK ''' assertNoViolations(SOURCE) } @Test void testDoubleQuotes() { final SOURCE = ''' def a = "I am a string" // violation ''' assertSingleViolation(SOURCE, 2, '"I am a string"', 'The String \'I am a string\' can be wrapped in single quotes instead of double quotes') } @Test void testMultiline() { final SOURCE = ''' def a = """ I am a string """ // violation ''' assertSingleViolation(SOURCE, 2, 'def a = """', """The String ' I am a string ' can be wrapped in single quotes instead of double quotes""") } @Test void testDoubleViolations() { final SOURCE = ''' class Person { def name = "Hamlet" } ''' assertSingleViolation(SOURCE, 3, 'def name = "Hamlet"') } protected Rule createRule() { new UnnecessaryGStringRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000151�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryFloatInstantiationRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryFloatInstantiationRuleTest.gr0000644�0001750�0001750�00000004107�12041642704�033470� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryFloatInstantiationRule * * @author Hamlet D'Arcy */ class UnnecessaryFloatInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryFloatInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' assert 0.42f == foo() assert 0.42f == new Float([] as char[]) assert 42.10f == new Float("42.10", 10) ''' assertNoViolations(SOURCE) } @Test void testStringConstructor() { final SOURCE = ''' new Float("42.10") ''' assertSingleViolation(SOURCE, 2, 'new Float("42.10")', 'Can be rewritten as 42.10f') } @Test void testDoubleConstructor() { final SOURCE = ''' new Float(42.10d) ''' assertSingleViolation(SOURCE, 2, 'new Float(42.10d)', 'Can be rewritten as 42.1f') } @Test void testFloatConstructor() { final SOURCE = ''' new Float(42.10f) ''' assertSingleViolation(SOURCE, 2, 'new Float(42.10f)', 'Can be rewritten as 42.1f') } protected Rule createRule() { new UnnecessaryFloatInstantiationRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000152�00000000000�011601� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDoubleInstantiationRuleTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDoubleInstantiationRuleTest.g0000644�0001750�0001750�00000003566�12041642704�033463� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryDoubleInstantiationRule * * @author Hamlet D'Arcy */ class UnnecessaryDoubleInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryDoubleInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' assert 0.42d == foo() assert 0.42d == new Double([] as char[]) assert 42.10d == new Double("42.10", 10) ''' assertNoViolations(SOURCE) } @Test void testStringConstructor() { final SOURCE = ''' new Double("42.10") ''' assertSingleViolation(SOURCE, 2, 'new Double("42.10")', 'Can be rewritten as 42.10d') } @Test void testDoubleConstructor() { final SOURCE = ''' new Double(42.10d) ''' assertSingleViolation(SOURCE, 2, 'new Double(42.10d)', 'Can be rewritten as 42.1d') } protected Rule createRule() { new UnnecessaryDoubleInstantiationRule() } } ������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000160�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryNullCheckBeforeInstanceOfRuleTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryNullCheckBeforeInstanceOfRule0000644�0001750�0001750�00000007065�12041642704�033362� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryNullCheckBeforeInstanceOfRule * * @author 'Hamlet D'Arcy' * @author Chris Mair */ class UnnecessaryNullCheckBeforeInstanceOfRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryNullCheckBeforeInstanceOf' } @Test void testSuccessScenario() { final SOURCE = ''' if (x instanceof MyClass) { } if (x instanceof MyClass) { } else if (x instanceof OtherClass) {} (x instanceof MyClass) ? foo : bar if (x != null && y instanceof MyClass) { } // different references ''' assertNoViolations(SOURCE) } @Test void testIfStatement() { final SOURCE = ''' if (x != null && x instanceof MyClass) { } ''' assertSingleViolation(SOURCE, 2, '(x != null && x instanceof MyClass)', 'The condition ((x != null) && (x instanceof MyClass)) can be safely simplified to (x instanceof MyClass)') } @Test void testElseIfStatement() { final SOURCE = ''' if (foo) {} else if (x != null && x instanceof MyClass) { } ''' assertSingleViolation(SOURCE, 2, '(x != null && x instanceof MyClass)', 'The condition ((x != null) && (x instanceof MyClass)) can be safely simplified to (x instanceof MyClass)') } @Test void testTernaryStatement() { final SOURCE = ''' (x != null && x instanceof MyClass) ? foo : bar ''' assertSingleViolation(SOURCE, 2, '(x != null && x instanceof MyClass)', 'The condition ((x != null) && (x instanceof MyClass)) can be safely simplified to (x instanceof MyClass)') } @Test void testTernaryStatementSwappedOrder() { final SOURCE = ''' (x instanceof MyClass && x != null) ? foo : bar ''' assertSingleViolation(SOURCE, 2, '(x instanceof MyClass && x != null)', 'The condition ((x instanceof MyClass) && (x != null)) can be safely simplified to (x instanceof MyClass)') } @Test void testStandaloneBinaryExpression() { final SOURCE = ''' boolean equals(Object object) { object != null && object instanceof RequestKey } ''' assertSingleViolation(SOURCE, 3, 'object != null && object instanceof RequestKey', 'The condition ((object != null) && (object instanceof RequestKey)) can be safely simplified to (object instanceof RequestKey)') } protected Rule createRule() { new UnnecessaryNullCheckBeforeInstanceOfRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryPackageReferenceRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryPackageReferenceRuleTest.groo0000644�0001750�0001750�00000026510�12314144331�033364� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.codenarc.util.GroovyVersion import org.junit.Test /** * Tests for UnnecessaryPackageReferenceRule * * @author Chris Mair */ class UnnecessaryPackageReferenceRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryPackageReference' } @Test void testNoViolations() { final SOURCE = ''' class MyClass { Map myMap = [:] def dateFormat = java.text.SimpleDateFormat('MM') Integer calculate(javax.sql.DataSource dataSource) { } java.lang.annotation.RetentionPolicy getRetentionPolicy() { } } ''' assertNoViolations(SOURCE) } @Test void testFieldsTypes_Violations() { final SOURCE = ''' class MyClass { java.math.BigDecimal amount = 42.10 java.lang.Integer count = 0 java.util.Map mapping def noViolation boolean noViolationBooleanAutoBox = false } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'java.math.BigDecimal amount = 42.10', messageText:'java.math'], [lineNumber:4, sourceLineText:'java.lang.Integer count = 0', messageText:'java.lang'], [lineNumber:5, sourceLineText:'java.util.Map mapping', messageText:'java.util'] ) } @Test void testWithinExpressions_Violations() { final SOURCE = ''' if (value.class == java.math.BigDecimal) { } println "isClosure=${value instanceof groovy.lang.Closure}" def processors = java.lang.Runtime.availableProcessors() ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (value.class == java.math.BigDecimal) { }', messageText:'java.math'], [lineNumber:3, sourceLineText:'println "isClosure=${value instanceof groovy.lang.Closure}"', messageText:'groovy.lang'], [lineNumber:4, sourceLineText:'def processors = java.lang.Runtime.availableProcessors()', messageText:'java.lang'] ) } @Test void testConstructorCalls_Violations() { final SOURCE = ''' class MyClass { def amount = new java.math.BigDecimal('42.10') def url = new java.net.URL('http://abc@example.com') } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:"def amount = new java.math.BigDecimal('42.10')", messageText:'java.math'], [lineNumber:4, sourceLineText:"def url = new java.net.URL('http://abc@example.com')", messageText:'java.net'] ) } @Test void testConstructorCall_CallToSuper_NoViolation() { final SOURCE = ''' class MyClass extends Object { MyClass() { super('and') } } ''' assertNoViolations(SOURCE) } @Test void testConstructorCall_CallToThis_NoViolation() { final SOURCE = ''' class MyClass { private String name MyClass() { this('Default') } private MyClass(String name) { this.name = name } } ''' assertNoViolations(SOURCE) } @Test void testVariableTypes_Violations() { final SOURCE = ''' void doSomething() { java.math.BigInteger maxValue = 0 java.net.URI uri groovy.lang.Closure closure = { println 'ok' } def noViolation = 123 boolean noViolationBooleanAutoBox = false int noViolationInegertAutoBox = 99 long noViolationLongAutoBox = 999999L } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'java.math.BigInteger maxValue = 0', messageText:'java.math'], [lineNumber:4, sourceLineText:'java.net.URI uri', messageText:'java.net'], [lineNumber:5, sourceLineText:"groovy.lang.Closure closure = { println 'ok' }", messageText:'groovy.lang'] ) } @Test void testMethodReturnTypes_Violations() { final SOURCE = ''' java.net.Socket getSocket() { } java.io.Reader getReader() { } groovy.util.AntBuilder getAntBuilder() { } def noViolation() { } int noViolationIntegerAutoBox() { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'java.net.Socket getSocket() { }', messageText:'java.net'], [lineNumber:3, sourceLineText:'java.io.Reader getReader() { }', messageText:'java.io'], [lineNumber:4, sourceLineText:'groovy.util.AntBuilder getAntBuilder() { }', messageText:'groovy.util'] ) } @Test void testMethodParameterTypes_Violations() { final SOURCE = ''' void writeCount(java.io.Writer writer, int count) { } void initializeBinding(String name, groovy.lang.Binding binding) { } void noViolation(def name, int intAutoBox) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'void writeCount(java.io.Writer writer, int count)', messageText:'java.io'], [lineNumber:3, sourceLineText:'void initializeBinding(String name, groovy.lang.Binding binding) { }', messageText:'groovy.lang'] ) } @Test void testClosureParameterTypes_Violations() { final SOURCE = ''' def writeCount = { java.io.Writer writer, int count -> } def initializeBinding = { String name, groovy.lang.Binding binding -> } def noViolation = { name, binding, int count -> } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def writeCount = { java.io.Writer writer, int count -> }', messageText:'java.io'], [lineNumber:3, sourceLineText:'def initializeBinding = { String name, groovy.lang.Binding binding -> }', messageText:'groovy.lang'] ) } @Test void testExtendsSuperclassOrSuperInterfaceTypes_Violations() { final SOURCE = ''' class MyHashMap extends java.util.HashMap { } interface MyList extends java.util.List { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyHashMap extends java.util.HashMap { }', messageText:'java.util'], [lineNumber:3, sourceLineText:'interface MyList extends java.util.List { }', messageText:'java.util'] ) } @Test void testExplicitlyExtendJavaLangObject_KnownLimitation_NoViolations() { final SOURCE = ''' class MyClass extends java.lang.Object { } ''' // Known limitation assertNoViolations(SOURCE) } @Test void testImplementsInterfaceTypes_Violations() { final SOURCE = ''' class MyList implements java.util.List { } class MyRange implements groovy.lang.Range { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyList implements java.util.List { }', messageText:'java.util'], [lineNumber:3, sourceLineText:'class MyRange implements groovy.lang.Range { }', messageText:'groovy.lang'] ) } @Test void testAsType_Violations() { final SOURCE = ''' class MyClass { def runnable = [:] as java.lang.Runnable def string = (java.lang.String)123 } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'def runnable = [:] as java.lang.Runnable', messageText:'java.lang'], [lineNumber:4, sourceLineText:'def string = (java.lang.String)123', messageText:'java.lang']) } @Test void testAnonymousInnerClassDeclaration_KnownLimitation_NoViolation() { final SOURCE = ''' def runnable = new java.lang.Runnable() { void run() { } } ''' if (GroovyVersion.groovy1_8_OrGreater ) { assertSingleViolation(SOURCE, 2, 'java.lang.Runnable') } else { // Known limitation: Does not check anonymous inner class violations assertNoViolations(SOURCE) } } @Test void testPackageReferencesForExplicitlyImportedClasses_Violations() { final SOURCE = ''' import javax.servlet.http.Cookie import javax.sql.DataSource import com.example.OtherClass class MyClass { void doStuff(javax.servlet.http.Cookie cookie, Cookie[] cookies) { def dataSource = [:] as javax.sql.DataSource DataSource dataSource2 = wrap(dataSource) } } ''' assertViolations(SOURCE, [lineNumber:7, sourceLineText:'void doStuff(javax.servlet.http.Cookie cookie, Cookie[] cookies)', messageText:'javax.servlet.http.Cookie'], [lineNumber:8, sourceLineText:'def dataSource = [:] as javax.sql.DataSource', messageText:'javax.sql.DataSource'] ) } @Test void testPackageReferencesForStarImports_Violations() { final SOURCE = ''' import javax.servlet.http.* import javax.sql.* import com.example.OtherClass class MyClass { void doStuff(javax.servlet.http.Cookie cookie, Cookie[] cookies) { def dataSource = new javax.sql.DataSource() DataSource dataSource2 = wrap(dataSource) } } ''' assertViolations(SOURCE, [lineNumber:7, sourceLineText:'void doStuff(javax.servlet.http.Cookie cookie, Cookie[] cookies)', messageText:'javax.servlet.http.Cookie'], [lineNumber:8, sourceLineText:'def dataSource = new javax.sql.DataSource()', messageText:'javax.sql.DataSource'] ) } @Test void testEnums() { final SOURCE = ''' package com.company.payment enum PaymentStatus { APPROVED, REJECTED, CANCELLED, UNDETERMINED} ''' assertNoViolations(SOURCE) } @Test void testScripts() { final SOURCE = ''' package com.example println 'hello' ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryPackageReferenceRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstanceOfCheckRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstanceOfCheckRuleTest.groov0000644�0001750�0001750�00000004736�12041642704�033401� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryInstanceOfCheckRule * * @author Hamlet D'Arcy */ class UnnecessaryInstanceOfCheckRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryInstanceOfCheck' } @Test void testSuccessScenario() { final SOURCE = ''' if (!(variable instanceof String)) { /* */ } def x = !(variable instanceof String) def y = variable instanceof String ''' assertNoViolations(SOURCE) } @Test void testDeclaration() { final SOURCE = ''' def x = !variable instanceof String ''' assertSingleViolation(SOURCE, 2, '!variable instanceof String', "The result of '!(variable)' will never be a String") } @Test void testDeclaration2() { final SOURCE = ''' def x = !variable instanceof Boolean ''' assertSingleViolation(SOURCE, 2, '!variable instanceof Boolean', "The result of '!(variable)' will always be a Boolean") } @Test void testIfStatement() { final SOURCE = ''' if (!var instanceof Integer) { /* */ } ''' assertSingleViolation(SOURCE, 2, '!var instanceof Integer', "The result of '!(var)' will never be a Integer") } @Test void testIfStatement2() { final SOURCE = ''' if (!var instanceof Boolean) { /* */ } ''' assertSingleViolation(SOURCE, 2, '!var instanceof Boolean', "The result of '!(var)' will always be a Boolean") } protected Rule createRule() { new UnnecessaryInstanceOfCheckRule() } } ����������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000155�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessarySafeNavigationOperatorRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessarySafeNavigationOperatorRuleTes0000644�0001750�0001750�00000014003�12416510754�033476� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for UnnecessarySafeNavigationOperatorRule * * @author Chris Mair */ class UnnecessarySafeNavigationOperatorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessarySafeNavigationOperator' } @Test void testNoViolations() { final SOURCE = ''' def myMethod() { x?.toString() x?.y?.z this.name 123.class [1].size() [:].class [abc:123].size() } ''' assertNoViolations(SOURCE) } @Test void testSafeNavigationOperator_PropertyAccess_Violations() { final SOURCE = ''' def myMethod() { "abc"?.bytes [1,2]?.name [abc:123]?.name [:]?.name 123?.class 123.45?.class Boolean.FALSE?.class Boolean.TRUE?.class this?.class super?.class new Long(0)?.class } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'"abc"?.bytes', messageText:'The safe navigation operator (?.) is unnecessary for "abc" in class None'], [lineNumber:4, sourceLineText:'[1,2]?.name', messageText:'The safe navigation operator (?.) is unnecessary for "[1, 2]" in class None'], [lineNumber:5, sourceLineText:'[abc:123]?.name', messageText:'The safe navigation operator (?.) is unnecessary for "[abc:123]" in class None'], [lineNumber:6, sourceLineText:'[:]?.name', messageText:'The safe navigation operator (?.) is unnecessary for'], // Older versions of Groovy show [] instead of [:] [lineNumber:7, sourceLineText:'123?.class', messageText:'The safe navigation operator (?.) is unnecessary for "123" in class None'], [lineNumber:8, sourceLineText:'123.45?.class', messageText:'The safe navigation operator (?.) is unnecessary for "123.45" in class None'], [lineNumber:9, sourceLineText:'Boolean.FALSE?.class', messageText:'The safe navigation operator (?.) is unnecessary for "Boolean.FALSE" in class None'], [lineNumber:10, sourceLineText:'Boolean.TRUE?.class', messageText:'The safe navigation operator (?.) is unnecessary for "Boolean.TRUE" in class None'], [lineNumber:11, sourceLineText:'this?.class', messageText:'The safe navigation operator (?.) is unnecessary for "this" in class None'], [lineNumber:12, sourceLineText:'super?.class', messageText:'The safe navigation operator (?.) is unnecessary for "super" in class None'], [lineNumber:13, sourceLineText:'new Long(0)?.class', messageText:'The safe navigation operator (?.) is unnecessary for "new Long(0)" in class None'], ) } @Test void testSafeNavigationOperator_MethodCall_Violations() { final SOURCE = ''' def myMethod() { "abc"?.toString() [1,2]?.toString() [abc:123]?.toString() [:]?.toString() 123?.getClass() 123.45?.getClass() Boolean.FALSE?.getClass() Boolean.TRUE?.getClass() this?.getClass() super?.getClass() new Long(100)?.toString() } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'"abc"?.toString()', messageText:'The safe navigation operator (?.) is unnecessary for "abc" in class None'], [lineNumber:4, sourceLineText:'[1,2]?.toString()', messageText:'The safe navigation operator (?.) is unnecessary for "[1, 2]" in class None'], [lineNumber:5, sourceLineText:'[abc:123]?.toString()', messageText:'The safe navigation operator (?.) is unnecessary for "[abc:123]" in class None'], [lineNumber:6, sourceLineText:'[:]?.toString()', messageText:'The safe navigation operator (?.) is unnecessary for'], // Older versions of Groovy show [] instead of [:] [lineNumber:7, sourceLineText:'123?.getClass()', messageText:'The safe navigation operator (?.) is unnecessary for "123" in class None'], [lineNumber:8, sourceLineText:'123.45?.getClass()', messageText:'The safe navigation operator (?.) is unnecessary for "123.45" in class None'], [lineNumber:9, sourceLineText:'Boolean.FALSE?.getClass()', messageText:'The safe navigation operator (?.) is unnecessary for "Boolean.FALSE" in class None'], [lineNumber:10, sourceLineText:'Boolean.TRUE?.getClass()', messageText:'The safe navigation operator (?.) is unnecessary for "Boolean.TRUE" in class None'], [lineNumber:11, sourceLineText:'this?.getClass()', messageText:'The safe navigation operator (?.) is unnecessary for "this" in class None'], [lineNumber:12, sourceLineText:'super?.getClass()', messageText:'The safe navigation operator (?.) is unnecessary for "super" in class None'], [lineNumber:13, sourceLineText:'new Long(100)?.toString()', messageText:'The safe navigation operator (?.) is unnecessary for "new Long(100)" in class None'], ) } protected Rule createRule() { new UnnecessarySafeNavigationOperatorRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000172�00000000000�011603� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryParenthesesForMethodCallWithClosureRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryParenthesesForMethodCallWithC0000644�0001750�0001750�00000006201�12041642704�033400� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryParenthesesForMethodCallWithClosureRule * * @author Marcin Erdmann */ class UnnecessaryParenthesesForMethodCallWithClosureRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryParenthesesForMethodCallWithClosure' } @Test void testSuccessScenario() { final SOURCE = ''' [1, 2, 3].each { println it } [1, 2, 3].collect { it * 2 }.any { it > 5 } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario2() { final SOURCE = ''' (1..10).inject(0) { acc, count -> if (delegate."msn$count"?.length() > 0) { acc++ } acc } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' [1,2,3].each() { println it } ''' assertSingleViolation(SOURCE, 2, '[1,2,3].each() { println it }', "Parentheses in the 'each' method call are unnecessary and can be removed.") } @Test void testTwoViolations() { final SOURCE = ''' [1, 2, 3].collect() { it * 2 }.any ( ) { it > 5 } ''' assertTwoViolations(SOURCE, 2, '''[1, 2, 3].collect() {''', 2, '''[1, 2, 3].collect() {''') // todo: replace violation line number and message } @Test void testSyntheticMethodCall() { final SOURCE = ''' dependencies { testCompile "org.springframework:spring-test:$springVersion", ( 'org.spockframework:spock-core:0.5-groovy-1.8' ) { exclude group: 'org.codehaus.groovy' } } ''' assertNoViolations(SOURCE) } @Test void testNonDetectableViolations() { final SOURCE = ''' [1, 2, 3].each(/*comment*/) { println it } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryParenthesesForMethodCallWithClosureRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryCatchBlockRuleTest.groovy����0000644�0001750�0001750�00000004471�12041642704�032574� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryCatchBlockRule * * @author Hamlet D'Arcy */ class UnnecessaryCatchBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryCatchBlock' } @Test void testSuccessScenario() { final SOURCE = ''' try { foo() } catch (Exception e) { throw new RuntimeException(e) } try { foo() } catch (IOException e1) { throw e1 } catch (Exception e2) { throw new RuntimeException(e2) } ''' assertNoViolations(SOURCE) } @Test void testSingleCatchBlock() { final SOURCE = ''' try { foo() } catch (Exception e) { throw e } ''' assertSingleViolation(SOURCE, 4, 'catch (Exception e)', 'Catch statement can probably be removed') } @Test void testMultipleCatchBlocks() { final SOURCE = ''' try { foo() } catch (IOException e1) { throw e1 } catch (Exception e2) { throw e2 } ''' assertTwoViolations(SOURCE, 4, 'catch (IOException e1)', 6, 'catch (Exception e2)') } protected Rule createRule() { new UnnecessaryCatchBlockRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000153�00000000000�011602� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryIntegerInstantiationRuleTest.groovy����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryIntegerInstantiationRuleTest.0000644�0001750�0001750�00000003554�12041642704�033474� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryIntegerInstantiationRule * * @author Hamlet D'Arcy */ class UnnecessaryIntegerInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryIntegerInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' assert 42i == foo() assert 42I == new Integer([] as char[]) assert 42i == new Integer("42", 10) ''' assertNoViolations(SOURCE) } @Test void testStringConstructor() { final SOURCE = ''' new Integer("42") ''' assertSingleViolation(SOURCE, 2, 'new Integer("42")', 'Can be rewritten as 42 or 42i') } @Test void testIntConstructor() { final SOURCE = ''' new Integer(42) ''' assertSingleViolation(SOURCE, 2, 'new Integer(42)', 'Can be rewritten as 42 or 42i') } protected Rule createRule() { new UnnecessaryIntegerInstantiationRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryPublicModifierRuleTest.groovy0000644�0001750�0001750�00000007602�12041642704�033473� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.apache.log4j.Level import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.captureLog4JMessages /** * Tests for UnnecessaryPublicModifierRule * * @author Hamlet D'Arcy */ class UnnecessaryPublicModifierRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryPublicModifier' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { void myMethod() {} public String field } class publicClass { void publicMyMethod() {} public String field } ''' assertNoViolations(SOURCE) } @Test void testClass0() { final SOURCE = '''public class MyClass { } ''' assertSingleViolation(SOURCE, 1, 'public class MyClass', 'The public keyword is unnecessary for classes') } @Test void testClass() { final SOURCE = ''' public class MyClass { } ''' assertSingleViolation(SOURCE, 2, 'public class MyClass', 'The public keyword is unnecessary for classes') } @Test void testClassSplit() { final SOURCE = ''' public class MyClass { } ''' assertSingleViolation(SOURCE, 2, 'public', 'The public keyword is unnecessary for classes') } @Test void testClassSplit2() { final SOURCE = '''public class MyClass { } ''' assertSingleViolation(SOURCE, 1, 'public', 'The public keyword is unnecessary for classes') } @Test void testMethodSplit() { final SOURCE = ''' class MyClass { public void myMethod() {} } ''' assertSingleViolation(SOURCE, 3, 'public', 'The public keyword is unnecessary for methods') } @Test void testMethod() { final SOURCE = ''' class MyClass { public void myMethod() {} } ''' assertSingleViolation(SOURCE, 3, 'public void myMethod()', 'The public keyword is unnecessary for methods') } @Test void testConstructor() { final SOURCE = ''' class MyClass { public MyClass() {} } ''' assertSingleViolation(SOURCE, 3, 'public MyClass() {}', 'The public keyword is unnecessary for constructors') } @Test void testGantScript() { final SOURCE = ''' includeTargets << grailsScript("_GrailsClean") setDefaultTarget("cleanAll") ''' def logMessages = captureLog4JMessages { assertNoViolations(SOURCE) } log('Messages=' + logMessages?.message) def warnMessages = logMessages.findAll { it.level == Level.WARN } assert warnMessages.empty } protected Rule createRule() { new UnnecessaryPublicModifierRule() } } ������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000154�00000000000�011603� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInFieldDeclarationRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInFieldDeclarationRuleTest0000644�0001750�0001750�00000014367�12141066466�033365� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryDefInFieldDeclarationRule * * @author Hamlet D'Arcy */ class UnnecessaryDefInFieldDeclarationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryDefInFieldDeclaration' } /* * Success scenarios */ @Test void testSuccessScenario_modifiers() { final SOURCE = ''' class MyClass { def field1 = { } private field2 = { } protected field3 = { } public field4 = { } static field5 = { } final field6 = { } strictfp field7 = { } } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_fieldNamesContainingModifierNames() { final SOURCE = ''' class MyClass { def privateField = { } def protectedField = { } def publicField = { } def staticField = { } def finalField = { } def synchronizedField = { } def strictfpField = { } def abstractField = { } } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_types() { final SOURCE = ''' class MyClass { Object field1 = {} String field2 = {} int field3 = {} void field4 = {} } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_defAfterAssignment() { final SOURCE = ''' class SampleTest { private static final String SOURCE_SHARED_BETWEEN_TESTS = \'\'\' def sum = 1 + 1 \'\'\' } ''' assertNoViolations(SOURCE) } /* * Violations */ @Test void testViolation_defAndPrivate() { final SOURCE = ''' class MyClass { def private field = {} } ''' assertSingleViolation(SOURCE, 3, 'def private field', 'The def keyword is unneeded when a field is marked private') } @Test void testViolation_defAndProtected() { final SOURCE = ''' class MyClass { def protected field = {} } ''' assertSingleViolation(SOURCE, 3, 'def protected field', 'The def keyword is unneeded when a field is marked protected') } @Test void testViolation_defAndPublic() { final SOURCE = ''' class MyClass { def public field = {} } ''' assertSingleViolation(SOURCE, 3, 'def public field', 'The def keyword is unneeded when a field is marked public') } @Test void testViolation_defAndStatic() { final SOURCE = ''' class MyClass { def static field = {} } ''' assertSingleViolation(SOURCE, 3, 'def static field', 'The def keyword is unneeded when a field is marked static') } @Test void testViolation_defAndFinal() { final SOURCE = ''' class MyClass { def final field = {} } ''' assertSingleViolation(SOURCE, 3, 'def final field', 'The def keyword is unneeded when a field is marked final') } @Test void testViolation_defAndTyped() { final SOURCE = ''' class MyClass { def String field = '' } ''' assertSingleViolation(SOURCE, 3, 'def String field', 'The def keyword is unneeded when a field type is specified') } @Test void testViolation_defAndStrictfp() { final SOURCE = ''' class MyClass { def strictfp field = { } } ''' assertSingleViolation(SOURCE, 3, 'def strictfp field', 'The def keyword is unneeded when a field is marked strictfp') } @Test void testViolation_defAndObjectType() { final SOURCE = ''' class MyClass { def Object field = {} } ''' assertSingleViolation(SOURCE, 3, 'def Object field', 'The def keyword is unneeded when a field is specified Object type') } @Test void testViolation_fieldDeclarationAcrossMultipleLines() { final SOURCE = ''' class MyClass { def static String field = { } } ''' assertSingleViolation(SOURCE, 3, 'def', 'The def keyword is unneeded when a field is marked static') } @Test void testViolation_multipleFieldsOnSingleLine() { final SOURCE = ''' class MyClass { def field1 = { 'good' }; def public field2 = { 'bad' } def public field3 = { 'bad' }; def field4 = { 'good' } } ''' assertTwoViolations(SOURCE, 3, 'def public field2', 'The def keyword is unneeded when a field is marked public', 4, 'def public field3', 'The def keyword is unneeded when a field is marked public') } protected Rule createRule() { new UnnecessaryDefInFieldDeclarationRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000151�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryCallForLastElementRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryCallForLastElementRuleTest.gr0000644�0001750�0001750�00000006504�12041642704�033341� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryCallForLastElementRule * * @author Hamlet D'Arcy */ class UnnecessaryCallForLastElementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryCallForLastElement' } @Test void testSuccessScenario() { final SOURCE = ''' def x = [0, 1, 2] def a = x.last() def b = x[-1] def c = x.getAt(-1) def d = x.get(z.size() -1) // different objects def e = x.get(z.length -1) // different objects def f = x.getAt(z.size() -1) // different objects x.get(x.size() - 2) x.get(x.length - 2) ''' assertNoViolations(SOURCE) } @Test void testGetAccessList() { final SOURCE = ''' x.get(x.size() - 1) ''' assertSingleViolation SOURCE, 2, 'x.get(x.size() - 1)', 'Unnecessarily complex access of last element. This can be simplified to x.last() or x[-1]' } @Test void testGetAccessArray() { final SOURCE = ''' x.get(x.length - 1) ''' assertSingleViolation SOURCE, 2, 'x.get(x.length - 1)', 'Unnecessarily complex access of last element. This can be simplified to x.last() or x[-1]' } @Test void testGetAtAccessList() { final SOURCE = ''' x.getAt(x.size() - 1) ''' assertSingleViolation SOURCE, 2, 'x.getAt(x.size() - 1)', 'Unnecessarily complex access of last element. This can be simplified to x.last() or x[-1]' } @Test void testGetAtAccessArray() { final SOURCE = ''' x.getAt(x.length -1) ''' assertSingleViolation SOURCE, 2, 'x.getAt(x.length -1)', 'Unnecessarily complex access of last element. This can be simplified to x.last() or x[-1]' } @Test void testArrayStyleAccess() { final SOURCE = ''' x[x.size() -1] x[x.length -1] ''' assertTwoViolations SOURCE, 2, 'x[x.size() -1]', 'Unnecessarily complex access of last element. This can be simplified to x.last() or x[-1]', 3, 'x[x.length -1]', 'Unnecessarily complex access of last element. This can be simplified to x.last() or x[-1]' } protected Rule createRule() { new UnnecessaryCallForLastElementRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000155�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInMethodDeclarationRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryDefInMethodDeclarationRuleTes0000644�0001750�0001750�00000020112�12304446161�033352� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryDefInMethodDeclarationRule * * @author Hamlet D'Arcy */ class UnnecessaryDefInMethodDeclarationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryDefInMethodDeclaration' } /* * Success scenarios */ @Test void testSuccessScenario_modifiers() { final SOURCE = ''' String getTreeCellRendererComponent(String p1, def p2) { null } def method1() { } private method2() { } protected method3() { } public method4() { } static method5() { } final method6() { } synchronized method7() { } strictfp method8() { } class Test { abstract method() } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_generics() { final SOURCE = ''' def <T> T getService(String serviceName) { null } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_methodNamesContainingModifierNames_beginOfMethodName() { final SOURCE = ''' def privateMethod() { } def protectedMethod() { } def publicMethod() { } def staticMethod() { } def finalMethod() { } def synchronizedMethod() { } def strictfpMethod() { } def abstractMethod() { } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_methodNamesContainingModifierNames_insideMethodName_singleQuotes() { final SOURCE = ''' def 'modifier private inside method name'() { } def 'modifier protected inside method name'() { } def 'modifier public inside method name'() { } def 'modifier static inside method name'() { } def 'modifier final inside method name'() { } def 'modifier synchronized inside method name'() { } def 'modifier strictfp inside method name'() { } def 'modifier abstract inside method name'() { } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_methodNamesContainingModifierNames_insideMethodName_doubleQuotes() { final SOURCE = ''' def "modifier private inside method name"() { } def "modifier protected inside method name"() { } def "modifier public inside method name"() { } def "modifier static inside method name"() { } def "modifier final inside method name"() { } def "modifier synchronized inside method name"() { } def "modifier strictfp inside method name"() { } def "modifier abstract inside method name"() { } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario_types() { final SOURCE = ''' Object method1() { null } String method2() { null } int method3() { 1 } void method4() { } ''' assertNoViolations(SOURCE) } /* * Violations */ @Test void testViolation_defInConstructor() { final SOURCE = ''' class MyClass { def MyClass() {} } ''' assertSingleViolation(SOURCE, 3, 'def MyClass()', 'Violation in class MyClass. The def keyword is unneeded on constructors') } @Test void testViolation_defAndPrivate() { final SOURCE = ''' def private method() { } ''' assertSingleViolation(SOURCE, 2, 'def private method()', 'The def keyword is unneeded when a method is marked private') } @Test void testViolation_defAndProtected() { final SOURCE = ''' def protected method() { } ''' assertSingleViolation(SOURCE, 2, 'def protected method()', 'The def keyword is unneeded when a method is marked protected') } @Test void testViolation_defAndPublic() { final SOURCE = ''' def public method() { } ''' assertSingleViolation(SOURCE, 2, 'def public method()', 'The def keyword is unneeded when a method is marked public') } @Test void testViolation_defAndStatic() { final SOURCE = ''' def static method() { } ''' assertSingleViolation(SOURCE, 2, 'def static method()', 'The def keyword is unneeded when a method is marked static') } @Test void testViolation_defAndFinal() { final SOURCE = ''' def final method() { } ''' assertSingleViolation(SOURCE, 2, 'def final method()', 'The def keyword is unneeded when a method is marked final') } @Test void testViolation_defAndSynchronized() { final SOURCE = ''' def synchronized method() { } ''' assertSingleViolation(SOURCE, 2, 'def synchronized method()', 'The def keyword is unneeded when a method is marked synchronized') } @Test void testViolation_defAndStrictfp() { final SOURCE = ''' def strictfp method() { } ''' assertSingleViolation(SOURCE, 2, 'def strictfp method()', 'The def keyword is unneeded when a method is marked strictfp') } @Test void testViolation_defAndAbstract() { final SOURCE = ''' abstract class Test { def abstract method() } ''' assertSingleViolation(SOURCE, 3, 'def abstract method()', 'The def keyword is unneeded when a method is marked abstract') } @Test void testViolation_defAndObjectType() { final SOURCE = ''' def Object method() { null } ''' assertSingleViolation(SOURCE, 2, 'def Object method()', 'The def keyword is unneeded when a method returns the Object type') } @Test void testViolation_defAndReturnType() { final SOURCE = ''' def List method() { null } ''' assertSingleViolation(SOURCE, 2, 'def List method()', 'The def keyword is unneeded when a method specifies a return type') } @Test void testViolation_methodDeclarationAcrossMultipleLines() { final SOURCE = ''' def static String method() { } ''' assertSingleViolation(SOURCE, 2, 'def', 'The def keyword is unneeded when a method is marked static') } @Test void testViolation_multipleMethodsOnSingleLine() { final SOURCE = ''' def method1() { 'good' }; def public method2() { 'bad' } def public method3() { 'bad' }; def method4() { 'good' } ''' assertTwoViolations(SOURCE, 2, 'def public method2()', 'The def keyword is unneeded when a method is marked public', 3, 'def public method3()', 'The def keyword is unneeded when a method is marked public') } protected Rule createRule() { new UnnecessaryDefInMethodDeclarationRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000156�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstantiationToGetClassRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryInstantiationToGetClassRuleTe0000644�0001750�0001750�00000004117�12041642704�033456� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for InstantiationToGetClassRule * * @author Hamlet D'Arcy */ class UnnecessaryInstantiationToGetClassRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryInstantiationToGetClass' } @Test void testSuccessScenario() { final SOURCE = ''' Class c = String.class Class b = foo.getClass() Class c = new String().getClass(someArg) // arg means it must be valid ''' assertNoViolations(SOURCE) } @Test void testBasicViolation() { final SOURCE = ''' Class c = new String().getClass() ''' assertSingleViolation(SOURCE, 2, 'Class c = new String().getClass()', 'String instantiation with getClass() should be simplified to String.class') } @Test void testComplexViolation() { final SOURCE = ''' new String('parm').getClass() ''' assertSingleViolation(SOURCE, 2, "new String('parm').getClass()", 'String instantiation with getClass() should be simplified to String.class') } protected Rule createRule() { new UnnecessaryInstantiationToGetClassRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000152�00000000000�011601� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/ConsecutiveStringConcatenationRuleTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/ConsecutiveStringConcatenationRuleTest.g0000644�0001750�0001750�00000007215�12041642704�033443� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConsecutiveStringConcatenationRule * * @author Hamlet D'Arcy */ class ConsecutiveStringConcatenationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ConsecutiveStringConcatenation' } @Test void testSuccessScenario() { final SOURCE = ''' def a = 1 + 1 def f = 'Hello' + // OK because of line break 'World' def h = 'Hello' + null // OK because not a string def i = 'Hello' + method() // OK because not a string def j = 'Hello' - "$World" // OK because not + ''' assertNoViolations(SOURCE) } @Test void testSimpleCase() { final SOURCE = ''' def a = 'Hello' + 'World' // should be 'HelloWorld' ''' assertSingleViolation(SOURCE, 2, "'Hello' + 'World'", "String concatenation in class None can be joined into the literal 'HelloWorld") } @Test void testStringAndNumber() { final SOURCE = ''' def g = 'Hello' + 5 // should be 'Hello5' ''' assertSingleViolation(SOURCE, 2, "'Hello' + 5", "String concatenation in class None can be joined into the literal 'Hello5'") } @Test void testGStringAndString() { final SOURCE = ''' def b = "$Hello" + 'World' // should be "${Hello}World" ''' assertSingleViolation(SOURCE, 2, """"\$Hello" + 'World'""", 'String concatenation in class None can be joined into a single literal') } @Test void testStringAndGString() { final SOURCE = ''' def c = 'Hello' + "$World" // should be "Hello${World}" ''' assertSingleViolation(SOURCE, 2, """ 'Hello' + \"\$World\"""", 'String concatenation in class None can be joined into a single literal') } @Test void testStringAndMultilineString() { final SOURCE = """ def d = 'Hello' + ''' world // should be joined ''' """ assertSingleViolation(SOURCE, 2, "'Hello' +", "String concatenation in class None can be joined into the literal 'Hello\\n world // should be joined\\n '") } @Test void testMultilineStringAndString() { final SOURCE = """ class MyClass { static { def e = '''Hello ''' + 'world' // should be joined } } """ assertSingleViolation(SOURCE, 5, "+ 'world'", "String concatenation in class MyClass can be joined into the literal 'Hello\\n world'") } protected Rule createRule() { new ConsecutiveStringConcatenationRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryBooleanExpressionRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryBooleanExpressionRuleTest.gro0000644�0001750�0001750�00000015465�12041642704�033505� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryBooleanExpressionRule * * @author Chris Mair */ class UnnecessaryBooleanExpressionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryBooleanExpression' } @Test void testApplyTo_AndOr_WithTrueOrFalse_IsAViolation() { final SOURCE = ''' def ready = value && true if (value || true) { println 'ok' } def result = value && false ready = true && value if (true || value) { println 'ok' } result = false && value ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def ready = value && true'], [lineNumber:3, sourceLineText:'if (value || true) {'], [lineNumber:6, sourceLineText:'def result = value && false'], [lineNumber:8, sourceLineText:'ready = true && value'], [lineNumber:9, sourceLineText:'if (true || value)'], [lineNumber:10, sourceLineText:'result = false && value']) } @Test void testApplyTo_AndOr_WithBooleanTrueOrFalse_IsAViolation() { final SOURCE = ''' def ready = value && Boolean.TRUE if (value || Boolean.TRUE) { println 'ok' } def result = value && Boolean.FALSE ready = Boolean.TRUE && value if (Boolean.TRUE || value) { println 'ok' } result = Boolean.FALSE && value ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def ready = value && Boolean.TRUE'], [lineNumber:3, sourceLineText:'if (value || Boolean.TRUE)'], [lineNumber:6, sourceLineText:'def result = value && Boolean.FALSE'], [lineNumber:8, sourceLineText:'ready = Boolean.TRUE && value'], [lineNumber:9, sourceLineText:'if (Boolean.TRUE || value)'], [lineNumber:10, sourceLineText:'result = Boolean.FALSE && value']) } @Test void testApplyTo_AndOr_WithMapLiteral_IsAViolation() { final SOURCE = ''' result = value && [:] result = [a:123] || value ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'result = value && [:]'], [lineNumber:3, sourceLineText:'result = [a:123] || value']) } @Test void testApplyTo_AndOr_WithListLiteral_IsAViolation() { final SOURCE = ''' result = value && [] result = [x, y, z] || value ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'result = value && []'], [lineNumber:3, sourceLineText:'result = [x, y, z] || value']) } @Test void testApplyTo_AndOr_WithNumberLiteral_IsAViolation() { final SOURCE = ''' result = value && 19 result = 67.898 || value ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'result = value && 19'], [lineNumber:3, sourceLineText:'result = 67.898 || value']) } @Test void testApplyTo_AndOr_WithStringLiteral_IsAViolation() { final SOURCE = ''' result = value && "" result = 'abcdef' || value ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'result = value && ""'], [lineNumber:3, sourceLineText:"result = 'abcdef' || value"]) } @Test void testApplyTo_AndOr_WithNull_IsAViolation() { final SOURCE = ''' result = value && null result = null || value ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'result = value && null'], [lineNumber:3, sourceLineText:'result = null || value']) } @Test void testApplyTo_AndOr_NotWithTrueOrFalse_NoViolations() { final SOURCE = ''' def ready = value && other if (value || hasElements()) { println 'ok' } def result = value && count ''' assertNoViolations(SOURCE) } @Test void testApplyTo_OtherOperators_WithTrueOrFalse_NoViolations() { final SOURCE = ''' def ready = value == true if (value != true) { println 'ok' } def result = value < false ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NegatingABoolean_IsAViolation() { final SOURCE = ''' def ready = !true if (!false) { println 'ok' } def result = value && !Boolean.FALSE println !Boolean.TRUE ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def ready = !true'], [lineNumber:3, sourceLineText:'if (!false)'], [lineNumber:4, sourceLineText:'def result = value && !Boolean.FALSE'], [lineNumber:5, sourceLineText:'println !Boolean.TRUE']) } @Test void testApplyTo_NegatingAConstantLiteral_IsAViolation() { final SOURCE = ''' def ready = !"abc" if (![]) { println 'ok' } if (![23]) { doSomething() } def result = value && ![a:123] result = !null ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def ready = !"abc"'], [lineNumber:3, sourceLineText:'if (![])'], [lineNumber:4, sourceLineText:'if (![23]) { doSomething() }'], [lineNumber:5, sourceLineText:'def result = value && ![a:123]'], [lineNumber:6, sourceLineText:'result = !null']) } @Test void testApplyTo_NegatingNonConstant_NoViolations() { final SOURCE = ''' result = !abc result = !(x || y) ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryBooleanExpressionRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryGetterRuleTest.groovy��������0000644�0001750�0001750�00000005521�12041642704�032026� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryGetterRule * * @author Hamlet D'Arcy */ class UnnecessaryGetterRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryGetter' } @Test void testSuccessScenario() { final SOURCE = ''' x.get() x.property x.first x.firstName x.a x.getnotagetter() x.getClass() x.getProperty('key') ''' assertNoViolations(SOURCE) } @Test void testTwoSimpleGetters() { final SOURCE = ''' x.getProperty() x.getPi() ''' assertTwoViolations SOURCE, 2, 'x.getProperty()', 'getProperty() can probably be rewritten as property', 3, 'x.getPi()', 'getPi() can probably be rewritten as pi' } @Test void testCamelCaseGetters() { final SOURCE = ''' x.getFirstName() ''' assertSingleViolation(SOURCE, 2, 'x.getFirstName()', 'getFirstName() can probably be rewritten as firstName') } @Test void testSingleLetterNamedGetters() { final SOURCE = ''' x.getA() ''' assertSingleViolation(SOURCE, 2, 'x.getA()', 'getA() can probably be rewritten as a') } @Test void testUpperCaseGetter1() { final SOURCE = ''' x.getURLs() ''' assertSingleViolation(SOURCE, 2, 'x.getURLs()', 'getURLs() can probably be rewritten as URLs') } @Test void testUpperCaseGetter2() { final SOURCE = ''' x.getURL() ''' assertSingleViolation(SOURCE, 2, 'x.getURL()', 'getURL() can probably be rewritten as URL') } @Test void testNonGetter() { final SOURCE = ''' def allPaths = resultsMap.keySet() ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnnecessaryGetterRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryConstructorRuleTest.groovy���0000644�0001750�0001750�00000006770�12041642704�033130� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryConstructorRule * * @author 'Tomasz Bujok' * @author Chris Mair */ class UnnecessaryConstructorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryConstructor' } @Test void testConstructors_NoViolations() { final SOURCE = ''' class MyClass { public MyClass() {} public MyClass(String text) {} class InnerClass { } } class MyUtility { private MyUtility(){ def inner = new Object() {} } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass { public MyClass() {} } ''' assertSingleViolation(SOURCE, 3, 'public MyClass() {}') } @Test void testConstructor_CallsOnlySuper_Violation() { final SOURCE = ''' class MyClass extends OtherClass { MyClass() { super() } } ''' assertSingleViolation(SOURCE, 3, 'MyClass() {') } @Test void testConstructor_CallsSuperAndDoesOtherStuff_NoViolation() { final SOURCE = ''' class MyClass extends OtherClass { MyClass() { super() doSomethingElse() } } ''' assertNoViolations(SOURCE) } @Test void testConstructor_CallsThis_NoViolation() { final SOURCE = ''' class MyClass extends OtherClass { MyClass() { this('abc') } private MyClass(String name) { println name } } ''' assertNoViolations(SOURCE) } @Test void testConstructor_NotEmpty_NoViolation() { final SOURCE = ''' class MyClass { MyClass() { println 123 } } ''' assertNoViolations(SOURCE) } @Test void testInnerClass() { final SOURCE = ''' class MyClass { static class MyInnerClass { public MyInnerClass() {} } } ''' assertSingleViolation(SOURCE, 5, 'public MyInnerClass() {}', 'The constructor can be safely deleted') } protected Rule createRule() { new UnnecessaryConstructorRule() } } ��������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unnecessary/UnnecessaryModOneRuleTest.groovy��������0000644�0001750�0001750�00000003440�12041642704�031753� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unnecessary import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryModOneRule * * @author Hamlet D'Arcy */ class UnnecessaryModOneRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryModOne' } @Test void testSuccessScenario() { final SOURCE = ''' if (exp & 1) {} // ok if (exp % 2) {} // ok ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' if (exp % 1) {} // violation if (method() % 1) {} // violation ''' assertTwoViolations(SOURCE, 2, '(exp % 1)', '(exp % 1) is guaranteed to be zero. Did you mean (exp & 1) or (exp % 2)', 3, '(method() % 1)', '(this.method() % 1) is guaranteed to be zero. Did you mean (this.method() & 1) or (this.method() % 2)') } protected Rule createRule() { new UnnecessaryModOneRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/�����������������������������������������0000755�0001750�0001750�00000000000�12623571301�023225� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAroundOperatorRuleTest.groovy�������0000644�0001750�0001750�00000026447�12461315153�032122� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAroundOperatorRule * * @author Chris Mair */ class SpaceAroundOperatorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAroundOperator' } // Tests for operators @Test void testApplyTo_Operators_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { def answer = 3 + 5 - x\t* 23 / 100 def name = fullname ? fullname + 'ME' : 'unknown' def v = fullname ? fullname + 'ME' : 'unknown' def greeting = fullname ?: 'you' def closure = { x -> println this.hashCode() } if (isFirstVisit(statement) && isStatementWithinFinally(statement)) { } list.find { statement.lineNumber in it } expression instanceof PropertyExpression && expression.objectExpression instanceof VariableExpression list << 'abc' other >> writer def moreInfo = violation.message ? violation.message : '' return expression instanceof BinaryExpression ? leftMostColumn(expression.leftExpression) : expression.columnNumber AstUtil.respondsTo(rule, 'getDescription') ? rule.description : null getResourceBundleString('htmlReport.titlePrefix') + (title ? " : $title" : '') def x = 3 + 5 23 as String } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_OperatorFollowingClosure() { final SOURCE = ''' class MyClass { def order1 = existingFunds.collect {it.fundSortOrder} ?: [] def order2 = existingFunds.collect {it.fundSortOrder} ? [1] : [2] def order3 = { 23 } << { 37} } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_UnicodeCharacterLiteral_Violation() { final SOURCE = ''' class MyClass { def mapping = myService.findAllMappings(0)?.collect { domain -> [description: countryCode?.padRight(6, '\\u00A0')+ domain.countryName] } String myString = ready ? '\\u00A0': 'error'+'99' } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'[description: countryCode?.padRight(', messageText:'The operator "+" within class MyClass is not preceded'], [lineNumber:7, sourceLineText:'String myString = ready ?', messageText:'The operator "+" within class MyClass is not preceded'], [lineNumber:7, sourceLineText:'String myString = ready ?', messageText:'The operator "+" within class MyClass is not followed']) } @Test void testApplyTo_IgnoreUnaryOperators_NoViolations() { final SOURCE = ''' doStuff(x++, y--, -x, +y, !ready, x?.name) ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreArrayOperator_NoViolations() { final SOURCE = ''' def statement = block.statements[it] ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssignmentOperationWithinDeclaration_WithoutSpace_KnownLimitation_NoViolations() { final SOURCE = ''' def x=5 ''' assertNoViolations(SOURCE) } @Test void testApplyTo_TernaryOperationWithMethodCall_WithoutSpace_KnownLimitation_NoViolations() { final SOURCE = ''' AstUtil.respondsTo(rule, 'getDescription')?rule.description: null ''' assertNoViolations(SOURCE) } @Test void testApplyTo_OperatorsWithoutSurroundingSpace_Violations() { final SOURCE = ''' class MyClass { def myMethod() { 3+ 5-x*23/ 100 list <<123 other>> writer x=99 x&& y x ||y x &y x| y } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'3+ 5-x*23/ 100', messageText:'The operator "-" within class MyClass is not preceded'], [lineNumber:4, sourceLineText:'3+ 5-x*23/ 100', messageText:'The operator "-" within class MyClass is not followed'], [lineNumber:4, sourceLineText:'3+ 5-x*23/ 100', messageText:'The operator "+" within class MyClass is not preceded'], [lineNumber:4, sourceLineText:'3+ 5-x*23/ 100', messageText:'The operator "/" within class MyClass is not preceded'], [lineNumber:4, sourceLineText:'3+ 5-x*23/ 100', messageText:'The operator "*" within class MyClass is not preceded'], [lineNumber:4, sourceLineText:'3+ 5-x*23/ 100', messageText:'The operator "*" within class MyClass is not followed'], [lineNumber:5, sourceLineText:'list <<123', messageText:'The operator "<<" within class MyClass is not followed'], [lineNumber:6, sourceLineText:'other>> writer', messageText:'The operator ">>" within class MyClass is not preceded'], [lineNumber:7, sourceLineText:'x=99', messageText:'The operator "=" within class MyClass is not preceded'], [lineNumber:7, sourceLineText:'x=99', messageText:'The operator "=" within class MyClass is not followed'], [lineNumber:8, sourceLineText:'x&& y', messageText:'The operator "&&" within class MyClass is not preceded'], [lineNumber:9, sourceLineText:'x ||y', messageText:'The operator "||" within class MyClass is not followed'], [lineNumber:10, sourceLineText:'x &y', messageText:'The operator "&" within class MyClass is not followed'], [lineNumber:11, sourceLineText:'x| y', messageText:'The operator "|" within class MyClass is not preceded']) } @Test void testApplyTo_AsOperatorWithoutSurroundingSpace_Violations() { final SOURCE = ''' class MyClass { def myMethod() { [1,2]as String { -> println 123 } as Runnable // ok { -> println 456 }as Runnable { -> println 789 }as Runnable (int)34.56 // ignored } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'[1,2]as String', messageText:'The operator "as" within class MyClass is not surrounded'], [lineNumber:6, sourceLineText:'{ -> println 456 }as', messageText:'The operator "as" within class MyClass is not surrounded'], [lineNumber:8, sourceLineText:'{ -> println 789', messageText:'The operator "as" within class MyClass is not surrounded']) } @Test void testApplyTo_TernaryOperatorsWithoutSurroundingSpace_Violations() { final SOURCE = ''' class MyClass { def myMethod() { def name = fullname?fullname + 'ME':'unknown' println name? 'yes' :'no' isEcpr? processRecords(records[0]): '' isEcpr ?processRecords(records[0]) :'' } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:"def name = fullname?fullname + 'ME':'unknown'", messageText:'The operator "?" within class MyClass is not preceded'], [lineNumber:4, sourceLineText:"def name = fullname?fullname + 'ME':'unknown'", messageText:'The operator "?" within class MyClass is not followed'], [lineNumber:4, sourceLineText:"def name = fullname?fullname + 'ME':'unknown'", messageText:'The operator ":" within class MyClass is not surrounded'], [lineNumber:5, sourceLineText:'println name?', messageText:'The operator "?" within class MyClass is not preceded'], [lineNumber:7, sourceLineText:"isEcpr? processRecords(records[0]): ''", messageText:'The operator "?" within class MyClass is not surrounded'], [lineNumber:7, sourceLineText:"isEcpr? processRecords(records[0]): ''", messageText:'The operator ":" within class MyClass is not surrounded'], [lineNumber:8, sourceLineText:"isEcpr ?processRecords(records[0]) :''", messageText:'The operator "?" within class MyClass is not surrounded'], [lineNumber:8, sourceLineText:"isEcpr ?processRecords(records[0]) :''", messageText:'The operator ":" within class MyClass is not surrounded']) } @Test void testApplyTo_ElvisOperatorsWithoutSurroundingSpace_Violations() { final SOURCE = ''' class MyClass { def myMethod() { def greeting = fullname?:'you' def f = funds.collect {it.fundSortOrder}?:[] assert model.UserID == expectedModel.UserID?:null } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:"def greeting = fullname?:'you'", messageText:'The operator "?:" within class MyClass is not preceded'], [lineNumber:4, sourceLineText:"def greeting = fullname?:'you'", messageText:'The operator "?:" within class MyClass is not followed'], [lineNumber:5, sourceLineText:'def f = funds.collect {it.fundSortOrder}?:[]', messageText:'The operator "?:" within class MyClass is not preceded'], [lineNumber:5, sourceLineText:'def f = funds.collect {it.fundSortOrder}?:[]', messageText:'The operator "?:" within class MyClass is not followed'], [lineNumber:6, sourceLineText:'assert model.UserID == expectedModel.UserID?:null', messageText:'The operator "?:" within class MyClass is not preceded'], [lineNumber:6, sourceLineText:'assert model.UserID == expectedModel.UserID?:null', messageText:'The operator "?:" within class MyClass is not followed']) } @Test void testApplyTo_Enum_NoViolations() { final SOURCE = ''' enum Day { YESTERDAY, TODAY, TOMORROW } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new SpaceAroundOperatorRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/BracesForMethodRuleTest.groovy�����������0000644�0001750�0001750�00000020315�12311373552�031176� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BracesForMethodRule * * @author <a href="mailto:geli.crick@osoco.es">Geli Crick</a> * @author Hamlet D'Arcy */ class BracesForMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BracesForMethod' } @Test void testInterfaces() { final SOURCE = ''' interface MyInterface { def method() } ''' assertNoViolations(SOURCE) } @Test void testMultilineInterfaces() { final SOURCE = ''' interface MyInterface extends OtherInterface { def method() } ''' assertNoViolations(SOURCE) } @Test void testMultiLineMethods() { final SOURCE = ''' def myMethod1(String x, String y) { } def myMethod2(String x, String y) throws Exception { } def myMethod3() throws Exception { } ''' assertNoViolations(SOURCE) } @Test void testMultilineInterfacesOverride() { final SOURCE = ''' interface MyInterface extends OtherInterface { def method() } ''' rule.sameLine = false assertNoViolations(SOURCE) } @Test void testAbstractMethods() { final SOURCE = ''' abstract class MyClass { abstract method() } ''' assertNoViolations(SOURCE) } @Test void testMultipleAnnotations() { final SOURCE = ''' @Override @SuppressWarnings('parameter') // for some reason the parameter is important and causes a failure def method() { } ''' assertNoViolations(SOURCE) } @Test void testMultipleAnnotations2() { final SOURCE = ''' @SuppressWarnings('parameter') // for some reason the parameter is important and causes a failure @Override def method() { } ''' assertNoViolations(SOURCE) } @Test void testMultipleAnnotations3() { final SOURCE = ''' @Override @SuppressWarnings def method() { } ''' assertNoViolations(SOURCE) } @Test void testMultipleAnnotations4() { final SOURCE = ''' @Override @SuppressWarnings def method() { } ''' assertNoViolations(SOURCE) } @Test void testMultipleAnnotations5() { final SOURCE = ''' @Override @SuppressWarnings('parameter') def method() { } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenarioClosureParameterSameLine() { final SOURCE = ''' def method1(closure = {}) { } def method2(closure = {}) {} ''' assertNoViolations(SOURCE) } @Test void testSuccessScenarioMultiLineClosureParameterSameLine() { final SOURCE = ''' def method(closure = { }) { } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenarioMultipleClosureParameterSameLine() { final SOURCE = ''' def method(closure1 = {}, closure2 = {}) { } ''' assertNoViolations(SOURCE) } @Test void testViolationClosureParameterSameLine() { final SOURCE = ''' def method(closure = {}) { } ''' assertSingleViolation(SOURCE, 2, 'def method(closure = {})', 'Opening brace for the method method should start on the same line') } @Test void testSuccessScenarioClosureParameterNewLine() { final SOURCE = ''' def method(closure = {}) { } ''' rule.sameLine = false assertNoViolations(SOURCE) } @Test void testSuccessScenarioMultiLineClosureParameterNewLine() { final SOURCE = ''' def method(closure = { }) { } ''' rule.sameLine = false assertNoViolations(SOURCE) } @Test void testViolationClosureParameterNewLine() { final SOURCE = ''' def method(closure = {}) { } ''' rule.sameLine = false assertSingleViolation(SOURCE, 2, 'def method(closure = {}) {', 'Opening brace for the method method should start on a new line') } @Test void testSuccessScenarioSameLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text assertNoViolations(SOURCE) } @Test void testSuccessScenarioNewLine() { rule.sameLine = false def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text assertNoViolations(SOURCE) } @Test void testViolationSameLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text assertViolations(SOURCE, [lineNumber: 9, sourceLineText: 'First()', messageText: 'Opening brace for the method <init> should start on the same line'], [lineNumber: 12, sourceLineText: 'void method1()', messageText: 'Opening brace for the method method1 should start on the same line'], [lineNumber: 19, sourceLineText: 'public Second()', messageText: 'Opening brace for the method <init> should start on the same line'], [lineNumber: 38, sourceLineText: 'private int method2()', messageText: 'Opening brace for the method method2 should start on the same line']) } @Test void testViolationNewLine() { rule.sameLine = false def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text assertViolations(SOURCE, [lineNumber: 9, sourceLineText: 'First(){}', messageText: 'Opening brace for the method <init> should start on a new line'], [lineNumber: 11, sourceLineText: 'void method1(){}', messageText: 'Opening brace for the method method1 should start on a new line'], [lineNumber: 15, sourceLineText: 'public Second(){', messageText: 'Opening brace for the method <init> should start on a new line'], [lineNumber: 27, sourceLineText: 'private int method2(){', messageText: 'Opening brace for the method method2 should start on a new line']) } @Test void testSingleLineMethod_NoViolations() { final SOURCE = ''' class MyClass { int size() { groups.size() } AutoScalingGroupData get(int i) { groups[i] } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new BracesForMethodRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/MissingBlankLineAfterImportsRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/MissingBlankLineAfterImportsRuleTest.groo0000644�0001750�0001750�00000003635�12311446762�033353� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for MissingBlankLineAfterImportsRule */ class MissingBlankLineAfterImportsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'MissingBlankLineAfterImports' } @Test void testSuccessScenario() { final SOURCE = '''\ package org.codenarc import org.codenarc.rule.Rule import org.codenarc.rule.StubRule class MyClass { def go() { /* ... */ } } '''.stripIndent() assertNoViolations(SOURCE) } @SuppressWarnings('MissingBlankLineAfterImports') @Test void testNoLinesBetweenPackageAndImports() { final SOURCE = '''\ package org.codenarc import org.codenarc.rule.Rule import org.codenarc.rule.StubRule class MyClass { void go() { /* ... */ } }'''.stripIndent() assertSingleViolation(SOURCE, 4, 'class MyClass {', 'Missing blank line after imports in file null') } protected Rule createRule() { new MissingBlankLineAfterImportsRule() } } ���������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterForRuleTest.groovy�������������0000644�0001750�0001750�00000004347�12461030523�030654� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterForRule * * @author Chris Mair */ class SpaceAfterForRuleTest extends AbstractRuleTestCase { private static final MESSAGE = 'The for keyword within class None is not followed by a single space' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterFor' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' for (name in names) { } for (int i=0; i < 10; i++) { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_WithoutSingleSpace_Violation() { final SOURCE = ''' for(name in names) { } for (int i=0; i < 10; i++) { } for( String name: names) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'for(name in names) { }', messageText:MESSAGE], [lineNumber:3, sourceLineText:'for (int i=0; i < 10; i++) { }', messageText:MESSAGE], [lineNumber:4, sourceLineText:'for(', messageText:MESSAGE]) } @Test void testApplyTo_KeywordAfterLabel_NoViolations() { final SOURCE = ''' def "sample test"() { setup: for (name in names) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new SpaceAfterForRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterWhileRuleTest.groovy�����������0000644�0001750�0001750�00000004275�12461027514�031204� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterWhileRule * * @author Chris Mair */ class SpaceAfterWhileRuleTest extends AbstractRuleTestCase { private static final MESSAGE = 'The while keyword within class None is not followed by a single space' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterWhile' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' while (true) { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_WithoutSingleSpace_Violation() { final SOURCE = ''' while(true) { } while (true) { } while( true) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'while(true) { }', messageText:MESSAGE], [lineNumber:3, sourceLineText:'while (true) { }', messageText:MESSAGE], [lineNumber:4, sourceLineText:'while(', messageText:MESSAGE]) } @Test void testApplyTo_KeywordAfterLabel_NoViolations() { final SOURCE = ''' def "sample test"() { when: stack.push(elem) then: while (true) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new SpaceAfterWhileRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterCommaRuleTest.groovy�����������0000644�0001750�0001750�00000026377�12466525115�031204� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterCommaRule * * @author Chris Mair */ class SpaceAfterCommaRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterComma' } // Tests for method calls @Test void testApplyTo_MethodCall_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def value = calculate(1, 3, 'abc') def method1() { doStuff() doStuff([1], 2,\t3) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MethodCall_NoPrecedingSpaceForSingleParameter_Violation() { final SOURCE = ''' class MyTestCase { def value = calculate(1,399, 'abc') } ''' assertSingleViolation(SOURCE, 3, "def value = calculate(1,399, 'abc')", 'The parameter 399') } @Test void testApplyTo_MethodCall_ChainedMethodCall_Violation() { final SOURCE = ''' class MyTestCase { def value = Math.min(1,2).toString() } ''' assertSingleViolation(SOURCE, 3, 'def value = Math.min(1,2).toString()', 'The parameter 2') } @Test void testApplyTo_ConstructorCall_Violation() { final SOURCE = ''' Calendar c = new GregorianCalendar(2011,Calendar.NOVEMBER,1) ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'Calendar c = new GregorianCalendar(2011,Calendar.NOVEMBER,1)', messageText:'The parameter Calendar.NOVEMBER'], [lineNumber:2, sourceLineText:'Calendar c = new GregorianCalendar(2011,Calendar.NOVEMBER,1)', messageText:'The parameter 1'] ) } @Test void testApplyTo_UnicodeLiteral_Violations() { final SOURCE = ''' def value1 = calculate( { '\\u00A0' },12) def value2 = calculate('\\u00A0',399,'abc' ,17) ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:"def value1 = calculate( { '\\u00A0' },12)", messageText:'The parameter 12'], [lineNumber:3, sourceLineText:"def value2 = calculate('\\u00A0',399,'abc' ,17)", messageText:'The parameter 399'], [lineNumber:3, sourceLineText:"def value2 = calculate('\\u00A0',399,'abc' ,17)", messageText:'The parameter abc'], [lineNumber:3, sourceLineText:"def value2 = calculate('\\u00A0',399,'abc' ,17)", messageText:'The parameter 17'] ) } @Test void testApplyTo_MethodCall_NoPrecedingSpaceForMultipleParameters_Violation() { final SOURCE = ''' class MyTestCase { def value = calculate(1,399,'abc',count) } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:"def value = calculate(1,399,'abc',count)", messageText:'The parameter 399'], [lineNumber:3, sourceLineText:"def value = calculate(1,399,'abc',count)", messageText:'The parameter abc'], [lineNumber:3, sourceLineText:"def value = calculate(1,399,'abc',count)", messageText:'The parameter count'] ) } // Tests for method declarations @Test void testApplyTo_MethodDeclaration_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def method1() { } def method2(int a) { } def method3(String a, int b) { } def method4(String a, int b,\tObject c) { } def method5(a, b, c) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MethodDeclaration_NoPrecedingSpaceForSingleParameter_Violation() { final SOURCE = ''' class MyClass { def method1(int a,String b) { } } ''' assertSingleViolation(SOURCE, 3, 'def method1(int a,String b) { }', 'The parameter b') } @Test void testApplyTo_MethodDeclaration_NoPrecedingSpaceForMultipleParameters_Violation() { final SOURCE = ''' class MyTestCase { void calculate(a,int b,String name,count) { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'void calculate(a,int b,String name,count) { }', messageText:'The parameter b'], [lineNumber:3, sourceLineText:'void calculate(a,int b,String name,count) { }', messageText:'The parameter name'], [lineNumber:3, sourceLineText:'void calculate(a,int b,String name,count) { }', messageText:'The parameter count'] ) } // Tests for constructor declarations @Test void testApplyTo_ConstructorDeclaration_NoPrecedingSpaceForMultipleParameters_Violation() { final SOURCE = ''' class MyTestCase { MyTestCase(a,int b,String name,count) { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'MyTestCase(a,int b,String name,count) { }', messageText:'The parameter b'], [lineNumber:3, sourceLineText:'MyTestCase(a,int b,String name,count) { }', messageText:'The parameter name'], [lineNumber:3, sourceLineText:'MyTestCase(a,int b,String name,count) { }', messageText:'The parameter count'] ) } // Tests for closure declarations @Test void testApplyTo_ClosureDeclaration_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def closure1 = { } def closure2 = { -> println 123 } def closure3 = { int a -> } def closure4 = { String a, int b -> } def closure5 = { String a, int b,\tObject c -> } def closure6 = { a, b, c -> } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ClosureDeclaration_NoPrecedingSpaceForSingleParameter_Violation() { final SOURCE = ''' class MyClass { def closure1 = { int a,String b -> } } ''' assertSingleViolation(SOURCE, 3, 'def closure1 = { int a,String b -> }', 'The closure parameter b') } @Test void testApplyTo_ClosureDeclaration_NoPrecedingSpaceForMultipleParameters_Violation() { final SOURCE = ''' class MyClass { void calculate = { a,int b,String name,count -> } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'void calculate = { a,int b,String name,count -> }', messageText:'The closure parameter b'], [lineNumber:3, sourceLineText:'void calculate = { a,int b,String name,count -> }', messageText:'The closure parameter name'], [lineNumber:3, sourceLineText:'void calculate = { a,int b,String name,count -> }', messageText:'The closure parameter count'] ) } // Tests for list literals @Test void testApplyTo_ListLiteral_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def list1 = [] def list2 = [1] def list3 = [1, 2,\tx, '123'] } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ListLiteral_NoPrecedingSpaceForSingleParameter_Violation() { final SOURCE = ''' def list1 = [a,b, c] ''' assertSingleViolation(SOURCE, 2, 'def list1 = [a,b, c]', 'The list element b') } @Test void testApplyTo_ListLiteral_NoPrecedingSpaceForMultipleParameters_Violation() { final SOURCE = ''' class MyClass { def list1 = [a,b,name,123,[x]] } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'def list1 = [a,b,name,123,[x]]', messageText:'The list element b'], [lineNumber:3, sourceLineText:'def list1 = [a,b,name,123,[x]]', messageText:'The list element name'], [lineNumber:3, sourceLineText:'def list1 = [a,b,name,123,[x]]', messageText:'The list element 123'], [lineNumber:3, sourceLineText:'def list1 = [a,b,name,123,[x]]', messageText:'The list element [x]'] ) } // Tests for map literals @Test void testApplyTo_MapLiteral_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def map1 = [:] def map2 = [a:1] def map3 = [a:1, b:2,\tc:x, d:'123'] } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MapLiteral_NoPrecedingSpaceForSingleParameter_Violation() { final SOURCE = ''' def map1 = [a:1,b:2, c:3] ''' assertSingleViolation(SOURCE, 2, 'def map1 = [a:1,b:2, c:3]', 'The map entry b:2') } @Test void testApplyTo_MapLiteral_NoPrecedingSpaceForMultipleParameters_Violation() { final SOURCE = ''' class MyClass { def map1 = [a:1,b:value,c:'123',d:123,e:[x],f:[a:1]] } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:"def map1 = [a:1,b:value,c:'123',d:123,e:[x],f:[a:1]]", messageText:'The map entry b:value'], [lineNumber:3, sourceLineText:"def map1 = [a:1,b:value,c:'123',d:123,e:[x],f:[a:1]]", messageText:'The map entry c:123'], [lineNumber:3, sourceLineText:"def map1 = [a:1,b:value,c:'123',d:123,e:[x],f:[a:1]]", messageText:'The map entry d:123'], [lineNumber:3, sourceLineText:"def map1 = [a:1,b:value,c:'123',d:123,e:[x],f:[a:1]]", messageText:'The map entry e:[x]'], [lineNumber:3, sourceLineText:"def map1 = [a:1,b:value,c:'123',d:123,e:[x],f:[a:1]]", messageText:'The map entry f:[a:1]'] ) } @Test void testApplyTo_ClosureParameterAfterParentheses_NoViolation() { final SOURCE = ''' shouldFail(Exception){ dao.read() } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ClosureParameterAfterParentheses_InsideParentheses_Violation() { final SOURCE = ''' shouldFail(Exception,{ dao.read() }) ''' assertSingleViolation(SOURCE, 2, 'shouldFail(Exception,{ dao.read() })', 'The parameter ' + SpaceAfterCommaRule.CLOSURE_TEXT) } protected Rule createRule() { new SpaceAfterCommaRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/LineLengthRuleTest.groovy����������������0000644�0001750�0001750�00000011226�12304455367�030230� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for LineLengthRule * * @author Hamlet D'Arcy * @author <a href="mailto:geli.crick@osoco.es">Geli Crick</a> */ class LineLengthRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'LineLength' assert rule.ignoreImportStatements assert rule.ignorePackageStatements } @Test void testSuccessScenario() { final SOURCE = ''' class Person { def longMethodButNotQuiteLongEnough1234567890123456789012345() { } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class Person { def longMethod123456789012345678900123456789012345678901234567890123456789012345678901234567890123456() { } } ''' assertSingleViolation(SOURCE, 3, 'def longMethod123456789012345678900123456789012345678901234567890123456789012345678901234567890123456', 'The line exceeds 120 characters. The line is 121 characters.') } @Test void testIgnoresImportStatements() { final SOURCE = ''' import longMethod123456789012345678900123456789012345678901234567890123456789012345678901234567890123456423452435asdfasdfadsfasdfasdfasdfadfasdfasdfadfasdfasdfadsf class Person { def longMethodButNotQuiteLongEnough1234567890123456789012345() { } } ''' assertNoViolations(SOURCE) } @Test void testDoesNotIgnoreImportStatementsWhenFlagDisabled() { rule.ignoreImportStatements = false final SOURCE = ''' import longMethod123456789012345678900123456789012345678901234567890123456789012345678901234567890123456423452435asdfasdfadsfasdfasdfasdfadfasdfasdfadfasdfasdfadsf class Person { def longMethodButNotQuiteLongEnough1234567890123456789012345() { } } ''' assertSingleViolation(SOURCE, 2, 'import longMethod123456789012345678900123456789012345678901234567890123456789012345678901234567890123456423452435asdfasdfadsfasdfasdfasdfadfasdfasdfadfasdfasdfadsf') } @Test void testIgnoresPackageStatements() { final SOURCE = ''' package longMethod123456789012345678900123456789012345678901234567890123456789012345678901234567890123456423452435asdfasdfadsfasdfasdfasdfadfasdfasdfadfasdfasdfadsf class Person { def longMethodButNotQuiteLongEnough1234567890123456789012345() { } } ''' assertNoViolations(SOURCE) } @Test void testDoesNotIgnorePackageStatementsWhenFlagDisabled() { rule.ignorePackageStatements = false final SOURCE = ''' package longMethod123456789012345678900123456789012345678901234567890123456789012345678901234567890123456423452435asdfasdfadsfasdfasdfasdfadfasdfasdfadfasdfasdfadsf class Person { def longMethodButNotQuiteLongEnough1234567890123456789012345() { } } ''' assertSingleViolation(SOURCE, 2, 'package longMethod123456789012345678900123456789012345678901234567890123456789012345678901234567890123456423452435asdfasdfadsfasdfasdfasdfadfasdfasdfadfasdfasdfadsf') } @Test void testComments() { final SOURCE = ''' class Person { // this is a really long comment 001234567890123456789012345678907890123456789012345678901234567890123456 } ''' assertSingleViolation(SOURCE, 3, '// this is a really long comment 001234567890123456789012345678907890123456789012345678901234567890123456') } protected Rule createRule() { new LineLengthRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterCatchRuleTest.groovy�����������0000644�0001750�0001750�00000003736�12311373552�031157� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterCatchRule * * @author Chris Mair */ class SpaceAfterCatchRuleTest extends AbstractRuleTestCase { private static final MESSAGE = 'The catch keyword within class None is not followed by a single space' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterCatch' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' try { } catch (Exception e) { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_WithoutSingleSpace_Violation() { final SOURCE = ''' try { } catch(Exception e) { } try { } catch (Exception e) { } try { } catch( Exception e) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'try { } catch(Exception e) { }', messageText:MESSAGE], [lineNumber:3, sourceLineText:'try { } catch (Exception e) { }', messageText:MESSAGE], [lineNumber:4, sourceLineText:'try { } catch(', messageText:MESSAGE]) } protected Rule createRule() { new SpaceAfterCatchRule() } } ����������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/BracesForClassRuleTest.groovy������������0000644�0001750�0001750�00000013016�12461174315�031025� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BracesForClassRule * * @author Hamlet D'Arcy */ class BracesForClassRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BracesForClass' } @Test void testMultilineDefinition() { final SOURCE = ''' class MyClass extends File { } ''' assertNoViolations(SOURCE) } @Test void testMultilineDefinitionViolation() { final SOURCE = ''' class MyClass extends File { } ''' assertSingleViolation(SOURCE, 4, '{') } @Test void testMultilineDefinitionOverride() { final SOURCE = ''' class MyClass extends File { } ''' rule.sameLine = false assertNoViolations(SOURCE) } @Test void testMultilineDefinitionOverrideViolation() { final SOURCE = ''' class MyClass extends File { } ''' rule.sameLine = false assertSingleViolation(SOURCE, 3, 'extends File {', 'Opening brace for the class MyClass should start on a new line') } @Test void testIgnoredForAnnotationTypeDefinition1() { final SOURCE = ''' @interface MyClass { } ''' rule.sameLine = false assertNoViolations(SOURCE) } @Test void testIgnoredForAnnotationTypeDefinition2() { final SOURCE = ''' public @interface MyClass { } ''' rule.sameLine = false assertNoViolations(SOURCE) } @Test void testEnumSuccessScenarioSameLine() { final SOURCE = ''' enum MyEnum { } ''' rule.sameLine = true assertNoViolations(SOURCE) } @Test void testEnumViolationSameLine() { final SOURCE = ''' enum MyEnum { } ''' rule.sameLine = true assertSingleViolation(SOURCE, 3, '{', 'Opening brace for the class MyEnum should start on the same line') } @Test void testEnumSuccessScenarioNewLine() { final SOURCE = ''' enum MyEnum { } ''' rule.sameLine = false assertNoViolations(SOURCE) } @Test void testEnumViolationNewLine() { final SOURCE = ''' enum MyEnum { } ''' rule.sameLine = false assertSingleViolation(SOURCE, 2, '{', 'Opening brace for the class MyEnum should start on a new line') } @Test void testSuccessScenarioSameLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text assertNoViolations(SOURCE) } @Test void testSuccessScenarioNewLine() { rule.sameLine = false def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text assertNoViolations(SOURCE) } @Test void testViolationSameLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text assertViolations(SOURCE, [lineNumber: 6, sourceLineText: '{', messageText: 'Opening brace for the class First should start on the same line'], [lineNumber: 18, sourceLineText: '{', messageText: 'Opening brace for the class Second should start on the same line'], [lineNumber: 64, sourceLineText: '{', messageText: 'Opening brace for the interface Third should start on the same line']) } @Test void testViolationNewLine() { rule.sameLine = false def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text assertViolations(SOURCE, [lineNumber: 6, sourceLineText: 'class First{', messageText: 'Opening brace for the class First should start on a new line'], [lineNumber: 14, sourceLineText: 'class Second{', messageText: 'Opening brace for the class Second should start on a new line'], [lineNumber: 44, sourceLineText: 'interface Third{', messageText: 'Opening brace for the interface Third should start on a new line']) } protected Rule createRule() { new BracesForClassRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAroundMapEntryColonRuleTest.groovy��0000644�0001750�0001750�00000011015�12406660764�033054� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for SpaceAroundMapEntryColonRule * * @author Chris Mair */ class SpaceAroundMapEntryColonRuleTest extends AbstractRuleTestCase { private static final PRECEDED = 'preceded' private static final FOLLOWED = 'followed' private static final CLASS = 'None' private static final REGEX = /\S/ @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAroundMapEntryColon' assert rule.characterBeforeColonRegex == REGEX assert rule.characterAfterColonRegex == REGEX } @Test void testMapEntryFormatting_DefaultConfiguration_NoViolations() { final SOURCE = ''' Map m1 = [myKey:12345] def m2 = [a:123, (key):'xxx', c:[1,2] ] println [k1:[a:1], k2:[b:2, c:3]] ''' assertNoViolations(SOURCE) } @Test void testMapEntryFormatting_BeforeColon_CustomConfiguration_NoViolations() { final SOURCE = ''' Map m1 = [myKey :12345] def m2 = [a :123, (key)\t:'xxx', c :[1,2] ] ''' rule.characterBeforeColonRegex = /\s/ assertNoViolations(SOURCE) } @Test void testMapEntryFormatting_AfterColon_CustomConfiguration_NoViolations() { final SOURCE = ''' println [k1: [a: 1], k2: [b:\t2, c: System.currentTmeMillis()]] ''' rule.characterAfterColonRegex = /\s/ assertNoViolations(SOURCE) } @Test void testMapEntryFormatting_DefaultConfiguration_Violations() { final SOURCE = """ Map m1 = [myKey : 12345] ${violation('myKey', PRECEDED, CLASS, REGEX)} \ ${violation('myKey', FOLLOWED, CLASS, REGEX)} def m2 = [a:\t123, (key) :'xxx', ${violation('a', FOLLOWED, CLASS, REGEX)} \ ${violation('key', PRECEDED, CLASS, REGEX)} 99:'ok', c: ${violation('c', FOLLOWED, CLASS, REGEX)} [1,2] ] println [a :[1:11, 2:22], ${violation('a', PRECEDED, CLASS, REGEX)} b:[(Integer): 33]] ${violation('Integer', FOLLOWED, CLASS, REGEX)} """ assertInlineViolations(SOURCE) } @Test void testMapEntryFormatting_CustomConfiguration_Violations() { final REGEX = /\s/ final SOURCE = """ Map m1 = [myKey:12345] ${violation('myKey', PRECEDED, CLASS, REGEX)} \ ${violation('myKey', FOLLOWED, CLASS, REGEX)} def m2 = [a\t:123, (key): 'xxx', ${violation('a', FOLLOWED, CLASS, REGEX)} \ ${violation('key', PRECEDED, CLASS, REGEX)} 99 : 'ok', c :[1,2] ] ${violation('c', FOLLOWED, CLASS, REGEX)} println [a: [1 : 11, 2 : 22], ${violation('a', PRECEDED, CLASS, REGEX)} b : [(Integer) :33]] ${violation('Integer', FOLLOWED, CLASS, REGEX)} """ rule.characterBeforeColonRegex = REGEX rule.characterAfterColonRegex = REGEX assertInlineViolations(SOURCE) } @Test void testIgnoresSpreadMapOperator_NoViolations() { final SOURCE = ''' def params = [:] to(page, *:params) ''' rule.characterAfterColonRegex = /\s/ assertNoViolations(SOURCE) } private String violation(String keyName, String precededOrFollowed, String className, String regex) { return inlineViolation("The colon for the literal Map entry for key [$keyName] within class $className" + " is not $precededOrFollowed by a match for regular expression [$regex]") } protected Rule createRule() { new SpaceAroundMapEntryColonRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/ConsecutiveBlankLinesRuleTest.groovy�����0000644�0001750�0001750�00000005174�12311370173�032423� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConsecutiveBlankLinesRule * * @author Joe Sondow */ @SuppressWarnings('ConsecutiveBlankLines') class ConsecutiveBlankLinesRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ConsecutiveBlankLines' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { def go() { /* ... */ } def goSomewhere() { /* ... */ } def build() { /* ... */ } def buildSomething() { /* ... */ } } ''' assertNoViolations(SOURCE) } @Test void testClassStartsWithDoubleBlankLines() { final SOURCE = ''' class MyClass { void go() { /* ... */ } } ''' assertSingleViolation(SOURCE, 3, '', 'File null has consecutive blank lines') } @Test void testFileStartsWithDoubleBlankLines() { final SOURCE = ''' class MyClass { void go() { /* ... */ } } ''' assertSingleViolation(SOURCE, 1, '', 'File null has consecutive blank lines') } @Test void testDoubleBlankLinesBetweenMethods() { final SOURCE = ''' class MyClass { void go() { /* ... */ } void stop() { /* ... */ } void run() { /* ... */ } } ''' assertTwoViolations(SOURCE, 4, '', 7, '') } @Test void testTripleBlankLines() { final SOURCE = ''' class MyClass { void go() { /* ... */ } void stop() { /* ... */ } } ''' assertTwoViolations(SOURCE, 4, '', 5, '') } protected Rule createRule() { new ConsecutiveBlankLinesRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/BracesForTryCatchFinallyRuleTest.groovy��0000644�0001750�0001750�00000007334�12041642702�033020� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BracesForTryCatchFinallyRule * * @author Hamlet D'Arcy * @author <a href="mailto:geli.crick@osoco.es">Geli Crick</a> */ class BracesForTryCatchFinallyRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BracesForTryCatchFinally' } @Test void testNewLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text assertViolations(SOURCE, [lineNumber:21, sourceLineText:'try', messageText: "Opening brace should be on the same line as 'try'"], [lineNumber:26, sourceLineText:'catch (Exception e)', messageText: "'catch' should be on the same line as the closing brace"], [lineNumber:26, sourceLineText:'catch (Exception e)', messageText: "Opening brace should be on the same line as 'catch'"], [lineNumber:29, sourceLineText:'finally', messageText: "'finally' should be on the same line as the closing brace"], [lineNumber:29, sourceLineText:'finally', messageText: "Opening brace should be on the same line as 'finally'"] ) } @Test void testNewLineOverride() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text rule.sameLine = false assertNoViolations(SOURCE) } @Test void testSameLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text assertNoViolations(SOURCE) } @Test void testSameLineOverride() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text rule.sameLine = false assertViolations(SOURCE, [lineNumber:16, sourceLineText:'try{', messageText: "Opening brace should not be on the same line as 'try'"], [lineNumber:19, sourceLineText:'}catch (Exception e){', messageText: "'catch' should not be on the same line as the closing brace"], [lineNumber:19, sourceLineText:'}catch (Exception e){', messageText: "Opening brace should not be on the same line as 'catch'"], [lineNumber:20, sourceLineText:'}finally{', messageText: "'finally' should not be on the same line as the closing brace"], [lineNumber:20, sourceLineText:'}finally{', messageText: "Opening brace should not be on the same line as 'finally'"] ) } protected Rule createRule() { BracesForTryCatchFinallyRule rule = new BracesForTryCatchFinallyRule() rule.validateCatch = true rule.validateFinally = true rule } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceBeforeClosingBraceRuleTest.groovy���0000644�0001750�0001750�00000024131�12461314605�032621� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceBeforeClosingBraceRule * * @author Chris Mair */ class SpaceBeforeClosingBraceRuleTest extends AbstractRuleTestCase { private static final String BLOCK_VIOLATION_MESSAGE = 'The closing brace for the block in class None is not preceded by a space or whitespace' private static final String CLOSURE_VIOLATION_MESSAGE = 'The closing brace for the closure in class None is not preceded by a space or whitespace' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceBeforeClosingBrace' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { def closure = { } if (true) { } while(ready) { } try { } catch(Exception e) { } finally { } for(int i=0; i<10; i++) { } for(String name in names) { } for(String name: names) { } if (count > this."maxPriority${priority}Violations") { } while (count > this."maxPriority${priority}Violations") { } } MyClass() { this(classNames) } static void reset() { violationCounts = [1:0, 2:0, 3:0] } void doStuff() { println 9 } } interface MyInterface { } enum MyEnum { OK, BAD } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ProperSpacingWithoutIgnoreEmptyBlock_OneViolations() { final SOURCE = ''' class MyClass { def myMethod() { def closure = {} } } ''' assertSingleViolation(SOURCE, 4, 'def closure = {}', 'The closing brace for the closure in class MyClass is not preceded by a space or whitespace') } @Test void testApplyTo_ProperSpacingWithIgnoreEmptyBlock_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { def closure = {} if (true) {} while(ready) {} try { } catch(Exception e) { } finally {} for(int i=0; i<10; i++) {} for(String name in names) {} for(String name: names) {} if (count > this."maxPriority${priority}Violations") {} while (count > this."maxPriority${priority}Violations") {} } void doStuff2() {} } interface MyInterface2 {} ''' rule.ignoreEmptyBlock = true assertNoViolations(SOURCE) } @Test void testApplyTo_ClassDeclaration_Violation() { final SOURCE = ''' class MyClass { int count} class MyOtherClass extends AbstractClass { int count} ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyClass { int count}', messageText:'The closing brace for class MyClass is not preceded'], [lineNumber:3, sourceLineText:'class MyOtherClass extends AbstractClass { int count}', messageText:'The closing brace for class MyOtherClass is not preceded']) } @Test void testApplyTo_InterfaceDeclaration_Violation() { final SOURCE = ''' interface MyInterface { void doStuff()} ''' assertSingleViolation(SOURCE, 2, 'interface MyInterface { void doStuff()}', 'The closing brace for interface MyInterface is not preceded') } @Test void testApplyTo_EnumDeclaration_Violation() { final SOURCE = ''' enum MyEnum { OK, BAD} c ''' assertSingleViolation(SOURCE, 2, 'enum MyEnum { OK, BAD}', 'The closing brace for enum MyEnum is not preceded') } @Test void testApplyTo_Method_Violations() { final SOURCE = ''' def myMethod() { return 9} def otherMethod() { return 9} ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def myMethod() { return 9}', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'{ return 9}', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_Constructor_Violations() { final SOURCE = ''' class MyClass { MyClass() { int count} MyClass(int num) { doStuff()} } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'MyClass() { int count}', messageText:'The closing brace for the block in class MyClass'], [lineNumber:5, sourceLineText:'doStuff()}', messageText:'The closing brace for the block in class MyClass']) } @Test void testApplyTo_If_Violations() { final SOURCE = ''' if (ready) { return 9} if (ready || done) { return 9} if (ready) println '}' // no block; ignore ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (ready) { return 9}', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'done) { return 9}', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_Else_Violations() { final SOURCE = ''' if (ready) { } else { return 9} if (ready) { } else println '{' // no block; ignore ''' assertSingleViolation(SOURCE, 3, 'else { return 9}', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_For_Violations() { final SOURCE = ''' for (int i=0; i<10; i++) { println i} for (int i=0; i<10; i++) println '{' // no block; ignore for (String name in names) { println name} for (String name: names) { println name} for (int i=0; i<10; i++) { println i} ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'for (int i=0; i<10; i++) { println i}', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'for (String name in names) { println name}', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:5, sourceLineText:'for (String name: names) { println name}', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:8, sourceLineText:'i++) { println i}', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_While_Violations() { final SOURCE = ''' while (ready) { println 9} while (ready || done) { println 9} while (ready) println '{' // no block; ignore ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'while (ready) { println 9}', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'done) { println 9}', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_Try_Violations() { final SOURCE = ''' try { doStuff()} finally { } ''' assertSingleViolation(SOURCE, 2, 'try { doStuff()}', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Catch_Violations() { final SOURCE = ''' try { } catch(Exception e) { doStuff()} ''' assertSingleViolation(SOURCE, 2, 'catch(Exception e) { doStuff()}', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Finally_Violations() { final SOURCE = ''' try { } finally { doStuff()} ''' assertSingleViolation(SOURCE, 2, 'finally { doStuff()}', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Closure_Violations() { final SOURCE = ''' list.each { name -> doStuff()} shouldFail(Exception) { doStuff()} def c = { println 123} def m = [a:123, b: { println 7}] ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'list.each { name -> doStuff()}', messageText:CLOSURE_VIOLATION_MESSAGE], [lineNumber:3, sourceLineText:'shouldFail(Exception) { doStuff()}', messageText:CLOSURE_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'def c = { println 123}', messageText:CLOSURE_VIOLATION_MESSAGE], [lineNumber:5, sourceLineText:'def m = [a:123, b: { println 7}]', messageText:CLOSURE_VIOLATION_MESSAGE]) } @Test void testApplyTo_Closure_UnicodeCharacterLiteral_Violation() { final SOURCE = ''' list.each { name -> doStuff('\\u00A0')} ''' assertSingleViolation(SOURCE, 2, 'list.each { name -> ', CLOSURE_VIOLATION_MESSAGE) } @Test void testApplyTo_CheckClosureMapEntryValue_False_NoViolations() { final SOURCE = ''' def m = [a:123, b: { println 7}] ''' rule.checkClosureMapEntryValue = false assertNoViolations(SOURCE) } protected Rule createRule() { new SpaceBeforeClosingBraceRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterClosingBraceRuleTest.groovy����0000644�0001750�0001750�00000025404�12465722174�032474� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterClosingBraceRule * * @author Chris Mair */ class SpaceAfterClosingBraceRuleTest extends AbstractRuleTestCase { private static final String BLOCK_VIOLATION_MESSAGE = 'The closing brace for the block in class None is not followed by a space or whitespace' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterClosingBrace' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { def closure = { } if (true) { } while(ready) { } try { } catch(Exception e) { } finally { } for(int i=0; i<10; i++) { } for(String name in names) { } for(String name: names) { } if (count > this."maxPriority${priority}Violations") { } while (count > this."maxPriority${priority}Violations") { } } MyClass() { this(classNames) } static void reset() { violationCounts = [1:0, 2:0, 3:0] } void doStuff() { println 9 } } interface MyInterface { } enum MyEnum { OK, BAD } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ClassDeclaration_Violation() { final SOURCE = ''' class MyClass { int count }//comment ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyClass { int count }//comment', messageText:'The closing brace for class MyClass is not followed']) } @Test void testApplyTo_InterfaceDeclaration_Violation() { final SOURCE = ''' interface MyInterface { void doStuff() }//comment ''' assertSingleViolation(SOURCE, 2, 'interface MyInterface { void doStuff() }//comment', 'The closing brace for interface MyInterface is not followed') } @Test void testApplyTo_EnumDeclaration_Violations() { final SOURCE = ''' enum MyEnum { OK, BAD }//comment c ''' assertSingleViolation(SOURCE, 2, 'enum MyEnum', 'The closing brace for enum MyEnum is not followed') } @Test void testApplyTo_Method_Violations() { final SOURCE = ''' def myMethod() { return 9 }// ok def otherMethod() { return 9 }// ok ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def myMethod() { return 9 }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'{ return 9 }', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_Constructor_Violations() { final SOURCE = ''' class MyClass { MyClass() { int count }//comment MyClass(int num) { doStuff() }//comment } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'MyClass() { int count }', messageText:'The closing brace for the block in class MyClass'], [lineNumber:5, sourceLineText:'doStuff() }', messageText:'The closing brace for the block in class MyClass']) } @Test void testApplyTo_If_Violations() { final SOURCE = ''' if (ready) { return 9 }//comment if (ready || done) { return 9 }else { } if (ready) println '}' // no block; ignore ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (ready) { return 9 }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'done) { return 9 }', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_Else_Violations() { final SOURCE = ''' if (ready) { } else { return 9 }//comment if (ready) { } else println '{' // no block; ignore ''' assertSingleViolation(SOURCE, 3, 'else { return 9 }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_For_Violations() { final SOURCE = ''' for (int i=0; i<10; i++) { println i }//comment for (int i=0; i<10; i++) println '{' // no block; ignore for (String name in names) { println name }//comment for (String name: names) { println name }//comment for (int i=0; i<10; i++) { println i }//comment ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'for (int i=0; i<10; i++) { println i }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'for (String name in names) { println name }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:5, sourceLineText:'for (String name: names) { println name }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:8, sourceLineText:'i++) { println i }', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_While_Violations() { final SOURCE = ''' while (ready) { println 9 }//comment while (ready || done) { println 9 }//comment while (ready) println '{' // no block; ignore ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'while (ready) { println 9 }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'done) { println 9 }', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_Try_Violations() { final SOURCE = ''' try { doStuff() }finally { } ''' assertSingleViolation(SOURCE, 2, 'try { doStuff() }finally', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Catch_Violations() { final SOURCE = ''' try { } catch(Exception e) { doStuff() }finally { } ''' assertSingleViolation(SOURCE, 3, 'catch(Exception e) {', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Finally_Violations() { final SOURCE = ''' try { } finally { doStuff() }//comment ''' assertSingleViolation(SOURCE, 2, 'finally { doStuff() }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Closure_Violations() { final SOURCE = ''' list.each { name -> doStuff() }//comment shouldFail(Exception) { doStuff() }//comment def c = { println 123 }//comment def m = [a:123, b:{ println 7 }] ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'list.each { name -> doStuff() }', messageText:'The closing brace for the closure in class None is not followed'], [lineNumber:3, sourceLineText:'shouldFail(Exception) { doStuff() }', messageText:'The closing brace for the closure in class None is not followed'], [lineNumber:4, sourceLineText:'def c = { println 123 }', messageText:'The closing brace for the closure in class None is not followed'], [lineNumber:5, sourceLineText:'def m = [a:123, b:{ println 7 }]', messageText:'The closing brace for the closure in class None is not followed']) } @Test void testApplyTo_Closure_AllowedCharacters_NoViolations() { final SOURCE = ''' def matching = list.find { it.isReady() }.filter() // no violation for dot operator assert list.every { it.isReady() }, "Error" // no violation for comma def m = [a:123, b:{ println 7 },c:99] // no violation for comma processItems(list.select { it.isReady() }) // no violation for closing parenthesis def names = records.findAll { it.age > 1 }*.name // no violation for spread operator parameters?.collect { it?.type?.toString() }?.join(', ') // no violation for null-safe operator def closure = { println 7 }; // no violation for comma ''' assertNoViolations(SOURCE) } @Test void testApplyTo_InnerClass_SemicolonFollowingClosingBrace_NoViolations() { final SOURCE = ''' def service = new MyService() { }; def service2 = new MyService() { @Override void run() throws Exception { println 123 } }; ''' assertNoViolations(SOURCE) } @Test void testApplyTo_UnicodeCharacterLiteral_Violation() { final SOURCE = ''' if (valid()) { return '\\u00A0' }else { } ''' assertSingleViolation(SOURCE, 2, 'if (valid())', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_CheckClosureMapEntryValue_False_NoViolations() { final SOURCE = ''' def m = [a:123, b:{ println 7 }] ''' rule.checkClosureMapEntryValue = false assertNoViolations(SOURCE) } @Test void testApplyTo_ClosingBraceWithinStringLiteral_NoViolations() { final SOURCE = ''' def doStuff() { def things = new ObjectMapper().readValue('{}', new TypeReference<List<Thing>>() {} ) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_GStringWithClosure_NoViolations() { assertNoViolations(''' def foo = 1 "I am a ${ -> foo }" ''') } @Test void testApplyTo_GStringWithClosure_AnyCharacterAllowedAfterClosureInsideGString_NoViolations() { assertNoViolations(''' def foo = 1 "I am a ${ -> foo }0" ''') } protected Rule createRule() { new SpaceAfterClosingBraceRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/MissingBlankLineAfterPackageRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/MissingBlankLineAfterPackageRuleTest.groo0000644�0001750�0001750�00000007511�12312152270�033233� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for MissingBlankLineAfterPackageRule * * @author Joe Sondow */ @SuppressWarnings('MissingBlankLineAfterImports') class MissingBlankLineAfterPackageRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'MissingBlankLineAfterPackage' } @Test void testSuccessScenarioWithoutPackage() { final SOURCE = '''\ class MyClass { def go() { /* ... */ } } '''.stripIndent() assertNoViolations(SOURCE) } @Test void testSuccessScenarioWithPackage() { final SOURCE = '''\ package org.codenarc class MyClass { def go() { /* ... */ } } '''.stripIndent() assertNoViolations(SOURCE) } @SuppressWarnings('ConsecutiveBlankLines') @Test void testSuccessScenarioTwoBlankLinesAfterPackage() { final SOURCE = '''\ package org.codenarc class MyClass { def go() { /* ... */ } } '''.stripIndent() assertNoViolations(SOURCE) } @Test void testSuccessScenarioPackageThenBlankThenImport() { final SOURCE = '''\ package org.codenarc import java.util.Date class MyClass { def go() { /* ... */ } } '''.stripIndent() assertNoViolations(SOURCE) } @Test void testNoLinesBetweenPackageAndImports() { final SOURCE = '''\ package org.codenarc import java.util.Date class MyClass { void go() { /* ... */ } }'''.stripIndent() assertSingleViolation(SOURCE, 1, 'import java.util.Date', 'Missing blank line after package statement in file null') } @Test void testNoLinesBetweenPackageAndImportsAndClass() { final SOURCE = '''\ package org.codenarc import java.util.Date class MyClass { void go() { /* ... */ } }'''.stripIndent() assertSingleViolation(SOURCE, 1, 'import java.util.Date', 'Missing blank line after package statement in file null') } @Test void testNoLinesBetweenPackageAndClassJavadoc() { final SOURCE = '''\ package org.codenarc /** * A very special class */ class MyClass { void go() { /* ... */ } }'''.stripIndent() assertSingleViolation(SOURCE, 1, '/**', 'Missing blank line after package statement in file null') } @Test void testNoLinesBetweenPackageAndClass() { final SOURCE = '''\ package org.codenarc class MyClass { void go() { /* ... */ } }'''.stripIndent() assertSingleViolation(SOURCE, 1, 'class MyClass {', 'Missing blank line after package statement in file null') } protected Rule createRule() { new MissingBlankLineAfterPackageRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/BracesForForLoopRuleTest.groovy����������0000644�0001750�0001750�00000005715�12041642702�031341� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BracesForForLoopRule * * @author Hamlet D'Arcy */ class BracesForForLoopRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BracesForForLoop' } @Test void testMultilineForLoop() { final SOURCE = ''' for (int x = 0; x < 10; x++) { } ''' assertNoViolations(SOURCE) } @Test void testMultilineForLoopOverride() { final SOURCE = ''' for (int x = 0; x < 10; x++) { } ''' rule.sameLine = false assertNoViolations(SOURCE) } @Test void testForLoopWithNoBraces_NoViolations() { final SOURCE = ''' for (int x = 0; x < 10; x++) println x ''' assertNoViolations(SOURCE) } @Test void testNewLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text assertSingleViolation(SOURCE, 33, 'for (i in 0..3)', 'Braces should start on the same line') } @Test void testNewLineOverride() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text rule.sameLine = false assertNoViolations(SOURCE) } @Test void testSameLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text assertNoViolations(SOURCE) } @Test void testSameLineOverride() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text rule.sameLine = false assertSingleViolation(SOURCE, 23, 'for (i in 0..3){', 'Braces should start on a new line') } protected Rule createRule() { new BracesForForLoopRule() } } ���������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/BracesForIfElseRuleTest.groovy�����������0000644�0001750�0001750�00000011262�12041642702�031122� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BracesForIfElseRule * * @author Hamlet D'Arcy * @author <a href="mailto:geli.crick@osoco.es">Geli Crick</a> */ class BracesForIfElseRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BracesForIfElse' } @Test void testBraceOnSameLine_NoViolations() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text assertNoViolations(SOURCE) } @Test void testBraceOnNewLine_SameLineFalse_NoViolations() { rule.sameLine = false def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text assertNoViolations(SOURCE) } @Test void testIfOrElseWithNoBraces_NoViolations() { final SOURCE = ''' if (a && b) println 'ok' else println 'bad' ''' assertNoViolations(SOURCE) } @Test void testMultilineIfStatement_NoViolations() { final SOURCE = ''' if (a && b) { } ''' assertNoViolations(SOURCE) } @Test void testMultilineIfStatement_Violation() { final SOURCE = ''' if (a && b) { } ''' assertSingleViolation(SOURCE, 2, 'if (a &&', "Opening brace should be on the same line as 'if'") } @Test void testViolationSameLine() { def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestNewLine.txt') final SOURCE = new File(testFile.toURI()).text assertViolations(SOURCE, [lineNumber: 40, sourceLineText: 'if(1==1)', messageText: "Opening brace should be on the same line as 'if'"], [lineNumber: 43, sourceLineText: 'else if (2==2)', messageText: "'else' should be on the same line as the closing brace"], [lineNumber: 43, sourceLineText: 'else if (2==2)', messageText: "Opening brace should be on the same line as 'if'"], [lineNumber: 47, sourceLineText: '{', messageText: "'else' should be on the same line as the closing brace"], [lineNumber: 47, sourceLineText: '{', messageText: "Opening brace should be on the same line as 'else'"], [lineNumber: 50, sourceLineText: 'if (3==3)', messageText: "Opening brace should be on the same line as 'if'"]) } @Test void testViolationNewLine() { rule.sameLine = false def testFile = this.getClass().getClassLoader().getResource('rule/BracesTestSameLine.txt') final SOURCE = new File(testFile.toURI()).text assertViolations(SOURCE, [lineNumber: 28, sourceLineText: 'if(1==1) {', messageText: "Opening brace should not be on the same line as 'if'"], [lineNumber: 29, sourceLineText: '} else if(2==2) {', messageText: "'else' should not be on the same line as the closing brace"], [lineNumber: 29, sourceLineText: '} else if(2==2) {', messageText: "Opening brace should not be on the same line as 'if'"], [lineNumber: 30, sourceLineText: '} else{', messageText: "'else' should not be on the same line as the closing brace"], [lineNumber: 30, sourceLineText: '} else{', messageText: "Opening brace should not be on the same line as 'else'"], [lineNumber: 33, sourceLineText: 'if (3==3){', messageText: "Opening brace should not be on the same line as 'if'"]) } protected Rule createRule() { BracesForIfElseRule rule = new BracesForIfElseRule() rule.validateElse = true rule } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterSwitchRuleTest.groovy����������0000644�0001750�0001750�00000004110�12311373552�031361� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterSwitchRule * * @author Chris Mair */ class SpaceAfterSwitchRuleTest extends AbstractRuleTestCase { private static final MESSAGE = 'The switch keyword within class None is not followed by a single space' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterSwitch' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' switch (x) { case 1: println 'one' } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SwitchWithoutSingleSpace_Violation() { final SOURCE = ''' switch(x) { case 1: println 'one' } switch (x) { case 1: println 'one' } switch( x) { case 1: println 'one' } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'switch(x) {', messageText:MESSAGE], [lineNumber:5, sourceLineText:'switch (x) {', messageText:MESSAGE], [lineNumber:8, sourceLineText:'switch(', messageText:MESSAGE]) } protected Rule createRule() { new SpaceAfterSwitchRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/FileEndsWithoutNewlineRuleTest.groovy����0000644�0001750�0001750�00000003247�12312152270�032564� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for FileEndsWithoutNewlineRule * * @author Joe Sondow */ class FileEndsWithoutNewlineRuleTest extends AbstractRuleTestCase { def skipTestThatUnrelatedCodeHasNoViolations def skipTestThatInvalidCodeHasNoViolations @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'FileEndsWithoutNewline' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { def go() { /* ... */ } } '''.stripIndent() assertNoViolations(SOURCE) } @Test void testClassStartsWithDoubleBlankLines() { final SOURCE = ''' class MyClass { void go() { /* ... */ } }''' assertSingleViolation(SOURCE, 3, '}', 'File null does not end with a newline') } protected Rule createRule() { new FileEndsWithoutNewlineRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/ClassJavadocRuleTest.groovy��������������0000644�0001750�0001750�00000010032�12311373552�030517� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.codenarc.source.SourceString import org.junit.Test /** * Tests for ClassJavadocRule * * @author Hamlet D'Arcy * @author Chris Mair */ class ClassJavadocRuleTest extends AbstractRuleTestCase { static skipTestThatUnrelatedCodeHasNoViolations @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ClassJavadoc' assert !rule.applyToNonMainClasses } @Test void testIgnoresNonMainClasses() { final SOURCE = ''' /** * */ class MyClass {} class OtherClass {} ''' sourceCodeName = 'MyClass.groovy' assertNoViolations(SOURCE) } @Test void testHasJavadoc_DefaultPackage_NoViolations() { final SOURCE = ''' /** * Javadoc */ class TestClass { } ''' sourceCodeName = 'TestClass.groovy' assertNoViolations(SOURCE) } @Test void testHasJavadoc_IgnoresBlankLinesBetweenJavadocAndClass_NoViolations() { final SOURCE = ''' /** * Javadoc */ class TestClass { } ''' sourceCodeName = 'TestClass.groovy' assertNoViolations(SOURCE) } @Test void testHasJavadoc_WithinPackage_NoViolations() { final SOURCE = ''' package org.example /** * Javadoc */ class TestClass { } ''' sourceCodeName = 'TestClass.groovy' assertNoViolations(SOURCE) } @Test void testMissingJavadoc_WithinPackage_Violation() { final SOURCE = ''' package org.example // Not javadoc class TestClass { } ''' sourceCodeName = 'TestClass.Groovy' assertViolations(SOURCE, [lineNumber:5, sourceLineText:'class TestClass', messageText:'Class org.example.TestClass missing JavaDoc']) } @Test void testApplyToNonMainPackages_Violations() { final SOURCE = ''' package org.example class MyClass { } // Not javadoc class OtherClass { } ''' rule.applyToNonMainClasses = true sourceCodeName = 'MyClass.groovy' assertViolations(SOURCE, [lineNumber: 4, sourceLineText: 'class MyClass', messageText: 'Class org.example.MyClass missing JavaDoc'], [lineNumber: 8, sourceLineText: 'class OtherClass', messageText: 'Class org.example.OtherClass missing JavaDoc']) } @Test void testSourceCodeNameWithoutExtension() { final SOURCE = 'println' assert rule.sourceCodeNameWithoutExtension(new SourceString(SOURCE, null, null)) == null assert rule.sourceCodeNameWithoutExtension(new SourceString(SOURCE, null, '')) == '' assert rule.sourceCodeNameWithoutExtension(new SourceString(SOURCE, null, 'abc')) == 'abc' assert rule.sourceCodeNameWithoutExtension(new SourceString(SOURCE, null, 'abc.groovy')) == 'abc' } protected Rule createRule() { new ClassJavadocRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceBeforeOpeningBraceRuleTest.groovy���0000644�0001750�0001750�00000022403�12461314673�032627� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceBeforeOpeningBraceRule * * @author Chris Mair */ class SpaceBeforeOpeningBraceRuleTest extends AbstractRuleTestCase { private static final String BLOCK_VIOLATION_MESSAGE = 'The opening brace for the block in class None is not preceded by a space or whitespace' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceBeforeOpeningBrace' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { def closure = { } if (true) { } while(ready) { } try { } catch(Exception e) { } finally { } for(int i=0; i<10; i++) { } for(String name in names) { } for(String name: names) { } if (count > this."maxPriority${priority}Violations") { } while (count > this."maxPriority${priority}Violations") { } } MyClass() { this(classNames) } } interface MyInterface { } enum MyEnum { OK, BAD } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ClassDeclaration_Violation() { final SOURCE = ''' class MyClass{ } class MyOtherClass extends AbstractClass{ } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyClass{', messageText:'The opening brace for class MyClass is not preceded'], [lineNumber:3, sourceLineText:'class MyOtherClass extends AbstractClass{ }', messageText:'The opening brace for class MyOtherClass is not preceded']) } @Test void testApplyTo_InterfaceDeclaration_Violation() { final SOURCE = ''' interface MyInterface{ } ''' assertSingleViolation(SOURCE, 2, 'interface MyInterface{ }', 'The opening brace for interface MyInterface is not preceded') } @Test void testApplyTo_EnumDeclaration_Violation() { final SOURCE = ''' enum MyEnum{ OK, BAD } c ''' assertSingleViolation(SOURCE, 2, 'enum MyEnum{ OK, BAD }', 'The opening brace for enum MyEnum is not preceded') } @Test void testApplyTo_Method_Violations() { final SOURCE = ''' def myMethod(){ } def otherMethod() { } // opening brace on separate line; no violation int putBulkAccountInfo(List<Map> jsonObject){ doStuff() } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def myMethod(){ }', messageText:'The opening brace for the method'], [lineNumber:6, sourceLineText:'int putBulkAccountInfo(List<Map> jsonObject){', messageText:'The opening brace for the method'] ) } @Test void testApplyTo_Constructor_Violations() { final SOURCE = ''' class MyClass { MyClass(){ } MyClass(int num){ doStuff() } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'MyClass(){ }', messageText:'The opening brace for the constructor in class MyClass'], [lineNumber:4, sourceLineText:'MyClass(int num){', messageText:'The opening brace for the constructor in class MyClass']) } @Test void testApplyTo_If_Violations() { final SOURCE = ''' if (ready){ } if (ready || done){ } if (ready) println '{' // no block; ignore ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (ready){ }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'done){ }', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_Else_Violations() { final SOURCE = ''' if (ready) { } else{} if (ready) {} else println '{' // no block; ignore ''' assertSingleViolation(SOURCE, 3, 'else{}', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_For_Violations() { final SOURCE = ''' for (int i=0; i<10; i++){ } for (int i=0; i<10; i++) println '{' // no block; ignore for (String name in names){ } for (String name: names){ } for (int i=0; i<10; i++){ } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'for (int i=0; i<10; i++){ }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'for (String name in names){ }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:5, sourceLineText:'for (String name: names){ }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:8, sourceLineText:'i++){ }', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_While_Violations() { final SOURCE = ''' while (ready){ } while (ready || done){ } while (ready) println '{' // no block; ignore ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'while (ready){ }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'done){ }', messageText:BLOCK_VIOLATION_MESSAGE], ) } @Test void testApplyTo_Try_Violations() { final SOURCE = ''' try{ } finally { } ''' assertSingleViolation(SOURCE, 2, 'try{ }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Catch_Violations() { final SOURCE = ''' try { } catch(Exception e){ } ''' assertSingleViolation(SOURCE, 2, 'catch(Exception e){ }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Finally_Violations() { final SOURCE = ''' try { } finally{ } ''' assertSingleViolation(SOURCE, 2, 'finally{ }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Switch_Violations() { final SOURCE = ''' switch (var){ } ''' assertSingleViolation(SOURCE, 2, 'switch (var){ }', 'The opening brace for the switch statement in class None') } @Test void testApplyTo_Closure_Violations() { final SOURCE = ''' list.each{ name -> } shouldFail(Exception){ doStuff() } def c ={ println 123 } def m = [a:123, b:{ println 7 }] ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'list.each{ name -> }', messageText:'The opening brace for the closure in class None is not preceded'], [lineNumber:3, sourceLineText:'shouldFail(Exception){ doStuff() }', messageText:'The opening brace for the closure in class None is not preceded'], [lineNumber:4, sourceLineText:'def c ={ println 123 }', messageText:'The opening brace for the closure in class None is not preceded'], [lineNumber:5, sourceLineText:'def m = [a:123, b:{ println 7 }]', messageText:'The opening brace for the closure in class None is not preceded']) } @Test void testApplyTo_UnicodeCharacterLiteral_CausesIncorrectColumnIndexesInAST_NoViolations_KnownIssue() { final SOURCE = ''' if (valid('\\u00A0')){ } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (valid(', messageText:BLOCK_VIOLATION_MESSAGE]) } @Test void testApplyTo_CheckClosureMapEntryValue_False_NoViolations() { final SOURCE = ''' def m = [a:123, b:{ println 7 }] ''' rule.checkClosureMapEntryValue = false assertNoViolations(SOURCE) } @Test void testApplyTo_CheckClosureAsFirstMethodParameter_NoViolations() { final SOURCE = ''' execute({ println 7 }, true) ''' assertNoViolations(SOURCE) } @Test void testApplyTo_GStringWithClosure_NoViolations() { assertNoViolations(''' def foo = 1 "I am a ${ -> foo }" ''') } protected Rule createRule() { new SpaceBeforeOpeningBraceRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/TrailingWhitespaceRuleTest.groovy��������0000644�0001750�0001750�00000005436�12407276321�031766� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for TrailingWhitespaceRule * * @author Joe Sondow */ class TrailingWhitespaceRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'TrailingWhitespace' } @Test void testSuccessScenario() { final SOURCE = '''\ package org.codenarc class MyClass { def go() { /* ... */ } def goSomewhere() { /* ... */ } } ''' assertNoViolations(SOURCE) } @Test void testLineEndingWithMultipleSpaces() { final SOURCE = 'class MyClass {} \n' assertSingleViolation(SOURCE, 1, 'class MyClass {} ', 'Line ends with whitespace characters') } @Test void testLineEndingWithOneSpace() { final SOURCE = 'class MyClass {} \n' assertSingleViolation(SOURCE, 1, 'class MyClass {} ', 'Line ends with whitespace characters') } @Test void testLineEndingWithATab() { final SOURCE = 'class MyClass {}\t\n' assertSingleViolation(SOURCE, 1, 'class MyClass {}\t', 'Line ends with whitespace characters') } @Test void testMultipleViolations() { final SOURCE = 'package org.codenarc \n' + '\n' + 'class MyClass {\t\n' + '\n' + ' def go() { /* ... */ } \n' + ' \n' + ' def stop() { /* ... */ }\n' + '}\t\n' def msg = 'Line ends with whitespace characters' assertViolations(SOURCE, [ [lineNumber: 1, sourceLineText: 'package org.codenarc ', messageText: msg], [lineNumber: 3, sourceLineText: 'class MyClass {\t', messageText: msg], [lineNumber: 5, sourceLineText: ' def go() { /* ... */ } ', messageText: msg], [lineNumber: 6, sourceLineText: ' ', messageText: msg], [lineNumber: 8, sourceLineText: '}\t', messageText: msg], ] as Map[]) } protected Rule createRule() { new TrailingWhitespaceRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/BlankLineBeforePackageRuleTest.groovy����0000644�0001750�0001750�00000005226�12311371417�032427� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BlankLineBeforePackageRule * * @author Joe Sondow */ @SuppressWarnings('ConsecutiveBlankLines') class BlankLineBeforePackageRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'BlankLineBeforePackage' } @Test void testSuccessScenarioWithPackage() { final SOURCE = '''\ package org.codenarc class MyClass { def go() { /* ... */ } def goSomewhere() { /* ... */ } } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenarioWithoutPackage() { final SOURCE = '''\ class MyClass { def go() { /* ... */ } def goSomewhere() { /* ... */ } } ''' assertNoViolations(SOURCE) } @Test void testFileStartsWithOneBlankLine() { final SOURCE = '''\ package org.codenarc class MyClass { void go() { /* ... */ } } ''' assertSingleViolation(SOURCE, 0, '', 'Blank line precedes package declaration in file null') } @Test void testFileStartsWithDoubleBlankLines() { final SOURCE = '''\ package org.codenarc class MyClass { void go() { /* ... */ } } ''' assertTwoViolations(SOURCE, 0, '', 1, '') } @Test void testBlankLineBetweenCommentAndPackage() { final SOURCE = '''\ /* Copyleft EFF */ package org.codenarc class MyClass { void go() { /* ... */ } } ''' assertSingleViolation(SOURCE, 1, '', 'Blank line precedes package declaration in file null') } protected Rule createRule() { new BlankLineBeforePackageRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAroundClosureArrowRuleTest.groovy���0000644�0001750�0001750�00000005421�12311373552�032744� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for SpaceAroundClosureArrowRule * * @author Chris Mair */ class SpaceAroundClosureArrowRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAroundClosureArrow' } @Test void testNoViolations() { final SOURCE = ''' def closure1 = { -> } def closure2 = { count -> } def closure3 = { count -> } def closure4 = { count\t->\t} def closure5 = { count -> } def closure6 = { count, name -> } ''' assertNoViolations(SOURCE) } @Test void testKnownLimitation_ClosureErrorOnSeparateLine_NoViolations() { final SOURCE = ''' def closure5 = { count, name ->} ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' def closure1 = {->} def closure2 = { ->} def closure3 = {-> } def closure4 = { count-> println 123 } def closure5 = { count, name ->println 123 } def closure6 = { ->println 123 } ''' final MESSAGE = 'The closure arrow (->) within class None is not surrounded by a space or whitespace' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def closure1 = {->}', messageText:MESSAGE], [lineNumber:3, sourceLineText:'def closure2 = { ->}', messageText:MESSAGE], [lineNumber:4, sourceLineText:'def closure3 = {-> }', messageText:MESSAGE], [lineNumber:5, sourceLineText:'def closure4 = { count-> println 123 }', messageText:MESSAGE], [lineNumber:6, sourceLineText:'def closure5 = { count, name ->println 123 }', messageText:MESSAGE], [lineNumber:7, sourceLineText:'def closure6 = { ->println 123', messageText:MESSAGE]) } protected Rule createRule() { new SpaceAroundClosureArrowRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterSemicolonRuleTest.groovy�������0000644�0001750�0001750�00000007401�12311370173�032052� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterSemicolonRule * * @author Chris Mair */ class SpaceAfterSemicolonRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterSemicolon' } // Tests for multiple statements per line @Test void testApplyTo_MultipleStatementsPerLine_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { println 1; println 2 int i=0;\ti++; println i def closure = { x -> println x; x = 23; } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MultipleStatementsPerLine_Violations() { final SOURCE = ''' class MyTestCase { def myMethod() { println 1;println 2 int i=0;i++;println i def closure = { x -> println x;x = 23; } } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'println 1;println 2', messageText:'The statement "println 2"'], [lineNumber:5, sourceLineText:'int i=0;i++;println i', messageText:'The statement "i++"'], [lineNumber:5, sourceLineText:'int i=0;i++;println i', messageText:'The statement "println i"'], [lineNumber:6, sourceLineText:'def closure = { x -> println x;x = 23; }', messageText:'The statement "x = 23"'] ) } // Tests for classic for statements @Test void testApplyTo_ForStatement_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { for(int i=0; i<10;\ti++) { } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NewForStatement_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { for (x in list) { } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ForStatement_Violations() { final SOURCE = ''' class MyTestCase { def myMethod() { for (int i=0;i<10;i++) { for (int j=0; j < 10;j++) { } } } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'for (int i=0;i<10;i++) {', messageText:'The for loop expression "i<10"'], [lineNumber:4, sourceLineText:'for (int i=0;i<10;i++) {', messageText:'The for loop expression "i++"'] , [lineNumber:5, sourceLineText:'for (int j=0; j < 10;j++) { }', messageText:'The for loop expression "j++"'] ) } protected Rule createRule() { new SpaceAfterSemicolonRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterOpeningBraceRuleTest.groovy����0000644�0001750�0001750�00000024327�12461202264�032465� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterOpeningBraceRule * * @author Chris Mair */ class SpaceAfterOpeningBraceRuleTest extends AbstractRuleTestCase { private static final String BLOCK_VIOLATION_MESSAGE = 'The opening brace for the block in class None is not followed by a space or whitespace' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterOpeningBrace' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { def closure = { } if (true) { } while(ready) { } try { } catch(Exception e) { } finally { } for(int i=0; i<10; i++) { } for(String name in names) { } for(String name: names) { } if (count > this."maxPriority${priority}Violations") { } while (count > this."maxPriority${priority}Violations") { } } MyClass() { this(classNames) } } interface MyInterface { } enum MyEnum { OK, BAD } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ProperSpacingWithoutIgnoreEmptyBlock_OneViolations() { final SOURCE = ''' class MyClass { def myMethod() { def closure = {} } } ''' assertSingleViolation(SOURCE, 4, 'def closure = {}', 'The opening brace for the closure in class MyClass is not followed by a space or whitespace') } @Test void testApplyTo_ProperSpacingWithIgnoreEmptyBlock_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { def closure = {} if (true) {} while(ready) {} try { } catch(Exception e) { } finally {} for(int i=0; i<10; i++) {} for(String name in names) {} for(String name: names) {} if (count > this."maxPriority${priority}Violations") {} while (count > this."maxPriority${priority}Violations") {} } void doStuff2() {} } interface MyInterface2 {} ''' rule.ignoreEmptyBlock = true assertNoViolations(SOURCE) } @Test void testApplyTo_ClassDeclaration_Violation() { final SOURCE = ''' class MyClass {int count } class MyOtherClass extends AbstractClass {int count } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyClass {int count }', messageText:'The opening brace for class MyClass is not followed'], [lineNumber:3, sourceLineText:'class MyOtherClass extends AbstractClass {int count }', messageText:'The opening brace for class MyOtherClass is not followed']) } @Test void testApplyTo_ClassDeclarationOnMultipleLines_Violation() { final SOURCE = ''' // starts at leftmost column class MyTest extends AbstractTest implements ManualTest { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_InterfaceDeclaration_Violation() { final SOURCE = ''' interface MyInterface {static final COUNT = 1 } ''' assertSingleViolation(SOURCE, 2, 'interface MyInterface {static final COUNT = 1 }', 'The opening brace for interface MyInterface is not followed') } @Test void testApplyTo_EnumDeclaration_Violation() { final SOURCE = ''' enum MyEnum {OK, BAD } c ''' assertSingleViolation(SOURCE, 2, 'enum MyEnum {OK, BAD }', 'The opening brace for enum MyEnum') } @Test void testApplyTo_Method_Violations() { final SOURCE = ''' def myMethod() {int count } def otherMethod() {int count } def bigMethod( String name) {println 9 } def myMethod2() { int count } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def myMethod() {int count }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'{int count }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:6, sourceLineText:'{println 9 }', messageText:BLOCK_VIOLATION_MESSAGE]) } @Test void testApplyTo_Constructor_Violations() { final SOURCE = ''' class MyClass { MyClass() {int count } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'MyClass() {int count }', messageText:'The opening brace for the block in class MyClass']) } @Test void testApplyTo_If_Violations() { final SOURCE = ''' if (ready) {println 9 } if (ready || done) {println 9 } if (ready) println '{' // no block; ignore ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (ready) {println 9 }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'done) {println 9 }', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_Else_Violations() { final SOURCE = ''' if (ready) { } else {println 9 } if (ready) { } else println '{' // no block; ignore ''' assertSingleViolation(SOURCE, 3, 'else {println 9 }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_For_Violations() { final SOURCE = ''' for (int i=0; i<10; i++) {println i } for (int i=0; i<10; i++) println '{' // no block; ignore for (String name in names) {println name } for (String name: names) {println name } for (int i=0; i<10; i++) {println name } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'for (int i=0; i<10; i++) {println i }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'for (String name in names) {println name }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:5, sourceLineText:'for (String name: names) {println name }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:8, sourceLineText:'i++) {println name }', messageText:BLOCK_VIOLATION_MESSAGE] ) } @Test void testApplyTo_While_Violations() { final SOURCE = ''' while (ready) {println name } while (ready || done) {println name } while (ready) println '{' // no block; ignore ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'while (ready) {println name }', messageText:BLOCK_VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'done) {println name }', messageText:BLOCK_VIOLATION_MESSAGE], ) } @Test void testApplyTo_Try_Violations() { final SOURCE = ''' try {doStuff() } finally { } ''' assertSingleViolation(SOURCE, 2, 'try {doStuff() }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Catch_Violations() { final SOURCE = ''' try { } catch(Exception e) {doStuff() } ''' assertSingleViolation(SOURCE, 2, 'catch(Exception e) {doStuff() }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Finally_Violations() { final SOURCE = ''' try { } finally {doStuff() } ''' assertSingleViolation(SOURCE, 2, 'finally {doStuff() }', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_Closure_Violations() { final SOURCE = ''' list.each {name -> } shouldFail(Exception) {doStuff() } def c = {println 123 } def m = [a:123, b: {println 7 }] ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'list.each {name -> }', messageText:'The opening brace for the closure in class None'], [lineNumber:3, sourceLineText:'shouldFail(Exception) {doStuff() }', messageText:'The opening brace for the closure in class None'], [lineNumber:4, sourceLineText:'def c = {println 123 }', messageText:'The opening brace for the closure in class None'], [lineNumber:5, sourceLineText:'def m = [a:123, b: {println 7 }]', messageText:'The opening brace for the closure in class']) } @Test void testApplyTo_UnicodeCharacterLiteral_Violation() { final SOURCE = ''' if (valid('\\u00A0')) {println 9 } ''' assertSingleViolation(SOURCE, 2, 'if (valid', BLOCK_VIOLATION_MESSAGE) } @Test void testApplyTo_CheckClosureMapEntryValue_False_NoViolations() { final SOURCE = ''' def m = [a:123, b: {println 7 }] ''' rule.checkClosureMapEntryValue = false assertNoViolations(SOURCE) } protected Rule createRule() { new SpaceAfterOpeningBraceRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000175�00000000000�011606� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/ClosureStatementOnOpeningLineOfMultipleLineClosureRuleTest.groovy����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/ClosureStatementOnOpeningLineOfMultipleLi0000644�0001750�0001750�00000007125�12325020371�033364� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for ClosureStatementOnOpeningLineOfMultipleLineClosureRule * * @author Chris Mair */ class ClosureStatementOnOpeningLineOfMultipleLineClosureRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ClosureStatementOnOpeningLineOfMultipleLineClosure' } @Test void testMultiLineClosure_NoViolations() { final SOURCE = ''' def closure1 = { name -> println name addToCounts() println "done" } def closure2 = { println name addToCounts() println "done" } ''' assertNoViolations(SOURCE) } @Test void testSingleLineClosure_NoViolations() { final SOURCE = ''' def closure = { name -> println name } ''' assertNoViolations(SOURCE) } @Test void testSingleLineClosure_WithMultipleStatements_NoViolations() { final SOURCE = ''' def sourceAnalyzer = [analyze: { rs -> ruleSet = rs; RESULTS }, getSourceDirectories: { SOURCE_DIRS }] as SourceAnalyzer ''' assertNoViolations(SOURCE) } @Test void testEmptyClosure_NoViolations() { final SOURCE = ''' def closure1 = { -> } def closure2 = { } ''' assertNoViolations(SOURCE) } @Test void testMultiLineClosure_MultipleStatements_Violation() { final SOURCE = ''' def closure = { name -> println name # The multi-line closure within class None contains a statement on the opening line of the closure addToCounts() println “done” } ''' assertInlineViolations(SOURCE) } @Test void testMultiLineClosure_SingleStatement_Violation() { final SOURCE = ''' def closure = { name -> doStuff(name, # The multi-line closure within class None contains a statement on the opening line of the closure 97, 'sample text') } ''' assertInlineViolations(SOURCE) } @Test void testEmptyClosure_NoViolation() { final SOURCE = ''' doStuff { } assertCondition(TEXT, 'Info') { } ''' assertNoViolations(SOURCE) } @Test void test_ClosureMapEntry_NoViolation() { final SOURCE = ''' def m = [isOkay:{ return true } ] resource.authenticationDao = [ getPlans:{ ssn, birthDate -> throw new NoMatchingDataException() }, isHandler:{ return true} ] as AuthenticationDao ''' assertNoViolations(SOURCE) } protected Rule createRule() { new ClosureStatementOnOpeningLineOfMultipleLineClosureRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/formatting/SpaceAfterIfRuleTest.groovy��������������0000644�0001750�0001750�00000004636�12461030201�030456� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.formatting import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpaceAfterIfRule * * @author Chris Mair */ class SpaceAfterIfRuleTest extends AbstractRuleTestCase { private static final MESSAGE = 'The if keyword within class None is not followed by a single space' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'SpaceAfterIf' } @Test void testApplyTo_ProperSpacing_NoViolations() { final SOURCE = ''' if (true) { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SyntheticIf_NoViolations() { final SOURCE = ''' enum MavenScope { COMPILE, RUNTIME, TEST, PROVIDED, SYSTEM } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IfWithoutSingleSpace_Violation() { final SOURCE = ''' if(true) { } if (true) { } if( true) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if(true) { }', messageText:MESSAGE], [lineNumber:3, sourceLineText:'if (true) { }', messageText:MESSAGE], [lineNumber:4, sourceLineText:'if(', messageText:MESSAGE]) } @Test void testApplyTo_KeywordAfterLabel_NoViolations() { final SOURCE = ''' def "sample test"() { setup: if (true) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new SpaceAfterIfRule() } } ��������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/AbstractAstVisitorTest.groovy�����������������������0000644�0001750�0001750�00000007300�12311373552�026757� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule import org.codehaus.groovy.ast.stmt.IfStatement import org.codehaus.groovy.ast.stmt.ReturnStatement import org.codenarc.source.SourceString import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test /** * Tests for AbstractAstVisitor * * @author Chris Mair * @author Hamlet D'Arcy */ class AbstractAstVisitorTest extends AbstractTestCase { private static final LONG_LINE = 'println "prefix"; if (true) println "1234567890123456789012345678901234567890123456789012345678901234567890"' private static final INDENT = ' ' private static final SOURCE = """class ABC { def justReturn() { println "about to return"; return "ABC" } def printVeryLongLine() { $LONG_LINE } } """ private astVisitor private sourceCode private rule @Test void testIsFirstVisit() { assert astVisitor.isFirstVisit('abc') assert !astVisitor.isFirstVisit('abc') assert astVisitor.isFirstVisit('def') } @Test void testSourceLine_ASTNode() { assert astVisitor.sourceLineTrimmed(astVisitor.returnStatement) == 'println "about to return"; return "ABC"' assert astVisitor.sourceLine(astVisitor.returnStatement) == INDENT + 'println "about to return"; return "ABC"' } @Test void testLastSourceLine_ASTNode() { assert astVisitor.lastSourceLineTrimmed(astVisitor.returnStatement) == 'println "about to return"; return "ABC"' assert astVisitor.lastSourceLine(astVisitor.returnStatement) == INDENT + 'println "about to return"; return "ABC"' } @Test void testSourceLine_ASTNode_LongLine() { assert astVisitor.sourceLineTrimmed(astVisitor.ifStatement) == LONG_LINE assert astVisitor.sourceLine(astVisitor.ifStatement) == INDENT + LONG_LINE } @Test void testAddViolation() { assert astVisitor.violations == [] astVisitor.addViolation(astVisitor.returnStatement) assert astVisitor.violations.size() == 1 def v = astVisitor.violations[0] assert v.sourceLine == 'println "about to return"; return "ABC"' assert v.rule == rule assert v.lineNumber == 3 } @Before void setUpAbstractAstVisitorTest() { sourceCode = new SourceString(SOURCE) rule = [getName : { 'DummyRule' } ] as Rule astVisitor = new FakeAstVisitor1(rule:rule, sourceCode:sourceCode) def ast = sourceCode.ast astVisitor.visitClass(ast.classes[0]) } } // Test AstVisitor implementation class class FakeAstVisitor1 extends AbstractAstVisitor { def returnStatement def ifStatement void visitReturnStatement(ReturnStatement returnStatement) { this.returnStatement = returnStatement super.visitReturnStatement(returnStatement) } void visitIfElse(IfStatement ifStatement) { this.ifStatement = ifStatement super.visitIfElse(ifStatement) } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/����������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022204� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitPublicNonTestMethodRuleTest.groovy�������0000644�0001750�0001750�00000014677�12311373552�032030� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitPublicNonTestMethodRule * * @author Chris Mair */ class JUnitPublicNonTestMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitPublicNonTestMethod' } @Test void testApplyTo_PublicNonTestMethod() { final SOURCE = ''' class MyTestCase extends GroovyTestCase { void doSomething() { // this does not need to be public } } ''' assertSingleViolation(SOURCE, 3, 'void doSomething() {') } @Test void testApplyTo_TwoPublicMethods() { final SOURCE = ''' class MyTest extends GroovyTestCase { boolean isThisNecessary() { false } void testSomething() { assert count > 0 } void doSomething() { // this does not need to be public } } ''' assertTwoViolations(SOURCE, 3, 'boolean isThisNecessary() { false }', 7, 'void doSomething() {') } @Test void testApplyTo_MethodNameStartsWithTestButHasParameters() { final SOURCE = ''' class MyTest extends GroovyTestCase { void testSomething(int count) { // this is not a test method } } ''' assertSingleViolation(SOURCE, 3, 'void testSomething(int count) {') } @Test void testApplyTo_TestMethodsOnly() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testSomething() { println 'ok' } void testOther() { println 'ok' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoresConstructors() { final SOURCE = ''' class MyTest extends GroovyTestCase { public MyTest() { } public MyTest(int count) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpAndTearDown() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testSomething() { println 'ok' } void doSomething() { // this does not need to be public } void setUp() { super.setUp() } void tearDown() { super.tearDown() } } ''' assertSingleViolation(SOURCE, 5, 'void doSomething() {') } @Test void testApplyTo_TestAnnotation() { final SOURCE = ''' class MyTest extends GroovyTestCase { @Test(expected = MyException.class) void shouldSendEmail() { assert count == 0 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_BeforeAnnotation() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testSomething() { println 'ok' } @Before void init() { println 'ok' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AfterAnnotation() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testSomething() { println 'ok' } @After void cleanUp() { println 'done' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_BeforeClassAnnotation() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testSomething() { println 'ok' } @BeforeClass void initClass() { println 'ok' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AfterClassAnnotation() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testSomething() { println 'ok' } @AfterClass void cleanUp() { println 'done' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_StaticMethods() { final SOURCE = ''' class MyTest extends GroovyTestCase { static int calculate() { 23 } public static boolean isReady() { true } private static String appendName(String n) { n } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoPublicNonTestMethods() { final SOURCE = ''' class MyTest extends GroovyTestCase { void testSomething() { assert count > 0 } protected boolean isReady() { true } private int calculate() { 23 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonTestClass() { final SOURCE = ''' class MyClass { public doSomething() { } } ''' assertNoViolations(SOURCE) } @Test void testThatAtOverrideSuppressesViolation() { final SOURCE = ''' class MyTest { @Override public doSomething() { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitPublicNonTestMethodRule() } } �����������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitLostTestRuleTest.groovy������������������0000644�0001750�0001750�00000007223�12311373552�027704� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitLostTestRule * * @author Chris Mair */ class JUnitLostTestRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitLostTest' } @Test void testApplyTo_NonMatchingMethods_NoViolations() { final SOURCE = ''' import org.junit.Test class MyTestCase { void doSomething() { } // not named test*() void testMe1(int count) { } // not zero-arg int testMe2() { } // not void private void testMe3() { } // not public static void testMe4() { } // static } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NotJUnit4TestClass_NoViolations() { final SOURCE = ''' class MyTestCase { void testMe() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AnnotatedWithTest_NoViolations() { final SOURCE = ''' import org.junit.Test class MyTestCase { @Test void testMe() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PublicVoidTestMethod_NoTestAnnotation_Violation() { final SOURCE = ''' import org.junit.Test class MyTestCase { void testMe() { } } ''' assertSingleViolation(SOURCE, 4, 'void testMe() { }') } @Test void testApplyTo_ExplicitlyDeclaredPublicMethod_Violation() { final SOURCE = ''' import org.junit.Test class MyTestCase { public void testMe() { } } ''' assertSingleViolation(SOURCE, 4, 'public void testMe() { }') } @Test void testApplyTo_OtherJUnit4Imports() { final SOURCE = ''' import org.junit.After class MyTestCase { void testMe() { } } ''' assertSingleViolation(SOURCE, 4, 'void testMe() { }') } @Test void testApplyTo_StarImportOfJUnit4Package() { final SOURCE = ''' import org.junit.* class MyTestCase { void testMe() { } } ''' assertSingleViolation(SOURCE, 4, 'void testMe() { }') } @Test void testApplyTo_NonTestClass_NoViolations() { final SOURCE = ''' import org.junit.* class MyOtherClass { void testMe() { } } ''' sourceCodePath = 'src/MyController.groovy' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitLostTestRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000152�00000000000�011601� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitAssertEqualsConstantActualValueRuleTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitAssertEqualsConstantActualValueRuleTest.g0000644�0001750�0001750�00000007352�12311373552�033304� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for JUnitAssertEqualsConstantActualValueRule * * @author Artur Gajowy */ class JUnitAssertEqualsConstantActualValueRuleTest extends AbstractRuleTestCase { @Before void setup() { sourceCodePath = '/src/test/SampleTest.groovy' } @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitAssertEqualsConstantActualValue' } @Test void testNoViolations() { final SOURCE = ''' import org.junit.Test import static org.junit.Assert.assertEquals class SampleTest { @Test def shouldFoo() { //when int result = 2 //then assertEquals(2, result) assertEquals("Message", 2, result) assertEquals(2.3d, result, 0.5d) assertEquals("Message", 2.3d, result, 0.5d) } } ''' assertNoViolations(SOURCE) } @Test void testProductionSourceNotChecked() { sourceCodePath = '/src/main/ProductionCode.groovy' assertNoViolations(SOURCE_WITH_SINGLE_VIOLATION) } @Test void testSingleViolation() { assertSingleViolation(SOURCE_WITH_SINGLE_VIOLATION, 4, 'Assert.assertEquals(sum, 2)', VIOLATION_MESSAGE) } private static final String SOURCE_WITH_SINGLE_VIOLATION = ''' import org.junit.Assert def sum = 1 + 1 Assert.assertEquals(sum, 2) ''' @Test void testMultipleViolations() { final SOURCE = ''' import org.junit.Test import static org.junit.Assert.assertEquals class SampleTest { @Test def shouldFoo() { //when int result = 2 //then assertEquals(result, 2) assertEquals("Message", result, 2) assertEquals(result, 2.3d, 0.5d) assertEquals("Message", result, 2.3d, 0.5d) } } ''' assertViolations(SOURCE, [lineNumber: 12, sourceLineText: 'assertEquals(result, 2)', messageText: VIOLATION_MESSAGE], [lineNumber: 13, sourceLineText: 'assertEquals("Message", result, 2)', messageText: VIOLATION_MESSAGE], [lineNumber: 14, sourceLineText: 'assertEquals(result, 2.3d, 0.5d)', messageText: VIOLATION_MESSAGE], [lineNumber: 15, sourceLineText: 'assertEquals("Message", result, 2.3d, 0.5d)', messageText: VIOLATION_MESSAGE] ) } private static final String VIOLATION_MESSAGE = 'Found `assertEquals` with literal or constant `actual` parameter. ' + 'Most likely it was intended to be the `expected` value.' protected Rule createRule() { new JUnitAssertEqualsConstantActualValueRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/CoupledTestCaseRuleTest.groovy����������������0000644�0001750�0001750�00000006627�12232065706�030210� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CoupledTestCaseRule * * @author 'Hamlet D'Arcy' */ class CoupledTestCaseRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CoupledTestCase' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { MyOtherObject.helperMethod() // OK, not test someTest.helperObject() // OK, not static new MyOtherObject() } } ''' assertNoViolations(SOURCE) } @Test void testStaticMethod() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { // violation, static method call to other test MyOtherTest.helperMethod() } } ''' assertSingleViolation(SOURCE, 5, 'MyOtherTest.helperMethod()', 'MyOtherTest.helperMethod() invokes a method on another test case. Test cases should not be coupled. Move this method to a helper object') } @Test void testInstantiation() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { // violation, instantiation of another test class new MyOtherTest() } } ''' assertSingleViolation(SOURCE, 5, 'new MyOtherTest()', 'new MyOtherTest() creates an instance of a test case. Test cases should not be coupled. Move this method to a helper object') } @Test void testStaticReferenceToSameClass_DefaultPackage_NoViolation() { final SOURCE = ''' class MyTest extends GroovyTestCase { void testMethod() { def input = MyTest.getResourceAsStream('sample.txt') } } ''' assertNoViolations(SOURCE) } @Test void testStaticReferenceToSameClass_WithinPackage_NoViolation() { final SOURCE = ''' package com.example class MyTest extends GroovyTestCase { void testMethod() { def input = MyTest.getResourceAsStream('sample.txt') def otherInput = com.example.MyTest.getResourceAsStream('other.txt') } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CoupledTestCaseRule() } } ���������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertTrueInsteadOfAssertEqualsRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertTrueInsteadOfAssertEqualsRuleTest.gro0000644�0001750�0001750�00000013550�12467726154�033337� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseAssertTrueInsteadOfAssertEqualsRule * * @author Hamlet D'Arcy */ class UseAssertTrueInsteadOfAssertEqualsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UseAssertTrueInsteadOfAssertEquals' assert rule.checkAssertStatements == false } @Test void testNoViolations() { final SOURCE = ''' class MyTestCase extends TestCase { @Test void testMethod() { assertEquals(1, foo()) assertEquals('message', foo()) assertTrue(foo()) assertTrue('message', foo()) assertSame(foo(), foo()) assertTrue(foo() > bar()) assert 1 == foo() assert 'message' == foo() assert foo() assert foo() : 'message' assert foo().is(foo()) assert foo() > bar() } } ''' assertNoViolations(SOURCE) } @Test void testAssertTrueViolation() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertEquals(true, foo()) assertEquals("message", true, foo()) } } ''' assertTwoViolations(SOURCE, 4, 'assertEquals(true, foo())', 5, 'assertEquals("message", true, foo())') } @Test void testAssertStatement_True_checkAssertStatements_True_Violations() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assert true == foo() assert foo() == true : "message" } } ''' rule.checkAssertStatements = true assertTwoViolations(SOURCE, 4, 'assert true == foo()', "The expression '(true == this.foo())' can be simplified to 'this.foo()'", 5, 'assert foo() == true : "message"', "The expression '(this.foo() == true)' can be simplified to 'this.foo()'") } @Test void testAssertStatement_True_checkAssertStatements_False_Violations() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assert true == foo() assert foo() == true : "message" } } ''' assertNoViolations(SOURCE) } @Test void testAssertTrueViolation_Backwards() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertEquals(foo(), true) assertEquals("message", foo(), true) } } ''' assertTwoViolations(SOURCE, 4, 'assertEquals(foo(), true)', 5, 'assertEquals("message", foo(), true)') } @Test void testAssertFalseViolation() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertEquals(false, foo()) assertEquals("message", false, foo()) } } ''' assertTwoViolations(SOURCE, 4, 'assertEquals(false, foo())', 5, 'assertEquals("message", false, foo())') } @Test void testAssertStatement_False_checkAssertStatements_True_Violations() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assert false == foo() assert foo() == false : "message" } } ''' rule.checkAssertStatements = true assertTwoViolations(SOURCE, 4, 'assert false == foo()', "The expression '(false == this.foo())' can be simplified to '!this.foo()'", 5, 'assert foo() == false : "message"', "The expression '(this.foo() == false)' can be simplified to '!this.foo()'") } @Test void testAssertStatement_False_checkAssertStatements_False_NoViolations() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assert false == foo() assert foo() == false : "message" } } ''' assertNoViolations(SOURCE) } @Test void testAssertFalseViolation_Backwards() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertEquals(foo(), false) assertEquals("message", foo(), false) } } ''' assertTwoViolations(SOURCE, 4, 'assertEquals(foo(), false)', 5, 'assertEquals("message", foo(), false)') } protected Rule createRule() { new UseAssertTrueInsteadOfAssertEqualsRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitTestMethodWithoutAssertRuleTest.groovy���0000644�0001750�0001750�00000013545�12443420675�032762� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitTestMethodWithoutAssertRule * * @author Hamlet D'Arcy */ class JUnitTestMethodWithoutAssertRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitTestMethodWithoutAssert' } @Test void testAnnotatedMethods_SuccessScenario() { final SOURCE = ''' class MyTest { @Test void someTestMethod1() { assert 1 == 2 } @Test void someTestMethod2() { assertEquals(1, 2) } @org.junit.Test void someTestMethod3() { assert 1 == 2 } @org.junit.Test void someTestMethod4() { assertEquals(1, 2) } } ''' assertNoViolations(SOURCE) } @Test void testAnnotatedMethodsWithAnnotationParameters_SuccessScenario() { final SOURCE = ''' class MyTest { @Test(expected = IllegalArgumentException) void someTestMethod1() { doSomething() } @Test(timeout = 1000) void someTestMethod2() { doSomething() } @org.junit.Test(expected = IllegalArgumentException) void someTestMethod3() { doSomething() } @org.junit.Test(timeout = 1000) void someTestMethod4() { doSomething() } } ''' assertNoViolations(SOURCE) } @Test void testJUnitStyleConventions_SuccessScenario() { final SOURCE = ''' class MyTest { private void testPrivate() { // ignored because method is private } int testIntMethod() { // ignored because method returns int } void testMethod1() { assert 1 == 2 } void testMethod2() { assertEquals(1, 2) } void testMethod3() { shouldFail { foo() } } void testMethod4() { fail() } void testMethod5() { verify() } } ''' assertNoViolations(SOURCE) } @Test void testViolationWithMethodNameConvention() { final SOURCE = ''' class MyTest { void testMethod() { doSomething() doSomethingElse() // where is the assertion? } } ''' assertSingleViolation(SOURCE, 3, 'void testMethod()', "Test method 'testMethod' makes no assertions") } @Test void testViolationWithEmptyBody() { final SOURCE = ''' class MyTest { void testMethod() { } } ''' assertSingleViolation(SOURCE, 3, 'void testMethod()', "Test method 'testMethod' makes no assertions") } @Test void testViolationWithTestAnnotation() { final SOURCE = ''' class MyTest { @Test void someMethod1() { doSomething() doSomethingElse() // where is the assertion? } @org.junit.Test @Unknown @YetAnotherAnnotation // these annotations ALSO test the line number fix void someMethod2() { doSomething() doSomethingElse() // where is the assertion? } } ''' assertTwoViolations(SOURCE, 4, 'void someMethod1()', "Test method 'someMethod1' makes no assertions", 12, 'void someMethod2()', "Test method 'someMethod2' makes no assertions") } @Test void testNoViolations_ExpectedExceptionSupport() { assertNoViolations(''' class MyTest { @Rule public ExpectedException exception = ExpectedException.none() @Test void myTest() { String nullString = null exception.expect(NullPointerException) nullString.toLowerCase() } @Test void myTest2() { exception.expectMessage('argument') throw new IllegalArgumentException('Illegal argument provided!') } } ''') } protected Rule createRule() { new JUnitTestMethodWithoutAssertRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitPublicPropertyRuleTest.groovy������������0000644�0001750�0001750�00000006074�12323636016�031111� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for JUnitPublicPropertyRule * * @author Chris Mair */ class JUnitPublicPropertyRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitPublicProperty' assert rule.applyToClassNames == DEFAULT_TEST_CLASS_NAMES } @Test void testTestClassWithNoProperties_NoViolations() { final SOURCE = ''' class MyTest { public static final MAX_VALUE = 1000 // field public int count // field private service // field @Test void testMe() { } } ''' assertNoViolations(SOURCE) } @Test void testNonTestClassWithProperty_NoViolations() { final SOURCE = ''' class MyClass { def id = 1234 String name } ''' assertNoViolations(SOURCE) } @Test void testTestClassWithProperty_Violation() { final SOURCE = ''' import org.junit.Test class MyTestCase { static String id // static property def helper // property String name // property @Test void testMe() { } } ''' def message = 'The test class %s contains a public property %s. There is usually no reason to have a public property (even a constant) on a test class.' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'static String id', messageText:String.format(message, 'MyTestCase', 'id')], [lineNumber:5, sourceLineText:'def helper', messageText:String.format(message, 'MyTestCase', 'helper')], [lineNumber:6, sourceLineText:'String name', messageText:String.format(message, 'MyTestCase', 'name')]) } @Test void testTestClassWithProperty_IgnorePropertyNames_NoViolations() { final SOURCE = ''' class MyTestCase { def helper // property String name // property } ''' rule.ignorePropertyNames = 'h*lper, name' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitPublicPropertyRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitAssertAlwaysFailsRuleTest.groovy���������0000644�0001750�0001750�00000022776�12311373552�031536� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitAssertAlwaysFailsRule * * @author Chris Mair */ class JUnitAssertAlwaysFailsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitAssertAlwaysFails' } // Tests for assertTrue() @Test void testApplyTo_AssertTrue_False() { final SOURCE = ''' class MyTestCase extends TestCase { void testSomething() { assertTrue(false) } } ''' assertSingleViolation(SOURCE, 4, 'assertTrue(false)') } @Test void testApplyTo_AssertTrue_True() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertTrue(true) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertTrue_ConstantNumber() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertTrue(1234) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertTrue_LiteralsThatEvaluateToFalse_Violations() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertTrue(0) assertTrue('error message', '') assertTrue([]) assertTrue('error message', [:]) assertTrue(99) // Not violations assertTrue('abc') assertTrue([123]) assertTrue([a:123]) } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'assertTrue(0)'], [lineNumber:5, sourceLineText:"assertTrue('error message', '')"], [lineNumber:6, sourceLineText:'assertTrue([])'], [lineNumber:7, sourceLineText:"assertTrue('error message', [:])"]) } @Test void testApplyTo_AssertTrue_Variable() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertTrue(myVariable) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertTrue_FalseWithMessage() { final SOURCE = ''' class MyTest extends TestCase { def myClosure = { assertTrue("This passed!", false) } } ''' assertSingleViolation(SOURCE, 4, 'assertTrue("This passed!", false)') } // Tests for assertFalse() @Test void testApplyTo_AssertFalse_True() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertFalse(true) } } ''' assertSingleViolation(SOURCE, 4, 'assertFalse(true)') } @Test void testApplyTo_AssertFalse_False() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertFalse(false) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertFalse_TrueWithMessage() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertFalse("This passed!", true) } } ''' assertSingleViolation(SOURCE, 4, 'assertFalse("This passed!", true)') } @Test void testApplyTo_AssertFalse_LiteralsThatEvaluateToTrue_Violations() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertFalse(99) assertFalse('error message', 'abc') assertFalse([123]) assertFalse('error message', [a:123]) assertFalse(0) // Not violations assertFalse('') assertFalse([]) assertFalse([:]) } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'assertFalse(99)'], [lineNumber:5, sourceLineText:"assertFalse('error message', 'abc')"], [lineNumber:6, sourceLineText:'assertFalse([123])'], [lineNumber:7, sourceLineText:"assertFalse('error message', [a:123])"]) } // Tests for assertNull @Test void testApplyTo_AssertNull_ConstantNumber() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull(123) } } ''' assertSingleViolation(SOURCE, 4, 'assertNull(123)') } @Test void testApplyTo_AssertNull_ConstantString() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull('abc') } } ''' assertSingleViolation(SOURCE, 4, "assertNull('abc')") } @Test void testApplyTo_AssertNull_ConstantBoolean() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull(false) } } ''' assertSingleViolation(SOURCE, 4, 'assertNull(false)') } @Test void testApplyTo_AssertNull_LiteralListOrMap() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull([]) assertNull([123]) assertNull([a:123]) assertNull([:]) } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'assertNull([])'], [lineNumber:5, sourceLineText:'assertNull([123])'], [lineNumber:6, sourceLineText:'assertNull([a:123])'], [lineNumber:7, sourceLineText:'assertNull([:])']) } @Test void testApplyTo_AssertNull_NonConstant() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull(plugin) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertNull_Null() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull(null) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertNull_NullWithMessage() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull("What?", false) } } ''' assertSingleViolation(SOURCE, 4, 'assertNull("What?", false)') } // Tests for assertNotNull @Test void testApplyTo_AssertNotNull_Null() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNotNull(null) } } ''' assertSingleViolation(SOURCE, 4, 'assertNotNull(null)') } @Test void testApplyTo_AssertNotNull_NonNullValues() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNotNull(123) assertNotNull('abc') assertNotNull(true) assertNotNull(false) assertNotNull(Boolean.FALSE) assertNotNull([]) assertNotNull([123]) assertNotNull([:]) assertNotNull([a:123]) } } ''' assertNoViolations(SOURCE) } // Tests for non-Test files @Test void testApplyTo_NonTestFile() { final SOURCE = ''' class MyClass { void testSomething() { assertTrue(false) } } ''' sourceCodePath = 'src/MyController.groovy' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitAssertAlwaysFailsRule() } } ��CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitUnnecessaryTearDownRuleTest.groovy�������0000644�0001750�0001750�00000007410�12041637550�032065� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitUnnecessaryTearDown * * @author Chris Mair */ class JUnitUnnecessaryTearDownRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'JUnitUnnecessaryTearDown' } @Test void testApplyTo_TearDownOnlyCallsSuperTearDown_Violation() { final SOURCE = ''' class MyTestCase extends TestCase { void tearDown() { super.tearDown() } } ''' assertSingleViolation(SOURCE, 3, 'void tearDown() {') } @Test void testApplyTo_TearDownCallsSuperTearDownAndSomethingElse() { final SOURCE = ''' class MyTest extends TestCase { void tearDown() { super.tearDown() println 'bad' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_TearDownDoesNotCallSuperTearDown() { final SOURCE = ''' class MyTest extends TestCase { void tearDown() { println 'bad' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_TearDownDoesNotCallSuperTearDown_CallsSuper() { final SOURCE = ''' class MyTest extends TestCase { void tearDown() { super.someOtherMethod() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_TearDownDoesNotCallSuperTearDown_CallsTearDown() { final SOURCE = ''' class MyTest extends TestCase { void tearDown() { other.tearDown() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_TearDownMethodHasAfterAnnotation() { final SOURCE = ''' class MyTest extends TestCase { @After void tearDown() { super.tearDown() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonTearDownMethod() { final SOURCE = ''' class MyTest extends TestCase { def otherMethod() { super.tearDown() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_TearDownMethodHasParameters() { final SOURCE = ''' class MyTest extends TestCase { void tearDown(int count, String name) { super.tearDown() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonTestClass() { final SOURCE = ''' class MyClass { int count } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitUnnecessaryTearDownRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertEqualsInsteadOfAssertTrueRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertEqualsInsteadOfAssertTrueRuleTest.gro0000644�0001750�0001750�00000005701�12311370173�033316� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseAssertEqualsInsteadOfAssertTrueRule * * @author Per Junel * @author Hamlet D'Arcy */ class UseAssertEqualsInsteadOfAssertTrueRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UseAssertEqualsInsteadOfAssertTrue' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTestCase extends TestCase { @Test void testMethod() { assertEquals(1, foo()) assertTrue(foo()) assertTrue('message', foo()) assertSame(foo(), foo()) assertTrue(foo() > bar()) assertTrue('message', obj.foo() != obj.bar()) assertFalse(foo() == bar()) assertFalse('message', obj.foo() == obj.bar()) assertTrue(foo() != bar()) assertTrue('message', obj.foo() != obj.bar()) } } ''' assertNoViolations(SOURCE) } @Test void testEqualsInTrueTest() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertTrue(foo() == bar()) assertTrue('message', foo() == bar()) } } ''' assertTwoViolations(SOURCE, 4, 'assertTrue(foo() == bar())', 5, "assertTrue('message', foo() == bar())") } @Test void testNotEqualsInAssertFalseTest() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertFalse(foo() != bar()) assertFalse('message', obj.foo() != obj.bar()) } } ''' assertTwoViolations(SOURCE, 4, 'assertFalse(foo() != bar())', 5, "assertFalse('message', obj.foo() != obj.bar())") } protected Rule createRule() { new UseAssertEqualsInsteadOfAssertTrueRule() } } ���������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertFalseInsteadOfNegationRuleTest.groovy0000644�0001750�0001750�00000004677�12041642702�033332� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseAssertFalseInsteadOfNegationRule * * @author 'Hamlet D'Arcy' */ class UseAssertFalseInsteadOfNegationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UseAssertFalseInsteadOfNegation' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { assertFalse(condition) assertTrue(condition) assertTrue(!condition, condition) assertFalse(!condition, condition) } } ''' assertNoViolations(SOURCE) } @Test void testUsingThisReference() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { assertTrue(!condition) } } ''' assertSingleViolation(SOURCE, 4, 'assertTrue(!condition)', 'assertTrue(!condition) can be simplified to assertFalse(condition)') } @Test void testUsingStaticReference() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { Assert.assertTrue(!condition) } } ''' assertSingleViolation(SOURCE, 4, 'Assert.assertTrue(!condition)', 'Assert.assertTrue(!condition) can be simplified to Assert.assertFalse(condition)') } protected Rule createRule() { new UseAssertFalseInsteadOfNegationRule() } } �����������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/ChainedTestRuleTest.groovy��������������������0000644�0001750�0001750�00000006652�12043056332�027345� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ChainedTestRule * * @author Hamlet D'Arcy */ class ChainedTestRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ChainedTest' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testFoo() { // OK, no violation: one arg method is not actually a test method 5.times { testBar(it) } } private static void assertSomething() { foo.testBar() // not a self/this call Other.testBar() // not a self/this call } public void testBar() { // ... } } ''' assertNoViolations(SOURCE) } @Test void testSelfCallImpliedThis() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testFoo() { 5.times { testBar() } } } ''' assertSingleViolation(SOURCE, 4, 'testBar()', 'The test method testBar() is being invoked explicitly from within a unit test. Tests should be isolated and not dependent on one another') } @Test void testSelfCallExplicitThis() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testFoo() { 5.times { this.testBar() } } } ''' assertSingleViolation(SOURCE, 4, 'this.testBar()', 'The test method testBar() is being invoked explicitly from within a unit test. Tests should be isolated and not dependent on one another') } @Test void testCallsInHelperMethods() { final SOURCE = ''' class MyTest extends GroovyTestCase { private static void assertSomething() { testBar() // violation, even if in helper method this.testBar() // violation, even if in helper method } } ''' assertTwoViolations(SOURCE, 5, 'testBar()', 'The test method testBar() is being invoked explicitly from within a unit test. Tests should be isolated and not dependent on one another', 6, 'this.testBar()', 'The test method testBar() is being invoked explicitly from within a unit test. Tests should be isolated and not dependent on one another') } protected Rule createRule() { new ChainedTestRule() } } ��������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitUnnecessaryThrowsExceptionRuleTest.groovy0000644�0001750�0001750�00000015002�12311373552�033502� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for JUnitUnnecessaryThrowsExceptionRule * * @author Chris Mair */ class JUnitUnnecessaryThrowsExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'JUnitUnnecessaryThrowsException' } @Test void testAnnotatedMethods_NoThrows_NoViolations() { final SOURCE = ''' class MyTest { @Test void shouldDoSomething() { } @BeforeClass void initialize() { } @Before void setUp() { } @After void tearDown() { } @AfterClass void cleanUp() { } } ''' assertNoViolations(SOURCE) } @Test void testTestMethod_NoThrows_NoViolations() { final SOURCE = ''' class MyTest extends GroovyTestCase { void test1() { } } ''' assertNoViolations(SOURCE) } @Test void testPrivateOrProtectedMethod_WithThrows_NoViolations() { final SOURCE = ''' class MyTest extends GroovyTestCase { void test1() { } private void testStuff() throws Throwable { } protected void test3() throws IOException { } } ''' assertNoViolations(SOURCE) } @Test void testNonVoidMethod_WithThrows_NoViolations() { final SOURCE = ''' class MyTest extends GroovyTestCase { int test1() throws NullPointerException { } } ''' assertNoViolations(SOURCE) } @Test void testMethodWithArguments_WithThrows_NoViolations() { final SOURCE = ''' class MyTest extends GroovyTestCase { void test1(int count) throws RuntimeException { } void setUp(int count) throws RuntimeException { } void tearDown(int count) throws RuntimeException { } } ''' assertNoViolations(SOURCE) } @Test void testStaticMethod_WithThrows_NoViolations() { final SOURCE = ''' class MyTestCase extends GroovyTestCase { static void test1() throws RuntimeException { } } ''' assertNoViolations(SOURCE) } @Test void testNonTestMethod_WithThrows_NoViolations() { final SOURCE = ''' class MyTest extends GroovyTestCase { void other() throws RuntimeException { } } ''' assertNoViolations(SOURCE) } @Test void testNonAnnotatedNonTestMethod_WithThrows_NoViolations() { final SOURCE = ''' class MyTests { void other1() throws RuntimeException { } } ''' assertNoViolations(SOURCE) } @Test void testAnnotatedMethods_ThrowsClauses_Violations() { final SOURCE = ''' class MyTest { @Test void shouldDoStuff() throws Exception { } @BeforeClass void initialize() throws RuntimeException { } @Before void setUp() throws Exception { } @After void tearDown() throws Exception { } @AfterClass void cleanUp() throws Exception { } @Ignore void ignored() throws Exception { } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'void shouldDoStuff() throws Exception { }', messageText:'The shouldDoStuff method in class MyTest'], [lineNumber:6, sourceLineText:'@BeforeClass void initialize() throws RuntimeException { }', messageText:'The initialize method in class MyTest'], [lineNumber:7, sourceLineText:'@Before void setUp() throws Exception { }', messageText:'The setUp method in class MyTest'], [lineNumber:8, sourceLineText:'@After void tearDown() throws Exception { }', messageText:'The tearDown method in class MyTest'], [lineNumber:9, sourceLineText:'@AfterClass void cleanUp() throws Exception { }', messageText:'The cleanUp method in class MyTest'], [lineNumber:10, sourceLineText:'@Ignore void ignored() throws Exception { }', messageText:'The ignored method in class MyTest']) } @Test void testJUnit3TestMethod_Throws_Violations() { final SOURCE = ''' class MyTest extends GroovyTestCase { void test1() throws Exception { } public void test2() throws IOException { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'void test1() throws Exception { }', messageText:'The test1 method in class MyTest'], [lineNumber:4, sourceLineText:'public void test2() throws IOException { }', messageText:'The test2 method in class MyTest']) } @Test void testJUnit3SetUpOrTearDownMethod_Throws_Violations() { final SOURCE = ''' class MyTest extends GroovyTestCase { void setUp() throws Exception { } public void tearDown() throws IOException { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'void setUp() throws Exception { }', messageText:'The setUp method in class MyTest'], [lineNumber:4, sourceLineText:'public void tearDown() throws IOException { }', messageText:'The tearDown method in class MyTest']) } @Test void testApplyTo_NonTestClass() { final SOURCE = ''' class SomeClass { void test1() throws Exception { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitUnnecessaryThrowsExceptionRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitPublicFieldRuleTest.groovy���������������0000644�0001750�0001750�00000005641�12311373552�030307� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for JUnitPublicFieldRule * * @author Chris Mair */ class JUnitPublicFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'JUnitPublicField' } @Test void testTestClassWithNoPublicFields_NoViolations() { final SOURCE = ''' import org.junit.Test class MyTestCase { private service protected count = 99 def helper // this is a property, not a public field String name // this is a property, not a public field @Test void testMe() { } } ''' assertNoViolations(SOURCE) } @Test void testNonTestClassWithPublicFields_NoViolations() { final SOURCE = ''' class MyClass { public int count public static final MAX_VALUE = 1000 } ''' sourceCodePath = 'src/MyClass.groovy' assertNoViolations(SOURCE) } @Test void testClassWithPublicFieldsAnnotatedWithRule_NoViolations() { final SOURCE = ''' class MyTestCase { @Rule public TestName testName = new TestName() } ''' assertNoViolations(SOURCE) } @Test void testClassWithPublicFields_Violations() { final SOURCE = ''' import org.junit.Test class MyTestCase { public int count public static final MAX_VALUE = 1000 @Test void testMe() { } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'public int count', messageText:'count'], [lineNumber:5, sourceLineText:'public static final MAX_VALUE = 1000', messageText:'MAX_VALUE']) } @Test void testInterfaceWithPublicFields_NoViolations() { final SOURCE = ''' interface MyTest { public static final MAX_VALUE = 1000 } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitPublicFieldRule() } } �����������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitFailWithoutMessageRuleTest.groovy��������0000644�0001750�0001750�00000003621�12041642702�031661� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitFailWithoutMessageRule * * @author Hamlet D'Arcy */ class JUnitFailWithoutMessageRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitFailWithoutMessage' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTestCase extends TestCase { @Test void testMethod() { fail('msg') Assert.fail('msg') this.fail('msg') foo.fail() } } ''' assertNoViolations(SOURCE) } @Test void testFailCalls() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { fail() Assert.fail() } } ''' assertTwoViolations(SOURCE, 4, 'fail()', 5, 'Assert.fail()') } protected Rule createRule() { new JUnitFailWithoutMessageRule() } } ���������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitUnnecessarySetUpRuleTest.groovy����������0000644�0001750�0001750�00000007252�12041637206�031404� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitUnnecessarySetUp * * @author Chris Mair */ class JUnitUnnecessarySetUpRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'JUnitUnnecessarySetUp' } @Test void testApplyTo_SetUpOnlyCallsSuperSetUp_Violation() { final SOURCE = ''' class MyTestCase extends TestCase { void setUp() { super.setUp() } } ''' assertSingleViolation(SOURCE, 3, 'void setUp() {') } @Test void testApplyTo_SetUpCallsSuperSetUpAndSomethingElse() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { super.setUp() println 'bad' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpDoesNotCallSuperSetUp() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { println 'bad' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpDoesNotCallSuperSetUp_CallsSuper() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { super.someOtherMethod() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpDoesNotCallSuperSetUp_CallsSetUp() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { other.setUp() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpMethodHasBeforeAnnotation() { final SOURCE = ''' class MyTest extends TestCase { @Before void setUp() { super.setUp() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonSetUpMethod() { final SOURCE = ''' class MyTest extends TestCase { def otherMethod() { super.setUp() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpMethodHasParameters() { final SOURCE = ''' class MyTest extends TestCase { void setUp(int count, String name) { super.setUp() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonTestClass() { final SOURCE = ''' class MyClass { int count } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitUnnecessarySetUpRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertSameInsteadOfAssertTrueRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertSameInsteadOfAssertTrueRuleTest.groov0000644�0001750�0001750�00000005403�12311370173�033315� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseAssertSameInsteadOfAssertTrueRule * * @author Hamlet D'Arcy */ class UseAssertSameInsteadOfAssertTrueRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UseAssertSameInsteadOfAssertTrue' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTestCase extends TestCase { @Test void testMethod() { assertEquals(1, foo()) assertTrue(foo()) assertTrue(x) assertTrue('message', x) assertTrue('message', foo()) assertSame(foo(), foo()) assertTrue(foo() > bar()) assertTrue(foo().is(bar(), baz())) assertTrue(foo().is(bar()), x, y) } } ''' assertNoViolations(SOURCE) } @Test void testAssertSame() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertTrue(foo().is(bar())) assertTrue("message", foo().is(bar())) } } ''' assertTwoViolations(SOURCE, 4, 'assertTrue(foo().is(bar()))', 5, 'assertTrue("message", foo().is(bar()))') } @Test void testNotAssertSame() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertFalse(foo().is(bar())) assertFalse("message", foo().is(bar())) } } ''' assertTwoViolations(SOURCE, 4, 'assertFalse(foo().is(bar()))', 5, 'assertFalse("message", foo().is(bar()))') } protected Rule createRule() { new UseAssertSameInsteadOfAssertTrueRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitAssertAlwaysSucceedsRuleTest.groovy������0000644�0001750�0001750�00000022014�12311373552�032217� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitAssertAlwaysSucceedsRule * * @author Chris Mair */ class JUnitAssertAlwaysSucceedsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitAssertAlwaysSucceeds' } // Tests for assertTrue() @Test void testApplyTo_AssertTrue_False() { final SOURCE = ''' class MyTestCase extends TestCase { void testSomething() { assertTrue(false) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertTrue_True() { final SOURCE = ''' class MyTestCase extends TestCase { void testSomething() { assertTrue(true) } } ''' assertSingleViolation(SOURCE, 4, 'assertTrue(true)') } @Test void testApplyTo_AssertTrue_TrueWithMessage() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertTrue("This passed!", true) } } ''' assertSingleViolation(SOURCE, 4, 'assertTrue("This passed!", true)') } @Test void testApplyTo_AssertTrue_LiteralsThatEvaluateToTrue_Violations() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertTrue(99) // Not violations assertTrue('error message', 'abc') assertTrue([123]) assertTrue('error message', [a:123]) assertTrue(0) // Not violations assertTrue('error message', '') assertTrue([]) assertTrue('error message', [:]) } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'assertTrue(99)'], [lineNumber:5, sourceLineText:"assertTrue('error message', 'abc')"], [lineNumber:6, sourceLineText:'assertTrue([123])'], [lineNumber:7, sourceLineText:"assertTrue('error message', [a:123])"]) } // Tests for assertFalse() @Test void testApplyTo_AssertFalse_True() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertFalse(true) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertFalse_False() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertFalse(false) } } ''' assertSingleViolation(SOURCE, 4, 'assertFalse(false)') } @Test void testApplyTo_AssertFalse_FalseWithMessage() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertFalse("This passed!", false) } } ''' assertSingleViolation(SOURCE, 4, 'assertFalse("This passed!", false)') } @Test void testApplyTo_AssertFalse_LiteralsThatEvaluateToFalse_Violations() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertFalse(0) assertFalse('error message', '') assertFalse([]) assertFalse('error message', [:]) assertFalse(99) // Not violations assertFalse('abc') assertFalse([123]) assertFalse([a:123]) } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'assertFalse(0)'], [lineNumber:5, sourceLineText:"assertFalse('error message', '')"], [lineNumber:6, sourceLineText:'assertFalse([])'], [lineNumber:7, sourceLineText:"assertFalse('error message', [:])"]) } // Tests for assertNull() @Test void testApplyTo_AssertNull_NotNullConstant() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull(123) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertNull_Variable() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull(myVariable) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertNull_Null() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull(null) } } ''' assertSingleViolation(SOURCE, 4, 'assertNull(null)') } @Test void testApplyTo_AssertNull_NullWithMessage() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNull("This passed!", null) } } ''' assertSingleViolation(SOURCE, 4, 'assertNull("This passed!", null)') } // Tests for assertNotNull @Test void testApplyTo_AssertNotNull_ConstantNumber() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNotNull(123) } } ''' assertSingleViolation(SOURCE, 4, 'assertNotNull(123)') } @Test void testApplyTo_AssertNotNull_ConstantString() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNotNull('abc') } } ''' assertSingleViolation(SOURCE, 4, "assertNotNull('abc')") } @Test void testApplyTo_AssertNotNull_ConstantBoolean() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNotNull(false) } } ''' assertSingleViolation(SOURCE, 4, 'assertNotNull(false)') } @Test void testApplyTo_AssertNotNull_LiteralListOrMap() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNotNull([]) assertNotNull([123]) assertNotNull([a:123]) assertNotNull([:]) } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'assertNotNull([])'], [lineNumber:5, sourceLineText:'assertNotNull([123])'], [lineNumber:6, sourceLineText:'assertNotNull([a:123])'], [lineNumber:7, sourceLineText:'assertNotNull([:])']) } @Test void testApplyTo_AssertNotNull_NonConstant() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNotNull(plugin) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertNotNull_Null() { final SOURCE = ''' class MyTest extends TestCase { void testSomething() { assertNotNull(null) } } ''' assertNoViolations(SOURCE) } // Tests for non-Test files @Test void testApplyTo_NonTestFile() { final SOURCE = ''' class MyClass { void testSomething() { assertTrue(true) } } ''' sourceCodePath = 'src/MyController.groovy' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitAssertAlwaysSucceedsRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertTrueInsteadOfNegationRuleTest.groovy�0000644�0001750�0001750�00000004677�12041642702�033217� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseAssertTrueInsteadOfNegationRule * * @author 'Hamlet D'Arcy' */ class UseAssertTrueInsteadOfNegationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UseAssertTrueInsteadOfNegation' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { assertFalse(condition) assertTrue(condition) assertTrue(!condition, condition) assertFalse(!condition, condition) } } ''' assertNoViolations(SOURCE) } @Test void testUsingThisReference() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { assertFalse(!condition) } } ''' assertSingleViolation(SOURCE, 4, 'assertFalse(!condition)', 'assertFalse(!condition) can be simplified to assertTrue(condition)') } @Test void testUsingStaticReference() { final SOURCE = ''' class MyTest extends GroovyTestCase { public void testMethod() { Assert.assertFalse(!condition) } } ''' assertSingleViolation(SOURCE, 4, 'Assert.assertFalse(!condition)', 'Assert.assertFalse(!condition) can be simplified to Assert.assertTrue(condition)') } protected Rule createRule() { new UseAssertTrueInsteadOfNegationRule() } } �����������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitStyleAssertionsRuleTest.groovy�����������0000644�0001750�0001750�00000014726�12041642702�031300� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitStyleAssertionsRule * * @author Hamlet D'Arcy */ class JUnitStyleAssertionsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'JUnitStyleAssertions' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assert 1 == 2 assert 1 == 2 : 'message' assertTrue() foo.assertTrue(x) foo.assertTrue('message', x) assertFalse() foo.assertFalse(x) foo.assertFalse('message', x) assertEquals() assertEquals(x) assertEquals(x, x, x, x) foo.assertEquals('message', 1, 2) assertNull() assertNull(1, 2, 3) foo.assertNull(x) foo.assertNull('message', x) assertNotNull() assertNotNull(1, 2, 3) foo.assertNotNull(x) foo.assertNotNull('message', x) } } ''' assertNoViolations(SOURCE) } @Test void testTrueOnThis() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertTrue(x) assertTrue('message', x) } } ''' assertTwoViolations(SOURCE, 4, 'assertTrue(x)', 5, "assertTrue('message', x)") } @Test void testTrueOnAssert() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { Assert.assertTrue(x) Assert.assertTrue('message', x) } } ''' assertTwoViolations(SOURCE, 4, 'Assert.assertTrue(x)', 5, "Assert.assertTrue('message', x)") } @Test void testFalseOnThis() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertFalse(x) assertFalse('message', x) } } ''' assertTwoViolations(SOURCE, 4, 'assertFalse(x)', 5, "assertFalse('message', x)") } @Test void testFalseOnAssert() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { Assert.assertFalse(x) Assert.assertFalse('message', x) } } ''' assertTwoViolations(SOURCE, 4, 'Assert.assertFalse(x)', 5, "Assert.assertFalse('message', x)") } @Test void testNullOnThis() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertNull(x) assertNull('message', x) } } ''' assertTwoViolations(SOURCE, 4, 'assertNull(x)', 5, "assertNull('message', x)") } @Test void testNullOnAssert() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { Assert.assertNull(x) Assert.assertNull('message', x) } } ''' assertTwoViolations(SOURCE, 4, 'Assert.assertNull(x)', 5, "Assert.assertNull('message', x)") } @Test void testNotNullOnThis() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertNotNull(x) assertNotNull('message', x) } } ''' assertTwoViolations(SOURCE, 4, 'assertNotNull(x)', 5, "assertNotNull('message', x)") } @Test void testNotNullOnAssert() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { Assert.assertNotNull(x) Assert.assertNotNull('message', x) } } ''' assertTwoViolations(SOURCE, 4, 'Assert.assertNotNull(x)', 5, "Assert.assertNotNull('message', x)") } @Test void testAssertEqualsOnThis() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertEquals(x, y) assertEquals('message', x, y) } } ''' assertTwoViolations(SOURCE, 4, 'assertEquals(x, y)', 5, "assertEquals('message', x, y)") } @Test void testAssertEqualsOnAssert() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { Assert.assertEquals(x, y) Assert.assertEquals('message', x, y) } } ''' assertTwoViolations(SOURCE, 4, 'Assert.assertEquals(x, y)', 5, "Assert.assertEquals('message', x, y)") } protected Rule createRule() { new JUnitStyleAssertionsRule() } } ������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitSetUpCallsSuperRuleTest.groovy�����������0000644�0001750�0001750�00000010263�12041636574�031165� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitSetUpCallsSuperRule * * @author Chris Mair */ class JUnitSetUpCallsSuperRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitSetUpCallsSuper' } @Test void testApplyTo_SetUpCallsSuperSetUp() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { super.setUp() println 'bad' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpDoesNotCallSuperSetUp() { final SOURCE = ''' class MyTestCase extends TestCase { void setUp() { println 'bad' } } ''' assertSingleViolation(SOURCE, 3, 'void setUp() {') } @Test void testApplyTo_SetUpDoesNotCallSuperSetUp_CallsSuperSetUpWithParameters() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { println 'bad' super.setUp('But', 'has', 'parameters') } } ''' sourceCodePath = 'src/MyTests.groovy' assertSingleViolation(SOURCE, 3, 'void setUp() {') } @Test void testApplyTo_SetUpDoesNotCallSuperSetUp_CallsSuper() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { println 'bad' super.someOtherMethod() } } ''' assertSingleViolation(SOURCE, 3, 'void setUp() {') } @Test void testApplyTo_SetUpDoesNotCallSuperSetUp_CallsSetUp() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { println 'bad' other.setUp() } } ''' assertSingleViolation(SOURCE, 3, 'void setUp() {') } @Test void testApplyTo_SetUpIncludesCallWithNamedParameterList() { final SOURCE = ''' class MyTest extends TestCase { void setUp() { super.setUp() ant.delete(dir:appBase, failonerror:false) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpMethodHasBeforeAnnotation() { final SOURCE = ''' class MyTest extends TestCase { @Before void setUp() { println 'bad' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonSetUpMethod() { final SOURCE = ''' class MyTest extends TestCase { def otherMethod() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SetUpMethodHasParameters() { final SOURCE = ''' class MyTest extends TestCase { void setUp(int count, String name) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonTestClass() { final SOURCE = ''' class MyClass { int count } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitSetUpCallsSuperRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UnnecessaryFailRuleTest.groovy����������������0000644�0001750�0001750�00000012255�12041642702�030241� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryFailRule * * @author Hamlet D'Arcy */ class UnnecessaryFailRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnnecessaryFail' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTest { public void testMethod() { try { something() } catch (Exception e) { LOG.error(e) // OK if (x) { fail(e.message) } } try { something() } catch (Exception e) { fail('xyz', e) //I suppose this is OK b/c it is not the JUnit Assert.fail() } try { something() } catch (Exception e) { assert 'xyz' == e.message } } } ''' assertNoViolations(SOURCE) } @Test void testFailWithArgument() { final SOURCE = ''' class MyTest { public void testMethod() { try { something() } catch (Exception e) { fail() } } } ''' assertSingleViolation(SOURCE, 7, 'fail()', 'Catching an exception and failing will hide the stack trace. It is better to rethrow the exception') } @Test void testMultiCatch() { final SOURCE = ''' class MyTest { public void testMethod() { try { something() } catch (IOException e) { } catch (Exception e) { fail() } } } ''' assertSingleViolation(SOURCE, 9, 'fail()', 'Catching an exception and failing will hide the stack trace. It is better to rethrow the exception') } @Test void testFailMultiline() { final SOURCE = ''' class MyTest { public void testMethod() { try { something() } catch (Exception e) { LOG.error(e) fail() } } } ''' assertSingleViolation(SOURCE, 8, 'fail()', 'Catching an exception and failing will hide the stack trace. It is better to rethrow the exception') } @Test void testFail() { final SOURCE = ''' class MyTest { public void testMethod() { try { something() } catch (Exception e) { fail() } } } ''' assertSingleViolation(SOURCE, 7, 'fail()', 'Catching an exception and failing will hide the stack trace. It is better to rethrow the exception') } @Test void testFailWithArgument_FullyQualified() { final SOURCE = ''' class MyTest { public void testMethod() { try { something() } catch (Exception e) { Assert.fail() } } } ''' assertSingleViolation(SOURCE, 7, 'Assert.fail()', 'Catching an exception and failing will hide the stack trace. It is better to rethrow the exception') } @Test void testFail_FullyQualified() { final SOURCE = ''' class MyTest { public void testMethod() { try { something() } catch (Exception e) { Assert.fail() } } } ''' assertSingleViolation(SOURCE, 7, 'Assert.fail()', 'Catching an exception and failing will hide the stack trace. It is better to rethrow the exception') } protected Rule createRule() { new UnnecessaryFailRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/SpockIgnoreRestUsedRuleTest.groovy������������0000644�0001750�0001750�00000012142�12407345123�031046� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SpockIgnoreRestUsedRule * * @author Jan Ahrens * @auther Stefan Armbruster */ class SpockIgnoreRestUsedRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SpockIgnoreRestUsed' assert rule.specificationSuperclassNames == '*Specification' assert rule.specificationClassNames == null } @Test void testNoIgnoreRest_NoViolations() { final SOURCE = ''' public class MySpec extends spock.lang.Specification { def "my first feature"() { expect: false } def "my second feature"() { given: def a = 2 when: a *= 2 then: a == 4 } } '''.stripIndent() assertNoViolations(SOURCE) } @Test void testIgnoreRestWithNonSpecificationClass_NoViolations() { final SOURCE = ''' public class SomeFancyClass { // I'm not a spec def "my first feature"() { expect: false } @IgnoreRest def "my second feature"() { given: def a = 2 when: a *= 2 then: a == 4 } } '''.stripIndent() assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = '''\ import spock.lang.* public class MySpec extends Specification { @IgnoreRest def "my first feature"() { expect: false } def "my second feature"() { given: def a = 2 when: a *= 2 then: a == 4 } } '''.stripIndent() assertSingleViolation(SOURCE, 4, 'def "my first feature"() {', "The method 'my first feature' in class MySpec uses @IgnoreRest") } @Test void testSingleViolationFullSpecificationClassName() { final SOURCE = '''\ public class MySpec extends spock.lang.Specification { @spock.lang.IgnoreRest def "my first feature"() { expect: false } def "my second feature"() { given: def a = 2 when: a *= 2 then: a == 4 } } '''.stripIndent() assertSingleViolation(SOURCE, 3, 'def "my first feature"() {', "The method 'my first feature' in class MySpec uses @IgnoreRest") } @Test void testIgnoreRest_specificationSuperclassNames_Violation() { final SOURCE = '''\ class MySpec extends OtherBaseClass { @spock.lang.IgnoreRest def "my first feature"() { expect: false } } '''.stripIndent() rule.specificationSuperclassNames = 'OtherBaseClass' assertSingleViolation(SOURCE, 3, 'def "my first feature"() {', "The method 'my first feature' in class MySpec uses @IgnoreRest") } @Test void testIgnoreRest_specificationClassNames_DoesNotMatch_NoViolations() { final SOURCE = '''\ class MySpec extends OtherBaseClass { @spock.lang.IgnoreRest def "my first feature"() { expect: false } } '''.stripIndent() rule.specificationClassNames = 'OtherName' assertNoViolations(SOURCE) } @Test void testIgnoreRest_specificationClassNames_Matches_Violation() { final SOURCE = '''\ class MySpec extends OtherBaseClass { @spock.lang.IgnoreRest def "my first feature"() { expect: false } } '''.stripIndent() rule.specificationClassNames = '*Spec' assertSingleViolation(SOURCE, 3, 'def "my first feature"() {', "The method 'my first feature' in class MySpec uses @IgnoreRest") } protected Rule createRule() { new SpockIgnoreRestUsedRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertNullInsteadOfAssertEqualsRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/UseAssertNullInsteadOfAssertEqualsRuleTest.gro0000644�0001750�0001750�00000005117�12041642702�033312� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseAssertNullInsteadOfAssertEqualsRule * * @author Hamlet D'Arcy */ class UseAssertNullInsteadOfAssertEqualsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UseAssertNullInsteadOfAssertEquals' } @Test void testSuccessScenario() { final SOURCE = ''' class MyTestCase extends TestCase { @Test void testMethod() { assertEquals(1, foo()) assertTrue(foo()) assertTrue('message', foo()) assertSame(foo(), foo()) assertTrue(foo() > bar()) } } ''' assertNoViolations(SOURCE) } @Test void testNullInAssertEquals() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertEquals(null, foo()) assertEquals(foo(), null) } } ''' assertTwoViolations(SOURCE, 4, 'assertEquals(null, foo())', 5, 'assertEquals(foo(), null)') } @Test void testNullInAssertEqualsWithMessage() { final SOURCE = ''' class MyTestCase extends TestCase { void testMethod() { assertEquals('message', null, foo()) assertEquals('message', foo(), null) } } ''' assertTwoViolations(SOURCE, 4, "assertEquals('message', null, foo())", 5, "assertEquals('message', foo(), null)") } protected Rule createRule() { new UseAssertNullInsteadOfAssertEqualsRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/junit/JUnitTearDownCallsSuperRuleTest.groovy��������0000644�0001750�0001750�00000010216�12041636766�031651� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.junit import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JUnitTearDownCallsSuperRule * * @author Chris Mair */ class JUnitTearDownCallsSuperRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JUnitTearDownCallsSuper' } @Test void testApplyTo_TearDownCallsSuperTearDown() { final SOURCE = ''' class MyTest extends TestCase { void tearDown() { super.tearDown() println 'bad' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_TearDownDoesNotCallSuperTearDown() { final SOURCE = ''' class MyTestCase extends TestCase { void tearDown() { println 'bad' } } ''' assertSingleViolation(SOURCE, 3, 'void tearDown() {') } @Test void testApplyTo_TearDownDoesNotCallSuperTearDown_CallsSuperTearDownWithParameters() { final SOURCE = ''' class MyTest extends TestCase { void tearDown() { println 'bad' super.tearDown('But', 'has', 'parameters') } } ''' sourceCodePath = 'src/MyTests.groovy' assertSingleViolation(SOURCE, 3, 'void tearDown() {') } @Test void testApplyTo_TearDownDoesNotCallSuperTearDown_CallsSuper() { final SOURCE = ''' class MyTest extends TestCase { void tearDown() { println 'bad' super.someOtherMethod() } } ''' assertSingleViolation(SOURCE, 3, 'void tearDown() {') } @Test void testApplyTo_TearDownDoesNotCallSuperTearDown_CallsTearDown() { final SOURCE = ''' class MyTest extends TestCase { void tearDown() { println 'bad' other.tearDown() } } ''' assertSingleViolation(SOURCE, 3, 'void tearDown() {') } @Test void testApplyTo_NonTestClass() { final SOURCE = ''' class MyClass { void tearDown() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonTestFile_TearDownMethodHasAfterAnnotation() { final SOURCE = ''' class MyTest extends TestCase { @After void tearDown() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonTearDownMethod() { final SOURCE = ''' class MyTest extends TestCase { def otherMethod() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_TearDownMethodHasParameters() { final SOURCE = ''' class MyTest extends TestCase { void tearDown(int count, String name) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoMethodDefinition() { final SOURCE = ''' class MyTest extends TestCase { int count } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new JUnitTearDownCallsSuperRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/�����������������������������������������0000755�0001750�0001750�00000000000�12623571301�023234� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/MissingNewInThrowStatementRuleTest.groovy0000644�0001750�0001750�00000005361�12041642702�033461� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for MissingNewInThrowStatementRule * * @author Hamlet D'Arcy */ class MissingNewInThrowStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'MissingNewInThrowStatement' } @Test void testSuccessScenario() { final SOURCE = ''' throw runtimeFailure() throw RuntimeObject() throw new RuntimeException() ''' assertNoViolations(SOURCE) } @Test void testException() { final SOURCE = ''' throw RuntimeException() // ends in Exceptions, first letter Capitalized ''' assertSingleViolation(SOURCE, 2, 'throw RuntimeException()', 'The throw statement appears to be throwing the class literal RuntimeException instead of a new instance') } @Test void testClassLiteral() { final SOURCE = ''' throw RuntimeException // class literal never allowed ''' assertSingleViolation(SOURCE, 2, 'throw RuntimeException', 'The throw statement appears to be throwing the class literal RuntimeException instead of a new instance') } @Test void testFailure() { final SOURCE = ''' throw RuntimeFailure() // ends in Failure, first letter Capitalized ''' assertSingleViolation(SOURCE, 2, 'throw RuntimeFailure()', 'The throw statement appears to be throwing the class literal RuntimeFailure instead of a new instance') } @Test void testFault() { final SOURCE = ''' throw RuntimeFault(foo) // ends in Fault, first letter Capitalized ''' assertSingleViolation(SOURCE, 2, 'throw RuntimeFault(foo)', 'The throw statement appears to be throwing the class literal RuntimeFault instead of a new instance') } protected Rule createRule() { new MissingNewInThrowStatementRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ThrowErrorRuleTest.groovy����������������0000644�0001750�0001750�00000004351�12041642702�030311� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThrowErrorRule * * @author Chris Mair */ class ThrowErrorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThrowError' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { void myMethod() { throw new Error() } } ''' assertSingleViolation(SOURCE, 4, 'throw new Error()') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = ''' class MyClass { def myClosure = { if (error) { throw new java.lang.Error('something bad') } } } ''' assertSingleViolation(SOURCE, 5, "throw new java.lang.Error('something bad')") } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { try { throw new MyException() // ok } finally { println 'ok' } throw new OtherException() // ok } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ThrowErrorRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ThrowRuntimeExceptionRuleTest.groovy�����0000644�0001750�0001750�00000004501�12041642702�032517� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThrowRuntimeExceptionRule * * @author Chris Mair */ class ThrowRuntimeExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThrowRuntimeException' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { void myMethod() { throw new RuntimeException() } } ''' assertSingleViolation(SOURCE, 4, 'throw new RuntimeException()') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = ''' class MyClass { void myMethod() { if (error) { throw new java.lang.RuntimeException('something bad') } } } ''' assertSingleViolation(SOURCE, 5, "throw new java.lang.RuntimeException('something bad')") } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { try { throw new MyException() // ok } finally { println 'ok' } throw new OtherException() // ok } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ThrowRuntimeExceptionRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ReturnNullFromCatchBlockRuleTest.groovy��0000644�0001750�0001750�00000005605�12407630733�033062� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ReturnNullFromCatchBlockRule * * @author Hamlet D'Arcy */ class ReturnNullFromCatchBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ReturnNullFromCatchBlock' } @Test void testReturnsVariable_NoViolation() { final SOURCE = ''' def x = null try { return x } catch (Exception e) { return x } finally { return x } ''' assertNoViolations(SOURCE) } @Test void testExplicitReturnNull() { final SOURCE = ''' try { def x = null return x } catch (IOException e) { return null } catch (Exception e) { LOG.error(e.getMessage()) return null } ''' assertTwoViolations(SOURCE, 6, 'return null', 9, 'return null') } @Test void testImplicitReturnNull_Violation() { final SOURCE = ''' try { doStuff() } catch (Exception e) { return } ''' assertSingleViolation(SOURCE, 5, 'return') } @Test void testNonVoidMethod_ImplicitReturnNull_Violation() { final SOURCE = ''' def doStuff() { try { doStuff() } catch (Exception e) { return } } ''' assertSingleViolation(SOURCE, 6, 'return') } @Test void testVoidMethod_ImplicitReturnNull_NoViolation() { final SOURCE = ''' void doStuff() { try { doStuff() } catch (Exception e) { return } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new ReturnNullFromCatchBlockRule() } } ���������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ExceptionExtendsThrowableRuleTest.groovy�0000644�0001750�0001750�00000003101�12316050677�033336� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for ExceptionExtendsThrowableRule * * @author Chris Mair */ class ExceptionExtendsThrowableRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExceptionExtendsThrowable' } @Test void testNoViolations() { final SOURCE = ''' class MyException extends Exception { } ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' class MyException extends Throwable { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyException extends Throwable', messageText:'The class MyException extends Throwable']) } protected Rule createRule() { new ExceptionExtendsThrowableRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchErrorRuleTest.groovy����������������0000644�0001750�0001750�00000003707�12041642702�030234� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CatchErrorRule * * @author Chris Mair */ class CatchErrorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CatchError' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { try { doSomething() } catch(Error t) { } } } ''' assertSingleViolation(SOURCE, 7, 'catch(Error t) {') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = 'try { } catch(java.lang.Error t) { }' assertSingleViolation(SOURCE, 1, 'catch(java.lang.Error t) {') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' def myMethod() { try { } catch(Exception t) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CatchErrorRule() } } ���������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ThrowThrowableRuleTest.groovy������������0000644�0001750�0001750�00000004402�12041642702�031144� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThrowThrowableRule * * @author Chris Mair */ class ThrowThrowableRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThrowThrowable' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { void myMethod() { throw new Throwable() } } ''' assertSingleViolation(SOURCE, 4, 'throw new Throwable()') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = ''' class MyClass { void myMethod() { if (error) { throw new java.lang.Throwable('something bad') } } } ''' assertSingleViolation(SOURCE, 5, "throw new java.lang.Throwable('something bad')") } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { try { throw new Exception() // ok } finally { println 'ok' } throw new Exception() // ok } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ThrowThrowableRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ExceptionNotThrownRuleTest.groovy��������0000644�0001750�0001750�00000006265�12311373552�032027� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for ExceptionNotThrownRule * * @author Chris Mair */ class ExceptionNotThrownRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExceptionNotThrown' } @Test void testThrowsException_NoViolation() { final SOURCE = ''' try { } catch(Exception e) { throw new Exception(e) } ''' assertNoViolations(SOURCE) } @Test void testCatchWithNoException_NoViolation() { final SOURCE = ''' try { } catch(Exception e) { log.error("Error doing stuff", e) } catch(Throwabl e) { } ''' assertNoViolations(SOURCE) } @Test void testNoCatch_NoViolation() { final SOURCE = ''' try { } finally { cleanUp() } ''' assertNoViolations(SOURCE) } @Test void testConstructsExceptionWithinCatch_Violations() { final SOURCE = ''' class MyClass { void execute() { try { } catch(Exception e) { new Exception(e) } } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'try { } catch(Exception e) { new Exception(e) }', messageText:'The catch statement within class MyClass constructs a [Exception] but does not throw it']) } @Test void testConstructsOtherExceptions_Violations() { final SOURCE = ''' try { doStuff() } catch(DaoException e) { log.warning("Ooops", e) new ServiceException(e) } catch(Exception e) { new SystemException(e) } ''' assertViolations(SOURCE, [lineNumber:6, sourceLineText:'new ServiceException(e)', messageText:'The catch statement within class None constructs a [ServiceException] but does not throw it'], [lineNumber:8, sourceLineText:'new SystemException(e)', messageText:'The catch statement within class None constructs a [SystemException] but does not throw it']) } protected Rule createRule() { new ExceptionNotThrownRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ThrowExceptionRuleTest.groovy������������0000644�0001750�0001750�00000004411�12041642702�031153� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThrowExceptionRule * * @author Chris Mair */ class ThrowExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThrowException' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { void myMethod() { throw new Exception() } } ''' assertSingleViolation(SOURCE, 4, 'throw new Exception()') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = ''' class MyClass { void myMethod() { if (error) { throw new java.lang.Exception('something bad') } } } ''' assertSingleViolation(SOURCE, 5, "throw new java.lang.Exception('something bad')") } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { try { throw new MyException() // ok } finally { println 'ok' } throw new OtherException() // ok } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ThrowExceptionRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ConfusingClassNamedExceptionRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ConfusingClassNamedExceptionRuleTest.groo0000644�0001750�0001750�00000005111�12465004172�033360� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConfusingClassNamedExceptionRule * * @author Your Name Here */ class ConfusingClassNamedExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ConfusingClassNamedException' } @Test void testNoViolations() { final SOURCE = ''' class MyClass {} class MyException extends Exception {} class MyThrowableException extends Throwable {} class MyRuntimeException extends RuntimeException{} class MyIllegalStateException extends IllegalStateException{} class MyExceptionSubclass extends MyException {} class MyOther { class MyNestedException extends Exception {} } class AutoLinkProcessingException extends Exception{ AutoLinkProcessingException(String cause) { super(cause) } } ''' assertNoViolations(SOURCE) } @Test void testExceptionWithParent() { final SOURCE = ''' class MyException extends PrintWriter {} ''' assertSingleViolation(SOURCE, 2, 'class MyException extends PrintWriter {}') } @Test void testExceptionWithoutParent() { final SOURCE = ''' class MyException {} ''' assertSingleViolation(SOURCE, 2, 'class MyException {}') } @Test void testExceptionInNestedClass() { final SOURCE = ''' class MyClass { class MyNestedException {} } ''' assertSingleViolation(SOURCE, 3, 'class MyNestedException {}') } protected Rule createRule() { new ConfusingClassNamedExceptionRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000156�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchArrayIndexOutOfBoundsExceptionRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchArrayIndexOutOfBoundsExceptionRuleTe0000644�0001750�0001750�00000004011�12041642704�033314� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CatchArrayIndexOutOfBoundsExceptionRule * * @author Chris Mair */ class CatchArrayIndexOutOfBoundsExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CatchArrayIndexOutOfBoundsException' } @Test void testApplyTo_Violation() { final SOURCE = ''' try { doSomething() } catch(ArrayIndexOutOfBoundsException t) { } ''' assertSingleViolation(SOURCE, 5, 'catch(ArrayIndexOutOfBoundsException t) {') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = 'try { } catch(java.lang.ArrayIndexOutOfBoundsException t) { }' assertSingleViolation(SOURCE, 1, 'catch(java.lang.ArrayIndexOutOfBoundsException t) {') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' def myMethod() { try { } catch(Exception t) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CatchArrayIndexOutOfBoundsExceptionRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchThrowableRuleTest.groovy������������0000644�0001750�0001750�00000003601�12041642702�031063� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CatchThrowableRule * * @author Chris Mair */ class CatchThrowableRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CatchThrowable' } @Test void testApplyTo_Violation() { final SOURCE = ''' try { doSomething() } catch(Throwable t) { } ''' assertSingleViolation(SOURCE, 5, 'catch(Throwable t) {') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = 'try { } catch(java.lang.Throwable t) { }' assertSingleViolation(SOURCE, 1, 'catch(java.lang.Throwable t) {') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { try { } catch(Exception t) { } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new CatchThrowableRule() } } �������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000151�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchIndexOutOfBoundsExceptionRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchIndexOutOfBoundsExceptionRuleTest.gr0000644�0001750�0001750�00000003741�12041642702�033302� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CatchIndexOutOfBoundsExceptionRule * * @author Chris Mair */ class CatchIndexOutOfBoundsExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CatchIndexOutOfBoundsException' } @Test void testApplyTo_Violation() { final SOURCE = ''' try { doSomething() } catch(IndexOutOfBoundsException t) { } ''' assertSingleViolation(SOURCE, 5, 'catch(IndexOutOfBoundsException t) {') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = 'try { } catch(java.lang.IndexOutOfBoundsException t) { }' assertSingleViolation(SOURCE, 1, 'catch(java.lang.IndexOutOfBoundsException t) {') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' def myMethod() { try { } catch(Exception t) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CatchIndexOutOfBoundsExceptionRule() } } �������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ExceptionExtendsErrorRuleTest.groovy�����0000644�0001750�0001750�00000003550�12041642702�032477� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExceptionExtendsErrorRule * * @author Hamlet D'Arcy */ class ExceptionExtendsErrorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExceptionExtendsError' } @Test void testSuccessScenario() { final SOURCE = ''' class MyException extends Exception { } // OK ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' class MyError1 extends Error { } // violation class MyError2 extends java.lang.Error { } // violation ''' assertTwoViolations(SOURCE, 2, 'class MyError1 extends Error', 'The class MyError1 extends Error, which is meant to be used only as a system exception', 4, 'class MyError2 extends java.lang.Error', 'The class MyError2 extends Error, which is meant to be used only as a system exception') } protected Rule createRule() { new ExceptionExtendsErrorRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchNullPointerExceptionRuleTest.groovy�0000644�0001750�0001750�00000003671�12041642702�033275� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CatchNullPointerExceptionRule * * @author Chris Mair */ class CatchNullPointerExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CatchNullPointerException' } @Test void testApplyTo_Violation() { final SOURCE = ''' try { doSomething() } catch(NullPointerException t) { } ''' assertSingleViolation(SOURCE, 5, 'catch(NullPointerException t) {') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = 'try { } catch(java.lang.NullPointerException t) { }' assertSingleViolation(SOURCE, 1, 'catch(java.lang.NullPointerException t) {') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' def myMethod() { try { } catch(Exception t) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CatchNullPointerExceptionRule() } } �����������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000154�00000000000�011603� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchIllegalMonitorStateExceptionRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchIllegalMonitorStateExceptionRuleTest0000644�0001750�0001750�00000004011�12041642702�033405� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CatchIllegalMonitorStateExceptionRule * * @author Hamlet D'Arcy */ class CatchIllegalMonitorStateExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CatchIllegalMonitorStateException' } @Test void testApplyTo_Violation() { final SOURCE = ''' try { doSomething() } catch(IllegalMonitorStateException t) { } ''' assertSingleViolation(SOURCE, 5, 'catch(IllegalMonitorStateException t) {') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = 'try { } catch(java.lang.IllegalMonitorStateException t) { }' assertSingleViolation(SOURCE, 1, 'catch(java.lang.IllegalMonitorStateException t) {') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' def myMethod() { try { } catch(Exception t) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CatchIllegalMonitorStateExceptionRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/ThrowNullPointerExceptionRuleTest.groovy�0000644�0001750�0001750�00000004541�12041642702�033353� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThrowNullPointerExceptionRule * * @author Chris Mair */ class ThrowNullPointerExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThrowNullPointerException' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { void myMethod() { throw new NullPointerException() } } ''' assertSingleViolation(SOURCE, 4, 'throw new NullPointerException()') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = ''' class MyClass { void myMethod() { if (error) { throw new java.lang.NullPointerException('something bad') } } } ''' assertSingleViolation(SOURCE, 5, "throw new java.lang.NullPointerException('something bad')") } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { try { throw new MyException() // ok } finally { println 'ok' } throw new OtherException() // ok } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ThrowNullPointerExceptionRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/SwallowThreadDeathRuleTest.groovy��������0000644�0001750�0001750�00000006042�12041642702�031721� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SwallowThreadDeathRule * * @author Rob Fletcher * @author Klaus Baumecker */ class SwallowThreadDeathRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SwallowThreadDeath' } @Test void testRethrowingCaughtErrorIsLegal() { final SOURCE = ''' try { def a = 0 } catch (ThreadDeath td) { throw td } ''' assertNoViolations(SOURCE) } @Test void testReThrowingAnotherInstanceOfThreadDeathIsLegal() { final SOURCE = ''' try { def a = 0 } catch (ThreadDeath td) { throw new ThreadDeath() } ''' assertNoViolations(SOURCE) } @Test void testNesting() { final SOURCE = ''' try { def a = 0 } catch (ThreadDeath td) { try { println 4 } catch (ThreadDeath ttdd) { throw ttdd } throw td } ''' assertNoViolations(SOURCE) } @Test void testCatchingWithoutRethrowingAnythingIsAViolation() { final SOURCE = ''' try { def a = 0 } catch (ThreadDeath td) { td.printStackTrace() } ''' assertSingleViolation(SOURCE, 4, '} catch (ThreadDeath td) {') } @Test void testCatchingAndThrowingAnotherVariableIsAViolation() { final SOURCE = ''' def other = new ThreadDeath() try { def a = 0 } catch (ThreadDeath td) { throw other } ''' assertSingleViolation(SOURCE, 5, '} catch (ThreadDeath td) {') } @Test void testCatchingAndThrowingSomethingElseIsAViolation() { final SOURCE = ''' try { def a = 0 } catch (ThreadDeath td) { throw new RuntimeException("o noes") } ''' assertSingleViolation(SOURCE, 4, '} catch (ThreadDeath td) {') } protected Rule createRule() { new SwallowThreadDeathRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchRuntimeExceptionRuleTest.groovy�����0000644�0001750�0001750�00000003651�12041642702�032443� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CatchRuntimeExceptionRule * * @author Chris Mair */ class CatchRuntimeExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CatchRuntimeException' } @Test void testApplyTo_Violation() { final SOURCE = ''' try { doSomething() } catch(RuntimeException t) { } ''' assertSingleViolation(SOURCE, 5, 'catch(RuntimeException t) {') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = 'try { } catch(java.lang.RuntimeException t) { }' assertSingleViolation(SOURCE, 1, 'catch(java.lang.RuntimeException t) {') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' def myMethod() { try { } catch(Exception t) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CatchRuntimeExceptionRule() } } ���������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/exceptions/CatchExceptionRuleTest.groovy������������0000644�0001750�0001750�00000003561�12041642702�031077� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.exceptions import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CatchExceptionRule * * @author Chris Mair */ class CatchExceptionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CatchException' } @Test void testApplyTo_Violation() { final SOURCE = ''' try { doSomething() } catch(Exception t) { } ''' assertSingleViolation(SOURCE, 5, 'catch(Exception t) {') } @Test void testApplyTo_Violation_FullPackageName() { final SOURCE = 'try { } catch(java.lang.Exception t) { }' assertSingleViolation(SOURCE, 1, 'catch(java.lang.Exception t) {') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' def myMethod() { try { } catch(Throwable t) { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CatchExceptionRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/���������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022334� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000151�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsDomainReservedSqlKeywordNameRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsDomainReservedSqlKeywordNameRuleTest.gr0000644�0001750�0001750�00000010570�12311373552�033262� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for GrailsDomainReservedSqlKeywordNameRule * * @author Artur Gajowy */ class GrailsDomainReservedSqlKeywordNameRuleTest extends AbstractRuleTestCase { @Before void setup() { sourceCodePath = 'project/MyProject/grails-app/domain/com/xxx/Whatever.groovy' } @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsDomainReservedSqlKeywordName' } @Test void testSuccessScenario() { assertNoViolations(''' class Whatever { } ''') } @Test void testSingleViolation() { assertInlineViolations(''' class Order { #'Order' is a reserved SQL keyword and - as such - a problematic domain class name. } ''') } @Test void testTwoViolations() { assertInlineViolations(""" class Whatever { String where ${violation('where')} Integer rows ${violation('rows')} } """) } @Test void testBasicTypesViolate() { assertInlineViolations(""" class Whatever { int column ${violation('column')} byte[] rows ${violation('rows')} Byte[] table ${violation('table')} char[] user ${violation('user')} Character[] order ${violation('order')} Serializable group ${violation('group')} } """) } @Test void testRelationshipsDoNotViolate() { assertNoViolations(''' class Whatever { Place where List<Row> rows } ''') } @Test void testTransientsDoNotViolate() { assertNoViolations(''' class Whatever { String where static transients = ['where'] } ''') } @Test void testDefsDoNotViolate() { assertNoViolations(''' class Whatever { def where } ''') } @Test void testStaticsDoNotViolate() { assertNoViolations(''' class Whatever { static String where } ''') } @Test void testSqlKeywordsOverride() { rule.additionalReservedSqlKeywords = 'customKeyword, evenMoreCustomKeyword' assertInlineViolations(""" class Whatever { String where ${violation('where')} String customKeyword ${violation('customKeyword')} String evenMoreCustomKeyword ${violation('evenMoreCustomKeyword')} } """) } @Test void testHibernateBasicTypesOverride() { rule.additionalHibernateBasicTypes = 'Place, Relation' assertInlineViolations(""" class Whatever { int rows ${violation('rows')} Place where ${violation('where')} Relation order ${violation('order')} } """) } @Test void testNonDomain_WithKeywordName_NoViolations() { sourceCodePath = 'project/MyProject/grails-app/service/Order.groovy' assertNoViolations(''' class Order { } ''') } private violation(String fieldName) { inlineViolation("'$fieldName' is a reserved SQL keyword and - as such - a problematic domain class' field name.") } protected Rule createRule() { new GrailsDomainReservedSqlKeywordNameRule() } } ����������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsStatelessServiceRuleTest.groovy��������0000644�0001750�0001750�00000015301�12061113722�031720� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test /** * Tests for GrailsStatelessServiceRule * * @author Chris Mair */ class GrailsStatelessServiceRuleTest extends AbstractRuleTestCase { private static final SERVICE_PATH = 'project/MyProject/grails-app/services/com/xxx/MyService.groovy' private static final OTHER_PATH = 'project/MyProject/src/groovy/MyHelper.groovy' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsStatelessService' } @Test void testApplyTo_HasFields() { final SOURCE = ''' class MyService { BigDecimal depositAmount int other } ''' assertTwoViolations(SOURCE, 3, 'BigDecimal depositAmount', 4, 'int other') } @Test void testApplyTo_FinalField() { final SOURCE = ''' class MyService { final value = 5 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoresDefProperties() { final SOURCE = ''' class MyService { def maxValue } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotIgnoreDefFieldsWithVisibilityModifier() { final SOURCE = ''' class MyService { private def depositAmount public def other } ''' assertTwoViolations(SOURCE, 3, 'private def depositAmount', 4, 'public def other') } @Test void testApplyTo_DoesNotIgnoreStaticDefProperties() { final SOURCE = ''' class MyService { static def other } ''' assertSingleViolation(SOURCE, 3, 'static def other') } @Test void testApplyTo_DefaultIgnoredFieldNames() { final SOURCE = ''' class MyService { DataSource dataSource OtherService otherService static scope = 'session' static transactional = false Sessionfactory sessionFactory } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_StaticField() { final SOURCE = ''' class MyService { static depositCount = 5 int other } ''' assertTwoViolations(SOURCE, 3, 'static depositCount = 5', 4, 'int other') } @Test void testApplyTo_StaticFinalField() { final SOURCE = ''' class MyService { static final DEFAULT_NAME = 'ABC' } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreFieldNames_OneExactName() { final SOURCE = ''' class MyService { BigDecimal depositAmount int other } ''' rule.ignoreFieldNames = 'other' assertSingleViolation(SOURCE, 3, 'BigDecimal depositAmount') } @Test void testApplyTo_IgnoreFieldNames_TwoExactNames() { final SOURCE = ''' class MyService { BigDecimal depositAmount int other } ''' rule.ignoreFieldNames = 'other,depositAmount' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreFieldNames_Wildcards() { final SOURCE = ''' class MyService { BigDecimal depositAmount int other int count long otherMax } ''' rule.ignoreFieldNames = 'oth*,deposit??ount' assertSingleViolation(SOURCE, 5, 'int count') } @Test void testApplyTo_IgnoreFieldTypes_OneExactName() { final SOURCE = ''' class MyService { BigDecimal depositAmount int other } ''' rule.ignoreFieldTypes = 'BigDecimal' assertSingleViolation(SOURCE, 4, 'int other') } @Test void testApplyTo_IgnoreFieldTypes_Wildcards() { final SOURCE = ''' class MyService { BigDecimal depositAmount int count = 23 long otherMax Object lock = new Object() } ''' rule.ignoreFieldTypes = '*Decimal,java.lang.Object,l?n?' assertTwoViolations(SOURCE, 4, 'int count = 23', 6, 'Object lock = new Object()') } @Test void testApplyTo_IgnoreFieldNamesAndIgnoreFieldTypes() { final SOURCE = ''' class MyService { BigDecimal depositAmount int other int count long otherMax } ''' rule.ignoreFieldNames = 'oth*,XXX' rule.ignoreFieldTypes = '*Decimal,YYY,int,l?n?' assertNoViolations(SOURCE) } @Test void testApplyTo_Script_HasField() { final SOURCE = ''' BigDecimal depositAmount // not considered a field xxx = 23 // not considered a field println 'ok' ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoFieldDefinition() { final SOURCE = ' class MyService { } ' assertNoViolations(SOURCE) } @Test void testApplyTo_FieldWithinNonServiceClass() { final SOURCE = ''' class MyServiceHelper { BigDecimal depositAmount } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_FieldWithinNonServiceDirectory() { final SOURCE = ''' class MyService { BigDecimal depositAmount } ''' sourceCodePath = OTHER_PATH assertNoViolations(SOURCE) } @Before void setUpGrailsStatelessServiceRuleTest() { sourceCodePath = SERVICE_PATH } protected Rule createRule() { new GrailsStatelessServiceRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsMassAssignmentRuleTest.groovy����������0000644�0001750�0001750�00000007666�12311373552�031412� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for GrailsMassAssignmentRule * * @author Brian Soby */ class GrailsMassAssignmentRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsMassAssignment' } @Test void testNoViolations() { final SOURCE = ''' class Person { String name Boolean isAdmin } def bindingMap = [name: 'John', isAdmin: true] def person = new Person() def p2 = new Person("It is currently ${ new Date() }") def p3 = new Person(bindingMap) person.name = bindingMap['name'] person.isAdmin = bindingMap.isAdmin person.properties = "It is currently ${ new Date() }" ''' assertNoViolations(SOURCE) } @Test void testDomainObjectNoViolations() { // grails specific final SOURCE = ''' class Person { String name Boolean isAdmin } def params = [name: 'John', isAdmin: true] def person = new Person() def staticData = [name: 'John'] person.properties = staticData bindData(person,params,include=['name']) bindData(person,params,exclude=['isAdmin']) ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class Person { String name Boolean isAdmin } params = [name: 'John', isAdmin: true] def person = new Person(params) ''' assertSingleViolation(SOURCE, 7, 'def person = new Person(params)') } @Test void testSingleDomainObjectViolation() { final SOURCE = ''' class Person { String name Boolean isAdmin } def params = [name: 'John', isAdmin: true] def person = Person.get(1) person.properties = params ''' assertSingleViolation(SOURCE, 8, 'person.properties = params') } @Test void testSingleClosureViolation() { final SOURCE = ''' class Person { String name Boolean isAdmin } a = { def params = [name: 'John', isAdmin: true] def person = Person.get(1) person.properties = params } a() ''' assertSingleViolation(SOURCE, 9, 'person.properties = params') } @Test void testMultipleViolations() { final SOURCE = ''' class Person { String name Boolean isAdmin } def params = [name: 'John', isAdmin: true] def person = new Person(params) def person2 = new Person() person2.properties = params ''' assertViolations(SOURCE, [lineNumber:7, sourceLineText:'def person = new Person(params)'], [lineNumber:9, sourceLineText:'person2.properties = params']) } protected Rule createRule() { new GrailsMassAssignmentRule() } } ��������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsDomainHasToStringRuleTest.groovy�������0000644�0001750�0001750�00000004602�12041642702�031772� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for GrailsDomainHasToStringRule * * @author Hamlet D'Arcy * @author Chris Mair */ class GrailsDomainHasToStringRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsDomainHasToString' } @Test void testSuccessScenario() { final SOURCE = ''' class Person { @Override String toString() { 'xxx' } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class Person { @Override String toString(Object o) { 'xxx' } } ''' sourceCodePath = 'project/MyProject/grails-app/domain/com/xxx/Person.groovy' assertSingleViolation(SOURCE, 2, 'class Person', 'The domain class Person should define a toString() method') } @Test void testIgnoresClassWithToStringAnnotation() { final SOURCE = ''' @ToString class Person { } ''' sourceCodePath = 'project/MyProject/grails-app/domain/com/xxx/Person.groovy' assertNoViolations(SOURCE) } @Test void testIgnoresClassWithCanonicalAnnotation() { final SOURCE = ''' @Canonical class Person { } ''' sourceCodePath = 'project/MyProject/grails-app/domain/com/xxx/Person.groovy' assertNoViolations(SOURCE) } protected Rule createRule() { new GrailsDomainHasToStringRule() } } ������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsServletContextReferenceRuleTest.groovy�0000644�0001750�0001750�00000007376�12323250673�033265� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test /** * Tests for GrailsServletContextReferenceRule * * @author Chris Mair */ class GrailsServletContextReferenceRuleTest extends AbstractRuleTestCase { private static final CONTROLLER_PATH = 'project/MyProject/grails-app/controllers/com/xxx/MyController.groovy' private static final TAGLIB_PATH = 'project/MyProject/grails-app/taglib/MyTagLib.groovy' private static final OTHER_PATH = 'project/MyProject/src/groovy/MyHelper.groovy' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsServletContextReference' } @Test void testApplyTo_AssignmentToServletContextProperty() { final SOURCE = ''' class MyClass { int someField private void doSomething() { servletContext.count = 23 } } ''' assertSingleViolation(SOURCE, 5, 'servletContext.count = 23') } @Test void testApplyTo_SimpleReference() { final SOURCE = ''' class MyClass { def edit = { println servletContext } } ''' assertSingleViolation(SOURCE, 4, 'println servletContext') } @Test void testApplyTo_ReferenceWithinMethodCallArgument() { final SOURCE = ''' class MyClass { def edit = { doSomething(1, 'abc', servletContext) } } ''' assertSingleViolation(SOURCE, 4, "doSomething(1, 'abc', servletContext)") } @Test void testApplyTo_ReferenceWithinFieldInitializer() { final SOURCE = ''' class MyClass { def mySession = servletContext def edit = { println "amount=${servletContext.amount}" } } ''' assertTwoViolations(SOURCE, 3, 'def mySession = servletContext', 6, 'println "amount=${servletContext.amount}"') } @Test void testApplyTo_ReferenceWithinTagLib() { final SOURCE = ''' class SimpleTagLib { def simple = { attrs, body -> servletContext.amount = attrs.amount } } ''' sourceCodePath = TAGLIB_PATH assertSingleViolation(SOURCE, 3, 'def simple = { attrs, body -> servletContext.amount = attrs.amount }') } @Test void testApplyTo_ReferenceWithinNonControllerClass() { final SOURCE = ''' class MyClass { def edit = { println servletContext } } ''' sourceCodePath = OTHER_PATH assertNoViolations(SOURCE) } @Before void setUpGrailsServletContextReferenceRuleTest() { sourceCodePath = CONTROLLER_PATH } protected Rule createRule() { new GrailsServletContextReferenceRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsDuplicateMappingRuleTest.groovy��������0000644�0001750�0001750�00000012277�12311373552�031676� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase import org.junit.Before /** * Tests for GrailsDuplicateMappingRule * * @author Chris Mair */ class GrailsDuplicateMappingRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsDuplicateMapping' } @Test void testNoDuplicates_NoViolations() { final SOURCE = ''' class Person { String firstName String lastName static mapping = { table 'people' firstName column: 'First_Name' lastName column: 'Last_Name' } } ''' assertNoViolations(SOURCE) } @Test void testEmptyMapping_NoViolations() { final SOURCE = ''' class Person { String firstName static mapping = { } } ''' assertNoViolations(SOURCE) } @Test void testCallsToOverloadedMethods_NoViolations() { final SOURCE = ''' class Person { void run() { doStuff() doStuff(99) } } ''' assertNoViolations(SOURCE) } @Test void testDuplicateMappings_Violation() { final SOURCE = ''' class Person { String firstName String lastName static mapping = { table 'people' firstName column: 'First_Name' lastName column: 'Last_Name' firstName column: 'First_Name' table 'people2' } } ''' assertViolations(SOURCE, [lineNumber:9, sourceLineText:"firstName column: 'First_Name'", messageText:'The mapping for firstName in domain class Person has already been specified'], [lineNumber:10, sourceLineText:"table 'people2'", messageText:'The mapping for table in domain class Person has already been specified']) } @Test void testDuplicateMappings_NestedColumnsClosure_Violation() { final SOURCE = ''' class Person { String firstName String lastName static mapping = { table 'people' columns { firstName column: 'First_Name' lastName column: 'Last_Name' firstName column: 'First_Name' } } } ''' assertViolations(SOURCE, [lineNumber:10, sourceLineText:"firstName column: 'First_Name'", messageText:'The mapping for firstName in domain class Person has already been specified']) } @Test void testMappingsAndConstraints_NoViolation() { final SOURCE = ''' class Person { String firstName static mapping = { columns { firstName column: 'First_Name' } } static constraints = { firstName nullable:true } } ''' assertNoViolations(SOURCE) } @Test void testMappings_ContainsMethodCalls_NoViolation() { final SOURCE = ''' class Person { String firstName String lastName static mapping = { columns { firstName column: buildColumnName(1) lastName column: buildColumnName(2) } } } ''' assertNoViolations(SOURCE) } @Test void testNotDomainClass_DuplicateMappings_NoViolation() { final SOURCE = ''' class Person { static mapping = { table 'people' table 'people2' } } ''' sourceCodePath = 'MyProject/other/Person.groovy' assertNoViolations(SOURCE) } @Before void setUp() { sourceCodePath = 'MyProject/grails-app/domain/com/example/Person.groovy' } protected Rule createRule() { new GrailsDuplicateMappingRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsSessionReferenceRuleTest.groovy��������0000644�0001750�0001750�00000007400�12323250740�031676� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test /** * Tests for GrailsSessionReferenceRule * * @author Chris Mair */ class GrailsSessionReferenceRuleTest extends AbstractRuleTestCase { private static final CONTROLLER_PATH = 'project/MyProject/grails-app/controllers/com/xxx/MyController.groovy' private static final TAGLIB_PATH = 'project/MyProject/grails-app/taglib/MyTagLib.groovy' private static final OTHER_PATH = 'project/MyProject/src/groovy/MyHelper.groovy' @Test void testDisabledByDefault() { assert !new GrailsSessionReferenceRule().enabled } @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsSessionReference' } @Test void testApplyTo_AssignmentToSessionProperty() { final SOURCE = ''' class MyClass { int someField private void doSomething() { session.count = 23 } } ''' assertSingleViolation(SOURCE, 5, 'session.count = 23') } @Test void testApplyTo_SimpleReferenceToSession() { final SOURCE = ''' class MyClass { def edit = { println session } } ''' assertSingleViolation(SOURCE, 4, 'println session') } @Test void testApplyTo_ReferenceWithinMethodCallArgument() { final SOURCE = ''' class MyClass { def edit = { doSomething(1, 'abc', session) } } ''' assertSingleViolation(SOURCE, 4, "doSomething(1, 'abc', session)") } @Test void testApplyTo_ReferenceWithinFieldInitializer() { final SOURCE = ''' class MyClass { def mySession = session def edit = { println "amount=${session.amount}" } } ''' assertTwoViolations(SOURCE, 3, 'def mySession = session', 6, 'println "amount=${session.amount}"') } @Test void testApplyTo_ReferenceWithinTagLib() { final SOURCE = ''' class SimpleTagLib { def simple = { attrs, body -> session.amount = attrs.amount } } ''' sourceCodePath = TAGLIB_PATH assertSingleViolation(SOURCE, 3, 'def simple = { attrs, body -> session.amount = attrs.amount }') } @Test void testApplyTo_ReferenceWithinNonControllerClass() { final SOURCE = ''' class MyClass { def edit = { println session } } ''' sourceCodePath = OTHER_PATH assertNoViolations(SOURCE) } @Before void setUpGrailsSessionReferenceRuleTest() { sourceCodePath = CONTROLLER_PATH } protected Rule createRule() { new GrailsSessionReferenceRule(enabled:true) } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsPublicControllerMethodRuleTest.groovy��0000644�0001750�0001750�00000012055�12323250626�033064� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test /** * Tests for GrailsPublicControllerMethodRule * * @author Chris Mair */ class GrailsPublicControllerMethodRuleTest extends AbstractRuleTestCase { private static final CONTROLLER_PATH = 'project/MyProject/grails-app/controllers/com/xxx/MyController.groovy' private static final OTHER_PATH = 'project/MyProject/src/groovy/MyHelper.groovy' @Test void testDisabledByDefault() { assert !new GrailsPublicControllerMethodRule().enabled } @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsPublicControllerMethod' } @Test void testApplyTo_PublicMethod() { final SOURCE = ''' class MyController { int someField def list = { [books: Book.list() ] } void doSomething() { // this does not need to be public } } ''' assertSingleViolation(SOURCE, 7, 'void doSomething() {') } @Test void testApplyTo_TwoPublicMethods() { final SOURCE = ''' class MyController { boolean isThisNecessary() { false } def list = { [books: Book.list() ] } void doSomething() { // this does not need to be public } } ''' assertTwoViolations(SOURCE, 3, 'boolean isThisNecessary() { false }', 5, 'void doSomething() {') } @Test void testApplyTo_PublicStaticMethods() { final SOURCE = ''' class MyClass { static int calculate() { 23 } public static boolean isReady() { true } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoPublicMethods() { final SOURCE = ''' class MyController { def list = { [books: Book.list() ] } protected boolean isReady() { true } def show = { [ book : Book.get( params.id ) ] } private int calculate() { 23 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PublicMethodsWithinNonControllerClass() { final SOURCE = ''' class MyHelper { int calculate() { 23 } protected boolean isReady() { true } public String getName() { 'abc' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PublicMethodsWithinNonControllerPath() { final SOURCE = ''' class MyController { int calculate() { 23 } protected boolean isReady() { true } public String getName() { 'abc' } } ''' sourceCodePath = OTHER_PATH assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesSingleName() { final SOURCE = ''' class MyController { void myMethod() { } } ''' rule.ignoreMethodNames = 'myMethod' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesNoNames() { final SOURCE = ''' class MyController { void myMethod() { } } ''' rule.ignoreMethodNames = 'otherMethod' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'void myMethod()']) } @Test void testApplyTo_IgnoreMethodNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyController { boolean isReady() { } def doOtherStuff() { } void myMethod() { } } ''' rule.ignoreMethodNames = 'is*,doO??erSt*ff,other' assertViolations(SOURCE, [lineNumber:5, sourceLineText:'void myMethod()']) } @Before void setUpGrailsPublicControllerMethodRuleTest() { sourceCodePath = CONTROLLER_PATH } protected Rule createRule() { new GrailsPublicControllerMethodRule(enabled:true) } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsDomainWithServiceReferenceRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsDomainWithServiceReferenceRuleTest.groo0000644�0001750�0001750�00000005350�12311373552�033266� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for GrailsDomainWithServiceReferenceRule * * @author Artur Gajowy */ class GrailsDomainWithServiceReferenceRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsDomainWithServiceReference' } @Before void setup() { sourceCodePath = 'project/MyProject/grails-app/domain/com/xxx/Book.groovy' } @Test void testDomain_NoService_NoViolations() { final SOURCE = ''' class Book { String title Author author } ''' assertNoViolations(SOURCE) } @Test void testDomain_SingleService_SingleViolation() { final SOURCE = ''' package foo.bar.baz; class Book { FooService fooService } ''' assertSingleViolation(SOURCE, 5, 'FooService fooService', errorMessage('fooService')) } @Test void testDomain_TwoServiceFields_TwoViolations() { final SOURCE = ''' class Book { FooService fooService def barService } ''' assertTwoViolations(SOURCE, 3, 'FooService fooService', errorMessage('fooService'), 4, 'def barService', errorMessage('barService')) } @Test void testNonDomain_WithService_NoViolations() { final SOURCE = ''' class BookService { FooService fooService } ''' sourceCodePath = 'project/MyProject/grails-app/service/BookService.groovy' assertNoViolations(SOURCE) } private static String errorMessage(String fieldName) { "Domain class Book should not reference services (offending field: $fieldName)" } protected Rule createRule() { new GrailsDomainWithServiceReferenceRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsDuplicateConstraintRuleTest.groovy�����0000644�0001750�0001750�00000014224�12414042204�032410� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase import org.junit.Before /** * Tests for GrailsDuplicateConstraintRule * * @author Chris Mair */ class GrailsDuplicateConstraintRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsDuplicateConstraint' } @Test void testNoDuplicates_NoViolations() { final SOURCE = ''' class Person { String firstName String lastName static constraints = { firstName nullable:true lastName nullable:true, maxSize:30 } } ''' assertNoViolations(SOURCE) } @Test void testEmptyConstraints_NoViolations() { final SOURCE = ''' class Person { String firstName static constraints = { } } ''' assertNoViolations(SOURCE) } @Test void testCallsToOverloadedMethods_NoViolations() { final SOURCE = ''' class Person { void run() { doStuff() doStuff(99) } } ''' assertNoViolations(SOURCE) } @Test void testDuplicateConstraints_Violation() { final SOURCE = ''' class Person { String firstName String lastName static constraints = { firstName nullable:true lastName nullable:true, maxSize:30 firstName nullable:false lastName nullable:false, maxSize:30 } } ''' assertViolations(SOURCE, [lineNumber:8, sourceLineText:'firstName nullable:false', messageText:'The constraint for firstName in domain class Person has already been specified'], [lineNumber:9, sourceLineText:'lastName nullable:false, maxSize:30', messageText:'The constraint for lastName in domain class Person has already been specified']) } @Test void testImportFrom_NoViolation() { final SOURCE = ''' class Person { String firstName String lastName static constraints = { importFrom Entity, include: ["firstName"] importFrom Entity, include: ["lastName"] } } ''' assertNoViolations(SOURCE) } @Test void testImportFrom_SameImportViolation() { final SOURCE = ''' class Person { String firstName String lastName static constraints = { importFrom Entity, include: ["firstName"] importFrom Entity, include: ["firstName"] } } ''' assertViolations(SOURCE, [lineNumber:7, sourceLineText:'importFrom Entity, include: ["firstName"]', messageText:'The constraint for firstName in domain class Person has already been specified']) } @Test void testImportFrom_ImportAndRegularConstraintViolation() { final SOURCE = ''' class Person { String firstName String lastName static constraints = { importFrom Entity, include: ["firstName"] firstName blank: false } } ''' assertViolations(SOURCE, [lineNumber:7, sourceLineText:'firstName blank: false', messageText:'The constraint for firstName in domain class Person has already been specified']) } @Test void testMappingsAndConstraints_NoViolation() { final SOURCE = ''' class Person { String firstName static constraints = { firstName nullable:true } static mapping = { columns { firstName column: 'First_Name' } } } ''' assertNoViolations(SOURCE) } @Test void testConstraints_ContainsMethodCalls_NoViolation() { final SOURCE = ''' class Person { String firstName String lastName static constraints = { firstName nullable:true, validator:buildValidator(1) lastName nullable:true, validator:buildValidator(2) } } ''' assertNoViolations(SOURCE) } @Test void testNotDomainClass_DuplicateMappings_NoViolation() { final SOURCE = ''' class Person { static constraints = { firstName nullable:true lastName nullable:true, maxSize:30 firstName nullable:false lastName nullable:false, maxSize:30 } } ''' sourceCodePath = 'MyProject/other/Person.groovy' assertNoViolations(SOURCE) } @Before void setUp() { sourceCodePath = 'MyProject/grails-app/domain/com/example/Person.groovy' } protected Rule createRule() { new GrailsDuplicateConstraintRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/grails/GrailsDomainHasEqualsRuleTest.groovy���������0000644�0001750�0001750�00000004626�12041642702�031461� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.grails import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for GrailsDomainHasEqualsRule * * @author Hamlet D'Arcy * @author Chris Mair */ class GrailsDomainHasEqualsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GrailsDomainHasEquals' } @Test void testSuccessScenario() { final SOURCE = ''' class Person { @Override boolean equals(Object o) { true } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class Person { @Override boolean equals(Object o, Object x) { true } } ''' sourceCodePath = 'project/MyProject/grails-app/domain/com/xxx/Person.groovy' assertSingleViolation(SOURCE, 2, 'class Person', 'The domain class Person should define an equals(Object) method') } @Test void testIgnoresClassWithToStringAnnotation() { final SOURCE = ''' @EqualsAndHashCode class Person { } ''' sourceCodePath = 'project/MyProject/grails-app/domain/com/xxx/Person.groovy' assertNoViolations(SOURCE) } @Test void testIgnoresClassWithCanonicalAnnotation() { final SOURCE = ''' @Canonical class Person { } ''' sourceCodePath = 'project/MyProject/grails-app/domain/com/xxx/Person.groovy' assertNoViolations(SOURCE) } protected Rule createRule() { new GrailsDomainHasEqualsRule() } } ����������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/�����������������������������������������0000755�0001750�0001750�00000000000�12623571301�023235� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/IfStatementCouldBeTernaryRuleTest.groovy�0000644�0001750�0001750�00000015334�12311373552�033232� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for IfStatementCouldBeTernaryRule * * @author Chris Mair */ class IfStatementCouldBeTernaryRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'IfStatementCouldBeTernary' assert rule.checkLastStatementImplicitElse } @Test void testIfNoElse_NoViolations() { final SOURCE = ''' if (condition) { return 123 } ''' assertNoViolations(SOURCE) } @Test void testIfMoreThanReturn_NoViolations() { final SOURCE = ''' if (condition) { doStuff() return 44 } else { return 55 } ''' assertNoViolations(SOURCE) } @Test void testIfNoReturn_NoViolations() { final SOURCE = ''' if (condition) { [a:1] } else { return 55 } ''' assertNoViolations(SOURCE) } @Test void testElseNoReturn_NoViolations() { final SOURCE = ''' if (condition) { return 44 } else { 99 } ''' assertNoViolations(SOURCE) } @Test void testElseMoreThanReturn_NoViolations() { final SOURCE = ''' if (condition) { return 44 } else { doStuff() return 55 } ''' assertNoViolations(SOURCE) } @Test void testReturnNotConstantOrLiteral_NoViolations() { final SOURCE = ''' if (condition) { return doStuff() } else { return condition } ''' assertNoViolations(SOURCE) } @Test void testElseIf_NoViolations() { final SOURCE = ''' if (condition) { return 44 } else if (ready) { return 55 } ''' assertNoViolations(SOURCE) } @Test void testMatchingIfElse_Violation() { final SOURCE = ''' if (condition) { return 44 } else { return 'yes' } if (check()) { return [a:1] } else { return "count=$count" } if (x + y - z) { return [1, 2, 3] } else { return 99.50 } if (other.name()) { return null } else { return false } if (x) { return } else { return Boolean.FALSE } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:"if (condition) { return 44 } else { return 'yes' }", messageText:"The if statement in class None can be rewritten using the ternary operator: return condition ? 44 : 'yes'"], [lineNumber:3, sourceLineText:'if (check()) { return [a:1] } else { return "count=$count" }', messageText:'The if statement in class None can be rewritten using the ternary operator: return this.check() ? [a:1] : "count=$count"'], [lineNumber:4, sourceLineText:'if (x + y - z) { return [1, 2, 3] } else { return 99.50 }', messageText:'The if statement in class None can be rewritten using the ternary operator: return ((x + y) - z) ? [1, 2, 3] : 99.50'], [lineNumber:5, sourceLineText:'if (other.name()) { return null } else { return false }', messageText:'The if statement in class None can be rewritten using the ternary operator: return other.name() ? null : false'], [lineNumber:6, sourceLineText:'if (x) { return } else { return Boolean.FALSE }', messageText:'The if statement in class None can be rewritten using the ternary operator: return x ? null : Boolean.FALSE']) } @Test void testMatchingIfElse_NoBraces_Violation() { final SOURCE = ''' if (condition) return 44 else return 55 ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (condition)', messageText:'The if statement in class None can be rewritten using the ternary']) } @Test void testMatchingIfElseWithinClosure_Violation() { final SOURCE = ''' class MyDomain { static constraints = { registrationState(nullable: true, validator: { val, obj -> if (val) { return false } else { return true } }) } } ''' assertViolations(SOURCE, [lineNumber:5, sourceLineText:'if (val) {', messageText:'The if statement in class MyDomain can be rewritten using the ternary']) } private static final SOURCE_FALLS_THROUGH_TO_RETURN = ''' def method1() { if (condition) { return 44 } return 'yes' } def closure1 = { if (check()) return Boolean.FALSE return [1, 2] } ''' @Test void testMatchingIfReturn_NoElse_FallsThroughToReturn_Violation() { assertViolations(SOURCE_FALLS_THROUGH_TO_RETURN, [lineNumber:3, sourceLineText:'if (condition)', messageText:"The if statement in class None can be rewritten using the ternary operator: return condition ? 44 : 'yes'"], [lineNumber:9, sourceLineText:'if (check())', messageText:'The if statement in class None can be rewritten using the ternary operator: return this.check() ? Boolean.FALSE : [1, 2]'] ) } @Test void testMatchingIfReturn_NoElse_FallsThroughToReturn_checkLastStatementImplicitElse_False_NoViolation() { rule.checkLastStatementImplicitElse = false assertNoViolations(SOURCE_FALLS_THROUGH_TO_RETURN) } protected Rule createRule() { new IfStatementCouldBeTernaryRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/VectorIsObsoleteRule_VectorTest.groovy���0000644�0001750�0001750�00000002374�12041642700�032753� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for VectorIsObsoleteRule * * @author Chris Mair */ class VectorIsObsoleteRule_VectorTest extends AbstractClassReferenceRuleTestCase { final String className = 'Vector' final String violationMessage = "The $className class is obsolete" @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'VectorIsObsolete' } protected Rule createRule() { new VectorIsObsoleteRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000152�00000000000�011601� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/VectorIsObsoleteRule_JavaUtilVectorTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/VectorIsObsoleteRule_JavaUtilVectorTest.g0000644�0001750�0001750�00000002474�12041642700�033315� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for VectorIsObsoleteRule. Checks for references to 'java.util.Vector'. * * @author Chris Mair */ class VectorIsObsoleteRule_JavaUtilVectorTest extends AbstractClassReferenceRuleTestCase { final String className = 'java.util.Vector' final String violationMessage = "The $className class is obsolete" @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'VectorIsObsolete' } protected Rule createRule() { new VectorIsObsoleteRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/TernaryCouldBeElvisRuleTest.groovy�������0000644�0001750�0001750�00000005342�12044343726�032072� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for TernaryCouldBeElvisRule * * @author Chris Mair */ class TernaryCouldBeElvisRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'TernaryCouldBeElvis' } @Test void testElvis_NoViolation() { final SOURCE = ''' x ?: 1 x ?: null ''' assertNoViolations(SOURCE) } @Test void testTernaryWithDifferentBooleanAndTrueVariableExpressions_NoViolation() { final SOURCE = ''' (x == y) ? same : diff (x) ? same : diff x ? y : z x ? 99 : 33 x ? x + 1 : x + 2 x ? 1 : 0 x ? !x : x !x ? x : null ''' assertNoViolations(SOURCE) } @Test void testTernary_SimpleVariable_SameBooleanAndTrueExpression_Violation() { final SOURCE = ''' x ? x : false ''' assertSingleViolation(SOURCE, 2, 'x ? x : false', 'x ?: false') } @Test void testTernaryWithDifferentBooleanAndTrueMethodCalls_NoViolation() { final SOURCE = ''' foo() ? bar() : 123 foo() ? foo(99) : 123 foo(x) ? foo() : 123 foo(1) ? foo(2) : 123 foo(1,2) ? foo(1) : 123 foo(1) ? !foo(1) : 123 ''' assertNoViolations(SOURCE) } @Test void testTernary_MethodCall_SameBooleanAndTrueExpression_Violation() { final SOURCE = ''' foo() ? foo() : bar() foo(1) ? foo(1) : 123 ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'foo() ? foo() : bar()', messageText:'foo() ?: this.bar()'], [lineNumber:3, sourceLineText:'foo(1) ? foo(1) : 123', messageText:'foo(1) ?: 123']) } protected Rule createRule() { new TernaryCouldBeElvisRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/ParameterReassignmentRuleTest.groovy�����0000644�0001750�0001750�00000012376�12041642700�032501� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ParameterReassignmentRule * * @author Chris Mair */ class ParameterReassignmentRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ParameterReassignment' } @Test void testMethodParametersWithoutReassignment_NoViolations() { final SOURCE = ''' void myMethod(int a, String b, c) { other = 123 println a doSomething(b) } ''' assertNoViolations(SOURCE) } @Test void testClosureParametersWithoutReassignment_NoViolations() { final SOURCE = ''' def myClosure = { int a, String b, c -> other = 123 println a doSomething(b) } ''' assertNoViolations(SOURCE) } @Test void testParameterReassigned_Violation() { final SOURCE = ''' class MyClass { void myMethod(int a, String b) { println a b = 'new value' } } ''' assertSingleViolation(SOURCE, 5, "b = 'new value'", 'parameter [b] in class MyClass was reassigned') } @Test void testTwoParametersReassigned_Violations() { final SOURCE = ''' void myMethod(int a, b) { a = 123 b = new Object() } ''' assertTwoViolations(SOURCE, 3, 'a = 123', 'parameter [a] in class None was reassigned', 4, 'b = new Object()', 'parameter [b] in class None was reassigned') } @Test void testMultipleMethodsWithParametersReassigned_Violations() { final SOURCE = ''' void myMethod1(int a, b) { a = 123 } void myMethod2(int a, b) { b = new Object() } ''' assertTwoViolations(SOURCE, 3, 'a = 123', 'parameter [a] in class None was reassigned', 6, 'b = new Object()', 'parameter [b] in class None was reassigned') } @Test void testMultipleClosuresWithParametersReassigned_Violations() { final SOURCE = ''' def myClosure1 = { int a, b -> a = 123 } def myClosure2 = { int a, b -> b = new Object() } ''' assertTwoViolations(SOURCE, 3, 'a = 123', 'parameter [a] in class None was reassigned', 6, 'b = new Object()', 'parameter [b] in class None was reassigned') } @Test void testParameterReassignedWithinInnerClass_Violation() { final SOURCE = ''' int myMethod(Integer a) { def comparable = new Comparable<Integer>() { int compareTo(Integer s) { s = null return 0 } } return comparable.compareTo(a) } ''' assertSingleViolation(SOURCE, 5, 's = null', 'parameter [s] in class None') } @Test void testNestedClosure_ParametersReassigned_Violations() { final SOURCE = ''' def myClosure = { int a, String b -> println a def myInnerClosure = { int c -> c = 39 a = 0 } b = null return myInnerClosure } ''' assertViolations(SOURCE, [lineNumber:5, sourceLineText:'c = 39', messageText:'parameter [c] in class None was reassigned'], [lineNumber:6, sourceLineText:'a = 0', messageText:'parameter [a] in class None was reassigned'], [lineNumber:8, sourceLineText:'b = null', messageText:'parameter [b] in class None was reassigned']) } @Test void testAssignToFieldWithSameNameAsParameter_NoViolations() { final SOURCE = ''' class MyClass { private count = 0 void myMethod(int count) { println count // parameter } void incrementCount() { count = count + 1 // field } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new ParameterReassignmentRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/InvertedIfElseRuleTest.groovy������������0000644�0001750�0001750�00000005061�12041642700�031042� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for InvertedIfElseRule * * @author Hamlet D'Arcy */ class InvertedIfElseRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'InvertedIfElse' } @Test void testSuccessScenario() { final SOURCE = ''' if (!x) { foo() } if (x) { false } else { true } if (!x) { 1 } else if (y) { 2 } else { 3 } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenarioWithElseIf() { final SOURCE = ''' if (x) { 1 } else if (!y) { 2 } else { 3 } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' if (!x) { false } else { true } ''' assertSingleViolation(SOURCE, 2, 'if (!x) {') } @Test void testDeepNesting() { final SOURCE = ''' if (x) { if (x) { 1 } else if (!x) { if (!x) { 5 } else { 6 } } else { 3 } } else { 2 } ''' assertSingleViolation(SOURCE, 6, 'if (!x) {') } protected Rule createRule() { new InvertedIfElseRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/LongLiteralWithLowerCaseLRuleTest.groovy�0000644�0001750�0001750�00000003462�12041642700�033166� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for LongLiteralWithLowerCaseLRule * * @author Hamlet D'Arcy */ class LongLiteralWithLowerCaseLRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'LongLiteralWithLowerCaseL' } @Test void testSuccessScenario() { final SOURCE = ''' def a = 55 def b = 55L def x = 5 def y = 5L def z = 5.0f ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' def x = 1l ''' assertSingleViolation(SOURCE, 2, 'def x = 1l', 'The literal 1l should be rewritten 1L') } @Test void testLongerNUmber() { final SOURCE = ''' def x = 222l ''' assertSingleViolation(SOURCE, 2, 'def x = 222l', 'The literal 222l should be rewritten 222L') } protected Rule createRule() { new LongLiteralWithLowerCaseLRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/ConfusingTernaryRuleTest.groovy����������0000644�0001750�0001750�00000004577�12041642700�031505� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConfusingTernaryRule * * @author Hamlet D'Arcy */ class ConfusingTernaryRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ConfusingTernary' } @Test void testSuccessScenario() { final SOURCE = ''' (x == y) ? same : diff (x) ? same : diff // because of GroovyTruth, there is no inverse of != null (x != null) ? diff : same (null != x) ? diff : same // because of GroovyTruth, there is no inverse of != true (x != true) ? diff : same (true != x) ? diff : same // because of GroovyTruth, there is no inverse of != true (x != false) ? diff : same (false != x) ? diff : same ''' assertNoViolations(SOURCE) } @Test void testNotEquals() { final SOURCE = ''' (x != y) ? diff : same ''' assertSingleViolation(SOURCE, 2, '(x != y) ? diff : same', '(x != y) is a confusing negation in a ternary expression. Rewrite as (x == y) and invert the conditions.') } @Test void testNot() { final SOURCE = ''' (!x) ? diff : same ''' assertSingleViolation(SOURCE, 2, '(!x) ? diff : same', '(!x) is a confusing negation in a ternary expression. Rewrite as (x) and invert the conditions.') } protected Rule createRule() { new ConfusingTernaryRule() } } ���������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/NoDefRuleTest.groovy���������������������0000644�0001750�0001750�00000004041�12414302317�027163� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * @author Dominik Przybysz */ class NoDefRuleTest extends AbstractRuleTestCase { @Test void testSuccessScenario() { final SOURCE = '''\ List l = [1, 2, 3, 4] l.flatten() '''.stripMargin() assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = '''\ def l = [1, 2, 3, 4] l.flatten() '''.stripMargin() assertSingleViolation SOURCE, 1, 'def l = [1, 2, 3, 4]', NoDefRule.MESSAGE } @Test void testTwoViolation() { final SOURCE = '''\ def test(def l){ int k = 3 def i = 5 } '''.stripMargin() assertTwoViolations (SOURCE, 1, 'def test(def l){', NoDefRule.MESSAGE, 3, 'def i = 5', NoDefRule.MESSAGE) } @Test void testExcludesNoViolation() { rule.excludeRegex = /((setup|cleanup)(|Spec)|"[^"].*")\(\)/ //spock methods final SOURCE = '''\ def setup(){} def setupSpec(){} def cleanup(){} def cleanupSpec(){} def "should send"(){} '''.stripMargin() assertNoViolations(SOURCE) } @Override protected Rule createRule() { new NoDefRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/HashtableIsObsoleteRule_HashtableTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/HashtableIsObsoleteRule_HashtableTest.gro0000644�0001750�0001750�00000002416�12041642700�033274� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for HashtableIsObsoleteRule * * @author Chris Mair */ class HashtableIsObsoleteRule_HashtableTest extends AbstractClassReferenceRuleTestCase { final String className = 'Hashtable' final String violationMessage = "The $className class is obsolete" @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'HashtableIsObsolete' } protected Rule createRule() { new HashtableIsObsoleteRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000160�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/HashtableIsObsoleteRule_JavaUtilHashtableTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/HashtableIsObsoleteRule_JavaUtilHashtable0000644�0001750�0001750�00000002521�12041642700�033303� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for HashtableIsObsoleteRule. Checks for references to 'java.util.Hashtable'. * * @author Chris Mair */ class HashtableIsObsoleteRule_JavaUtilHashtableTest extends AbstractClassReferenceRuleTestCase { final String className = 'java.util.Hashtable' final String violationMessage = "The $className class is obsolete" @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'HashtableIsObsolete' } protected Rule createRule() { new HashtableIsObsoleteRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/convention/CouldBeElvisRuleTest.groovy��������������0000644�0001750�0001750�00000010026�12311373553�030516� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.convention import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CouldBeElvisRule * * @author GUM */ class CouldBeElvisRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'CouldBeElvis' } @Test void testIfStatement_AssignmentToDifferentVariable_NoViolation() { final SOURCE = ''' def x def y if(!x) { y = "something" } ''' assertNoViolations(SOURCE) } @Test void testIfStatement_NonAssignmentToSameVariable_NoViolation() { final SOURCE = ''' def x def y if(!x) { println x } ''' assertNoViolations(SOURCE) } @Test void testIfStatement_AssignmentToSameVariable_Violation() { final SOURCE = ''' def x if (!x) { x = "some value" } ''' assertSingleViolation(SOURCE, 4, 'if (!x)', "Code could use elvis operator: x = x ?: 'some value'") } @Test void testIfStatement_NoBraces_AssignmentToSameVariable_Violation() { final SOURCE = ''' def x if (!x) x = "some value" ''' assertSingleViolation(SOURCE, 4, 'if (!x)', "Code could use elvis operator: x = x ?: 'some value'") } @Test void testIfStatement_AssignmentToSameObjectProperty_Violation() { final SOURCE = ''' def params if (!params.max) { params.max = 10 } ''' assertSingleViolation(SOURCE, 4, 'if (!params.max)', 'Code could use elvis operator: params.max = params.max ?: 10') } @Test void testIfStatement_NoBraces_AssignmentToSameObjectProperty_Violation() { final SOURCE = ''' def params if (!params.max) params.max = 10 ''' assertSingleViolation(SOURCE, 3, 'if (!params.max)', 'Code could use elvis operator: params.max = params.max ?: 10') } @Test void testThisReferenceCouldBeElvisViolation() { final SOURCE = ''' if (!this.x) { this.x = foo() } ''' assertSingleViolation(SOURCE, 2, 'if (!this.x)', 'Code could use elvis operator: this.x = this.x ?: this.foo()') } @Test void testDoingWorkInIf() { final SOURCE = ''' def x def y if (!x) { def z = "do this" x = z + "some value" y = x+"bob" } ''' assertNoViolations(SOURCE) } @Test void testDoingWorkInIfWithXFirst() { final SOURCE = ''' def x def y if (!x) { x = "some value" def z = "do this" y = x+"bob" } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new CouldBeElvisRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/serialization/��������������������������������������0000755�0001750�0001750�00000000000�12623571301�023730� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000154�00000000000�011603� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/serialization/EnumCustomSerializationIgnoredRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/serialization/EnumCustomSerializationIgnoredRuleTest0000644�0001750�0001750�00000007040�12311373552�033513� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.serialization import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for EnumCustomSerializationIgnoredRule * * @author Chris Mair */ class EnumCustomSerializationIgnoredRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EnumCustomSerializationIgnored' } @Test void testEnum_NoViolations() { final SOURCE = ''' enum MyEnum { ONE, TWO, THREE } ''' assertNoViolations(SOURCE) } @Test void testRegularClass_CustomSerialization_NoViolations() { final SOURCE = ''' class MyClass { private static final long serialVersionUID = 1234567L private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("name", String.class) } String name; Object writeReplace() { } private void writeObject(ObjectOutputStream stream) throws IOException { } } ''' assertNoViolations(SOURCE) } @Test void testEnum_IgnoredSerializationFields_Violations() { final SOURCE = ''' enum MyEnum { ONE, TWO, THREE private static final long serialVersionUID = 1234567L private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("name", String.class) } String name; } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'private static final long serialVersionUID = 1234567L', messageText:'serialVersionUID'], [lineNumber:5, sourceLineText:'private static final ObjectStreamField[] serialPersistentFields', messageText:'serialPersistentFields'] ) } @Test void testEnum_IgnoredSerializationMethods_Violations() { final SOURCE = ''' enum MyEnum { ONE, TWO, THREE Object writeReplace() { } private void writeObject(ObjectOutputStream stream) throws IOException { } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'Object writeReplace()', messageText:'writeReplace'], [lineNumber:5, sourceLineText:'private void writeObject(ObjectOutputStream stream)', messageText:'writeObject'] ) } @Test void testEnum_IgnoredSerializationMethodNames_ButDifferentSignatures_NoViolations() { final SOURCE = ''' enum MyEnum { ONE, TWO, THREE Object writeReplace(String name) { } private Object writeReplace(int count) { } private void writeObject(String name) throws IOException { } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new EnumCustomSerializationIgnoredRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/serialization/SerialPersistentFieldsRuleTest.groovy�0000644�0001750�0001750�00000012022�12311370173�033311� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.serialization import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SerialPersistentFieldsRule * * @author 'Hamlet D'Arcy' */ class SerialPersistentFieldsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SerialPersistentFields' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass implements Serializable { private static final ObjectStreamField[] serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } // not serializable class MyClass2 { ObjectStreamField[] serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } // wrong field name class MyClass3 implements Serializable { ObjectStreamField[] zz_serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } ''' assertNoViolations(SOURCE) } @Test void testCommonMisspelling() { final SOURCE = ''' class MyClass implements Serializable { private static final serialPerSIStentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } ''' assertSingleViolation(SOURCE, 3, 'private static final serialPerSIStentFields', 'Violation in class MyClass. The class is Serializable and defines a field named serialPerSIStentFields. This should be named serialPersistentFields instead') } @Test void testWrongFieldType() { final SOURCE = ''' // Wrong field type, JVM sees it as Object! class MyClass implements Serializable { private static final serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } ''' assertSingleViolation(SOURCE, 4, 'private static final serialPersistentFields', 'Violation in class MyClass. The class is Serializable and defines a field named serialPersistentFields of type java.lang.Object. The field should be declared as a ObjectStreamField[] instead') } @Test void testNotFinal() { final SOURCE = ''' // Wrong field type, JVM sees it as Object! class MyClass implements Serializable { private static ObjectStreamField[] serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } ''' assertSingleViolation(SOURCE, 4, 'private static ObjectStreamField[] serialPersistentFields', 'Violation in class MyClass. The class is Serializable and defines a field named serialPersistentFields which is not private, static, and final') } @Test void testNotPrivate() { final SOURCE = ''' // Wrong field type, JVM sees it as Object! class MyClass implements Serializable { static final public ObjectStreamField[] serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } ''' assertSingleViolation(SOURCE, 4, 'static final public ObjectStreamField[] serialPersistentFields', 'Violation in class MyClass. The class is Serializable and defines a field named serialPersistentFields which is not private, static, and final') } @Test void testNotStatic() { final SOURCE = ''' // Wrong field type, JVM sees it as Object! class MyClass implements Serializable { private final ObjectStreamField[] serialPersistentFields = [ new ObjectStreamField("myField", List.class) ] as ObjectStreamField[] } ''' assertSingleViolation(SOURCE, 4, 'private final ObjectStreamField[] serialPersistentFields', 'Violation in class MyClass. The class is Serializable and defines a field named serialPersistentFields which is not private, static, and final') } protected Rule createRule() { new SerialPersistentFieldsRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/serialization/SerialVersionUIDRuleTest.groovy�������0000644�0001750�0001750�00000005764�12311373552�032034� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.serialization import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SerialVersionUIDRule * * @author Hamlet D'Arcy * @author Chris Mair */ class SerialVersionUIDRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SerialVersionUID' } @Test void testApplyTo_NoViolations() { final SOURCE = ''' class MyClass { private static final long serialVersionUID = 13241234134 as long } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_2_Violations() { final SOURCE = ''' class MyClass1 { private final long serialVersionUID = 13241234134 } class MyClass2 { private static long serialVersionUID = 665544 } ''' assertTwoViolations(SOURCE, 3, 'private final long serialVersionUID = 13241234134', 6, 'private static long serialVersionUID = 665544') } @Test void testApplyTo_WrongType() { final SOURCE = ''' class MyClass1 { private static final int serialVersionUID = 13241234134 } class MyClass2 { private static final Long serialVersionUID = 665544 } ''' assertTwoViolations(SOURCE, 3, 'static final int serialVersionUID = 13241234134', 6, 'static final Long serialVersionUID = 665544') } @Test void testApplyTo_Property() { final SOURCE = ''' class MyClass1 { static final long serialVersionUID = 13241234134 as long } ''' assertSingleViolation(SOURCE, 3, 'static final long serialVersionUID = 13241234134 as long') } @Test void testApplyTo_NotPrivate() { final SOURCE = ''' class MyClass { protected static final long serialVersionUID = 12345 } ''' assertSingleViolation(SOURCE, 3, 'protected static final long serialVersionUID = 12345') } protected Rule createRule() { new SerialVersionUIDRule() } } ������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000171�00000000000�011602� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/serialization/SerializableClassMustDefineSerialVersionUIDRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/serialization/SerializableClassMustDefineSerialVersi0000644�0001750�0001750�00000005207�12202002226�033374� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.serialization import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SerializableClassMustDefineSerialVersionUIDRule * * @author Hamlet D'Arcy */ class SerializableClassMustDefineSerialVersionUIDRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SerializableClassMustDefineSerialVersionUID' } @Test void testNoViolations() { final SOURCE = ''' class MyClass implements Serializable { private static final long serialVersionUID = -403250971215465050L } class MyNotSerializableClass { } return "some script" ''' assertNoViolations(SOURCE) } @Test void testEnums_NoViolations() { final SOURCE = ''' enum DeferralRequestStatus { PENDING(0), ACCEPTED(1), DENIED(2) long value DeferralRequestStatus(long pValue) { value = pValue } long getId() { return value } String getName() { return GapEnumHelper.getValue(GrailsNameUtils.getShortName(DeferralRequestStatus.class.name), value).name } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass implements Serializable { // missing serialVersionUID } ''' assertSingleViolation(SOURCE, 2, 'class MyClass implements Serializable', 'The class MyClass implements Serializable but does not define a serialVersionUID') } protected Rule createRule() { new SerializableClassMustDefineSerialVersionUIDRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/AbstractAstVisitorRuleTest.groovy�������������������0000644�0001750�0001750�00000020175�12323245545�027617� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule import org.codehaus.groovy.ast.ClassNode import org.codenarc.util.WildcardPattern import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining import static org.junit.Assert.assertFalse /** * Tests for AbstractAstVisitorRule * * @author Chris Mair * @author Hamlet D'Arcy */ class AbstractAstVisitorRuleTest extends AbstractRuleTestCase { private static final SOURCE = ''' class MyClass { int value } ''' static skipTestThatUnrelatedCodeHasNoViolations @Test void testApplyTo() { assertSingleViolation(SOURCE) } @Test void testApplyTo_TwoClasses() { final SOURCE2 = ''' class MyClass1 { int value } class MyClass2 { String name } ''' assertTwoViolations(SOURCE2, null, null, null, null) } @Test void testApplyToClassNames() { rule.applyToClassNames = 'MyClass' assertSingleViolation(SOURCE) rule.applyToClassNames = 'OtherClass,SomeTest,MyClass' assertSingleViolation(SOURCE) rule.applyToClassNames = 'XXX' assertNoViolations(SOURCE) } @Test void testApplyToClassNames_Wildcards() { rule.applyToClassNames = 'My*' assertSingleViolation(SOURCE) rule.applyToClassNames = 'MyTest??' assertNoViolations(SOURCE) } @Test void testApplyToClassNames_PatternSpecifiesPackage_NoPackage() { rule.applyToClassNames = 'org.codenarc.MyClass' assertNoViolations(SOURCE) } @Test void testApplyToClassNames_PatternMatchesSamePackage() { final SOURCE2 = ''' package org.codenarc class MyClass { } ''' rule.applyToClassNames = 'org.codenarc.OtherClass,MyClass' assertSingleViolation(SOURCE2) } @Test void testApplyToClassNames_PatternMatchesDifferentPackage() { final SOURCE2 = ''' package org.other.project class MyClass { } ''' rule.applyToClassNames = 'com.big.Other*,MyTest,org.codenarc.MyCla?s' assertNoViolations(SOURCE2) } @Test void testDoNotApplyToClassNames() { rule.doNotApplyToClassNames = 'OtherClass' assertSingleViolation(SOURCE) rule.doNotApplyToClassNames = 'OtherClass,MyClass,SomeTest' assertNoViolations(SOURCE) rule.doNotApplyToClassNames = 'MyClass' assertNoViolations(SOURCE) } @Test void testDoNotApplyToClassNames_Wildcards() { rule.doNotApplyToClassNames = 'My??Test' assertSingleViolation(SOURCE) rule.doNotApplyToClassNames = 'My??Test,OtherTest' assertSingleViolation(SOURCE) rule.doNotApplyToClassNames = 'M*Cl?ss' assertNoViolations(SOURCE) } @Test void testDoNotApplyToClassNames_PatternSpecifiesPackage_NoPackage() { rule.doNotApplyToClassNames = 'org.codenarc.MyClass' assertSingleViolation(SOURCE) } @Test void testDoNotApplyToClassNames_PatternMatchesClassNameWithPackage() { final SOURCE2 = ''' package org.codenarc class MyClass { } ''' rule.doNotApplyToClassNames = 'Other*,MyTest,org.codenarc.MyCla?s' assertNoViolations(SOURCE2) } @Test void testDoNotApplyToClassNames_PatternMatchestClassNameWithoutPackage() { final SOURCE2 = ''' package org.codenarc class MyClass { } ''' rule.doNotApplyToClassNames = 'Other*,MyClass' assertNoViolations(SOURCE2) } @Test void testDoNotApplyToClassNames_PatternDoesNotMatchPackage() { final SOURCE2 = ''' package org.other.project class MyClass { } ''' rule.doNotApplyToClassNames = 'Other*,MyTest,org.codenarc.MyCla?s' assertSingleViolation(SOURCE2) } @Test void testDoNotApplyToClassNames_PatternMatchesClassNameAndAlsoPackage() { final SOURCE2 = ''' package org.codenarc class MyClass { } ''' rule.doNotApplyToClassNames = 'MyC*ss,MyTest,org.*.MyClass' assertNoViolations(SOURCE2) } @Test void testBothApplyToClassNamesAndDoNotApplyToClassNames() { rule.applyToClassNames = 'MyClass' // apply = YES rule.doNotApplyToClassNames = 'MyClass' // doNotApply = YES assertNoViolations(SOURCE) rule.applyToClassNames = 'Xxx' // apply = NO rule.doNotApplyToClassNames = 'MyClass' // doNotApply = YES assertNoViolations(SOURCE) rule.applyToClassNames = 'MyClass' // apply = YES rule.doNotApplyToClassNames = 'Xxx' // doNotApply = NO assertSingleViolation(SOURCE) rule.applyToClassNames = 'Xxx' // apply = NO rule.doNotApplyToClassNames = 'Xxx' // doNotApply = NO assertNoViolations(SOURCE) } @Test void testDefineNewApplyToClassNamesProperty() { rule = new FakeAstVisitorRuleDefinesNewApplyToClassNamesRule() assertSingleViolation('class ApplyToClassName { }') assertNoViolations('class DoNotApplyToClassName { }') assertNoViolations('class OtherClass { }') } @Test void testApplyTo_AstVisitorClassNull() { rule.astVisitorClass = null shouldFailWithMessageContaining('astVisitorClass') { applyRuleTo('def x') } } @Test void testApplyTo_AstVisitorClassNotAnAstVisitor() { rule.astVisitorClass = String shouldFailWithMessageContaining('astVisitorClass') { applyRuleTo('def x') } } @Test void testDEFAULT_TEST_FILES() { assert 'MyTest.groovy' ==~ AbstractAstVisitorRule.DEFAULT_TEST_FILES assert 'MyTests.groovy' ==~ AbstractAstVisitorRule.DEFAULT_TEST_FILES assert 'MyTestCase.groovy' ==~ AbstractAstVisitorRule.DEFAULT_TEST_FILES assertFalse 'MyNonTestClass.groovy' ==~ AbstractAstVisitorRule.DEFAULT_TEST_FILES } @Test void testDEFAULT_TEST_CLASS_NAMES() { def wildcardPattern = new WildcardPattern(AbstractAstVisitorRule.DEFAULT_TEST_CLASS_NAMES) assert wildcardPattern.matches('MyTest') assert wildcardPattern.matches('MyTests') assert wildcardPattern.matches('MyTestCase') assertFalse wildcardPattern.matches('MyNonTestClass')\ } protected Rule createRule() { new FakeAstVisitorRule() } } // Test AbstractAstVisitorRule implementation class class FakeAstVisitorRule extends AbstractAstVisitorRule { String name = 'Test' int priority = 3 Class astVisitorClass = FakeAstVisitor } // Test AstVisitor implementation class class FakeAstVisitor extends AbstractAstVisitor { void visitClassEx(ClassNode classNode) { violations.add(new Violation(rule:rule)) super.visitClassEx(classNode) } } // Test AbstractAstVisitorRule implementation class that defines new 'applyToClassNames' and 'doNotApplyToClassNames' properties class FakeAstVisitorRuleDefinesNewApplyToClassNamesRule extends AbstractAstVisitorRule { String name = 'Test' int priority = 3 Class astVisitorClass = FakeAstVisitor String applyToClassNames = 'ApplyToClassName' String doNotApplyToClassNames = 'DoNotApplyToClassName' } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/������������������������������������������0000755�0001750�0001750�00000000000�12623571301�023111� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/CollectAllIsDeprecatedRuleTest.groovy�����0000644�0001750�0001750�00000003561�12041642702�032346� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CollectAllIsDeprecatedRule * * @author Joachim Baumann */ class CollectAllIsDeprecatedRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CollectAllIsDeprecated' } @Test void testSuccessScenario() { final SOURCE = ''' def list = [1, 2, [3, 4, [5, 6]], 7] list.collectNested { it * 2 } ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' def list = [1, 2, [3, 4, [5, 6]], 7] list.collectAll { it * 2 } list.collectAll([8, 9]) { it * 2 } ''' //assertSingleViolation(SOURCE, 3, 'list.collectAll { it * 2 }', CollectAllIsDeprecatedRule.MESSAGE) assertTwoViolations(SOURCE, 3, 'list.collectAll', CollectAllIsDeprecatedRule.MESSAGE, 4, 'list.collectAll', CollectAllIsDeprecatedRule.MESSAGE) } protected Rule createRule() { new CollectAllIsDeprecatedRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitHashMapInstantiationRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitHashMapInstantiationRuleTest.groov0000644�0001750�0001750�00000004743�12041642702�033455� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCreationOfHashMapRule * * @author Hamlet D'Arcy */ class ExplicitHashMapInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitHashMapInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' def x = [:] class MyClass { def x = [:] def m(foo = [:]) { def x = [:] def y = new HashMap() { // anony inner class OK } def m1 = new HashMap(x) // constructor with parameter is OK def m2 = new HashMap(23) def m3 = new HashMap([a:1, b:2]) } } ''' assertNoViolations(SOURCE) } @Test void testVariableDeclarations() { final SOURCE = ''' def x = new HashMap() class MyClass { def m() { def x = new HashMap() } } ''' assertTwoViolations(SOURCE, 2, 'def x = new HashMap()', 5, 'def x = new HashMap()') } @Test void testInClassUsage() { final SOURCE = ''' class MyClass { def x = new HashMap() def m(foo = new HashMap()) { } } ''' assertTwoViolations(SOURCE, 3, 'def x = new HashMap()', 4, 'def m(foo = new HashMap())') } protected Rule createRule() { new ExplicitHashMapInstantiationRule() } } �����������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToOrMethodRuleTest.groovy�����0000644�0001750�0001750�00000003066�12041642702�032375� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToOrMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToOrMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToOrMethod' } @Test void testSuccessScenario() { final SOURCE = ''' a | b a.or() a.or(a, b) or(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.or(b) ''' assertSingleViolation(SOURCE, 2, 'a.or(b)', 'Explicit call to a.or(b) method can be rewritten as a | (b)') } protected Rule createRule() { new ExplicitCallToOrMethodRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ConfusingMultipleReturnsRuleTest.groovy���0000644�0001750�0001750�00000004676�12461175513�033124� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConfusingMultipleReturnsRule * * @author Hamlet D'Arcy */ class ConfusingMultipleReturnsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ConfusingMultipleReturns' } @Test void testSuccessScenario() { final SOURCE = ''' final uninitialized_variable def x = 1 // ok def z = null def (f, g) = [1, 2] // ok (a, b, c) = [1, 2, 3] // ok class MyClass { def a = null, b = null, c = null def d, e, f } ''' assertNoViolations(SOURCE) } @Test void testDeclaration() { final SOURCE = ''' def c def d = null def e, f, g def h = null, i = null, j = null def a, b = [1, 2] // bad, b is null ''' assertSingleViolation(SOURCE, 6, 'def a, b = [1, 2]', 'Confusing declaration in class None. The variable \'a\' is initialized to null') } @Test void testInClass() { final SOURCE = ''' class MyClass { def a, b, c = [1, 2, 3] // bad, a and b are null } ''' assertTwoViolations(SOURCE, 3, 'def a, b, c = [1, 2, 3]', "Confusing declaration in class MyClass. The field 'a' is initialized to null", 3, 'def a, b, c = [1, 2, 3]', "Confusing declaration in class MyClass. The field 'b' is initialized to null", ) } protected Rule createRule() { new ConfusingMultipleReturnsRule() } } ������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000154�00000000000�011603� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitLinkedHashMapInstantiationRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitLinkedHashMapInstantiationRuleTest0000644�0001750�0001750�00000005541�12436176211�033453� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitLinkedHashMapInstantiationRule * * @author René Scheibe */ class ExplicitLinkedHashMapInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitLinkedHashMapInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' def x = [:] class MyClass { def x = [:] def m(foo = [:]) { def x = [:] def y = new LinkedHashMap() { // anonymous inner class OK } def m1 = new LinkedHashMap(x) // constructor with parameter is OK def m2 = new LinkedHashMap(23) def m3 = new LinkedHashMap([a:1, b:2]) } } ''' assertNoViolations(SOURCE) } @Test void testVariableDeclarations() { final SOURCE = ''' def x = new LinkedHashMap() class MyClass { def m() { def x = new LinkedHashMap() } } ''' assertTwoViolations(SOURCE, 2, 'def x = new LinkedHashMap()', 'LinkedHashMap objects are better instantiated using the form "[:]"', 5, 'def x = new LinkedHashMap()', 'LinkedHashMap objects are better instantiated using the form "[:]"') } @Test void testInClassUsage() { final SOURCE = ''' class MyClass { def x = new LinkedHashMap() def m(foo = new LinkedHashMap()) { } } ''' assertTwoViolations(SOURCE, 3, 'def x = new LinkedHashMap()', 'LinkedHashMap objects are better instantiated using the form "[:]"', 4, 'def m(foo = new LinkedHashMap())', 'LinkedHashMap objects are better instantiated using the form "[:]"') } protected Rule createRule() { new ExplicitLinkedHashMapInstantiationRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToXorMethodRuleTest.groovy����0000644�0001750�0001750�00000003151�12041642702�032560� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToXorMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToXorMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToXorMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a ^ b a.xor() a.xor(a, b) xor(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.xor(b) ''' assertSingleViolation(SOURCE, 2, 'a.xor(b)', 'Explicit call to a.xor(b) method can be rewritten as a ^ (b)') } protected Rule createRule() { new ExplicitCallToXorMethodRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToGetAtMethodRuleTest.groovy��0000644�0001750�0001750�00000003173�12041642702�033020� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToGetAtMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToGetAtMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToGetAtMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a[b] a.getAt() a.getAt(a, b) getAt(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.getAt(b) ''' assertSingleViolation(SOURCE, 2, 'a.getAt(b)', 'Explicit call to a.getAt(b) method can be rewritten as a[(b)]') } protected Rule createRule() { new ExplicitCallToGetAtMethodRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToLeftShiftMethodRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToLeftShiftMethodRuleTest.groo0000644�0001750�0001750�00000003247�12041642702�033327� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToLeftShiftMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToLeftShiftMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToLeftShiftMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a << b a.leftShift() a.leftShift(a, b) leftShift(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.leftShift(b) ''' assertSingleViolation(SOURCE, 2, 'a.leftShift(b)', 'Explicit call to a.leftShift(b) method can be rewritten as a << (b)') } protected Rule createRule() { new ExplicitCallToLeftShiftMethodRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000151�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitLinkedListInstantiationRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitLinkedListInstantiationRuleTest.gr0000644�0001750�0001750�00000005364�12041642702�033452� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitLinkedListInstantiationRule * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitLinkedListInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitLinkedListInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' def x = [] as Queue class MyClass { def x = [] as Queue def m(foo = [] as Queue) { def x = [] as Queue def y = new LinkedList() { // anony inner class OK } def m1 = new LinkedList(x) // constructor with parameter is OK def m2 = new LinkedList(23) def m3 = new LinkedList([1,2,3]) } } ''' assertNoViolations(SOURCE) } @Test void testVariableDeclarations() { final SOURCE = ''' def x = new LinkedList() class MyClass { def m() { def x = new LinkedList() } } ''' assertTwoViolations(SOURCE, 2, 'def x = new LinkedList()', 5, 'def x = new LinkedList()') } @Test void testInClassUsage() { final SOURCE = ''' class MyClass { def x = new LinkedList() def m(foo = new LinkedList()) { } } ''' assertTwoViolations(SOURCE, 3, 'def x = new LinkedList()', 'LinkedList objects are better instantiated using the form "[] as Queue"', 4, 'def m(foo = new LinkedList())', 'LinkedList objects are better instantiated using the form "[] as Queue"') } protected Rule createRule() { new ExplicitLinkedListInstantiationRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ClosureAsLastMethodParameterRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ClosureAsLastMethodParameterRuleTest.groov0000644�0001750�0001750�00000016231�12041642702�033406� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ClosureAsLastMethodParameterRule * * @author Marcin Erdmann */ class ClosureAsLastMethodParameterRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ClosureAsLastMethodParameter' } @Test void testSimpleSuccessScenario() { final SOURCE = ''' [1,2,3].each { println it } [1,2,3].inject([]) { acc, value -> println value } [1,2,3].inject([]) { acc, value -> println value }; ''' assertNoViolations(SOURCE) } @Test void testWithComments() { final SOURCE = ''' [1, 2, 3].each { /* sth // */ println it } [1, 2, 3].each { /* ) // */ println it } [1, 2, 3].each { /* // */ println it } ''' assertNoViolations(SOURCE) } @Test void testWithLogicalStatementAtTheEndSuccessScenario() { final SOURCE = ''' [1,2,3].any { it > 2 } && [1,2,3].all { it < 4 } ''' assertNoViolations(SOURCE) } @Test void testOneLineWithWhiteCharactersAtTheEndSuccessScenario() { final SOURCE = ' [1,2,3].each { println it } ' assertNoViolations(SOURCE) } @Test void testCallWithClosureThatIsNotTheLastMethodParameter() { final SOURCE = ''' [1,2,3].someMethod({ println it }, 'second param') ''' assertNoViolations(SOURCE) } @Test void testSimpleSingleViolation() { final SOURCE = ''' [1,2,3].each({ println it }) ''' assertSingleViolation(SOURCE, 2, '[1,2,3].each({ println it })', "The last parameter to the 'each' method call is a closure an can appear outside the parenthesis") } @Test void testComplexSingleViolation() { final SOURCE = ''' [1,2,3].each({ println it }).someMethodCall() ''' assertSingleViolation(SOURCE, 2, '''[1,2,3].each({''' ) } @Test void testLastParenthesesOnLineFollowingEndOfClosure() { final SOURCE = ''' [1,2,3].each({ println it } ).someMethodCall() ''' assertSingleViolation(SOURCE, 2, '''[1,2,3].each({''' ) } @Test void testSimpleTwoViolations() { final SOURCE = ''' [1,2,3].each({ println it }) def value = 1 [1,2,3].someMethod('first param', { println it }) ''' assertTwoViolations(SOURCE, 2, '[1,2,3].each({ println it })', 4, '[1,2,3].someMethod(\'first param\', { println it })') } @Test void testComplexTwoViolations() { final SOURCE = ''' [1,2,3].each({ println it }).someMethod('first param', { println it } ) ''' assertTwoViolations(SOURCE, 2, '''[1,2,3].each({''', 2, '''[1,2,3].each({''' ) } @Test void testLinesWithStringsContainingDoubleSlash() { final SOURCE = ''' @Test void testProcess() { shouldFail { process('xxx://wrsnetdev.usa.wachovia.net') } shouldFail(Exception) { process('http://') } shouldFail { process('http://wrsnetdev.usa.wachovia.net:xxx') } } ''' assertNoViolations(SOURCE) } @Test void testMethodCallWiderThanClosureParameter() { final SOURCE = ''' doWithTransactionAndReallyLongName( 'testing within a transaction', new BigDecimal("123456789012345")) { process('12345') } ''' assertNoViolations(SOURCE) } @Test void testMethodCallSurroundedByExtraParentheses() { final SOURCE = ''' def filterFunds() { (funds.findAll { it.fundCode } ) } def filterFunds_TwoExtraParentheses() { ((funds.findAll{it.fundCode})) } def extendFunds() { (funds.extend(3) { it.fundCode } ) } def purgeFunds() { (funds.purge { it.fundCode } ) } boolean isSkipParticipant(Participant participant) { if(((majorMinorStatusList.findAll{it -> it==(participant.majorStatus + participant.minorStatus).trim()})) || ((majorStatusList.findAll{it ->it==(participant.majorStatus).trim()})) || (participant.paymentCode == 1)||(participant.ssn=='')) { return true } return false } // The only violation def clearFunds() { (println(funds.clear('clearing', { it.fundCode }) )) } ''' assertSingleViolation(SOURCE, 28, "funds.clear('clearing', { it.fundCode })", "The last parameter to the 'clear' method call is a closure an can appear outside the parenthesis") } @Test void testNestedMethodCallSurroundedByExtraParentheses_KnownLimitation() { final SOURCE = ''' def clearFunds() { (println((funds.clear('clearing', { it.fundCode })) )) } ''' // Should actually fail with violation for inner method call -- clear() //assertSingleViolation(SOURCE, 3, "funds.clear('clearing', { it.fundCode })", "The last parameter to the 'clear' method call is a closure an can appear outside the parenthesis") assertNoViolations(SOURCE) } @Test void testMultiLineMethodCall_StartsWithParentheses() { final SOURCE = ''' ((Node)o).children().inject( [:] ){ Map<String, String> m, Node childNode -> println m } (0..1).inject( [:] ){ Map<String, String> m, Node childNode -> println m } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new ClosureAsLastMethodParameterRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitHashSetInstantiationRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitHashSetInstantiationRuleTest.groov0000644�0001750�0001750�00000005211�12311370173�033462� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitHashSetInstantiationRule * * @author Hamlet D'Arcy */ class ExplicitHashSetInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitHashSetInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' def x = [] as Set class MyClass { def x = [] as Set def m(foo = [] as Set) { def x = [] as Set def y = new HashSet() { // anony inner class OK } def s1 = new HashSet(x) // constructor with parameter is OK def s2 = new HashSet(23) def s3 = new HashSet([a:1, b:2]) } } ''' assertNoViolations(SOURCE) } @Test void testVariableDeclarations() { final SOURCE = ''' def x = new HashSet() class MyClass { def m() { def x = new HashSet() } } ''' assertTwoViolations(SOURCE, 2, 'def x = new HashSet()', 5, 'def x = new HashSet()') } @Test void testInClassUsage() { final SOURCE = ''' class MyClass { def x = new HashSet() def m(foo = new HashSet()) { } } ''' assertTwoViolations(SOURCE, 3, 'def x = new HashSet()', 'HashSet objects are better instantiated using the form "[] as Set"', 4, 'def m(foo = new HashSet())', 'HashSet objects are better instantiated using the form "[] as Set"') } protected Rule createRule() { new ExplicitHashSetInstantiationRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/GroovyLangImmutableRuleTest.groovy��������0000644�0001750�0001750�00000005635�12041642702�032006� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for GroovyLangImmutableRule * * @author Hamlet D'Arcy */ class GroovyLangImmutableRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GroovyLangImmutable' } @Test void testSuccessScenario1() { final SOURCE = ''' @groovy.transform.Immutable class Person { } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario2() { final SOURCE = ''' import groovy.transform.Immutable @Immutable class Person { } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario3() { final SOURCE = ''' import groovy.transform.* @Immutable class Person { } ''' assertNoViolations(SOURCE) } @Test void testSuccessScenario4() { final SOURCE = ''' import groovy.transform.Immutable as Imtl @Imtl class Person { } ''' assertNoViolations(SOURCE) } @Test void testDefaultImport() { final SOURCE = ''' @Immutable class Person { } ''' assertSingleViolation(SOURCE, 2, '@Immutable', 'groovy.lang.Immutable is deprecated in favor of groovy.transform.Immutable') } @Test void testFullyQualified() { final SOURCE = ''' @groovy.lang.Immutable class Person { } ''' assertSingleViolation(SOURCE, 2, '@groovy.lang.Immutable', 'groovy.lang.Immutable is deprecated in favor of groovy.transform.Immutable') } @Test void testImportAlias() { final SOURCE = ''' import groovy.lang.Immutable as Imtl @Imtl class Person { } ''' assertSingleViolation(SOURCE, 3, '@Imtl', 'groovy.lang.Immutable is deprecated in favor of groovy.transform.Immutable') } protected Rule createRule() { new GroovyLangImmutableRule() } } ���������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/UseCollectNestedRuleTest.groovy�����������0000644�0001750�0001750�00000005174�12041642702�031262� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseCollectNestedRule * * @author Joachim Baumann * @author Chris Mair */ class UseCollectNestedRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UseCollectNested' } @Test void testProperUsageOfCollect_NoViolations() { final SOURCE = ''' def list = [1, 2, [3, 4, 5, 6], [7]] println list.collect { elem -> if (elem instanceof List) [elem, elem * 2].collect {it * 2} else elem * 2 } ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' def list = [1, 2, [3, 4, 5, 6], [7]] println list.collect { elem -> if (elem instanceof List) elem.collect {it *2} // violation else elem * 2 } println list.collect([8]) { if (it instanceof List) it.collect {it *2} // violation else it * 2 } ''' assertTwoViolations(SOURCE, 6, 'elem.collect {it *2} // violation', UseCollectNestedRule.MESSAGE, 12, 'it.collect {it *2} // violation', UseCollectNestedRule.MESSAGE) } @Test void testBugFix_CannotCastVariableExpression_NoViolations() { final SOURCE = ''' class MyBuilder { void execute(Closure antClosure) { Closure converter = {File file -> file.toURI().toURL() } List<URL> classpathUrls = fullClasspath.collect(converter) } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UseCollectNestedRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToCompareToMethodRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToCompareToMethodRuleTest.groo0000644�0001750�0001750�00000003264�12041642702�033327� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToCompareToMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToCompareToMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToCompareToMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a == b a <=> b a < b a > b a >= b a <= b a.compareTo() a.compareTo(a, b) compareTo(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.compareTo(b) ''' assertSingleViolation(SOURCE, 2, 'a.compareTo(b)') } protected Rule createRule() { new ExplicitCallToCompareToMethodRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToPlusMethodRuleTest.groovy���0000644�0001750�0001750�00000003557�12041642702�032745� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToPlusMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToPlusMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToPlusMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a + b a.plus() a.plus(a, b) plus(a) ''' assertNoViolations(SOURCE) } @Test void testChainedCall() { rule.ignoreThisReference = false final SOURCE = ''' value?.toBigDecimal()?.plus(100000) value?.plus(100000) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.plus(b) ''' assertSingleViolation(SOURCE, 2, 'a.plus(b)', 'Explicit call to a.plus(b) method can be rewritten as a + (b)') } protected Rule createRule() { new ExplicitCallToPlusMethodRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitStackInstantiationRuleTest.groovy�0000644�0001750�0001750�00000005211�12041642702�033361� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitStackInstantiationRule * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitStackInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitStackInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' def x = [] as Stack class MyClass { def x = [] as Stack def m(foo = [] as Stack) { def x = [] as Stack def y = new Stack() { // anony inner class OK } def m1 = new Stack(x) // constructor with parameter is OK def m2 = new Stack(23) def m3 = new Stack([a:1, b:2]) } } ''' assertNoViolations(SOURCE) } @Test void testVariableDeclarations() { final SOURCE = ''' def x = new Stack() class MyClass { def m() { def x = new Stack() } } ''' assertTwoViolations(SOURCE, 2, 'def x = new Stack()', 5, 'def x = new Stack()') } @Test void testInClassUsage() { final SOURCE = ''' class MyClass { def x = new Stack() def m(foo = new Stack()) { } } ''' assertTwoViolations(SOURCE, 3, 'def x = new Stack()', 'Stack objects are better instantiated using the form "[] as Stack"', 4, 'def m(foo = new Stack())', 'Stack objects are better instantiated using the form "[] as Stack"') } protected Rule createRule() { new ExplicitStackInstantiationRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/AssignCollectionUniqueRuleTest.groovy�����0000644�0001750�0001750�00000004440�12041642702�032477� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AssignCollectionUniqueRule * * @author Nick Larson * @author Juan Vazquez * @author Jon DeJong * */ class AssignCollectionUniqueRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AssignCollectionUnique' } @Test void testSuccessScenario() { final SOURCE = ''' def allPaths = resultsMap.values().unique() myList.unique() myList.unique() { it } myList.unique(2) { it } myList.findAll{ it < 50 }.unique() def w = getMyList().unique().findAll { x < 1 } def x = myList.foo.unique().findAll { x < 1 } def y = myList.foo().unique().findAll { x < 1 } ''' assertNoViolations(SOURCE) } @Test void testNoArgs() { final SOURCE = ''' def x = myList.unique() ''' assertSingleViolation(SOURCE, 2, 'def x = myList.unique()') } @Test void testOneArgs() { final SOURCE = ''' def x = myList.unique() { it } ''' assertSingleViolation(SOURCE, 2, 'def x = myList.unique()') } @Test void testChaining() { final SOURCE = ''' def x = myList.unique().findAll { x < 1 } ''' assertSingleViolation(SOURCE, 2, 'def x = myList.unique().findAll { x < 1 }') } protected Rule createRule() { new AssignCollectionUniqueRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToEqualsMethodRuleTest.groovy�0000644�0001750�0001750�00000003404�12311370173�033243� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToEqualsMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToEqualsMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToEqualsMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a == b a.equals() a.equals(a, b) equals(a) this.equals(a) super.equals(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.equals(b) ''' assertSingleViolation(SOURCE, 2, 'a.equals(b)', 'Violation in class None. Explicit call to a.equals(b) method can be rewritten as (a == (b))') } protected Rule createRule() { new ExplicitCallToEqualsMethodRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitTreeSetInstantiationRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitTreeSetInstantiationRuleTest.groov0000644�0001750�0001750�00000005277�12311370173�033512� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCreationOfTreeSetRule * * @author Hamlet D'Arcy * @author Chris Mair */ class ExplicitTreeSetInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitTreeSetInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' def x = [] as SortedSet class MyClass { def x = [] as SortedSet def m(foo = [] as SortedSet) { def x = [] as SortedSet def y = new TreeSet() { // anony inner class OK } def m1 = new TreeSet(x) // constructor with parameter is OK def m2 = new TreeSet(23) def m3 = new TreeSet([1,2,3]) } } ''' assertNoViolations(SOURCE) } @Test void testVariableDeclarations() { final SOURCE = ''' def x = new TreeSet() class MyClass { def m() { def x = new TreeSet() } } ''' assertTwoViolations(SOURCE, 2, 'def x = new TreeSet()', 5, 'def x = new TreeSet()') } @Test void testInClassUsage() { final SOURCE = ''' class MyClass { def x = new TreeSet() def m(foo = new TreeSet()) { } } ''' assertTwoViolations(SOURCE, 3, 'def x = new TreeSet()', 'TreeSet objects are better instantiated using the form "[] as SortedSet"', 4, 'def m(foo = new TreeSet())', 'TreeSet objects are better instantiated using the form "[] as SortedSet"') } protected Rule createRule() { new ExplicitTreeSetInstantiationRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000146�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToMultiplyMethodRuleTest.groovy���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToMultiplyMethodRuleTest.groov0000644�0001750�0001750�00000003321�12311370173�033435� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToMultiplyMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToMultiplyMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToMultiplyMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a * b a.multiply() x*.multiply(2) // spread safe must be OK a.multiply(a, b) multiply(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.multiply(b) ''' assertSingleViolation(SOURCE, 2, 'a.multiply(b)', 'Explicit call to a.multiply(b) method can be rewritten as a * (b)') } protected Rule createRule() { new ExplicitCallToMultiplyMethodRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/GStringAsMapKeyRuleTest.groovy������������0000644�0001750�0001750�00000004154�12041642702�031022� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for GStringAsMapKeyRule * * @author @Hackergarten */ class GStringAsMapKeyRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GStringAsMapKey' } @Test void testSimpleMapIsOK() { final SOURCE = ''' Map map = [string: 'thats ok'] ''' assertNoViolations(SOURCE) } @Test void testAnyGStringIsDisallowedAsKey() { final SOURCE = ''' Map map = ["${ someRef }" : 'invalid' ] ''' assertSingleViolation( SOURCE, 2, '["${ someRef }" :') } @Test void testNestedGStringInValueIsCalled() { final SOURCE = ''' def x = 'something' Map map = ["outer $x" : ["nested $x" : 'invalid'] ] ''' assertTwoViolations( SOURCE, 3, '["outer $x" ', 4, '["nested $x" ') } @Test void testNestedGStringInKeyIsCalled() { final SOURCE = ''' def x = 'something' Map map = [ ["outer $x" : 'foo'] : 'invalid' ] ''' assertSingleViolation( SOURCE, 3, '["outer $x" ' ) } protected Rule createRule() { new GStringAsMapKeyRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToPowerMethodRuleTest.groovy��0000644�0001750�0001750�00000003177�12041642702�033114� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToPowerMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToPowerMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToPowerMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a ** b a.power() a.power(a, b) power(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.power(b) ''' assertSingleViolation(SOURCE, 2, 'a.power(b)', 'Explicit call to a.power(b) method can be rewritten as a ** (b)') } protected Rule createRule() { new ExplicitCallToPowerMethodRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/GetterMethodCouldBePropertyRuleTest.groovy0000644�0001750�0001750�00000013761�12041642702�033454� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for GetterMethodCouldBePropertyRule * * @author Hamlet D'Arcy * @author Chris Mair */ class GetterMethodCouldBePropertyRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'GetterMethodCouldBeProperty' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { static VALUE = 'value' final String something = 'something' // this is cleaner final String somethingElse = VALUE // this is cleaner final String someClass = String // this is cleaner @Override String getSomething(def parameter) { //not a java getter } @Override String getSomethingElse() { performSomeWork() // not a simple one liner 'something else' } } ''' assertNoViolations(SOURCE) } @Test void testIgnoreProtectedGetterMethods() { final SOURCE = ''' class MyClass { @Override protected int getValue() { 123 } @Override protected getValue2() { return 'abc' } } ''' assertNoViolations(SOURCE) } @Test void testConstantReturn() { final SOURCE = ''' class MyClass { @Override String getSomething() { 'something' // this could be simplified } } ''' assertSingleViolation(SOURCE, 4, 'String getSomething()', "The method 'getSomething ' in class MyClass can be expressed more simply as the field declaration\nfinal String something = 'something'") } @Test void testConstantReturnExplicit() { final SOURCE = ''' class MyClass { @Override String getSomething() { return 'something' // this could be simplified } } ''' assertSingleViolation(SOURCE, 4, 'String getSomething()', "The method 'getSomething ' in class MyClass can be expressed more simply as the field declaration\nfinal String something = 'something'") } @Test void testClassReturn() { final SOURCE = ''' class MyClass { @Override Class getSomething() { String // this could be simplified } } ''' assertSingleViolation(SOURCE, 4, 'Class getSomething()', "The method 'getSomething ' in class MyClass can be expressed more simply as the field declaration\nfinal Class something = String") } @Test void testConstantExplicitReturn() { final SOURCE = ''' class MyClass { @Override String getSomething() { return 'something' // this could be simplified } } ''' assertSingleViolation(SOURCE, 4, 'String getSomething()', "The method 'getSomething ' in class MyClass can be expressed more simply as the field declaration\nfinal String something = 'something'") } @Test void testStaticReturn() { final SOURCE = ''' class MyClass { static VALUE = 'value' @Override String getSomethingElse() { VALUE // this could be simplified } } ''' assertSingleViolation(SOURCE, 6, 'String getSomethingElse()', "The method 'getSomethingElse ' in class MyClass can be expressed more simply as the field declaration\nfinal String somethingElse = VALUE") } @Test void testStaticExplicitReturn() { final SOURCE = ''' class MyClass { static VALUE = 'value' @Override String getSomethingElse() { return VALUE // this could be simplified } } ''' assertSingleViolation(SOURCE, 6, 'String getSomethingElse()', "The method 'getSomethingElse ' in class MyClass can be expressed more simply as the field declaration\nfinal String somethingElse = VALUE") } @Test void testStaticGetterMethod() { final SOURCE = ''' class MyClass { static VALUE = 'value' static String getValue() { VALUE // this could be simplified } } ''' assertSingleViolation(SOURCE, 4, 'static String getValue()', "The method 'getValue ' in class MyClass can be expressed more simply as the field declaration\nstatic final String value = VALUE") } protected Rule createRule() { new GetterMethodCouldBePropertyRule() } } ���������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/UseCollectManyRuleTest.groovy�������������0000644�0001750�0001750�00000003255�12041642702�030742� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseCollectManyRule * * @author Joachim Baumann */ class UseCollectManyRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UseCollectMany' } @Test void testSuccessScenario() { final SOURCE = ''' def l = [1, 2, 3, 4] l.collect{ [it, it*2] } l.flatten() def res = l.collect{ [it, it*2] } res.flatten() ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' def l = [1, 2, 3, 4] l.collect{ [it, it*2] }.flatten() ''' assertSingleViolation SOURCE, 3, 'l.collect{ [it, it*2] }.flatten()', UseCollectManyRule.MESSAGE } protected Rule createRule() { new UseCollectManyRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToAndMethodRuleTest.groovy����0000644�0001750�0001750�00000003000�12311370173�032503� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToAndMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToAndMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToAndMethod' } @Test void testSuccessScenario() { final SOURCE = ''' a & b a.and() a.and(a, b) and(b) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.and(b) ''' assertSingleViolation(SOURCE, 2, 'a.and(b)') } protected Rule createRule() { new ExplicitCallToAndMethodRule() } } CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToModMethodRuleTest.groovy����0000644�0001750�0001750�00000003151�12311370173�032527� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToModMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToModMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToModMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a % b a.mod() a.mod(a, b) mod(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.mod(b) ''' assertSingleViolation(SOURCE, 2, 'a.mod(b)', 'Explicit call to a.mod(b) method can be rewritten as a % (b)') } protected Rule createRule() { new ExplicitCallToModMethodRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitArrayListInstantiationRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitArrayListInstantiationRuleTest.gro0000644�0001750�0001750�00000005225�12041642702�033475� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitArrayListInstantiationRule * * @author Hamlet D'Arcy */ class ExplicitArrayListInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitArrayListInstantiation' } @Test void testSuccessScenario() { final SOURCE = ''' def x = [] class MyClass { def x = [] def m(foo = []) { def x = [] def y = new ArrayList() { // anony inner class OK } def a1 = new ArrayList(x) // constructor with parameter is OK def a2 = new ArrayList(23) def a3 = ArrayList([1, 2, 3]) } } ''' assertNoViolations(SOURCE) } @Test void testVariableDeclarations() { final SOURCE = ''' def x = new ArrayList() class MyClass { def m() { def x = new ArrayList() } } ''' assertTwoViolations(SOURCE, 2, 'def x = new ArrayList()', 'ArrayList objects are better instantiated using the form "[]"', 5, 'def x = new ArrayList()', 'ArrayList objects are better instantiated using the form "[]"') } @Test void testInClassUsage() { final SOURCE = ''' class MyClass { def x = new ArrayList() def m(foo = new ArrayList()) { } } ''' assertTwoViolations(SOURCE, 3, 'def x = new ArrayList()', 4, 'def m(foo = new ArrayList())') } protected Rule createRule() { new ExplicitArrayListInstantiationRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToMinusMethodRuleTest.groovy��0000644�0001750�0001750�00000003175�12311370173�033111� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToMinusMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToMinusMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToMinusMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a - b a.minus() a.minus(a, b) minus(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.minus(b) ''' assertSingleViolation(SOURCE, 2, 'a.minus(b)', 'Explicit call to a.minus(b) method can be rewritten as a - (b)') } protected Rule createRule() { new ExplicitCallToMinusMethodRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToDivMethodRuleTest.groovy����0000644�0001750�0001750�00000003051�12041642702�032531� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToDivMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToDivMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToDivMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a / b a.div() a.div(a, b) div(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.div(b) ''' assertSingleViolation(SOURCE, 2, 'a.div(b)') } protected Rule createRule() { new ExplicitCallToDivMethodRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/GStringExpressionWithinStringRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/GStringExpressionWithinStringRuleTest.groo0000644�0001750�0001750�00000010751�12430534750�033507� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for GStringExpressionWithinStringRule * * @author Chris Mair */ class GStringExpressionWithinStringRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'GStringExpressionWithinString' } @Test void testSingleQuoteStrings_WithoutGStringExpressions_NoViolations() { final SOURCE = ''' def str1 = '123' def str2 = 'abc def ghi' def str3 = 'abc ${ ghu' def str4 = 'abc $ghu }' def str5 = 'abc {123}' def str6 = 'abc $}' ''' assertNoViolations(SOURCE) } @Test void testSingleQuoteStrings_WithQuasiGStringExpressionInAnnotation_NoViolations() { final SOURCE = ''' class SomeClass { @SomeAnnotationOnField('${sample.property1}') String sampleProperty @SomeAnnotationOnMethod('${sample.property2}') void method() { } } ''' assertNoViolations(SOURCE) } @Test void testSingleQuoteStrings_WithQuasiGStringExpressionInAnnotation_AnnotatedMethodInAnnotatedClass_NoViolations() { final SOURCE = ''' @SomeAnnotationOnClass('${sample.property1}') class SomeClass { @SomeAnnotationOnField('${sample.property2}') String sampleProperty @SomeAnnotationOnMethod('${sample.property3}') void method() { } } ''' assertNoViolations(SOURCE) } @Test void testSingleQuoteStrings_WithQuasiGStringExpressionInAnnotation_NestedAnnotations_NoViolations() { final SOURCE = ''' @SomeAnnotationOnClass(attribute='${sample.property1}', nested=[@NestedAnnotation('${sample.property2}'), @NestedAnnotation('${sample.property3}')], someOtherAttribute='${sample.property4}') class SomeClass { } ''' assertNoViolations(SOURCE) } @Test void testSingleQuoteStrings_WithQuasiGStringExpressionInAnnotation_MultivalueElement_NoViolations() { final SOURCE = ''' @SomeAnnotationOnClass(attribute=['${sample.property1}', '${sample.property2}']) class SomeClass { } ''' assertNoViolations(SOURCE) } @Test void testDoubleQuoteStrings_NoViolations() { final SOURCE = ''' def str1 = "123" def str2 = "abc def ghi" def str3 = "abc ${count}" def str4 = "abc $count }" def str5 = "abc {123}" def str6 = "abc ${}" def str7 = "total: ${count * 25}" ''' assertNoViolations(SOURCE) } @Test void testSingleQuoteStrings_WithGStringExpression_Violations() { final SOURCE = ''' def str1 = 'total: ${count}' def str2 = 'average: ${total / count}' ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:"def str1 = 'total: \${count}'", messageText:'\'${count}\''], [lineNumber:3, sourceLineText:"def str2 = 'average: \${total / count}'", messageText:'\'${total / count}\'']) } @Test void testSingleQuoteStrings_WithGStringExpressionInAnnotatedMethod_SingleViolation() { final SOURCE = ''' class SomeClass { @SomeAnnotationOnMethod('${sample.property}') void method() { def str1 = 'total: ${count}' } } ''' assertSingleViolation(SOURCE, 5, "def str1 = 'total: \${count}'", '\'${count}\'') } protected Rule createRule() { new GStringExpressionWithinStringRule() } } �����������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/AssignCollectionSortRuleTest.groovy�������0000644�0001750�0001750�00000007130�12106560372�032163� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AssignCollectionSortRule * * @author Hamlet D'Arcy * @author Chris Mair */ class AssignCollectionSortRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AssignCollectionSort' } @Test void testNoViolations() { final SOURCE = ''' def allPaths = resultsMap.keySet().sort() myList.sort() myList.sort() { it } myList.sort(2) { it } myList.findAll{ it < 50 }.sort() def w = getMyList().sort().findAll { x < 1 } def x = myList.foo.sort().findAll { x < 1 } def y = myList.foo().sort().findAll { x < 1 } ''' assertNoViolations(SOURCE) } @Test void testNoArgs() { final SOURCE = ''' def x = myList.sort() ''' assertSingleViolation(SOURCE, 2, 'def x = myList.sort()') } @Test void testOneArg_Closure() { final SOURCE = ''' def x = myList.sort { it } ''' assertSingleViolation(SOURCE, 2, 'def x = myList.sort') } @Test void testOneArg_Comparator() { final SOURCE = ''' def x = myList.sort(comparator) ''' assertSingleViolation(SOURCE, 2, 'def x = myList.sort') } @Test void testOneArg_True() { final SOURCE = ''' def x = myList.sort(true) ''' assertSingleViolation(SOURCE, 2, 'def x = myList.sort') } @Test void testOneArg_False() { final SOURCE = ''' def x = myList.sort(false) ''' assertNoViolations(SOURCE) } @Test void testTwoArgs_Closure_MutateTrue() { final SOURCE = ''' def x = myList.sort(true) { it } ''' assertSingleViolation(SOURCE, 2, 'def x = myList.sort') } @Test void testTwoArgs_Closure_MutateFalse() { final SOURCE = ''' def x = myList.sort(false) { it } ''' assertNoViolations(SOURCE) } @Test void testTwoArgs_Comparator_MutateTrue() { final SOURCE = ''' def x = myList.sort(true, comparator) ''' assertSingleViolation(SOURCE, 2, 'def x = myList.sort') } @Test void testTwoArgs_Comparator_MutateFalse() { final SOURCE = ''' def x = myList.sort(false, comparator) ''' assertNoViolations(SOURCE) } @Test void testChaining() { final SOURCE = ''' def x = myList.sort().findAll { x < 1 } ''' assertSingleViolation(SOURCE, 2, 'def x = myList.sort().findAll { x < 1 }') } protected Rule createRule() { new AssignCollectionSortRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToRightShiftMethodRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/groovyism/ExplicitCallToRightShiftMethodRuleTest.gro0000644�0001750�0001750�00000003261�12041642702�033327� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.groovyism import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitCallToRightShiftMethodRule * * @author Hamlet D'Arcy */ class ExplicitCallToRightShiftMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitCallToRightShiftMethod' } @Test void testSuccessScenario() { rule.ignoreThisReference = true final SOURCE = ''' a >> b a.rightShift() a.rightShift(a, b) rightShift(a) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' a.rightShift(b) ''' assertSingleViolation(SOURCE, 2, 'a.rightShift(b)', 'Explicit call to a.rightShift(b) method can be rewritten as a >> (b)') } protected Rule createRule() { new ExplicitCallToRightShiftMethodRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/ClassResolutionTest.groovy��������������������������0000644�0001750�0001750�00000002154�12041642700�026311� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule import org.junit.Test /** * * @author Hamlet D'Arcy */ class ClassResolutionTest extends AbstractRuleTestCase { @Test void testGrabError() { def source = ''' @Grab(group='org.springframework', module='spring', version='2.5.6') import org.springframework.jdbc.core.JdbcTemplate ''' assertNoViolations source } @Override protected Rule createRule() { new StubRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/�������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022722� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/UnsafeImplementationAsMapRuleTest.groovy���0000644�0001750�0001750�00000006625�12236326516�032751� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for UnsafeImplementationAsMapRule * * @author Artur Gajowy */ class UnsafeImplementationAsMapRuleTest extends AbstractRuleTestCase { private static final SOURCE_WITH_SINGLE_VIOLATION = """ [next: {}] as Iterator ${violation('java.util.Iterator', 'hasNext, remove')} """ @Before void setup() { sourceCodePath = '/src/main/where/ever/Whatever.groovy' } @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnsafeImplementationAsMap' } @Test void testNoViolations() { assertNoViolations(''' [run: {}] as Runnable ''') } @Test void testTestSourcesNotCheckedByDefault() { sourceCodePath = '/where/ever/WhateverTest.groovy' assertNoViolations(removeInlineViolations(SOURCE_WITH_SINGLE_VIOLATION)) } @Test void testSingleViolation() { assertInlineViolations(SOURCE_WITH_SINGLE_VIOLATION) } @Test void testMultipleViolations() { assertInlineViolations(""" [:] as Runnable ${violation('java.lang.Runnable', 'run')} [noSuchMethod: {}] as Iterator ${violation('java.util.Iterator', 'hasNext, next, remove')} ['next': {}] as Iterator ${violation('java.util.Iterator', 'hasNext, remove')} """) } @Test void testMethodsMissingFromInheritedInterfaceViolate() { assertInlineViolations(""" interface FunnyIterator extends Iterator { void makeFun() void makeLotsOfFun() } [next: {}, makeFun: {}] as FunnyIterator ${violation('FunnyIterator', 'hasNext, makeLotsOfFun, remove')} """) } @Test void testViolation_WithinClass() { assertInlineViolations(''' class ValueClass { def listener = [mouseClicked: { }] as java.awt.event.MouseListener #java.awt.event.MouseListener } ''') } private static String violation(String implementedInterface, String missingMethods) { inlineViolation( "Incomplete interface implementation. The following methods of $implementedInterface are not implemented" + " by this map-to-interface coercion: [$missingMethods]. Please note that calling any of these methods" + ' on this implementation will cause an UnsupportedOperationException, which is likely not intended.' ) } protected Rule createRule() { new UnsafeImplementationAsMapRule() } } �����������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/JavaIoPackageAccessRuleTest.groovy���������0000644�0001750�0001750�00000010061�12041642702�031424� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JavaIoPackageAccessRule * * @author 'Hamlet D'Arcy' */ class JavaIoPackageAccessRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JavaIoPackageAccess' } @Test void testSuccessScenario() { final SOURCE = ''' fileSystem.getFileSystem() //just a variable reference, not a FileSystem reference fileSystem.fileSystem.delete(aFile) new File() // no arg ctor allowed, b/c they don't exist in JDK new File(one, two, three) // three arg ctor allowed, b/c they don't exist in JDK new FileReader() // no arg ctor allowed, b/c they don't exist in JDK new FileReader(one, two, three) // three arg ctor allowed, b/c they don't exist in JDK new FileOutputStream() // no arg ctor allowed, b/c they don't exist in JDK new FileOutputStream(one, two, three) new FileOutputStream(one, two, three) new RandomAccessFile(parm) new RandomAccessFile(one, two, three) ''' assertNoViolations(SOURCE) } @Test void testFileOutputStream() { final SOURCE = ''' new FileOutputStream(name) new FileOutputStream(name, true) ''' assertTwoViolations(SOURCE, 2, 'new FileOutputStream(name)', 'The use of java.io.FileOutputStream violates the Enterprise Java Bean specification', 3, 'new FileOutputStream(name, true)', 'The use of java.io.FileOutputStream violates the Enterprise Java Bean specification') } @Test void testFileReader() { final SOURCE = ''' new FileReader(file) ''' assertSingleViolation(SOURCE, 2, 'new FileReader(file)', 'The use of java.io.FileReader violates the Enterprise Java Bean specification') } @Test void testRandomAccessFile() { final SOURCE = ''' new RandomAccessFile(name, parent) ''' assertSingleViolation(SOURCE, 2, 'new RandomAccessFile(name, parent)', 'The use of java.io.RandomAccessFile violates the Enterprise Java Bean specification') } @Test void testFile() { final SOURCE = ''' new File(name) new File(name, parent) ''' assertTwoViolations(SOURCE, 2, 'new File(name)', 'The use of java.io.File violates the Enterprise Java Bean specification', 3, 'new File(name, parent)', 'The use of java.io.File violates the Enterprise Java Bean specification') } @Test void testFileSystem() { final SOURCE = ''' FileSystem.getFileSystem() // any method on FileSystem FileSystem.fileSystem.delete(aFile) // property access of FileSystem ''' assertTwoViolations(SOURCE, 2, 'FileSystem.getFileSystem()', 'The use of java.io.FileSystem violates the Enterprise Java Bean specification', 3, 'FileSystem.fileSystem.delete(aFile)', 'The use of java.io.FileSystem violates the Enterprise Java Bean specification') } protected Rule createRule() { new JavaIoPackageAccessRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/NonFinalPublicFieldRuleTest.groovy���������0000644�0001750�0001750�00000003307�12041642702�031471� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for NonFinalPublicFieldRule * * @author 'Hamlet D'Arcy' */ class NonFinalPublicFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'NonFinalPublicField' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { final String myField public final String myConstant = '' } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass { public String myField } ''' assertSingleViolation(SOURCE, 3, 'public String myField', 'The field myField is public but not final, which violates secure coding principles') } protected Rule createRule() { new NonFinalPublicFieldRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000155�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/NonFinalSubclassOfSensitiveInterfaceRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/NonFinalSubclassOfSensitiveInterfaceRuleTes0000644�0001750�0001750�00000014624�12041642704�033364� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for NonFinalSubclassOfSensitiveInterfaceRule * * @author Hamlet D'Arcy */ class NonFinalSubclassOfSensitiveInterfaceRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'NonFinalSubclassOfSensitiveInterface' } @Test void testSuccessScenario() { final SOURCE = ''' final class MyPermission extends java.security.Permission { MyPermission(String name) { super(name) } boolean implies(Permission permission) { true } boolean equals(Object obj) { true } int hashCode() { 0 } String getActions() { "action" } } final class MyBasicPermission extends java.security.Permission { MyBasicPermission(String name) { super(name) } boolean implies(Permission permission) { true } boolean equals(Object obj) { true } int hashCode() { 0 } String getActions() { "action" } } final class MyPrivilegedAction implements PrivilegedAction { Object run() { 0 } } final class MyPrivilegedActionException extends PrivilegedActionException { MyPrivilegedActionException(Exception exception) { super(exception) } } ''' assertNoViolations(SOURCE) } @Test void testPermissionFullyQualified() { final SOURCE = ''' class MyPermission extends java.security.Permission { MyPermission(String name) { super(name) } boolean implies(Permission permission) { true } boolean equals(Object obj) { true } int hashCode() { 0 } String getActions() { "action" } } ''' assertSingleViolation(SOURCE, 2, 'class MyPermission extends java.security.Permission', 'The class MyPermission extends java.security.Permission but is not final') } @Test void testBasicPermissionFullyQualified() { final SOURCE = ''' class MyBasicPermission extends java.security.BasicPermission { MyBasicPermission(String name) { super(name) } } ''' assertSingleViolation(SOURCE, 2, 'class MyBasicPermission extends java.security.BasicPermission {', 'The class MyBasicPermission extends java.security.BasicPermission but is not final') } @Test void testPrivilegedActionFullyQualified() { final SOURCE = ''' class MyPrivilegedAction implements java.security.PrivilegedAction { Object run() { 0 } } ''' assertSingleViolation(SOURCE, 2, 'class MyPrivilegedAction implements java.security.PrivilegedAction', 'The class MyPrivilegedAction implements java.security.PrivilegedAction but is not final') } @Test void testPrivilegedActionExceptionFullyQualified() { final SOURCE = ''' class MyPrivilegedActionException extends java.security.PrivilegedActionException { MyPrivilegedActionException(Exception exception) { super(exception) } } ''' assertSingleViolation(SOURCE, 2, 'class MyPrivilegedActionException extends java.security.PrivilegedActionException', ' class MyPrivilegedActionException extends java.security.PrivilegedActionException but is not final') } @Test void testPermission() { final SOURCE = ''' import java.security.Permission class MyPermission extends Permission { MyPermission(String name) { super(name) } boolean implies(Permission permission) { true } boolean equals(Object obj) { true } int hashCode() { 0 } String getActions() { "action" } } ''' assertSingleViolation(SOURCE, 3, 'class MyPermission extends Permission', 'The class MyPermission extends java.security.Permission but is not final') } @Test void testBasicPermission() { final SOURCE = ''' import java.security.BasicPermission class MyBasicPermission extends BasicPermission { MyBasicPermission(String name) { super(name) } } ''' assertSingleViolation(SOURCE, 3, 'class MyBasicPermission extends BasicPermission', 'The class MyBasicPermission extends java.security.BasicPermission but is not final') } @Test void testPrivilegedAction() { final SOURCE = ''' import java.security.PrivilegedAction class MyPrivilegedAction implements PrivilegedAction { Object run() { 0 } } ''' assertSingleViolation(SOURCE, 3, 'class MyPrivilegedAction implements PrivilegedAction', 'The class MyPrivilegedAction implements java.security.PrivilegedAction but is not final') } @Test void testPrivilegedActionException() { final SOURCE = ''' import java.security.PrivilegedActionException class MyPrivilegedActionException extends PrivilegedActionException { MyPrivilegedActionException(Exception exception) { super(exception) } } ''' assertSingleViolation(SOURCE, 3, 'class MyPrivilegedActionException extends PrivilegedActionException', 'The class MyPrivilegedActionException extends java.security.PrivilegedActionException but is not final') } protected Rule createRule() { new NonFinalSubclassOfSensitiveInterfaceRule() } } ������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/SystemExitRuleTest.groovy������������������0000644�0001750�0001750�00000005630�12041642704�030003� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SystemExitRule * * @author Hamlet D'Arcy */ class SystemExitRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SystemExit' } @Test void testApplyTo_Violation_Initializers() { final SOURCE = ''' class MyClass { static { System.exit(1) } { System.exit(0) } } ''' assertTwoViolations(SOURCE, 4, 'System.exit(1)', 'Calling System.exit() is insecure and can expose a denial of service attack', 7, 'System.exit(0)', 'Calling System.exit() is insecure and can expose a denial of service attack') } @Test void testApplyTo_Violation_Methods() { final SOURCE = ''' class MyClass { static def method1() { System.exit(0) } def method2() { System.exit(0) } } ''' assertTwoViolations(SOURCE, 4, 'System.exit(0)', 'Calling System.exit() is insecure and can expose a denial of service attack', 7, 'System.exit(0)', 'Calling System.exit() is insecure and can expose a denial of service attack') } @Test void testApplyTo_Violation_Closures() { final SOURCE = ''' System.exit(0) def method = { System.exit(0) } ''' assertTwoViolations(SOURCE, 2, 'System.exit(0)', 4, 'System.exit(0)') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { System2.exit(1) System.exit2(1) System.exit() System.exit(1, 1) } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new SystemExitRule() } } ��������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/InsecureRandomRuleTest.groovy��������������0000644�0001750�0001750�00000004075�12041642702�030603� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for InsecureRandomRule * * @author Hamlet D'Arcy */ class InsecureRandomRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'InsecureRandom' } @Test void testSuccessScenario() { final SOURCE = ''' new java.security.SecureRandom() new SecureRandom() ''' assertNoViolations(SOURCE) } @Test void testMathRandom() { final SOURCE = ''' Math.random() java.lang.Math.random() ''' assertTwoViolations(SOURCE, 2, 'Math.random()', 'Using Math.random() is insecure. Use SecureRandom instead', 3, 'java.lang.Math.random()', 'Using Math.random() is insecure. Use SecureRandom instead') } @Test void testRandom() { final SOURCE = ''' def r1 = new Random() def r2 = new java.util.Random() ''' assertTwoViolations(SOURCE, 2, 'new Random()', 'Using Random is insecure. Use SecureRandom instead', 3, 'new java.util.Random()', 'Using Random is insecure. Use SecureRandom instead') } protected Rule createRule() { new InsecureRandomRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/PublicFinalizeMethodRuleTest.groovy��������0000644�0001750�0001750�00000004136�12041642704�031726� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for PublicFinalizeMethodRule * * @author Hamlet D'Arcy */ class PublicFinalizeMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'PublicFinalizeMethod' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass1 { protected finalize() {} public finalize(String arg) { // overloading finalize is a bad practice, but OK for this rule } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass { public finalize() {} } ''' assertSingleViolation(SOURCE, 3, 'public finalize()', 'The finalize() method should only be declared with protected visibility') } @Test void testPrivateDeclaration() { final SOURCE = ''' class MyClass { private finalize() {} } ''' assertSingleViolation(SOURCE, 3, 'private finalize()', 'The finalize() method should only be declared with protected visibility') } protected Rule createRule() { new PublicFinalizeMethodRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/UnsafeArrayDeclarationRuleTest.groovy������0000644�0001750�0001750�00000004365�12041642704�032257� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnsafeArrayDeclarationRule * * @author Hamlet D'Arcy */ class UnsafeArrayDeclarationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnsafeArrayDeclaration' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { public static final String myArray = init() public static final def myArray = [] static final String[] myArray = init() public static String[] myArray = init() } ''' assertNoViolations(SOURCE) } @Test void testArrayDeclaration() { final SOURCE = ''' class MyClass { public static final String[] myArray = init() } ''' assertSingleViolation(SOURCE, 3, 'public static final String[] myArray = init()', 'The Array field myArray is public, static, and final but still mutable') } @Test void testArrayInitialization() { final SOURCE = ''' class MyClass { public static final def myArray2 = [] as String[] } ''' assertSingleViolation(SOURCE, 3, 'public static final def myArray2 = [] as String[]', 'The Array field myArray2 is public, static, and final but still mutable') } protected Rule createRule() { new UnsafeArrayDeclarationRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/FileCreateTempFileRuleTest.groovy����������0000644�0001750�0001750�00000006415�12041642702�031316� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for FileCreateTempFileRule * * @author Hamlet D'Arcy */ class FileCreateTempFileRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'FileCreateTempFile' } @Test void testApplyTo_Violation_Initializers() { final SOURCE = ''' class MyClass { static { File.createTempFile(null, null) } { File.createTempFile(null, null, null) } } ''' assertTwoViolations(SOURCE, 4, 'File.createTempFile(null, null)', 'The method File.createTempFile is insecure. Use a secure API such as that provided by ESAPI', 7, 'File.createTempFile(null, null, null)', 'The method File.createTempFile is insecure. Use a secure API such as that provided by ESAPI') } @Test void testApplyTo_Violation_Methods() { final SOURCE = ''' class MyClass { static def method1() { File.createTempFile(null, null) } def method2() { File.createTempFile(null, null, null) } } ''' assertTwoViolations(SOURCE, 4, 'File.createTempFile(null, null)', 'The method File.createTempFile is insecure. Use a secure API such as that provided by ESAPI', 7, 'File.createTempFile(null, null, null)', 'The method File.createTempFile is insecure. Use a secure API such as that provided by ESAPI') } @Test void testApplyTo_Violation_Closures() { final SOURCE = ''' File.createTempFile('a', 'b') def method = { File.createTempFile('a', 'b') } ''' assertTwoViolations(SOURCE, 2, "File.createTempFile('a', 'b')", 4, "File.createTempFile('a', 'b')") } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { file.createTempFile('', '') File.createTempFile2('', '', '') File.createTempFile('') File.createTempFile('', '', '', '') } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new FileCreateTempFileRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/security/ObjectFinalizeRuleTest.groovy��������������0000644�0001750�0001750�00000005726�12041642704�030563� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.security import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ObjectFinalizeRule * * @author Hamlet D'Arcy */ class ObjectFinalizeRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ObjectFinalize' } @Test void testApplyTo_Violation_Initializers() { final SOURCE = ''' class MyClass { static { this.finalize() } { widget.finalize() } } ''' assertTwoViolations(SOURCE, 4, 'this.finalize()', 'The finalize() method should only be called by the JVM after the object has been garbage collected', 7, 'widget.finalize()', 'The finalize() method should only be called by the JVM after the object has been garbage collected') } @Test void testApplyTo_Violation_Methods() { final SOURCE = ''' class MyClass { static def method1() { foo.finalize() } def method2() { property.finalize() } } ''' assertTwoViolations(SOURCE, 4, 'foo.finalize()', 'The finalize() method should only be called by the JVM after the object has been garbage collected', 7, 'property.finalize()', 'The finalize() method should only be called by the JVM after the object has been garbage collected') } @Test void testApplyTo_Violation_Closures() { final SOURCE = ''' File.finalize() def method = { file.finalize() } ''' assertTwoViolations(SOURCE, 2, 'File.finalize()', 4, 'file.finalize()') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { widget.Finalize() widget.finalize('') } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ObjectFinalizeRule() } } ������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/AbstractClassReferenceRuleTestCase.groovy�����������0000644�0001750�0001750�00000016541�12461173167�031175� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule import org.junit.Test /** * Abstract superclass for tests of classes that check for class references. * * @author Chris Mair */ abstract class AbstractClassReferenceRuleTestCase extends AbstractRuleTestCase { /** * @return the name of the class to check for */ protected abstract String getClassName() // Subclasses can override (or define property) to customize violation message protected String getViolationMessage() { "Found reference to ${getClassName()}" } /** * @return an initialized rule instance */ protected abstract Rule createRule() //------------------------------------------------------------------------------------ // Common Tests //------------------------------------------------------------------------------------ @Test void testImport_Violation() { final SOURCE = """ import ${getClassName()} class MyClass { } """ assertSingleViolation(SOURCE, 2, "import ${getClassName()}", violationMessage) } @Test void testStaticImport_Violation() { final SOURCE = """ import static ${getClassName()}.* class MyClass { } """ assertSingleViolation(SOURCE, 2, "import static ${getClassName()}.*", violationMessage) } @Test void testFieldType_Violation() { final SOURCE = """ class MyClass { ${getClassName()} connection } """ assertSingleViolation(SOURCE, 3, "${getClassName()} connection", violationMessage) } @Test void testWithinExpressions_Violations() { final SOURCE = """ if (value.class == ${getClassName()}) { } def isCorrectType = value instanceof ${getClassName()} def txLevel = ${getClassName()}.TRANSACTION_NONE class MyClass { def field = new ${getClassName()}() } """ assertViolations(SOURCE, [lineNumber:2, sourceLineText:"if (value.class == ${getClassName()}) { }", messageText:violationMessage], [lineNumber:3, sourceLineText:"def isCorrectType = value instanceof ${getClassName()}", messageText:violationMessage], [lineNumber:4, sourceLineText:"def txLevel = ${getClassName()}.TRANSACTION_NONE", messageText:violationMessage], [lineNumber:7, sourceLineText:"def field = new ${getClassName()}()", messageText:violationMessage] ) } @Test void testConstructorCall_Violation() { final SOURCE = """ def c = new ${getClassName()}() """ assertSingleViolation(SOURCE, 2, "def c = new ${getClassName()}()", violationMessage) } @Test void testConstructorCall_CallToSuper_NoViolation() { final SOURCE = """ class MyClass extends Object { MyClass() { super('and') } } """ assertNoViolations(SOURCE) } @Test void testVariableType_Violation() { final SOURCE = """ ${getClassName()} c = getConnection() """ assertSingleViolation(SOURCE, 2, "${getClassName()} c = getConnection()", violationMessage) } @Test void testMethodReturnType_Violation() { final SOURCE = """ class MyClass { ${getClassName()} getConnection() { } } """ assertSingleViolation(SOURCE, 3, "${getClassName()} getConnection() { }", violationMessage) } @Test void testMethodParameterType_Violations() { final SOURCE = """ void writeCount(${getClassName()} connection, int count) { } void initializeBinding(String name, ${getClassName()} connection) { } """ assertViolations(SOURCE, [lineNumber:2, sourceLineText:"void writeCount(${getClassName()} connection, int count) { }", messageText:violationMessage], [lineNumber:3, sourceLineText:"void initializeBinding(String name, ${getClassName()} connection) { }", messageText:violationMessage]) } @Test void testConstructorCall_Parameter_Violation() { final SOURCE = """ def handler = new Handler(${getClassName()}) """ assertSingleViolation(SOURCE, 2, "def handler = new Handler(${getClassName()})", violationMessage) } @Test void testConstructorParameterType_Violation() { final SOURCE = """ class MyClass { MyClass(${getClassName()} connection) { } } """ assertSingleViolation(SOURCE, 3, "MyClass(${getClassName()} connection) { }", violationMessage) } @Test void testClosureParameterType_Violations() { final SOURCE = """ def writeCount = { ${getClassName()} connection, int count -> } def initializeBinding = { String name, ${getClassName()} connection -> } """ assertViolations(SOURCE, [lineNumber:2, sourceLineText:"def writeCount = { ${getClassName()} connection, int count -> }", messageText:violationMessage], [lineNumber:3, sourceLineText:"def initializeBinding = { String name, ${getClassName()} connection -> }", messageText:violationMessage]) } @Test void testAsType_Violation() { final SOURCE = """ def x = value as ${getClassName()} """ assertSingleViolation(SOURCE, 2, "def x = value as ${getClassName()}", violationMessage) } @Test void testExtendsSuperclassOrSuperInterfaceTypes_Violations() { final SOURCE = """ class MyConnection extends ${getClassName()} { } interface MyInterface extends ${getClassName()} { } """ assertViolations(SOURCE, [lineNumber:2, sourceLineText:"class MyConnection extends ${getClassName()} { }", messageText:violationMessage], [lineNumber:3, sourceLineText:"interface MyInterface extends ${getClassName()} { }", messageText:violationMessage]) } @Test void testAnonymousInnerClass_Violation() { final SOURCE = """ def x = new ${getClassName()}() { } """ assertSingleViolation(SOURCE, 2, "def x = new ${getClassName()}() { }", violationMessage) } @Test void testOtherConnectionClasses_NoViolations() { final SOURCE = ''' import org.example.dating.Connection class MyClass { def c = new org.codenarc.Connection() Connection createConnection() { } } ''' assertNoViolations(SOURCE) } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/braces/���������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022312� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/braces/IfStatementBracesRuleTest.groovy�������������0000644�0001750�0001750�00000004226�12041642700�030614� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.braces import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for IfStatementBracesRule * * @author Chris Mair */ class IfStatementBracesRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'IfStatementBraces' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { if (x==23) println '23' println 'ok' if (alreadyInitialized()) println 'initialized' } } ''' assertTwoViolations(SOURCE, 4, 'if (x==23)', 6, 'if (alreadyInitialized())') } @Test void testApplyTo_Violation_IfStatementWithCommentOnly() { final SOURCE = ''' if (isReady) { // TODO Should do something here } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { if (isReady) { println "ready" } if (x==23) { println '23' } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new IfStatementBracesRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/braces/ForStatementBracesRuleTest.groovy������������0000644�0001750�0001750�00000004342�12041642700�031003� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.braces import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ForStatementBracesRule * * @author Chris Mair */ class ForStatementBracesRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ForStatementBraces' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { for (int i=0; i < 10; i++) println '23' println 'ok' for (int j=0; j < 10; j++) println 'loop' } } ''' assertTwoViolations(SOURCE, 4, 'for (int i=0; i < 10; i++)', 6, 'for (int j=0; j < 10; j++)') } @Test void testApplyTo_Violation_ForStatementWithCommentOnly() { final SOURCE = ''' for (int i=0; i < 10; i++) { // TODO Should do something here } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { for (int j=0; j < 10; j++) { println "ready" } for (int j=0; j < 10; j++) { println '23' } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ForStatementBracesRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/braces/ElseBlockBracesRuleTest.groovy���������������0000644�0001750�0001750�00000006302�12041642700�030231� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.braces import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ElseBlockBracesRule * * @author Chris Mair */ class ElseBlockBracesRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ElseBlockBraces' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { if (x==23) { } else println '23' println 'ok' if (alreadyInitialized()) println 'initialized' else println 'not initialized' } } ''' assertTwoViolations(SOURCE, 4, "else println '23'", 6, 'if (alreadyInitialized())') } @Test void testApplyTo_IfWithoutElse() { final SOURCE = ''' if (isReady) { println 'ready' } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ElseIf() { final SOURCE = ''' if (isReady) { println 'ready' } else if (able) { println 'able' } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_BracesRequiredForElseIf() { final SOURCE = ''' if (isReady) { println 'ready' } else if (able) { println 'able' } ''' rule.bracesRequiredForElseIf = true assertSingleViolation(SOURCE, 2, 'if (isReady)') } @Test void testApplyTo_Violation_ElseBlockWithCommentOnly() { final SOURCE = ''' if (isReady) { // TODO Should do something here } else { // TODO And should do something here } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { if (isReady) { println "ready" } else { println 'not ready' } if (x==23) { println '23' } else { println 'ok' } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ElseBlockBracesRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/braces/WhileStatementBracesRuleTest.groovy����������0000644�0001750�0001750�00000004267�12041642700�031333� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.braces import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for WhileStatementBracesRule * * @author Chris Mair */ class WhileStatementBracesRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'WhileStatementBraces' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { while (x==23) println '23' println 'ok' while (alreadyInitialized()) println 'initialized' } } ''' assertTwoViolations(SOURCE, 4, 'while (x==23)', 6, 'while (alreadyInitialized())') } @Test void testApplyTo_Violation_IfStatementWithCommentOnly() { final SOURCE = ''' while (isReady) { // TODO Should do something here } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { while (isReady) { println "ready" } while (x==23) { println '23' } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new WhileStatementBracesRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/�����������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021755� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/DirectConnectionManagementRuleTest.groovy������0000644�0001750�0001750�00000003646�12041642702�032152� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DirectConnectionManagementRule * * @author Hamlet D'Arcy */ class DirectConnectionManagementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DirectConnectionManagement' } @Test void testSuccessScenario() { final SOURCE = ''' OtherManager.getConnection() java.something.DriverManager.getConnection() ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' DriverManager.getConnection() java.sql.DriverManager.getConnection() ''' assertTwoViolations(SOURCE, 2, 'DriverManager.getConnection()', 'Using DriverManager.getConnection() violates the J2EE standards. Use the connection from the context instead', 3, 'java.sql.DriverManager.getConnection()', 'Using DriverManager.getConnection() violates the J2EE standards. Use the connection from the context instead') } protected Rule createRule() { new DirectConnectionManagementRule() } } ������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/JdbcStatementReferenceRule_StatementTest.groovy0000644�0001750�0001750�00000003034�12041642702�033304� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JdbcStatementReferenceRule - checks for references to java.sql.Statement * * @author Chris Mair */ class JdbcStatementReferenceRule_StatementTest extends AbstractClassReferenceRuleTestCase { final String className = 'java.sql.Statement' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JdbcStatementReference' } @Test void testOtherClassesInTheSamePackage_NoViolations() { final SOURCE = ''' import java.sql.Other class MyClass { def c = new java.sql.Example() } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new JdbcStatementReferenceRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/JdbcConnectionReferenceRuleTest.groovy���������0000644�0001750�0001750�00000002320�12041642702�031410� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JdbcConnectionReferenceRule * * @author Chris Mair */ class JdbcConnectionReferenceRuleTest extends AbstractClassReferenceRuleTestCase { final String className = 'java.sql.Connection' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JdbcConnectionReference' } protected Rule createRule() { new JdbcConnectionReferenceRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000155�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/JdbcStatementReferenceRule_PreparedStatementTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/JdbcStatementReferenceRule_PreparedStatementTes0000644�0001750�0001750�00000002166�12041642702�033264� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule /** * Tests for JdbcStatementReferenceRule - checks for references to java.sql.PreparedStatement * * @author Chris Mair */ class JdbcStatementReferenceRule_PreparedStatementTest extends AbstractClassReferenceRuleTestCase { final String className = 'java.sql.PreparedStatement' protected Rule createRule() { new JdbcStatementReferenceRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/JdbcResultSetReferenceRuleTest.groovy����������0000644�0001750�0001750�00000002313�12041642702�031245� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for JdbcResultSetReferenceRule * * @author Chris Mair */ class JdbcResultSetReferenceRuleTest extends AbstractClassReferenceRuleTestCase { final String className = 'java.sql.ResultSet' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'JdbcResultSetReference' } protected Rule createRule() { new JdbcResultSetReferenceRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000155�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/JdbcStatementReferenceRule_CallableStatementTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/jdbc/JdbcStatementReferenceRule_CallableStatementTes0000644�0001750�0001750�00000002166�12041642702�033221� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.jdbc import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule /** * Tests for JdbcStatementReferenceRule - checks for references to java.sql.CallableStatement * * @author Chris Mair */ class JdbcStatementReferenceRule_CallableStatementTest extends AbstractClassReferenceRuleTestCase { final String className = 'java.sql.CallableStatement' protected Rule createRule() { new JdbcStatementReferenceRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/��������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022501� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/PrintStackTraceRuleTest.groovy��������������0000644�0001750�0001750�00000006103�12311373552�030503� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for PrintStackTraceRule * * @author Chris Mair */ class PrintStackTraceRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'PrintStackTrace' } @Test void testApplyTo_PrintStackTrace() { final SOURCE = ''' try { } catch(MyException e) { e.printStackTrace() } ''' assertSingleViolation(SOURCE, 4, 'e.printStackTrace()') } @Test void testApplyTo_PrintStackTrace_WithinClosure() { final SOURCE = ''' class MyClass { def myClosure = { try { } catch(MyException e) { e.printStackTrace() } } } ''' assertSingleViolation(SOURCE, 6, 'e.printStackTrace()') } @Test void testApplyTo_PrintStackTrace_WithParameter_NoViolation() { final SOURCE = ''' try { } catch(MyException e) { e.printStackTrace(System.err) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrintSanitizedStackTrace() { final SOURCE = ''' try { } catch(MyException e) { StackTracUtils.printSanitizedStackTrace(e) } ''' assertSingleViolation(SOURCE, 4, 'StackTracUtils.printSanitizedStackTrace(e)') } @Test void testApplyTo_PrintSanitizedStackTrace_WithPrintWriter_NoViolation() { final SOURCE = ''' try { } catch(MyException e) { StackTracUtils.printSanitizedStackTrace(e, myPrintWriter) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolation() { final SOURCE = ''' @Test void testSomething() { println "123" } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_GStringMethodName() { final SOURCE = ' "$myMethodName"(1234) ' assertNoViolations(SOURCE) } protected Rule createRule() { new PrintStackTraceRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/LoggerForDifferentClassRuleTest.groovy������0000644�0001750�0001750�00000027461�12041642702�032153� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.logging import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for LoggerForDifferentClassRule * * @author Chris Mair */ class LoggerForDifferentClassRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'LoggerForDifferentClass' } @Test void testApplyTo_NoLoggers_NoViolations() { final SOURCE = ''' class MyClass { private static final int count = 67 } ''' assertNoViolations(SOURCE) } // Logger (Log4J and Java Logging API) Tests @Test void testApplyTo_Logger_Violations() { final SOURCE = ''' class MyClass { private static final LOG = Logger.getLogger(SomeOtherClass) def log1 = Logger.getLogger(SomeOtherClass.class) def log2 = Logger.getLogger(SomeOtherClass.class.name) } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'private static final LOG = Logger.getLogger(SomeOtherClass)'], [lineNumber:4, sourceLineText:'def log1 = Logger.getLogger(SomeOtherClass.class)'], [lineNumber:5, sourceLineText:'def log2 = Logger.getLogger(SomeOtherClass.class.name)']) } @Test void testApplyTo_Logger_SameClass_NoViolations() { final SOURCE = ''' class MyClass { private static final LOG = Logger.getLogger(MyClass) def log2 = Logger.getLogger(MyClass.class) private static log3 = Logger.getLogger(MyClass.getClass().getName()) private static log4 = Logger.getLogger(MyClass.getClass().name) private static log5 = Logger.getLogger(MyClass.class.getName()) private static log6 = Logger.getLogger(MyClass.class.name) private static log7 = Logger.getLogger(MyClass.name) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Logger_SameClass_NoViolations_DerivedAllowed() { rule.allowDerivedClasses = true final SOURCE = ''' class MyClass { private final LOG1 = Logger.getLogger(this.class) private final LOG2 = Logger.getLogger(this.getClass()) private final LOG3 = Logger.getLogger(getClass()) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Logger_SameClass_Violations_DerivedAllowed() { rule.allowDerivedClasses = true final SOURCE = ''' class MyClass { private final LOG1 = Logger.getLogger(unknown) } ''' assertSingleViolation(SOURCE, 3, 'private final LOG1 = Logger.getLogger(unknown)', 'Logger is defined in MyClass but initialized with unknown') } @Test void testApplyTo_Logger_This_NoViolations() { final SOURCE = ''' class MyClass { private static final LOG = Logger.getLogger(this) def log2 = Logger.getLogger(this.class) private static log3 = Logger.getLogger(this.getName()) private static log4 = Logger.getLogger(this.name) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Logger_NotAClassOrClassName_NoViolations() { final SOURCE = ''' class MyClass { private static log1 = Logger.getLogger(getLogName()) private static log2 = Logger.getLogger("some.OtherName") } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Logger_ConstantForLoggerName_Violation() { final SOURCE = ''' class MyClass { private static final log = Logger.getLogger(CONSTANT) } ''' assertSingleViolation(SOURCE, 3, 'private static final log = Logger.getLogger(CONSTANT)', 'Logger is defined in MyClass but initialized with CONSTANT') } @Test void testApplyTo_Logger_FullPackageNameOfLogger_NoViolations() { final SOURCE = ''' class MyClass { private static final log = org.apache.log4.Logger.getLogger(SomeOtherClass) } ''' assertNoViolations(SOURCE) } // LogFactory (Commons Logging) Tests @Test void testApplyTo_LogFactory_Violations() { final SOURCE = ''' class MyClass { private static final LOG = LogFactory.getLog(SomeOtherClass) Log log = LogFactory.getLog(SomeOtherClass.class) } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'private static final LOG = LogFactory.getLog(SomeOtherClass)'], [lineNumber:4, sourceLineText:'Log log = LogFactory.getLog(SomeOtherClass.class)']) } @Test void testApplyTo_LogFactory_SameClass_NoViolations() { final SOURCE = ''' class MyClass { private static final LOG = LogFactory.getLog(MyClass) def log2 = LogFactory.getLog(MyClass.class) private static log3 = LogFactory.getLog(MyClass.getClass().getName()) private static log4 = LogFactory.getLog(MyClass.getClass().name) private static log5 = LogFactory.getLog(MyClass.class.getName()) private static log6 = LogFactory.getLog(MyClass.class.name) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_LogFactory_This_NoViolations() { final SOURCE = ''' class MyClass { private static final LOG = LogFactory.getLog(this) def log2 = LogFactory.getLog(this.class) private static log3 = LogFactory.getLog(this.getName()) private static log4 = LogFactory.getLog(this.name) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_LogFactory_NotAClassOrClassName_NoViolations() { final SOURCE = ''' class MyClass { private static final log1 = LogFactory.getLog(getLogName()) private static final log2 = LogFactory.getLog("some.OtherName") } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_LogFactory_ConstantForLoggerName_Violation() { final SOURCE = ''' class MyClass { private static final log = LogFactory.getLog(CONSTANT) } ''' assertSingleViolation(SOURCE, 3, 'private static final log = LogFactory.getLog(CONSTANT)') } @Test void testApplyTo_LogFactory_ConstantForLoggerName_InnerClassViolation() { final SOURCE = ''' class MyClass { class MyOtherClass { } private static final log = LogFactory.getLog(MyOtherClass) } ''' assertSingleViolation(SOURCE, 5, 'private static final log = LogFactory.getLog(MyOtherClass)') } @Test void testApplyTo_LogFactory_FullPackageNameOfLogFactory_NoViolations() { final SOURCE = ''' class MyClass { private static final log = org.apache.commons.logging.LogFactory.getLog(SomeOtherClass) } ''' assertNoViolations(SOURCE) } // LoggerFactory (SLF4J and Logback) Tests @Test void testApplyTo_LoggerFactory_Violations() { final SOURCE = ''' class MyClass { private static final LOG = LoggerFactory.getLogger(SomeOtherClass) Log log = LoggerFactory.getLogger(SomeOtherClass.class) } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'private static final LOG = LoggerFactory.getLogger(SomeOtherClass)'], [lineNumber:4, sourceLineText:'Log log = LoggerFactory.getLogger(SomeOtherClass.class)']) } @Test void testApplyTo_LoggerFactory_SameClass_NoViolations() { final SOURCE = ''' class MyClass { private static final LOG = LoggerFactory.getLogger(MyClass) def log2 = LoggerFactory.getLogger(MyClass.class) private static log3 = LoggerFactory.getLogger(MyClass.getClass().getName()) private static log4 = LoggerFactory.getLogger(MyClass.getClass().name) private static log5 = LoggerFactory.getLogger(MyClass.class.getName()) private static log6 = LoggerFactory.getLogger(MyClass.class.name) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_LoggerFactory_This_NoViolations() { final SOURCE = ''' class MyClass { private static final LOG = LoggerFactory.getLogger(this) def log2 = LoggerFactory.getLogger(this.class) private static log3 = LoggerFactory.getLogger(this.getName()) private static log4 = LoggerFactory.getLogger(this.name) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_LoggerFactory_NotAClassOrClassName_NoViolations() { final SOURCE = ''' class MyClass { private static final log1 = LoggerFactory.getLogger(getLogName()) private static final log2 = LoggerFactory.getLogger("some.OtherName") } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_LoggerFactory_ConstantForLoggerName_Violation() { final SOURCE = ''' class MyClass { private static final log = LoggerFactory.getLogger(CONSTANT) } ''' assertSingleViolation(SOURCE, 3, 'private static final log = LoggerFactory.getLogger(CONSTANT)') } @Test void testApplyTo_LoggerFactory_FullPackageNameOfLoggerFactory_NoViolations() { final SOURCE = ''' class MyClass { private static final log = org.apache.commons.logging.LoggerFactory.getLogger(SomeOtherClass) } ''' assertNoViolations(SOURCE) } @Test void testInnerClasses() { final SOURCE = ''' class Outer { private class InnerRunnable implements Runnable { final Logger LOGGER = LoggerFactory.getLogger(InnerRunnable.class) } } ''' assertNoViolations(SOURCE) } @Test void testInnerClassViolation() { final SOURCE = ''' class Outer { private class InnerRunnable implements Runnable { final Logger LOGGER = LoggerFactory.getLogger(Outer) } } ''' assertSingleViolation(SOURCE, 4, 'LoggerFactory.getLogger(Outer)', 'Logger is defined in InnerRunnable but initialized with Outer') } protected Rule createRule() { new LoggerForDifferentClassRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/LoggerWithWrongModifiersRuleTest.groovy�����0000644�0001750�0001750�00000012440�12311370173�032371� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.logging import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for LoggerWithWrongModifiersRule * * @author Hamlet D'Arcy */ class LoggerWithWrongModifiersRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'LoggerWithWrongModifiers' } /* * static logger */ @Test void testSuccessScenario_staticLogger() { final SOURCE = ''' class MyClass { private static final LOG = Logger.getLogger(MyClass) } ''' assertNoViolations(SOURCE) } @Test void testNotPrivate_staticLogger() { final SOURCE = ''' class MyClass { public static final LOG = Logger.getLogger(MyClass) } ''' assertSingleViolation(SOURCE, 3, 'public static final LOG = Logger.getLogger(MyClass)', 'The Logger field LOG should be private, static and final') } @Test void testNotStatic_staticLogger() { final SOURCE = ''' class MyClass { private final LOG = Logger.getLogger(MyClass) } ''' assertSingleViolation(SOURCE, 3, 'private final LOG = Logger.getLogger(MyClass)', 'The Logger field LOG should be private, static and final') } @Test void testNotFinal_staticLogger() { final SOURCE = ''' class MyClass { private static LOG = Logger.getLogger(MyClass) } ''' assertSingleViolation(SOURCE, 3, 'private static LOG = Logger.getLogger(MyClass)', 'The Logger field LOG should be private, static and final') } @Test void testSuccessScenario_derivedLogger() { rule.allowProtectedLogger = true rule.allowNonStaticLogger = true final SOURCE = ''' class MyClass1 { protected final LOG = Logger.getLogger(this.class) } class MyClass2 { protected final LOG = Logger.getLogger(this.getClass()) } class MyClass3 { protected final LOG = Logger.getLogger(getClass()) } ''' assertNoViolations(SOURCE) } @Test void testPublic_derivedLogger() { rule.allowProtectedLogger = true rule.allowNonStaticLogger = true final SOURCE = ''' class MyClass { public final LOG = Logger.getLogger(this.class) } ''' assertSingleViolation(SOURCE, 3, 'public final LOG = Logger.getLogger(this.class)', 'The Logger field LOG should be private (or protected) and final') } @Test void testPublic() { rule.allowProtectedLogger = true final SOURCE = ''' class MyClass { public static final LOG = Logger.getLogger(this.class) } ''' assertSingleViolation(SOURCE, 3, 'public static final LOG = Logger.getLogger(this.class)', 'The Logger field LOG should be private (or protected), static and final') } @Test void testPrivate_derivedLogger() { rule.allowProtectedLogger = true rule.allowNonStaticLogger = true final SOURCE = ''' class MyClass { private final LOG = Logger.getLogger(this.class) protected static final LOG2 = Logger.getLogger(this.class) } ''' assertNoViolations(SOURCE) } @Test void testStatic_derivedLogger() { rule.allowProtectedLogger = true rule.allowNonStaticLogger = true final SOURCE = ''' class MyClass { protected static final LOG = Logger.getLogger(this.class) } ''' assertNoViolations(SOURCE) } @Test void testNotFinal_derivedLogger() { rule.allowProtectedLogger = true final SOURCE = ''' class MyClass { protected LOG = Logger.getLogger(this.class) } ''' assertSingleViolation(SOURCE, 3, 'protected LOG = Logger.getLogger(this.class)', 'The Logger field LOG should be private (or protected), static and final') } protected Rule createRule() { new LoggerWithWrongModifiersRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/LoggingSwallowsStacktraceRuleTest.groovy����0000644�0001750�0001750�00000006062�12041642702�032571� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.logging import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for LoggingSwallowsStacktraceRule * * @author 'Hamlet D'Arcy' */ class LoggingSwallowsStacktraceRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'LoggingSwallowsStacktrace' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { private static final Log LOG = LogFactory.getLog( Main.class ) def method() { try { LOG.error(foo) } catch (Exception e) { if (true) { LOG.error('error') // ok... surrounded by if } LOG.error(e.getMessage(), e) // ok, logs exception } } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass { private static final Log LOG = LogFactory.getLog( Main.class ) private static final Log logger = LogFactory.getLog( Main.class ) def method() { try { LOG.error(foo) } catch (Exception e) { if (true) { LOG.error('error') // ok... surrounded by if } LOG.error(e) // violation logger.error(e) // violation foo(e) } } } ''' assertTwoViolations(SOURCE, 13, 'LOG.error(e)', 'The error logging may hide the stacktrace from the exception named e', 14, 'logger.error(e)', 'The error logging may hide the stacktrace from the exception named e') } @Test void testReportedDefect() { final SOURCE = ''' class MyClass { private log = Logger.getLogger(Class) private logger = Logger.getLogger(MyClass) }''' assertNoViolations(SOURCE) } protected Rule createRule() { new LoggingSwallowsStacktraceRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/PrintlnRuleTest.groovy����������������������0000644�0001750�0001750�00000012351�12316055541�027072� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for PrintlnRule * * @author Chris Mair */ class PrintlnRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'Println' } @Test void testApplyTo_Println_NoArgs() { final SOURCE = ''' println() ''' assertSingleViolation(SOURCE, 2, 'println') } @Test void testApplyTo_Println_NoArgs_WithinClosure() { final SOURCE = ''' class MyClass { def myClosure = { if (hasResult) { println "$result" } } } ''' assertSingleViolation(SOURCE, 5, 'println') } @Test void testApplyTo_Println_OneArg() { final SOURCE = ''' println "message" ''' assertSingleViolation(SOURCE, 2, 'println "message"') } @Test void testApplyTo_Println_ExplicitThis() { final SOURCE = ''' this.println "message" ''' assertSingleViolation(SOURCE, 2, 'this.println "message"') } @Test void testApplyTo_Print_OneArg() { final SOURCE = ''' print("message") ''' assertSingleViolation(SOURCE, 2, 'print("message")') } @Test void testApplyTo_Printf_TwoArgs() { final SOURCE = ''' printf "%d", 99 ''' assertSingleViolation(SOURCE, 2, 'printf "%d", 99') } @Test void testApplyTo_Printf_ThreeArgs() { final SOURCE = ''' printf "%d, %d", 23, 34 ''' assertSingleViolation(SOURCE, 2, 'printf "%d, %d", 23, 34') } @Test void testApplyTo_Printf_FourArgs() { final SOURCE = ''' printf "%d, %d", 23, 34, 45 ''' assertSingleViolation(SOURCE, 2, 'printf "%d, %d", 23, 34, 45') } @Test void testApplyTo_Println_AnnotatedMethod() { final SOURCE = ''' import org.gcontracts.annotations.Requires class CodenarcViolationService { @Requires({arg}) def violate(arg) { println 'foo bar' } } ''' assertSingleViolation(SOURCE, 6, "println 'foo bar'") } @Test void testApplyTo_PrintlnButNotThis() { final SOURCE = ''' @Test void testSomething() { System.out.println "123" } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrintlnLocallyDefinedMethod() { final SOURCE = ''' class MyClass1 { def println(p) { } def method() { println('a') println('b') } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrintlnLocallyDefinedClosure() { final SOURCE = ''' class MyClass1 { def println = { } def method() { println('a') println('b') } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrintlnLocallyDefinedClosure2() { final SOURCE = ''' class MyClass1 { Closure println = makeClosure() def method() { println('a') println('b') } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrintLocallyDefinedClosure() { final SOURCE = ''' class MyClass1 { def print = { } def method() { print('a') print('b') } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrintLocallyDefinedClosure2() { final SOURCE = ''' class MyClass1 { Closure print = makeClosure() def method() { print('a') print('b') } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new PrintlnRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/SystemOutPrintRuleTest.groovy���������������0000644�0001750�0001750�00000005452�12041642702�030435� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SystemOutPrintRule * * @author Chris Mair */ class SystemOutPrintRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SystemOutPrint' } @Test void testApplyTo_SystemOutPrintln_NoArgs() { final SOURCE = ''' System.out.println() ''' assertSingleViolation(SOURCE, 2, 'System.out.println()') } @Test void testApplyTo_SystemOutPrintln_String() { final SOURCE = ''' System.out.println("yes") ''' assertSingleViolation(SOURCE, 2, 'System.out.println("yes")') } @Test void testApplyTo_SystemOutPrintln_Int() { final SOURCE = ''' System.out.println(1234) ''' assertSingleViolation(SOURCE, 2, 'System.out.println(1234)') } @Test void testApplyTo_SystemOutPrint_Int() { final SOURCE = ''' System.out.print(1234) ''' assertSingleViolation(SOURCE, 2, 'System.out.print(1234)') } @Test void testApplyTo_SystemOutPrintf() { final SOURCE = ''' System.out.printf("%d", 1234) System.out.printf("%d %d", 1234, -99) ''' assertTwoViolations(SOURCE, 2, 'System.out.printf("%d", 1234)', 3, 'System.out.printf("%d %d", 1234, -99)') } @Test void testApplyTo_SystemOutPrint_WithinClosure() { final SOURCE = ''' class MyClass { def myClosure = { System.out.print(1234) } } ''' assertSingleViolation(SOURCE, 4, 'System.out.print(1234)') } @Test void testApplyTo_PrintlnButNotSystemOut() { final SOURCE = ''' @Test void testSomething() { println "123" } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new SystemOutPrintRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/MultipleLoggersRuleTest.groovy��������������0000644�0001750�0001750�00000005044�12041642702�030557� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.logging import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for MultipleLoggersRule * * @author 'Hamlet D'Arcy' */ class MultipleLoggersRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'MultipleLoggers' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { private static final LOG = Logger.getLogger(MyClass) private static final LOG2 = '' // not a logger } class MyOtherClass { private static final LOG3 = Logger.getLogger(MyClass) class MyInnerClass { private static final LOG4 = Logger.getLogger(MyClass) } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass { def LOG = Logger.getLogger(MyClass) def logger = Logger.getLogger(MyClass) } ''' assertSingleViolation(SOURCE, 4, 'def logger = Logger.getLogger(MyClass)', 'Violation in class MyClass. The class defines multiple loggers: LOG, logger') } @Test void testInnerClass() { final SOURCE = ''' class MyClass { class MyInnerClass { def LOG = Logger.getLogger(MyClass) def logger = Logger.getLogger(MyClass) } } ''' assertSingleViolation(SOURCE, 5, 'def logger = Logger.getLogger(MyClass)', 'Violation in class MyClass$MyInnerClass. The class defines multiple loggers: LOG, logger') } protected Rule createRule() { new MultipleLoggersRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/logging/SystemErrPrintRuleTest.groovy���������������0000644�0001750�0001750�00000005433�12041642702�030415� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.logging import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SystemErrPrintRule * * @author Chris Mair */ class SystemErrPrintRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SystemErrPrint' } @Test void testApplyTo_SystemErrPrintln_NoArgs() { final SOURCE = ''' System.err.println() ''' assertSingleViolation(SOURCE, 2, 'System.err.println()') } @Test void testApplyTo_SystemErrPrintln_String() { final SOURCE = ''' System.err.println("yes") ''' assertSingleViolation(SOURCE, 2, 'System.err.println("yes")') } @Test void testApplyTo_SystemErrPrintln_Int() { final SOURCE = ''' System.err.println(1234) ''' assertSingleViolation(SOURCE, 2, 'System.err.println(1234)') } @Test void testApplyTo_SystemErrPrint_Int() { final SOURCE = ''' System.err.print(1234) ''' assertSingleViolation(SOURCE, 2, 'System.err.print(1234)') } @Test void testApplyTo_SystemErrPrintf() { final SOURCE = ''' System.err.printf("%d", 1234) System.err.printf("%d %d", 1234, -99) ''' assertTwoViolations(SOURCE, 2, 'System.err.printf("%d", 1234)', 3, 'System.err.printf("%d %d", 1234, -99)') } @Test void testApplyTo_WithinClosure() { final SOURCE = ''' class MyClass { def myClosure = { System.err.print(1234) } } ''' assertSingleViolation(SOURCE, 4, 'System.err.print(1234)') } @Test void testApplyTo_PrintlnButNotSystemErr() { final SOURCE = ''' @Test void testSomething() { println "123" } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new SystemErrPrintRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/�����������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022025� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/CrapMetricRuleTest.groovy����������������������0000644�0001750�0001750�00000021324�12054510440�027012� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.captureLog4JMessages /** * Tests for CrapMetricRule * * @author Chris Mair */ class CrapMetricRuleTest extends AbstractRuleTestCase { private static final String COBERTURA_FILE = 'coverage/Cobertura-example.xml' private static final BigDecimal CRAP_SCORE = 6.0 private static final String CLASS_NAME = 'com.example.service.Email' private static final String METHOD_NAME = 'toString' private static final String METRIC_DESCRIPTION = 'CRAP score' private static final SOURCE = ''' package com.example.service class Email { String toString() { // complexity=4, coverage=0.5 if (ready || paused || started) return null } } ''' //------------------------------------------------------------------------------------ // Tests //------------------------------------------------------------------------------------ @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CrapMetric' assert rule.maxMethodCrapScore == 30.0 assert rule.maxClassAverageMethodCrapScore == 30.0 assert rule.maxClassCrapScore == 0 assert rule.crapMetricClassName == 'org.gmetrics.metric.crap.CrapMetric' } @Test void testCoberturaXmlFileNullOrEmpty_IsReadyReturnsFalse() { def logEvents = captureLog4JMessages { rule.coberturaXmlFile = null assert !rule.ready rule.coberturaXmlFile = '' assert !rule.ready } assertNumberOfLogMessages(logEvents, 'Cobertura XML file', 1) } @Test void testApplyTo_CoberturaXmlFileDoesNotExist_IsReadyReturnsFalse_OnlyLogsWarningOnce() { rule.coberturaXmlFile = 'DoesNotExist.xml' assert !rule.ready } @Test void testApplyTo_CoberturaXmlFileDoesNotExist_NoViolations_OnlyLogsWarningOnce() { rule.coberturaXmlFile = 'DoesNotExist.xml' def logEvents = captureLog4JMessages { assertNoViolations(SOURCE) assertNoViolations(SOURCE) } assertNumberOfLogMessages(logEvents, 'Cobertura XML file', 1) } @Test void testCrapMetricClassNotOnClassPath_IsReadyReturnsFalse() { rule.crapMetricClassName = 'some.NonExistentClass' assert !rule.ready } @Test void testCrapMetricClassNotOnClassPath_NoViolations() { rule.crapMetricClassName = 'some.NonExistentClass' rule.maxMethodCrapScore = 1.0 def logEvents = captureLog4JMessages { assertNoViolations(SOURCE) assertNoViolations(SOURCE) } assertNumberOfLogMessages(logEvents, 'GMetrics CrapMetric class', 1) } @Test void testApplyTo_ClassWithNoMethods() { final SOURCE = ''' class MyClass { def myValue = 23 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SingleMethod_EqualToMaxMethodCrapScore() { rule.maxMethodCrapScore = CRAP_SCORE assertNoViolations(SOURCE) } @Test void testApplyTo_SingleMethod_ExceedsMaxMethodCrapScore() { rule.maxMethodCrapScore = 5.0 assertSingleViolation(SOURCE, 4, 'String toString() {', [CLASS_NAME, METRIC_DESCRIPTION, METHOD_NAME, CRAP_SCORE]) } @Test void testSuppressWarningsOnClass() { final SOURCE = ''' package com.example.service @SuppressWarnings('CrapMetric') class Email { String toString() { if (ready || paused || started) return null } } ''' rule.maxMethodCrapScore = 1.0 assert manuallyApplyRule(SOURCE).size() == 0 } @Test void testSuppressWarningsOnMethod() { final SOURCE = ''' package com.example.service class Email { @SuppressWarnings('CrapMetric') String toString() { if (ready || paused || started) return null } } ''' rule.maxMethodCrapScore = 1.0 assert manuallyApplyRule(SOURCE).size() == 0 } @Test void testApplyTo_IgnoresClosureFields() { final SOURCE = ''' class MyClass { def myClosure = { a && b && c && d && e } } ''' rule.maxMethodCrapScore = 1.0 assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoresMethodThatHasNoCoverageInformation() { final SOURCE = ''' package com.example.service class Email { String unknown() { if (ready || paused || started) return null } } ''' rule.maxMethodCrapScore = 1.0 assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoresAbstractMethods() { final SOURCE = ''' package com.example.service abstract class Email { abstract String toString() } ''' rule.maxMethodCrapScore = 1.0 assertNoViolations(SOURCE) } @Test void testApplyTo_Class_ExceedsMaxAverageClassComplexity() { rule.maxClassAverageMethodCrapScore = 1.0 assertSingleViolation(SOURCE, 3, 'class Email', [CLASS_NAME, METRIC_DESCRIPTION, CRAP_SCORE]) } @Test void testApplyTo_Class_ExceedsMaxClassComplexity() { rule.maxClassCrapScore = 1.0 assertSingleViolation(SOURCE, 3, 'class Email', [CLASS_NAME, METRIC_DESCRIPTION, 'total', CRAP_SCORE]) } @Test void testApplyTo_Class_ZeroMaxClassAverageMethodCrapScore_NoViolations() { rule.maxClassAverageMethodCrapScore = 0.0 assertNoViolations(SOURCE) } @Test void testApplyTo_Class_NullMaxClassAverageMethodCrapScore_NoViolations() { rule.maxClassAverageMethodCrapScore = null assertNoViolations(SOURCE) } @Test void testApplyTo_ClassAndMethod_ExceedThreshold() { rule.maxMethodCrapScore = 1.0 rule.maxClassAverageMethodCrapScore = 1.0 rule.maxClassCrapScore = 5.9 assertViolations(SOURCE, [lineNumber:3, sourceLineText:'class Email', messageText:[CLASS_NAME, METRIC_DESCRIPTION, 'average', CRAP_SCORE]], [lineNumber:3, sourceLineText:'class Email', messageText:[CLASS_NAME, METRIC_DESCRIPTION, 'total', CRAP_SCORE]], [lineNumber:4, sourceLineText:'String toString() {', messageText:[CLASS_NAME, METRIC_DESCRIPTION, METHOD_NAME, CRAP_SCORE]]) } @Test void testApplyTo_ClassAndMethods_AtThreshold() { rule.maxMethodCrapScore = CRAP_SCORE rule.maxClassAverageMethodCrapScore = CRAP_SCORE assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesSingleName() { rule.maxMethodCrapScore = 1.0 rule.ignoreMethodNames = METHOD_NAME assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesNoNames() { rule.maxMethodCrapScore = 1.0 rule.ignoreMethodNames = 'other,x*' assertSingleViolation(SOURCE, 4, 'String toString() {', [CLASS_NAME, METRIC_DESCRIPTION, METHOD_NAME, CRAP_SCORE]) } @Test void testApplyTo_IgnoreMethodNames_MultipleNamesWithWildcards() { rule.ignoreMethodNames = 'myM*d*,t?Str*ng' assertNoViolations(SOURCE) } @Override protected Rule createRule() { new CrapMetricRule(coberturaXmlFile:COBERTURA_FILE) } private void assertNumberOfLogMessages(logEvents, String expectedText, int expectedCount) { def matchingLogEvents = logEvents.findAll { it.message.contains(expectedText) } assert matchingLogEvents.size() == expectedCount } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/MethodSizeRuleTest.groovy����������������������0000644�0001750�0001750�00000010472�12413644426�027051� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for MethodSizeRule * * @author Chris Mair */ class MethodSizeRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'MethodSize' } @Test void testApplyTo_LongerThanDefaultMaxLines() { final SOURCE = """ class MyClass { def myMethod() { ${'println 23\n' * 98} } } """ assertSingleViolation(SOURCE, 3, null, 'myMethod') } @Test void testApplyTo_SetMaxLines() { final SOURCE = """ /** class description */ class MyClass { def myMethod() { 'println 23' } } """ rule.maxLines = 2 assertSingleViolation(SOURCE, 4, null, 'myMethod') } @Test void testApplyTo_ConstructorExceedsMaxLines() { final SOURCE = """ class MyClass { MyClass() { 'println 23' } } """ rule.maxLines = 2 assertSingleViolation(SOURCE, 3, null, CONSTRUCTOR_METHOD_NAME) } @Test void testApplyTo_NoMethodDefinition() { final SOURCE = ''' class MyClass { int count } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_EqualToMaxLines() { final SOURCE = """ class MyClass { def myMethod() { ${'println 23\n' * 97} } }""" assertNoViolations(SOURCE) } @Test void testApplyTo_CountsAnnotationsInNumberOfLines() { final SOURCE = ''' class MyClass { @Override def myMethod() { println 123 } }''' rule.maxLines = 3 assertSingleViolation(SOURCE, 3, null, 'myMethod') } @Test void testApplyTo_IgnoreMethodNames_MatchesSingleName() { final SOURCE = ''' class MyClass { def myMethod() { 'println 23' } } ''' rule.maxLines = 2 rule.ignoreMethodNames = 'myMethod' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesNoNames() { final SOURCE = ''' class MyClass { def myMethod1() { 'println 23' } String myMethod2() { 'error: 23' } } ''' rule.maxLines = 2 rule.ignoreMethodNames = 'otherMethod' assertSingleViolation(SOURCE, 4, null, 'myMethod2') } @Test void testApplyTo_IgnoreMethodNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { def names private open(String destination) { } String initialize() { names = ['a', 'b'] } void process() { } void doOtherStuff() { } } ''' rule.maxLines = 1 rule.ignoreMethodNames = 'init*ze,doO??erSt*ff,other' assertTwoViolations(SOURCE, 4, null, 'open', 9, null, 'process') } protected Rule createRule() { new MethodSizeRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/AbcComplexityRuleTest.groovy�������������������0000644�0001750�0001750�00000017017�12055541642�027541� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AbcComplexityRule * * @author Chris Mair */ class AbcComplexityRuleTest extends AbstractRuleTestCase { @Test void testDisabledByDefault() { assert !new AbcComplexityRule().enabled } @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AbcComplexity' assert rule.maxMethodComplexity == 60 assert rule.maxClassAverageMethodComplexity == 60 assert rule.maxClassComplexity == 0 } @Test void testApplyTo_ClassWithNoMethods() { final SOURCE = ''' class MyClass { def myValue = 23 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SingleMethod_EqualToClassAndMethodThreshold() { final SOURCE = ''' class MyClass { def myMethod() { switch(x) { case 1: break case 3: break } } } ''' rule.maxMethodComplexity = 2 rule.maxClassAverageMethodComplexity = 2 assertNoViolations(SOURCE) } @Test void testApplyTo_SingleMethod_ExceedsMaxMethodComplexity() { final SOURCE = ''' class MyClass { def myMethod() { a = 1; b = 2; c = 3 } } ''' rule.maxMethodComplexity = 2 assertSingleViolation(SOURCE, 3, 'def myMethod()', ['myMethod', '3.0']) } @Test void testApplyTo_SingleClosureField_ExceedsMaxMethodComplexity() { final SOURCE = ''' class MyClass { def myClosure = { a.someMethod(); b.aProperty } } ''' rule.maxMethodComplexity = 1 assertSingleViolation(SOURCE, 3, 'def myClosure', ['myClosure', '2.0']) } @Test void testApplyTo_TwoMethodsExceedsMaxMethodComplexity() { final SOURCE = """ class MyClass { def myMethod1() { a && b && c } def myMethod2(int someValue) { println 'ok' } def myMethod3() { a || b || c || d || e || f || g } } """ rule.maxMethodComplexity = 2 assertTwoViolations(SOURCE, 3, 'def myMethod1()', ['myMethod1', '3'], 9, 'def myMethod3()', ['myMethod3', '7']) } @Test void testApplyTo_Class_ExceedsMaxClassAverageMethodComplexity() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassAverageMethodComplexity = 5 assertSingleViolation(SOURCE, 2, 'class MyClass', ['MyClass', '6']) } @Test void testApplyTo_Class_ExceedsMaxClassComplexity() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassComplexity = 5 assertSingleViolation(SOURCE, 2, 'class MyClass', ['MyClass', '6']) } @Test void testApplyTo_Class_ZeroMaxClassAverageMethodComplexity_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassAverageMethodComplexity = 0 assertNoViolations(SOURCE) } @Test void testApplyTo_ClassAndMethod_ExceedThreshold() { final SOURCE = """ class MyClass { def myMethod1() { a = 1; b = 2 } def myMethod2(int someValue) { println 'ok' } def myMethod3() { a || b || c || d || e || f } } """ rule.maxMethodComplexity = 4.5 rule.maxClassAverageMethodComplexity = 1.9 rule.maxClassComplexity = 6.0 assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyClass', messageText:['MyClass', '2.2']], [lineNumber:2, sourceLineText:'class MyClass', messageText:['MyClass', '6.4']], [lineNumber:8, sourceLineText:'def myMethod3()', messageText:['myMethod3', '6']]) } @Test void testApplyTo_IgnoreMethodNames_MatchesSingleName() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.ignoreMethodNames = 'myMethod' rule.maxMethodComplexity = 1 assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesNoNames() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.ignoreMethodNames = 'otherMethod' rule.maxMethodComplexity = 1 assertSingleViolation(SOURCE, 3, 'def myMethod()', ['myMethod', '6']) } @Test void testApplyTo_IgnoreMethodNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } def myClosure = { a && b && c } def otherClosure = { a ?: (b ?: c) } def myMethod2() { a || b || c } } ''' rule.ignoreMethodNames = 'myM*d*,otherC??su*' rule.maxMethodComplexity = 1 assertSingleViolation(SOURCE, 6, 'def myClosure', ['myClosure', '3']) } @Test void testApplyTo_NoExplicitClass_StillChecksMethods() { final SOURCE = ''' def myMethod() { a && b && c && d && e && f } ''' rule.maxMethodComplexity = 1 rule.maxClassAverageMethodComplexity = 1 assertSingleViolation(SOURCE, 2, 'def myMethod()', ['myMethod', '6']) } @Test void testApplyTo_NoExplicitMethodDefinition_ChecksAsRunMethod() { final SOURCE = ''' if (isReady) { println a && b && c && d && e } ''' rule.maxMethodComplexity = 1 rule.maxClassAverageMethodComplexity = 1 assertSingleViolation(SOURCE, null, null, ['run', '6']) } protected Rule createRule() { new AbcComplexityRule(enabled: true) } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/NestedBlockDepthRuleTest.groovy����������������0000644�0001750�0001750�00000027271�12041642704�030157� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for NestedBlockDepthRule * * @author Chris Mair */ class NestedBlockDepthRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'NestedBlockDepth' assert rule.maxNestedBlockDepth == 5 } @Test void testNoNestedBlocks_CausesNoViolations() { final SOURCE = ''' class MyClass { def myMethod() { int count = 23 } } ''' assertNoViolations(SOURCE) } @Test void testNestingDepthLessThanDefaultMaximum_CausesNoViolations() { final SOURCE = ''' class MyClass { def myMethod() { if (count > maxCount) { // 1 while(notReady()) { // 2 listeners.each { notify(it) } // 3 } } } } ''' assertNoViolations(SOURCE) } @Test void testNestingDepthGreaterThanDefaultMaximum_CausesAViolation() { final SOURCE = ''' class MyClass { def myMethod() { if (count > maxCount) { // 1 myList.each { element-> // 2 sleep(1000L) listeners.each { notify(it) // 3 if (logging) { // 4 if (loggingFilename) { // 5 element.values.each { // 6 println "value=$it" } } } } } } } } ''' assertSingleViolation(SOURCE, 11, 'element.values.each {', '6') } @Test void testIgnoresOuterClosureForNestingDepthOfClosureField() { final SOURCE = ''' class MyClass { def myClosure = { // ignore if (count > maxCount) { // 1 while(notReady()) { // 2 println 'not ready' } } } } ''' rule.maxNestedBlockDepth = 2 assertNoViolations(SOURCE) } @Test void testClosureFieldThatExceedsConfiguredNesting_CausesAViolation() { final SOURCE = ''' class MyClass { def myClosure = { // ignore if (count > maxCount) { // 1 while(notReady()) { // 2 println 'not ready' } } } } ''' rule.maxNestedBlockDepth = 1 assertSingleViolation(SOURCE, 5, 'while(notReady()) {', '2') } @Test void testNestingDepthExceededForFinally_CausesAViolation() { final SOURCE = ''' class MyClass { def myMethod() { try { // 1 while (notReady()) { // 2 sleep(1000L) } } catch(Exception e) { } finally { // 1 if (ready) { // 2 println 'ready' } } } } ''' rule.maxNestedBlockDepth = 1 assertTwoViolations(SOURCE, 5, 'while (notReady()) {', '2', 12, 'if (ready) {', '2') } @Test void testNestingDepthExceededForTryOrCatch_CausesAViolation() { final SOURCE = ''' class MyClass { def myMethod() { while(notReady()) { // 1 try { // 2 sleep(1000L) } catch(Exception e) { // 2 log(e) } } } } ''' rule.maxNestedBlockDepth = 1 assertTwoViolations(SOURCE, 5, 'try {', '2', 8, 'catch(Exception e) {', '2') } @Test void testNestingDepthExceededForWhile_CausesAViolation() { final SOURCE = ''' def myMethod() { while (notReady()) { // 1 sleep(1000L) while(hasChars()) { // 2 } } } ''' rule.maxNestedBlockDepth = 1 assertSingleViolation(SOURCE, 5, 'while(hasChars()) {', '2') } @Test void testNestingDepthExceededForIfOrElse_CausesAViolation() { final SOURCE = ''' if (ready) { // 1 if (logging) { // 2 println "waiting..." } else { // 2 start() } } ''' rule.maxNestedBlockDepth = 1 assertTwoViolations(SOURCE, 3, 'if (logging) {', '2', 5, '} else {', '2') } @Test void testNestingDepthExceededForSwitch_CausesAViolation() { final SOURCE = ''' if (ready) { // 1 switch(code) { case 1: println "one" // 2 case 2: println "two" // 2 } } ''' rule.maxNestedBlockDepth = 1 assertTwoViolations(SOURCE, 4, 'case 1: println "one"', '2', 5, 'case 2: println "two"', '2') } @Test void testNestingDepthExceededForAForLoop_CausesAViolation() { final SOURCE = ''' while (notReady()) { // 1 sleep(1000L) for(int i=0; i < 5; i++) { // 2 println "waiting..." } } ''' rule.maxNestedBlockDepth = 1 assertSingleViolation(SOURCE, 4, 'for(int i=0; i < 5; i++) {', '2') } @Test void testNestingDepthExceededForSynchronized_CausesAViolation() { final SOURCE = ''' def myMethod() { while (notReady()) { // 1 sleep(1000L) synchronized(this) { // 2 doSomething() } } } ''' rule.maxNestedBlockDepth = 1 assertSingleViolation(SOURCE, 5, 'synchronized(this) {', '2') } @Test void testNestingDepthExceeded_IfStatementWithoutABlock_CausesNoViolation() { final SOURCE = ''' if (ready) { // 1 if (logging) println "ok" // 2 - but does not count - no block } ''' rule.maxNestedBlockDepth = 1 assertNoViolations(SOURCE) } @Test void testNestingDepthExceededForClosureAssignment_CausesAViolation() { final SOURCE = ''' def myMethod() { while (notReady()) { // 1 sleep(1000L) def closure = { // 2 doSomething() } } } ''' rule.maxNestedBlockDepth = 1 assertSingleViolation(SOURCE, 5, 'def closure = {', '2') } @Test void testNestingDepthExceededForClosureIteration_CausesAViolation() { final SOURCE = ''' def myMethod() { while (notReady()) { // 1 sleep(1000L) myList.each { element -> // 2 doSomething(element) } } } ''' rule.maxNestedBlockDepth = 1 assertSingleViolation(SOURCE, 5, 'myList.each { element ->', '2') } @Test void testBuilderConstructorInvocation() { final SOURCE = ''' new MarkupBuilder().root { foo { bar { baz { quix { qux { quaxz { } } } } } } } ''' assertNoViolations(SOURCE) } @Test void testBuilderPropertyInvocation() { final SOURCE = ''' myBuilder.root { foo { bar { baz { quix { qux { quaxz { } } } } } } } ''' assertNoViolations(SOURCE) } @Test void testBuilderMethodInvocation() { final SOURCE = ''' createBuilder().root { foo { bar { baz { quix { qux { quaxz { } } } } } } } ''' assertNoViolations(SOURCE) } @Test void testNotABuilderMethodInvocation() { final SOURCE = ''' notABuilderMethod().root { foo { bar { baz { quix { qux { } } } } } } ''' assertSingleViolation(SOURCE, 7, 'qux {', 'The nested block depth is 6') } protected Rule createRule() { new NestedBlockDepthRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/ParameterCountRuleTest.groovy������������������0000644�0001750�0001750�00000011655�12444433061�027726� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase import static org.codenarc.test.TestUtil.shouldFail /** * Tests for ParameterCountRule * * @author Maciej Ziarko */ class ParameterCountRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ParameterCount' } @Test void testSetMaxParameter_negativeInteger() { shouldFail(IllegalArgumentException) { rule.maxParameters = -1 } } @Test void testSetMaxParameter_zero() { shouldFail(IllegalArgumentException) { rule.maxParameters = 0 } } @Test void testNoViolations_defaultMaxParameter() { assertNoViolations(''' class TestClass { TestClass() { } TestClass(int arg1) { } TestClass(int arg1, int arg2, int arg3, int arg4) { } void someMethod() { } void someMethod(int arg1, int arg2, int arg3, int arg4, int arg5) { } } ''') } @Test void testNoViolations_customMaxParameter() { rule.maxParameters = 3 assertNoViolations(''' class TestClass { TestClass() { } TestClass(int arg1) { } TestClass(int arg1, int arg2, int arg3) { } void someMethod() { } void someMethod(int arg1, int arg2, int arg3) { } } ''') } @Test void testSingleViolation_defaultMaxParameter() { assertInlineViolations(""" class TestClass { TestClass() { } TestClass(int arg1) { } TestClass(int arg1, int arg2, int arg3, int arg4) { } void someMethod() { } void someMethod(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) { ${violation('method TestClass.someMethod')} } } """) } @Test void testSingleViolation_customMaxParameter() { rule.maxParameters = 3 assertInlineViolations(""" class TestClass { TestClass() { } TestClass(int arg1) { } TestClass(int arg1, int arg2, int arg3, int arg4) { ${violation('constructor of class TestClass')} } void someMethod() { } void someMethod(int arg1, int arg2, int arg3) { } } """) } @Test void testMultipleViolations_defaultMaxParameter() { assertInlineViolations(""" class TestClass { TestClass() { } TestClass(int arg1) { } TestClass(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) { ${violation('constructor of class TestClass')} } void someMethod() { } void someMethod(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) { ${violation('method TestClass.someMethod')} } } """) } @Test void testMultipleViolations_customMaxParameter() { rule.maxParameters = 3 assertInlineViolations(""" class TestClass { TestClass() { } TestClass(int arg1) { } TestClass(int arg1, int arg2, int arg3, int arg4) { ${violation('constructor of class TestClass')} } void someMethod() { } void someMethod(int arg1, int arg2, int arg3, int arg4, int arg5) { ${violation('method TestClass.someMethod')} } } """) } private String violation(String name) { return inlineViolation("Number of parameters in ${name} exceeds maximum allowed (${rule.maxParameters}).") } protected Rule createRule() { new ParameterCountRule() } } �����������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/CyclomaticComplexityRuleTest.groovy������������0000644�0001750�0001750�00000021062�12311373552�031134� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CyclomaticComplexityRule * * @author Chris Mair */ class CyclomaticComplexityRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CyclomaticComplexity' assert rule.maxMethodComplexity == 20 assert rule.maxClassComplexity == 0 assert rule.maxClassAverageMethodComplexity == 20 } @Test void testApplyTo_ClassWithNoMethods() { final SOURCE = ''' class MyClass { def myValue = 23 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SingleMethod_EqualToMaxMethodComplexity() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e } } ''' rule.maxMethodComplexity = 5 assertNoViolations(SOURCE) } @Test void testApplyTo_SingleMethod_ExceedsMaxMethodComplexity() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxMethodComplexity = 5 assertSingleViolation(SOURCE, 3, 'def myMethod()', ['myMethod', '6']) } @Test void testSuppressWarningsOnClass() { final SOURCE = ''' @SuppressWarnings('CyclomaticComplexity') class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxMethodComplexity = 5 assert manuallyApplyRule(SOURCE).size() == 0 } @Test void testSuppressWarningsOnMethod() { final SOURCE = ''' class MyClass { @SuppressWarnings('CyclomaticComplexity') def myMethod() { a && b && c && d && e && f } } ''' rule.maxMethodComplexity = 5 assert manuallyApplyRule(SOURCE).size() == 0 } @Test void testApplyTo_SingleClosureField_ExceedsMaxMethodComplexity() { final SOURCE = ''' class MyClass { def myClosure = { a && b && c && d && e } } ''' rule.maxMethodComplexity = 2 assertSingleViolation(SOURCE, 3, 'def myClosure', ['myClosure', '5']) } @Test void testApplyTo_TwoMethodsExceedsMaxMethodComplexity() { final SOURCE = """ class MyClass { def myMethod1() { a && b && c } def myMethod2(int someValue) { println 'ok' } def myMethod3() { a || b || c || d || e || f || g } } """ rule.maxMethodComplexity = 2 assertTwoViolations(SOURCE, 3, 'def myMethod1()', ['myMethod1', '3'], 9, 'def myMethod3()', ['myMethod3', '7']) } @Test void testApplyTo_Class_ExceedsMaxAverageClassComplexity() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassAverageMethodComplexity = 5 assertSingleViolation(SOURCE, 2, 'class MyClass', ['MyClass', '6']) } @Test void testApplyTo_Class_ExceedsMaxClassComplexity() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassComplexity = 5 assertSingleViolation(SOURCE, 2, 'class MyClass', ['MyClass', '6']) } @Test void testApplyTo_Class_ZeroMaxClassAverageMethodComplexity_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassAverageMethodComplexity = 0 assertNoViolations(SOURCE) } @Test void testApplyTo_ClassAndMethod_ExceedThreshold() { final SOURCE = ''' class MyClass { def myMethod1() { a && b && c } def myMethod2(int someValue) { println 'ok' } def myMethod3() { a || b || c || d || e || f } } ''' rule.maxMethodComplexity = 5 rule.maxClassComplexity = 9 rule.maxClassAverageMethodComplexity = 3 assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyClass', messageText:['MyClass', '3.3']], [lineNumber:2, sourceLineText:'class MyClass', messageText:['MyClass', '10']], [lineNumber:8, sourceLineText:'def myMethod3()', messageText:['myMethod3', '6']]) } @Test void testApplyTo_ClassAndMethods_AtThreshold() { final SOURCE = ''' class MyClass { def myMethod1() { a && b && c } def myClosure = { a ?: (b ?: c) } def myMethod2() { a || b || c } } ''' rule.maxMethodComplexity = 3 rule.maxClassComplexity = 9 rule.maxClassAverageMethodComplexity = 3 assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesSingleName() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.ignoreMethodNames = 'myMethod' rule.maxMethodComplexity = 1 assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesNoNames() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.ignoreMethodNames = 'otherMethod' rule.maxMethodComplexity = 1 assertSingleViolation(SOURCE, 3, 'def myMethod()', ['myMethod', '6']) } @Test void testApplyTo_IgnoreMethodNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } def myClosure = { a ?: (b ?: c) } def otherClosure = { a ?: (b ?: c) } def myMethod2() { a || b || c } } ''' rule.ignoreMethodNames = 'myM*d*,otherC??su*' rule.maxMethodComplexity = 1 assertSingleViolation(SOURCE, 6, 'def myClosure', ['myClosure', '3']) } @Test void testApplyTo_NoExplicitClass_StillChecksMethods() { final SOURCE = ''' def myMethod() { a && b && c && d && e && f } ''' rule.maxMethodComplexity = 1 rule.maxClassAverageMethodComplexity = 1 assertSingleViolation(SOURCE, 2, 'def myMethod()', ['myMethod', '6']) } @Test void testApplyTo_NoExplicitMethodDefinition_ChecksAsRunMethod() { final SOURCE = ''' if (isReady) { println a && b && c && d && e } ''' rule.maxMethodComplexity = 1 rule.maxClassAverageMethodComplexity = 1 assertSingleViolation(SOURCE, null, null, ['run', '6']) } protected Rule createRule() { new CyclomaticComplexityRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/MethodCountRuleTest.groovy���������������������0000644�0001750�0001750�00000004117�12041642704�027220� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for MethodCountRule * * @author 'Tomasz Bujok' */ class MethodCountRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'MethodCount' assert rule.maxMethods == 30 } @Test void testSuccessScenario() { String classContent = 'class MyClass {\n' for (int i = 0; i < rule.maxMethods; i++) { classContent += "public void method${i}() {}\n" } classContent += '\n}' assertNoViolations(classContent) } @Test void testSingleViolation() { String classContent = ''' class MyClass { void method1() { } void method2() { } void method3() { } } ''' rule.maxMethods = 2 assertSingleViolation(classContent, 2, 'class MyClass {', ['MyClass', '3']) } @Test void testIgnoreGeneratedMethods() { rule.maxMethods = 2 // A script will result in generated run and main methods String classContent = ''' void method1() {} void method2() {} ''' assertNoViolations(classContent) } protected Rule createRule() { new MethodCountRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/AbcMetricRuleTest.groovy�����������������������0000644�0001750�0001750�00000016523�12055541374�026632� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AbcMetricRule * * @author Chris Mair */ class AbcMetricRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AbcMetric' assert rule.maxMethodAbcScore == 60 assert rule.maxClassAverageMethodAbcScore == 60 assert rule.maxClassAbcScore == 0 } @Test void testApplyTo_ClassWithNoMethods() { final SOURCE = ''' class MyClass { def myValue = 23 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SingleMethod_EqualToClassAndMethodThreshold() { final SOURCE = ''' class MyClass { def myMethod() { switch(x) { case 1: break case 3: break } } } ''' rule.maxMethodAbcScore = 2 rule.maxClassAverageMethodAbcScore = 2 assertNoViolations(SOURCE) } @Test void testApplyTo_SingleMethod_ExceedsMaxMethodAbcScore() { final SOURCE = ''' class MyClass { def myMethod() { a = 1; b = 2; c = 3 } } ''' rule.maxMethodAbcScore = 2 assertSingleViolation(SOURCE, 3, 'def myMethod()', ['myMethod', '3.0']) } @Test void testApplyTo_SingleClosureField_ExceedsMaxMethodAbcScore() { final SOURCE = ''' class MyClass { def myClosure = { a.someMethod(); b.aProperty } } ''' rule.maxMethodAbcScore = 1 assertSingleViolation(SOURCE, 3, 'def myClosure', ['myClosure', '2.0']) } @Test void testApplyTo_TwoMethodsExceedsMaxMethodAbcScore() { final SOURCE = """ class MyClass { def myMethod1() { a && b && c } def myMethod2(int someValue) { println 'ok' } def myMethod3() { a || b || c || d || e || f || g } } """ rule.maxMethodAbcScore = 2 assertTwoViolations(SOURCE, 3, 'def myMethod1()', ['myMethod1', '3'], 9, 'def myMethod3()', ['myMethod3', '7']) } @Test void testApplyTo_Class_ExceedsMaxClassAverageMethodAbcScore() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassAverageMethodAbcScore = 5 assertSingleViolation(SOURCE, 2, 'class MyClass', ['MyClass', '6']) } @Test void testApplyTo_Class_ExceedsMaxClassAbcScore() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassAbcScore = 5 assertSingleViolation(SOURCE, 2, 'class MyClass', ['MyClass', '6']) } @Test void testApplyTo_Class_ZeroMaxClassAverageMethodAbcScore_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.maxClassAverageMethodAbcScore = 0 assertNoViolations(SOURCE) } @Test void testApplyTo_ClassAndMethod_ExceedThreshold() { final SOURCE = """ class MyClass { def myMethod1() { a = 1; b = 2 } def myMethod2(int someValue) { println 'ok' } def myMethod3() { a || b || c || d || e || f } } """ rule.maxMethodAbcScore = 4.5 rule.maxClassAverageMethodAbcScore = 1.9 rule.maxClassAbcScore = 6.0 assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyClass', messageText:['MyClass', '2.2']], [lineNumber:2, sourceLineText:'class MyClass', messageText:['MyClass', '6.4']], [lineNumber:8, sourceLineText:'def myMethod3()', messageText:['myMethod3', '6']]) } @Test void testApplyTo_IgnoreMethodNames_MatchesSingleName() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.ignoreMethodNames = 'myMethod' rule.maxMethodAbcScore = 1 assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesNoNames() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } } ''' rule.ignoreMethodNames = 'otherMethod' rule.maxMethodAbcScore = 1 assertSingleViolation(SOURCE, 3, 'def myMethod()', ['myMethod', '6']) } @Test void testApplyTo_IgnoreMethodNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { def myMethod() { a && b && c && d && e && f } def myClosure = { a && b && c } def otherClosure = { a ?: (b ?: c) } def myMethod2() { a || b || c } } ''' rule.ignoreMethodNames = 'myM*d*,otherC??su*' rule.maxMethodAbcScore = 1 assertSingleViolation(SOURCE, 6, 'def myClosure', ['myClosure', '3']) } @Test void testApplyTo_NoExplicitClass_StillChecksMethods() { final SOURCE = ''' def myMethod() { a && b && c && d && e && f } ''' rule.maxMethodAbcScore = 1 rule.maxClassAverageMethodAbcScore = 1 assertSingleViolation(SOURCE, 2, 'def myMethod()', ['myMethod', '6']) } @Test void testApplyTo_NoExplicitMethodDefinition_ChecksAsRunMethod() { final SOURCE = ''' if (isReady) { println a && b && c && d && e } ''' rule.maxMethodAbcScore = 1 rule.maxClassAverageMethodAbcScore = 1 assertSingleViolation(SOURCE, null, null, ['run', '6']) } protected Rule createRule() { new AbcMetricRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/GMetricsSourceCodeAdapterTest.groovy�����������0000644�0001750�0001750�00000003451�12041642704�031131� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.size import org.codenarc.source.SourceString import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for GMetricsSourceCodeAdapter * * @author Chris Mair */ class GMetricsSourceCodeAdapterTest extends AbstractTestCase { private static final SOURCE = 'abc\ndef' @Test void testConstructor_Null() { shouldFailWithMessageContaining('sourceCode') { new GMetricsSourceCodeAdapter(null) } } @Test void testDelegatesMethods() { def sourceCode = new SourceString(SOURCE, 'path', 'name') def adapter = new GMetricsSourceCodeAdapter(sourceCode) assert adapter.name == sourceCode.name assert adapter.path == sourceCode.path assert adapter.text == sourceCode.text assert adapter.valid == sourceCode.valid assert adapter.lines == sourceCode.lines assert adapter.line(0) == sourceCode.line(0) assert adapter.ast == sourceCode.ast assert adapter.getLineNumberForCharacterIndex(4) == sourceCode.getLineNumberForCharacterIndex(4) } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/size/ClassSizeRuleTest.groovy�����������������������0000644�0001750�0001750�00000004410�12466776246�026707� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.size import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ClassSizeRule * * @author Chris Mair */ class ClassSizeRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ClassSize' } @Test void testApplyTo_LongerThanDefaultMaxLines() { final SOURCE = """ class MyClass { def myMethod() { ${'println 23\n' * 996} } } """ assertSingleViolation(SOURCE, 2, null, 'MyClass') } @Test void testApplyTo_SetMaxLines() { final SOURCE = """ package some.pkg /** class description */ class MyClass { def myMethod() { 'println 23' } } """ rule.maxLines = 4 assertSingleViolation(SOURCE, 4, null, '"MyClass"') } @Test void testApplyTo_GeneratedClass() { final SOURCE = ''' if (isReady) { println 'ready' } ''' rule.maxLines = 1 assertNoViolations(SOURCE) } @Test void testApplyTo_EqualToMaxLines() { final SOURCE = """ class MyClass { def myMethod() { ${'println 23\n' * 995} } }""" assertNoViolations(SOURCE) } protected Rule createRule() { new ClassSizeRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/imports/��������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022550� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/imports/DuplicateImportRuleTest.groovy��������������0000644�0001750�0001750�00000007610�12041642702�030616� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DuplicateImportRule * * @author Chris Mair */ class DuplicateImportRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'DuplicateImport' } @Test void testApplyTo_Violation() { final SOURCE = ''' import java.io.InputStream import java.io.OutputStream import java.io.InputStream class MyClass { def str = "import java.io.InputStream" // ignored } interface MyInterface { static final NAME = "import java.io.OutputStream" // ignored } ''' assertSingleViolation(SOURCE, 4, 'import java.io.InputStream') } @Test void testApplyTo_DuplicateImportWithWildcards_Violation() { final SOURCE = ''' import java.io.* import org.sample.MyClass import java.io.* ''' assertSingleViolation(SOURCE, 4, 'import java.io.*') } @Test void testApplyTo_ImportsWithWildcards_NoViolations() { final SOURCE = ''' import java.io.* import org.sample.* import java.text.* ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MultipleDuplicateImports() { final SOURCE = ''' import abc.def.MyClass import java.io.OutputStream import abc.def.MyClass import xyz.OtherClass import abc.def.MyClass interface MyInterface { } ''' assertTwoViolations(SOURCE, 4, 'import abc.def.MyClass', 6, 'import abc.def.MyClass') } @Test void testApplyTo_DuplicateStaticImportWithWildcards_Violation() { final SOURCE = ''' import static com.wystar.app.payroll.util.DataMaintenanceUtil.* import static com.wystar.app.payroll.util.PayrollProcessingConstants.* import static com.wystar.app.payroll.util.DataMaintenanceUtil.* import org.sample.MyClass ''' assertSingleViolation(SOURCE, 4, 'import static com.wystar.app.payroll.util.DataMaintenanceUtil.*') } @Test void testApplyTo_StaticImportWithWildcards_NoViolations() { final SOURCE = ''' import static com.wystar.app.payroll.util.DataMaintenanceUtil.* import static com.wystar.app.payroll.util.PayrollProcessingConstants.* ''' assertNoViolations(SOURCE) } @Test void testApplyTo_CommentedOutDuplicateImport_NoViolations() { final SOURCE = ''' import java.io.InputStream // import java.io.InputStream ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations() { final SOURCE = ''' import java.io.InputStream import java.io.OutputStream import java.util.HashMap ''' assertNoViolations(SOURCE) } protected Rule createRule() { new DuplicateImportRule() } } ������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/imports/NoWildcardImportsRuleTest.groovy������������0000644�0001750�0001750�00000003660�12311373552�031122� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for NoWildcardImportsRule * * @author Kyle Boon */ class NoWildcardImportsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'NoWildcardImports' } @Test void testNoViolations() { final SOURCE = ''' import com.google public class Foo {} ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' import com.google.* public class Foo {} ''' assertSingleViolation(SOURCE, 2, 'import com.google.*') } @Test void testMultipleViolations() { final SOURCE = ''' import com.google.* import org.codenarc.rule.* public class Foo {} ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'import com.google.*'], // todo: replace line number, source line and message [lineNumber:3, sourceLineText:'import org.codenarc.rule.*']) // todo: replace line number, source line and message } protected Rule createRule() { new NoWildcardImportsRule() } } ��������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/imports/ImportFromSamePackageRuleTest.groovy��������0000644�0001750�0001750�00000004727�12041642702�031677� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ImportFromSamePackageRule * * @author Chris Mair */ class ImportFromSamePackageRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ImportFromSamePackage' } @Test void testApplyTo_Violations() { final SOURCE = ''' package org.xyz import org.xyz.MyController import java.text.SimpleDateFormat import org.xyz.MyService ''' assertTwoViolations(SOURCE, 3, 'org.xyz.MyController', 5, 'org.xyz.MyService') } @Test void testApplyTo_ImportStar_Violations() { final SOURCE = ''' package org.xyz import org.xyz.* ''' assertSingleViolation(SOURCE, 3, 'import org.xyz.*') } @Test void testApplyTo_IgnoreStaticImports() { final SOURCE = ''' package org.xyz import static org.xyz.MyUtil.calculate import static Math.* import static org.xyz.Helper.* ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreImportsWithExplicitAliasDeclarations() { final SOURCE = ''' package org.xyz import org.xyz.MyBigClass as MBC ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations() { final SOURCE = ''' package org.mypackage import java.text.SimpleDateFormat import com.xxx.MyClass ''' assertNoViolations(SOURCE) } protected Rule createRule() { new ImportFromSamePackageRule() } } �����������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/imports/MisorderedStaticImportsRuleTest.groovy������0000644�0001750�0001750�00000006574�12041642702�032344� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for MisorderedStaticImportsRule * * @author Erik Pragt * @author Marcin Erdmann */ class MisorderedStaticImportsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'MisorderedStaticImports' } @Test void testSuccessScenarioWithNonStaticImports() { final SOURCE = ''' import foo.bar.* import my.something.* ''' assertNoViolations(SOURCE) } @Test void testSuccessScenarioWithStaticImportsOnly() { final SOURCE = ''' import static foo.bar.* import static my.something.* ''' assertNoViolations(SOURCE) } @Test void testSuccessScenarioWithCorrectSequence() { final SOURCE = ''' import static foo.bar.* import my.something.* ''' assertNoViolations(SOURCE) } @Test void testSuccessScenarioWithCorrectSequence_After() { final SOURCE = ''' import my.something.* import static foo.bar.* ''' rule.comesBefore = false assertNoViolations(SOURCE) } @Test void testSingleViolationWithIncorrectSequence() { final SOURCE = ''' import my.something.* import static foo.bar.* ''' assertSingleViolation(SOURCE, 3, 'import static foo.bar.*', 'Static imports should appear before normal imports') } @Test void testSingleViolationWithIncorrect_After() { final SOURCE = ''' import static foo.bar.* import my.something.* ''' rule.comesBefore = false assertSingleViolation(SOURCE, 3, 'import my.something.*', 'Normal imports should appear before static imports') } @Test void testTwoViolations() { final SOURCE = ''' import my.something.* import static foo.bar.* import my.otherthing.* import static bar.foo.* ''' assertTwoViolations(SOURCE, 3, 'import static foo.bar.*', 5, 'import static bar.foo.*') } @Test void testOneViolationStartingWithStaticImport() { final SOURCE = ''' import static foo.bar.* import my.something.* import static bar.foo.* import my.otherthing.* ''' assertSingleViolation(SOURCE, 4, 'import static bar.foo.*') } protected Rule createRule() { new MisorderedStaticImportsRule() } } ������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/imports/UnnecessaryGroovyImportRuleTest.groovy������0000644�0001750�0001750�00000012077�12041642702�032414� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnnecessaryGroovyImportRule * * @author Chris Mair */ class UnnecessaryGroovyImportRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnnecessaryGroovyImport' } /* * no violations */ @Test void testApplyTo_NoViolations() { final SOURCE = ''' import java.text.SimpleDateFormat import com.xxx.MyClass import MyClassFromSamePackage ''' assertNoViolations(SOURCE) } @Test void testApplyTo_StaticImport() { final SOURCE = ''' import static java.math.BigDecimal.* import static java.math.BigInteger.* import static java.io.InputStream.* import static java.lang.Integer.* import static java.net.Socket.* import static java.util.Map.* import static groovy.lang.GString.* import static groovy.util.Expando.* ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MixtureOfStaticAndRegularImports_NoViolations() { final SOURCE = ''' import static java.net.HttpURLConnection.* import org.junit.* class Test1 { static me() { println HTTP_OK } } ''' assertNoViolations(SOURCE) } @Test void testImportAliases_NoViolations() { final SOURCE = ''' import groovy.lang.MetaClass as Foo import com.xxx.MyClass import groovy.lang.GString as Bar ''' assertNoViolations(SOURCE) } /* * violations - misc. */ @Test void testApplyTo_ImportStar_Violations() { final SOURCE = ''' import java.io.* ''' assertSingleViolation(SOURCE, 2, 'import java.io.*') } /* * violations - Java imports */ @Test void testApplyTo_ImportJavaIo() { final SOURCE = ''' import com.xxx.MyClass import java.io.InputStream import java.io.OutputStream ''' assertTwoViolations(SOURCE, 3, 'java.io.InputStream', 4, 'java.io.OutputStream') } @Test void testApplyTo_ImportJavaLang() { final SOURCE = ''' import java.lang.String import com.xxx.MyClass import java.lang.reflect.Field import java.lang.Integer ''' assertTwoViolations(SOURCE, 2, 'java.lang.String', 5, 'java.lang.Integer') } @Test void testApplyTo_ImportJavaMath() { final SOURCE = ''' import java.math.BigDecimal import com.xxx.MyClass import java.math.RoundingMode import java.math.BigInteger ''' assertTwoViolations(SOURCE, 2, 'java.math.BigDecimal', 5, 'java.math.BigInteger') } @Test void testApplyTo_ImportJavaNet() { final SOURCE = ''' import java.net.URL import com.xxx.MyClass import java.net.Socket ''' assertTwoViolations(SOURCE, 2, 'java.net.URL', 4, 'java.net.Socket') } @Test void testApplyTo_ImportJavaUtil() { final SOURCE = ''' import java.util.List import com.xxx.MyClass import java.util.Map ''' assertTwoViolations(SOURCE, 2, 'java.util.List', 4, 'java.util.Map') } /* * violations - Groovy imports */ @Test void testApplyTo_ImportGroovyLang() { final SOURCE = ''' import groovy.lang.MetaClass import com.xxx.MyClass import groovy.lang.GString ''' assertTwoViolations(SOURCE, 2, 'groovy.lang.MetaClass', 4, 'groovy.lang.GString') } @Test void testApplyTo_ImportGroovyUtil() { final SOURCE = ''' import groovy.util.Eval import com.xxx.MyClass import groovy.util.Expando ''' assertTwoViolations(SOURCE, 2, 'groovy.util.Eval', 4, 'groovy.util.Expando') } protected Rule createRule() { new UnnecessaryGroovyImportRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/imports/ImportFromSunPackagesRuleTest.groovy��������0000644�0001750�0001750�00000004177�12041642702�031741� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ImportFromSunPackagesRule * * @author Hamlet D'Arcy */ class ImportFromSunPackagesRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ImportFromSunPackages' } @Test void testSuccessScenario() { final SOURCE = ''' import foo.bar "hellO" ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' import sun.misc.foo import sun.misc.foo as Foo public class Foo {} ''' assertViolations(SOURCE, [lineNumber: 2, sourceLineText: 'import sun.misc.foo', messageText: 'The file imports sun.misc.foo, which is not portable and likely to change'], [lineNumber: 3, sourceLineText: 'import sun.misc.foo as Foo', messageText: 'The file imports sun.misc.foo, which is not portable and likely to change']) } @Test void testStarImport() { final SOURCE = ''' import sun.* public class Foo {} ''' assertSingleViolation(SOURCE, 2, 'import sun.*', 'The file imports sun.*, which is not portable and likely to change') } protected Rule createRule() { new ImportFromSunPackagesRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/imports/UnusedImportRuleTest.groovy�����������������0000644�0001750�0001750�00000013351�12314642644�030156� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.imports import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnusedImportRule * * @author Chris Mair */ class UnusedImportRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'UnusedImport' } @Test void testApplyTo_OneViolation() { final SOURCE = ''' import java.io.InputStream import java.io.OutputStream class ABC { InputStream input } ''' assertSingleViolation(SOURCE, 3, 'import java.io.OutputStream', 'The [java.io.OutputStream] import is never referenced') } @Test void testApplyTo_TwoViolations() { final SOURCE = ''' import java.io.InputStream import java.util.Map import java.io.OutputStream class ABC { Map map } ''' assertTwoViolations(SOURCE, 2, 'import java.io.InputStream', 'The [java.io.InputStream] import is never referenced', 4, 'import java.io.OutputStream', 'The [java.io.OutputStream] import is never referenced') } @Test void testApplyTo_OnlyFullyQualifiedClassNameReferenced() { final SOURCE = ''' import a.b.SomeClass import d.e.OtherClass as OC import f.g.ThirdClass as TC class ABC extends a.b.SomeClass { def name = d.e.OtherClass.name def info = f.g.ThirdClass.name + ":" + TC.metaClass.name } ''' assertTwoViolations(SOURCE, 2, 'import a.b.SomeClass', 'The [a.b.SomeClass] import is never referenced', 3, 'import d.e.OtherClass as OC', 'The [d.e.OtherClass] import is never referenced') } @Test void testApplyTo_UnusedStaticImportConstant() { final SOURCE = ''' import static Math.PI class ABC { def name } ''' assertSingleViolation(SOURCE, 2, 'import static Math.PI', 'The [Math] import is never referenced') } @Test void testApplyTo_UnusedImport_WithSemicolon() { final SOURCE = ''' import com.example.MyService; import com.example.test.AbstractTestCase; abstract class AbstractMyProfileTestCase extends AbstractTestCase { protected void assertEmailAddress(EmailPreference emailPref) { assert emailPref.emailAddress } } ''' assertSingleViolation(SOURCE, 2, 'import com.example.MyService', 'The [com.example.MyService] import is never referenced') } @Test void testApplyTo_SimilarlyNamedImports() { final SOURCE = ''' import static com.example.FaultCode.* import com.example.Fault class MyResourceTest { @Test void testUpdateUserWidget_UpdateFails() { useStubFormatter(false, [UPDATE_FAILED]) def response = resource.getRecords() assert response.status == 404 } } ''' assertSingleViolation(SOURCE, 3, 'import com.example.Fault', 'The [com.example.Fault] import is never referenced') } @Test void testApplyTo_UnusedImport_SubstringOccurrence() { final SOURCE = ''' import com.example.Service class ABC { def getService() { } } ''' assertSingleViolation(SOURCE, 2, 'import com.example.Service', 'The [com.example.Service] import is never referenced') } @Test void testApplyTo_UnusedImportWildcard() { final SOURCE = ''' import org.codenarc.* class ABC { def name } ''' // Can't know whether any of the classes within org.codenarc package were ever referenced, // since we don't know what they are assertNoViolations(SOURCE) } @Test void testApplyTo_UnusedStaticImportWildcard() { final SOURCE = ''' import static Math.* class ABC { def name } ''' // Can't know whether any of the static members of the Math class were ever referenced, // since we don't know what they are assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations() { final SOURCE = ''' import java.io.InputStream import java.io.OutputStream import static Math.PI class ABC { def run() { String fff InputStream input OutputStream output def value = PI } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnusedImportRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/����������������������������������������0000755�0001750�0001750�00000000000�12623571301�023405� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/StaticDateFormatFieldRuleTest.groovy����0000644�0001750�0001750�00000013367�12041642700�032514� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for StaticDateFormatFieldRule * * @author Hamlet D'Arcy * @author Chris Mair */ class StaticDateFormatFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'StaticDateFormatField' } @Test void testSuccessScenario() { final SOURCE = ''' // these usages are OK class MyCorrectClass { private final DateFormat dateFormat1 static ThreadLocal<DateFormat> dateFormat2 static object = new Object() public static final VALUE = 1234 } ''' assertNoViolations(SOURCE) } @Test void testStaticField() { final SOURCE = ''' class MyClass { static DateFormat dateFormat } ''' assertSingleViolation(SOURCE, 3, 'static DateFormat dateFormat', 'DateFormat instances are not thread safe. Wrap the DateFormat field dateFormat in a ThreadLocal or make it an instance field') } @Test void testStaticFieldFullyQualifiedName() { final SOURCE = ''' class MyClass { static java.text.DateFormat dateFormat } ''' assertSingleViolation(SOURCE, 3, 'static java.text.DateFormat dateFormat', 'DateFormat instances are not thread safe. Wrap the DateFormat field dateFormat in a ThreadLocal or make it an instance field') } @Test void testStaticUntypedField_InitializesValueToDateFormat() { final SOURCE = ''' class MyClass { static final DATE1 = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE) static final def DATE2 = DateFormat.getDateInstance(DateFormat.LONG) static Object date3 = DateFormat.getDateInstance() static date4 = java.text.DateFormat.getDateInstance() static final DATETIME1 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.FRANCE) static final def DATETIME2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT) static Object dateTime3 = DateFormat.getDateTimeInstance() static dateTime4 = java.text.DateFormat.getDateTimeInstance() static final TIME1 = DateFormat.getTimeInstance(DateFormat.LONG, Locale.FRANCE) static final def TIME2 = DateFormat.getTimeInstance(DateFormat.LONG) static final Object TIME3 = DateFormat.getTimeInstance() static time4 = java.text.DateFormat.getTimeInstance() } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'static final DATE1 = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE)', messageText:['DateFormat', 'DATE1']], [lineNumber:4, sourceLineText:'static final def DATE2 = DateFormat.getDateInstance(DateFormat.LONG)', messageText:['DateFormat', 'DATE2']], [lineNumber:5, sourceLineText:'static Object date3 = DateFormat.getDateInstance()', messageText:['DateFormat', 'date3']], [lineNumber:6, sourceLineText:'static date4 = java.text.DateFormat.getDateInstance()', messageText:['DateFormat', 'date4']], [lineNumber:8, sourceLineText:'static final DATETIME1 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.FRANCE)', messageText:['DateFormat', 'DATETIME1']], [lineNumber:9, sourceLineText:'static final def DATETIME2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT)', messageText:['DateFormat', 'DATETIME2']], [lineNumber:10, sourceLineText:'static Object dateTime3 = DateFormat.getDateTimeInstance()', messageText:['DateFormat', 'dateTime3']], [lineNumber:11, sourceLineText:'static dateTime4 = java.text.DateFormat.getDateTimeInstance()', messageText:['DateFormat', 'dateTime4']], [lineNumber:13, sourceLineText:'static final TIME1 = DateFormat.getTimeInstance(DateFormat.LONG, Locale.FRANCE)', messageText:['DateFormat', 'TIME1']], [lineNumber:14, sourceLineText:'static final def TIME2 = DateFormat.getTimeInstance(DateFormat.LONG)', messageText:['DateFormat', 'TIME2']], [lineNumber:15, sourceLineText:'static final Object TIME3 = DateFormat.getTimeInstance()', messageText:['DateFormat', 'TIME3']], [lineNumber:16, sourceLineText:'static time4 = java.text.DateFormat.getTimeInstance()', messageText:['DateFormat', 'time4']], ) } @Test void testNonStaticFieldWithDateFormatInitializer() { final SOURCE = ''' class MyClass { final DateFormat filenameDateFormat = DateFormat.getTimeInstance(DateFormat.LONG) def anotherFormat = DateFormat.getDateInstance() } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new StaticDateFormatFieldRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedOnThisRuleTest.groovy�������0000644�0001750�0001750�00000004363�12041642700�032152� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SynchronizedOnThisRule. * * @author Hamlet D'Arcy */ class SynchronizedOnThisRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SynchronizedOnThis' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { private final def lock = new Object() def Method1() { synchronized(this) { ; } } def Method2() { synchronized(lock) { ; } } def Method3() { synchronized(this) { ; } } def Method4() { synchronized(lock) { ; } } } ''' assertTwoViolations(SOURCE, 6, 'synchronized(this) { ; }', 12, 'synchronized(this) { ; }') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' class MyClass { private final def lock = new Object() def Method1() { synchronized(lock) { ; } } def Method2() { synchronized(lock) { ; } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new SynchronizedOnThisRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/VolatileArrayFieldRuleTest.groovy�������0000644�0001750�0001750�00000010141�12041642700�032057� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for VolatileArrayFieldRule * * @author Hamlet D'Arcy */ class VolatileArrayFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'VolatileArrayField' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { private Object[] field1 = value() def field2 = value as Object[] def field3 = (Object[])value } ''' assertNoViolations(SOURCE) } @Test void testDeclarationType() { final SOURCE = ''' class MyClass { private volatile Object[] field1 = value() } ''' assertSingleViolation(SOURCE, 3, 'private volatile Object[] field1', 'The array field field1 is marked volatile, but the contents of the array will not share the same volatile semantics. Use a different data type') } @Test void testDeclarationType2() { final SOURCE = ''' class MyClass { private volatile UnknownClass[] field1 = value() } ''' assertSingleViolation(SOURCE, 3, 'private volatile UnknownClass[] field1', 'The array field field1 is marked volatile, but the contents of the array will not share the same volatile semantics. Use a different data type') } @Test void testCastAsType() { final SOURCE = ''' class MyClass { volatile field2 = value as Object[] } ''' assertSingleViolation(SOURCE, 3, 'volatile field2 = value as Object[]', 'The array field field2 is marked volatile, but the contents of the array will not share the same volatile semantics. Use a different data type') } @Test void testCastAsType2() { final SOURCE = ''' class MyClass { volatile field2 = value as UnknownClass[] } ''' assertSingleViolation(SOURCE, 3, 'volatile field2 = value as UnknownClass[]', 'The array field field2 is marked volatile, but the contents of the array will not share the same volatile semantics. Use a different data type') } @Test void testCastType() { final SOURCE = ''' class MyClass { volatile field3 = (Object[])value } ''' assertSingleViolation(SOURCE, 3, 'volatile field3 = (Object[])value', 'The array field field3 is marked volatile, but the contents of the array will not share the same volatile semantics. Use a different data type') } @Test void testCastType2() { final SOURCE = ''' class MyClass { volatile field3 = (UnknownClass[])value } ''' assertSingleViolation(SOURCE, 3, 'volatile field3 = (UnknownClass[])value', 'The array field field3 is marked volatile, but the contents of the array will not share the same volatile semantics. Use a different data type') } protected Rule createRule() { new VolatileArrayFieldRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/StaticSimpleDateFormatFieldRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/StaticSimpleDateFormatFieldRuleTest.groo0000644�0001750�0001750�00000010054�12041642700�033275� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for StaticSimpleDateFormatFieldRule * * @author Chris Mair */ class StaticSimpleDateFormatFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'StaticSimpleDateFormatField' } @Test void testSuccessScenario() { final SOURCE = ''' // these usages are OK class MyCorrectClass { private final SimpleDateFormat dateFormat1 static ThreadLocal<SimpleDateFormat> dateFormat2 static object = new Object() public static final VALUE = 1234 } ''' assertNoViolations(SOURCE) } @Test void testStaticField() { final SOURCE = ''' class MyClass { static SimpleDateFormat dateFormat } ''' assertSingleViolation(SOURCE, 3, 'static SimpleDateFormat dateFormat', 'SimpleDateFormat instances are not thread safe. Wrap the SimpleDateFormat field dateFormat in a ThreadLocal or make it an instance field') } @Test void testStaticFieldFullyQualifiedName() { final SOURCE = ''' class MyClass { static java.text.SimpleDateFormat dateFormat } ''' assertSingleViolation(SOURCE, 3, 'static java.text.SimpleDateFormat dateFormat', 'SimpleDateFormat instances are not thread safe. Wrap the SimpleDateFormat field dateFormat in a ThreadLocal or make it an instance field') } @Test void testStaticUntypedField_InitializesValueToDateFormat() { final SOURCE = ''' class MyClass { static final DATE1 = new SimpleDateFormat() static final DATE2 = new SimpleDateFormat('MM/dd') static final DATE3 = new SimpleDateFormat('MM/dd', DateFormatSymbols.instance) static date4 = new SimpleDateFormat('MM/dd', Locale.FRANCE) static date5 = new java.text.SimpleDateFormat('MM/dd') } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'static final DATE1 = new SimpleDateFormat()', messageText:['SimpleDateFormat', 'DATE1']], [lineNumber:4, sourceLineText:"static final DATE2 = new SimpleDateFormat('MM/dd')", messageText:['SimpleDateFormat', 'DATE2']], [lineNumber:5, sourceLineText:"static final DATE3 = new SimpleDateFormat('MM/dd', DateFormatSymbols.instance)", messageText:['SimpleDateFormat', 'DATE3']], [lineNumber:6, sourceLineText:"static date4 = new SimpleDateFormat('MM/dd', Locale.FRANCE)", messageText:['SimpleDateFormat', 'date4']], [lineNumber:7, sourceLineText:"static date5 = new java.text.SimpleDateFormat('MM/dd')", messageText:['SimpleDateFormat', 'date5']] ) } @Test void testNonStaticFieldWithSimpleDateFormatInitializer() { final SOURCE = ''' class MyClass { final SimpleDateFormat filenameDateFormat = new SimpleDateFormat("yyyyMMdd") def anotherFormat = new SimpleDateFormat("yyyyMMdd") } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new StaticSimpleDateFormatFieldRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedMethodRuleTest.groovy�������0000644�0001750�0001750�00000003465�12041642700�032170� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SynchronizedMethodRule * * @author Hamlet D'Arcy */ class SynchronizedMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SynchronizedMethod' } @Test void testApplyTo_Violation() { final SOURCE = ''' class SynchronizedMethodRuleTestClass1 { synchronized def syncMethod1() {} def method2() {} synchronized def syncMethod3() {} def method4() {} } ''' assertTwoViolations(SOURCE, 3, 'synchronized def syncMethod1() {}', 5, 'synchronized def syncMethod3() {}') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class SynchronizedMethodRuleTestClass2 { def myMethod() {} }''' assertNoViolations(SOURCE) } protected Rule createRule() { new SynchronizedMethodRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/DoubleCheckedLockingRuleTest.groovy�����0000644�0001750�0001750�00000011622�12041642700�032332� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DoubleCheckedLockingRule * * @author 'Hamlet D'Arcy' */ class DoubleCheckedLockingRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DoubleCheckedLocking' } @Test void testSuccessScenario() { final SOURCE = ''' def result = object if (result == null) { synchronized(this) { result = object if (result == null) object = result = createObject() } } // and a better solution for a singleton: class myClass { private static class ObjectHolder { public static Object object = createObject() } public static Object getObject() { return ObjectHolder.object } } if (object1 == null) { synchronized(this) { if (object1 == null) { object2 = createObject() } } } if (object == 5) { synchronized(this) { if (object == null) { object = createObject() } } } if (object == 5) { synchronized(this) { if (5 == object) { object = createObject() } } } if (object == 5) { synchronized(this) { if (object == null) { x = createObject() } } } if (object == 5) { synchronized(this) { if (object == null) { doSomething() object = createObject() } } } if (object == 5) { synchronized(this) { doSomething() if (object == null) { object = createObject() } } } if (object == 5) { doSomething() synchronized(this) { if (object == null) { object = createObject() } } } ''' assertNoViolations(SOURCE) } @Test void testPlainViolation() { final SOURCE = ''' if (object == null) { synchronized(this) { if (object == null) { object = createObject() } } } ''' assertSingleViolation(SOURCE, 5, 'object = createObject()', 'Double checked locking detected for variable object. replace with more robust lazy initialization') } @Test void testBackwardIfViolations() { final SOURCE = ''' if (null == object) { synchronized(this) { if (null == object) { object = createObject() } } } ''' assertSingleViolation(SOURCE, 5, 'object = createObject()', 'Double checked locking detected for variable object. replace with more robust lazy initialization') } @Test void testNoCompare() { final SOURCE = ''' if (!object) { synchronized(this) { if (!object) { object = createObject() } } } ''' assertSingleViolation(SOURCE, 5, 'object = createObject()', 'Double checked locking detected for variable object. replace with more robust lazy initialization') } protected Rule createRule() { new DoubleCheckedLockingRule() } } ��������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedOnStringRuleTest.groovy�����0000644�0001750�0001750�00000013645�12041642700�032514� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SynchronizedOnStringRule * * @author Hamlet D'Arcy */ class SynchronizedOnStringRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SynchronizedOnString' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass1 { final Object lock = new Object[0] def method() { synchronized(lock) { } } class MyInnerClass { def method() { synchronized(lock) { } } } } class MyClass2 { final def lock = new Object[0] def method() { synchronized(lock) { } } } class MyClass3 { final def lock = new Object[0] // correct idiom def method() { return new Runnable() { public void run() { synchronized(lock) { } } } } } class MyClass4 { final def lock = "" class MyInnerClass { final def lock = new Object[0] // shadows parent from inner class def method() { synchronized(lock) { } } } } ''' assertNoViolations(SOURCE) } @Test void testStringField() { final SOURCE = ''' class MyClass5 { final String lock = someMethod() // not interned, but quite possibly is def method() { synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 5, 'synchronized(lock)', 'Synchronizing on the constant String field lock is unsafe. Do not synchronize on interned strings') } @Test void testBasicViolation() { final SOURCE = ''' class MyClass { final String stringLock = "stringLock" def method() { synchronized(stringLock) { } } } ''' assertSingleViolation(SOURCE, 7, 'synchronized(stringLock)', 'Synchronizing on the constant String field stringLock is unsafe. Do not synchronize on interned strings') } @Test void testInnerClass() { final SOURCE = ''' class MyClass { final String stringLock = "stringLock" class MyInnerClass { def method() { // violation synchronized(stringLock) { } } } } ''' assertSingleViolation(SOURCE, 9, 'synchronized(stringLock)', 'Synchronizing on the constant String field stringLock is unsafe. Do not synchronize on interned strings') } @Test void testImplicitTyping() { final SOURCE = ''' class MyClass { // implicit typing final def stringLock = "stringLock" def method() { // violation synchronized(stringLock) { } } } ''' assertSingleViolation(SOURCE, 8, 'synchronized(stringLock)', 'Synchronizing on the constant String field stringLock is unsafe. Do not synchronize on interned strings') } @Test void testAnonymousClass() { final SOURCE = ''' class MyClass { // implicit typing final def lock = new Object[0] // correct idiom def method() { return new Runnable() { final def lock = "" // shadows parent from inner class public void run() { // violation synchronized(lock) { } } } } } ''' assertSingleViolation(SOURCE, 11, 'synchronized(lock)', 'Synchronizing on the constant String field lock is unsafe. Do not synchronize on interned strings') } @Test void testShadowing() { final SOURCE = ''' class MyClass { // implicit typing final def lock = new Object[0] // correct idiom class MyInnerClass { final def lock = "" // shadows parent from inner class def method() { // violation synchronized(lock) { } } } } ''' assertSingleViolation(SOURCE, 11, 'synchronized(lock)', 'Synchronizing on the constant String field lock is unsafe. Do not synchronize on interned strings') } protected Rule createRule() { new SynchronizedOnStringRule() } } �������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedOnBoxedPrimitiveRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedOnBoxedPrimitiveRuleTest.gro0000644�0001750�0001750�00000053253�12311370173�033443� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SynchronizedOnBoxedPrimitiveRule * * @author Hamlet D'Arcy */ class SynchronizedOnBoxedPrimitiveRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SynchronizedOnBoxedPrimitive' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass1 { final Object lock = new Object[0] def method() { synchronized(lock) { } } class MyInnerClass { def method() { synchronized(lock) { } } } } class MyClass2 { final def lock = new Object[0] def method() { synchronized(lock) { } } } class MyClass3 { final def lock = new Object[0] // correct idiom def method() { return new Runnable() { public void run() { synchronized(lock) { } } } } } class MyClass4 { final def lock = true class MyInnerClass { final def lock = new Object[0] // shadows parent from inner class def method() { synchronized(lock) { } } } } ''' assertNoViolations(SOURCE) } @Test void testReferenceTypeDeclaration() { final SOURCE = ''' class MyClass { Byte byte1 = 100 Short short1 = 1 Double double1 = 1 Integer integer1 = 1 Long long1 = 1 Float float1 = 1 Character char1 = 1 def method() { synchronized(byte1) {} synchronized(short1) {} synchronized(double1) {} synchronized(integer1) {} synchronized(long1) {} synchronized(float1) {} synchronized(char1) {} } } ''' assertViolations(SOURCE, [lineNumber: 12, sourceLineText: 'synchronized(byte1)', messageText: 'Synchronizing on the Byte field byte1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 13, sourceLineText: 'synchronized(short1)', messageText: 'Synchronizing on the Short field short1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 14, sourceLineText: 'synchronized(double1)', messageText: 'Synchronizing on the Double field double1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 15, sourceLineText: 'synchronized(integer1)', messageText: 'Synchronizing on the Integer field integer1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 16, sourceLineText: 'synchronized(long1)', messageText: 'Synchronizing on the Long field long1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 17, sourceLineText: 'synchronized(float1)', messageText: 'Synchronizing on the Float field float1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 18, sourceLineText: 'synchronized(char1)', messageText: 'Synchronizing on the Character field char1 is unsafe. Do not synchronize on boxed types']) } @Test void testPrimitiveTypeDeclaration() { final SOURCE = ''' class MyClass { byte byte2 = getValue() short short2 = getValue() double double2 = getValue() int integer2 = getValue() long long2 = getValue() float float2 = getValue() char char2 = getValue() def method() { synchronized(byte2) {} synchronized(short2) {} synchronized(double2) {} synchronized(integer2) {} synchronized(long2) {} synchronized(float2) {} synchronized(char2) {} } } ''' assertViolations(SOURCE, [lineNumber: 12, sourceLineText: 'synchronized(byte2)', messageText: 'Synchronizing on the Byte field byte2 is unsafe. Do not synchronize on boxed types'], [lineNumber: 13, sourceLineText: 'synchronized(short2)', messageText: 'Synchronizing on the Short field short2 is unsafe. Do not synchronize on boxed types'], [lineNumber: 14, sourceLineText: 'synchronized(double2)', messageText: 'Synchronizing on the Double field double2 is unsafe. Do not synchronize on boxed types'], [lineNumber: 15, sourceLineText: 'synchronized(integer2)', messageText: 'Synchronizing on the Integer field integer2 is unsafe. Do not synchronize on boxed types'], [lineNumber: 16, sourceLineText: 'synchronized(long2)', messageText: 'Synchronizing on the Long field long2 is unsafe. Do not synchronize on boxed types'], [lineNumber: 17, sourceLineText: 'synchronized(float2)', messageText: 'Synchronizing on the Float field float2 is unsafe. Do not synchronize on boxed types'], [lineNumber: 18, sourceLineText: 'synchronized(char2)', messageText: 'Synchronizing on the Character field char2 is unsafe. Do not synchronize on boxed types']) } @Test void testReferenceInstanceDeclaration() { final SOURCE = ''' class MyClass { def byte3 = new Byte((byte)100) def short3 = new Short((short)1) def double3 = new Double((double)1) def integer3 = new Integer(1) def long3 = new Long(1) def float3 = new Float(1) def char3 = new Character((char)'1') def method() { synchronized(byte3) {} synchronized(short3) {} synchronized(double3) {} synchronized(integer3) {} synchronized(long3) {} synchronized(float3) {} synchronized(char3) {} } } ''' assertViolations(SOURCE, [lineNumber: 12, sourceLineText: 'synchronized(byte3)', messageText: 'Synchronizing on the Byte field byte3 is unsafe. Do not synchronize on boxed types'], [lineNumber: 13, sourceLineText: 'synchronized(short3)', messageText: 'Synchronizing on the Short field short3 is unsafe. Do not synchronize on boxed types'], [lineNumber: 14, sourceLineText: 'synchronized(double3)', messageText: 'Synchronizing on the Double field double3 is unsafe. Do not synchronize on boxed types'], [lineNumber: 15, sourceLineText: 'synchronized(integer3)', messageText: 'Synchronizing on the Integer field integer3 is unsafe. Do not synchronize on boxed types'], [lineNumber: 16, sourceLineText: 'synchronized(long3)', messageText: 'Synchronizing on the Long field long3 is unsafe. Do not synchronize on boxed types'], [lineNumber: 17, sourceLineText: 'synchronized(float3)', messageText: 'Synchronizing on the Float field float3 is unsafe. Do not synchronize on boxed types'], [lineNumber: 18, sourceLineText: 'synchronized(char3)', messageText: 'Synchronizing on the Character field char3 is unsafe. Do not synchronize on boxed types']) } @Test void testPrimitiveCastDeclaration() { final SOURCE = ''' class MyClass { def byte4 = 1 as byte def short4 = 1 as short def double4 = 1 as double def integer4 = 1 as int def long4 = 1 as long def float4 = 1 as float def char4 = 1 as char def method() { synchronized(byte4) {} synchronized(short4) {} synchronized(double4) {} synchronized(integer4) {} synchronized(long4) {} synchronized(float4) {} synchronized(char4) {} } } ''' assertViolations(SOURCE, [lineNumber: 12, sourceLineText: 'synchronized(byte4)', messageText: 'Synchronizing on the Byte field byte4 is unsafe. Do not synchronize on boxed types'], [lineNumber: 13, sourceLineText: 'synchronized(short4)', messageText: 'Synchronizing on the Short field short4 is unsafe. Do not synchronize on boxed types'], [lineNumber: 14, sourceLineText: 'synchronized(double4)', messageText: 'Synchronizing on the Double field double4 is unsafe. Do not synchronize on boxed types'], [lineNumber: 15, sourceLineText: 'synchronized(integer4)', messageText: 'Synchronizing on the Integer field integer4 is unsafe. Do not synchronize on boxed types'], [lineNumber: 16, sourceLineText: 'synchronized(long4)', messageText: 'Synchronizing on the Long field long4 is unsafe. Do not synchronize on boxed types'], [lineNumber: 17, sourceLineText: 'synchronized(float4)', messageText: 'Synchronizing on the Float field float4 is unsafe. Do not synchronize on boxed types'], [lineNumber: 18, sourceLineText: 'synchronized(char4)', messageText: 'Synchronizing on the Character field char4 is unsafe. Do not synchronize on boxed types']) } @Test void testReferenceCastDeclaration() { final SOURCE = ''' class MyClass { def byte5 = 1 as Byte def short5 = 1 as Short def double5 = 1 as Double def integer5 = 1 as Integer def long5 = 1 as Long def float5 = 1 as Float def char5 = 1 as Character def method() { synchronized(byte5) {} synchronized(short5) {} synchronized(double5) {} synchronized(integer5) {} synchronized(long5) {} synchronized(float5) {} synchronized(char5) {} } } ''' assertViolations(SOURCE, [lineNumber: 12, sourceLineText: 'synchronized(byte5)', messageText: 'Synchronizing on the Byte field byte5 is unsafe. Do not synchronize on boxed types'], [lineNumber: 13, sourceLineText: 'synchronized(short5)', messageText: 'Synchronizing on the Short field short5 is unsafe. Do not synchronize on boxed types'], [lineNumber: 14, sourceLineText: 'synchronized(double5)', messageText: 'Synchronizing on the Double field double5 is unsafe. Do not synchronize on boxed types'], [lineNumber: 15, sourceLineText: 'synchronized(integer5)', messageText: 'Synchronizing on the Integer field integer5 is unsafe. Do not synchronize on boxed types'], [lineNumber: 16, sourceLineText: 'synchronized(long5)', messageText: 'Synchronizing on the Long field long5 is unsafe. Do not synchronize on boxed types'], [lineNumber: 17, sourceLineText: 'synchronized(float5)', messageText: 'Synchronizing on the Float field float5 is unsafe. Do not synchronize on boxed types'], [lineNumber: 18, sourceLineText: 'synchronized(char5)', messageText: 'Synchronizing on the Character field char5 is unsafe. Do not synchronize on boxed types']) } @Test void testPrimitiveJava5StyleCastDeclaration() { final SOURCE = ''' class MyClass { def byte7 = (byte)1 def short7 = (short)1 def double7 = (double)1 def integer7 = (int)1 def long7 = (long)1 def float7 = (float)1 def char7 = (char)1 def method() { synchronized(byte7) {} synchronized(short7) {} synchronized(double7) {} synchronized(integer7) {} synchronized(long7) {} synchronized(float7) {} synchronized(char7) {} } } ''' assertViolations(SOURCE, [lineNumber: 12, sourceLineText: 'synchronized(byte7)', messageText: 'Synchronizing on the Byte field byte7 is unsafe. Do not synchronize on boxed types'], [lineNumber: 13, sourceLineText: 'synchronized(short7)', messageText: 'Synchronizing on the Short field short7 is unsafe. Do not synchronize on boxed types'], [lineNumber: 14, sourceLineText: 'synchronized(double7)', messageText: 'Synchronizing on the Double field double7 is unsafe. Do not synchronize on boxed types'], [lineNumber: 15, sourceLineText: 'synchronized(integer7)', messageText: 'Synchronizing on the Integer field integer7 is unsafe. Do not synchronize on boxed types'], [lineNumber: 16, sourceLineText: 'synchronized(long7)', messageText: 'Synchronizing on the Long field long7 is unsafe. Do not synchronize on boxed types'], [lineNumber: 17, sourceLineText: 'synchronized(float7)', messageText: 'Synchronizing on the Float field float7 is unsafe. Do not synchronize on boxed types'], [lineNumber: 18, sourceLineText: 'synchronized(char7)', messageText: 'Synchronizing on the Character field char7 is unsafe. Do not synchronize on boxed types']) } @Test void testLiteralDeclaration() { final SOURCE = ''' class MyClass { def integer1 = 5I def integer2 = 5 def long1 = 5L def double1 = 1d def float1 = 5F def method() { synchronized(integer1) {} synchronized(integer2) {} synchronized(long1) {} synchronized(double1) {} synchronized(float1) {} } } ''' assertViolations(SOURCE, [lineNumber: 10, sourceLineText: 'synchronized(integer1)', messageText: 'Synchronizing on the Integer field integer1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 11, sourceLineText: 'synchronized(integer2)', messageText: 'Synchronizing on the Integer field integer2 is unsafe. Do not synchronize on boxed types'], [lineNumber: 12, sourceLineText: 'synchronized(long1)', messageText: 'Synchronizing on the Long field long1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 13, sourceLineText: 'synchronized(double1)', messageText: 'Synchronizing on the Double field double1 is unsafe. Do not synchronize on boxed types'], [lineNumber: 14, sourceLineText: 'synchronized(float1)', messageText: 'Synchronizing on the Float field float1 is unsafe. Do not synchronize on boxed types']) } @Test void testBooleanSuccessScenario() { final SOURCE = ''' class MyClass1 { final Object lock = new Object[0] def method() { synchronized(lock) { } } class MyInnerClass { def method() { synchronized(lock) { } } } } class MyClass2 { final def lock = new Object[0] def method() { synchronized(lock) { } } } class MyClass3 { final def lock = new Object[0] // correct idiom def method() { return new Runnable() { public void run() { synchronized(lock) { } } } } } class MyClass4 { final def lock = true class MyInnerClass { final def lock = new Object[0] // shadows parent from inner class def method() { synchronized(lock) { } } } } ''' assertNoViolations(SOURCE) } @Test void testBoolPrimitiveField() { final SOURCE = ''' class MyClass5 { final boolean lock = someMethod() // not interned, but quite possibly is def method() { synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 5, 'synchronized(lock)', 'Synchronizing on the Boolean field lock is unsafe. Do not synchronize on boxed types') } @Test void testBoolField() { final SOURCE = ''' class MyClass5 { final Boolean lock = someMethod() // not interned, but quite possibly is def method() { synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 5, 'synchronized(lock)', 'Synchronizing on the Boolean field lock is unsafe. Do not synchronize on boxed types') } @Test void testBasicViolation() { final SOURCE = ''' class MyClass { final boolean lock = true def method() { synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 7, 'synchronized(lock)', 'Synchronizing on the Boolean field lock is unsafe. Do not synchronize on boxed types') } @Test void testInnerClass() { final SOURCE = ''' class MyClass { final Boolean boollock = true class MyInnerClass { def method() { // violation synchronized(boollock) { } } } } ''' assertSingleViolation(SOURCE, 9, 'synchronized(boollock)', 'Synchronizing on the Boolean field boollock is unsafe. Do not synchronize on boxed types') } @Test void testImplicitTyping() { final SOURCE = ''' class MyClass { // implicit typing final def lock = true def method() { // violation synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 8, 'synchronized(lock)', 'Synchronizing on the Boolean field lock is unsafe. Do not synchronize on boxed types') } @Test void testAnonymousClass() { final SOURCE = ''' class MyClass { // implicit typing final def lock = new Object[0] // correct idiom def method() { return new Runnable() { final def lock = false // shadows parent from inner class public void run() { // violation synchronized(lock) { } } } } } ''' assertSingleViolation(SOURCE, 11, 'synchronized(lock)', 'Synchronizing on the Boolean field lock is unsafe. Do not synchronize on boxed types') } @Test void testShadowing() { final SOURCE = ''' class MyClass { // implicit typing final def lock = new Object[0] // correct idiom class MyInnerClass { final def lock = true // shadows parent from inner class def method() { // violation synchronized(lock) { } } } } ''' assertSingleViolation(SOURCE, 11, 'synchronized(lock)', 'Synchronizing on the Boolean field lock is unsafe. Do not synchronize on boxed types') } protected Rule createRule() { new SynchronizedOnBoxedPrimitiveRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/StaticConnectionRuleTest.groovy���������0000644�0001750�0001750�00000003337�12041642700�031615� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for StaticConnectionRule * * @author 'Hamlet D'Arcy' */ class StaticConnectionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'StaticConnection' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { Connection conn } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass { static Connection conn } ''' assertSingleViolation(SOURCE, 3, 'static Connection conn', 'Violation in class MyClass. The field conn is marked static, meaning the Connection will be shared between threads and will possibly experience race conditions') } protected Rule createRule() { new StaticConnectionRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/StaticMatcherFieldRuleTest.groovy�������0000644�0001750�0001750�00000004234�12041642700�032042� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for StaticMatcherFieldRule * * @author Hamlet D'Arcy */ class StaticMatcherFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'StaticMatcherField' } @Test void testSuccessScenario() { final SOURCE = ''' // these usages are OK class MyCorrectClass { private Matcher matcher1 static ThreadLocal<Matcher> matcher2 } ''' assertNoViolations(SOURCE) } @Test void testStaticField() { final SOURCE = ''' class MyClass { static Matcher matcher1 } ''' assertSingleViolation(SOURCE, 3, 'static Matcher matcher1', 'Matcher instances are not thread safe. Wrap the Matcher field matcher1 in a ThreadLocal or make it an instance field') } @Test void testStaticFieldFullyQUalifiedName() { final SOURCE = ''' class MyClass { static java.util.regex.Matcher matcher2 } ''' assertSingleViolation(SOURCE, 3, 'static java.util.regex.Matcher matcher2', 'Matcher instances are not thread safe. Wrap the Matcher field matcher2 in a ThreadLocal or make it an instance field') } protected Rule createRule() { new StaticMatcherFieldRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000153�00000000000�011602� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/ThisReferenceEscapesConstructorRuleTest.groovy����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/ThisReferenceEscapesConstructorRuleTest.0000644�0001750�0001750�00000005210�12311373552�033376� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThisReferenceEscapesConstructorRule * * @author Artur Gajowy */ class ThisReferenceEscapesConstructorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThisReferenceEscapesConstructor' } @Test void testNoViolations() { final SOURCE = ''' class Valid { Integer value Valid() { this.value = 42 } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class Invalid { Invalid() { What.ever(this) } } ''' assertSingleViolation(SOURCE, 4, 'What.ever(this)', VIOLATION_MESSAGE) } @Test void testMultipleViolations() { final SOURCE = ''' class EventListener { EventListener(EventPublisher publisher) { publisher.register(this) new WorkThread(publisher, this).start() new AnotherWorkThread(listener: this) } } ''' assertViolations(SOURCE, [lineNumber: 4, sourceLineText: 'publisher.register(this)', messageText: VIOLATION_MESSAGE], [lineNumber: 5, sourceLineText: 'new WorkThread(publisher, this)', messageText: VIOLATION_MESSAGE], [lineNumber: 6, sourceLineText: 'new AnotherWorkThread(listener: this)', messageText: VIOLATION_MESSAGE]) } private static final String VIOLATION_MESSAGE = 'The `this` reference escapes constructor.' + ' This equals exposing a half-baked object and can lead to race conditions.' protected Rule createRule() { new ThisReferenceEscapesConstructorRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000157�00000000000�011606� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/InconsistentPropertySynchronizationRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/InconsistentPropertySynchronizationRuleT0000644�0001750�0001750�00000020024�12041642700�033645� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for InconsistentPropertySynchronizationRule * * @author 'Hamlet D'Arcy' */ class InconsistentPropertySynchronizationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'InconsistentPropertySynchronization' } @Test void testSuccessScenario() { final SOURCE = ''' class Person { String name Date birthday boolean deceased boolean parent synchronized setName(String name) { this.name = name } synchronized String getName() { name } void setBirthday(Date birthday) { this.birthday = birthday } String getBirthday() { birthday } synchronized void setDeceased(boolean deceased) { this.deceased = deceased } synchronized boolean isDeceased() { deceased } synchronized void setParent(boolean parent) { this.parent = parent } synchronized boolean isParent() { parent } } ''' assertNoViolations(SOURCE) } @Test void testUnsynchronizedStringGetMethod() { final SOURCE = ''' class Person { String name synchronized setName(String name) { this.name = name } // violation, get method should be synchronized String getName() { name } } ''' assertSingleViolation(SOURCE, 9, 'String getName()', 'The setter method setName is synchronized but the getter method getName is not') } @Test void testUnsynchronizedDateSetMethod() { final SOURCE = ''' class Person { Date birthday // violation, set method should be synchronized void setBirthday(Date birthday) { this.birthday = birthday } synchronized String getBirthday() { birthday } } ''' assertSingleViolation(SOURCE, 6, 'void setBirthday', 'The getter method getBirthday is synchronized but the setter method setBirthday is not') } @Test void testUnsynchronizedBooleanSetMethod() { final SOURCE = ''' class Person { boolean deceased // violation, set method should be synchronized void setDeceased(boolean deceased) { this.deceased = deceased } synchronized boolean isDeceased() { deceased } } ''' assertSingleViolation(SOURCE, 6, 'void setDeceased(', 'The getter method isDeceased is synchronized but the setter method setDeceased is not') } @Test void testUnsynchronizedBooleanGetMethod() { final SOURCE = ''' class Person { boolean parent synchronized void setParent(boolean parent) { this.parent = parent } // violation, get method should be synchronized boolean isParent() { parent } } ''' assertSingleViolation(SOURCE, 10, 'boolean isParent()', 'The setter method setParent is synchronized but the getter method isParent is not') } @Test void testSyncedSetterMissingGetter() { final SOURCE = ''' class Person { String name List addresses synchronized void setAddresses(List addresses) { this.addresses.clear() this.addresses.addAll(addresses) } }''' assertSingleViolation(SOURCE, 6, 'synchronized void setAddresses', 'The setter method setAddresses is synchronized but the getter method [getAddresses, isAddresses] is not') } @Test void testSyncedGetterMissingSetter() { final SOURCE = ''' class Person { String name List addresses synchronized List getAddresses() { addresses } }''' assertSingleViolation(SOURCE, 6, 'synchronized List getAddresses', 'The getter method getAddresses is synchronized but the setter method setAddresses is not') } @Test void testAtSyncedGetterMissingSetter_FullyQualified() { final SOURCE = ''' class Person { String name List addresses @groovy.transform.Synchronized List getAddresses() { addresses } }''' assertSingleViolation(SOURCE, 6, '@groovy.transform.Synchronized List getAddresses()', 'The getter method getAddresses is synchronized but the setter method setAddresses is not') } @Test void testAtSyncedGetterMissingSetter() { final SOURCE = ''' import groovy.transform.* class Person { String name List addresses @Synchronized List getAddresses() { addresses } }''' assertSingleViolation(SOURCE, 8, '@Synchronized List getAddresses()', 'The getter method getAddresses is synchronized but the setter method setAddresses is not') } /** * In this test there is no Properties property, so synchronizing on getProperties is OK because there is never a setter. */ @Test void testFalsePositiveOnGetter() { final SOURCE = ''' class DbConfigurationProperties { String dbConfigurationFile private synchronized Object getA() { null } } ''' assertNoViolations(SOURCE) } @Test void testFalsePositiveOnSetter() { final SOURCE = ''' class DbConfigurationProperties { String dbConfigurationFile private synchronized void setProperties(Properties p) { } } ''' assertNoViolations(SOURCE) } @Test void testFalsePositiveOnIzzer() { final SOURCE = ''' class DbConfigurationProperties { String dbConfigurationFile private synchronized boolean isProperties() { true } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new InconsistentPropertySynchronizationRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/InconsistentPropertyLockingRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/InconsistentPropertyLockingRuleTest.groo0000644�0001750�0001750�00000011545�12041642700�033523� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for InconsistentPropertyLockingRule * * @author Hamlet D'Arcy */ class InconsistentPropertyLockingRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'InconsistentPropertyLocking' } @Test void testSuccessScenario() { final SOURCE = ''' class Person { String name Date birthday boolean deceased boolean parent @WithWriteLock setName(String name) { this.name = name } @groovy.transform.WithReadLock String getName() { name } void setBirthday(Date birthday) { this.birthday = birthday } String getBirthday() { birthday } @groovy.transform.WithWriteLock void setDeceased(boolean deceased) { this.deceased = deceased } @WithReadLock boolean isDeceased() { deceased } @WithWriteLock void setParent(boolean parent) { this.parent = parent } @WithReadLock boolean isParent() { parent } } ''' assertNoViolations(SOURCE) } @Test void testWriteLockStringGetMethod() { final SOURCE = ''' class Person { String name @WithWriteLock setName(String name) { this.name = name } // violation, get method should be locked String getName() { name } } ''' assertSingleViolation(SOURCE, 9, 'String getName()', 'The setter method setName is marked @WithWriteLock but the getter method getName is not locked') } @Test void testReadLockDateSetMethod() { final SOURCE = ''' class Person { Date birthday // violation, set method should be locked void setBirthday(Date birthday) { this.birthday = birthday } @groovy.transform.WithReadLock String getBirthday() { birthday } } ''' assertSingleViolation(SOURCE, 6, 'void setBirthday', 'The getter method getBirthday is marked @WithReadLock but the setter method setBirthday is not locked') } @Test void testLockedBooleanSetMethod() { final SOURCE = ''' class Person { boolean deceased // violation, set method should be locked void setDeceased(boolean deceased) { this.deceased = deceased } @WithReadLock boolean isDeceased() { deceased } } ''' assertSingleViolation(SOURCE, 6, 'void setDeceased(', 'The getter method isDeceased is marked @WithReadLock but the setter method setDeceased is not locked') } @Test void testWriteLockBooleanGetMethod() { final SOURCE = ''' class Person { boolean parent @groovy.transform.WithWriteLock void setParent(boolean parent) { this.parent = parent } // violation, get method should be locked boolean isParent() { parent } } ''' assertSingleViolation(SOURCE, 10, 'boolean isParent()', 'The setter method setParent is marked @WithWriteLock but the getter method isParent is not locked') } protected Rule createRule() { new InconsistentPropertyLockingRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/ThreadGroupRuleTest.groovy��������������0000644�0001750�0001750�00000005236�12041642700�030572� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThreadGroupRule * * @author Hamlet D'Arcy */ class ThreadGroupRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThreadGroup' } @Test void testSuccessScenario() { final SOURCE = ''' getThreadGroup('...') // a parameter means it must not be a getter. ''' assertNoViolations(SOURCE) } @Test void testConstructors() { final SOURCE = ''' new ThreadGroup("...") ''' assertSingleViolation(SOURCE, 2, 'new ThreadGroup("...")', 'Avoid using java.lang.ThreadGroup; it is unsafe') } @Test void testConstructorsFullyQualified() { final SOURCE = ''' new java.lang.ThreadGroup("...") ''' assertSingleViolation(SOURCE, 2, 'new java.lang.ThreadGroup("...")', 'Avoid using java.lang.ThreadGroup; it is unsafe') } @Test void testConstructors2() { final SOURCE = ''' new ThreadGroup(tg, "my thread group") ''' assertSingleViolation(SOURCE, 2, 'new ThreadGroup(tg, "my thread group")', 'Avoid using java.lang.ThreadGroup; it is unsafe') } @Test void testFromCurrentThread() { final SOURCE = ''' Thread.currentThread().getThreadGroup() ''' assertSingleViolation(SOURCE, 2, 'Thread.currentThread().getThreadGroup()', 'Avoid using java.lang.ThreadGroup; it is unsafe') } @Test void testFromSecurityManager() { final SOURCE = ''' System.getSecurityManager().getThreadGroup() ''' assertSingleViolation(SOURCE, 2, 'System.getSecurityManager().getThreadGroup()', 'Avoid using java.lang.ThreadGroup; it is unsafe') } protected Rule createRule() { new ThreadGroupRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000150�00000000000�011577� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedReadObjectMethodRuleTest.groovy�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedReadObjectMethodRuleTest.gro0000644�0001750�0001750�00000006312�12041642700�033347� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SynchronizedReadObjectMethodRule * * @author Hamlet D'Arcy */ class SynchronizedReadObjectMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SynchronizedReadObjectMethod' } @Test void testSuccessScenario() { final SOURCE = ''' // OK, class not Serializable class MyClass1 { private synchronized void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { } } // OK, class not Serializable class MyClass2 { private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { synchronized(lock) { } } } // OK, Synchronized block is sufficiently advanced class MyClass3 { private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { synchronized(lock) { } doSomething() } } ''' assertNoViolations(SOURCE) } @Test void testSynchronizedMethod() { final SOURCE = ''' class MyClass implements Serializable { private synchronized void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { // violation, no need to synchronized } } ''' assertSingleViolation(SOURCE, 4, 'synchronized void readObject', 'The Serializable class MyClass has a synchronized readObject method. It is normally unnecesary to synchronize within deserializable') } @Test void testSynchronizedBlock() { final SOURCE = ''' class MyClass implements Serializable { private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { synchronized(lock) { // violation, no need to synchronized } } } ''' assertSingleViolation(SOURCE, 5, 'synchronized(lock)', 'The Serializable class MyClass has a synchronized readObject method. It is normally unnecesary to synchronize within deserializable') } protected Rule createRule() { new SynchronizedReadObjectMethodRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/StaticCalendarFieldRuleTest.groovy������0000644�0001750�0001750�00000007017�12041642700�032172� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for StaticCalendarFieldRule * * @author Hamlet D'Arcy * @author Chris Mair */ class StaticCalendarFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'StaticCalendarField' } @Test void testSuccessScenario() { final SOURCE = ''' // these usages are OK class MyCorrectClass { private final Calendar calendar1 static ThreadLocal<Calendar> calendar2 } ''' assertNoViolations(SOURCE) } @Test void testStaticField() { final SOURCE = ''' class MyClass { static Calendar calendar } ''' assertSingleViolation(SOURCE, 3, 'static Calendar calendar', 'Calendar instances are not thread safe. Wrap the Calendar field calendar in a ThreadLocal or make it an instance field') } @Test void testStaticFieldFullyQualifiedName() { final SOURCE = ''' class MyClass { static java.util.Calendar calendar } ''' assertSingleViolation(SOURCE, 3, 'static java.util.Calendar calendar', 'Calendar instances are not thread safe. Wrap the Calendar field calendar in a ThreadLocal or make it an instance field') } @Test void testStaticUntypedField_InitializesValueToCalendar() { final SOURCE = ''' class MyClass { static final CAL1 = Calendar.getInstance() static final CAL2 = Calendar.getInstance(Locale.FRANCE) static def cal3 = Calendar.getInstance(timezone) static Object cal4 = Calendar.getInstance(timezone, locale) } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'static final CAL1 = Calendar.getInstance()', messageText:['Calendar', 'CAL1']], [lineNumber:4, sourceLineText:'static final CAL2 = Calendar.getInstance(Locale.FRANCE)', messageText:['Calendar', 'CAL2']], [lineNumber:5, sourceLineText:'static def cal3 = Calendar.getInstance(timezone)', messageText:['Calendar', 'cal3']], [lineNumber:6, sourceLineText:'static Object cal4 = Calendar.getInstance(timezone, locale)', messageText:['Calendar', 'cal4']], ) } @Test void testNonStaticFieldWithCalendarInitializer() { final SOURCE = ''' class MyClass { final Calendar cal = Calendar.getInstance() def anotherCalendar = Calendar.getInstance(timezone) } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new StaticCalendarFieldRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedOnGetClassRuleTest.groovy���0000644�0001750�0001750�00000004512�12311370173�032746� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SynchronizedOnGetClassRule * * @author Hamlet D'Arcy */ class SynchronizedOnGetClassRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SynchronizedOnGetClass' } @Test void testBadSynchronization() { final SOURCE = ''' class MyClass { def Method1() { synchronized(getClass()) { ; } } } ''' assertSingleViolation(SOURCE, 4, 'synchronized(getClass()) { ; }') } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { def Method1() { synchronized(getFoo()) { ; } } def Method2() { synchronized(MyClass) { ; } } def Method3() { synchronized(String.class) { ; } } }''' assertNoViolations(SOURCE) } @Test void testDoubleMessagesAreNotCreated() { final SOURCE = ''' class C { def m = { synchronized(getClass()) { // ... } } } ''' assertSingleViolation(SOURCE, 4, 'synchronized(getClass())') } protected Rule createRule() { new SynchronizedOnGetClassRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000147�00000000000�011605� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedOnReentrantLockRuleTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SynchronizedOnReentrantLockRuleTest.groo0000644�0001750�0001750�00000014470�12041642700�033437� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SynchronizedOnReentrantLockRule * * @author 'Hamlet D'Arcy' */ class SynchronizedOnReentrantLockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SynchronizedOnReentrantLock' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass1 { final lock = new ReentrantLock() def method() { lock.lock() try { } finally { lock.unlock() } } class MyInnerClass { def method() { lock.lock() try { } finally { lock.unlock() } } } } class MyClass2 { final lock = new ReentrantLock() def method() { lock.lock() try { } finally { lock.unlock() } } } class MyClass3 { final lock = new ReentrantLock() def method() { return new Runnable() { public void run() { lock.lock() try { } finally { lock.unlock() } } } } } class MyClass4 { final lock = new ReentrantLock() class MyInnerClass { final def lock = new Object[0] // shadows parent from inner class def method() { synchronized(lock) { } } } } ''' assertNoViolations(SOURCE) } @Test void testTypeDeclarationInField() { final SOURCE = ''' class MyClass5 { final ReentrantLock lock = value() def method() { synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 5, 'synchronized(lock)', 'Synchronizing on a ReentrantLock field lock. This is almost never the intended usage; use the lock() and unlock() methods instead') } @Test void testFQNViolation() { final SOURCE = ''' class MyClass { final lock = new java.util.concurrent.locks.ReentrantLock() def method() { synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 7, 'synchronized(lock)', 'Synchronizing on a ReentrantLock field lock. This is almost never the intended usage; use the lock() and unlock() methods instead') } @Test void testInnerClass() { final SOURCE = ''' class MyClass { final ReentrantLock lock = (ReentrantLock)"stringLock" class MyInnerClass { def method() { // violation synchronized(lock) { } } } } ''' assertSingleViolation(SOURCE, 9, 'synchronized(lock)', 'Synchronizing on a ReentrantLock field lock. This is almost never the intended usage; use the lock() and unlock() methods instead') } @Test void testImplicitTyping() { final SOURCE = ''' class MyClass { // implicit typing final def lock = "stringLock" as ReentrantLock def method() { // violation synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 8, 'synchronized(lock)', 'Synchronizing on a ReentrantLock field lock. This is almost never the intended usage; use the lock() and unlock() methods instead') } @Test void testAnonymousClass() { final SOURCE = ''' class MyClass { // implicit typing final def lock = new Object[0] // correct idiom def method() { return new Runnable() { final def lock = new ReentrantLock() // shadows parent from inner class public void run() { // violation synchronized(lock) { } } } } } ''' assertSingleViolation(SOURCE, 11, 'synchronized(lock)', 'Synchronizing on a ReentrantLock field lock. This is almost never the intended usage; use the lock() and unlock() methods instead') } @Test void testShadowing() { final SOURCE = ''' class MyClass { // implicit typing final def lock = new Object[0] // correct idiom class MyInnerClass { final lock = value as ReentrantLock // shadows parent from inner class def method() { // violation synchronized(lock) { } } } } ''' assertSingleViolation(SOURCE, 11, 'synchronized(lock)', 'Synchronizing on a ReentrantLock field lock. This is almost never the intended usage; use the lock() and unlock() methods instead') } protected Rule createRule() { new SynchronizedOnReentrantLockRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/SystemRunFinalizersOnExitRuleTest.groovy0000644�0001750�0001750�00000005624�12041642700�033476� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SystemRunFinalizersOnExitRule * * @author Hamlet D'Arcy */ class SystemRunFinalizersOnExitRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SystemRunFinalizersOnExit' } @Test void testApplyTo_Violation_Initializers() { final SOURCE = ''' class SystemRunFinalizersOnExitClass1 { static { System.runFinalizersOnExit(true) } { System.runFinalizersOnExit(true) } } ''' assertTwoViolations(SOURCE, 4, 'System.runFinalizersOnExit(true)', 7, 'System.runFinalizersOnExit(true)') } @Test void testApplyTo_Violation_Methods() { final SOURCE = ''' class SystemRunFinalizersOnExitClass2 { static def method1() { System.runFinalizersOnExit(true) } def method2() { System.runFinalizersOnExit(true) } } ''' assertTwoViolations(SOURCE, 4, 'System.runFinalizersOnExit(true)', 7, 'System.runFinalizersOnExit(true)') } @Test void testApplyTo_Violation_Closures() { final SOURCE = ''' System.runFinalizersOnExit(true) def method = { System.runFinalizersOnExit(false) } ''' assertTwoViolations(SOURCE, 2, 'System.runFinalizersOnExit(true)', 4, 'System.runFinalizersOnExit(false)') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class SystemRunFinalizersOnExitClass3 { def myMethod() { otherObject.runFinalizersOnExit(true) System.out.println "1234" } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new SystemRunFinalizersOnExitRule() } } ������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/UseOfNotifyMethodRuleTest.groovy��������0000644�0001750�0001750�00000003471�12041642700�031720� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UseOfNotifyMethodRule * * @author Hamlet D'Arcy */ class UseOfNotifyMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UseOfNotifyMethod' } @Test void testSuccessScenario() { final SOURCE = ''' notifyAll() notify(foo) notify foo ''' assertNoViolations(SOURCE) } @Test void testThisNotify() { final SOURCE = ''' this.notify() ''' assertSingleViolation(SOURCE, 2, 'this.notify()') } @Test void testNotify() { final SOURCE = ''' notify() ''' assertSingleViolation(SOURCE, 2, 'notify()') } @Test void testOther() { final SOURCE = ''' other.notify() ''' assertSingleViolation(SOURCE, 2, 'other.notify()') } protected Rule createRule() { new UseOfNotifyMethodRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/ThreadYieldRuleTest.groovy��������������0000644�0001750�0001750�00000005173�12041642700�030544� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThreadYieldRule * * @author Hamlet D'Arcy */ class ThreadYieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThreadYield' } @Test void testApplyTo_Violation_Initializers() { final SOURCE = ''' class ThreadYieldClass1 { static { Thread.yield() } { Thread.yield() } } ''' assertTwoViolations(SOURCE, 4, 'Thread.yield()', 7, 'Thread.yield()') } @Test void testApplyTo_Violation_Methods() { final SOURCE = ''' class ThreadYieldClass2 { static def method1() { Thread.yield() } def method2() { Thread.yield() } } ''' assertTwoViolations(SOURCE, 4, 'Thread.yield()', 7, 'Thread.yield()') } @Test void testApplyTo_Violation_Closures() { final SOURCE = ''' Thread.yield() def method = { Thread.yield() } ''' assertTwoViolations(SOURCE, 2, 'Thread.yield()', 4, 'Thread.yield()') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' class ThreadYieldClass3 { def myMethod() { otherObject.yield() System.out.println "1234" } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ThreadYieldRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/BusyWaitRuleTest.groovy�����������������0000644�0001750�0001750�00000005660�12041642700�030116� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BusyWaitRule * * @author 'Hamlet D'Arcy' */ class BusyWaitRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BusyWait' } @Test void testSuccessScenario() { final SOURCE = ''' // here is the proper way to wait: countDownLatch.await() // this is weird code to write, but does not cause a violation // sleep inside a for-each loop is OK for some reason for (def x : collections) { sleep(1000) } for (def x = 0; x < 10; x++) { sleep(1000, 1, 3) // sleep does not take 3 parameters } while (x) { // you should use a lock here, but technically you are // not just busy waiting because you are doing other work doSomething() sleep(1000) } ''' assertNoViolations(SOURCE) } @Test void testWhileLoop() { final SOURCE = ''' while (x) { Thread.sleep(1000) } ''' assertSingleViolation(SOURCE, 3, 'Thread.sleep(1000)', 'Busy wait detected. Switch the usage of Thread.sleep() to a lock or gate from java.util.concurrent') } @Test void testWhileLoopWithClosure() { final SOURCE = ''' while (x) { sleep(1000) { /* interruption handler */} } ''' assertSingleViolation(SOURCE, 3, 'sleep(1000)', 'Busy wait detected. Switch the usage of Thread.sleep() to a lock or gate from java.util.concurrent') } @Test void testForLoop() { final SOURCE = ''' for (int x = 10; x; x--) { sleep(1000) // sleep is added to Object in Groovy } ''' assertSingleViolation(SOURCE, 3, 'sleep(1000)', 'Busy wait detected. Switch the usage of Thread.sleep() to a lock or gate from java.util.concurrent') } protected Rule createRule() { new BusyWaitRule() } } ��������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/ThreadLocalNotStaticFinalRuleTest.groovy0000644�0001750�0001750�00000006004�12041642700�033325� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThreadLocalNotStaticFinalRule. * * @author Hamlet D'Arcy */ class ThreadLocalNotStaticFinalRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThreadLocalNotStaticFinal' } @Test void testApplyTo_Violation_StaticOrFinalButNotBoth() { final SOURCE = ''' class ThreadLocalNotStaticFinalClass1 { private static ThreadLocal local1 = new ThreadLocal() private final ThreadLocal local2 = new ThreadLocal() } ''' assertTwoViolations(SOURCE, 3, 'private static ThreadLocal local1 = new ThreadLocal()', 4, 'private final ThreadLocal local2 = new ThreadLocal()') } @Test void testApplyTo_Violation_NotFinalOrStatic() { final SOURCE = ''' class ThreadLocalNotStaticFinalClass1 { static ThreadLocal local1 = new ThreadLocal() final protected ThreadLocal local2 = new ThreadLocal() } ''' assertTwoViolations(SOURCE, 3, 'ThreadLocal local1 = new ThreadLocal()', 'The ThreadLocal field local1 is not final', 4, 'protected ThreadLocal local2 = new ThreadLocal()', 'The ThreadLocal field local2 is not static') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' class ThreadLocalNotStaticFinalClass3 { private static final ThreadLocal local1 = new ThreadLocal() private static final ThreadLocal local2 = new ThreadLocal() }''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolationsInnerClass() { final SOURCE = ''' class ThreadLocalNotStaticFinalClass4 { static class ThreadLocalNotStaticFinalInnerClass4 { private static final ThreadLocal local1 = new ThreadLocal() private static final ThreadLocal local2 = new ThreadLocal() } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ThreadLocalNotStaticFinalRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/NestedSynchronizationRuleTest.groovy����0000644�0001750�0001750�00000016243�12465006640�032721� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Unit test for NestedSynchronizationRule. * * @author Hamlet D'Arcy */ class NestedSynchronizationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'NestedSynchronization' } @Test void testApplyTo_NoViolations_InClosure() { final SOURCE = ''' class testApplyTo_NoViolations_InClosureClass { def myMethod() { synchronized(this) { def closure1 = { synchronized(this) { } } def closure2 = { synchronized(this) { } } } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations_AnonymousInnerClass() { final SOURCE = ''' class testApplyTo_NoViolations_InAnonymousInnerClass { def myMethod() { synchronized(this) { def runnable = new Runnable() { public void run() { synchronized(this) {} } } } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_FileWithTwoClasses() { final SOURCE = ''' class NestedSynchronizationClass1 { def myMethod() { synchronized(this) {} } } // synchronized within a second class class NestedSynchronizationClass2 { def myMethod() { synchronized(this) {} } def method2() { synchronized(this) {} } def method3() { synchronized(this) { // synchronized block within a closure def closure1 = { synchronized(this) { } } def closure2 = { synchronized(this) { } } } } // synchronized within a static inner class static class NestedSynchronizationClass3 { def myMethod() { synchronized(this) {} } def method2() { synchronized(this) {} } def method3() { synchronized(this) { // synchronized block within a closure def closure1 = { synchronized(this) { } } def closure2 = { synchronized(this) { } } } } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Method() { final SOURCE = ''' class NestedSynchronizationClass4 { // within a method def myMethod() { synchronized(this) { synchronized(this) {} } } } ''' assertSingleViolation(SOURCE, 7, 'synchronized(this) {}') } @Test void testApplyTo_Closure() { final SOURCE = ''' class NestedSynchronizationClass5 { def closure1 = { synchronized(this) { synchronized(this) { } } } } ''' assertSingleViolation(SOURCE, 6, 'synchronized(this) { }') } @Test void testApplyTo_AnonymousInnerClass() { final SOURCE = ''' class NestedSynchronizationClass6 { def runnable = new Runnable() { public void run() { synchronized(this) { synchronized(this) {} } } } } ''' assertSingleViolation(SOURCE, 7, 'synchronized(this) {}') } @Test void testApplyTo_StaticInnerClass() { final SOURCE = ''' class NestedSynchronizationClass7 { static class NestedSynchronizationClass8 { def closure1 = { synchronized(this) { synchronized(this) {} } } def myMethod() { synchronized(this) { synchronized(this) {} } } } } ''' assertTwoViolations(SOURCE, 7, 'synchronized(this) {}', 12, 'synchronized(this) {}') } @Test void testApplyTo_SecondClass() { final SOURCE = ''' class NestedSynchronizationClass9 { def myMethod() { synchronized(this) {} } } // synchronized within a second class class NestedSynchronizationClass2 { def myMethod() { synchronized(this) { synchronized(this) {} } } } ''' assertSingleViolation(SOURCE, 12, 'synchronized(this) {}') } @Test void testApplyTo_DifferentLockObjects() { final SOURCE = ''' class NestedSynchronizationClass10 { private lock1 = new Object() private lock2 = new Object() def myMethod() { synchronized(lock1) { synchronized(lock2) {} } } } ''' assertSingleViolation(SOURCE, 8, 'synchronized(lock2) {}') } protected Rule createRule() { new NestedSynchronizationRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/WaitOutsideOfWhileLoopRuleTest.groovy���0000644�0001750�0001750�00000005046�12041642700�032716� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for WaitOutsideOfWhileLoopRule * * @author Chris Mair */ class WaitOutsideOfWhileLoopRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'WaitOutsideOfWhileLoop' } @Test void testApplyTo_WaitWithinWhileLoop_NoViolation() { final SOURCE = ''' synchronized(data) { while (!data.isReady()) { data.wait() } data.calculateStatistics() } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_WaitWithinNestedLoop_NoViolation() { final SOURCE = ''' synchronized(data) { while(dataFile.hasRecords()) { doStuff() while(!data.isReady()) { data.wait() } processData() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_WaitNotWithinWhileLoop_Violation() { final SOURCE = ''' synchronized(data) { data.wait() data.calculateStatistics() } ''' assertSingleViolation(SOURCE, 3, 'data.wait()') } @Test void testApplyTo_WaitWithinForLoop_Violation() { final SOURCE = ''' synchronized(data) { for(;!data.isReady();) { data.wait() } data.calculateStatistics() } ''' assertSingleViolation(SOURCE, 4, 'data.wait()') } protected Rule createRule() { new WaitOutsideOfWhileLoopRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/concurrency/VolatileLongOrDoubleFieldRuleTest.groovy0000644�0001750�0001750�00000005007�12041642700�033341� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.concurrency import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Unit test for VolatileLongOrDoubleFieldRule. * * @author Hamlet D'Arcy */ class VolatileLongOrDoubleFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'VolatileLongOrDoubleField' } @Test void testApplyTo_Violation_Doubles() { final SOURCE = ''' class VolatileLongOrDoubleFieldClass1 { private volatile double d private volatile Double e } ''' assertTwoViolations(SOURCE, 3, 'private volatile double d', 4, 'private volatile Double e') } @Test void testApplyTo_Violation_Floats() { final SOURCE = ''' class VolatileLongOrDoubleFieldClass2 { private volatile long f private volatile Long g } ''' assertTwoViolations(SOURCE, 3, 'private volatile long f', 4, 'private volatile Long g') } @Test void testApplyTo_Violation_FloatsWithoutModifier() { final SOURCE = ''' class VolatileLongOrDoubleFieldClass3 { def volatile long f def volatile Long g } ''' assertTwoViolations(SOURCE, 3, 'def volatile long f', 4, 'def volatile Long g') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class VolatileLongOrDoubleFieldClass4 { double d Double e }''' assertNoViolations(SOURCE) } protected Rule createRule() { new VolatileLongOrDoubleFieldRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unused/���������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022356� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unused/UnusedPrivateMethodParameterRuleTest.groovy��0000644�0001750�0001750�00000013576�12041642704�033131� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.unused import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnusedPrivateMethodParameterRule * * @author Chris Mair */ class UnusedPrivateMethodParameterRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnusedPrivateMethodParameter' } @Test void testApplyTo_SingleUnusedPrivateMethodParameter() { final SOURCE = ''' class MyClass { private void myMethod(int value) { } } ''' assertSingleViolation(SOURCE, 3, 'private void myMethod(int value) { }', 'Method parameter [value] is never referenced') } @Test void testIgnoreRegexDefaults() { final SOURCE = ''' class MyClass { private void myMethod1(int ignore) { } private void myMethod2(int ignored) { } } ''' assertNoViolations(SOURCE) } @Test void testCustomIgnoreRegex() { final SOURCE = ''' class MyClass { private void myMethod1(int value) { } private void myMethod2(int ignore) { } private void myMethod3(int ignored) { } } ''' rule.ignoreRegex = 'value|ignored|ignore' assertNoViolations(SOURCE) } @Test void testApplyTo_SingleUnusedPrivateMethodParameterSuspiciousReferenceInAnonymousClass() { final SOURCE = ''' class MyClass { private void myMethod(int value) { } // this is NOT a reference, but the AST does not have enough information for this def x = new Object() { def y = value } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MultipleUnusedParametersForSinglePrivateMethod() { final SOURCE = ''' class MyClass { private void myMethod(int value, String name) { } private void myMethod2(int ignore) { } private void myMethod3(int ignored) { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'private void myMethod(int value, String name) { }', messageText:'value'], [lineNumber:3, sourceLineText:'private void myMethod(int value, String name) { }', messageText:'name']) } @Test void testApplyTo_MultiplePrivateMethodsWithUnusedParameters() { final SOURCE = ''' class MyClass { private void myMethod1(String id, int value) { print value } protected void myMethod2(int otherValue) { print otherValue } private int myMethod3(Date startDate) { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'private void myMethod1(String id, int value) { print value }', messageText:'id'], [lineNumber:5, sourceLineText:'private int myMethod3(Date startDate) { }', messageText:'startDate']) } @Test void testApplyTo_AllParametersUsed() { final SOURCE = ''' class MyClass { private String myMethod1(String id, int value) { doSomething(value); return id } private void myMethod2(int value) { def x = value } private def myMethod3(Date startDate) { return "${startDate}" } private def myMethod4(Date startDate) { return new Object() { def x = startDate } } private def myMethod5(Date startDate) { return new Object() { String toString() { return startDate } } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonPrivateMethods() { final SOURCE = ''' class MyClass { void myMethod1(String id, int value) { } protected void myMethod2(int value) { } public int myMethod3(Date startDate) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_OnlyReferenceIsAMapKeyOrValue() { final SOURCE = ''' class MyClass { private myMethod1(String id, int value) { return [(id):value] } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ParameterIsAClosureThatIsCalled() { final SOURCE = ''' class MyClass { private myMethod1(Closure closure, def closure2, closure3) { def value1 = closure() def value2 = closure2.call() return closure3(value1, value2) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoMethods() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } protected Rule createRule() { new UnusedPrivateMethodParameterRule() } } ����������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unused/UnusedVariableRuleTest.groovy����������������0000644�0001750�0001750�00000027077�12412651200�030234� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unused import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnusedVariableRule * * @author Chris Mair */ class UnusedVariableRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnusedVariable' } @Test void testApplyTo_SingleUnusedVariable() { final SOURCE = ''' class MyClass { def myMethod() { int count } } ''' assertSingleViolation(SOURCE, 4, 'int count', 'The variable [count] in class MyClass is not used') } @Test void testApplyTo_SingleUnusedVariable_WithInitialExpression() { final SOURCE = ''' class MyClass { def myMethod() { int count = 23 } } ''' assertSingleViolation(SOURCE, 4, 'int count = 23', 'count') } @Test void testApplyTo_MultipleUnusedVariables() { final SOURCE = ''' class MyClass { def myMethod() { int count = 23 String name String other name = 'def' } } ''' assertTwoViolations(SOURCE, 4, 'int count = 23', 6, 'String other') } @Test void testApplyTo_AllVariablesUsed() { final SOURCE = ''' class MyClass { static final GLOBAL_NAME = 'xxx' def doStuff() { def otherVar def defaultName = GLOBAL_NAME String startName = defaultName otherVar = startName.size() println "name=$startName" def amount = 123.45 println "amount=$amount" } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_VariableWithSameNameReferencedInAnotherBlock() { final SOURCE = ''' class MyClass { def myMethod() { int count = 23 def name = 'abc' println name } def myOtherMethod() { println count } } ''' assertSingleViolation(SOURCE, 4, 'int count = 23', 'count') } @Test void testApplyTo_SameVariableInOtherBlocks() { final SOURCE = ''' class MyClass { def myMethod1() { int count = 23 } def myOtherMethod() { println count } def myMethod2() { int count = 99 } } ''' assertTwoViolations(SOURCE, 4, 'int count = 23', 10, 'int count = 99') } @Test void testApplyTo_NestedBlock() { final SOURCE = ''' class MyClass { def myMethod() { int count = 23 if (ready) { def name = 'abc' println count println name } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReferencedFromReturn() { final SOURCE = ''' def defaultMethod = dc.metaClass.getMetaMethod(name, args) if(x == 99) { println "too much" if (y > 5){ println 'way too much' } } return defaultMethod.invoke(delegate, args) ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReferencePropertyWithSameName() { final SOURCE = ''' class MyClass { def doSomething() { int count = 99 someOtherObject.count = 23 } } ''' assertSingleViolation(SOURCE, 4, 'int count = 99', 'count') } @Test void testApplyTo_ReferencedWithinClosure() { final SOURCE = ''' class MyClass { def doSomething() { int count return { -> println count } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReferencedWithinGString() { final SOURCE = ''' def doSomething() { def value = null println "value=$value" } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReferenceClosureVariableByInvokingIt() { final SOURCE = ''' class MyClass { def doSomething() { def myClosure = { println 'ok' } if (ready) { myClosure() } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReferenceNestedClosureVariablesByInvokingThem() { final SOURCE = ''' class MyClass { def doSomething() { def outerClosure = { def innerClosure = { count -> println 'ok' } innerClosure(99) } outerClosure() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ClosureVariableReferencedButNotInvoked() { final SOURCE = ''' class MyClass { def myMethod() { final CLOSURE = { doSomething() } return CLOSURE } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_UntypedVariableInvokedAsAClosure() { final SOURCE = ''' class MyClass { def myMethod(someClosure) { def defaultClosure = someClosure defaultClosure() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_UnusedClosureVariable() { final SOURCE = ''' class MyClass { def myMethod() { def count = { println 'ok' } } } ''' assertSingleViolation(SOURCE, 4, "def count = { println 'ok' }", 'count') } @Test void testApplyTo_ExplicitMethodCallOnThisWithSameMethodName() { final SOURCE = ''' class MyClass { def myMethod() { int count = 23 this.count() } def count() { println 99 } } ''' assertSingleViolation(SOURCE, 4, 'int count = 23', 'count') } @Test void testApplyTo_ReferencedOnSameLineAsDeclaration() { final SOURCE = ''' class MyClass { def doSomething() { int count = 99; println 'abc'; println "count=$count" for(int i=0; i<10; i++) { println 'me' } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_VariableOnlyReferencedWithinInnerClass() { final SOURCE = ''' def buildCallable() { String ssn = 'xxx' return new Callable<Object>() { public Object call(){ return participantDao.getParticipantPlans(ssn) } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_LoopVariable_ReferencedWithinLoopBlock() { final SOURCE = ''' def doStuff() { for (int i = 0; i < 8; i++) { outputMap.putAll(CopanSystemService.canisterInfo(suuid[i], i)) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_LoopVariable_NotReferenced() { final SOURCE = ''' for (int i = 0; ; ) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'for (int i = 0; ; )', messageText:'i']) } @Test void testApplyTo_ClassicForLoop_SameVariableName() { final SOURCE = ''' for (int i=0;i<3;i++) { System.out.println("bla") } for (int i=0;i<3;i++) { System.out.println("bla") } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Script_UnusedVariable() { final SOURCE = ''' BigDecimal depositAmount ''' assertSingleViolation(SOURCE, 2, 'BigDecimal depositAmount', 'depositAmount') } @Test void testApplyTo_Script_UnusedBinding() { final SOURCE = ''' depositCount = 99 // not considered a variable ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoVariableDefinition() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreVariableNames_MatchesSingleName() { final SOURCE = ''' class MyClass { def myMethod() { BigDecimal depositAmount } } ''' rule.ignoreVariableNames = 'depositAmount' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreVariableNames_MatchNoNames() { final SOURCE = ''' class MyClass { def myMethod() { BigDecimal depositAmount } } ''' rule.ignoreVariableNames = 'other' assertSingleViolation(SOURCE, 4, 'BigDecimal depositAmount', 'The variable [depositAmount] in class MyClass is not used') } @Test void testApplyTo_IgnoreVariableNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { def myMethod() { BigDecimal depositAmount def other int count long otherMax } } ''' rule.ignoreVariableNames = 'oth*,xxx,deposit??ount' assertSingleViolation(SOURCE, 6, 'int count', 'The variable [count] in class MyClass is not used') } protected Rule createRule() { new UnusedVariableRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unused/UnusedPrivateFieldRuleTest.groovy������������0000644�0001750�0001750�00000030623�12311370173�031061� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.unused import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnusedPrivateFieldRule * * @author Chris Mair * @author Hamlet D'Arcy * */ class UnusedPrivateFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnusedPrivateField' } @Test void testGroovyCoreBug() { final SOURCE = ''' class CallOnOwner { @AnnWithClassElement() private aField }''' assertSingleViolation(SOURCE, 4, 'private aField', 'The field aField is not used within the class CallOnOwner') } @Test void testApplyTo_SingleUnusedPrivateField() { final SOURCE = ''' class MyClass { @SomeAnnotationToCorruptLineNumbers private int count } ''' assertSingleViolation(SOURCE, 4, 'private int count', 'The field count is not used within the class MyClass') } @Test void testApplyTo_MultipleUnusedPrivateFields() { final SOURCE = ''' class MyClass { private int count def otherField private static String globalName = 'xxx' MyClass() { otherField = 'abc' } } ''' assertTwoViolations(SOURCE, 3, 'private int count', 5, "private static String globalName = 'xxx'") } @Test void testApplyTo_UnusedPrivateFieldWithAssignment() { final SOURCE = ''' class MyClass { private int count = 23 } ''' assertSingleViolation(SOURCE, 3, 'private int count = 23') } @Test void testSuppressWarningsOnClass() { final SOURCE = ''' @SuppressWarnings('UnusedPrivateField') class MyClass { private int count = 23 } ''' assertNoViolations(SOURCE) } @Test void testSuppressWarningsOnField() { final SOURCE = ''' class MyClass { @SuppressWarnings('UnusedPrivateField') private int count = 23 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AllPrivateFieldsUsed() { final SOURCE = ''' @MyAnnotation(elem = { 1 + 2 }) class MyClass { private int count def otherField static String globalName = 'xxx' private defaultName = 'abc' private startName = defaultName def dateFormat = java.text.DateFormat.getDateTimeInstance() @MyAnnotation(elem = { 1 + 2 }) def doStuff() { this.count = 23 def newName = globalName + startName } def myClosure = { println "using $otherField" } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonPrivateFields() { final SOURCE = ''' class MyClass { public int count protected String name def myOtherField // property } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReferencePropertyOfAnotherObject() { final SOURCE = ''' class MyClass { private int count def doSomething() { someOtherObject.count = 23 } } ''' assertSingleViolation(SOURCE, 3, 'private int count') } @Test void testApplyTo_StringPropertyReference() { final SOURCE = ''' class MyClass { private int count def other = this."count" private serialVersionUID = 6700367864074699984L // should be ignored } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_GStringPropertyReference() { final SOURCE = ''' class MyClass { private int count def other = this."${'count'}" } ''' assertSingleViolation(SOURCE, 3, 'private int count') } @Test void testApplyTo_DereferencedGStringPropertyReference() { final SOURCE = ''' class MyClass { private int count def varName = "count" def other = this."${varName}" // can't see this } ''' assertSingleViolation(SOURCE, 3, 'private int count') } @Test void testApplyTo_OnlyReferenceIsAMethodDefaultValue() { final SOURCE = ''' class MyClass { private static final COUNT = 3 private defaultName = 'abc' private String doStuff(int repeat = COUNT) { } private String doOtherStuff(int number, name = defaultName) { } private otherMethod_NoParameters() { } private otherMethod_ParameterDefaultValueIsALiteral(value=123) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_OnlyReferenceIsAMapKeyOrValue() { final SOURCE = ''' class MyClass { private static final NAME = 'abc' private static final VALUE = 123 def doStuff() { [(NAME):VALUE] } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MoreThanOneClassInASourceFile() { final SOURCE = ''' class MyClass { private int count } class OtherClass { int defaultCount = count } ''' // TODO This "should" cause a violation for count assertNoViolations(SOURCE) } @Test void testApplyTo_ClosureField() { final SOURCE = ''' class MyClass { private myClosure1 = { println '1' } private myClosure2 = { println '2' } private otherClosure = { println '3' } def getValue() { def value = myClosure1() def otherValue = someOtherObject.otherClosure() // different object/method this.myClosure2(value, otherValue) } } ''' assertSingleViolation(SOURCE, 5, "private otherClosure = { println '3' }") } @Test void testApplyTo_StaticFieldReferencedThroughClassName() { final SOURCE = ''' package com.example class MyClass { private static count = 0 private static calc = { val -> val * 2 } void printReport(){ println MyClass.count println MyClass.calc.call(99) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoFields() { final SOURCE = ''' class DataServiceException extends RuntimeException{ DataServiceException(){ } DataServiceException(String message){ super(message) } DataServiceException(String message, Throwable cause){ super(message, cause) } DataServiceException(Throwable cause){ super(cause) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Script() { final SOURCE = ''' private BigDecimal depositAmount // not considered a field private int count // not considered a field ''' assertNoViolations(SOURCE) } @Test void testAnonymousInnerClassAsField() { final SOURCE = ''' class MyClass { private static def x def y = new Class() { def call() { println(x) } } } ''' assertNoViolations SOURCE } @Test void testInnerClass() { final SOURCE = ''' class MyClass { private static def x = 5 class MyInnerClass { def call() { x++ } } } ''' assertNoViolations SOURCE } @Test void testApplyTo_IgnoreFieldNames() { final SOURCE = ''' class MyClass { private field1 private int count private field2 } ''' rule.ignoreFieldNames = 'count, fiel*' assertNoViolations(SOURCE) } @Test void testAnonymousInnerClassAsLocalVariable() { final SOURCE = ''' class MyClass { private static def foo = {} def myMethod() { return new Class() { def call() { foo() } } } } ''' assertNoViolations SOURCE } @Test void testSuperPropertyReferenceFromInner() { final SOURCE = ''' class ImportForm { private String importFilePath = null class ChooseFileHandler implements IFileChooseHandler { void onSuccess(String[] paths, String[] names) { ImportForm.this.importFilePath = paths[0] } void onFailure(int i, String s) { println ImportForm.this.importFilePath } } } ''' assertNoViolations(SOURCE) } @Test void testSuperMethodReferenceFromInner() { final SOURCE = ''' class ImportForm { private importFilePath = {} class ChooseFileHandler implements IFileChooseHandler { void onFailure(int i, String s) { ImportForm.this.importFilePath() } } } ''' assertNoViolations(SOURCE) } @Test void testSuperMethodReferenceFromInner_InMethodParmDefault() { final SOURCE = ''' class ImportForm { private String importFilePath = 'xxx' class ChooseFileHandler implements IFileChooseHandler { def myMethod(foo = ImportForm.this.importFilePath) { } } } ''' assertNoViolations(SOURCE) } @Test void testBugFix_CannotCastFieldNodeToMetaClass() { final SOURCE = ''' class FlowBuilder extends AbstractFlowBuilder implements GroovyObject, ApplicationContextAware { private MetaClass metaClass FlowBuilder() { println metaClass } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoFieldDefinition() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } protected Rule createRule() { new UnusedPrivateFieldRule() } } �������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unused/UnusedPrivateMethodRuleTest.groovy�����������0000644�0001750�0001750�00000034001�12041642704�031252� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.unused import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnusedPrivateMethodRule * * @author Chris Mair */ class UnusedPrivateMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnusedPrivateMethod' } @Test void testLocalUseOfGetter() { final SOURCE = ''' class ExecuteTest { private String getCmd() { 'cmd' } private String getCmd2() { 'cmd' } private String getCMD() { 'cmd' } private String getCMD2() { 'cmd' } private void setCMD3(x) { } private boolean isCmd4() { false } private boolean isCmd5() { true } private String getUnused() { 'unused' } void myMethod() { cmd.execute(cmd2) new Foo().CMD foo.CMD2.bar = 'xxx' CMD3 = 'yyy' cmd4.class cmd5.toString() } } ''' assertSingleViolation(SOURCE, 11, 'getUnused()', 'The method getUnused is not used within the class') } @Test void testGetterMethodWithIsPrefix_AccessedAsProperty_NoViolation() { final SOURCE = ''' class A { private boolean isCompleted() { true } boolean ready() { completed } } ''' assertNoViolations(SOURCE) } @Test void testStaticMethodsInOuterClass() { final SOURCE = ''' package groovy.bugs class MyClass { void myMethod() { MyClass.myPrivateMethod() MyOuterClass.myInnerPrivateMethod() } private static void myPrivateMethod() { } private static void myUncalledPrivateMethod() { } } class MyOuterClass { private static myInnerPrivateMethod() { } private static myUnCalledPrivateMethod() { } }''' assertTwoViolations(SOURCE, 11, 'myUncalledPrivateMethod', 'The method myUncalledPrivateMethod is not used within the class', 18, 'myUnCalledPrivateMethod', 'The method myUnCalledPrivateMethod is not used within the class') } @Test void testStaticMethodsInOuterClass_MethodHandles() { final SOURCE = ''' class MyClass { void myMethod() { def x = MyClass.&myPrivateMethod def y = MyOuterClass.&myInnerPrivateMethod } private static void myPrivateMethod() { } private static void myUncalledPrivateMethod() { } } class MyOuterClass { private static myInnerPrivateMethod() { } private static myUnCalledPrivateMethod() { } }''' assertTwoViolations(SOURCE, 9, 'myUncalledPrivateMethod', 'The method myUncalledPrivateMethod is not used within the class', 16, 'myUnCalledPrivateMethod', 'The method myUnCalledPrivateMethod is not used within the class') } @Test void testStaticMethodsInInnerClass_MethodHandles() { final SOURCE = ''' package groovy.bugs class MyClass { void myMethod() { def x = MyInnerClass.&myInnerPrivateMethod1 def y = MyInnerClass.myInnerPrivateMethod2() } class MyInnerClass { private static myInnerPrivateMethod1() { } private static myInnerPrivateMethod2() { } private static myInnerPrivateMethod3() { } private static myInnerPrivateMethod4() { } } } ''' assertTwoViolations(SOURCE, 13, 'myInnerPrivateMethod3', 'The method myInnerPrivateMethod3 is not used within the class', 14, 'myInnerPrivateMethod4', 'The method myInnerPrivateMethod4 is not used within the class') } @Test void testGetterMethodsInOuterClass() { final SOURCE = ''' package groovy.bugs class MyClass { @Test void test () { Foo.test() } } class Foo { private static test() { } } ''' assertNoViolations(SOURCE) } @Test void testGetterMethodsInInnerClass() { final SOURCE = ''' package groovy.bugs class MyClass { @Test void test () { Foo.test() } class Foo { private static test() { } } } ''' assertNoViolations(SOURCE) } @Test void testAnonymousInnerClassAsField() { final SOURCE = ''' class MyClass { private static def methodWithParameters(a,b) { a >> b } def x = new Class() { def call() { methodWithParameters(10,1) } } } ''' assertNoViolations SOURCE } @Test void testClosureAsField() { final SOURCE = ''' class MyClass { private static def methodWithParameters(a,b) { a >> b } def x = { methodWithParameters(10,1) } } ''' assertNoViolations SOURCE } @Test void testAnonymousInnerClassAsLocalVariable() { final SOURCE = ''' class MyClass { private static def methodWithParameters(a,b) { a >> b } def myMethod() { return new Class() { def call() { methodWithParameters(10,1) } } } } ''' assertNoViolations SOURCE } @Test void testClosureAsLocalVariable() { final SOURCE = ''' class MyClass { private static def methodWithParameters(a,b) { a >> b } def myClosure = { methodWithParameters(10,1) } } ''' assertNoViolations SOURCE } @Test void testInnerClass() { final SOURCE = ''' class MyClass { private static def methodWithParameters(a,b) { a >> b } class MyInnerClass { def call() { methodWithParameters(10,1) } } } ''' assertNoViolations SOURCE } @Test void testApplyTo_SingleUnusedPrivateMethod() { final SOURCE = ''' class MyClass { private int countStuff() { } } ''' assertSingleViolation(SOURCE, 3, 'private int countStuff() { }', 'The method countStuff is not used within the class') } @Test void testApplyTo_MultipleUnusedPrivateMethods() { final SOURCE = ''' class MyClass { private int countStuff() { } def otherMethod() { } private static String buildName(int count) { return "abc" + count } } ''' assertTwoViolations(SOURCE, 3, 'private int countStuff() { }', 6, 'private static String buildName(int count) {') } @Test void testApplyTo_PrivateConstructor_NotUsed() { final SOURCE = ''' class MyClass { private MyClass() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_AllPrivateMethodsUsed() { final SOURCE = ''' class MyClass { private int countStuff() { return 99 } int somePublicMethod() { } def abc = 'abc' private String getName() { 'abc' } private getPrice() { 0.0 } def doStuff() { def count = countStuff() def newName = this.getName() } def myClosure = { println "price is ${getPrice()}" } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonPrivateMethods() { final SOURCE = ''' class MyClass { int countStuff() { } protected String getName() { } def myOtherMethod() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MultipleOverloadedMethods() { final SOURCE = ''' class MyClass { private int fireEvent(int index) { } private int fireEvent(String name) { } private int fireEvent(int index, String name) { } def other = this.fireEvent(object) } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReferenceMethodOfAnotherObject() { final SOURCE = ''' class MyClass { private int countStuff() { } def doSomething() { someOtherObject.countStuff() } } ''' assertSingleViolation(SOURCE, 3, 'private int countStuff() { }') } @Test void testApplyTo_UnusedPrivateStaticMethod() { final SOURCE = ''' class MyClass { private static int countStuff() { } } ''' assertSingleViolation(SOURCE, 3, 'private static int countStuff() { }') } @Test void testApplyTo_PrivateStaticMethodAccessedThroughClassName() { final SOURCE = ''' class MyClass { static int getTotal() { println "total=${MyClass.countStuff()}" } private static int countStuff() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_GStringMethodReference() { final SOURCE = ''' class MyClass { private int countStuff() { } def other = this."${countStuff}"() } ''' assertSingleViolation(SOURCE, 3, 'private int countStuff() { }') } @Test void testApplyTo_StringMethodReference() { final SOURCE = ''' class MyClass { private int countStuff() { } def other = this."countStuff"() } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_DereferencedGStringMethodReference() { final SOURCE = ''' class MyClass { private int countStuff() { } def varName = "countStuff" def other = this."${varName}"() // can't see this } ''' assertSingleViolation(SOURCE, 3, 'private int countStuff() { }') } @Test void testApplyTo_MethodPointerReference() { final SOURCE = ''' class MyClass { private int myMethod() { } private int otherMethod() { } def getValue() { return this.&myMethod } } ''' assertSingleViolation(SOURCE, 4, 'private int otherMethod()') } @Test void testApplyTo_MoreThanOneClassInASourceFile() { final SOURCE = ''' class MyClass { private int countStuff() { } } class OtherClass { int defaultCount = count } ''' assertSingleViolation(SOURCE, 3, 'private int countStuff() { }') } @Test void testApplyTo_Script() { final SOURCE = ''' private BigDecimal calculateDepositAmount() { 23 } ''' assertSingleViolation(SOURCE, 2, 'private BigDecimal calculateDepositAmount() { 23 }') } @Test void testApplyTo_NoMethodDefinition() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } @Test void testApplyTo_StackOverflow() { final SOURCE = ' Map map = ["a" : 1, "b": 2, "$c": 3, "b": 4 ] ' assertNoViolations(SOURCE) } @Test void testApplyTo_ZeroLengthMethodName() { final SOURCE = ''' def doStuff() { def results = calculate() results[0]."" } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnusedPrivateMethodRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unused/UnusedArrayRuleTest.groovy�������������������0000644�0001750�0001750�00000004557�12041642704�027572� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.unused import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnusedArrayRule * * @author Your Name Here */ class UnusedArrayRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnusedArray' } @Test void testApplyTo_ArrayAssigned_NoViolations() { final SOURCE = ''' def array1 = new String[3] Object[] array2 = [] println new Integer[3] ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ArrayNotAssigned_ButLastStatementWithinAMethod_NoViolations() { final SOURCE = ''' println new BigDecimal("23.45") new String[3] ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ArrayNotAssigned_ButLastStatementWithinAClosure_NoViolations() { final SOURCE = ''' def closure = { new String[3] } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ArrayNotAssigned_Violations() { final SOURCE = ''' new String[3] println "ok" ''' assertViolations(SOURCE, [lineNumber: 2, sourceLineText: 'new String[3]']) } @Test void testApplyTo_ArrayNotAssigned_WithinClosure_Violations() { final SOURCE = ''' def myClosure = { -> new Object[2] doStuff() } ''' assertViolations(SOURCE, [lineNumber: 3, sourceLineText: 'new Object[2]']) } protected Rule createRule() { new UnusedArrayRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unused/UnusedMethodParameterRuleTest.groovy���������0000644�0001750�0001750�00000020016�12041642704�031561� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unused import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnusedMethodParameterRule * * @author Hamlet D'Arcy * @author Chris Mair */ class UnusedMethodParameterRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnusedMethodParameter' } @Test void testApplyTo_SingleUnusedMethodParameter() { final SOURCE = ''' class MyClass { void myMethod(int value) { } } ''' assertSingleViolation(SOURCE, 3, 'void myMethod(int value) { }', 'Method parameter [value] is never referenced') } @Test void testIgnoreRegexDefaults() { final SOURCE = ''' class MyClass { void myMethod1(int ignore) { } void myMethod2(int ignored) { } } ''' assertNoViolations(SOURCE) } @Test void testCustomIgnoreRegex() { final SOURCE = ''' class MyClass { void myMethod1(int value) { } void myMethod2(int ignore) { } void myMethod3(int ignored) { } } ''' rule.ignoreRegex = 'value|ignored|ignore' assertNoViolations(SOURCE) } @Test void testIgnoresCategoryClassesByDefault() { final SOURCE = ''' class MyCategory { void myMethod1(String string, int value) { } void myMethod1(String string, int value, name) { } } ''' assertNoViolations(SOURCE) } @Test void testCustomIgnoreClassRegex() { final SOURCE = ''' class MyCustomClass { void myMethod1(int value) { } void myMethod1(int value, name) { } } ''' rule.ignoreClassRegex = '.*Custom.*' assertNoViolations(SOURCE) } @Test void testApplyTo_SingleUnusedPrivateMethodParameterSuspiciousReferenceInAnonymousClass() { final SOURCE = ''' class MyClass { void myMethod(int value) { } // this is NOT a reference, but the AST does not have enough information for this def x = new Object() { def y = value } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MultipleUnusedParametersForSinglePrivateMethod() { final SOURCE = ''' class MyClass { void myMethod(int value, String name) { } void myMethod2(int ignore) { } void myMethod3(int ignored) { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'void myMethod(int value, String name) { }', messageText:'value'], [lineNumber:3, sourceLineText:'void myMethod(int value, String name) { }', messageText:'name']) } @Test void testApplyTo_MultiplePrivateMethodsWithUnusedParameters() { final SOURCE = ''' class MyClass { void myMethod1(String id, int value) { print value } protected void myMethod2(int otherValue) { print otherValue } int myMethod3(Date startDate) { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'void myMethod1(String id, int value) { print value }', messageText:'id'], [lineNumber:5, sourceLineText:'int myMethod3(Date startDate) { }', messageText:'startDate']) } @Test void testApplyTo_AllParametersUsed() { final SOURCE = ''' class MyClass { String myMethod1(String id, int value) { doSomething(value); return id } void myMethod2(int value) { def x = value } def myMethod3(Date startDate) { return "${startDate}" } def myMethod4(Date startDate) { return new Object() { def x = startDate } } def myMethod5(Date startDate) { return new Object() { String toString() { return startDate } } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NonPrivateMethodsWithOverride() { final SOURCE = ''' class MyClass { @Override void myMethod1(String id, int value) { } @Override protected void myMethod2(int value) { } @Override public int myMethod3(Date startDate) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_OnlyReferenceIsAMapKeyOrValue() { final SOURCE = ''' class MyClass { def myMethod1(String id, int value) { return [(id):value] } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ParameterIsAClosureThatIsCalled() { final SOURCE = ''' class MyClass { def myMethod1(Closure closure, def closure2, closure3) { def value1 = closure() def value2 = closure2.call() return closure3(value1, value2) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMainMethod() { // In Groovy, the main() method does not have to specify void return type or String[] args type. // But it must be static, with one parameter. final SOURCE = ''' class MyClass1 { public static void main(String[] args) { } } class MyClass2 { static main(args) { } } class MyClass3 { public static void main(java.lang.String[] args) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreNonMatchingMainMethods() { final SOURCE = ''' class MyClass1 { void main(String[] args) { } // not static } class MyClass2 { static main(arg1, arg2) { } // too many args } class MyClass3 { static main(int value) { } // wrong arg type } class MyClass4 { static int main(String[] args) { } // wrong return type } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'void main(String[] args) { }', messageText:'args'], [lineNumber:6, sourceLineText:'static main(arg1, arg2) { }', messageText:'arg1'], [lineNumber:6, sourceLineText:'static main(arg1, arg2) { }', messageText:'arg2'], [lineNumber:9, sourceLineText:'static main(int value) { }', messageText:'value'], [lineNumber:12, sourceLineText:'static int main(String[] args) { }', messageText:'args']) } @Test void testApplyTo_NoMethods() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } protected Rule createRule() { new UnusedMethodParameterRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/unused/UnusedObjectRuleTest.groovy������������������0000644�0001750�0001750�00000006676�12041642704�027726� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.unused import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for UnusedObjectRule * * @author Your Name Here */ class UnusedObjectRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'UnusedObject' assert rule.doNotApplyToFilesMatching == DEFAULT_TEST_FILES } @Test void testApplyTo_ObjectAssigned_NoViolations() { final SOURCE = ''' def v1 = new Object() URL v2 = new URL("www.google.com") println new BigDecimal("23.45") ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ObjectNotAssigned_ButLastStatementWithinAMethod_NoViolations() { final SOURCE = ''' println new BigDecimal("23.45") new Object() ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ObjectNotAssigned_ButLastStatementWithinAClosure_NoViolations() { final SOURCE = ''' def closure = { new Date() } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ObjectNotAssigned_Violations() { final SOURCE = ''' new Object() new URL("www.google.com") println "ok" ''' assertViolations(SOURCE, [lineNumber: 2, sourceLineText: 'new Object()'], [lineNumber: 3, sourceLineText: 'new URL("www.google.com")']) } @Test void testApplyTo_ObjectNotAssigned_WithinClosure_Violations() { final SOURCE = ''' def myClosure = { -> new Object() doSomething() } ''' assertViolations(SOURCE, [lineNumber: 3, sourceLineText: 'new Object()']) } @Test void testApplyTo_SuperConstructorCall_NoViolations() { final SOURCE = ''' class MyClass { MyClass() { super() doSomething() } MyClass(String name) { super(name) doSomething() } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ThisConstructorCall_NoViolations() { final SOURCE = ''' class MyClass { MyClass() { this() doSomething() } MyClass(String name) { this(name) doSomething() } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new UnusedObjectRule() } } ������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/dry/������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021651� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/dry/DuplicateNumberLiteralRuleTest.groovy�����������0000644�0001750�0001750�00000013745�12041642702�031220� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.dry import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DuplicateNumberLiteralRule * * @author Hamlet D'Arcy */ class DuplicateNumberLiteralRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DuplicateNumberLiteral' } @Test void testSuccessScenario() { final SOURCE = ''' println 123 println -17 def y = 0 def z = 9876543 class MyClass { def static x = 'xyz' def static y = 'xyz' def field = System.getProperty('file.seperator') def x = 'foo' def y = 11.783 String a = 'a' String b = 'b' def method() { method('c', 'd') ('e' == 'f') ? 'g' : 'h' 'i' ?: 'j' return 'return' } } println '123' println '123' ''' assertNoViolations(SOURCE) } @Test void testAcrossManyMethodCalls() { final SOURCE = ''' println 123 println 123 println 123 ''' assertTwoViolations(SOURCE, 3, 'println 123', 4, 'println 123') } @Test void testMethodCall() { final SOURCE = ''' println 123, 123, 123 ''' assertTwoViolations(SOURCE, 2, 'println 123, 123, 123', 2, 'println 123, 123, 123') } @Test void testInAList() { final SOURCE = ''' def x = [3, 11.783, 3] ''' assertSingleViolation(SOURCE, 2, 'def x = [3, 11.783, 3]') } @Test void testInAMap() { final SOURCE = ''' def y = [x: -99, y: -99] ''' assertSingleViolation(SOURCE, 2, 'def y = [x: -99, y: -99]') } @Test void testDoublesAndFloatLiteralsCanBeIgnored() { final SOURCE = ''' println 99.0d println 99.0d println 99.0f println 99.0f println 99.0G println 99.0G println 99G println 99G println 99.0 println 99.0 ''' rule.ignoreNumbers = '99,99.0,99.0d,99.0f,99.0G' assertNoViolations(SOURCE) } @Test void testInDeclarations() { final SOURCE = ''' def x = 99 def y = 99 x = 11.783 y = 11.783 ''' assertTwoViolations(SOURCE, 3, 'def y = 99', 5, 'y = 11.783') } @Test void testInFields() { final SOURCE = ''' class MyClass { def x = 67890 def y = 67890 } ''' assertSingleViolation(SOURCE, 4, 'def y = 67890') } @Test void testInTernary() { final SOURCE = ''' (0.7 == 0.7) ? -5.13 : 'h' (0.7 == 12) ? -5.13 : -5.13 ''' assertTwoViolations(SOURCE, 2, "(0.7 == 0.7) ? -5.13 : 'h'", 3, '(0.7 == 12) ? -5.13 : -5.13') } @Test void testInElvis() { final SOURCE = ''' 67890 ?: 67890 ''' assertSingleViolation(SOURCE, 2, '67890 ?: 67890') } @Test void testInIf() { final SOURCE = ''' if (x == 67890) return x else if (y == 67890) return y else if (z == 67890) return z ''' assertTwoViolations(SOURCE, 3, 'else if (y == 67890) return y', 4, 'else if (z == 67890) return z') } @Test void testInReturn() { final SOURCE = ''' if (true) return 67890 else return 67890 ''' assertSingleViolation(SOURCE, 3, 'else return 67890') } @Test void testInInvocation() { final SOURCE = ''' 67890.equals(x) 67890.equals(y) ''' assertSingleViolation(SOURCE, 3, '67890.equals(y)') } @Test void testInNamedArgumentList() { final SOURCE = ''' x(b: 11.783) y(a: 11.783) ''' assertSingleViolation(SOURCE, 3, 'y(a: 11.783)') } @Test void testIgnoreNumbers_IgnoresSingleValue() { final SOURCE = ''' def x = [23, -3.5, 23] def y = [37, -7, 37] ''' rule.ignoreNumbers = 23 assertSingleViolation(SOURCE, 3, 'def y = [37, -7, 37]') } @Test void testIgnoreNumbers_IgnoresMultipleValues() { final SOURCE = ''' def x = [0.725, 897.452, 0.725] def y = [-97, 11, -97] ''' rule.ignoreNumbers = '0.725,7654, -97' assertNoViolations(SOURCE) } @Test void testIgnoreNumbers_ByDefaultIgnoresZeroAndOne() { final SOURCE = ''' def x = [0, 12, 1, 34.567, 99, 1, 78, 0, 12.345] ''' assertNoViolations(SOURCE) } @Test void testIgnoreNumbers_InvalidNumber() { final SOURCE = ''' def x = [0.725,0.725, 'xxx'] ''' rule.ignoreNumbers = '0.725,xxx, yyy' assertNoViolations(SOURCE) } protected Rule createRule() { new DuplicateNumberLiteralRule() } } ���������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/dry/DuplicateStringLiteralRuleTest.groovy�����������0000644�0001750�0001750�00000014511�12224273206�031230� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.dry import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DuplicateStringLiteralRule * * @author Hamlet D'Arcy */ class DuplicateStringLiteralRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DuplicateStringLiteral' } @Test void testSuccessScenario() { final SOURCE = ''' println 'w' println 'x' def y = 'y' def z = 'z' class MyClass { def static x = 'xyz' def static y = 'xyz' def field = System.getProperty('file.seperator') def x = 'foo' def y = 'bar' String a = 'a' String b = 'b' def method() { method('c', 'd') ('e' == 'f') ? 'g' : 'h' 'i' ?: 'j' return 'return' } } println 123 println 123 ''' assertNoViolations(SOURCE) } @Test void testAcrossManyMethodCalls() { final SOURCE = ''' println 'w' println 'w' println 'w' ''' assertTwoViolations(SOURCE, 3, "println 'w'", 4, "println 'w'") } @Test void testEnums() { final SOURCE = ''' enum MyEnum { FOO( 'FOO' ) String field MyEnum(String field) { this.field = field } } ''' assertNoViolations SOURCE } @Test void testMethodCall() { final SOURCE = ''' println 'w', 'w', 'w' ''' assertTwoViolations(SOURCE, 2, "println 'w', 'w', 'w'", 2, "println 'w', 'w', 'w'") } @Test void testInAList() { final SOURCE = ''' def x = ['foo', 'bar', 'foo'] ''' assertSingleViolation(SOURCE, 2, "def x = ['foo', 'bar', 'foo']") } @Test void testInAMap() { final SOURCE = ''' def y = [x: 'bar', y: 'bar'] ''' assertSingleViolation(SOURCE, 2, "def y = [x: 'bar', y: 'bar']") } @Test void testInDeclarations() { final SOURCE = ''' def x = 'foo' def y = 'foo' x = 'bar' y = 'bar' ''' assertTwoViolations(SOURCE, 3, "def y = 'foo'", 5, "y = 'bar'") } @Test void testInFields() { final SOURCE = ''' class MyClass { def x = 'foo' def y = 'foo' } ''' assertSingleViolation(SOURCE, 4, "def y = 'foo'") } @Test void testInTernary() { final SOURCE = ''' ('e' == 'e') ? 'g' : 'h' ('e' == 'f') ? 'g' : 'g' ''' assertTwoViolations(SOURCE, 2, "('e' == 'e') ? 'g' : 'h'", 3, "('e' == 'f') ? 'g' : 'g'") } @Test void testInElvis() { final SOURCE = ''' 'foo' ?: 'foo' ''' assertSingleViolation(SOURCE, 2, "'foo' ?: 'foo'") } @Test void testInIf() { final SOURCE = ''' if (x == 'foo') return x else if (y == 'foo') return y else if (z == 'foo') return z ''' assertTwoViolations(SOURCE, 3, "else if (y == 'foo') return y", 4, "else if (z == 'foo') return z") } @Test void testInReturn() { final SOURCE = ''' if (true) return 'foo' else return 'foo' ''' assertSingleViolation(SOURCE, 3, "else return 'foo'") } @Test void testInInvocation() { final SOURCE = ''' 'foo'.equals('bar') 'foo'.equals('baz') ''' assertSingleViolation(SOURCE, 3, "'foo'.equals('baz')") } @Test void testInNamedArgumentList() { final SOURCE = ''' x(b: 'bar') y(a: 'bar') ''' assertSingleViolation(SOURCE, 3, "y(a: 'bar')") } @Test void testIgnoreStrings_IgnoresSingleValue() { final SOURCE = ''' def x = ['xyz', 'abc', 'xyz'] def y = ['foo', 'bar', 'foo'] ''' rule.ignoreStrings = 'xyz' assertSingleViolation(SOURCE, 3, "def y = ['foo', 'bar', 'foo']") } @Test void testIgnoreStrings_IgnoresMultipleValues() { final SOURCE = ''' def x = ['xyz', 'abc', 'xyz'] def y = ['foo', 'bar', 'foo'] ''' rule.ignoreStrings = 'xyz,foo' assertNoViolations(SOURCE) } @Test void testIgnoreStrings_IgnoresMultipleValuesWithEmptyString() { final SOURCE = ''' def x = ['xyz', 'abc', 'xyz'] def y = ['foo', 'bar', 'foo'] def z = ['', 'efg', ''] ''' rule.ignoreStrings = ',xyz,foo' assertNoViolations(SOURCE) } @Test void testIgnoreValues_IgnoresValuesSurroundedByWhitespace() { final SOURCE = ''' def x = [' xyz ', 'abc', ' xyz '] def y = ['foo', 'bar', 'foo'] ''' rule.ignoreStrings = ' xyz ,foo' assertNoViolations(SOURCE) } @Test void testIgnoreNumbers_ByDefaultIgnoresEmptyString() { final SOURCE = ''' def x = ['', 'abc', '', 'def', ''] ''' assertNoViolations(SOURCE) } protected Rule createRule() { new DuplicateStringLiteralRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/dry/DuplicateListLiteralRuleTest.groovy�������������0000644�0001750�0001750�00000011103�12041642700�030663� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.dry import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DuplicateListLiteralRule * * @author Chris Mair */ class DuplicateListLiteralRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'DuplicateListLiteral' assert 'MyTest.groovy' =~ rule.doNotApplyToFilesMatching } @Test void testIgnoresDifferentValues_NoViolations() { final SOURCE = ''' class MyClass { def var1 = [1, 1, 1] def var2 = [2, 1, 1] def var3 = [1, 1, 2] def var4 = ['a', 'b'] def var5 = ['b', 'a'] def var6 = ['a', 'b', 'c'] } ''' assertNoViolations(SOURCE) } @Test void testIgnoresVariableValues_NoViolations() { final SOURCE = ''' class MyClass { def init(String name) { def var1 = [name, 'b', 'c'] } def cleanUp(String name) { return [name, 'b', 'c'] } } ''' assertNoViolations(SOURCE) } @Test void testIgnoresNestedListsWithNonConstantValues_NoViolations() { final SOURCE = ''' class MyClass { def name def var1 = [1, ['x', name]] def var2 = [1, ['x', name]] } ''' assertNoViolations(SOURCE) } @Test void testIgnoresValuesContainingExpressions_NoViolations() { final SOURCE = ''' class MyClass { def var1 = [7+5] def var2 = [7+5] } ''' assertNoViolations(SOURCE) } @Test void testIgnoresEmptyList_NoViolations() { final SOURCE = ''' class MyClass { def var1 = [] def var2 = [] } ''' assertNoViolations(SOURCE) } @Test void testDuplicateListLiteral_ListValuesAsConstants() { final SOURCE = ''' class MyClass { def var1 = [1, null, Boolean.FALSE, 'x', true] def var2 = [1, null, Boolean.FALSE, 'x', true] def var3 = ["a", 99] Map getMap() { return ["a", 99] } } ''' assertTwoViolations(SOURCE, 4, "def var2 = [1, null, Boolean.FALSE, 'x', true]", '[1, null, Boolean.FALSE, x, true]', 7, 'return ["a", 99]', '[a, 99]') } @Test void testDuplicateListLiteral_HandlesNestedListLiterals() { final SOURCE = ''' def var1 = [1, [3, 4]] def var2 = [1, [3,4]] ''' assertSingleViolation(SOURCE, 3, 'def var2 = [1, [3,4]]', '[1, [3, 4]]') } @Test void testDuplicateListLiteral_HandlesNestedListLiterals_OuterListsAreNotTheSame() { final SOURCE = ''' def var1 = [123, [3,4]] def var2 = [99, [3,4]] ''' assertSingleViolation(SOURCE, 3, 'def var2 = [99, [3,4]]', '[3, 4]') } @Test void testDuplicateListLiteral_HandlesMapsNestedWithinListLiterals() { final SOURCE = ''' def var1 = [123, [3, 4, [x:99], 5]] def var2 = [99, [3, 4, [x:99], 5]] ''' assertSingleViolation(SOURCE, 3, 'def var2 = [99, [3, 4, [x:99], 5]]', '[3, 4, [x:99], 5]') } @Test void testDuplicateListLiteral_NestedEmptyList_Violations() { final SOURCE = ''' class Lists { def list1 = [1, []] def list2 = [1, []] } ''' assertSingleViolation(SOURCE, 4, 'def list2 = [1, []]', '[1, []]') } protected Rule createRule() { new DuplicateListLiteralRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/dry/DuplicateMapLiteralRuleTest.groovy��������������0000644�0001750�0001750�00000015542�12461174462�030513� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.dry import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DuplicateMapLiteralRule * * @author Chris Mair */ class DuplicateMapLiteralRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'DuplicateMapLiteral' assert 'MyTest.groovy' =~ rule.doNotApplyToFilesMatching } @Test void testIgnoresDifferentKeys_NoViolations() { final SOURCE = ''' class MyClass { def var1 = [a:1, b:1, c:1] def var2 = [a:1, 2:1] def var3 = [a:1, c:1] def var4 = [b:1, c:1] def var1 = [a:1, b:1, c:1, d:1] } ''' assertNoViolations(SOURCE) } @Test void testIgnoresDifferentValues_NoViolations() { final SOURCE = ''' class MyClass { def var1 = [a:1, b:1, c:1] def var2 = [a:2, b:1, c:1] def var3 = [a:1, b:1, c:2] } ''' assertNoViolations(SOURCE) } @Test void testIgnoresMapsWithVariableKeys_NoViolations() { final SOURCE = ''' class MyClass { def init(String name) { def var1 = [(name):1, b:1, c:1] } def cleanUp(String name) { return [(name):1, b:1, c:1] } } ''' assertNoViolations(SOURCE) } @Test void testIgnoresNestedMapsWithNonConstantValues_NoViolations() { final SOURCE = ''' class MyClass { def name def var1 = [a:1, b:[a:name]] def var2 = [a:1, b:[a:name]] } ''' assertNoViolations(SOURCE) } @Test void testIgnoresNestedListsWithNonConstantValues_NoViolations() { final SOURCE = ''' class MyClass { def name def var1 = [a:1, b:['x', name]] def var2 = [a:1, b:['x', name]] } ''' assertNoViolations(SOURCE) } @Test void testIgnoresMapsWithVariableValues_NoViolations() { final SOURCE = ''' class MyClass { private count = 7 def init(String name) { def var1 = [a:name, b:1, c:1] def var2 = [a:count+1, b:1, c:1] def var3 = [a:count+1, b:1, c:1] } def cleanUp(String name) { return [a:name, b:1, c:1] } } ''' assertNoViolations(SOURCE) } @Test void testIgnoresValuesContainingExpressions_NoViolations() { final SOURCE = ''' class MyClass { def var1 = [a:7+5] def var2 = [a:7+5] } ''' assertNoViolations(SOURCE) } @Test void testIgnoresEmptyMap_NoViolations() { final SOURCE = ''' class MyClass { def var1 = [:] def var2 = [:] } ''' assertNoViolations(SOURCE) } @Test void testDuplicateMapLiteral_MapValuesAsConstants() { final SOURCE = ''' class MyClass { def var1 = [a:1, b:null, c:Boolean.FALSE, d:'x', e:true] def var2 = [a:1, b:null, c:Boolean.FALSE, d:'x', e:true] def var3 = ["a":99] Map getMap() { return ["a":99] } } ''' assertTwoViolations(SOURCE, 4, "def var2 = [a:1, b:null, c:Boolean.FALSE, d:'x', e:true]", '[a:1, b:null, c:Boolean.FALSE, d:x, e:true]', 7, 'return ["a":99]', '[a:99]') } @Test void testDuplicateMapLiteral_HandlesNestedMapLiterals() { final SOURCE = ''' def var1 = [a:1, b:[x:3,y:4]] def var2 = [a:1, b:[x:3,y:4]] ''' assertSingleViolation(SOURCE, 3, 'def var2 = [a:1, b:[x:3,y:4]]', '[a:1, b:[x:3, y:4]]') } @Test void testDuplicateMapLiteral_HandlesNestedMapLiterals_OuterMapsAreNotTheSame() { final SOURCE = ''' def var1 = [a:123, b:[x:3,y:4]] def var2 = [a:99, b:[x:3,y:4]] ''' assertSingleViolation(SOURCE, 3, 'def var2 = [a:99, b:[x:3,y:4]]', '[x:3, y:4]') } @Test void testDuplicateMapLiteral_HandlesNestedListLiterals() { final SOURCE = ''' def var1 = [a:1, b:[3,4]] def var2 = [a:1, b:[3,4]] ''' assertSingleViolation(SOURCE, 3, 'def var2 = [a:1, b:[3,4]]', '[a:1, b:[3, 4]]') } @Test void testDuplicateMapLiteral_HandlesMapsNestedWithinListLiterals() { final SOURCE = ''' def var1 = [a:123, b:[3, 4, [x:99], 5]] def var2 = [a:99, b:[3, 4, [other:[x:99]], 5]] ''' assertSingleViolation(SOURCE, 3, 'def var2 = [a:99, b:[3, 4, [other:[x:99]], 5]]', '[x:99]') } @Test void testDuplicateMapLiteral_MapKeysAsConstants() { final SOURCE = ''' def var1 = [null:1, 'b':2, (Boolean.FALSE):3, (4):4, (true):5] def var2 = [null:1, 'b':2, (Boolean.FALSE):3, (4):4, (true):5] ''' assertSingleViolation(SOURCE, 3, "def var2 = [null:1, 'b':2, (Boolean.FALSE):3, (4):4, (true):5]", '[null:1, b:2, Boolean.FALSE:3, 4:4, true:5]') } @Test void testDuplicateMapLiteral_HandlesQuotedKeys() { final SOURCE = ''' class MyClass { def var1 = ["a":99] def var2 = [a:99] } ''' assertSingleViolation(SOURCE, 4, 'def var2 = [a:99]', '[a:99]') } @Test void testDuplicateMapLiteral_NestedEmptyMap_Violations() { final SOURCE = ''' class Maps { def map1 = [messages:[:]] def map2 = [messages:[:]] } ''' assertSingleViolation(SOURCE, 4, 'def map2 = [messages:[:]]', '[messages:[:]]') } protected Rule createRule() { new DuplicateMapLiteralRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/���������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022324� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/FinalClassWithProtectedMemberRuleTest.groovy�0000644�0001750�0001750�00000005731�12041642700�033142� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for FinalClassWithProtectedMemberRule * * @author Hamlet D'Arcy */ class FinalClassWithProtectedMemberRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'FinalClassWithProtectedMember' } @Test void testSuccessScenario() { final SOURCE = ''' final class MyClass1 { public method1() {} def method2() {} @PackageScope def method3() {} private def method3() {} } class MyClass2 { protected def method() {} protected def closure = {} protected String property } final class MyClass { @Override protected def methodName() {} } ''' assertNoViolations(SOURCE) } @Test void testMethodFailure() { final SOURCE = ''' final class MyClass { protected def methodName() {} } ''' assertSingleViolation(SOURCE, 3, 'protected def methodName() {}', 'The method methodName has protected visibility but the enclosing class MyClass is marked final') } @Test void testFieldFailure() { final SOURCE = ''' final class MyClass { protected def closure = {} } ''' assertSingleViolation(SOURCE, 3, 'protected def closure = {}', 'The field closure has protected visibility but the enclosing class MyClass is marked final') } @Test void testPropertyFailure() { final SOURCE = ''' final class MyClass { protected String myProperty } ''' assertSingleViolation(SOURCE, 3, 'protected String myProperty', 'The field myProperty has protected visibility but the enclosing class MyClass is marked final') } protected Rule createRule() { new FinalClassWithProtectedMemberRule() } } ���������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/CloneableWithoutCloneRuleTest.groovy���������0000644�0001750�0001750�00000006115�12311370173�031515� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CloneableWithoutCloneRule * * @author Hamlet D'Arcy */ class CloneableWithoutCloneRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CloneableWithoutClone' } @Test void testNonCloneableClass() { final SOURCE = ''' class CloneableWithoutCloneRuleClass0 { def myMethod() { } } ''' assertNoViolations SOURCE } @Test void testCloneableWithClone() { final SOURCE = ''' class CloneableWithoutCloneRuleClass1 implements Cloneable { public Object clone() { return super.clone() } } ''' assertNoViolations SOURCE } @Test void testCloneableWithMisnamedClone() { final SOURCE = ''' class CloneableWithoutCloneRuleClass2 implements Cloneable, Serializable { public Object CLONE() { } } ''' assertSingleViolation SOURCE, 2, 'class CloneableWithoutCloneRuleClass2 implements Cloneable' } @Test void testCloneableWithMisnamedCloneWithPath() { final SOURCE = ''' class CloneableWithoutCloneRuleClass3 implements java.lang.Cloneable, Serializable { public Object CLONE() { } } ''' assertSingleViolation SOURCE, 2, 'class CloneableWithoutCloneRuleClass3 implements java.lang.Cloneable' } @Test void testCloneableWithParameters() { final SOURCE = ''' class CloneableWithoutCloneRuleClass3 implements java.lang.Cloneable, Serializable { public Object clone(int x) { } } ''' assertSingleViolation SOURCE, 2, 'class CloneableWithoutCloneRuleClass3 implements java.lang.Cloneable' } @Test void testCloneableWithMissingClone() { final SOURCE = ''' class CloneableWithoutCloneRuleClass4 implements Cloneable { } ''' assertSingleViolation SOURCE, 2, 'class CloneableWithoutCloneRuleClass4 implements Cloneable ' } protected Rule createRule() { new CloneableWithoutCloneRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/BuilderMethodWithSideEffectsRuleTest.groovy��0000644�0001750�0001750�00000007433�12041642700�032756� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BuilderMethodWithSideEffectsRule * * @author Hamlet D'Arcy */ class BuilderMethodWithSideEffectsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BuilderMethodWithSideEffects' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { def make() { /* ... */ } def makeSomething() { /* ... */ } def create() { /* ... */ } def createSomething() { /* ... */ } def build() { /* ... */ } def buildSomething() { /* ... */ } } ''' assertNoViolations(SOURCE) } @Test void testMakeMethod() { final SOURCE = ''' class MyClass { void make() { /* ... */ } } ''' assertSingleViolation(SOURCE, 3, 'void make()', "Violation in class MyClass. The method 'make' is named like a builder method but has a void return type") } @Test void testCreateMethod() { final SOURCE = ''' class MyClass { void create() { /* ... */ } } ''' assertSingleViolation(SOURCE, 3, 'void create()', "Violation in class MyClass. The method 'create' is named like a builder method but has a void return type") } @Test void testBuildMethod() { final SOURCE = ''' class MyClass { void build() { /* ... */ } } ''' assertSingleViolation(SOURCE, 3, 'void build()', "Violation in class MyClass. The method 'build' is named like a builder method but has a void return type") } @Test void testMakeSomethingMethod() { final SOURCE = ''' class MyClass { void makeSomething() { /* ... */ } } ''' assertSingleViolation(SOURCE, 3, 'void makeSomething()', "Violation in class MyClass. The method 'makeSomething' is named like a builder method but has a void return type") } @Test void testCreateSomethingMethod() { final SOURCE = ''' class MyClass { void createSomething() { /* ... */ } } ''' assertSingleViolation(SOURCE, 3, 'void createSomething()', "Violation in class MyClass. The method 'createSomething' is named like a builder method but has a void return type") } @Test void testBuildSomethingMethod() { final SOURCE = ''' class MyClass { void buildSomething() { /* ... */ } } ''' assertSingleViolation(SOURCE, 3, 'void buildSomething()', "Violation in class MyClass. The method 'buildSomething' is named like a builder method but has a void return type") } protected Rule createRule() { new BuilderMethodWithSideEffectsRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/NestedForLoopRuleTest.groovy�����������������0000644�0001750�0001750�00000006124�12440206243�030006� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for NestedForLoopRule * * @author Maciej Ziarko */ class NestedForLoopRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'NestedForLoop' } @Test void testNoViolations() { assertNoViolations(''' class TestClass { void methodWithoutNestedForLoops() { for (int i = 0; i < 100; ++i) { println i } for (int i = 0; i < 200; ++i) { println i } } } ''') } @Test void testSingleViolation() { assertInlineViolations(""" class TestClass { void methodWithNestedForLoops() { for (int i = 0; i < 100; ++i) { for (int j = 0; j < 100; ++j) { ${violation()} println i + j } } } } """) } @Test void testMultipleViolations_2ForLoopsInsideFor() { assertInlineViolations(""" class TestClass { void methodWithNestedForLoops() { for (int i = 0; i < 100; ++i) { for (int j = 0; j < 100; ++j) { ${violation()} println i + j } for (int j = 0; j < 100; ++j) { ${violation()} println i + j } } } } """) } @Test void testMultipleViolations_ForInsideForInsideFor() { assertInlineViolations(""" class TestClass { void methodWithNestedForLoops() { for (int i = 0; i < 100; ++i) { for (int j = 0; j < 100; ++j) { ${violation()} for (int k = 0; k < 100; ++k) { ${violation()} println i + j + k } } } } } """) } protected Rule createRule() { new NestedForLoopRule() } private String violation() { return inlineViolation('Nested for loop') } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000152�00000000000�011601� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/ReturnsNullInsteadOfEmptyCollectionRuleTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/ReturnsNullInsteadOfEmptyCollectionRuleTest.g0000644�0001750�0001750�00000017337�12041642700�033320� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ReturnsNullInsteadOfEmptyCollectionRule * * @author Hamlet D'Arcy */ class ReturnsNullInsteadOfEmptyCollectionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ReturnsNullInsteadOfEmptyCollection' } @Test void testNoViolation() { final SOURCE = ''' List myMethod() { def c = { return null // ignore returns from nested closure } def o = new Object() { def foo() { return null // ignore returns from nested class } } return [] } def c = { return [] } ''' assertNoViolations(SOURCE) } @Test void testTernaryReturns() { final SOURCE = ''' def a = { return foo ? null : [] } def b = { return foo ? [] : null } ''' assertTwoViolations SOURCE, 3, 'foo ? null : []', 6, 'foo ? [] : null' } @Test void testElvis() { final SOURCE = ''' def a = { if (x) return null return foo ?: [] } def b = { if (x) return [] return foo ?: null } ''' assertTwoViolations SOURCE, 3, 'return null', 8, 'foo ?: null' } @Test void testListMethod() { final SOURCE = ''' List myMethod() { if (x) return null return foo() } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testCollectionMethod() { final SOURCE = ''' Collection myMethod() { if (x) return null return foo() } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testStringListMethod() { final SOURCE = ''' List<String> myMethod() { if (x) return null return foo() } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testMapMethod() { final SOURCE = ''' Map myMethod() { if (x) return null return foo() } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testGenericMapMethod() { final SOURCE = ''' Map<String, String> myMethod() { if (x) return null return foo() } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testStringListMethodInClass() { final SOURCE = ''' class MyClass { List myMethod() { if (x) return null return [] } } ''' assertSingleViolation(SOURCE, 4, 'null') } @Test void testDefMethod() { final SOURCE = ''' def myMethod() { if (x) return null return [] } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testDefMethodCtorCall() { final SOURCE = ''' def myMethod() { if (x) return null return new ArrayList() } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testDefMethodCtorCallNotCollection() { final SOURCE = ''' def myMethod() { if (x) return null return new java.awt.List() } ''' assertNoViolations(SOURCE) } @Test void testDefMethodCastResult() { final SOURCE = ''' def myMethod() { if (x) return null return foo() as List } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testDefMethodInClass() { final SOURCE = ''' class MyClass { def myMethod() { if (x) return null return [] } } ''' assertSingleViolation(SOURCE, 4, 'null') } @Test void testStringListMethodInInnerClass() { final SOURCE = ''' def o = new Object() { List myMethod() { if (x) return null return [] } } ''' assertSingleViolation(SOURCE, 4, 'null') } @Test void testInClosure() { final SOURCE = ''' def c = { if (x) return null // bad return [] } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testInClosureWithinAClosure() { final SOURCE = ''' def a = { def b = { if (x) return null // bad return [] } def c = { if (x) return null // bad return [] } return [] // ok } ''' assertTwoViolations(SOURCE, 4, 'null', 8, 'null') } @Test void testInAnonymousClassWithinAnonymousClass() { final SOURCE = ''' def a = new Object() { List m1() { def b = new Object() { List m1() { return null } List m2() { return null } } return [] } } ''' assertTwoViolations(SOURCE, 6, 'null', 9, 'null') } @Test void testClosureInAnonymousClassWithinAnonymousClass() { final SOURCE = ''' def a = new Object() { String[] m1() { def b = new Object() { void m1() { def z = { if (q) { return null } else { return [] } } } } return [] } } ''' assertSingleViolation(SOURCE, 8, 'null') } protected Rule createRule() { new ReturnsNullInsteadOfEmptyCollectionRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/ReturnsNullInsteadOfEmptyArrayRuleTest.groovy0000644�0001750�0001750�00000013430�12311370173�033372� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ReturnsNullInsteadOfEmptyArrayRule * * @author Hamlet D'Arcy */ class ReturnsNullInsteadOfEmptyArrayRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ReturnsNullInsteadOfEmptyArray' } @Test void testNoViolation() { final SOURCE = ''' String[] myMethod() { def c = { return null // ignore returns from nested closure } def o = new Object() { def foo() { return null // ignore returns from nested class } } return [] as String[] } def c = { return [] as String[] } ''' assertNoViolations(SOURCE) } @Test void testStringArrayMethod() { final SOURCE = ''' String[] myMethod() { if (x) return null return [] as String[] } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testStringArrayMethodInClass() { final SOURCE = ''' class MyClass { String[] myMethod() { if (x) return null return [] as String[] } } ''' assertSingleViolation(SOURCE, 4, 'null') } @Test void testDefMethod() { final SOURCE = ''' def myMethod() { if (x) return null return [] as String[] } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testTernaryReturns() { final SOURCE = ''' def a = { return foo ? null : [] as String[] } def b = { return foo ? [] as String[] : null } ''' assertTwoViolations SOURCE, 3, 'foo ? null : [] as String[]', 6, 'foo ? [] as String[] : null' } @Test void testDefMethodInClass() { final SOURCE = ''' class MyClass { def myMethod() { if (x) return null return [] as String[] } } ''' assertSingleViolation(SOURCE, 4, 'null') } @Test void testStringArrayMethodInInnerClass() { final SOURCE = ''' def o = new Object() { String[] myMethod() { if (x) return null return [] as String[] } } ''' assertSingleViolation(SOURCE, 4, 'null') } @Test void testInClosure() { final SOURCE = ''' def c = { if (x) return null // bad return [] as String[] } ''' assertSingleViolation(SOURCE, 3, 'null') } @Test void testInClosureWithinAClosure() { final SOURCE = ''' def a = { def b = { if (x) return null // bad return [] as String[] } def c = { if (x) return null // bad return [] as String[] } return [] as String[] // ok } ''' assertTwoViolations(SOURCE, 4, 'null', 8, 'null') } @Test void testInAnonymousClassWithinAnonymousClass() { final SOURCE = ''' def a = new Object() { String[] m1() { def b = new Object() { String[] m1() { return null } String[] m2() { return null } } return [] as String[] } } ''' assertTwoViolations(SOURCE, 6, 'null', 9, 'null') } @Test void testClosureInAnonymousClassWithinAnonymousClass() { final SOURCE = ''' def a = new Object() { String[] m1() { def b = new Object() { void m1() { def z = { if (q) { return null } else { return [] as String[] } } } } return [] as String[] } } ''' assertSingleViolation(SOURCE, 8, 'null') } protected Rule createRule() { new ReturnsNullInsteadOfEmptyArrayRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/InstanceofRuleTest.groovy��������������������0000644�0001750�0001750�00000005700�12415113037�027353� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for InstanceofRule * * @author Chris Mair */ class InstanceofRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'Instanceof' assert rule.ignoreTypeNames == '*Exception' assert rule.doNotApplyToFilesMatching == DEFAULT_TEST_FILES } @Test void testNoViolations() { final SOURCE = ''' class MyClass { def myMethod() { println 123 + 99 } } ''' assertNoViolations(SOURCE) } @Test void test_instanceof_Violation() { final SOURCE = ''' class MyClass { boolean isRunnable = this instanceof Runnable } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'boolean isRunnable = this instanceof Runnable', messageText:'The instanceof operator is used in class MyClass']) } @Test void test_instanceof_Exception_NoViolation() { final SOURCE = ''' class MyClass { boolean isRuntimeException = this instanceof RuntimeException boolean isIOException = this instanceof IOException boolean isException = this instanceof Exception } ''' assertNoViolations(SOURCE) } @Test void test_instanceof_IgnoreTypeNames_Matches_NoViolation() { final SOURCE = ''' class MyClass { boolean isA = this instanceof MyClass boolean isB = this instanceof MyOtherClass } ''' rule.ignoreTypeNames = 'My*Class' assertNoViolations(SOURCE) } @Test void test_instanceof_IgnoreTypeNames_NoMatch_Violation() { final SOURCE = ''' class MyClass { boolean isRunnable = this instanceof Runnable } ''' rule.ignoreTypeNames = 'SomeClass' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'boolean isRunnable = this instanceof Runnable', messageText:'The instanceof operator is used in class MyClass']) } protected Rule createRule() { new InstanceofRule() } } ����������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/PublicInstanceFieldRuleTest.groovy�����������0000644�0001750�0001750�00000004335�12041642700�031133� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for PublicInstanceFieldRule * * @author Victor Savkin */ class PublicInstanceFieldRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'PublicInstanceField' } @Test void testShouldAddNoViolationsForPrivateField() { final SOURCE = ''' class Person { private String name } ''' assertNoViolations SOURCE } @Test void testShouldAddViolationForPublicField() { final SOURCE = ''' class Person { public String name } ''' assertSingleViolation SOURCE, 3, null, "Using public fields is considered bad design. Create property 'name' instead." } @Test void testShouldAddViolationForPublicFieldWithInitializer() { final SOURCE = ''' class Person { public String name = 'John' } ''' assertSingleViolation SOURCE, 3, null, "Using public fields is considered bad design. Create property 'name' instead." } @Test void testShouldAddNoViolationsForPublicStaticField() { final SOURCE = ''' class Person { public static String name } ''' assertNoViolations SOURCE } protected Rule createRule() { new PublicInstanceFieldRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/SimpleDateFormatMissingLocaleRuleTest.groovy�0000644�0001750�0001750�00000004650�12041642700�033136� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for SimpleDateFormatMissingLocaleRule * * @author Hamlet D'Arcy */ class SimpleDateFormatMissingLocaleRuleTest extends AbstractRuleTestCase { private static final VIOLATION_MESSAGE = 'Created an instance of SimpleDateFormat without specifying a Locale' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'SimpleDateFormatMissingLocale' } @Test void testSuccessScenario() { final SOURCE = ''' // OK, includes locale new SimpleDateFormat('pattern', Locale.US) // OK, includes a variable that perhaps is a locale new SimpleDateFormat('pattern', locale) ''' assertNoViolations(SOURCE) } @Test void testMissingLocale() { final SOURCE = ''' new SimpleDateFormat('pattern') ''' assertSingleViolation(SOURCE, 2, "new SimpleDateFormat('pattern')", VIOLATION_MESSAGE) } @Test void testMissingLocaleFullyQualified() { final SOURCE = ''' new java.text.SimpleDateFormat('pattern') ''' assertSingleViolation(SOURCE, 2, "new java.text.SimpleDateFormat('pattern')", VIOLATION_MESSAGE) } @Test void testMissingLocale_NoDuplicateViolation() { final SOURCE = ''' class CalendarUtil { static FORMAT = new SimpleDateFormat('MM/dd/YYYY') } ''' assertSingleViolation(SOURCE, 3, "new SimpleDateFormat('MM/dd/YYYY')", VIOLATION_MESSAGE) } protected Rule createRule() { new SimpleDateFormatMissingLocaleRule() } } ����������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/ToStringReturnsNullRuleTest.groovy�����������0000644�0001750�0001750�00000007435�12407311612�031260� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ToStringReturnsNullRule * * @author Chris Mair */ class ToStringReturnsNullRuleTest extends AbstractRuleTestCase { private static final String ERROR_MESSAGE = 'The toString() method within class MyClass returns null' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ToStringReturnsNull' } @Test void testToString_ReturnsNonNull_NoViolation() { final SOURCE = ''' class MyClass { String toString() { return 'MyClass' } } ''' assertNoViolations(SOURCE) } @Test void testToStringWithParameters_NoViolation() { final SOURCE = ''' class MyClass { String toString(int count) { return null } void toString(String name) { return null } String toString(String name, int count) { return null } } ''' assertNoViolations(SOURCE) } @Test void testSingleReturn_ReturnsNull_Violation() { final SOURCE = ''' class MyClass { String toString() { return null } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'return null', messageText:ERROR_MESSAGE]) } @Test void testNoReturnKeyword_Null_Violation() { final SOURCE = ''' class MyClass { String toString() { calculateStuff() null } } ''' assertViolations(SOURCE, [lineNumber:5, sourceLineText:'null', messageText: ERROR_MESSAGE]) } @Test void testEmptyMethod_ImplicitlyReturnsNull_Violation() { final SOURCE = ''' class MyClass { String toString() { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'String toString()', messageText: ERROR_MESSAGE]) } @Test void testMultipleReturns_MayReturnNull_Violation() { final SOURCE = ''' class MyClass { String toString() { if (foo()) { return 'MyClass' } else { return null } } } ''' assertViolations(SOURCE, [lineNumber:7, sourceLineText:'return null', messageText:ERROR_MESSAGE]) } @Test void testToString_ContainsClosure_NoViolation() { final SOURCE = ''' class MyClass { @Override String toString() { StringBuilder sb = new StringBuilder() (1..10).each { int index -> sb << getCharacter[index] } return sb.toString(); } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new ToStringReturnsNullRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/CloneWithoutCloneableRuleTest.groovy���������0000644�0001750�0001750�00000006320�12311373552�031517� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for CloneWithoutCloneableRule * * @author ArturGajowy */ class CloneWithoutCloneableRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CloneWithoutCloneable' } @Test void testNoViolations() { final SOURCE = ''' class Unrelated { def irrelevant() {} } ''' assertNoViolations(SOURCE) } @Test void testCloneWithCloneable_NoViolations() { final SOURCE = ''' class ProperValueClass implements Cloneable { public Object clone() { } } ''' assertNoViolations(SOURCE) } @Test void testCloneWith_IndirectlyImplementedCloneable_NoViolations() { final SOURCE = ''' class ArrayListsAreCloneable extends ArrayList<String> { def clone() { } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class ValueClass { ValueClass clone() { } } ''' assertSingleViolation(SOURCE, 3, 'ValueClass clone()', violationMessage('ValueClass')) } @Test void testMultipleViolations() { final SOURCE = ''' class ValueClass { def clone() { } } class ValueClass2 { @Override public Object clone() { } } class ValueClass3 { @Override protected Object clone() throws CloneNotSupportedException { } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'def clone()', messageText: violationMessage('ValueClass')], [lineNumber:9, sourceLineText:'Object clone()', messageText:violationMessage('ValueClass2')], [lineNumber:15, sourceLineText:'protected Object clone() throws CloneNotSupportedException', messageText:violationMessage('ValueClass3')] ) } private GString violationMessage(String className) { "Class $className declares a clone() method, but does not implement java.lang.Cloneable interface" } protected Rule createRule() { new CloneWithoutCloneableRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/ConstantsOnlyInterfaceRuleTest.groovy��������0000644�0001750�0001750�00000004545�12041642700�031726� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConstantsOnlyInterfaceRule * * @author Hamlet D'Arcy */ class ConstantsOnlyInterfaceRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ConstantsOnlyInterface' } @Test void testSuccessScenario() { final SOURCE = ''' public interface Interface1 { public static final int CONSTANT_1 = 0 public static final String CONSTANT_2 = "1" void method() } public interface Interface2 { // don't know why you'd want to do this, but it is legal } public interface Interface3 { void method() } ''' assertNoViolations(SOURCE) } @Test void testSuccessInScript() { final SOURCE = ''' int CONSTANT_1 = 0 String CONSTANT_2 = "1" println CONSTANT_1 ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' public interface ConstantInterface { public static final int CONSTANT_1 = 0 public static final String CONSTANT_2 = "1" } ''' assertSingleViolation(SOURCE, 2, 'public interface ConstantInterface', 'The interface ConstantInterface has only fields and no methods defined') } protected Rule createRule() { new ConstantsOnlyInterfaceRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/CloseWithoutCloseableRuleTest.groovy���������0000644�0001750�0001750�00000004415�12041642700�031526� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CloseWithoutCloseableRule * * @author Hamlet D'Arcy */ class CloseWithoutCloseableRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CloseWithoutCloseable' } @Test void testSuccessScenario() { final SOURCE = ''' void close() { } // in script, OK class MyClass implements Closeable { void close() {} } class MyClass2 { private void close() { } // private, OK void close(arg1) { } // with arguments, OK } class MyClass3 { def close() { null } // return type, OK } ''' assertNoViolations(SOURCE) } @Test void testPublicCloseViolation() { final SOURCE = ''' class MyClass { void close() { } } ''' assertSingleViolation(SOURCE, 3, 'void close() { }', 'void close() method defined without implementing Closeable') } @Test void testProtectedCloseViolation() { final SOURCE = ''' class MyClass { protected void close() { } } ''' assertSingleViolation(SOURCE, 3, 'protected void close() { }', 'void close() method defined without implementing Closeable') } protected Rule createRule() { new CloseWithoutCloseableRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000151�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/AbstractClassWithoutAbstractMethodRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/AbstractClassWithoutAbstractMethodRuleTest.gr0000644�0001750�0001750�00000004413�12041642700�033306� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AbstractClassWithoutAbstractMethodRule * * @author 'Hamlet D'Arcy' */ class AbstractClassWithoutAbstractMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AbstractClassWithoutAbstractMethod' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { void method1() { } void method2() { } } abstract class MyClass2 extends AbstractParent{ void method1() { } void method2() { } } abstract class MyClass3 extends BaseParent{ void method1() { } void method2() { } } abstract class MyBaseClass { void method1() { } abstract void method2() } interface MyMarkerInterface { } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' abstract class MyBaseClass { void method1() { } void method2() { } } ''' assertSingleViolation(SOURCE, 2, 'abstract class MyBaseClass', 'The abstract class MyBaseClass contains no abstract methods') } protected Rule createRule() { new AbstractClassWithoutAbstractMethodRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/BooleanMethodReturnsNullRuleTest.groovy������0000644�0001750�0001750�00000015526�12467643554�032252� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BooleanMethodReturnsNullRule * * @author Hamlet D'Arcy */ class BooleanMethodReturnsNullRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BooleanMethodReturnsNull' } @Test void testProperReturnOfTrueAndFalse_NoViolations() { final SOURCE = ''' def c = { if (foo()) { return true } else { return false } } def scriptMethod() { if (foo()) { return true } else { return false } } class MyClass { def x = new Object() { def method1() { if (foo()) { return true } else { return false } } } def method2() { def y = { if (foo()) { return true } else { return false } } if (foo()) { return true } else { return false } } boolean method3() { if (foo()) { return true } else { return false } } boolean method4() { if (foo()) { return ret() as Boolean } else { return ret() as Boolean } } } ''' assertNoViolations(SOURCE) } @Test void testDefMethodReturnsNull() { final SOURCE = ''' def scriptMethod() { if (foo()) { return true } else { return null } } ''' assertSingleViolation(SOURCE, 6, 'return null') } @Test void testDefTernaryReturnsNull() { final SOURCE = ''' def scriptMethod() { return x ? null : true } def scriptMethod2() { return x ? false : null } ''' assertTwoViolations(SOURCE, 3, 'x ? null : true', 6, 'x ? false : null') } @Test void testDefClassMethodReturnsNull() { final SOURCE = ''' class MyClass { def scriptMethod() { if (foo()) { return true } else { return null } } } ''' assertSingleViolation(SOURCE, 7, 'return null') } @Test void testAnonymousClassMethodReturnsNull() { final SOURCE = ''' def x = new Object() { def scriptMethod() { if (foo()) { return true } else { return null } } } ''' assertSingleViolation(SOURCE, 7, 'return null') } @Test void testDefMethodReturnsNullAndTRUE() { final SOURCE = ''' def scriptMethod() { if (foo()) { return Boolean.TRUE } else { return null } } ''' assertSingleViolation(SOURCE, 6, 'return null') } @Test void testDefMethodReturnsBooleanCast() { final SOURCE = ''' def scriptMethod() { if (foo()) { return ret() as Boolean } else { return null } } ''' assertSingleViolation(SOURCE, 6, 'return null') } @Test void testBooleanMethodReturnsNull() { final SOURCE = ''' boolean scriptMethod() { if (foo()) { return ret() } else { return null } } ''' assertSingleViolation(SOURCE, 6, 'return null') } @Test void testMethodReturnsNonBooleanTypesAndNull_NoViolations() { final SOURCE = ''' def scriptMethod(clazz) { if (clazz == String) { return 'something' } if (clazz == Number) { return 1 } if (clazz == Boolean) { return true } return null } ''' assertNoViolations(SOURCE) } @Test void testClosureReturnsNull() { final SOURCE = ''' def closure = { if (foo()) { return true } else { return null } } ''' assertSingleViolation(SOURCE, 6, 'return null') } @Test void testClosureReturnsNonBooleanTypesAndNull_NoViolations() { final SOURCE = ''' def closure = { if (clazz == String) { return 'something' } if (clazz == Number) { return 1 } if (clazz == Boolean) { return true } return null } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new BooleanMethodReturnsNullRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/PrivateFieldCouldBeFinalRuleTest.groovy������0000644�0001750�0001750�00000033131�12427743540�032062� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for PrivateFieldCouldBeFinalRule * * @author Chris Mair */ class PrivateFieldCouldBeFinalRuleTest extends AbstractRuleTestCase { private static final VIOLATION_MESSAGE = 'Private field [count] in class MyClass is only' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'PrivateFieldCouldBeFinal' } @Test void testApplyTo_NonPrivateField_OnlySetWithinInitializer_NoViolations() { final SOURCE = ''' class MyClass { protected int count = 23 int someProperty = 99 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateFieldSetWithinMethod_NoViolations() { final SOURCE = ''' class MyClass { private int count = 11 void initialize() { count = 1 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateFieldSetWithinClosure_NoViolations() { final SOURCE = ''' class MyClass { private int count = 11 def myClosure = { count = 1 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateFieldNeverSet_NoViolations() { final SOURCE = ''' class MyClass { private int count } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateField_OnlyInitializedInClosureWithinConstructor_NoViolations() { final SOURCE = ''' class MyClass { private int count public MyClass() { 1..2.each { count = 99 } } } ''' // Closures within constructor cannot set final fields, so cannot make count final assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateFieldSetWithinInitializerAndWithinMethod_NoViolations() { final SOURCE = ''' class MyClass { private int count = 99 void initialize() { count = 1 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateField_AssignedUsingOtherOperators_NoViolations() { final SOURCE = ''' class MyClass { private value1 = 0 private value2 = 3 private value3 = 2 private value4 = 0 private value5 = 0 private value6 = 0 void initialize() { value1 += 2 value2 *= 3 value3 |= 1 value4++ value5-- ++value6 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateFieldSetWithinConstructorAndWithinMethod_NoViolations() { final SOURCE = ''' class MyClass { private int count void initialize() { count = 1 } MyClass(int c) { count = 99 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateFieldSetUsingThis_NoViolations() { final SOURCE = ''' class MyClass { private int count = 99 void initialize() { this.count = 1 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateField_OnlySetWithinInitializer_Violation() { final SOURCE = ''' class MyClass { private int count = 0 } ''' assertSingleViolation(SOURCE, 3, 'private int count = 0', VIOLATION_MESSAGE) } @Test void testApplyTo_PrivateStaticNonFinalField_OnlySetWithinInitializer_Violation() { final SOURCE = ''' class MyClass { private static int count = 100 } ''' assertSingleViolation(SOURCE, 3, 'private static int count = 100', VIOLATION_MESSAGE) } @Test void testApplyTo_PrivateField_ComparedWithinMethodButNotSet_Violation() { final SOURCE = ''' class MyClass { private int count = 0 private completed = 0 boolean hasCount() { count > 0 } boolean isReady() { completed == 5 } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'private int count = 0', messageText:VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'private completed = 0', messageText:'Private field [completed] in class MyClass is only']) } @Test void testApplyTo_PrivateField_ReferencedWithinMethodButNotSet_Violation() { final SOURCE = ''' class MyClass { private int count = 0 void printCount() { println count } } ''' assertSingleViolation(SOURCE, 3, 'private int count = 0', VIOLATION_MESSAGE) } @Test void testApplyTo_PrivateField_OnlySetWithinConstructor_Violation() { final SOURCE = ''' class MyClass { private int count MyClass() { count = 1 } } ''' assertSingleViolation(SOURCE, 3, 'private int count', VIOLATION_MESSAGE) } @Test void testApplyTo_PrivateField_OnlySetWithinConstructorUsingThis_Violation() { final SOURCE = ''' class MyClass { private int count MyClass() { this.count = 1 } } ''' assertSingleViolation(SOURCE, 3, 'private int count', VIOLATION_MESSAGE) } @Test void testApplyTo_PrivateFields_MultipleViolations() { final SOURCE = ''' class MyClass { private int count private name = 'abc' MyClass() { count = 1 } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'private int count', messageText:VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:"private name = 'abc'", messageText:'Private field [name] in class MyClass is only']) } @Test void testApplyTo_PrivateField_SetWithinInitializerAndConstructor_Violation() { final SOURCE = ''' class MyClass { private int count = 2 MyClass() { count = 0 } } ''' assertSingleViolation(SOURCE, 3, 'private int count', VIOLATION_MESSAGE) } @Test void testApplyTo_PrivateFinalField_OnlySetWithinInitializer_NoViolations() { final SOURCE = ''' class MyClass { private final int count = 99 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateFinalField_OnlySetWithinConstructor_NoViolations() { final SOURCE = ''' class MyClass { private final int count MyClass() { count = 1 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateField_MultipleClassesWithinSource() { final SOURCE = ''' class MyClass { private int count = 0 private other = 'abc' } class MyOtherClass { int defaultCount = count int other = 123 void init() { other = 456 } } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'private int count = 0', messageText:VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:"private other = 'abc'", messageText:'Private field [other] in class MyClass is only']) } @Test void testApplyTo_PrivateField_ReferencedWithinInnerClass_NoViolations() { final SOURCE = ''' class MyClass { private int count = 0 class MyInnerClass { def doStuff() { count = count + 5 } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateField_ReferencedWithinAnonymousInnerClass_NoViolations() { final SOURCE = ''' class MyClass { private int count = 0 def runnable = new Runnable() { void run() { count = count + 5 } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateField_PostfixAndPrefixOperators() { final SOURCE = ''' class FakeIdGeneratorHelper { private static long id = 0 private long negCounter = 0 private long c1 = 0 private long c2 = 0 long generate(SessionImplementor session) { println id++ println negCounter-- println (--c1) println (--c2) } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MultipleClassesWithinSource_HavePrivateFieldWithSameName_Violation() { final SOURCE = ''' class MyOtherClass { private count def doStuff() { count = new MyClass(count) } } class MyClass { private int count protected MyClass(int count) { this.count = count } } ''' assertSingleViolation(SOURCE, 11, 'private int count', VIOLATION_MESSAGE) } @Test void testApplyTo_IgnoreFieldNames_NoViolations() { final SOURCE = ''' class MyClass { private int count = 0 private int other = 0 } ''' rule.ignoreFieldNames = 'count, xxx, ot*r' assertNoViolations(SOURCE) } @Test void testApplyTo_DoNotApplyToClassNames_NoViolations() { final SOURCE = ''' class MyClass { private int count = 0 } ''' rule.doNotApplyToClassNames = 'MyClass' assertNoViolations(SOURCE) } @Test void testApplyTo_SuppressWarningsOnClass_NoViolations() { final SOURCE = ''' @SuppressWarnings('PrivateFieldCouldBeFinal') class MyClass { private int count = 0 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ignoreJpaEntities_Entity_NoViolations() { final SOURCE = ''' @Entity class MyClass { private DateTime created = DateTime.now() } ''' rule.ignoreJpaEntities = true assertNoViolations(SOURCE) } @Test void testApplyTo_ignoreJpaEntities_fullPackageEntity_NoViolations() { final SOURCE = ''' @javax.persistence.Entity class MyClass { private DateTime created = DateTime.now() } ''' rule.ignoreJpaEntities = true assertNoViolations(SOURCE) } @Test void testApplyTo_ignoreJpaEntities_MappedSuperclass_NoViolations() { final SOURCE = ''' @MappedSuperclass class MyClass { private DateTime created = DateTime.now() } ''' rule.ignoreJpaEntities = true assertNoViolations(SOURCE) } @Test void testApplyTo_ignoreJpaEntities_fullPackageMappedSuperclass_NoViolations() { final SOURCE = ''' @javax.persistence.MappedSuperclass class MyClass { private DateTime created = DateTime.now() } ''' rule.ignoreJpaEntities = true assertNoViolations(SOURCE) } protected Rule createRule() { new PrivateFieldCouldBeFinalRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000151�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/AbstractClassWithPublicConstructorRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/AbstractClassWithPublicConstructorRuleTest.gr0000644�0001750�0001750�00000004663�12041642700�033345� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AbstractClassWithPublicConstructorRule * * @author Chris Mair */ class AbstractClassWithPublicConstructorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AbstractClassWithPublicConstructor' } @Test void testNoViolations() { final SOURCE = ''' class MyClass { } abstract class MyClass2 { } abstract class MyClass3 { protected MyClass3() { } def method1() { } public int method2() { } } abstract class MyClass4 extends AbstractParent { protected MyClass4() { this(23) } private MyClass4(int count) { } } interface MyInterface { } ''' assertNoViolations(SOURCE) } @Test void testAbstractClassWithOnlyPublicConstructor() { final SOURCE = ''' abstract class MyClass { MyClass() { } } ''' assertSingleViolation(SOURCE, 3, 'MyClass() { }', 'MyClass') } @Test void testAbstractClassWithMultipleConstructors() { final SOURCE = ''' abstract class MyClass { protected MyClass() { } public MyClass(int count) { } private MyClass(String name) { } } ''' assertSingleViolation(SOURCE, 4, 'public MyClass(int count) { }', 'MyClass') } protected Rule createRule() { new AbstractClassWithPublicConstructorRule() } } �����������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/CompareToWithoutComparableRuleTest.groovy����0000644�0001750�0001750�00000005063�12041642700�032526� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for CompareToWithoutComparableRule * * @author Hamlet D'Arcy */ class CompareToWithoutComparableRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'CompareToWithoutComparable' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass implements Comparable { int compareTo(Object o) { 0 } } class MyClass2 implements Serializable, Comparable { int compareTo(Object o) { 0 } } class MyClass3 { int compareTo(Object o1, Object o2) { 0 } } ''' assertNoViolations(SOURCE) } @Test void testNoInterfaces() { final SOURCE = ''' class MyClass { int compareTo(Object o) { 0 } } ''' assertSingleViolation(SOURCE, 2, 'class MyClass', 'compareTo method at line 3 would implement Comparable.compareTo(Object) but the enclosing class does not implement Comparable') } @Test void testTwoInterfaces() { final SOURCE = ''' class MyClass implements Serializable, Cloneable { int compareTo(Object o) { 0 } } ''' assertSingleViolation(SOURCE, 2, 'class MyClass', 'compareTo method at line 3 would implement Comparable.compareTo(Object) but the enclosing class does not implement Comparable') } protected Rule createRule() { new CompareToWithoutComparableRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/LocaleSetDefaultRuleTest.groovy��������������0000644�0001750�0001750�00000005113�12311373552�030445� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for LocaleSetDefaultRule * * @author mingzhi.huang, rob.patrick * @author Chris Mair */ class LocaleSetDefaultRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'LocaleSetDefault' } @Test void testNoViolations() { final SOURCE = ''' Locale.getAvailableLocales() Other.setDefault(Locale.US) Other.setDefault(Locale.Category.DISPLAY, Locale.US) println Locale.getDefault() println Locale.default println Other.default ''' assertNoViolations(SOURCE) } @Test void testLocaleSetDefault_Violations() { final SOURCE = ''' java.util.Locale.setDefault(Locale.FRANCE) Locale.setDefault(Locale.UK) Locale.setDefault(Locale.Category.DISPLAY, Locale.JAPAN) ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'java.util.Locale.setDefault', messageText:'Avoid explicit calls to Locale.setDefault'], [lineNumber:3, sourceLineText:'Locale.setDefault', messageText:'Avoid explicit calls to Locale.setDefault'], [lineNumber:4, sourceLineText:'Locale.setDefault', messageText:'Avoid explicit calls to Locale.setDefault']) } @Test void testLocaleDefaultEquals_Violations() { final SOURCE = ''' java.util.Locale.default = Locale.FRANCE Locale.default = Locale.UK ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'java.util.Locale.default', messageText:'Avoid explicit assignment to Locale.default'], [lineNumber:3, sourceLineText:'Locale.default', messageText:'Avoid explicit assignment to Locale.default']) } protected Rule createRule() { new LocaleSetDefaultRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/EmptyMethodInAbstractClassRuleTest.groovy����0000644�0001750�0001750�00000006645�12041642700�032472� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyMethodInAbstractClassRule * * @author Hamlet D'Arcy */ class EmptyMethodInAbstractClassRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyMethodInAbstractClass' } @Test void testSuccessScenario() { final SOURCE = ''' abstract class MyClass { abstract def method1() def method2() { return "value" } private void method3() { // private is OK } private void method4() { return null // private is OK } void method5() { println '...' // has implementation } def method6() { "value" // implicit return } } class MyOtherClass { void method1() { // OK because not in abstract class } private void method4() { return null // OK because not in abstract class } } ''' assertNoViolations(SOURCE) } @Test void testReturnVoid() { final SOURCE = ''' abstract class MyClass { void couldBeAbstract() { // Should be abstract method } } ''' assertSingleViolation(SOURCE, 3, 'void couldBeAbstract()', 'The method couldBeAbstract in abstract class MyClass is empty. Consider making it abstract') } @Test void testReturnNull() { final SOURCE = ''' abstract class MyClass { def couldBeAbstract() { return null // Should be abstract method } } ''' assertSingleViolation(SOURCE, 3, 'def couldBeAbstract()', 'The method couldBeAbstract in abstract class MyClass contains no logic. Consider making it abstract') } @Test void testReturnNullImplicitReturn() { final SOURCE = ''' abstract class MyClass { def couldBeAbstract() { null // Should be abstract method } } ''' assertSingleViolation(SOURCE, 3, 'def couldBeAbstract()', 'The method couldBeAbstract in abstract class MyClass contains no logic. Consider making it abstract') } protected Rule createRule() { new EmptyMethodInAbstractClassRule() } } �������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/ImplementationAsTypeRuleTest.groovy����������0000644�0001750�0001750�00000013401�12051324426�031374� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test /** * Tests for ImplementationAsTypeRule * * @author Chris Mair */ class ImplementationAsTypeRuleTest extends AbstractRuleTestCase { private static final BAD_TYPES = [ 'java.util.ArrayList', 'java.util.ArrayList<String>', 'java.util.GregorianCalendar', 'java.util.HashMap', 'java.util.HashMap<String,String>', 'java.util.HashSet', 'java.util.HashSet<String>', 'java.util.Hashtable', 'java.util.Hashtable<Integer,String>', 'java.util.LinkedHashMap', 'java.util.LinkedHashMap<Integer,BigDecimal>', 'java.util.LinkedHashSet', 'java.util.LinkedHashSet<Integer>', 'java.util.LinkedList', 'java.util.LinkedList<String>', 'java.util.TreeMap', 'java.util.TreeMap<String,Integer>', 'java.util.TreeSet', 'java.util.TreeSet<String>', 'java.util.Vector', 'java.util.Vector<Integer>', 'java.util.concurrent.CopyOnWriteArrayList', 'java.util.concurrent.CopyOnWriteArrayList<String>', 'java.util.concurrent.CopyOnWriteArraySet', 'java.util.concurrent.ConcurrentHashMap', 'java.util.concurrent.ArrayBlockingQueue', 'java.util.concurrent.ConcurrentLinkedQueue', 'java.util.concurrent.DelayQueue', 'java.util.concurrent.LinkedBlockingQueue', 'java.util.concurrent.PriorityBlockingQueue', 'java.util.concurrent.PriorityQueue', 'java.util.concurrent.SynchronousQueue', ] private allBadTypes @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ImplementationAsType' } @Test void testApplyTo_Parameters_NoViolations() { final SOURCE = ''' def findUnique(Calendar cal, Map map, Set set, List list, def other) { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ReturnTypes_NoViolations() { final SOURCE = ''' Calendar m1() { } Map m2() { } List m3() { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Variables_NoViolations() { final SOURCE = ''' Calendar v1 Map v2 List v3 ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MethodParameters_Violations() { allBadTypes.each { badType -> log("Testing for [$badType]") final SOURCE = "def doSomething($badType parm) { }" assertSingleViolation(SOURCE, 1, SOURCE) } } @Test void testApplyTo_ConstructorParameters_Violations() { allBadTypes.each { badType -> final SOURCE = """ class MyClass { MyClass($badType parm) { } } """ assertSingleViolation(SOURCE, 3, "$badType parm") } } @Test void testApplyTo_ClosureParameters_Violations() { allBadTypes.each { badType -> log("Testing for [$badType]") final SOURCE = "def closure = { $badType parm -> }" assertSingleViolation(SOURCE, 1, "$badType parm") } } @Test void testApplyTo_ReturnTypes_Violations() { allBadTypes.each { badType -> final SOURCE = "$badType doSomething() { }" assertSingleViolation(SOURCE, 1, SOURCE) } } @Test void testApplyTo_VariableTypes_Violations() { allBadTypes.each { badType -> final SOURCE = """ def myMethod() { $badType someVariable = null } """ assertSingleViolation(SOURCE, 3, "$badType someVariable") } } @Test void testApplyTo_MultipleVariables_Violations() { final SOURCE = ''' def myMethod() { def (LinkedList v1, Vector v2) = [null, null] } ''' assertViolations(SOURCE, [lineNumber: 3, sourceLineText:'LinkedList v1'], [lineNumber: 3, sourceLineText:'Vector v2']) } @Test void testApplyTo_FieldTypes_Violations() { allBadTypes.each { badType -> final SOURCE = """ class MyClass { $badType someField } """ assertSingleViolation(SOURCE, 3, "$badType someField") } } @Before void setUpImplementationAsTypeRuleTest() { def badTypesClassNameOnly = BAD_TYPES.collect { badType -> classNameOnly(badType) } allBadTypes = BAD_TYPES + badTypesClassNameOnly } protected Rule createRule() { new ImplementationAsTypeRule() } private String classNameOnly(String fullClassName) { def index = fullClassName.lastIndexOf('.') assert index > -1 fullClassName[index + 1..-1] } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/design/StatelessSingletonRuleTest.groovy������������0000644�0001750�0001750�00000012401�12050572112�031106� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.design import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for StatelessSingletonRule * * @author Victor Savkin */ class StatelessSingletonRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'StatelessSingleton' } @Test void testShouldAddNoViolationsForStatelessClassThatIsNotSingleton() { final SOURCE = ''' class Service { void processItem(item){ } } ''' assertNoViolations SOURCE } @Test void testShouldAddNoViolationsForStatefulClassThatIsNotSingleton() { final SOURCE = ''' class Service { def state void processItem(item){ } } ''' assertNoViolations SOURCE } @Test void testShouldAddNoViolationsForStatefulClassAnnotatedAsSingleton() { final SOURCE = ''' @groovy.lang.Singleton class Service { def state } ''' assertNoViolations SOURCE } @Test void testShouldAddNoViolationsForStatefulClassImplementingSingletonPattern() { final SOURCE = ''' class Service { static Service instance = new Service() def state } ''' assertNoViolations SOURCE } @Test void testShouldAddViolationForClassAnnotatedAsSingletonThatDoesNotHaveState() { final SOURCE = ''' @groovy.lang.Singleton class Service { void processItem(item){ } } ''' assertSingleViolation SOURCE, 3, 'class Service', createErrorMsgForClass('Service') } @Test void testShouldAddNoViolationsForClassAnnotatedAsSingletonExtendingAnotherClass() { final SOURCE = ''' class Parent {} @groovy.lang.Singleton class Service extends Parent { void processItem(item){ } } ''' assertNoViolations SOURCE } @Test void testShouldAddViolationForClassHavingOneStaticFieldOfItsOwnType() { final SOURCE = ''' class Service { static Service srv void processItem(item){ } } ''' assertSingleViolation SOURCE, 2, 'class Service', createErrorMsgForClass('Service') } @Test void testShouldAddViolationForClassHavingOneStaticFieldNamedInstance() { final SOURCE = ''' class Service { static instance void processItem(item){ } } ''' assertSingleViolation SOURCE, 2, 'class Service', createErrorMsgForClass('Service') } @Test void testShouldAddViolationForClassHavingOneStaticFieldNamed_Instance() { final SOURCE = ''' class Service { static _instance void processItem(item){ } } ''' assertSingleViolation SOURCE, 2, 'class Service', createErrorMsgForClass('Service') } @Test void testShouldAddNoViolationsForClassHavingStaticFieldNamedInstanceOfDifferentType() { final SOURCE = ''' class Service { static String instance void processItem(item){ } } ''' assertNoViolations SOURCE } @Test void testShouldAddNoViolationsForClassImplementingSingletonPatternAndExtendingAnotherClass() { final SOURCE = ''' class Parent {} class Service extends Parent { static Service srv void processItem(item){ } } ''' assertNoViolations SOURCE } @Test void testShouldAddNoViolationsForClassHaving2StaticFieldsOfItsOwnType() { final SOURCE = ''' class Service { static Service srv1, srv1 void processItem(item){ } } ''' assertNoViolations SOURCE } protected Rule createRule() { new StatelessSingletonRule() } private createErrorMsgForClass(name) { "There is no point in creating a stateless Singleton. Make a new instance of '$name' with the new keyword instead." } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/InlineViolationsParserTest.groovy�������������������0000644�0001750�0001750�00000016076�12311370173�027635� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule import org.junit.Test import static org.codenarc.rule.InlineViolationsParser.inlineViolation /** * Tests for InlineViolationsParser * * @author Artur Gajowy */ class InlineViolationsParserTest { @Test void testFindsNoViolations() { def source = ''' class NoViolations { } ''' assertParse(source, [], source) } @Test void testFindsSingleViolation() { def violatingLine = /println 'Hello, World!'/ def violationMessage = /Use a logger instead of a println!/ assertParse( violatingLine + ' ' + "#$violationMessage", [createViolation(1, violatingLine, violationMessage)], violatingLine ) } @Test void testFindsSingleViolationWhenUsingInlineViolationMethod() { def violatingLine = /println 'Hello, World!'/ def violationMessage = /Use a logger instead of a println!/ assertParse( violatingLine + ' ' + "${inlineViolation(violationMessage)}", [createViolation(1, violatingLine, violationMessage)], violatingLine ) } @Test void testFindsViolationsInMultipleLines() { assertParse(""" class TwoViolations { ${inlineViolation('violation 1')} String foo } ${inlineViolation('violation 2')} """, [ createViolation(2, 'class TwoViolations {', 'violation 1'), createViolation(4, '}', 'violation 2'), ], ''' class TwoViolations { String foo } ''') } @Test void testFindsMultipleViolationsPerLine() { assertParse(""" class TwoViolations { ${inlineViolation('violation 1')}${inlineViolation('violation 2')} String foo ${inlineViolation('violation 3')} ${inlineViolation('violation 4')} } """, [ createViolation(2, 'class TwoViolations {', 'violation 1'), createViolation(2, 'class TwoViolations {', 'violation 2'), createViolation(3, 'String foo', 'violation 3'), createViolation(3, 'String foo', 'violation 4'), ], ''' class TwoViolations { String foo } ''') } @Test void testFindsNoViolationsInEmptySource() { String source = '' assertParse(source, [], source) } @Test void testFindsNoViolationsInAllWhitespaceSource() { String source = ''' ''' assertParse(source, [], source) } @Test @SuppressWarnings('ConsecutiveBlankLines') void testFindsViolationsInOtherwiseEmptySource() { assertParse(""" #violation 1 ${inlineViolation('violation 2')} """, [ createViolation(2, '', 'violation 1'), createViolation(3, '', 'violation 2') ], ''' ''') } @Test void testViolationMessagesCanContainEscapedHash() { def violatingLine = /def penguin/ def violationMessage = /'penguin' is a swearword. Ask on #kernelnewbies why./ assertParse( "$violatingLine #'penguin' is a swearword. Ask on \\#kernelnewbies why.", [createViolation(1, violatingLine, violationMessage)], violatingLine ) } @Test void testViolationMessagesAreEscapedByInlineViolationMethod() { def violatingLine = /def penguin/ def violationMessage = /'penguin' is a swearword. Ask on #kernelnewbies why./ assertParse( "$violatingLine ${inlineViolation(violationMessage)}", [createViolation(1, violatingLine, violationMessage)], violatingLine ) } @Test void testBackslashAtViolationMessageEndDoesNotEscapeNextViolation() { def messageEndingWithBackslash = 'It\'s a trap!\\' def anotherMessage = 'Yep, I know...' assertParse( "${inlineViolation(messageEndingWithBackslash)}#$anotherMessage", [ createViolation(1, '', messageEndingWithBackslash), createViolation(1, '', anotherMessage) ], '' ) } @Test void testNoViolationsInScriptSource() { def source = '''#!/usr/bin/groovy println 'All well!' ''' assertParse(source, [], source) } @Test void testViolationsInScriptSource() { assertParse( """#!/usr/bin/groovy #Hardcoded groovy location! Use `\\#!/usr/bin/env groovy` instead! #Really do! println "All well" ${inlineViolation('v1')}${inlineViolation('v2')} #v3#v4 """, [ createViolation(1, '#!/usr/bin/groovy', 'Hardcoded groovy location! Use `#!/usr/bin/env groovy` instead!'), createViolation(1, '#!/usr/bin/groovy', 'Really do!'), createViolation(2, 'println "All well"', 'v1'), createViolation(2, 'println "All well"', 'v2'), createViolation(3, '', 'v3'), createViolation(3, '', 'v4'), ], '''#!/usr/bin/groovy println "All well" ''' ) } @Test void testOnlyFirstTwoCharactersOfScriptTreatedAsShebang() { def violationMessage = '!/user/bin/groovy' def shebang = "#$violationMessage" assertParse(" $shebang", [createViolation(1, '', violationMessage)], '') assertParse("\n$shebang", [createViolation(2, '', violationMessage)], '\n') } private Map createViolation(int lineNumber, String sourceLineText, String messageText) { return [lineNumber: lineNumber, sourceLineText: sourceLineText, messageText: messageText] } private void assertParse(String source, List<Map> expectedViolations, String expectedSourceWithoutMarkers) { def expectedSource = removeTrailingWhitespace(expectedSourceWithoutMarkers) def parser = new InlineViolationsParser() def result = parser.parse(source) assert result.violations == expectedViolations assert result.source == expectedSource } private String removeTrailingWhitespace(String lines) { lines.replaceAll(~/(?m)[ \t\f]*$/, '') } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/���������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022324� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/PackageNameMatchesFilePathRuleTest.groovy����0000644�0001750�0001750�00000013555�12410135450�032345� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for PackageMismatchesFilepathRule * * @author Simon Tost */ class PackageNameMatchesFilePathRuleTest extends AbstractRuleTestCase { @Before void setup() { sourceCodePath = '/some/absolute/path/to/project/org/organization/project/component/module/MyClass.groovy' sourceCodeName = 'MyClass.groovy' } @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'PackageNameMatchesFilePath' } @Test void testGroupId_NullOrEmpty() { final SOURCE = '''\ package ignore ''' rule.groupId = null assertNoViolations(SOURCE) assert !rule.ready rule.groupId = '' assertNoViolations(SOURCE) assert !rule.ready } @Test void testSourceCodePath_NullOrEmpty() { final SOURCE = '''\ package ignore ''' rule.groupId = 'org.organization' sourceCodePath = null assertNoViolations(SOURCE) assert rule.ready sourceCodePath = '' assertNoViolations(SOURCE) assert rule.ready } @Test void testNoViolations() { final SOURCE = '''\ package org.organization.project.component.module ''' rule.groupId = 'org.organization' assertNoViolations(SOURCE) } @Test void testNoSubmodule() { final SOURCE = '''\ package org.organization ''' sourceCodePath = '/some/absolute/path/to/project/org/organization/MyClass.groovy' rule.groupId = 'org.organization' assertNoViolations(SOURCE) } @Test void testRelativePath() { final SOURCE = '''\ package org.organization.project.component.module ''' sourceCodePath = 'org/organization/project/component/module/MyClass.groovy' rule.groupId = 'org.organization' assertNoViolations(SOURCE) } @Test void testScriptsOk() { final SOURCE = '''\ println 'Hello world!' ''' assertNoViolations(SOURCE) } @Test void testDifferentPackage() { final SOURCE = '''\ package other.pack.age.name ''' rule.groupId = 'org.organization' assertSingleViolation( SOURCE, 1, 'package other.pack.age.name', "Could not find groupId 'org.organization' in package (other.pack.age.name) or file's path ($sourceCodePath)", ) } @Test void testTypoInGroupId() { final SOURCE = '''\ package org.orgXnization.project.component.module ''' rule.groupId = 'org.organization' assertSingleViolation( SOURCE, 1, 'package org.orgXnization.project.component.module', "Could not find groupId 'org.organization' in package (org.orgXnization.project.component.module) or file's path ($sourceCodePath)", ) } @Test void testTypoInSubmodule() { final SOURCE = '''\ package org.organization.project.compXnent.module ''' rule.groupId = 'org.organization' assertSingleViolation( SOURCE, 1, 'package org.organization.project.compXnent.module', "The package source file's path (${filePath('org_organization_project_component_module')}) should match the package declaration", ) } @Test void testMissingSubpackage() { final SOURCE = '''\ package org.organization.project.component ''' rule.groupId = 'org.organization' assertSingleViolation( SOURCE, 1, 'package org.organization.project.component', "The package source file's path (${filePath('org_organization_project_component_module')}) should match the package declaration", ) } @Test void testExtraSubpackage() { final SOURCE = '''\ package org.organization.project.component.module.extra ''' rule.groupId = 'org.organization' assertSingleViolation( SOURCE, 1, 'package org.organization.project.component.module.extra', "The package source file's path (${filePath('org_organization_project_component_module')}) should match the package declaration", ) } @Test void testDuplicateOccurrenceOfGroupId() { sourceCodePath = filePath('src_main_groovy_org_organization_project_org_component_module_MyClass.groovy') final SOURCE = '''\ package org.organization.project.org.compXnent.module ''' rule.groupId = 'org' assertSingleViolation( SOURCE, 1, 'package org.organization.project.org.compXnent.module', "The package source file's path (${filePath('org_organization_project_org_component_module')}) should match the package declaration", ) } protected Rule createRule() { new PackageNameMatchesFilePathRule() } private String filePath(pathPattern) { pathPattern.tr('_', File.separator) } } ���������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/FactoryMethodNameRuleTest.groovy�������������0000644�0001750�0001750�00000007620�12041642702�030637� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for FactoryMethodNameRule * * @author Hamlet D'Arcy */ class FactoryMethodNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'FactoryMethodName' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { def doSomething() {} def make() {} def makeSomething() {} @Override build() { } // OK, overriding } class WidgetBuilder { def build() {} def buildSomething() {} } ''' assertNoViolations(SOURCE) } @Test void testCreate() { final SOURCE = ''' class MyClass { // violation. Factory methods should be named make() def create() { } } ''' assertSingleViolation(SOURCE, 5, 'def create()', "Violation in class MyClass. The method 'create' matches the regular expression /(build.*|create.*)/ and does not appear in a class matching /*.Builder/") } @Test void testCreateSomething() { final SOURCE = ''' class MyClass { // violation. Factory methods should be named make() def createSomething() { } } ''' assertSingleViolation(SOURCE, 5, 'def createSomething()', "Violation in class MyClass. The method 'createSomething' matches the regular expression /(build.*|create.*)/ and does not appear in a class matching /*.Builder/") } @Test void testBuild() { final SOURCE = ''' package test class MyClass { // violation. Builder method not in class named *Builder def build() { } } ''' assertSingleViolation(SOURCE, 7, 'def build()', "Violation in class MyClass. The method 'build' matches the regular expression /$rule.regex/ and does not appear in a class matching /*.Builder/") } @Test void testBuildSomething() { final SOURCE = ''' package test class MyClass { // violation. Builder method not in class named *Builder def buildSomething() { } } ''' assertSingleViolation(SOURCE, 7, 'def buildSomething()', "The method 'buildSomething' matches the regular expression /(build.*|create.*)/ and does not appear in a class matching /*.Builder/") } @Test void testCreateInBuilder() { final SOURCE = ''' class WidgetBuilder { def create() { } } ''' assertSingleViolation(SOURCE, 3, 'def create()', "Violation in class WidgetBuilder. The method 'create' matches the regular expression /(build.*|create.*)/") } protected Rule createRule() { new FactoryMethodNameRule() } } ����������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/VariableNameRuleTest.groovy������������������0000644�0001750�0001750�00000021221�12041642700�027603� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for VariableNameRule * * @author Chris Mair */ class VariableNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'VariableName' } @Test void testRegex_DefaultValue() { assert 'abc' ==~ rule.regex assert 'aXaX123' ==~ rule.regex assert !('abc_def' ==~ rule.regex) assert !('ABC123abc' ==~ rule.regex) } @Test void testFinalRegex_DefaultValue() { assert 'ABC' ==~ rule.finalRegex assert 'A_B_C' ==~ rule.finalRegex assert !('abc_def' ==~ rule.finalRegex) assert !('ABC123abc' ==~ rule.finalRegex) assert !('ABCabc' ==~ rule.finalRegex) assert !('a_b_CDEF' ==~ rule.finalRegex) } @Test void testRegexIsNull() { rule.regex = null shouldFailWithMessageContaining('regex') { applyRuleTo('def myMethod() { int count }') } } @Test void testApplyTo_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { def myMethod() { BigDecimal deposit_amount } } ''' assertSingleViolation(SOURCE, 4, 'BigDecimal deposit_amount', 'Variable named deposit_amount in class MyClass does not match the pattern [a-z][a-zA-Z0-9]*') } @Test void testApplyTo_MatchesDefaultRegex() { final SOURCE = ''' class MyClass { def myMethod() { BigDecimal depositAmount } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchCustomRegex() { final SOURCE = ''' class MyClass { def myMethod() { int count = 23 } } ''' rule.regex = /z.*/ assertSingleViolation(SOURCE, 4, 'int count = 23') } @Test void testApplyTo_MatchesCustomRegex() { final SOURCE = ''' class MyClass { def myMethod() { int zCount = 23 } } ''' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_NonFinal_IgnoreFinalInValue() { final SOURCE = ''' class MyClass { def myMethod() { String name = "final name" } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Final_MatchesDefaultFinalRegex() { final SOURCE = ''' class MyClass { def myMethod() { final int COUNT = 23 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Final_DoesNotMatchDefaultFinalRegex() { final SOURCE = ''' class MyClass { def myMethod() { final int count } } ''' assertSingleViolation(SOURCE, 4, 'final int count') } @Test void testApplyTo_Final_FinalRegexIsEmpty() { final SOURCE = ''' class MyClass { def myMethod() { final int count = 23 } } ''' rule.finalRegex = '' assertNoViolations(SOURCE) } @Test void testApplyTo_Final_DoesNotMatchCustomFinalRegex() { final SOURCE = ''' class MyClass { def myMethod() { final\tString COUNT = 23 } } ''' rule.finalRegex = /z.*/ assertSingleViolation(SOURCE, 4, 'final\tString COUNT = 23') } @Test void testApplyTo_Final_MatchesCustomFinalRegex() { final SOURCE = ''' class MyClass { def myMethod() { final int zCount = 23 } } ''' rule.finalRegex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchDefaultRegex_NoClassDefined() { final SOURCE = ''' def myMethod() { int Count = 23 } ''' assertSingleViolation(SOURCE, 3, 'int Count = 23') } @Test void testApplyTo_NoVariableDefinition() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchDefaultRegex_ClosureDefinition() { final SOURCE = ''' class MyClass { def closure = { int Count = 23 Count } } ''' assertSingleViolation(SOURCE, 4, 'int Count = 23') } @Test void testApplyTo_MultipleVariableNames_MatchesDefaultRegex() { final SOURCE = ''' def myMethod() { def (pkg, name) = 123 } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MultipleVariableNames_OneDoesNotMatchDefaultRegex() { final SOURCE = ''' def myMethod() { def (pkg, Count) = 123 } ''' assertSingleViolation(SOURCE, 3, 'def (pkg, Count) = 123', 'Variable named Count in class None does not match the pattern [a-z][a-zA-Z0-9]*') } @Test void testApplyTo_MultipleVariableNames_Final_OneDoesNotMatchDefaultRegex() { final SOURCE = ''' def myMethod() { final def (OK, bad, OK2) = 123 } ''' assertSingleViolation(SOURCE, 3, 'final def (OK, bad, OK2) = 123', 'Variable named bad in class None does not match the pattern [A-Z][A-Z0-9_]*') } @Test void testApplyTo_MultipleVariableNames_TwoDoNotMatchDefaultRegex() { final SOURCE = ''' def myMethod() { def (Count, pkg, _MYVAR) = 123 } ''' assertTwoViolations(SOURCE, 3, 'def (Count, pkg, _MYVAR) = 123', 'Count', 3, 'def (Count, pkg, _MYVAR) = 123', '_MYVAR') } @Test void testApplyTo_IgnoreVariableNames_MatchesSingleName() { final SOURCE = ''' class MyClass { def myMethod() { BigDecimal deposit_amount } } ''' rule.ignoreVariableNames = 'deposit_amount' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreVariableNames_MatchesNoNames() { final SOURCE = ''' class MyClass { def myMethod() { BigDecimal deposit_amount } } ''' rule.ignoreVariableNames = 'Other' assertSingleViolation(SOURCE, 4, 'BigDecimal deposit_amount') } @Test void testApplyTo_IgnoreVariableNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { def myMethod() { String GOOD_NAME = 'good' BigDecimal deposit_amount def _amount = 100.25 def OTHER_name } } ''' rule.ignoreVariableNames = 'OTHER?name,_*,GOOD_NAME' assertSingleViolation(SOURCE, 5, 'BigDecimal deposit_amount') } @Test void testApplyTo_Enums() { final SOURCE = ''' public enum AuthorizationLevel { NONE, READ, WRITE } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new VariableNameRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/ParameterNameRuleTest.groovy�����������������0000644�0001750�0001750�00000013410�12041642700�027777� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for ParameterNameRule * * @author Chris Mair */ class ParameterNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ParameterName' } @Test void testRegex_DefaultValue() { assert 'abc' ==~ rule.regex assert 'aXaX123' ==~ rule.regex assert !('abc_def' ==~ rule.regex) assert !('ABC123abc' ==~ rule.regex) } @Test void testRegexIsNull() { rule.regex = null shouldFailWithMessageContaining('regex') { applyRuleTo('def myMethod(int count) { }') } } @Test void testApplyTo_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { def myMethod(BigDecimal deposit_amount) { } } ''' assertSingleViolation(SOURCE, 3, 'BigDecimal deposit_amount', 'The parameter named deposit_amount in method myMethod of class MyClass does not match [a-z][a-zA-Z0-9]*') } @Test void testApplyTo_MatchesDefaultRegex() { final SOURCE = ''' class MyClass { def myMethod(BigDecimal depositAmount) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchCustomRegex() { final SOURCE = ''' class MyClass { def myMethod(int count) { } } ''' rule.regex = /z.*/ assertSingleViolation(SOURCE, 3, 'int count') } @Test void testApplyTo_MatchesCustomRegex() { final SOURCE = ''' class MyClass { def myMethod(int _Count = 23) { } } ''' rule.regex = /_.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_Final_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { def myMethod(final BigDecimal deposit_amount) { } } ''' assertSingleViolation(SOURCE, 3, 'final BigDecimal deposit_amount') } @Test void testApplyTo_Constructor_MatchesDefaultRegex() { final SOURCE = ''' class MyClass { MyClass(BigDecimal depositAmount) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Constructor_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { private MyClass(BigDecimal deposit_amount) { } } ''' assertSingleViolation(SOURCE, 3, 'BigDecimal deposit_amount') } @Test void testApplyTo_DoesNotMatchDefaultRegex_NoClassDefined() { final SOURCE = 'def myMethod(int Count = 23) { }' assertSingleViolation(SOURCE, 1, 'int Count = 23') } @Test void testApplyTo_Closure_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { def closure = { int Count = 23 -> Count } } ''' assertSingleViolation(SOURCE, 3, 'int Count = 23') } @Test void testApplyTo_ClosureAndConstructor() { final SOURCE = ''' class MyClass { private MyClass(BigDecimal deposit_amount) { } def closure = { int Count = 23 -> Count } } ''' assertTwoViolations(SOURCE, 3, 'BigDecimal deposit_amount', 4, 'int Count = 23') } @Test void testApplyTo_IgnoreParametersNames_MatchesSingleName() { final SOURCE = ''' class MyClass { def myMethod(BigDecimal deposit_amount) { } } ''' rule.ignoreParameterNames = 'deposit_amount' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreParameterNames_MatchesNoNames() { final SOURCE = ''' class MyClass { def myMethod(BigDecimal deposit_amount) { } } ''' rule.ignoreParameterNames = 'Other' assertSingleViolation(SOURCE, 3, 'BigDecimal deposit_amount') } @Test void testApplyTo_IgnoreParameterNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { def myMethod(BigDecimal deposit_amount) { } String m2(int GOOD) { } def m4(int _amount) { 100.25 } def m5(int OTHER_name) { } } ''' rule.ignoreParameterNames = 'OTHER?name,_*,GOOD' assertSingleViolation(SOURCE, 3, 'BigDecimal deposit_amount') } @Test void testApplyTo_NoParameterDefinition() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } protected Rule createRule() { new ParameterNameRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/InterfaceNameRuleTest.groovy�����������������0000644�0001750�0001750�00000005025�12041642702�027764� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for InterfaceNameRule * * @author Chris Mair */ class InterfaceNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'InterfaceName' assert rule.regex == null } @Test void testRegexIsNull() { final SOURCE = 'interface aaa$bbb{ }' assert !rule.ready assertNoViolations(SOURCE) } @Test void testApplyTo_WithPackage_MatchesRegex() { final SOURCE = ''' package org.codenarc.sample interface AbstractClass { } ''' rule.regex = /[A-Z].*/ assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchRegex() { final SOURCE = ' interface MyInterface { } ' rule.regex = /z.*/ assertSingleViolation(SOURCE, 1, 'interface MyInterface') } @Test void testApplyTo_MatchesRegex() { final SOURCE = ' interface zClass { } ' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_NonInterfaceClass() { final SOURCE = ' class nonInterfaceClass { } ' rule.regex = /[A-Z].*/ assertNoViolations(SOURCE) } @Test void testApplyTo_Interface() { final SOURCE = 'abstract class abstractClass { }' rule.regex = /[A-Z].*/ assertNoViolations(SOURCE) } @Test void testApplyTo_NoClassDefinition() { rule.regex = /[A-Z].*/ final SOURCE = ''' if (isReady) { println 'ready' } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new InterfaceNameRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000151�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/ObjectOverrideMisspelledMethodNameRuleTest.groovy������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/ObjectOverrideMisspelledMethodNameRuleTest.gr0000644�0001750�0001750�00000006303�12041642702�033240� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ObjectOverrideMisspelledMethodNameRule * * @author @Hackergarten */ class ObjectOverrideMisspelledMethodNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ObjectOverrideMisspelledMethodName' } @Test void testApplyTo_NoViolations() { final SOURCE = ''' class MyClass { boolean equals(o){} } boolean equals(Object o){} int hashCode(){} String toString(){} ''' assertNoViolations(SOURCE) } @Test void testEqual() { final SOURCE = ''' boolean equal(Object o) {} boolean equal(int other) {} // ok; wrong param type boolean equal(Object o, int other) {} // ok; too many params ''' assertSingleViolation(SOURCE, 2, 'boolean equal(Object o) {}') } @Test void testEquals_WrongCase() { final SOURCE = ''' boolean eQuals(Object o) {} boolean equaLS(Object o) {} boolean equals(int other) {} // ok; wrong param type boolean equals(Object o, int other) {} // ok; too many params ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'boolean eQuals(Object o) {}'], [lineNumber:3, sourceLineText:'boolean equaLS(Object o) {}']) } @Test void testHashCode_WrongCase() { final SOURCE = ''' int hashcode() {} int haSHcode(int value) {} // ok; not empty params Object hashCOde() {} // Note that it does not enforce type ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'int hashcode() {}'], [lineNumber:4, sourceLineText:'Object hashCOde() {}'], ) } @Test void testToString_WrongCase() { final SOURCE = ''' String tostring() {} String tostring(int value) {} // ok; not empty params String toSTring() {} ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'String tostring() {}'], [lineNumber:4, sourceLineText:'String toSTring() {}'], ) } protected Rule createRule() { new ObjectOverrideMisspelledMethodNameRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/PropertyNameRuleTest.groovy������������������0000644�0001750�0001750�00000017762�12041642700�027721� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for PropertyNameRule * * @author Chris Mair */ class PropertyNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'PropertyName' } @Test void testRegex_DefaultValue() { assert 'abc' ==~ rule.regex assert 'aXaX123' ==~ rule.regex assert !('abc_def' ==~ rule.regex) assert !('ABC123abc' ==~ rule.regex) } @Test void testFinalRegex_DefaultValue() { assert rule.finalRegex == null } @Test void testStaticRegex_DefaultValue() { assert rule.staticRegex == null } @Test void testStaticFinalRegex_DefaultValue() { assert 'ABC' ==~ rule.staticFinalRegex assert 'ABC_123_DEF' ==~ rule.staticFinalRegex assert !('abc_def' ==~ rule.staticFinalRegex) assert !('ABC123abc' ==~ rule.staticFinalRegex) } @Test void testRegexIsNull() { rule.regex = null shouldFailWithMessageContaining('regex') { applyRuleTo('class MyClass { int count }') } } @Test void testApplyTo_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { BigDecimal deposit_amount } ''' assertSingleViolation(SOURCE, 3, 'BigDecimal deposit_amount') } @Test void testApplyTo_MatchesDefaultRegex() { final SOURCE = ''' class MyClass { int count } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Static_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { static int Count } ''' assertSingleViolation(SOURCE, 3, 'static int Count', 'The property name Count in class MyClass does not match the pattern [a-z][a-zA-Z0-9]*') } @Test void testApplyTo_DoesNotMatchCustomRegex() { final SOURCE = ''' class MyClass { int count } ''' rule.regex = /z.*/ assertSingleViolation(SOURCE, 3, 'int count') } @Test void testApplyTo_MatchesCustomRegex() { final SOURCE = ''' class MyClass { int zCount = 23 } ''' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchDefaultRegex_NoClassDefined() { final SOURCE = ' int Count ' assertNoViolations(SOURCE) } @Test void testApplyTo_MatchesCustomRegex_NoClassDefined() { final SOURCE = ' int zCount ' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_Final_DefaultFinalRegex() { final SOURCE = ''' class MyClass { final int Count final int ok } ''' assertSingleViolation(SOURCE, 3, 'final int Count') } @Test void testApplyTo_Final_FinalRegexSet() { final SOURCE = ''' class MyClass { final int zCount } ''' rule.finalRegex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_Static_StaticRegexNotSet() { final SOURCE = ''' class MyClass { static int Count } ''' assertSingleViolation(SOURCE, 3, 'static int Count') } @Test void testApplyTo_Static_StaticRegexSet() { final SOURCE = ''' class MyClass { static int Count } ''' rule.staticRegex = /C.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_StaticFinal_DefaultStaticFinalRegex() { final SOURCE = ''' class MyClass { static final int count } ''' assertSingleViolation(SOURCE, 3, 'static final int count') } @Test void testApplyTo_StaticFinal_CustomStaticFinalRegex() { final SOURCE = ''' class MyClass { static final int Count } ''' rule.staticRegex = /Z.*/ // ignored rule.finalRegex = /X.*/ // ignored rule.staticFinalRegex = /C.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_StaticFinal_DefaultsToFinalRegex() { final SOURCE = ''' class MyClass { static final int Count } ''' rule.staticRegex = /C.*/ // ignored assertSingleViolation(SOURCE, 3, 'static final int Count') } @Test void testApplyTo_StaticFinal_DefaultsToStaticRegex() { final SOURCE = ''' class MyClass { static final int Count } ''' rule.staticFinalRegex = null rule.staticRegex = /C.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_StaticFinal_DefaultsToRegex() { final SOURCE = ''' class MyClass { static final int Count } ''' rule.staticFinalRegex = null rule.staticRegex = null rule.regex = /C.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_ignorePropertyNames_MatchesSingleName() { final SOURCE = ''' class MyClass { static int Count } ''' rule.ignorePropertyNames = 'Count' assertNoViolations(SOURCE) } @Test void testApplyTo_ignorePropertyNames_MatchesNoNames() { final SOURCE = ''' class MyClass { int Count } ''' rule.ignorePropertyNames = 'Other' assertSingleViolation(SOURCE, 3, 'int Count') } @Test void testApplyTo_ignorePropertyNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { String GOOD_NAME = 'good' static int Count def _amount = 100.25 def OTHER_name } ''' rule.ignorePropertyNames = 'OTHER?name,_*,GOOD_NAME' assertSingleViolation(SOURCE, 4, 'static int Count') } @Test void testApplyTo_Script() { final SOURCE = ''' BigDecimal deposit_amount // not considered a field int COUNT // not considered a field ''' assertNoViolations(SOURCE) } @Test void testApplyTo_FieldDefinitions() { final SOURCE = ''' class MyClass { public BigDecimal Deposit_amount // a field, not a property protected int COUNT // a field, not a property private _someName = 'abc' // a field, not a property } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoPropertyDefinition() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } protected Rule createRule() { new PropertyNameRule() } } ��������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/ClassNameSameAsFilenameRuleTest.groovy�������0000644�0001750�0001750�00000006643�12461317047�031702� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for ClassNameSameAsFilenameRule * * @author Artur Gajowy * @author Chris Mair */ class ClassNameSameAsFilenameRuleTest extends AbstractRuleTestCase { static skipTestThatUnrelatedCodeHasNoViolations @Before void setup() { sourceCodeName = 'SameAsFilename.groovy' } @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ClassNameSameAsFilename' } @Test void testNoViolations() { final SOURCE = ''' class SameAsFilename { static class Foo {} } ''' assertNoViolations(SOURCE) } @Test void testSourceCodeName_NullOrEmpty() { final SOURCE = ''' class Ignore { } ''' sourceCodeName = null assertNoViolations(SOURCE) sourceCodeName = '' assertNoViolations(SOURCE) } @Test void test_MultipleClasses_NoViolations() { final SOURCE = ''' class SameAsFilename {} enum NotSameAsFilename {} ''' assertNoViolations(SOURCE) } @Test void test_ScriptFile_NoViolations() { final SOURCE = ''' println 'Hello world!' ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class NotSameAsFilename {} ''' assertSingleViolation(SOURCE, 2, 'class NotSameAsFilename {}', violationMessage('Class', 'NotSameAsFilename')) } @Test void testEnumsChecked() { final SOURCE = ''' enum NotSameAsFilename {} ''' assertSingleViolation(SOURCE, 2, '', violationMessage('Enum', 'NotSameAsFilename')) } @Test void testInterfacesChecked() { final SOURCE = ''' interface NotSameAsFilename {} ''' assertSingleViolation(SOURCE, 2, 'interface NotSameAsFilename {}', violationMessage('Interface', 'NotSameAsFilename')) } @Test void testNestedClassesNotCountedAsTopLevel() { final SOURCE = ''' class NotSameAsFilename { enum Foo {} class Baz {} static class FooBar {} } ''' assertSingleViolation(SOURCE, 2, 'class NotSameAsFilename {', violationMessage('Class', 'NotSameAsFilename')) } private String violationMessage(String sourceUnitType, String violatingClass) { "$sourceUnitType `$violatingClass` is the only class in `$sourceCodeName`. " + 'In such a case the file and the class should have the same name.' } protected Rule createRule() { new ClassNameSameAsFilenameRule() } } ���������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/MethodNameRuleTest.groovy��������������������0000644�0001750�0001750�00000011200�12041642702�027274� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for MethodNameRule * * @author Chris Mair */ class MethodNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'MethodName' } @Test void testRegexIsNull() { rule.regex = null shouldFailWithMessageContaining('regex') { applyRuleTo('def myMethod() { }') } } @Test void testApplyTo_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { def MyMethod() { println 'bad' } } ''' assertSingleViolation(SOURCE, 3, 'def MyMethod', 'The method name MyMethod in class MyClass does not match [a-z]\\w*') } @Test void testApplyTo_DoesMatchDefaultRegex() { final SOURCE = ''' class MyClass { def myMethod_Underscores() { println 'bad' } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreConstructors() { final SOURCE = ''' class MyClass { MyClass() { } def myMethod_Underscores() { println 'bad' } public MyClass() { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchCustomRegex() { final SOURCE = ''' class MyClass { def myMethod() { println 'bad' } } ''' rule.regex = /z.*/ assertSingleViolation(SOURCE, 3, 'def myMethod()') } @Test void testApplyTo_DoesMatchCustomRegex() { final SOURCE = ''' class MyClass { def zMethod() { println 'bad' } } ''' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchCustomRegex_NoClassDefined() { final SOURCE = ' def myMethod() { println "bad" }' rule.regex = /z.*/ assertSingleViolation(SOURCE, 1, 'def myMethod()') } @Test void testApplyTo_DoesMatchCustomRegex_NoClassDefined() { final SOURCE = ' def zMethod() { println "bad" } ' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesSingleName() { final SOURCE = ''' class MyClass { def MyMethod() { println 'bad' } } ''' rule.ignoreMethodNames = 'MyMethod' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesNoNames() { final SOURCE = ''' class MyClass { def MyMethod() { println 'bad' } } ''' rule.ignoreMethodNames = 'OtherMethod' assertSingleViolation(SOURCE, 3, 'def MyMethod') } @Test void testApplyTo_IgnoreMethodNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { def MyMethod() { println 'bad' } String GOOD_NAME() { } def _amount() { } def OTHER_name() { } } ''' rule.ignoreMethodNames = 'OTHER?name,_*,GOOD_NAME' assertSingleViolation(SOURCE, 3, 'def MyMethod') } @Test void testApplyTo_NoMethodDefinition() { final SOURCE = ''' class MyClass { int count } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_ClosureDefinition() { final SOURCE = ''' class MyClass { def MY_CLOSURE = { println 'ok' } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new MethodNameRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/FieldNameRuleTest.groovy���������������������0000644�0001750�0001750�00000022220�12403117552�027105� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for FieldNameRule * * @author Chris Mair */ class FieldNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'FieldName' } @Test void testRegex_DefaultValue() { assert 'abc' ==~ rule.regex assert 'aXaX123' ==~ rule.regex assert !('abc_def' ==~ rule.regex) assert !('ABC123abc' ==~ rule.regex) } @Test void testFinalRegex_DefaultValue() { assert rule.finalRegex == null } @Test void testStaticRegex_DefaultValue() { assert rule.staticRegex == null } @Test void testStaticFinalRegex_DefaultValue() { assert 'ABC' ==~ rule.staticFinalRegex assert 'ABC_123_DEF' ==~ rule.staticFinalRegex assert !('abcdef' ==~ rule.staticFinalRegex) assert !('ABC123abc' ==~ rule.staticFinalRegex) } @Test void testRegexIsNull() { rule.regex = null shouldFailWithMessageContaining('regex') { applyRuleTo('class MyClass { int count }') } } @Test void testApplyTo_MatchesNewRegex() { final SOURCE = ''' class MyClass { private File bug4013 } ''' rule.regex = /^[a-z]([a-zA-Z0-9$])*\b/ assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchNewRegex() { final SOURCE = ''' class MyClass { private BigDecimal deposit_amount } ''' assertSingleViolation(SOURCE, 3, 'BigDecimal deposit_amount', 'The fieldname deposit_amount in class MyClass does not match [a-z][a-zA-Z0-9]*') } @Test void testApplyTo_MatchesDefaultRegex() { final SOURCE = ''' class MyClass { protected int count } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Static_DoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { protected static int Count } ''' assertSingleViolation(SOURCE, 3, 'static int Count') } @Test void testApplyTo_DoesNotMatchCustomRegex() { final SOURCE = ''' class MyClass { public int count } ''' rule.regex = /z.*/ assertSingleViolation(SOURCE, 3, 'public int count') } @Test void testApplyTo_MatchesCustomRegex() { final SOURCE = ''' class MyClass { public zMethod() { println 'bad' } } ''' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchDefaultRegex_NoClassDefined() { final SOURCE = ' int Count ' assertNoViolations(SOURCE) } @Test void testApplyTo_MatchesCustomRegex_NoClassDefined() { final SOURCE = ' int zCount ' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_Final_DefaultFinalRegex() { final SOURCE = ''' class MyClass { public final int COUNT } ''' assertSingleViolation(SOURCE, 3, 'final int COUNT') } @Test void testApplyTo_Final_FinalRegexSet() { final SOURCE = ''' class MyClass { private final int zCount } ''' rule.finalRegex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_Static_StaticRegexNotSet() { final SOURCE = ''' class MyClass { protected static int Count } ''' assertSingleViolation(SOURCE, 3, 'static int Count') } @Test void testApplyTo_Static_StaticRegexSet() { final SOURCE = ''' class MyClass { public static int Count } ''' rule.staticRegex = /C.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_StaticFinal_DefaultStaticFinalRegex() { final SOURCE = ''' class MyClass { public static final int count } ''' assertSingleViolation(SOURCE, 3, 'static final int count') } @Test void testApplyTo_StaticFinal_CustomStaticFinalRegex() { final SOURCE = ''' class MyClass { private static final int Count } ''' rule.staticRegex = /Z.*/ // ignored rule.finalRegex = /X.*/ // ignored rule.staticFinalRegex = /C.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_PrivateStaticFinal_CustomStaticFinalRegex() { final SOURCE = ''' class MyClass { private static final int Count } ''' rule.staticRegex = /Z.*/ // ignored rule.finalRegex = /X.*/ // ignored rule.staticFinalRegex = /C.*/ //ignored rule.privateStaticFinalRegex = /[a-z][a-zA-Z0-9]*/ assertSingleViolation(SOURCE, 3, 'private static final int Count') } @Test void testApplyTo_StaticFinal_StaticFinalRegexIsNull_DefaultsToFinalRegex() { final SOURCE = ''' class MyClass { protected static final int COUNT } ''' rule.staticRegex = /C.*/ // ignored rule.finalRegex = /X.*/ rule.staticFinalRegex = null assertSingleViolation(SOURCE, 3, 'static final int COUNT') } @Test void testApplyTo_StaticFinal_DefaultsToStaticRegex() { final SOURCE = ''' class MyClass { private static final int Count } ''' rule.finalRegex = null rule.staticRegex = /C.*/ rule.staticFinalRegex = null assertNoViolations(SOURCE) } @Test void testApplyTo_StaticFinal_DefaultsToRegex() { final SOURCE = ''' class MyClass { public static final int Count } ''' rule.staticFinalRegex = null rule.finalRegex = null rule.staticRegex = null rule.regex = /C.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoresSerialVersionUID () { final SOURCE = ''' class MyClass { private static final long serialVersionUID = 1234567890L } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreFieldNames_MatchesSingleName() { final SOURCE = ''' class MyClass { protected static int Count } ''' rule.ignoreFieldNames = 'Count' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreFieldNames_MatchesNoNames() { final SOURCE = ''' class MyClass { private int Count } ''' rule.ignoreFieldNames = 'Other' assertSingleViolation(SOURCE, 3, 'int Count') } @Test void testApplyTo_IgnoreFieldNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { private String GOOD_NAME = 'good' protected static int Count private def _amount = 100.25 private def OTHER_name } ''' rule.ignoreFieldNames = 'OTHER?name,_*,GOOD_NAME' assertSingleViolation(SOURCE, 4, 'static int Count') } @Test void testApplyTo_Script() { final SOURCE = ''' private BigDecimal deposit_amount // not considered a field private int COUNT // not considered a field ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PropertyDefinitions() { final SOURCE = ''' class MyClass { BigDecimal deposit_amount int COUNT = 99 def _NAME = 'abc' } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoFieldDefinition() { final SOURCE = ' class MyClass { } ' assertNoViolations(SOURCE) } protected Rule createRule() { new FieldNameRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/PackageNameRuleTest.groovy�������������������0000644�0001750�0001750�00000007221�12407624573�027433� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for PackageNameRule * * @author Chris Mair */ class PackageNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'PackageName' } @Test void testRegexIsNull() { rule.regex = null shouldFailWithMessageContaining('regex') { applyRuleTo('println 1') } } @Test void testApplyTo_DoesNotMatchDefaultRegex() { final SOURCE = ''' package MyPackage.base class _MyClass { } ''' assertSingleViolation(SOURCE, null, null, 'MyPackage.base') } @Test void testApplyTo_MatchesDefaultRegex() { final SOURCE = ''' package mypackage.base.domain class _MyClass { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NumbersWithinFirstPartOfThePackageName() { final SOURCE = ''' package t3 class MyClass { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_MatchesDefaultRegex_Numbers() { final SOURCE = ''' package mypackage.base.i18n class _MyClass { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoPackage() { final SOURCE = ''' class MyClass { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchCustomRegex() { final SOURCE = ''' package mypackage.base.domain class _MyClass { } ''' rule.regex = /z.*/ assertSingleViolation(SOURCE, null, null, 'mypackage.base.domain') } @Test void testApplyTo_MatchesCustomRegex() { final SOURCE = ''' package zpackage.base.domain class _MyClass { } ''' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_NoClassDefinition() { final SOURCE = ''' if (isReady) { println 'ready' } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_PackageNameRequired_MatchesDefaultRegex() { final SOURCE = ''' package mypackage.base.domain class _MyClass { } ''' rule.packageNameRequired = true assertNoViolations(SOURCE) } @Test void testApplyTo_PackageNameRequired_NoPackage() { final SOURCE = ''' class MyClass { } ''' rule.packageNameRequired = true assertSingleViolation(SOURCE, 2, 'MyClass', 'Required package declaration is missing') } protected Rule createRule() { new PackageNameRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/ClassNameRuleTest.groovy���������������������0000644�0001750�0001750�00000007252�12041642702�027135� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for ClassNameRule * * @author Chris Mair */ class ClassNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ClassName' } @Test void testRegexIsNull() { rule.regex = null shouldFailWithMessageContaining('regex') { applyRuleTo('println 1') } } @Test void testApplyTo_DoesNotMatchDefaultRegex() { final SOURCE = ' class _MyClass { } ' assertSingleViolation(SOURCE, 1, '_MyClass') } @Test void testApplyTo_NestedClassDoesNotMatchDefaultRegex() { final SOURCE = ' class MyClass { static class _MyNestedClass { } } ' assertSingleViolation(SOURCE, 1, '_MyNestedClass') } @Test void testApplyTo_InnerClassDoesNotMatchDefaultRegex() { final SOURCE = ''' class MyClass { class _MyInnerClass { } } ''' assertSingleViolation(SOURCE, 2, '_MyInnerClass') } @Test void testApplyTo_MatchesDefaultRegex() { final SOURCE = ''' class MyClass { MyClass() { new _MyAnonymousClass() {} } class MyInnerClass {} static class MyNestedClass { class MyInnerInnerClass {} } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_WithPackage_MatchesDefaultRegex() { final SOURCE = ''' package org.codenarc.sample class MyClass { } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchCustomRegex() { rule.regex = /z.*/ final SOURCE = ' class MyClass { } ' assertSingleViolation(SOURCE, 1, 'MyClass') } @Test void testApplyTo_MatchesCustomRegex() { rule.regex = /z.*/ final SOURCE = ' class zClass { } ' assertNoViolations(SOURCE) } @Test void testApplyTo_NoClassDefinition_DoesNotMatchRegex() { final SOURCE = ''' if (isReady) { println 'ready' } ''' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_ClosureDefinition() { final SOURCE = ''' class MyClass { def c = { println 'ok' } } ''' assertNoViolations(SOURCE) } @Test void testInnerClasses() { final SOURCE = ''' class Outer { private class InnerRunnable implements Runnable { final Logger LOGGER = LoggerFactory.getLogger(InnerRunnable.class) } } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new ClassNameRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/ConfusingMethodNameRuleTest.groovy�����������0000644�0001750�0001750�00000013255�12311370173�031164� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConfusingMethodNameRule * * @author Hamlet D'Arcy * @author Hubert 'Mr. Haki' Klein Ikkink */ class ConfusingMethodNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ConfusingMethodName' } @Test void testNoViolations() { final SOURCE = ''' def foo() {} def foo(int x) {} def bar() {} def bar(int x) {} def baz = {} def bif = {} def car = 100 class MyClass { def foo() {} def foo(int x) {} def bar() {} def bar(int x) {} def baz = {} def bif = {} def car = 100 def x = new Object() { def foo() {} def foo(int x) {} def y = new Object() { def foo() {} def foo(int x) {} } } } ''' assertNoViolations(SOURCE) } @Test void test2MethodViolationsInScript() { final SOURCE = ''' def foo() {} def foo(int x) {} def Foo() {} def foO() {} ''' assertTwoViolations(SOURCE, 4, 'def Foo() {}', 5, 'def foO() {}') } @Test void test2ClosureViolationsInScript() { final SOURCE = ''' def foo = {} def Foo = {} def foO = {} ''' // it is too hard to trap this condition. Must let it succeed assertNoViolations(SOURCE) } // TODO: this condition can only be found in the CLASS_GENERATION compile phase // for now the test is ignored // void test2ClosureViolationsInClass() { // final SOURCE = ''' // class MyClass { // def foo = {} // Closure FOo // def foO = {} // } // ''' // assertTwoViolations(SOURCE, // 4, 'Closure FOo', // 5, 'def foO = {}') // } @Test void test2ViolationsInClass() { final SOURCE = ''' class MyClass { def Foo = {} // this one is a closure! def foo() {} def foO() {} } ''' assertTwoViolations(SOURCE, 4, 'def foo() {}', 5, 'def foO() {}') } @Test void test2ViolationsInClassWithOverloading() { final SOURCE = ''' class MyClass { def foo() {} def foo(int x) {} def foO() {} def foO(int x) {} } ''' assertTwoViolations(SOURCE, 5, 'def foO() {}', 6, 'def foO(int x) {}') } @Test void test2ViolationsInNestedClasses() { final SOURCE = ''' class MyClass { def foo() {} def foO() {} def x = new Object() { def innerFoo() {} def innerfoO = {} // this one is a closure! } } ''' assertTwoViolations(SOURCE, 4, 'def foO() {}', 7, 'def innerFoo() {}') // this seems out of order but is correct } @Test void testDeepNesting() { final SOURCE = ''' def foo() {} def foo(int x) {} class MyClass { def foo() {} def foo(int x) {} def x = new Object() { def foo() {} def foo(int x) {} def y = new Object() { def foo = {} def FoO = {} def foO() {} } } } ''' assertTwoViolations(SOURCE, 12, 'def FoO = {}', 13, 'def foO() {}') } @Test void testViolatingFieldNameAndMethodName() { final SOURCE = ''' class Totaller { int total int total() {} } ''' assertSingleViolation(SOURCE, 4, 'int total', 'The method name total is similar to the field name total') } @Test void test2ViolatingFieldNameAndMethodNames() { final SOURCE = ''' class MyClass { def total = 1 def totaL() {} def toTal() {} } ''' assertTwoViolations(SOURCE, 4, 'def totaL() {}', 5, 'def toTal() {}') } protected Rule createRule() { new ConfusingMethodNameRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/naming/AbstractClassNameRuleTest.groovy�������������0000644�0001750�0001750�00000005057�12041642702�030622� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.naming import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AbstractClassNameRule * * @author Chris Mair */ class AbstractClassNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AbstractClassName' assert rule.regex == null } @Test void testRegexIsNull() { final SOURCE = 'abstract class aaa$bbb{ }' assert !rule.ready assertNoViolations(SOURCE) } @Test void testApplyTo_WithPackage_MatchesRegex() { final SOURCE = ''' package org.codenarc.sample abstract class AbstractClass { } ''' rule.regex = /[A-Z].*/ assertNoViolations(SOURCE) } @Test void testApplyTo_DoesNotMatchRegex() { final SOURCE = ' abstract class AbstractClass { } ' rule.regex = /z.*/ assertSingleViolation(SOURCE, 1, 'AbstractClass') } @Test void testApplyTo_MatchesRegex() { final SOURCE = ' abstract class zClass { } ' rule.regex = /z.*/ assertNoViolations(SOURCE) } @Test void testApplyTo_NonAbstractClass() { final SOURCE = ' class nonAbstractClass { } ' rule.regex = /[A-Z].*/ assertNoViolations(SOURCE) } @Test void testApplyTo_Interface() { final SOURCE = ' interface interfaceClass { } ' rule.regex = /[A-Z].*/ assertNoViolations(SOURCE) } @Test void testApplyTo_NoClassDefinition() { rule.regex = /[A-Z].*/ final SOURCE = ''' if (isReady) { println 'ready' } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new AbstractClassNameRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/AbstractRuleTest.groovy�����������������������������0000644�0001750�0001750�00000024534�12142572100�025557� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule import org.codehaus.groovy.control.Phases import org.codenarc.source.SourceCode import org.codenarc.source.SourceString import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.assertContainsAll import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for the AbstractRule class * * @author Chris Mair */ class AbstractRuleTest extends AbstractRuleTestCase { private static final NAME = 'Rule123' private static final PRIORITY = 2 private static final SOURCE = 'class MyClass { }' private static final FILENAME = 'MyTest.groovy' private static final PATH = 'org/codenarc/MyTest.groovy' private static final MATCH = /.*Test\.groovy/ private static final NO_MATCH = /.*Other\.groovy/ static skipTestThatUnrelatedCodeHasNoViolations static skipTestThatInvalidCodeHasNoViolations @Test void testToString() { assertContainsAll(rule.toString(), ['FakePathRule', NAME, PRIORITY.toString()]) } @Test void testName() { rule.name = 'abc' assert rule.getName() == 'abc' } @Test void testDescription() { assert rule.description == null rule.description = 'abc' assert rule.getDescription() == 'abc' } @Test void testPriority() { rule.priority = 1 assert rule.getPriority() == 1 } @Test void testIsReady_DefaultsToTrue() { assert rule.ready } @Test void testIsReady() { rule = new NotReadyRule() assert !rule.isReady() assertNoViolations(SOURCE) } @Test void testEnabled() { assertSingleViolation(SOURCE) rule.enabled = false assertNoViolations(SOURCE) } @Test void testValidatesAstCompilerPhase() { rule = new FakePathRule() { int compilerPhase = Phases.SEMANTIC_ANALYSIS } def source = new SourceString(SOURCE) assert source.astCompilerPhase == SourceCode.DEFAULT_COMPILER_PHASE shouldFailWithMessageContaining(IllegalArgumentException, 'SourceCode with AST compiler phase') { rule.applyTo(source) } } @Test void testApplyToFilesMatching() { rule.applyToFilesMatching = MATCH assertSingleViolation(SOURCE) rule.applyToFilesMatching = NO_MATCH assertNoViolations(SOURCE) } @Test void testDoNotApplyToFilesMatching() { rule.doNotApplyToFilesMatching = NO_MATCH assertSingleViolation(SOURCE) rule.doNotApplyToFilesMatching = MATCH assertNoViolations(SOURCE) } @Test void testBothApplyToFilesMatchingAndDoNotApplyToFilesMatching() { rule.applyToFilesMatching = MATCH // apply = YES rule.doNotApplyToFilesMatching = MATCH // doNotApply = YES assertNoViolations(SOURCE) rule.applyToFilesMatching = NO_MATCH // apply = NO rule.doNotApplyToFilesMatching = MATCH // doNotApply = YES assertNoViolations(SOURCE) rule.applyToFilesMatching = MATCH // apply = YES rule.doNotApplyToFilesMatching = NO_MATCH // doNotApply = NO assertSingleViolation(SOURCE) rule.applyToFilesMatching = NO_MATCH // apply = NO rule.doNotApplyToFilesMatching = NO_MATCH // doNotApply = NO assertNoViolations(SOURCE) } @Test void testApplyToFileNames_FilenameOnly() { rule.applyToFileNames = FILENAME assertSingleViolation(SOURCE) rule.applyToFileNames = 'Xxx.groovy' assertNoViolations(SOURCE) rule.applyToFileNames = 'My*.groovy' assertSingleViolation(SOURCE) rule.applyToFileNames = 'MyTest??.groovy' assertNoViolations(SOURCE) } @Test void testApplyToFileNames_WithPath() { rule.applyToFileNames = 'org/codenarc/MyTest.groovy' assertSingleViolation(SOURCE) rule.applyToFileNames = '**/MyTest.groovy' assertSingleViolation(SOURCE) rule.applyToFileNames = '**/codenarc/MyTest.groovy' assertSingleViolation(SOURCE) rule.applyToFileNames = '**org/*/My*.groovy' assertSingleViolation(SOURCE) rule.applyToFileNames = 'other/**/MyTest.groovy' assertNoViolations(SOURCE) rule.applyToFileNames = 'org/codenarc/MyOtherTest.groovy' assertNoViolations(SOURCE) } @Test void testDoNotApplyToFileNames_FilenameOnly() { rule.doNotApplyToFileNames = 'Xxx.groovy' assertSingleViolation(SOURCE) rule.doNotApplyToFileNames = FILENAME assertNoViolations(SOURCE) rule.doNotApplyToFileNames = 'MyTest??.groovy' assertSingleViolation(SOURCE) rule.doNotApplyToFileNames = 'My*.gr*' assertNoViolations(SOURCE) } @Test void testDoNotApplyToFileNames_WithPath() { rule.doNotApplyToFileNames = 'org/codenarc/Xxx.groovy' assertSingleViolation(SOURCE) rule.doNotApplyToFileNames = PATH assertNoViolations(SOURCE) rule.doNotApplyToFileNames = 'org/code*rc/MyT??t.groovy' assertNoViolations(SOURCE) rule.doNotApplyToFileNames = '*/codenarc/MyOtherTest.groovy' assertSingleViolation(SOURCE) rule.doNotApplyToFileNames = '**/codenarc/My*.gr*' assertNoViolations(SOURCE) } @Test void testBothApplyToFileNamesAndDoNotApplyToFileNames() { rule.applyToFileNames = FILENAME // apply = YES rule.doNotApplyToFileNames = FILENAME // doNotApply = YES assertNoViolations(SOURCE) rule.applyToFileNames = 'Xxx.groovy' // apply = NO rule.doNotApplyToFileNames = FILENAME // doNotApply = YES assertNoViolations(SOURCE) rule.applyToFileNames = FILENAME // apply = YES rule.doNotApplyToFileNames = 'Xxx.groovy' // doNotApply = NO assertSingleViolation(SOURCE) rule.applyToFileNames = 'Xxx.groovy' // apply = NO rule.doNotApplyToFileNames = 'Xxx.groovy' // doNotApply = NO assertNoViolations(SOURCE) } @Test void testApplyToFileNamesAndDoNotApplyToFilesMatching() { rule.applyToFileNames = FILENAME // apply filename = YES rule.doNotApplyToFilesMatching = MATCH // doNotApply regex = YES assertNoViolations(SOURCE) rule.applyToFileNames = 'Xxx.groovy' // apply filename = NO rule.doNotApplyToFilesMatching = MATCH // doNotApply regex = YES assertNoViolations(SOURCE) } @Test void testApplyToFilesMatchingAndDoNotApplyToFileNames() { rule.applyToFilesMatching = MATCH // apply regex = YES rule.doNotApplyToFileNames = 'Xxx.groovy' // doNotApply filename = NO assertSingleViolation(SOURCE) rule.applyToFilesMatching = NO_MATCH // apply regex = NO rule.doNotApplyToFileNames = FILENAME // doNotApply filename = YES assertNoViolations(SOURCE) } @Test void testApplyTo_ViolationMessageIsNotSet() { def violations = applyRuleTo(SOURCE) assert violations[0].message == PATH } @Test void testApplyTo_ViolationMessageIsSetToEmpty() { rule.violationMessage = '' def violations = applyRuleTo(SOURCE) assert violations[0].message == '' } @Test void testApplyTo_ViolationMessageIsSet() { rule.violationMessage = 'abc' rule.numberOfViolations = 2 def violations = applyRuleTo(SOURCE) assert violations[0].message == 'abc' assert violations[1].message == 'abc' } @Test void testApplyTo_Error() { rule = new ExceptionRule(new Exception('abc')) shouldFailWithMessageContaining('abc') { applyRuleTo(SOURCE) } } @Test void testCreateViolation() { def v = rule.createViolation(23, 'src', 'msg') assert v.lineNumber == 23 assert v.sourceLine == 'src' assert v.message == 'msg' } @Test void testCreateViolation_Defaults() { def v = rule.createViolation(99) assert v.lineNumber == 99 assert v.sourceLine == null assert v.message == null } @Test void testCreateViolation_ASTNode() { final SOURCE = ''' class MyClass { int count } ''' def sourceCode = new SourceString(SOURCE) def classNode = sourceCode.ast.classes[0] def v = rule.createViolation(sourceCode, classNode) assert v.lineNumber == 2 assert v.sourceLine == 'class MyClass {' assert v.message == null } //-------------------------------------------------------------------------- // Setup and helper methods //-------------------------------------------------------------------------- @Before void setUpAbstractRuleTest() { sourceCodePath = PATH sourceCodeName = FILENAME } protected Rule createRule() { new FakePathRule(name:NAME, priority:PRIORITY) } } class NotReadyRule extends FakePathRule { boolean isReady() { false } } class ExceptionRule extends AbstractRule { String name = 'Exception' int priority = 1 Throwable throwable ExceptionRule(Throwable throwable) { this.throwable = throwable } @Override void applyTo(SourceCode sourceCode, List violations) { throw throwable } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/MockRule.groovy�������������������������������������0000644�0001750�0001750�00000002515�12224267656�024062� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule import org.codenarc.source.SourceCode /** * Mock implementation of the Rule interface for testing */ class MockRule implements Rule { String name int priority int compilerPhase private final Closure applyToClosure MockRule(Map parameters) { this.name = parameters.name this.priority = parameters.priority ?: 0 this.compilerPhase = parameters.compilerPhase ?: SourceCode.DEFAULT_COMPILER_PHASE this.applyToClosure = parameters.applyTo } @Override List applyTo(SourceCode sourceCode) { if (applyToClosure) { applyToClosure(sourceCode) } else { throw new UnsupportedOperationException() } } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/FakeCountRule.groovy��������������������������������0000644�0001750�0001750�00000002252�12311373552�025034� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule import org.codenarc.source.SourceCode /** * Test-specific Rule implementation that maintins count of how many times it has been applied. * * @author Chris Mair */ class FakeCountRule extends AbstractRule { String name ='FakeCountRule' int priority = 2 int count = 0 /** * Increment count and add no violations * @param sourceCode - the sourceCode to which the rule is applied */ @Override void applyTo(SourceCode sourceCode, List violations) { count ++ } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/����������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022134� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/DuplicateMapKeyRuleTest.groovy����������������0000644�0001750�0001750�00000005505�12041642700�030115� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DuplicateMapKeyRule * * @author '?ukasz Indykiewicz' */ class DuplicateMapKeyRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DuplicateMapKey' } @Test void testSuccessScenario() { final SOURCE = ''' def var4 = [a:1, b:1, c:1] def var5 = [1:1, 2:1, 3:1] def var6 = ["a":1, "b":1, "c":1] ''' assertNoViolations(SOURCE) } @Test void testDuplicateKey() { final SOURCE = ''' def var1 = [a:1, a:2, b:3] ''' assertSingleViolation(SOURCE, 3, 'a:2,', "Key 'a' is duplicated.") } @Test void testMultipleDuplicateKeys() { final SOURCE = ''' def var1 = [a:1, a:2, a:4, b:3] ''' assertTwoViolations(SOURCE, 3, 'a:2,', "Key 'a' is duplicated.", 4, 'a:4,', "Key 'a' is duplicated.") } @Test void testDuplicateIntegerKey() { final SOURCE = ''' def var2 = [1:1, 1:2, 2:3] ''' assertSingleViolation(SOURCE, 2, 'def var2 = [1:1, 1:2, 2:3]', "Key '1' is duplicated.") } @Test void testDuplicateStringKey() { final SOURCE = ''' def var3 = ["a":1, "a":2, "b":3] ''' assertSingleViolation SOURCE, 2, 'def var3 = ["a":1, "a":2, "b":3]', "Key 'a' is duplicated." } @Test void testDuplicateKeyNotAdjacent() { final SOURCE = ''' def list = { [breadCrumb: REPORT_BREAD_CRUMB, pageName: REPORT_PAGE_NAME, errorFlag:false, planId:"", errorFlag:false ] } ''' assertSingleViolation SOURCE, 4, 'planId:"", errorFlag:false ]', "Key 'errorFlag' is duplicated." } protected Rule createRule() { new DuplicateMapKeyRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyTryBlockRuleTest.groovy������������������0000644�0001750�0001750�00000004311�12041642700�027636� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyTryBlockRule * * @author Chris Mair */ class EmptyTryBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyTryBlock' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { try { } catch(MyException e) { e.printStackTrace() } } } ''' assertSingleViolation(SOURCE, 4, 'try {') } @Test void testApplyTo_Violation_TryBlockContainsComment() { final SOURCE = ''' try { // TODO Should do something here } catch(MyException e) { e.printStackTrace() } ''' assertSingleViolation(SOURCE, 2, 'try') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { try { doSomething() } catch(Exception t) { println "bad stuff happened" } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptyTryBlockRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ComparisonWithSelfRuleTest.groovy�������������0000644�0001750�0001750�00000007246�12041642700�030660� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ComparisonWithSelfRule * * @author Chris mair */ class ComparisonWithSelfRuleTest extends AbstractRuleTestCase { private static final MESSAGE = 'Comparing an object to itself' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ComparisonWithSelf' } @Test void testComparisonOperators_NoViolations() { final SOURCE = ''' if (value == true) { } while (x <= y) { } def v1 = value == ready ? x : y def v2 = value <=> other def v3 = value >= 23 def x = 23 println x == 23 ''' assertNoViolations(SOURCE) } @Test void testEqualsMethod_NoViolations() { final SOURCE = ''' if (value.equals(true)) { } while (x.equals(y)) { } value.equals(true ? x : y) value.equals(true ?: x) def x = 23 println x.equals(23) ''' assertNoViolations(SOURCE) } @Test void testCompareToMethod_NoViolations() { final SOURCE = ''' if (value.compareTo(other)) { } while (x.compareTo(y) < 0) { } def v1 = value.compareTo(ready ? x : y) def v2 = value.compareTo([1,2,3]) def v3 = value.compareTo(0) ''' assertNoViolations(SOURCE) } @Test void testComparisonOperators_Violations() { final SOURCE = ''' println isReady = x == x if (x != x) { } while (x < x) { } if (x <= x) { } while (x > x) { } if (x >= x) { } def c = (x <=> x) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'println isReady = x == x', messageText:MESSAGE], [lineNumber:3, sourceLineText:'if (x != x) { }', messageText:MESSAGE], [lineNumber:4, sourceLineText:'while (x < x) { }', messageText:MESSAGE], [lineNumber:5, sourceLineText:'if (x <= x) { }', messageText:MESSAGE], [lineNumber:6, sourceLineText:'while (x > x) { }', messageText:MESSAGE], [lineNumber:7, sourceLineText:'if (x >= x) { }', messageText:MESSAGE], [lineNumber:8, sourceLineText:'def c = (x <=> x) { }', messageText:MESSAGE] ) } @Test void testEqualsMethod_Violation() { final SOURCE = ''' println isReady = x.equals(x) ''' assertSingleViolation(SOURCE, 2, 'println isReady = x.equals(x)', MESSAGE) } @Test void testCompareToMethod_Violation() { final SOURCE = ''' println x.compareTo(x) ''' assertSingleViolation(SOURCE, 2, 'println x.compareTo(x)', MESSAGE) } protected Rule createRule() { new ComparisonWithSelfRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ConstantIfExpressionRuleTest.groovy�����������0000644�0001750�0001750�00000006061�12041642700�031222� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConstantIfExpressionRule * * @author Chris Mair */ class ConstantIfExpressionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ConstantIfExpression' } @Test void testApplyTo_True_IsAViolation() { final SOURCE = ''' if (true) { } if (Boolean.TRUE) { } ''' assertTwoViolations(SOURCE, 2, 'if (true) { }', 3, 'if (Boolean.TRUE) { }') } @Test void testApplyTo_False_IsAViolation() { final SOURCE = ''' if (false) { } if (Boolean.FALSE) { } ''' assertTwoViolations(SOURCE, 2, 'if (false) { }', 3, 'if (Boolean.FALSE) { }') } @Test void testApplyTo_Null_IsAViolation() { final SOURCE = ''' if (null) { } ''' assertSingleViolation(SOURCE, 2, 'if (null) { }', 'The if statement condition (null) contains a constant') } @Test void testApplyTo_StringLiteral_IsAViolation() { final SOURCE = ''' if ("abc") { } if ("") { } ''' assertTwoViolations(SOURCE, 2, 'if ("abc") { }', 3, 'if ("") { }') } @Test void testApplyTo_NumberLiteral_IsAViolation() { final SOURCE = ''' if (99.9) { } if (0) { } ''' assertTwoViolations(SOURCE, 2, 'if (99.9) { }', 3, 'if (0) { }') } @Test void testApplyTo_MapLiteral_IsAViolation() { final SOURCE = ''' if ([:]) { } if ([a:123, b:234]) { } ''' assertTwoViolations(SOURCE, 2, 'if ([:])', 3, 'if ([a:123, b:234])') } @Test void testApplyTo_ListLiteral_IsAViolation() { final SOURCE = ''' if ([]) { } if ([a, 123]) { } ''' assertTwoViolations(SOURCE, 2, 'if ([])', 3, 'if ([a, 123])') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' if (z) { } if (z+2) { } if ("$abc") { } if (MAX_VALUE) { } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new ConstantIfExpressionRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptySwitchStatementRuleTest.groovy�����������0000644�0001750�0001750�00000003443�12041642700�031240� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptySwitchStatementRule * * @author Chris Mair */ class EmptySwitchStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptySwitchStatement' } @Test void testApplyTo_EmptySwitchStatement() { final SOURCE = ''' class MyClass { def myClosure = { switch(myVariable) { // empty } } } ''' assertSingleViolation(SOURCE, 4, 'switch(myVariable) {') } @Test void testApplyTo_NonEmptySwitchStatement() { final SOURCE = ''' def myVar = 123 switch(myVariable) { case 123: println 'ok'; break default: println 'bad' } ''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptySwitchStatementRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/HardCodedWindowsFileSeparatorRuleTest.groovy��0000644�0001750�0001750�00000005507�12041642700�032747� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for HardCodedWindowsFileSeparatorRule * * @author Hamlet D'Arcy */ class HardCodedWindowsFileSeparatorRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'HardCodedWindowsFileSeparator' } @Test void testSuccessScenario() { final SOURCE = ''' new File('/a/b/c') new File("", "a/b/") new File('..') new File('a\\$b') ''' assertNoViolations(SOURCE) } @Test void testCRoot() { final SOURCE = ''' new File('.\\\\c') ''' assertSingleViolation(SOURCE, 2, "new File('.\\\\c')", 'The windows file separator is not portable') } @Test void testCRootTwoParm1() { final SOURCE = ''' new File('../b\\\\', null) ''' assertSingleViolation(SOURCE, 2, "new File('../b\\\\', null)", 'The windows file separator is not portable') } @Test void testCRootTwoParm2() { final SOURCE = ''' new File(null, '\\\\') ''' assertSingleViolation(SOURCE, 2, "new File(null, '\\\\')", 'The windows file separator is not portable') } @Test void testCRootAndDir() { final SOURCE = ''' new File('c:\\\\dir') ''' assertSingleViolation(SOURCE, 2, "new File('c:\\\\dir')", 'The windows file separator is not portable') } @Test void testSingleViolation() { final SOURCE = ''' new File('E:\\\\dir') ''' assertSingleViolation(SOURCE, 2, "new File('E:\\\\dir')", 'The windows file separator is not portable') } @Test void testGStringParameter() { final SOURCE = ''' new File("E:\\\\dir\\\\$foo") ''' assertSingleViolation(SOURCE, 2, 'new File("E:\\\\dir\\\\$foo")', 'The windows file separator is not portable') } protected Rule createRule() { new HardCodedWindowsFileSeparatorRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/AssignmentInConditionalRuleTest.groovy��������0000644�0001750�0001750�00000007352�12041642700�031661� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AssignmentInConditionalRule * * @author 'Hamlet D'Arcy' * @author Chris Mair */ class AssignmentInConditionalRuleTest extends AbstractRuleTestCase { private static final VIOLATION_MESSAGE = 'Assignment used as conditional value, which always results in true. Use the == operator instead' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AssignmentInConditional' } @Test void testConditionalsWithoutAssignments_NoViolations() { final SOURCE = ''' if (value == true) { } while (value == true) { } value == true ? x : y value == true ?: x ''' assertNoViolations(SOURCE) } @Test void testIfStatement() { final SOURCE = ''' if ((value = true)) { // should be == } ''' assertSingleViolation(SOURCE, 2, 'if ((value = true))', VIOLATION_MESSAGE) } @Test void testExpressionWithMultipleConditionsWithAssignment_AndOr_Violations() { final SOURCE = ''' while(value > 5 || (value = -1)) { } if ((value = 5) && ready && doSomething()) { } if (ready && (doSomething() || (value = 5))) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'while(value > 5 || (value = -1)) { }', messageText:VIOLATION_MESSAGE], [lineNumber:3, sourceLineText:'if ((value = 5) && ready && doSomething()) { }', messageText:VIOLATION_MESSAGE], [lineNumber:4, sourceLineText:'if (ready && (doSomething() || (value = 5))) { }', messageText:VIOLATION_MESSAGE]) } @Test void testExpressionWithMultipleConditionsWithAssignment_ButNotAndOr_NoViolations() { final SOURCE = ''' while ((len = input.read(buf)) > 0) { } if ((ready = true) == (temp && doSomething())) { } ''' assertNoViolations(SOURCE) } @Test void testWhileStatement() { final SOURCE = ''' while (value = true) { // should be == } ''' assertSingleViolation(SOURCE, 2, 'while (value = true)', VIOLATION_MESSAGE) } @Test void testExpressionContainingConditionalWithAssignment_NoViolation() { final SOURCE = ''' def ready = (value = true) ''' assertNoViolations(SOURCE) } @Test void testElvis() { final SOURCE = ''' (value = true) ?: x ''' assertSingleViolation(SOURCE, 2, '(value = true) ?: x', VIOLATION_MESSAGE) } @Test void testTernary() { final SOURCE = ''' (value = true) ? x : y ''' assertSingleViolation(SOURCE, 2, '(value = true) ? x : y', VIOLATION_MESSAGE) } protected Rule createRule() { new AssignmentInConditionalRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/HardCodedWindowsRootDirectoryRuleTest.groovy��0000644�0001750�0001750�00000005427�12041642700�033020� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for HardCodedWindowsRootDirectoryRule * * @author Hamlet D'Arcy */ class HardCodedWindowsRootDirectoryRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'HardCodedWindowsRootDirectory' } @Test void testSuccessScenario() { final SOURCE = ''' new File('cc:\\\\') new File('a\\\\b\\\\c') new File('/a/b') ''' assertNoViolations(SOURCE) } @Test void testCRoot() { final SOURCE = ''' new File('c:\\\\') ''' assertSingleViolation(SOURCE, 2, "new File('c:\\\\')", 'The file location c:\\ is not portable') } @Test void testCRootTwoParm1() { final SOURCE = ''' new File('c:\\\\', null) ''' assertSingleViolation(SOURCE, 2, "new File('c:\\\\', null)", 'The file location c:\\ is not portable') } @Test void testCRootTwoParm2() { final SOURCE = ''' new File(null, 'c:\\\\') ''' assertSingleViolation(SOURCE, 2, "new File(null, 'c:\\\\')", 'The file location c:\\ is not portable') } @Test void testCRootAndDir() { final SOURCE = ''' new File('c:\\\\dir') ''' assertSingleViolation(SOURCE, 2, "new File('c:\\\\dir')", 'The file location c:\\ is not portable') } @Test void testSingleViolation() { final SOURCE = ''' new File('E:\\\\dir') ''' assertSingleViolation(SOURCE, 2, "new File('E:\\\\dir')", 'The file location E:\\ is not portable') } @Test void testGStringParameter() { final SOURCE = ''' new File("E:\\\\dir\\\\$foo") ''' assertSingleViolation(SOURCE, 2, 'new File("E:\\\\dir\\\\$foo")', 'The file location E:\\ is not portable') } protected Rule createRule() { new HardCodedWindowsRootDirectoryRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EqualsOverloadedRuleTest.groovy���������������0000644�0001750�0001750�00000005666�12041642700�030343� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EqualsOverloadedRule * * @author Hamlet D'Arcy, * @author Artur Gajowy * @author Marcin Smialek * */ class EqualsOverloadedRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EqualsOverloaded' } @Test void testSuccessScenario() { final SOURCE = ''' class Person { boolean equals(Object other) { true } } class Person3 { boolean equals(java.lang.Object other) { true } } class Person4 { boolean equals(other) { true } } ''' assertNoViolations(SOURCE) } // TODO: WHen we have more type information then this can be moved to a passing test. @Test void testFalsePositive() { final SOURCE = ''' import java.lang.Object as Foo class Person5 { boolean equals(Foo other) { true } } ''' assertSingleViolation(SOURCE, 5, 'boolean equals(Foo other)') } @Test void testSingleParameter() { final SOURCE = ''' class Person { boolean equals(String other) { true } } ''' assertSingleViolation(SOURCE, 3, 'equals(String other)', 'The class Person overloads the equals method, it does not override it.') } @Test void testDoubleParameter() { final SOURCE = ''' class Widget { boolean equals(Object other, String other2) { true } } ''' assertSingleViolation(SOURCE, 3, 'equals(Object other, String other2)', 'The class Widget overloads the equals method, it does not override it.') } @Test void testNoParameters() { final SOURCE = ''' class Person { boolean equals() { true } } ''' assertSingleViolation(SOURCE, 3, 'equals()', 'The class Person overloads the equals method, it does not override it.') } protected Rule createRule() { new EqualsOverloadedRule() } } ��������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/DuplicateSetValueRuleTest.groovy��������������0000644�0001750�0001750�00000007347�12041642700�030465� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DuplicateSetValueRule * * @author Hamlet D'Arcy */ class DuplicateSetValueRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DuplicateSetValue' } @Test void testSuccessScenario() { final SOURCE = ''' def a = [1, 2, 3, 4, null] as Set def b = ['1', '2', '3', null, '4'] as Set def c = [1, '1', null] as Set def d = [1, 1, 1] as ArrayList ''' assertNoViolations(SOURCE) } @Test void testDuplicateIntegers() { final SOURCE = ''' def a = [1, 2, null, 2, 4] as Set def b = [1, 2, 2, 4] as HashSet def c = [1, 3, null, 3, 4] as SortedSet def d = [1, null, null, 3, 4] as SortedSet ''' assertViolations(SOURCE, [lineNumber: 2, sourceLineText: 'def a = [1, 2, null, 2, 4] as Set', messageText: 'The constant value 2 is duplicated in the Set literal'], [lineNumber: 3, sourceLineText: 'def b = [1, 2, 2, 4] as HashSet', messageText: 'The constant value 2 is duplicated in the Set literal'], [lineNumber: 4, sourceLineText: 'def c = [1, 3, null, 3, 4] as SortedSet', messageText: 'The constant value 3 is duplicated in the Set literal'], [lineNumber: 5, sourceLineText: 'def d = [1, null, null, 3, 4] as SortedSet', messageText: 'The constant value null is duplicated in the Set literal']) } @Test void testDuplicateStrings() { final SOURCE = ''' def e = ['1', '2', '2', null, '4'] as Set def f = ['1', '2', '2', null, '4'] as java.util.HashSet def g = ['1', '3', '3', null, '4'] as SortedSet ''' assertViolations(SOURCE, [lineNumber: 2, sourceLineText: "def e = ['1', '2', '2', null, '4'] as Set", messageText: "The constant value '2' is duplicated in the Set literal"], [lineNumber: 3, sourceLineText: "def f = ['1', '2', '2', null, '4'] as java.util.HashSet", messageText: "The constant value '2' is duplicated in the Set literal"], [lineNumber: 4, sourceLineText: "def g = ['1', '3', '3', null, '4'] as SortedSet", messageText: "The constant value '3' is duplicated in the Set literal"]) } @Test void testDuplicateIntsInCustomType() { final SOURCE = ''' def d = [1, 2, 2, 4] as FooSet def h = ['1', '2', '2', '4'] as FooSet ''' assertViolations(SOURCE, [lineNumber: 2, sourceLineText: 'def d = [1, 2, 2, 4] as FooSet', messageText: 'The constant value 2 is duplicated in the Set literal'], [lineNumber: 3, sourceLineText: "def h = ['1', '2', '2', '4'] as FooSet", messageText: "The constant value '2' is duplicated in the Set literal"]) } protected Rule createRule() { new DuplicateSetValueRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/BigDecimalInstantiationRuleTest.groovy��������0000644�0001750�0001750�00000011756�12041642700�031626� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BigDecimalInstantiationRule * * @author Chris Mair */ class BigDecimalInstantiationRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BigDecimalInstantiation' } @Test void testApplyTo_double_Violation() { final SOURCE = ''' class MyClass { def b1 = new BigDecimal(123.45) def b2 = new java.math.BigDecimal(0.26789d) def b3 = new BigDecimal(123.45, MathContext.UNLIMITED) } ''' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'new BigDecimal(123.45)'], [lineNumber:4, sourceLineText:'new java.math.BigDecimal(0.26789d)'], [lineNumber:5, sourceLineText:'new BigDecimal(123.45, MathContext.UNLIMITED)']) } @Test void testApplyTo_WithinClosure() { final SOURCE = ''' class MyClass { def myClosure = { def b2 = new BigDecimal(12.0001) } } ''' assertSingleViolation(SOURCE, 4, 'def b2 = new BigDecimal(12.0001)', 'Call to new BigDecimal(12.0001) uses the double constructor and should probably be replaced with new BigDecimal("12.0001")') } @Test void testApplyTo_Violation_NotWithinClass() { final SOURCE = ''' def b1 = new java.math.BigDecimal(0.1) def name2 = "abc" void calculate() { def b2 = new BigDecimal(12345678.987654321d) } ''' assertTwoViolations(SOURCE, 2, 'def b1 = new java.math.BigDecimal(0.1)', 5, 'def b2 = new BigDecimal(12345678.987654321d)') } @Test void testApplyTo_BigInteger_NoViolation() { final SOURCE = ''' class MyClass { def myMethod() { def b1 = new BigDecimal(BigInteger.ONE) def b2 = new BigDecimal(BigInteger.TEN, 3) def b3 = new BigDecimal(BigInteger.TEN, 3, MathContext.UNLIMITED) def b4 = new BigDecimal(BigInteger.TEN, MathContext.UNLIMITED) } }''' assertNoViolations(SOURCE) } @Test void testApplyTo_CharArray_NoViolation() { final SOURCE = ''' class MyClass { def myMethod() { def b1 = new BigDecimal("123.45" as char[]) def b2 = new BigDecimal("123.45" as char[], 0, 6) def b3 = new BigDecimal("123.45" as char[], 0, 3, MathContext.UNLIMITED) def b4 = new BigDecimal("123.45" as char[], MathContext.UNLIMITED) } }''' assertNoViolations(SOURCE) } @Test void testApplyTo_int_NoViolation() { final SOURCE = ''' class MyClass { def myMethod() { def b1 = new BigDecimal(99) def b2 = new BigDecimal(12345, MathContext.UNLIMITED) } }''' assertNoViolations(SOURCE) } @Test void testApplyTo_long_NoViolation() { final SOURCE = ''' class MyClass { def myMethod() { def b1 = new BigDecimal(99L) final L = 12345 as long def b2 = new BigDecimal(L, MathContext.UNLIMITED) } }''' assertNoViolations(SOURCE) } @Test void testApplyTo_String_NoViolation() { final SOURCE = ''' class MyClass { def myMethod() { def b1 = new BigDecimal("12345.67") def b2 = new BigDecimal("0.45", MathContext.UNLIMITED) } }''' assertNoViolations(SOURCE) } @Test void testApplyTo_Variable_NoViolation() { final SOURCE = ''' def myMethod() { def b1 = new BigDecimal(xyz) }''' assertNoViolations(SOURCE) } protected Rule createRule() { new BigDecimalInstantiationRule() } } ������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyFinallyBlockRuleTest.groovy��������������0000644�0001750�0001750�00000004667�12041642700�030474� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyFinallyBlockRule * * @author Chris Mair */ class EmptyFinallyBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyFinallyBlock' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myMethod() { try { doSomething() } finally { } } } ''' assertSingleViolation(SOURCE, 6, 'finally {') } @Test void testApplyTo_Violation_FinallyBlockContainsComment() { final SOURCE = ''' class MyClass { def myClosure = { try { doSomething() } catch(MyException e) { e.printStackTrace() } finally { // TODO Should do something here } } } ''' assertSingleViolation(SOURCE, 9, 'finally') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { try { doSomething() } finally { println "cleanup" } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptyFinallyBlockRule() } } �������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/MultipleUnaryOperatorsRuleTest.groovy���������0000644�0001750�0001750�00000005247�12323627514�031621� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for MultipleUnaryOperatorsRule * * @author Chris Mair */ class MultipleUnaryOperatorsRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'MultipleUnaryOperators' } @Test void testSingleUnaryOperators_NoViolations() { final SOURCE = ''' int i = ~2 int j = -1 int z = +2 boolean b = !true boolean c = !false int i = ~-2 // KNOWN LIMITATION; parses as BitwiseNegation+Constant int j = ~+9 // KNOWN LIMITATION; parses as BitwiseNegation+Constant ''' assertNoViolations(SOURCE) } @Test void testMultipleUnaryOperators_Violations() { final SOURCE = ''' int z = ~~2 boolean b = !!true boolean c = !!!false int j = -~7 int k = +~8 boolean d = !~1 ''' def message = 'The expression %s in class None contains confusing multiple consecutive unary operators' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'int z = ~~2', messageText:String.format(message, '(~~2)')], [lineNumber:3, sourceLineText:'boolean b = !!true', messageText:String.format(message, '(!!true)')], [lineNumber:4, sourceLineText:'boolean c = !!!false', messageText:String.format(message, '(!!false)')], [lineNumber:4, sourceLineText:'boolean c = !!!false', messageText:String.format(message, '(!!false)')], [lineNumber:5, sourceLineText:'int j = -~7', messageText:String.format(message, '(-~7)')], [lineNumber:6, sourceLineText:'int k = +~8', messageText:String.format(message, '(+~8)')], [lineNumber:7, sourceLineText:'boolean d = !~1', messageText:String.format(message, '(!~1)')]) } protected Rule createRule() { new MultipleUnaryOperatorsRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ClassForNameRuleTest.groovy�������������������0000644�0001750�0001750�00000004056�12041642700�027411� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ClassForNameRule * * @author Hamlet D'Arcy */ class ClassForNameRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ClassForName' } @Test void testSuccessScenario() { final SOURCE = ''' Class.forName() // zero args is not API Class.forName(aClassName, true) // two args is not API Class.forName(aClassName, true, aClassLoader, unknown) // four args is not API ''' assertNoViolations(SOURCE) } @Test void testViolations() { final SOURCE = ''' Class.forName('SomeClassName') Class.forName(aClassName, true, aClassLoader) ''' assertTwoViolations(SOURCE, 2, "Class.forName('SomeClassName')", 'Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)', 3, 'Class.forName(aClassName, true, aClassLoader)', 'Methods calls to Class.forName(...) can create resource leaks and should almost always be replaced with calls to ClassLoader.loadClass(...)') } protected Rule createRule() { new ClassForNameRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyClassRuleTest.groovy���������������������0000644�0001750�0001750�00000010427�12170525600�027161� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyClassRule * * @author Artur Gajowy */ class EmptyClassRuleTest extends AbstractRuleTestCase { def skipTestThatUnrelatedCodeHasNoViolations @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyClass' } @Test void testNoViolations() { final SOURCE = ''' class OneField { int i } class OneMethod { void method() {} } class OneConstructor { OneConstructor() {} } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class Empty { } ''' assertSingleViolation(SOURCE, 2, 'class Empty', violationMessage('Empty')) } @Test void testMultipleViolations() { final SOURCE = ''' abstract class AbstractEmpty { } class EmptyAsWell { //comments do not make a difference } ''' assertViolations(SOURCE, [lineNumber: 2, sourceLineText: 'class AbstractEmpty', messageText: violationMessage('AbstractEmpty')], [lineNumber: 5, sourceLineText: 'class EmptyAsWell', messageText: violationMessage('EmptyAsWell')]) } @Test void testAllowsMarkerInterfaces() { final SOURCE = ''' interface Marker { } ''' assertNoViolations(SOURCE) } @Test void testEmptyEnumDoesNotViolate() { final SOURCE = ''' enum Empty { } ''' assertNoViolations(SOURCE) } @Test void testEmptyAnonymousClassDoesNotViolate() { final SOURCE = ''' class Outer { def foo = new ArrayList<String>() {} } ''' assertNoViolations(SOURCE) } @Test void testEmptyInnerClassViolates() { final SOURCE = ''' class Outer { int i class Inner { } } ''' assertSingleViolation(SOURCE, 5, 'class Inner', violationMessage('Outer$Inner')) } @Test void testClassContainingOnlyTypeNodesViolates() { final SOURCE = ''' class TypesOnly { class Inner { int notEmpty } enum Empty {} } ''' assertSingleViolation(SOURCE, 2, 'class TypesOnly', violationMessage('TypesOnly')) } @Test void testEmptySubclasses_NoViolations() { final SOURCE = ''' class MyException extends RuntimeException { } class ArrayListOfStrings extends ArrayList<String> { } ''' assertNoViolations(SOURCE) } @Test void testJUnitSuiteClasses_Annotation_NoViolations() { final SOURCE = ''' @RunWith(Suite.class) @Suite.SuiteClasses([TestClass1.class, TestClass2.class]) class TestSuite { } ''' assertNoViolations(SOURCE) } @Test void testOtherAnnotation_NoViolations() { final SOURCE = ''' @AnyAnnotation class Empty { } ''' assertNoViolations(SOURCE) } private String violationMessage(String violatingClass) { "Class '$violatingClass' is empty (has no methods, fields or properties). Why would you need a class like this?" } protected Rule createRule() { new EmptyClassRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyElseBlockRuleTest.groovy�����������������0000644�0001750�0001750�00000004667�12041642700�027766� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyElseBlockRule * * @author Chris Mair */ class EmptyElseBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyElseBlock' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myMethod() { if (x==23) { println 'ok' } else { } if (alreadyInitialized()) { println 'ok' } else { } } } ''' assertTwoViolations(SOURCE, 6, '} else {', 10, '} else { }') } @Test void testApplyTo_Violation_ElseBlockContainsComment() { final SOURCE = ''' class MyClass { def update = { if (isReady) { println 'ok' } else { // TODO Should do something here } } } ''' assertSingleViolation(SOURCE, 7, 'else {') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { if (isReady) { println "ready" } else { println "not ready" } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptyElseBlockRule() } } �������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/DeadCodeRuleTest.groovy�����������������������0000644�0001750�0001750�00000006024�12041642700�026521� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DeadCodeRule * * @author Hamlet D'Arcy */ class DeadCodeRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DeadCode' } @Test void testSuccessScenario() { final SOURCE = ''' def x = true def y = { if (x) { return y } println x } def y = { return } return x ''' assertNoViolations(SOURCE) } @Test void testCodeAfterThrow() { final SOURCE = ''' def x = { throw new Exception() println x } def m() { throw new Exception() println x } ''' assertTwoViolations(SOURCE, 4, 'println x', 8, 'println x') } @Test void testCodeAfterReturn() { final SOURCE = ''' def x = { return println x } def m() { return println x } ''' assertTwoViolations(SOURCE, 4, 'println x', 8, 'println x') } @Test void testInIfStatement() { final SOURCE = ''' def x = { if (x) { return y println x } } ''' assertSingleViolation(SOURCE, 5, 'println x') } @Test void testIfStatementAllBranchesReturn() { final SOURCE = ''' def x = { if (x) return y else if (x) return z else throw y println x } ''' assertSingleViolation(SOURCE, 9, 'println x') } @Test void testInWhile() { final SOURCE = ''' while (true) { return println x } ''' assertSingleViolation(SOURCE, 4, 'println x') } protected Rule createRule() { new DeadCodeRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EqualsAndHashCodeRuleTest.groovy��������������0000644�0001750�0001750�00000005520�12041642700�030345� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EqualsAndHashCodeRule * * @author Chris Mair */ class EqualsAndHashCodeRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EqualsAndHashCode' } @Test void testApplyTo_EqualsButNoHashCode() { final SOURCE = ''' class MyClass { boolean equals(Object object) { // do something } } ''' assertSingleViolation(SOURCE, 2, 'class MyClass {') } @Test void testApplyTo_HashCodeButNoEquals() { final SOURCE = ''' class MyClass { int hashCode() { return 0 } } ''' assertSingleViolation(SOURCE, 2, 'class MyClass {') } @Test void testApplyTo_BothEqualsAndHashCode() { final SOURCE = ''' class MyClass { boolean equals(java.lang.Object object) { return true } int hashCode() { return 0 } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_EqualsButWithDifferentSignature() { final SOURCE = ''' class MyClass { boolean equals(String string) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_HashCodeButWithDifferentSignature() { final SOURCE = ''' class MyClass { int hashCode(String value) { } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_NeitherEqualsNorHashCode() { final SOURCE = '''class MyClass { def myMethod() { def b = new String(myBytes) } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EqualsAndHashCodeRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/RemoveAllOnSelfRuleTest.groovy����������������0000644�0001750�0001750�00000003676�12041642700�030100� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for RemoveAllOnSelfRule * * @author Hamlet D'Arcy */ class RemoveAllOnSelfRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'RemoveAllOnSelf' } @Test void testNoViolations() { final SOURCE = ''' def x = [1, 2, 3] x.clear() x.removeAll(otherVariable) x.removeAll(x, otherVariable) ''' assertNoViolations(SOURCE) } @Test void testViolation() { final SOURCE = ''' def x = [1, 2, 3] x.removeAll(x) ''' assertSingleViolation(SOURCE, 3, 'x.removeAll(x)', 'A call to x.removeAll(x) can be replaced with x.clear()') } @Test void testViolationInClass() { final SOURCE = ''' class MyClass { List x = [1, 2, 3] def someMethod() { x.removeAll(x) } } ''' assertSingleViolation(SOURCE, 5, 'x.removeAll(x)') } protected Rule createRule() { new RemoveAllOnSelfRule() } } ������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ConstantAssertExpressionRuleTest.groovy�������0000644�0001750�0001750�00000006737�12461172066�032150� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConstantAssertExpressionRule * * @author Chris Mair */ class ConstantAssertExpressionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ConstantAssertExpression' } @Test void testApplyTo_True_IsAViolation() { final SOURCE = ''' assert true assert Boolean.TRUE, 'bad stuff' ''' assertTwoViolations(SOURCE, 2, 'assert true', 'true', 3, 'assert Boolean.TRUE', 'Boolean.TRUE') } @Test void testApplyTo_False_IsAViolation() { final SOURCE = ''' assert false assert Boolean.FALSE ''' assertTwoViolations(SOURCE, 2, 'assert false', 'false', 3, 'assert Boolean.FALSE', 'Boolean.FALSE') } @Test void testApplyTo_Null_IsAViolation() { final SOURCE = ''' assert null ''' assertSingleViolation(SOURCE, 2, 'assert null', 'null') } @Test void testApplyTo_StringLiteral_IsAViolation() { final SOURCE = ''' assert 'abc' assert "" ''' assertTwoViolations(SOURCE, 2, "assert 'abc'", 'abc', 3, 'assert ""', '') } @Test void testApplyTo_NumberLiteral_IsAViolation() { final SOURCE = ''' class MyClass { def doStuff() { assert 99.9, 'bad stuff' assert 0 } } ''' assertTwoViolations(SOURCE, 4, "assert 99.9, 'bad stuff'", ['99.9', 'MyClass'], 5, 'assert 0', ['0', 'MyClass']) } @Test void testApplyTo_MapLiteral_IsAViolation() { final SOURCE = ''' assert [:] assert [a:123, b:456] ''' assertTwoViolations(SOURCE, 2, 'assert [:]', '[:]', 3, 'assert [a:123, b:456]', '[a:123, b:456]') } @Test void testApplyTo_ListLiteral_IsAViolation() { final SOURCE = ''' assert [] assert [a, 456] ''' assertTwoViolations(SOURCE, 2, 'assert []', '[]', 3, 'assert [a, 456]', '[a, 456]') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' class MyClass { def myMethod() { assert x assert y, 'bad stuff' } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ConstantAssertExpressionRule() } } ���������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyForStatementRuleTest.groovy��������������0000644�0001750�0001750�00000005026�12041642700�030524� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyForStatementRule * * @author Chris Mair */ class EmptyForStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyForStatement' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { for (int i=0; i < 23; i++) { } println 'ok' for (int j=0; j < 10; j++) { } } } ''' assertTwoViolations(SOURCE, 4, 'for (int i=0; i < 23; i++) {', 7, 'for (int j=0; j < 10; j++) {') } @Test void testApplyTo_Violation_ForStatementContainsComment() { final SOURCE = ''' for (int j=0; j < 10; j++) { // TODO Should do something here } ''' assertSingleViolation(SOURCE, 2, 'for (int j=0; j < 10; j++) {') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { for (int j=0; j < 10; j++) { println "ready" } } }''' assertNoViolations(SOURCE) } @SuppressWarnings('UnnecessarySemicolon') @Test void testApplyTo_SingleEmptyStatement() { final SOURCE = '''class MyClass { def myMethod() { for (int j=0; j < 10; j++) ; } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptyForStatementRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyCatchBlockRuleTest.groovy����������������0000644�0001750�0001750�00000006116�12041642700�030107� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyCatchBlockRule * * @author Chris Mair */ class EmptyCatchBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyCatchBlock' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myMethod() { try { } catch(MyException e) { } } } ''' assertSingleViolation(SOURCE, 5, 'catch(MyException e) {') } @Test void testApplyTo_Violation_CatchBlockContainsComment() { final SOURCE = ''' class MyClass { def myClosure = { try { } catch(MyException e) { // TODO Should do something here } } } ''' assertSingleViolation(SOURCE, 5, 'catch(MyException e)') } @Test void testApplyTo_NoViolations_IfParameterNameContainsIgnore() { final SOURCE = ''' class MyClass { def myClosure = { try { } catch(MyException ignore) { } try { } catch(MyException ignored) { } } } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_Violation_IfThereIsNoParameterName() { final SOURCE = ''' class MyClass { def myClosure = { try { } catch(MyException) { } } } ''' assertSingleViolation(SOURCE, 5, 'catch(MyException) {') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { try { } catch(Exception t) { println "bad stuff happened" } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptyCatchBlockRule() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/IntegerGetIntegerRuleTest.groovy��������������0000644�0001750�0001750�00000003604�12041642700�030445� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for IntegerGetIntegerRule * * @author Hamlet D'Arcy */ class IntegerGetIntegerRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'IntegerGetInteger' } @Test void testSuccessScenario() { final SOURCE = ''' Integer.getInteger() Integer.getInteger(value, radix, locale) ''' assertNoViolations(SOURCE) } @Test void testTwoViolations() { final SOURCE = ''' Integer.getInteger(value) Integer.getInteger(value, radix) ''' assertTwoViolations(SOURCE, 2, 'Integer.getInteger(value)', 'Integer.getInteger(String) is a confusing API for reading System properties. Prefer the System.getProperty(String) API.', 3, 'Integer.getInteger(value, radix)', 'Integer.getInteger(String, Integer) is a confusing API for reading System properties. Prefer the System.getProperty(String) API.') } protected Rule createRule() { new IntegerGetIntegerRule() } } ����������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/AssertWithinFinallyBlockRuleTest.groovy�������0000644�0001750�0001750�00000010051�12041642700�032002� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for AssertWithinFinallyBlockRule * * @author Chris Mair */ class AssertWithinFinallyBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'AssertWithinFinallyBlock' } @Test void testApplyTo_FinallyWithAssert_Violation() { final SOURCE = ''' class MyClass { boolean ready = true int myMethod() { try { doSomething() } finally { assert ready // BAD } } } ''' assertSingleViolation(SOURCE, 8, 'assert ready', ['finally block', 'MyClass']) } @Test void testApplyTo_NestedTryFinallyWithAssert_Violation() { final SOURCE = ''' class MyClass { boolean ready = false def myClosure = { try { doSomething() } finally { try { assert ready // BAD } finally { println "ok" } assert ready // BAD } } } ''' assertTwoViolations(SOURCE, 9, 'assert ready', 13, 'assert ready') } @Test void testApplyTo_FinallyBlockWithoutAssert_NoViolation() { final SOURCE = ''' class MyClass { boolean ready = true def myMethod() { try { assert ready // ok } finally { println 'ok' } assert ready // ok } }''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertInMethod_NoViolation() { final SOURCE = ''' class MyClass { def myMethod(int count) { assert count > 0 } }''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertInTry_NoViolation() { final SOURCE = ''' class MyClass { def myMethod(int count) { try { assert count > 0 } finally { println count } } }''' assertNoViolations(SOURCE) } @Test void testApplyTo_AssertInCatch_NoViolation() { final SOURCE = ''' class MyClass { def myMethod(int count) { try { doStuff(count) } catch(Exception e) { assert count > 0 } finally { println count } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new AssertWithinFinallyBlockRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyWhileStatementRuleTest.groovy������������0000644�0001750�0001750�00000004630�12041642700�031046� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyWhileStatementRule * * @author Chris Mair */ class EmptyWhileStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyWhileStatement' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { while (x==23) { } println 'ok' while (!stopped) { } } } ''' assertTwoViolations(SOURCE, 4, 'while (x==23) {', 7, 'while (!stopped) {') } @Test void testApplyTo_Violation_WhileStatementContainsComment() { final SOURCE = ''' while (isReady) { // TODO Should do something here } ''' assertSingleViolation(SOURCE, 2, 'while (isReady) {') } @SuppressWarnings('UnnecessarySemicolon') @Test void testApplyTo_SingleEmptyStatement() { final SOURCE = ''' def myMethod() { while (isReady) ; }''' assertNoViolations(SOURCE) } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { while (isReady) { println "ready" } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptyWhileStatementRule() } } ��������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/BrokenOddnessCheckRuleTest.groovy�������������0000644�0001750�0001750�00000004610�12041642700�030566� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BrokenOddnessCheckRule * * @author 'Hamlet D'Arcy' */ class BrokenOddnessCheckRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BrokenOddnessCheck' } @Test void testSuccessScenario() { final SOURCE = ''' if (x & 1 == 1) { } // OK if (x % 2 != 0) { } // OK ''' assertNoViolations(SOURCE) } @Test void testProperty() { final SOURCE = ''' if (x % 2 == 1) { } // violation ''' assertSingleViolation(SOURCE, 2, '(x % 2 == 1)', "The code uses '(x % 2 == 1)' to check for oddness, which does not work for negative numbers. Use (x & 1 == 1) or (x % 2 != 0) instead") } @Test void testPropertyReverse() { final SOURCE = ''' if (1 == x % 2) { } // violation ''' assertSingleViolation(SOURCE, 2, '(1 == x % 2)', "The code uses '(1 == x % 2)' to check for oddness, which does not work for negative numbers. Use (x & 1 == 1) or (x % 2 != 0) instead") } @Test void testMethod() { final SOURCE = ''' if (method() % 2 == 1) { } // violation ''' assertSingleViolation(SOURCE, 2, '(method() % 2 == 1)', "The code uses '(this.method() % 2 == 1)' to check for oddness, which does not work for negative numbers. Use (this.method() & 1 == 1) or (this.method() % 2 != 0) instead") } protected Rule createRule() { new BrokenOddnessCheckRule() } } ������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/BooleanGetBooleanRuleTest.groovy��������������0000644�0001750�0001750�00000003201�12041642700�030402� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BooleanGetBooleanRule * * @author Hamlet D'Arcy */ class BooleanGetBooleanRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BooleanGetBoolean' } @Test void testSuccessScenario() { final SOURCE = ''' Boolean.getBoolean(value, 1) Boolean.getBoolean() ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' Boolean.getBoolean(value) ''' assertSingleViolation(SOURCE, 2, 'Boolean.getBoolean(value)', 'Boolean.getBoolean(String) is a confusing API for reading System properties. Prefer the System.getProperty(String) API.') } protected Rule createRule() { new BooleanGetBooleanRule() } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ComparisonOfTwoConstantsRuleTest.groovy�������0000644�0001750�0001750�00000011020�12041642700�032047� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ComparisonOfTwoConstants * * @author Chris mair */ class ComparisonOfTwoConstantsRuleTest extends AbstractRuleTestCase { private static final MESSAGE = 'Comparing two constants or constant literals' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ComparisonOfTwoConstants' } @Test void testComparisonOperators_NoViolations() { final SOURCE = ''' if (value == true) { } while (x <= 23) { } def v1 = value == [1,2] ? x : y def v2 = value <=> 23.45 def v3 = value >= 23 println 23 < x println Boolean.FALSE == x def v4 = [a:1] == [a:x] def v5 = [(x):1] == [a:23] ''' assertNoViolations(SOURCE) } @Test void testEqualsMethod_NoViolations() { final SOURCE = ''' if (value.equals(true)) { } while (x.equals([1,2,3])) { } value.equals(Boolean.TRUE) value.equals(1.23) def x = 23 println [a:1,b:2].equals(x) return [a,b].equals([1,2]) ''' assertNoViolations(SOURCE) } @Test void testCompareToMethod_NoViolations() { final SOURCE = ''' if (value.compareTo(23)) { } while (x.compareTo([a]) < 0) { } def v1 = value.compareTo(ready ? x : y) def v2 = 0.compareTo(x) return [a:1].compareTo([a:x]) ''' assertNoViolations(SOURCE) } @Test void testComparisonOperators_Violations() { final SOURCE = ''' println isReady = 23 == 67 if (Boolean.FALSE != false) { } while (23 < 88) { } if (0.17 <= 0.99) { } while ("abc" > "ddd") { } if ([Boolean.FALSE] >= [27]) { } def c = ([a:1] <=> [a:2]) { } ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'println isReady = 23 == 67', messageText:MESSAGE], [lineNumber:3, sourceLineText:'if (Boolean.FALSE != false) { }', messageText:MESSAGE], [lineNumber:4, sourceLineText:'while (23 < 88) { }', messageText:MESSAGE], [lineNumber:5, sourceLineText:'if (0.17 <= 0.99) { }', messageText:MESSAGE], [lineNumber:6, sourceLineText:'while ("abc" > "ddd") { }', messageText:MESSAGE], [lineNumber:7, sourceLineText:'if ([Boolean.FALSE] >= [27]) { }', messageText:MESSAGE], [lineNumber:8, sourceLineText:'def c = ([a:1] <=> [a:2]) { }', messageText:MESSAGE] ) } @Test void testEqualsMethod_Violation() { final SOURCE = ''' println isReady = [1,2].equals([3,4]) return [a:123, b:true].equals(['a':222, b:Boolean.FALSE]) ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'println isReady = [1,2].equals([3,4])', messageText:MESSAGE], [lineNumber:3, sourceLineText:"return [a:123, b:true].equals(['a':222, b:Boolean.FALSE])", messageText:MESSAGE] ) } @Test void testCompareToMethod_Violation() { final SOURCE = ''' println cmp = [a:123, b:456].compareTo([a:222, b:567]) return [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE]) ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'println cmp = [a:123, b:456].compareTo([a:222, b:567])', messageText:MESSAGE], [lineNumber:3, sourceLineText:"return [a:false, b:true].compareTo(['a':34.5, b:Boolean.TRUE])", messageText:MESSAGE]) } protected Rule createRule() { new ComparisonOfTwoConstantsRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/DoubleNegativeRuleTest.groovy�����������������0000644�0001750�0001750�00000003161�12041642700�027765� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DoubleNegativeRule * * @author Hamlet D'Arcy */ class DoubleNegativeRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DoubleNegative' } @Test void testSuccessScenario() { final SOURCE = ''' !true ''' assertNoViolations(SOURCE) } @Test void testDoubleNegatives() { final SOURCE = ''' def x = !!true def y = !(!true) ''' assertTwoViolations(SOURCE, 2, 'def x = !!true', 'The expression (!!true) is a confusing double negative', 3, 'def y = !(!true)', 'The expression (!!true) is a confusing double negative') } protected Rule createRule() { new DoubleNegativeRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyIfStatementRuleTest.groovy���������������0000644�0001750�0001750�00000004160�12041642700�030332� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyIfStatementRule * * @author Chris Mair */ class EmptyIfStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyIfStatement' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { def myClosure = { if (x==23) { } println 'ok' if (alreadyInitialized()) { } } } ''' assertTwoViolations(SOURCE, 4, 'if (x==23) {', 7, 'if (alreadyInitialized()) {') } @Test void testApplyTo_Violation_IfStatementContainsComment() { final SOURCE = ''' if (isReady) { // TODO Should do something here } ''' assertSingleViolation(SOURCE, 2, 'if (isReady)') } @Test void testApplyTo_NoViolations() { final SOURCE = '''class MyClass { def myMethod() { if (isReady) { println "ready" } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptyIfStatementRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/RandomDoubleCoercedToZeroRuleTest.groovy������0000644�0001750�0001750�00000014500�12311370173�032074� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for RandomDoubleCoercedToZeroRule * * @author Hamlet D'Arcy */ class RandomDoubleCoercedToZeroRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'RandomDoubleCoercedToZero' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { def a = (double) Math.random() def b = (Double) Math.random() double c = Math.random() Double d = Math.random() def e = (Math.random()) as double def f = (Math.random()) as Double def g = Math.random() } Double intMethod() { if (foo) return Math.random() } double integerMethod() { if (foo) return Math.random() } def defMethod() { if (foo) return Math.random() } ''' assertNoViolations(SOURCE) } @Test void testFieldsCastToLong() { final SOURCE = ''' class MyClass { def a = (long) Math.random() def b = (Long) Math.random() } ''' assertTwoViolations(SOURCE, 3, '(long) Math.random()', 'Casting the result of Math.random() to a long always results in 0', 4, '(Long) Math.random()', 'Casting the result of Math.random() to a Long always results in 0') } @Test void testLongFields() { final SOURCE = ''' class MyClass { long c = Math.random() Long d = Math.random() } ''' assertTwoViolations(SOURCE, 3, 'long c = Math.random()', 'Assigning the result of Math.random() to a long always results in 0', 4, 'Long d = Math.random()', 'Assigning the result of Math.random() to a Long always results in 0') } @Test void testFieldsAsLong() { final SOURCE = ''' class MyClass { def e = (Math.random()) as long def f = (Math.random()) as Long } ''' assertTwoViolations(SOURCE, 3, '(Math.random()) as long', 'Casting the result of Math.random() to a long always results in 0', 4, '(Math.random()) as Long', 'Casting the result of Math.random() to a Long always results in 0') } @Test void testLongReturningMethods() { final SOURCE = ''' long longMethod() { if (foo) return Math.random() } Long longMethod2() { return ((foo) ?: Math.random()) } ''' assertTwoViolations(SOURCE, 3, 'Math.random()', 'Returning the result of Math.random() from a long-returning method always returns 0', 6, 'Math.random()', 'Returning the result of Math.random() from a Long-returning method always returns 0') } @Test void testFieldsCastToInt() { final SOURCE = ''' class MyClass { def a = (int) Math.random() def b = (Integer) Math.random() } ''' assertTwoViolations(SOURCE, 3, '(int) Math.random()', 'Casting the result of Math.random() to an int always results in 0', 4, '(Integer) Math.random()', 'Casting the result of Math.random() to an Integer always results in 0') } @Test void testIntFields() { final SOURCE = ''' class MyClass { int c = Math.random() Integer d = Math.random() } ''' assertTwoViolations(SOURCE, 3, 'int c = Math.random()', 'Assigning the result of Math.random() to an int always results in 0', 4, 'Integer d = Math.random()', 'Assigning the result of Math.random() to an Integer always results in 0') } @Test void testFieldsAsInt() { final SOURCE = ''' class MyClass { def e = (Math.random()) as int def f = (Math.random()) as Integer } ''' assertTwoViolations(SOURCE, 3, '(Math.random()) as int', 'Casting the result of Math.random() to an int always results in 0', 4, '(Math.random()) as Integer', 'Casting the result of Math.random() to an Integer always results in 0') } @Test void testIntReturningMethods() { final SOURCE = ''' int intMethod() { if (foo) return Math.random() } Integer integerMethod() { if (foo) return Math.random() } ''' assertTwoViolations(SOURCE, 3, 'Math.random()', 'Returning the result of Math.random() from an int-returning method always returns 0', 6, 'Math.random()', 'Returning the result of Math.random() from an Integer-returning method always returns 0') } protected Rule createRule() { new RandomDoubleCoercedToZeroRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ReturnFromFinallyBlockRuleTest.groovy���������0000644�0001750�0001750�00000006051�12041642700�031466� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ReturnFromFinallyBlockRule * * @author Chris Mair */ class ReturnFromFinallyBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ReturnFromFinallyBlock' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { int myMethod() { if (debug) { return 0 // ok } try { doSomething() return 0 // ok } catch(Exception e) { println 'exception' return -1 // ok } finally { println 'finally' return 99 // BAD } } } ''' assertSingleViolation(SOURCE, 15, 'return 99') } @Test void testApplyTo_NestedTryFinally() { final SOURCE = ''' class MyClass { int myClosure = { try { doSomething() return 0 // ok } finally { try { // clean up return 88 // BAD } finally { println "ok" } println 'finally' return 99 } // BAD 0 // ok } } ''' assertTwoViolations(SOURCE, 10, '88', 15, '99') } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { try { 'abc' } finally { println 'ok' } 'def' } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ReturnFromFinallyBlockRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ConstantTernaryExpressionRuleTest.groovy������0000644�0001750�0001750�00000006610�12041642700�032310� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConstantTernaryExpressionRule * * @see ConstantTernaryExpressionRule_ElvisTest * * @author Chris Mair */ class ConstantTernaryExpressionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ConstantTernaryExpression' } @Test void testApplyTo_True_IsAViolation() { final SOURCE = ''' def x = true ? 1 : 0 def y def z = Boolean.TRUE ? 1 : 0 ''' assertTwoViolations(SOURCE, 2, 'def x = true ? 1 : 0', 4, 'def z = Boolean.TRUE ? 1 : 0') } @Test void testApplyTo_False_IsAViolation() { final SOURCE = ''' def x = false ? 1 : 0 println 'ok' def y = Boolean.FALSE ? 1 : 0 ''' assertTwoViolations(SOURCE, 2, 'def x = false ? 1 : 0', 4, 'def y = Boolean.FALSE ? 1 : 0') } @Test void testApplyTo_Null_IsAViolation() { final SOURCE = ''' def x = null ? 1 : 0 ''' assertSingleViolation(SOURCE, 2, 'def x = null ? 1 : 0') } @Test void testApplyTo_StringLiteral_IsAViolation() { final SOURCE = ''' def x = "abc" ? 1 : 0 def y = "" ? 1 : 0 ''' assertTwoViolations(SOURCE, 2, 'def x = "abc" ? 1 : 0', 3, 'def y = "" ? 1 : 0') } @Test void testApplyTo_NumberLiteral_IsAViolation() { final SOURCE = ''' def x = 99.9 ? 1 : 0 def y = 0 ? 1 : 0 ''' assertTwoViolations(SOURCE, 2, 'def x = 99.9 ? 1 : 0', 3, 'def y = 0 ? 1 : 0') } @Test void testApplyTo_MapLiteral_IsAViolation() { final SOURCE = ''' def x = [:] ? 1 : 0 def y = [a:123, b:456] ? 1 : 0 ''' assertTwoViolations(SOURCE, 2, 'def x = [:] ? 1 : 0', 3, 'def y = [a:123, b:456] ? 1 : 0') } @Test void testApplyTo_ListLiteral_IsAViolation() { final SOURCE = ''' def x = [] ? 1 : 0 def y = [a, 456] ? 1 : 0 ''' assertTwoViolations(SOURCE, 2, 'def x = [] ? 1 : 0', 3, 'def y = [a, 456] ? 1 : 0') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' class MyClass { def x1 = z ? 1 : 0 def x2 = (z+2) ? 1 : 0 def x3 = "$abc" ? 1 : 0 def x4 = MAX_VALUE ? 1 : 0 }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ConstantTernaryExpressionRule() } } ������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyMethodRuleTest.groovy��������������������0000644�0001750�0001750�00000004216�12041642700�027331� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyMethodRule * * @author Hamlet D'Arcy */ class EmptyMethodRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyMethod' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { @Override public void method1() {} public void method2() { 4 + 5 } } abstract class MyBaseClass { // OK, handled by EmptyMethodInAbstractClass Rule public void method() {} } ''' assertNoViolations(SOURCE) } @Test void testDeclaredMethod() { final SOURCE = ''' class MyClass { public void method() {} } ''' assertSingleViolation(SOURCE, 3, 'method()', 'The method method is both empty and not marked with @Override') } @Test void testDeffedMethod() { final SOURCE = ''' class MyClass { def method() {} } ''' assertSingleViolation(SOURCE, 3, 'method()', 'The method method is both empty and not marked with @Override') } protected Rule createRule() { new EmptyMethodRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ExplicitGarbageCollectionRuleTest.groovy������0000644�0001750�0001750�00000005266�12041642700�032146� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ExplicitGarbageCollectionRule * * @author 'Hamlet D'Arcy' */ class ExplicitGarbageCollectionRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ExplicitGarbageCollection' } @Test void testSuccessScenario() { final SOURCE = ''' System.gc(666) System2.gc() Runtime2.getRuntime().gc() Runtime.getRuntime2().gc() Runtime.getRuntime(666).gc() Runtime.getRuntime().gc(666) System.runFinalization(666) System2.runFinalization() Runtime.runtime.gc2() Runtime.runtime.gc(666) Runtime2.runtime.gc() ''' assertNoViolations(SOURCE) } @Test void testSystemGC() { final SOURCE = ''' System.gc() ''' assertSingleViolation(SOURCE, 2, 'System.gc()', 'Garbage collection should not be explicitly forced') } @Test void testSystemFinalization() { final SOURCE = ''' System.runFinalization() ''' assertSingleViolation(SOURCE, 2, 'System.runFinalization()', 'Garbage collection should not be explicitly forced') } @Test void testRuntimeGcMethodCall() { final SOURCE = ''' Runtime.getRuntime().gc() ''' assertSingleViolation(SOURCE, 2, 'Runtime.getRuntime().gc()', 'Garbage collection should not be explicitly forced') } @Test void testRuntimeGcPropertyInvocation() { final SOURCE = ''' Runtime.runtime.gc() ''' assertSingleViolation(SOURCE, 2, 'Runtime.runtime.gc()', 'Garbage collection should not be explicitly forced') } protected Rule createRule() { new ExplicitGarbageCollectionRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/BitwiseOperatorInConditionalRuleTest.groovy���0000644�0001750�0001750�00000014713�12311370173�032674� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BitwiseOperatorInConditionalRule * * @author Jeff Beck */ class BitwiseOperatorInConditionalRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BitwiseOperatorInConditional' } @Test void testTempBitwiseOr() { //(3 | 6) == 7 a bitwise or final SOURCE = ''' def temp = (3 | 6) if(temp==7) { return true} ''' assertNoViolations(SOURCE) } @Test void testOr() { final SOURCE = ''' def a = false def b = true if(a||b) { return true} ''' assertNoViolations(SOURCE) } @Test void testTempWhileOr() { final SOURCE = ''' def temp = (3 | 6) while(temp==7) { return true} ''' assertNoViolations(SOURCE) } @Test void testBitwiseOrViolation() { final SOURCE = ''' def a = false def b = true if(a|b) { return true} ''' assertSingleViolation(SOURCE, 4, 'if(a|b) { return true}', 'Use of a bitwise or (|) operator in a conditional') } @Test void testBitwiseOrViolationNested() { final SOURCE = ''' def a = false def b = true if(a|b||a) { return true} ''' assertSingleViolation(SOURCE, 4, 'if(a|b||a) { return true}') } @Test void testBitwiseOrViolationNestedLeft() { final SOURCE = ''' def a = false def b = true if((a|b)||(a||b)) { return true} ''' assertSingleViolation(SOURCE, 4, 'if((a|b)||(a||b)) { return true}') } @Test void testBitwiseOrViolationNestedRight() { final SOURCE = ''' def a = false def b = true if((a||b)||(a|b)) { return true} ''' assertSingleViolation(SOURCE, 4, 'if((a||b)||(a|b)) { return true}') } @Test void testBitwiseOrViolationNestedRightDeep() { final SOURCE = ''' def a = false def b = true if((a||b)||a && b || b || (a|b)) { return true} ''' assertSingleViolation(SOURCE, 4, 'if((a||b)||a && b || b || (a|b)) { return true}') } @Test void testBitwiseOrViolationWhile() { final SOURCE = ''' def a = false def b = true while(a|b) { return true} ''' assertSingleViolation(SOURCE, 4, 'while(a|b) { return true}') } @Test void testBitwiseOrViolationTernary() { final SOURCE = ''' def a = false def b = true a|b ? true : false ''' assertSingleViolation(SOURCE, 4, 'a|b ? true : false', 'Use of a bitwise or (|) operator in a conditional') } @Test void testBitwiseOrViolationShortTernary() { final SOURCE = ''' def a = false def b = true a|b ?: false ''' assertSingleViolation(SOURCE, 4, 'a|b ?: false') } @Test void testTempBitwiseAnd() { //(3 & 6) == 2 a bitwise and final SOURCE = ''' def temp = (3 & 6) if(temp==2) { return true} ''' assertNoViolations(SOURCE) } @Test void testBitwiseAndViolation() { final SOURCE = ''' def a = false def b = true if(a&b) { return true} ''' assertSingleViolation(SOURCE, 4, 'if(a&b) { return true}', 'Use of a bitwise and (&) operator in a conditional') } @Test void testBitwiseAndViolationNested() { final SOURCE = ''' def a = false def b = true if(a&b||a) { return true} ''' assertSingleViolation(SOURCE, 4, 'if(a&b||a) { return true}') } @Test void testBitwiseAndViolationNestedLeft() { final SOURCE = ''' def a = false def b = true if((a&b)||(a||b)) { return true} ''' assertSingleViolation(SOURCE, 4, 'if((a&b)||(a||b)) { return true}') } @Test void testBitwiseAndViolationNestedRight() { final SOURCE = ''' def a = false def b = true if((a||b)||(a&b)) { return true} ''' assertSingleViolation(SOURCE, 4, 'if((a||b)||(a&b)) { return true}') } @Test void testBitwiseAndViolationNestedRightDeep() { final SOURCE = ''' def a = false def b = true if((a||b)||a && b || b || (a&b)) { return true} ''' assertSingleViolation(SOURCE, 4, 'if((a||b)||a && b || b || (a&b)) { return true}') } @Test void testBitwiseAndViolationWhile() { final SOURCE = ''' def a = false def b = true while(a&b) { return true} ''' assertSingleViolation(SOURCE, 4, 'while(a&b) { return true}') } @Test void testBitwiseAndViolationTernary() { final SOURCE = ''' def a = false def b = true a&b ? true : false ''' assertSingleViolation(SOURCE, 4, 'a&b ? true : false') } @Test void testBitwiseAndViolationShortTernary() { final SOURCE = ''' def a = false def b = true a&b ?: false ''' assertSingleViolation(SOURCE, 4, 'a&b ?: false') } protected Rule createRule() { new BitwiseOperatorInConditionalRule() } } �����������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ThrowExceptionFromFinallyBlockRuleTest.groovy�0000644�0001750�0001750�00000006340�12041642700�033172� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ThrowExceptionFromFinallyBlockRule * * @author Chris Mair */ class ThrowExceptionFromFinallyBlockRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'ThrowExceptionFromFinallyBlock' } @Test void testApplyTo_Violation() { final SOURCE = ''' class MyClass { int myMethod() { if (debug) { throw new Exception() // ok } try { doSomething() throw new Exception() // ok } catch(Exception e) { println 'exception' throw new Exception() // ok } finally { println 'finally' throw new Exception() // BAD } } } ''' assertSingleViolation(SOURCE, 15, 'throw new Exception()') } @Test void testApplyTo_NestedTryFinally() { final SOURCE = ''' class MyClass { def myClosure = { try { doSomething() throw new Exception() // ok } finally { try { // clean up throw new Exception('A') // BAD } finally { println "ok" } println 'finally' throw new Exception('B') } // BAD throw new Exception() // ok } } ''' assertTwoViolations(SOURCE, 10, "throw new Exception('A')", 15, "throw new Exception('B')") } @Test void testApplyTo_NoViolation() { final SOURCE = '''class MyClass { def myMethod() { try { throw new Exception() // ok } finally { println 'ok' } throw new Exception() // ok } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ThrowExceptionFromFinallyBlockRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ConstantTernaryExpressionRule_ElvisTest.groovy0000644�0001750�0001750�00000006277�12041642700�033463� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ConstantTernaryExpressionRule handling of the "Elvis" operator. * * @see ConstantTernaryExpressionRuleTest * * @author Chris Mair */ class ConstantTernaryExpressionRule_ElvisTest extends AbstractRuleTestCase { @Test void testApplyTo_True_IsAViolation() { final SOURCE = ''' def x = true ?: 0 def y def z = Boolean.TRUE ?: 0 ''' assertTwoViolations(SOURCE, 2, 'def x = true ?: 0', 4, 'def z = Boolean.TRUE ?: 0') } @Test void testApplyTo_False_IsAViolation() { final SOURCE = ''' def x = false ?: 0 println 'ok' def y = Boolean.FALSE ?: 0 ''' assertTwoViolations(SOURCE, 2, 'def x = false ?: 0', 4, 'def y = Boolean.FALSE ?: 0') } @Test void testApplyTo_Null_IsAViolation() { final SOURCE = ''' def x = null ?: 0 ''' assertSingleViolation(SOURCE, 2, 'def x = null ?: 0') } @Test void testApplyTo_StringLiteral_IsAViolation() { final SOURCE = ''' def x = "abc" ?: 0 def y = "" ?: 0 ''' assertTwoViolations(SOURCE, 2, 'def x = "abc" ?: 0', 3, 'def y = "" ?: 0') } @Test void testApplyTo_NumberLiteral_IsAViolation() { final SOURCE = ''' def x = 99.9 ?: 0 def y = 0 ?: 0 ''' assertTwoViolations(SOURCE, 2, 'def x = 99.9 ?: 0', 3, 'def y = 0 ?: 0') } @Test void testApplyTo_MapLiteral_IsAViolation() { final SOURCE = ''' def x = [:] ?: 0 def y = [a:123, b:456] ?: 0 ''' assertTwoViolations(SOURCE, 2, 'def x = [:] ?: 0', 3, 'def y = [a:123, b:456] ?: 0') } @Test void testApplyTo_ListLiteral_IsAViolation() { final SOURCE = ''' def x = [] ?: 0 def y = [a, 456] ?: 0 ''' assertTwoViolations(SOURCE, 2, 'def x = [] ?: 0', 3, 'def y = [a, 456] ?: 0') } @Test void testApplyTo_NoViolations() { final SOURCE = ''' class MyClass { def x1 = z ?: 0 def x2 = (z+2) ?: 0 def x3 = "$abc" ?: 0 def x4 = MAX_VALUE ?: 0 }''' assertNoViolations(SOURCE) } protected Rule createRule() { new ConstantTernaryExpressionRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptySynchronizedStatementRuleTest.groovy�����0000644�0001750�0001750�00000004136�12041642700�032456� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptySynchronizedStatementRule * * @author Chris Mair */ class EmptySynchronizedStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptySynchronizedStatement' } @Test void testApplyTo_EmptySynchronized() { final SOURCE = ''' class MyClass { def myClosure = { synchronized(lock) { } } } ''' assertSingleViolation(SOURCE, 4, 'synchronized(lock) {') } @Test void testApplyTo_Violation_SynchronizedContainsComment() { final SOURCE = ''' synchronized(lock) { // TODO Should do something here } ''' assertSingleViolation(SOURCE, 2, 'synchronized(lock) {') } @Test void testApplyTo_NonEmptySynchronized() { final SOURCE = ''' class MyClass { def myMethod() { synchronized(lock) { println "bad stuff happened" } } }''' assertNoViolations(SOURCE) } protected Rule createRule() { new EmptySynchronizedStatementRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyInstanceInitializerRuleTest.groovy�������0000644�0001750�0001750�00000003167�12041642700�032065� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyInstanceInitializerRule * * @author Hamlet D'Arcy */ class EmptyInstanceInitializerRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyInstanceInitializer' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { def x = { } } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass { { } } ''' assertSingleViolation(SOURCE, 3, '{ }', 'The class MyClass defines an empty instance initializer. It is safe to delete it') } protected Rule createRule() { new EmptyInstanceInitializerRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/EmptyStaticInitializerRuleTest.groovy���������0000644�0001750�0001750�00000003350�12041642700�031542� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for EmptyStaticInitializerRule * * @author Hamlet D'Arcy */ class EmptyStaticInitializerRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'EmptyStaticInitializer' } @Test void testSuccessScenario() { final SOURCE = ''' class MyClass { static { println 'statement' } } class MyClass2 { } ''' assertNoViolations(SOURCE) } @Test void testSingleViolation() { final SOURCE = ''' class MyClass { static { } } ''' assertSingleViolation(SOURCE, 3, 'static {', 'The class MyClass has an empty static initializer. It is safe to delete it') } protected Rule createRule() { new EmptyStaticInitializerRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/BrokenNullCheckRuleTest.groovy����������������0000644�0001750�0001750�00000010037�12041642700�030101� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2012 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for BrokenNullCheckRule * * @author Chris Mair */ class BrokenNullCheckRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'BrokenNullCheck' } @Test void testNoNullChecks_NoViolations() { final SOURCE = ''' if (name == 'xxx' || name.length > 0) { } (string != null && isReady()) ? 'yes' : 'no' while (string != null) { } def ok = string != null && x == 99 ''' assertNoViolations(SOURCE) } @Test void testProperNullChecks_NoViolations() { final SOURCE = ''' if (name == null || name.length < 1) { } def notValid = name == null || name.length == 0 def notValidStr = (name == null || !name.size()) ? 'not valid' : 'valid' if (string != null && string.length == 5) { } if (string != null && string.equals("")) { } while (nextRecord != null && nextRecord.getId()) { } ''' assertNoViolations(SOURCE) } @Test void testBrokenNullChecks_PropertyAccess_Violations() { final SOURCE = ''' if (name != null || name.length > 0) { } if (name != null || name.length) { } while (record == null && record.id < 10) { } if (record == null && record.id && somethingElse()) { } def isNotValid = record == null && record.id < 10 return record == null && !record.id ''' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (name != null || name.length > 0) { }', messageText:['name', 'None']], [lineNumber:3, sourceLineText:'if (name != null || name.length) { }', messageText:'name'], [lineNumber:4, sourceLineText:'while (record == null && record.id < 10) { }', messageText:'record'], [lineNumber:5, sourceLineText:'if (record == null && record.id && somethingElse()) { }', messageText:'record'], [lineNumber:6, sourceLineText:'def isNotValid = record == null && record.id < 10', messageText:'record'], [lineNumber:7, sourceLineText:'return record == null && !record.id', messageText:'record']) } @Test void testBrokenNullChecks_MethodCall_Violations() { final SOURCE = ''' class MyClass { def doStuff() { if (name != null || name.size() > 0) { } if (string == null && string.equals("")) { } def isValid = name != null || name.size() > 0 return name != null || !name.size() } } ''' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'if (name != null || name.size() > 0) { }', messageText:['name', 'MyClass']], [lineNumber:5, sourceLineText:'if (string == null && string.equals("")) { }', messageText:'string'], [lineNumber:6, sourceLineText:'def isValid = name != null || name.size() > 0', messageText:'name'], [lineNumber:7, sourceLineText:'return name != null || !name.size()', messageText:'name']) } protected Rule createRule() { new BrokenNullCheckRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/DuplicateCaseStatementRuleTest.groovy���������0000644�0001750�0001750�00000004356�12041642700�031472� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for DuplicateCaseStatementRule * * @author Hamlet D'Arcy */ class DuplicateCaseStatementRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'DuplicateCaseStatement' } @Test void testApplyTo_NoViolations() { final SOURCE = ''' def value = 2 switch( value ) { case 1: break case 2: break } ''' assertNoViolations(SOURCE) } @Test void testApplyTo_SingleViolationInteger() { final SOURCE = ''' switch( 0 ) { case 1: break case 2: break case 2: break } ''' assertSingleViolation(SOURCE, 7, 'case 2:') } @Test void testApplyTo_SingleViolationString() { final SOURCE = ''' switch( "test" ) { case "$a": break case "$a": break case "ab": break case "ab": break case "abc": break } ''' assertSingleViolation(SOURCE, 9, 'case "ab":') } protected Rule createRule() { new DuplicateCaseStatementRule() } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/basic/ForLoopShouldBeWhileLoopRuleTest.groovy�������0000644�0001750�0001750�00000005266�12041642700�031731� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.basic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for ForLoopShouldBeWhileLoopRule * * @author 'Victor Savkin' */ class ForLoopShouldBeWhileLoopRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'ForLoopShouldBeWhileLoop' } @Test void testShouldNotAddViolationsForWhileLoops() { final SOURCE = ''' while(1 > 2) println "never happen" ''' assertNoViolations SOURCE } @Test void testShouldNotAddViolationsForNewLoops() { final SOURCE = ''' for(i in [1,2]) println i ''' assertNoViolations SOURCE } @Test void testForWithPropertyExpression() { final SOURCE = ''' for(child in this.children) { } ''' assertNoViolations SOURCE } @Test void testShouldNotAddViolationsIfForLoopHasInitExpr() { final SOURCE = ''' for(int i = 0; i<5;) println i++ ''' assertNoViolations SOURCE } @Test void testShouldNotAddViolationsIfForLoopHasUpdateExpr() { final SOURCE = ''' int i = 0 for(; i < 5; i++) println i ''' assertNoViolations SOURCE } @Test void testShouldAddViolationIfForLoopHasOnlyConditionExpr() { final SOURCE = ''' int i = 0 for(; i < 5;) println i++ ''' assertSingleViolation SOURCE, 3, 'for(; i < 5;)', 'The for loop can be simplified to a while loop' } @Test void testForEachLoop() { final SOURCE = ''' for (Plan p : plans) { println "Plan=$p" } ''' assertNoViolations SOURCE } protected Rule createRule() { new ForLoopShouldBeWhileLoopRule() } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/FakePathRule.groovy���������������������������������0000644�0001750�0001750�00000002711�12311373552�024640� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2008 the original author or 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 org.codenarc.rule import org.codenarc.source.SourceCode /** * Test-specific Rule implementation that always returns one or more violation whose messages are * equal to the source file path. Set <code>numberOfViolations</code> to generate more than one violation. * * @author Chris Mair */ class FakePathRule extends AbstractRule { String name = 'TestPath' int priority = 1 int numberOfViolations = 1 /** * Always add a single violation whose message is equal to the source file path * @param sourceCode - the sourceCode to which the rule is applied */ void applyTo(SourceCode sourceCode, List violations) { def message = sourceCode.path?.replaceAll('\\\\', '/') numberOfViolations.times { violations << new Violation(rule:this, message:message) } } } �������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/��������������������������������������������0000755�0001750�0001750�00000000000�12623571301�022467� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalSubclassRuleTest.groovy��������������0000644�0001750�0001750�00000006437�12322754076�030521� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for IllegalSubclassRule * * @author Chris Mair */ class IllegalSubclassRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'IllegalSubclass' } @Test void testNullSuperclassNames_RuleIsNotReady() { final SOURCE = 'class MyClass { }' assert !rule.ready assertNoViolations(SOURCE) } @Test void testDoesNotMatchSuperclassNames_NoViolations() { final SOURCE = ''' class MyClass { } class MyClass2 extends Object { } class MyClass3 extends MyClass { } ''' rule.superclassNames = 'OtherClass,ClassAbc' assertNoViolations(SOURCE) } @Test void testMatchesSingleNames_Violations() { final SOURCE = ''' class MyObject extends Object { } class MyException extends Exception { } class MyClass2 extends MyClass { } ''' rule.superclassNames = 'MyClass,Object, Exception, Other' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyObject extends Object { }', messageText:'The class MyObject extends from the illegal superclass Object'], [lineNumber:3, sourceLineText:'class MyException extends Exception { }', messageText:'The class MyException extends from the illegal superclass Exception'], [lineNumber:4, sourceLineText:'class MyClass2 extends MyClass { }', messageText:'The class MyClass2 extends from the illegal superclass MyClass']) } @Test void testMatchesFullyQualifiedNames_Violations() { final SOURCE = ''' class MyObject extends java.lang.Object { } class MyException extends java.lang.Exception { } class MyClass2 extends org.example.MyClass { } ''' rule.superclassNames = '*MyClass,java.lang.Object, java.*.Exception, Other' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyObject extends java.lang.Object { }', messageText:'The class MyObject extends from the illegal superclass java.lang.Object'], [lineNumber:3, sourceLineText:'class MyException extends java.lang.Exception { }', messageText:'The class MyException extends from the illegal superclass java.lang.Exception'], [lineNumber:4, sourceLineText:'class MyClass2 extends org.example.MyClass { }', messageText:'The class MyClass2 extends from the illegal superclass org.example.MyClass']) } protected Rule createRule() { new IllegalSubclassRule() } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalPackageReferenceRuleTest.groovy������0000644�0001750�0001750�00000026776�12461314042�032111� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for IllegalPackageReferenceRule * * @author Chris Mair */ class IllegalPackageReferenceRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'IllegalPackageReference' assert rule.packageNames == null } @Test void testDefaultConfiguration_NoViolations() { final SOURCE = ''' class MyClass { Map myMap = [:] def dateFormat = java.text.SimpleDateFormat('MM') Integer calculate(javax.sql.DataSource dataSource) { } java.lang.annotation.RetentionPolicy getRetentionPolicy() { } } ''' assertNoViolations(SOURCE) assert !rule.ready } @Test void testFieldsTypes_Violations() { final SOURCE = ''' class MyClass { java.math.BigDecimal amount = 42.10 com.example.MyClass myClass } ''' rule.packageNames = 'java.math' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'java.math.BigDecimal amount = 42.10', messageText:'java.math']) } @Test void testWithinExpressions_Violations() { final SOURCE = ''' if (value.class == org.bad.BadClass) { } println "isClosure=${value instanceof org.bad.OtherClass}" def count = org.bad.Helper.getCount() ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'if (value.class == org.bad.BadClass) { }', messageText:'org.bad'], [lineNumber:3, sourceLineText:'println "isClosure=${value instanceof org.bad.OtherClass}"', messageText:'org.bad'], [lineNumber:4, sourceLineText:'def count = org.bad.Helper.getCount()', messageText:'org.bad'] ) } @Test void testConstructorCalls_Violations() { final SOURCE = ''' class MyClass { def amount = new org.bad.Value() def url = new org.bad.Name('ABC') } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'def amount = new org.bad.Value()', messageText:'org.bad'], [lineNumber:4, sourceLineText:"def url = new org.bad.Name('ABC')", messageText:'org.bad'] ) } @Test void testConstructorCall_CallToSuper_NoViolation() { final SOURCE = ''' class MyClass extends Object { MyClass() { super('and') } } ''' rule.packageNames = 'org.bad' assertNoViolations(SOURCE) } @Test void testVariableTypes_Violations() { final SOURCE = ''' void doSomething() { org.bad.Value maxValue = 0 org.bad.URI uri org.bad.Code code def noViolation = 123 } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'org.bad.Value maxValue = 0', messageText:'org.bad'], [lineNumber:4, sourceLineText:'org.bad.URI uri', messageText:'org.bad'], [lineNumber:5, sourceLineText:'org.bad.Code code', messageText:'org.bad'] ) } @Test void testMethodReturnTypes_Violations() { final SOURCE = ''' org.bad.Socket getSocket() { } org.bad.Reader getReader() { } org.bad.AntBuilder getAntBuilder() { } def noViolation() { } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'org.bad.Socket getSocket() { }', messageText:'org.bad'], [lineNumber:3, sourceLineText:'org.bad.Reader getReader() { }', messageText:'org.bad'], [lineNumber:4, sourceLineText:'org.bad.AntBuilder getAntBuilder() { }', messageText:'org.bad'] ) } @Test void testMethodParameterTypes_Violations() { final SOURCE = ''' void writeCount(org.bad.Writer writer, int count) { } void initializeBinding(String name, org.bad.Binding binding) { } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'void writeCount(org.bad.Writer writer, int count)', messageText:'org.bad'], [lineNumber:3, sourceLineText:'void initializeBinding(String name, org.bad.Binding binding) { }', messageText:'org.bad'] ) } @Test void testConstructorCall_Parameter_Violation() { final SOURCE = ''' def handler = new Handler(org.bad.Request) ''' rule.packageNames = 'org.bad' assertSingleViolation(SOURCE, 2, 'def handler = new Handler(org.bad.Request)', 'org.bad') } @Test void testConstructorParameterType_Violation() { final SOURCE = ''' class MyClass { MyClass(org.bad.Stuff stuff) { } } ''' rule.packageNames = 'org.bad' assertSingleViolation(SOURCE, 3, 'MyClass(org.bad.Stuff stuff) { }', 'org.bad') } @Test void testClosureParameterTypes_Violations() { final SOURCE = ''' def writeCount = { org.bad.Writer writer, int count -> } def initializeBinding = { String name, org.bad.Binding binding -> } def noViolation = { name, binding, int count -> } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def writeCount = { org.bad.Writer writer, int count -> }', messageText:'org.bad'], [lineNumber:3, sourceLineText:'def initializeBinding = { String name, org.bad.Binding binding -> }', messageText:'org.bad'] ) } @Test void testAsType_Violation() { final SOURCE = ''' def x = value as org.bad.Widget ''' rule.packageNames = 'org.bad' assertSingleViolation(SOURCE, 2, 'def x = value as org.bad.Widget', 'org.bad') } @Test void testExtendsSuperclassOrSuperInterfaceTypes_Violations() { final SOURCE = ''' class MyHashMap extends org.bad.HashMap { } class MyScript extends org.bad.Script { } interface MyList extends org.bad.List { } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyHashMap extends org.bad.HashMap { }', messageText:'org.bad'], [lineNumber:3, sourceLineText:'class MyScript extends org.bad.Script { }', messageText:'org.bad'], [lineNumber:4, sourceLineText:'interface MyList extends org.bad.List { }', messageText:'org.bad'] ) } @Test void testImplementsInterfaceTypes_Violations() { final SOURCE = ''' class MyList implements org.bad.List { } class MyRange implements org.bad.Range { } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyList implements org.bad.List { }', messageText:'org.bad'], [lineNumber:3, sourceLineText:'class MyRange implements org.bad.Range { }', messageText:'org.bad'] ) } @Test void testImports_Violations() { final SOURCE = ''' import org.bad.BadStuff import org.bad.other.Stuff import org.evil.* class MyList { BadStuff badStuff = new Stuff() } ''' rule.packageNames = 'org.bad, org.evil' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'import org.bad.BadStuff', messageText:'org.bad'], [lineNumber:4, sourceLineText:'import org.evil.*', messageText:'org.evil'] ) } @Test void testStaticImports_Violations() { final SOURCE = ''' import org.other.Stuff import static org.bad.BadUtil.* class MyList { def name = BAD_NAME } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'import static org.bad.BadUtil.*', messageText:'org.bad'] ) } @Test void testMultiplePackageNames_SingleViolation() { final SOURCE = ''' class MyClass { java.text.DateFormat dateFormat = 'MM' com.example.service.MyService myService } ''' rule.packageNames = 'com.other,com.example.service' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'com.example.service.MyService myService', messageText:'com.example.service']) } @Test void testMultiplePackageNames_MultipleViolations() { final SOURCE = ''' class MyHashMap extends org.bad.HashMap { def myMethod() { println 'ok' } int getCount(com.example.Widget widget) { return widget.count } } ''' rule.packageNames = 'com.example,com.example,org.bad,com.other.ignore' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'class MyHashMap extends org.bad.HashMap {', messageText:'org.bad'], [lineNumber:4, sourceLineText:'int getCount(com.example.Widget widget) { return widget.count }', messageText:'com.example'] ) } @Test void testMultiplePackageNames_Wildcards_MultipleViolations() { final SOURCE = ''' import com.example.ExampleHelper class MyClass implements com.example.print.Printable { def myMethod() { println 'ok' } int getCount(org.bad.widget.Widget widget) { return widget.count } } ''' rule.packageNames = 'com.ex?mple*,org.*,com.other.*' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'import com.example.ExampleHelper', messageText:'com.example'], [lineNumber:3, sourceLineText:'class MyClass implements com.example.print.Printable {', messageText:'com.example.print'], [lineNumber:5, sourceLineText:'int getCount(org.bad.widget.Widget widget) { return widget.count }', messageText:'org.bad'] ) } @Test void testAnonymousInnerClass_KnownIssue_NoViolation() { final SOURCE = ''' def x = new org.bad.Handler() { } ''' rule.packageNames = 'org.bad' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'def x = new org.bad.Handler() { }', messageText:'org.bad'] ) } protected Rule createRule() { new IllegalPackageReferenceRule() } } ��././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000155�00000000000�011604� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalClassReferenceRule_SingleClassNameTest.groovy��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalClassReferenceRule_SingleClassNameTes0000644�0001750�0001750�00000003075�12041642702�033167� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for IllegalClassReferenceRule - checks for specifying a single class name for the classNames field * * @see IllegalClassReferenceRule_MultipleClassNamesTest * @see IllegalClassReferenceRule_WildcardsClassNamesTest * * @author Chris Mair */ class IllegalClassReferenceRule_SingleClassNameTest extends AbstractClassReferenceRuleTestCase { final String className = 'com.example.MyExampleClass' @Test void testRuleProperties() { rule = new IllegalClassReferenceRule() assert rule.priority == 2 assert rule.name == 'IllegalClassReference' assert rule.classNames == null assert !rule.ready } protected Rule createRule() { new IllegalClassReferenceRule(classNames:'com.example.MyExampleClass') } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalClassMemberRuleTest.groovy�����������0000644�0001750�0001750�00000016607�12311373552�031131� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.Rule import org.junit.Test import org.codenarc.rule.AbstractRuleTestCase /** * Tests for IllegalClassMemberRule * * @author Chris Mair */ class IllegalClassMemberRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'IllegalClassMember' } @Test void testNoConfiguration_RuleIsNotReady() { final SOURCE = ' class MyClass { }' rule.applyToClassNames = null // overwrite initialization assert !rule.ready assertNoViolations(SOURCE) } @Test void testMustConfigureOneOfApplyToFields_AndOneOfTheModifiersFields() { def newRule = new IllegalClassMemberRule() newRule.illegalFieldModifiers = 'public' assert !newRule.ready newRule.applyToClassNames = '*' assert newRule.ready newRule.applyToClassNames = null newRule.applyToFileNames = '*' assert newRule.ready newRule.applyToFileNames = null newRule.applyToFilesMatching = 'A.*' assert newRule.ready newRule.illegalFieldModifiers = null newRule.applyToClassNames = '*' assert !newRule.ready } // Fields @Test void testFields_IllegalFieldModifiers_Match_Violations() { final SOURCE = ''' class MyClass { public field1 protected field2 private field3 public static final FIELD4 } ''' rule.illegalFieldModifiers = 'public static, protected' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'protected field2', messageText:'field2'], [lineNumber:6, sourceLineText:'public static final FIELD4', messageText:'FIELD4']) } @Test void testFields_AllowedFieldModifiers_NoMatch_Violations() { final SOURCE = ''' class MyClass { public field1 protected field2 } ''' rule.allowedFieldModifiers = 'public final, private, protected static' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'public field1', messageText:'field1'], [lineNumber:4, sourceLineText:'protected field2', messageText:'field2']) } // Properties @Test void testProperties_IllegalPropertyModifiers_Match_Violations() { final SOURCE = ''' class MyClass { def property1 final property2 static property3 } ''' rule.illegalPropertyModifiers = 'final' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'final property2', messageText:'property2']) } @Test void testProperties_AllowedPropertyModifiers_NoMatch_Violations() { final SOURCE = ''' class MyClass { def property1 final property2 static property3 } ''' rule.allowedPropertyModifiers = 'static' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'def property1', messageText:'property1'], [lineNumber:4, sourceLineText:'final property2', messageText:'property2']) } // Methods @Test void testMethods_IllegalMethodModifiers_Match_Violations() { final SOURCE = ''' class MyClass { public method1() { } protected method2() { } private method3() { } public static final method4() { } } ''' rule.illegalMethodModifiers = 'public static, protected' assertViolations(SOURCE, [lineNumber:4, sourceLineText:'protected method2()', messageText:'method2'], [lineNumber:6, sourceLineText:'public static final method4()', messageText:'method4']) } @Test void testMethods_AllowedMethodModifiers_NoMatch_Violations() { final SOURCE = ''' class MyClass { public method1() { } protected method2() { } } ''' rule.allowedMethodModifiers = 'public final, private, protected static' assertViolations(SOURCE, [lineNumber:3, sourceLineText:'public method1()', messageText:'method1'], [lineNumber:4, sourceLineText:'protected method2', messageText:'method2']) } @Test void testMethods_IgnoreMethodNames_MatchesSingleName_NoViolations() { final SOURCE = ''' class MyClass { public method1() { } } ''' rule.ignoreMethodNames = 'method1' rule.illegalMethodModifiers = 'public' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodNames_MatchesNoNames() { final SOURCE = ''' class MyClass { public method1() { } } ''' rule.ignoreMethodNames = 'method2' rule.illegalMethodModifiers = 'public' assertSingleViolation(SOURCE, 3, 'public method1') } @Test void testApplyTo_IgnoreMethodNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { public method1() { } public otherMethod1() { } public badMethod1() { } } ''' rule.allowedMethodModifiers = 'protected' rule.ignoreMethodNames = 'meth?d?,x*, badM*' assertSingleViolation(SOURCE, 4, 'public otherMethod1') } //----------------------- @Test void testMethods_IgnoreMethodsWithAnnotationNames_MatchesSingleName_NoViolations() { final SOURCE = ''' class MyClass { @Override public method1() { } } ''' rule.ignoreMethodsWithAnnotationNames = 'Override' rule.illegalMethodModifiers = 'public' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreMethodsWithAnnotationNames_MatchesNoNames() { final SOURCE = ''' class MyClass { @Override public method1() { } } ''' rule.ignoreMethodsWithAnnotationNames = 'Test' rule.illegalMethodModifiers = 'public' assertSingleViolation(SOURCE, 4, 'public method1') } @Test void testApplyTo_IgnoreMethodsWithAnnotationNames_MultipleNamesWithWildcards() { final SOURCE = ''' class MyClass { @Override public method1() { } public otherMethod1() { } @SuppressWarnings('Bad') public badMethod1() { } } ''' rule.allowedMethodModifiers = 'protected' rule.ignoreMethodsWithAnnotationNames = 'Over?ide,Other,Supp*Warnings' assertSingleViolation(SOURCE, 5, 'public otherMethod1') } //--------------- protected Rule createRule() { new IllegalClassMemberRule(applyToClassNames:'*') } } �������������������������������������������������������������������������������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000161�00000000000�011601� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalClassReferenceRule_WildcardsClassNamesTest.groovy����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalClassReferenceRule_WildcardsClassName0000644�0001750�0001750�00000005171�12041642702�033205� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for IllegalClassReferenceRule - checks for specifying values containing wildcards for the classNames field * * @see IllegalClassReferenceRule_SingleClassNameTest * @see IllegalClassReferenceRule_MultipleClassNamesTest * * @author Chris Mair */ class IllegalClassReferenceRule_WildcardsClassNamesTest extends AbstractRuleTestCase { // Just test proper handling of wildcards by this rule. Assume that the other IllegalClassReferenceRule_*Test // classes sufficiently test references across the possible language constructs. @Test void testWildcards_Violations() { final SOURCE = ''' import com.other.Example class MyClass extends com.example.Example { void writeOther(com.other.Other other) { } def myDao = new org.stuff.CoolDao() } ''' rule.classNames = 'com.*.Example, com.other.Oth?r,*Dao' assertViolations(SOURCE, [lineNumber:2, sourceLineText:'import com.other.Example', messageText:'com.other.Example'], [lineNumber:3, sourceLineText:'class MyClass extends com.example.Example {', messageText:'com.example.Example'], [lineNumber:4, sourceLineText:'void writeOther(com.other.Other other) { }', messageText:'com.other.Other'], [lineNumber:5, sourceLineText:'def myDao = new org.stuff.CoolDao', messageText:'org.stuff.CoolDao']) } @Test void testWildcards_NoViolations() { final SOURCE = ''' import com.other.Example class MyClass extends com.example.Example { void writeOther(com.other.Other other) { } } ''' rule.classNames = 'ignore.*.Example, com.ignore.Oth?r' assertNoViolations(SOURCE) } protected Rule createRule() { new IllegalClassReferenceRule() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/RequiredStringRuleTest.groovy���������������0000644�0001750�0001750�00000003610�12240300572�030370� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for RequiredStringRule * * @author Chris Mair */ class RequiredStringRuleTest extends AbstractRuleTestCase { static skipTestThatUnrelatedCodeHasNoViolations static skipTestThatInvalidCodeHasNoViolations private static final TEXT = '@author Joe' @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'RequiredString' } @Test void testStringIsNull() { final SOURCE = 'class MyClass { } ' rule.string = null assert !rule.ready assertNoViolations(SOURCE) } @Test void testStringIsPresent() { final SOURCE = ''' /** @author Joe */ class MyClass { } ''' assertNoViolations(SOURCE) } @Test void testStringIsNotPresent() { final SOURCE = ''' /** @author Mike */ class MyClass { } ''' assertSingleViolation(SOURCE, null, null, ['string', TEXT]) } protected Rule createRule() { new RequiredStringRule(string:TEXT) } } ������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalStringRuleTest.groovy����������������0000644�0001750�0001750�00000003320�12311373552�030166� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for IllegalStringRule * * @author Chris Mair */ class IllegalStringRuleTest extends AbstractRuleTestCase { private static final TEXT = '@author Joe' @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'IllegalString' } @Test void testStringIsNull() { final SOURCE = 'class MyClass { } ' rule.string = null assert !rule.ready assertNoViolations(SOURCE) } @Test void testStringIsNotPresent() { final SOURCE = ''' /** @author Mike */ class MyClass { } ''' assertNoViolations(SOURCE) } @Test void testStringIsPresent() { final SOURCE = ''' /** @author Joe */ class MyClass { } ''' assertSingleViolation(SOURCE, null, null, ['string', TEXT]) } protected Rule createRule() { new IllegalStringRule(string:TEXT) } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/RequiredRegexRuleTest.groovy����������������0000644�0001750�0001750�00000003733�12041642702�030205� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test import static org.codenarc.test.TestUtil.containsAll /** * Tests for RequiredRegexRule * * @author Chris Mair */ class RequiredRegexRuleTest extends AbstractRuleTestCase { static skipTestThatUnrelatedCodeHasNoViolations static skipTestThatInvalidCodeHasNoViolations private static final REGEX = /\@author Joe/ @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'RequiredRegex' } @Test void testRegexIsNull() { final SOURCE = 'class MyClass { } ' rule.regex = null assert !rule.ready assertNoViolations(SOURCE) } @Test void testRegexIsPresent() { final SOURCE = ''' /** @author Joe */ class MyClass { } ''' assertNoViolations(SOURCE) } @Test void testRegexIsNotPresent() { final SOURCE = ''' /** @author Mike */ class MyClass { } ''' assertSingleViolation(SOURCE) { v -> containsAll(v.message, ['regular expression', REGEX]) } } protected Rule createRule() { new RequiredRegexRule(regex:REGEX) } } �������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalRegexRuleTest.groovy�����������������0000644�0001750�0001750�00000004675�12407277657�030027� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Test /** * Tests for IllegalRegexRule * * @author Chris Mair */ class IllegalRegexRuleTest extends AbstractRuleTestCase { private static final REGEX = /\@author Joe/ @Test void testRuleProperties() { assert rule.priority == 3 assert rule.name == 'IllegalRegex' } @Test void testRegexIsNull() { final SOURCE = ' class MyClass { }' rule.regex = null assert !rule.ready assertNoViolations(SOURCE) } @Test void testRegexIsPresent() { final SOURCE = ''' /** @author Joe */ class MyClass { } ''' assertSingleViolation(SOURCE, 2, '@author Joe', ['regular expression', REGEX]) } @Test void testTwoOccurrences() { final SOURCE = ''' /** @author Joe */ class MyClass { } // Other @author Joe ''' assertTwoViolations(SOURCE, 2, '@author Joe', ['regular expression', REGEX], 5, '@author Joe', ['regular expression', REGEX]) } @Test void testRegexIsNotPresent() { final SOURCE = ''' /** @author Mike */ class MyClass { } ''' assertNoViolations(SOURCE) } @Test void testOverrideViolationMessage() { final SOURCE = ''' /** @author Joe */ class MyClass { } ''' rule.violationMessage = 'abc123' assertSingleViolation(SOURCE, 2, '@author Joe', 'abc123') } protected Rule createRule() { new IllegalRegexRule(regex:REGEX) } } �������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/StatelessClassRuleTest.groovy���������������0000644�0001750�0001750�00000015716�12311370173�030373� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractRuleTestCase import org.codenarc.rule.Rule import org.junit.Before import org.junit.Test /** * Tests for StatelessClassRule * * @author Chris Mair */ class StatelessClassRuleTest extends AbstractRuleTestCase { @Test void testRuleProperties() { assert rule.priority == 2 assert rule.name == 'StatelessClass' } @Test void testDefaultConfiguration_NoViolations() { final SOURCE = ''' class MyClass { BigDecimal depositAmount def other } ''' assertNoViolations(SOURCE) assert !rule.ready } @Test void testApplyTo_HasFields() { final SOURCE = ''' class MyClass { BigDecimal depositAmount def other } ''' rule.applyToClassNames = 'MyClass' assertTwoViolations(SOURCE, 3, 'BigDecimal depositAmount', 4, 'def other') } @Test void testApplyTo_IgnoresClassesWithImmutableAnnotation() { final SOURCE = ''' @Immutable class Coordinates { Double latitude, longitude } ''' rule.applyToClassNames = '*' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoresFieldsWithInjectAnnotation() { final SOURCE = ''' class MyClass { @Inject BigDecimal depositAmount } ''' rule.applyToClassNames = '*' assertNoViolations(SOURCE) } @Test void testApplyTo_FinalField() { final SOURCE = ''' class MyClass { final value = 5 } ''' rule.applyToFileNames = '*' assertNoViolations(SOURCE) } @Test void testApplyTo_StaticField() { final SOURCE = ''' class MyClass { static depositCount = 5 def other } ''' rule.applyToFilesMatching = /.*/ assertTwoViolations(SOURCE, 3, 'static depositCount = 5', 4, 'def other') } @Test void testApplyTo_StaticFinalField() { final SOURCE = ''' class MyClass { static final DEFAULT_NAME = 'ABC' } ''' rule.applyToClassNames = '*' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreFieldNames_OneExactName() { final SOURCE = ''' class MyClass { BigDecimal depositAmount def other } ''' rule.applyToClassNames = '*' rule.ignoreFieldNames = 'other' assertSingleViolation(SOURCE, 3, 'BigDecimal depositAmount', "Violation in class MyClass. The class is marked as stateless but contains the non-final field 'depositAmount'") } @Test void testApplyTo_IgnoreFieldNames_TwoExactNames() { final SOURCE = ''' class MyClass { BigDecimal depositAmount def other } ''' rule.applyToClassNames = '*' rule.ignoreFieldNames = 'other,depositAmount' assertNoViolations(SOURCE) } @Test void testApplyTo_IgnoreFieldNames_Wildcards() { final SOURCE = ''' class MyClass { BigDecimal depositAmount def other int count long otherMax } ''' rule.applyToClassNames = '*' rule.ignoreFieldNames = 'oth*,xxxx' rule.addToIgnoreFieldNames = 'yyy,deposit??ount' assertSingleViolation(SOURCE, 5, 'int count') } @Test void testApplyTo_IgnoreFieldTypes_OneExactName() { final SOURCE = ''' class MyClass { BigDecimal depositAmount def other } ''' rule.applyToClassNames = '*' rule.ignoreFieldTypes = 'BigDecimal' assertSingleViolation(SOURCE, 4, 'def other') } @Test void testApplyTo_IgnoreFieldTypes_Wildcards() { final SOURCE = ''' class MyClass { BigDecimal depositAmount def other int count = 23 long otherMax Object lock = new Object() } ''' rule.applyToClassNames = '*' rule.ignoreFieldTypes = '*Decimal,java.lang.Object,l?n?' assertTwoViolations(SOURCE, 5, 'int count = 23', 7, 'Object lock = new Object()') } @Test void testApplyTo_IgnoreFieldNamesAndIgnoreFieldTypes() { final SOURCE = ''' class MyClass { BigDecimal depositAmount def other int count long otherMax } ''' rule.applyToClassNames = '*' rule.ignoreFieldNames = 'oth*,XXX' rule.ignoreFieldTypes = '*Decimal,YYY,int,l?n?' assertNoViolations(SOURCE) } @Test void testApplyTo_Script_HasField() { final SOURCE = ''' BigDecimal depositAmount // not considered a field xxx = 23 // not considered a field println 'ok' ''' rule.applyToFileNames = '*' assertNoViolations(SOURCE) } @Test void testApplyTo_NoFieldDefinition() { final SOURCE = ' class MyClass { } ' rule.applyToClassNames = '*' assertNoViolations(SOURCE) } @Test void testSetAddToIgnoreFieldNames_IgnoreFieldNamesIsNull() { rule.setAddToIgnoreFieldNames('abc') assert rule.ignoreFieldNames == 'abc' } @Test void testSetAddToIgnoreFieldNames_IgnoreFieldNamesAlreadySet() { rule.ignoreFieldNames = 'abc' rule.setAddToIgnoreFieldNames('def,ghi') assert rule.ignoreFieldNames == 'abc,def,ghi' } @Test void testSetAddToIgnoreFieldNames_MultipleCalls_AddToIgnoreFieldNames() { rule.setAddToIgnoreFieldNames('abc,d*f') rule.addToIgnoreFieldNames = 'gh?' assert rule.ignoreFieldNames == 'abc,d*f,gh?' } @Before void setUpStatelessClassRuleTest() { sourceCodeName = 'MyClass.groovy' sourceCodePath = "/$sourceCodeName" } protected Rule createRule() { new StatelessClassRule() } } ��������������������������������������������������././@LongLink���������������������������������������������������������������������������������������0000644�0000000�0000000�00000000160�00000000000�011600� L����������������������������������������������������������������������������������������������������ustar �root����������������������������root�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalClassReferenceRule_MultipleClassNamesTest.groovy�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/rule/generic/IllegalClassReferenceRule_MultipleClassNames0000644�0001750�0001750�00000002536�12041642702�033251� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2011 the original author or 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 org.codenarc.rule.generic import org.codenarc.rule.AbstractClassReferenceRuleTestCase import org.codenarc.rule.Rule /** * Tests for IllegalClassReferenceRule - checks for specifying a multiple, comma-separated class names for the classNames field * * @see IllegalClassReferenceRule_SingleClassNameTest * @see IllegalClassReferenceRule_WildcardsClassNamesTest * * @author Chris Mair */ class IllegalClassReferenceRule_MultipleClassNamesTest extends AbstractClassReferenceRuleTestCase { final String className = 'com.example.MyExampleClass' protected Rule createRule() { new IllegalClassReferenceRule(classNames:'org.example.OtherClass,com.example.MyExampleClass, UnrelatedClass') } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/��������������������������������������������������0000755�0001750�0001750�00000000000�12623571301�021417� 5����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/AbstractTextReportWriterTestCase.groovy�����������0000644�0001750�0001750�00000017330�12405332435�031330� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.report import org.codenarc.AnalysisContext import org.codenarc.results.DirectoryResults import org.codenarc.results.FileResults import org.codenarc.rule.StubRule import org.codenarc.rule.Violation import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import java.text.DateFormat import static org.codenarc.test.TestUtil.captureSystemOut import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining import static org.junit.Assert.assertEquals /** * Abstract superclass for TestReportWriter and subclass tests * * @author Chris Mair * @author Hamlet D'Arcy */ abstract class AbstractTextReportWriterTestCase extends AbstractTestCase { protected static final LINE1 = 11 protected static final LINE2 = 2 protected static final LINE3 = 333 protected static final SOURCE_LINE1 = 'if (count < 23 && index <= 99) {' protected static final SOURCE_LINE3 = 'throw new Exception() // Something bad happened' protected static final MESSAGE2 = 'bad stuff: !@#$%^&*()_+<>' protected static final MESSAGE3 = 'Other info' protected static final VIOLATION1 = new Violation(rule:new StubRule(name:'Rule1', priority:1), lineNumber:LINE1, sourceLine:SOURCE_LINE1) protected static final VIOLATION2 = new Violation(rule:new StubRule(name:'AnotherRule', priority:2), lineNumber:LINE2, message:MESSAGE2) protected static final VIOLATION3 = new Violation(rule:new StubRule(name:'BadStuff', priority:3), lineNumber:LINE3, sourceLine:SOURCE_LINE3, message:MESSAGE3 ) protected static final NEW_REPORT_FILE = 'target/NewTextReport.txt' protected static final TITLE = 'My Cool Project' protected static final SRC_DIR1 = 'c:/MyProject/src/main/groovy' protected static final SRC_DIR2 = 'c:/MyProject/src/test/groovy' protected static final VERSION_FILE = 'src/main/resources/codenarc-version.txt' protected static final VERSION = new File(VERSION_FILE).text protected static final TIMESTAMP_DATE = new Date(1262361072497) protected static final FORMATTED_TIMESTAMP = DateFormat.getDateTimeInstance().format(TIMESTAMP_DATE) protected reportWriter protected analysisContext protected results, srcMainDaoDirResults protected stringWriter //------------------------------------------------------------------------------------ // Abstract declarations //------------------------------------------------------------------------------------ protected abstract TextReportWriter createReportWriter() protected abstract String getReportTextMaxPriority() protected abstract String getReportText() //------------------------------------------------------------------------------------ // Tests //------------------------------------------------------------------------------------ @Test void testWriteReport_Writer() { reportWriter.writeReport(stringWriter, analysisContext, results) def reportText = stringWriter.toString() assertReportText(reportText, getReportText()) } @Test void testWriteReport_MaxPriority() { reportWriter.maxPriority = 1 reportWriter.writeReport(stringWriter, analysisContext, results) def reportText = stringWriter.toString() assertReportText(reportText, getReportTextMaxPriority()) } @Test void testWriteReport_WritesToDefaultReportFile() { reportWriter.writeReport(analysisContext, results) def reportFile = new File('CodeNarcReport.txt') def reportText = reportFile.text reportFile.delete() // comment out to keep report file around for easy inspection assertReportText(reportText, getReportText()) } @Test void testWriteReport_WritesToConfiguredReportFile() { reportWriter.outputFile = NEW_REPORT_FILE reportWriter.writeReport(analysisContext, results) def reportFile = new File(NEW_REPORT_FILE) def reportText = reportFile.text reportFile.delete() assertReportText(reportText, getReportText()) } @Test void testWriteReport_WritesToStandardOut() { reportWriter.writeToStandardOut = true def output = captureSystemOut { reportWriter.writeReport(analysisContext, results) } assertReportText(output, getReportText()) } @Test void testWriteReport_NullResults() { shouldFailWithMessageContaining('results') { reportWriter.writeReport(analysisContext, null) } } @Test void testWriteReport_NullAnalysisContext() { shouldFailWithMessageContaining('analysisContext') { reportWriter.writeReport(null, results) } } @Test void testDefaultOutputFile_CodeNarcReport() { assert reportWriter.defaultOutputFile == 'CodeNarcReport.txt' } @Test void testMaxPriority_DefaultsTo3() { assert reportWriter.maxPriority == 3 } //------------------------------------------------------------------------------------ // Setup and helper methods //------------------------------------------------------------------------------------ @Before void setUpAbstractTextReportWriterTestCase() { reportWriter = createReportWriter() reportWriter.getTimestamp = { TIMESTAMP_DATE } def srcMainDirResults = new DirectoryResults('src/main', 1) srcMainDaoDirResults = new DirectoryResults('src/main/dao', 2) def srcTestDirResults = new DirectoryResults('src/test', 3) def srcMainFileResults1 = new FileResults('src/main/MyAction.groovy', [VIOLATION1, VIOLATION3, VIOLATION3, VIOLATION1, VIOLATION2]) def fileResultsMainDao1 = new FileResults('src/main/dao/MyDao.groovy', [VIOLATION3]) def fileResultsMainDao2 = new FileResults('src/main/dao/MyOtherDao.groovy', [VIOLATION2, VIOLATION1]) srcMainDirResults.addChild(srcMainFileResults1) srcMainDirResults.addChild(srcMainDaoDirResults) srcMainDaoDirResults.addChild(fileResultsMainDao1) srcMainDaoDirResults.addChild(fileResultsMainDao2) results = new DirectoryResults() results.addChild(srcMainDirResults) results.addChild(srcTestDirResults) analysisContext = new AnalysisContext(sourceDirectories:[SRC_DIR1, SRC_DIR2]) stringWriter = new StringWriter() } @SuppressWarnings('JUnitStyleAssertions') protected void assertReportText(String actualText, String expectedText) { def actualLines = actualText.readLines() def expectedLines = expectedText.readLines() actualLines.eachWithIndex { line, index -> def lineNumber = "$index".padLeft(2) println "$lineNumber: $line" assertEquals("line=$line", expectedLines[index], line) } assertEquals(expectedLines.size(), actualLines.size()) } @SuppressWarnings('ConfusingMethodName') protected static String version() { return VERSION } protected static String formattedTimestamp() { return FORMATTED_TIMESTAMP } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/AbstractReportWriterTest.groovy�������������������0000644�0001750�0001750�00000023411�12144040134�027654� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2009 the original author or 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 org.codenarc.report import org.codenarc.AnalysisContext import org.codenarc.results.DirectoryResults import org.codenarc.results.Results import org.codenarc.rule.StubRule import org.codenarc.ruleset.ListRuleSet import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.captureSystemOut /** * Tests for AbstractReportWriter * * @author Chris Mair */ class AbstractReportWriterTest extends AbstractTestCase { private static final RESULTS = new DirectoryResults() private static final ANALYSIS_CONTEXT = new AnalysisContext() private static final DEFAULT_STRING = '?' private static final CUSTOM_FILENAME = 'abc.txt' private static final NEW_OUTPUT_DIR = 'tempdir' private static final CONTENTS = 'abc' private FakeAbstractReportWriter reportWriter @Test void testWriteReport_WritesToDefaultOutputFile_IfOutputFileIsNull() { def defaultOutputFile = FakeAbstractReportWriter.defaultOutputFile reportWriter.writeReport(ANALYSIS_CONTEXT, RESULTS) assertOutputFile(defaultOutputFile) } @Test void testWriteReport_WritesToOutputFile_IfOutputFileIsDefined() { reportWriter.outputFile = CUSTOM_FILENAME reportWriter.writeReport(ANALYSIS_CONTEXT, RESULTS) assertOutputFile(CUSTOM_FILENAME) } @Test void testWriteReport_CreatesOutputDirectoryIfItDoesNotExist() { def outputDir = new File(NEW_OUTPUT_DIR) outputDir.delete() assert !outputDir.exists() def filename = NEW_OUTPUT_DIR + '/' + CUSTOM_FILENAME reportWriter.outputFile = filename reportWriter.writeReport(ANALYSIS_CONTEXT, RESULTS) assertOutputFile(filename) outputDir.delete() } @Test void testWriteReport_WritesToStandardOut_IfWriteToStandardOutIsTrue_String() { reportWriter.outputFile = CUSTOM_FILENAME reportWriter.writeToStandardOut = 'true' def output = captureSystemOut { reportWriter.writeReport(ANALYSIS_CONTEXT, RESULTS) } assertFileDoesNotExist(CUSTOM_FILENAME) assert output == CONTENTS } @Test void testWriteReport_WritesToStandardOut_IfWriteToStandardOutIsTrue() { reportWriter.outputFile = CUSTOM_FILENAME reportWriter.writeToStandardOut = true def output = captureSystemOut { reportWriter.writeReport(ANALYSIS_CONTEXT, RESULTS) } assertFileDoesNotExist(CUSTOM_FILENAME) assert output == CONTENTS } @Test void testWriteReport_WritesToStandardOut_AndResetsSystemOut() { def originalSystemOut = System.out reportWriter.writeToStandardOut = true reportWriter.writeReport(ANALYSIS_CONTEXT, RESULTS) assert System.out == originalSystemOut } @Test void testWriteReport_WritesToOutputFile_IfWriteToStandardOutIsNotTrue() { reportWriter.outputFile = CUSTOM_FILENAME reportWriter.writeToStandardOut = 'false' reportWriter.writeReport(ANALYSIS_CONTEXT, RESULTS) assertOutputFile(CUSTOM_FILENAME) } @Test void testInitializeResourceBundle_CustomMessagesFileExists() { reportWriter.initializeResourceBundle() assert reportWriter.getResourceBundleString('htmlReport.titlePrefix', null) // in "codenarc-base-messages.properties" assert reportWriter.getResourceBundleString('abc', null) // in "codenarc-messages.properties" } @Test void testInitializeResourceBundle_CustomMessagesFileDoesNotExist() { reportWriter.customMessagesBundleName = 'DoesNotExist' reportWriter.initializeResourceBundle() assert reportWriter.getResourceBundleString('htmlReport.titlePrefix', null) // in "codenarc-base-messages.properties" assert reportWriter.getResourceBundleString('abc') == DEFAULT_STRING } @Test void testGetResourceBundleString() { reportWriter.initializeResourceBundle() assert reportWriter.getResourceBundleString('abc') == '123' } @Test void testGetResourceBundleString_ReturnsDefaultStringIfKeyNotFound() { reportWriter.initializeResourceBundle() assert reportWriter.getResourceBundleString('DoesNotExist') == DEFAULT_STRING } @Test void testGetDescriptionForRule_RuleDescriptionFoundInMessagesFile() { reportWriter.initializeResourceBundle() def rule = new StubRule(name:'MyRuleXX') assert reportWriter.getDescriptionForRule(rule) == 'My Rule XX' } @Test void testGetDescriptionForRule_DescriptionPropertySetOnRuleObject() { reportWriter.initializeResourceBundle() def rule = new StubRule(name:'MyRuleXX', description:'xyz') assert reportWriter.getDescriptionForRule(rule) == 'xyz' } @Test void testGetDescriptionForRule_DescriptionContainsSubstitutionParameters() { reportWriter.initializeResourceBundle() def rule = new StubRule(name: 'MyRuleXX', priority: 3, description: 'xyz.${rule.name}.${rule.priority}') assert reportWriter.getDescriptionForRule(rule) == 'xyz.MyRuleXX.3' } @Test void testGetDescriptionForRule_RuleDescriptionNotFoundInMessagesFile() { reportWriter.initializeResourceBundle() def rule = new StubRule(name:'Unknown') assert reportWriter.getDescriptionForRule(rule).startsWith('No description provided') } @Test void testGetHtmlDescriptionForRule_HtmlRuleDescriptionFoundInMessagesFile() { reportWriter.initializeResourceBundle() def rule = new StubRule(name:'MyRuleXX') assert reportWriter.getHtmlDescriptionForRule(rule) == 'HTML Rule XX' } @Test void testGetHtmlDescriptionForRule_OnlyRuleDescriptionFoundInMessagesFile() { reportWriter.initializeResourceBundle() def rule = new StubRule(name:'MyRuleYY') assert reportWriter.getHtmlDescriptionForRule(rule) == 'My Rule YY' } @Test void testGetHtmlDescriptionForRule_DescriptionPropertySetOnRuleObject() { reportWriter.initializeResourceBundle() def rule = new StubRule(name:'MyRuleXX', description:'xyz') assert reportWriter.getHtmlDescriptionForRule(rule) == 'xyz' } @Test void testGetHtmlDescriptionForRule_DescriptionContainsSubstitutionParameters() { reportWriter.initializeResourceBundle() def rule = new StubRule(name: 'MyRuleXX', priority: 3, description: 'xyz.${rule.name}.${rule.priority}') assert reportWriter.getHtmlDescriptionForRule(rule) == 'xyz.MyRuleXX.3' } @Test void testGetHtmlDescriptionForRule_NoRuleDescriptionNotFoundInMessagesFile() { reportWriter.initializeResourceBundle() def rule = new StubRule(name:'Unknown') assert reportWriter.getHtmlDescriptionForRule(rule).startsWith('No description provided') } @Test void testGetFormattedTimestamp() { def timestamp = new Date(1262361072497) reportWriter.getTimestamp = { timestamp } def expected = java.text.DateFormat.getDateTimeInstance().format(timestamp) assert reportWriter.getFormattedTimestamp() == expected } @Test void testGetSortedRules() { def ruleSet = new ListRuleSet([new StubRule(name:'BB'), new StubRule(name:'AA'), new StubRule(name:'DD'), new StubRule(name:'CC')]) def analysisContext = new AnalysisContext(ruleSet:ruleSet) def sorted = reportWriter.getSortedRules(analysisContext) log(sorted) assert sorted.name == ['AA', 'BB', 'CC', 'DD'] } @Test void testGetSortedRules_RemovesDisabledRules() { def ruleSet = new ListRuleSet([new StubRule(name:'BB', enabled:false), new StubRule(name:'AA'), new StubRule(name:'DD'), new StubRule(name:'CC', enabled:false)]) def analysisContext = new AnalysisContext(ruleSet:ruleSet) def sorted = reportWriter.getSortedRules(analysisContext) log(sorted) assert sorted.name == ['AA', 'DD'] } @Test void testGetCodeNarcVersion() { assert reportWriter.getCodeNarcVersion() == new File('src/main/resources/codenarc-version.txt').text } @Before void setUpAbstractReportWriterTest() { reportWriter = new FakeAbstractReportWriter() } private void assertOutputFile(String outputFile) { def file = new File(outputFile) assert file.exists(), "The output file [$outputFile] does not exist" def contents = file.text file.delete() assert contents == CONTENTS } private void assertFileDoesNotExist(String filename) { assert !new File(filename).exists() } } /** * Concrete subclass of AbstractReportWriter for testing */ class FakeAbstractReportWriter extends AbstractReportWriter { static defaultOutputFile = 'TestReportWriter.txt' String title @Override void writeReport(Writer writer, AnalysisContext analysisContext, Results results) { writer.write('abc') writer.flush() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/InlineXmlReportWriterTest.groovy������������������0000644�0001750�0001750�00000020741�12447632300�030023� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.report import org.codenarc.AnalysisContext import org.codenarc.results.DirectoryResults import org.codenarc.results.FileResults import org.codenarc.rule.Violation import org.codenarc.rule.basic.EmptyCatchBlockRule import org.codenarc.rule.imports.UnusedImportRule import org.codenarc.rule.unused.UnusedPrivateMethodRule import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import java.text.DateFormat import static org.junit.Assert.assertEquals /** * Tests for InlineXmlReportWriter. * * @author Robin Bramley * @author Hamlet D'Arcy */ class InlineXmlReportWriterTest extends AbstractTestCase { private static final LINE1 = 111 private static final LINE2 = 222 private static final LINE3 = 333 private static final SOURCE_LINE1 = 'if (count < 23 && index <= 99) {' private static final SOURCE_LINE3 = 'throw new Exception("cdata=<![CDATA[whatever]]>") // Some very long message 1234567890123456789012345678901234567890' private static final MESSAGE2 = 'bad stuff: !@#$%^&*()_+<>' private static final MESSAGE3 = 'Other info' private static final VIOLATION1 = new Violation(rule:new UnusedImportRule(), lineNumber:LINE1, sourceLine:SOURCE_LINE1) private static final VIOLATION2 = new Violation(rule:new UnusedPrivateMethodRule(), lineNumber:LINE2, message:MESSAGE2) private static final VIOLATION3 = new Violation(rule:new EmptyCatchBlockRule(), lineNumber:LINE3, sourceLine:SOURCE_LINE3, message:MESSAGE3 ) private static final TITLE = 'My Cool Project' private static final SRC_DIR1 = 'c:/MyProject/src/main/groovy' private static final SRC_DIR2 = 'c:/MyProject/src/test/groovy' private static final VERSION_FILE = 'src/main/resources/codenarc-version.txt' private static final VERSION = new File(VERSION_FILE).text private static final TIMESTAMP_DATE = new Date(1262361072497) private static final FORMATTED_TIMESTAMP = DateFormat.getDateTimeInstance().format(TIMESTAMP_DATE) private static final REPORT_XML = """<?xml version='1.0'?> <CodeNarc url='http://www.codenarc.org' version='${VERSION}'> <Report timestamp='${FORMATTED_TIMESTAMP}'/> <Project title='My Cool Project'> <SourceDirectory>c:/MyProject/src/main/groovy</SourceDirectory> <SourceDirectory>c:/MyProject/src/test/groovy</SourceDirectory> </Project> <PackageSummary totalFiles='6' filesWithViolations='3' priority1='0' priority2='5' priority3='2'> </PackageSummary> <Package path='src/main' totalFiles='3' filesWithViolations='3' priority1='0' priority2='5' priority3='2'> <File name='MyAction.groovy'> <Violation ruleName='UnusedImport' priority='3' lineNumber='111'> <SourceLine><![CDATA[if (count < 23 && index <= 99) {]]></SourceLine> <Description><![CDATA[Imports for a class that is never referenced within the source file is unnecessary.]]></Description> </Violation> <Violation ruleName='EmptyCatchBlock' priority='2' lineNumber='333'> <SourceLine><![CDATA[throw new Exception("cdata=<![CDATA[whatever]]>") // Some very long message 1234567890123456789012345678901234567890]]></SourceLine> <Message><![CDATA[Other info]]></Message> <Description><![CDATA[In most cases, exceptions should not be caught and ignored (swallowed).]]></Description> </Violation> <Violation ruleName='EmptyCatchBlock' priority='2' lineNumber='333'> <SourceLine><![CDATA[throw new Exception("cdata=<![CDATA[whatever]]>") // Some very long message 1234567890123456789012345678901234567890]]></SourceLine> <Message><![CDATA[Other info]]></Message> <Description><![CDATA[In most cases, exceptions should not be caught and ignored (swallowed).]]></Description> </Violation> <Violation ruleName='UnusedImport' priority='3' lineNumber='111'> <SourceLine><![CDATA[if (count < 23 && index <= 99) {]]></SourceLine> <Description><![CDATA[Imports for a class that is never referenced within the source file is unnecessary.]]></Description> </Violation> <Violation ruleName='UnusedPrivateMethod' priority='2' lineNumber='222'> <Message><![CDATA[bad stuff: !@#\$%^&*()_+<>]]></Message> <Description><![CDATA[Checks for private methods that are not referenced within the same class.]]></Description> </Violation> </File> </Package> <Package path='src/main/dao' totalFiles='2' filesWithViolations='2' priority1='0' priority2='2' priority3='0'> <File name='MyDao.groovy'> <Violation ruleName='EmptyCatchBlock' priority='2' lineNumber='333'> <SourceLine><![CDATA[throw new Exception("cdata=<![CDATA[whatever]]>") // Some very long message 1234567890123456789012345678901234567890]]></SourceLine> <Message><![CDATA[Other info]]></Message> <Description><![CDATA[In most cases, exceptions should not be caught and ignored (swallowed).]]></Description> </Violation> </File> <File name='MyOtherDao.groovy'> <Violation ruleName='UnusedPrivateMethod' priority='2' lineNumber='222'> <Message><![CDATA[bad stuff: !@#\$%^&*()_+<>]]></Message> <Description><![CDATA[Checks for private methods that are not referenced within the same class.]]></Description> </Violation> </File> </Package> <Package path='src/test' totalFiles='3' filesWithViolations='0' priority1='0' priority2='0' priority3='0'> </Package> </CodeNarc> """ private reportWriter private analysisContext private results, srcMainDaoDirResults private ruleSet private stringWriter @Test void testWriteReport_Writer() { reportWriter.writeReport(stringWriter, analysisContext, results) def xmlAsString = stringWriter.toString() assertXml(xmlAsString) } @Before void setUpInlineXmlReportWriterTest() { reportWriter = new InlineXmlReportWriter(title:TITLE) reportWriter.getTimestamp = { TIMESTAMP_DATE } def srcMainDirResults = new DirectoryResults('src/main', 1) srcMainDaoDirResults = new DirectoryResults('src/main/dao', 2) def srcTestDirResults = new DirectoryResults('src/test', 3) def srcMainFileResults1 = new FileResults('src/main/MyAction.groovy', [VIOLATION1, VIOLATION3, VIOLATION3, VIOLATION1, VIOLATION2]) def fileResultsMainDao1 = new FileResults('src/main/dao/MyDao.groovy', [VIOLATION3]) def fileResultsMainDao2 = new FileResults('src/main/dao/MyOtherDao.groovy', [VIOLATION2]) srcMainDirResults.addChild(srcMainFileResults1) srcMainDirResults.addChild(srcMainDaoDirResults) srcMainDaoDirResults.addChild(fileResultsMainDao1) srcMainDaoDirResults.addChild(fileResultsMainDao2) results = new DirectoryResults() results.addChild(srcMainDirResults) results.addChild(srcTestDirResults) analysisContext = new AnalysisContext(sourceDirectories:[SRC_DIR1, SRC_DIR2], ruleSet:ruleSet) stringWriter = new StringWriter() } @SuppressWarnings('JUnitStyleAssertions') private void assertXml(String actualXml) { log(actualXml) assertEquals(normalizeXml(REPORT_XML), normalizeXml(actualXml)) } private String normalizeXml(String xml) { xml.replaceAll(/\>\s*\</, '><').trim() } } �������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/IdeTextReportWriterTest.groovy��������������������0000644�0001750�0001750�00000005557�12445625631�027511� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.report /** * Tests for IdeTestReportWriter * * @author Chris Mair */ class IdeTextReportWriterTest extends AbstractTextReportWriterTestCase { private static final REPORT_TEXT = """ CodeNarc Report: My Cool Project - ${formattedTimestamp()} Summary: TotalFiles=6 FilesWithViolations=3 P1=3 P2=2 P3=3 File: src/main/MyAction.groovy Violation: Rule=Rule1 P=1 Loc=.(MyAction.groovy:11) Src=[if (count < 23 && index <= 99) {] Violation: Rule=Rule1 P=1 Loc=.(MyAction.groovy:11) Src=[if (count < 23 && index <= 99) {] Violation: Rule=AnotherRule P=2 Loc=.(MyAction.groovy:2) Msg=[bad stuff: !@#\$%^&*()_+<>] Violation: Rule=BadStuff P=3 Loc=.(MyAction.groovy:333) Msg=[Other info] Src=[throw new Exception() // Something bad happened] Violation: Rule=BadStuff P=3 Loc=.(MyAction.groovy:333) Msg=[Other info] Src=[throw new Exception() // Something bad happened] File: src/main/dao/MyDao.groovy Violation: Rule=BadStuff P=3 Loc=.(MyDao.groovy:333) Msg=[Other info] Src=[throw new Exception() // Something bad happened] File: src/main/dao/MyOtherDao.groovy Violation: Rule=Rule1 P=1 Loc=.(MyOtherDao.groovy:11) Src=[if (count < 23 && index <= 99) {] Violation: Rule=AnotherRule P=2 Loc=.(MyOtherDao.groovy:2) Msg=[bad stuff: !@#\$%^&*()_+<>] [CodeNarc (http://www.codenarc.org) v${version()}] """.trim() private static final REPORT_TEXT_MAX_PRIORITY = """ CodeNarc Report: My Cool Project - ${formattedTimestamp()} Summary: TotalFiles=6 FilesWithViolations=2 P1=3 File: src/main/MyAction.groovy Violation: Rule=Rule1 P=1 Loc=.(MyAction.groovy:11) Src=[if (count < 23 && index <= 99) {] Violation: Rule=Rule1 P=1 Loc=.(MyAction.groovy:11) Src=[if (count < 23 && index <= 99) {] File: src/main/dao/MyOtherDao.groovy Violation: Rule=Rule1 P=1 Loc=.(MyOtherDao.groovy:11) Src=[if (count < 23 && index <= 99) {] [CodeNarc (http://www.codenarc.org) v${version()}] """.trim() protected TextReportWriter createReportWriter() { return new IdeTextReportWriter(title:TITLE) } protected String getReportTextMaxPriority() { return REPORT_TEXT_MAX_PRIORITY } protected String getReportText() { return REPORT_TEXT } } �������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/TextReportWriterTest.groovy�����������������������0000644�0001750�0001750�00000005267�12405305552�027056� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.report /** * Tests for TestReportWriter * * @author Chris Mair * @author Hamlet D'Arcy */ class TextReportWriterTest extends AbstractTextReportWriterTestCase { private static final REPORT_TEXT = """ CodeNarc Report: My Cool Project - ${formattedTimestamp()} Summary: TotalFiles=6 FilesWithViolations=3 P1=3 P2=2 P3=3 File: src/main/MyAction.groovy Violation: Rule=Rule1 P=1 Line=11 Src=[if (count < 23 && index <= 99) {] Violation: Rule=Rule1 P=1 Line=11 Src=[if (count < 23 && index <= 99) {] Violation: Rule=AnotherRule P=2 Line=2 Msg=[bad stuff: !@#\$%^&*()_+<>] Violation: Rule=BadStuff P=3 Line=333 Msg=[Other info] Src=[throw new Exception() // Something bad happened] Violation: Rule=BadStuff P=3 Line=333 Msg=[Other info] Src=[throw new Exception() // Something bad happened] File: src/main/dao/MyDao.groovy Violation: Rule=BadStuff P=3 Line=333 Msg=[Other info] Src=[throw new Exception() // Something bad happened] File: src/main/dao/MyOtherDao.groovy Violation: Rule=Rule1 P=1 Line=11 Src=[if (count < 23 && index <= 99) {] Violation: Rule=AnotherRule P=2 Line=2 Msg=[bad stuff: !@#\$%^&*()_+<>] [CodeNarc (http://www.codenarc.org) v${version()}] """.trim() private static final REPORT_TEXT_MAX_PRIORITY = """ CodeNarc Report: My Cool Project - ${formattedTimestamp()} Summary: TotalFiles=6 FilesWithViolations=2 P1=3 File: src/main/MyAction.groovy Violation: Rule=Rule1 P=1 Line=11 Src=[if (count < 23 && index <= 99) {] Violation: Rule=Rule1 P=1 Line=11 Src=[if (count < 23 && index <= 99) {] File: src/main/dao/MyOtherDao.groovy Violation: Rule=Rule1 P=1 Line=11 Src=[if (count < 23 && index <= 99) {] [CodeNarc (http://www.codenarc.org) v${version()}] """.trim() protected TextReportWriter createReportWriter() { return new TextReportWriter(title:TITLE) } protected String getReportTextMaxPriority() { return REPORT_TEXT_MAX_PRIORITY } protected String getReportText() { return REPORT_TEXT } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/ReportWriterFactoryTest.groovy��������������������0000644�0001750�0001750�00000010371�12415111370�027523� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2010 the original author or 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 org.codenarc.report import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for ReportWriterFactory * * @author Chris Mair */ class ReportWriterFactoryTest extends AbstractTestCase { private static final TITLE = 'Custom title' private static final OUTPUT_FILE = 'report/CustomReport.data' private reportWriterFactory = new ReportWriterFactory() @Test void testGetReportWriter_Html() { assert reportWriterFactory.getReportWriter('html').class == HtmlReportWriter } @Test void testGetReportWriter_Xml() { assert reportWriterFactory.getReportWriter('xml').class == XmlReportWriter } @Test void testGetReportWriter_InlineXml() { assert reportWriterFactory.getReportWriter('inlineXml').class == InlineXmlReportWriter } @Test void testGetReportWriter_Text() { assert reportWriterFactory.getReportWriter('text').class == TextReportWriter } @Test void testGetReportWriter_Console() { def reportWriter = reportWriterFactory.getReportWriter('console') assert reportWriter.class == TextReportWriter assert reportWriter.writeToStandardOut } @Test void testGetReportWriter_Ide() { def reportWriter = reportWriterFactory.getReportWriter('ide') assert reportWriter.class == IdeTextReportWriter assert reportWriter.writeToStandardOut } @Test void testGetReportWriter_SpecifyClassName() { assert reportWriterFactory.getReportWriter('org.codenarc.report.HtmlReportWriter').class == HtmlReportWriter } @Test void testGetReportWriter_ThrowsExceptionForClassThatIsNotAReportWriter() { shouldFailWithMessageContaining('org.codenarc.CodeNarcRunner') { reportWriterFactory.getReportWriter('org.codenarc.CodeNarcRunner') } } @Test void testGetReportWriter_ThrowsExceptionForInvalidType() { shouldFailWithMessageContaining('xxx') { reportWriterFactory.getReportWriter('xxx') } } @Test void testGetReportWriter_ThrowsExceptionForNullType() { shouldFailWithMessageContaining('type') { reportWriterFactory.getReportWriter(null) } } @Test void testGetReportWriter_Html_WithOptions() { def reportWriter = reportWriterFactory.getReportWriter('html', [title:TITLE, maxPriority:'4']) assert reportWriter.class == HtmlReportWriter assert reportWriter.title == TITLE assert reportWriter.maxPriority == 4 } @Test void testGetReportWriter_Xml_WithOptions() { def reportWriter = reportWriterFactory.getReportWriter('xml', [outputFile:OUTPUT_FILE]) assert reportWriter.class == XmlReportWriter assert reportWriter.outputFile == OUTPUT_FILE } @Test void testGetReportWriter_Text_WithOptions() { def reportWriter = reportWriterFactory.getReportWriter('text', [outputFile:OUTPUT_FILE, maxPriority:'2']) assert reportWriter.class == TextReportWriter assert reportWriter.outputFile == OUTPUT_FILE assert reportWriter.maxPriority == 2 } @Test void testGetReportWriter_WithOptions_ThrowsExceptionForInvalidType() { shouldFailWithMessageContaining('xxx') { reportWriterFactory.getReportWriter('xxx', [title:TITLE]) } } @Test void testGetReportWriter_WithOptions_ThrowsExceptionForInvalidOption() { shouldFailWithMessageContaining('badOption') { reportWriterFactory.getReportWriter('html', [badOption:'abc']) } } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/XmlReportWriterTest.groovy������������������������0000644�0001750�0001750�00000027102�12451100460�026652� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2014 the original author or 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 org.codenarc.report import org.codenarc.AnalysisContext import org.codenarc.results.DirectoryResults import org.codenarc.results.FileResults import org.codenarc.rule.StubRule import org.codenarc.rule.Violation import org.codenarc.rule.imports.DuplicateImportRule import org.codenarc.rule.unnecessary.UnnecessaryBooleanInstantiationRule import org.codenarc.ruleset.ListRuleSet import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import java.text.DateFormat import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for XmlReportWriter * * @author Chris Mair * @author Hamlet D'Arcy */ class XmlReportWriterTest extends AbstractTestCase { private static final LINE1 = 111 private static final LINE2 = 222 private static final LINE3 = 333 private static final SOURCE_LINE1 = "if (count < 23 && index <= 99 && name.contains('\u0000')) {" private static final SOURCE_LINE3 = 'throw new Exception("cdata=<![CDATA[whatever]]>") // Some very long message 1234567890123456789012345678901234567890' private static final MESSAGE2 = 'bad stuff: !@#$%^&*()_+<>' private static final MESSAGE3 = 'Other info' private static final VIOLATION1 = new Violation(rule:new StubRule(name:'RULE1', priority:1), lineNumber:LINE1, sourceLine:SOURCE_LINE1) private static final VIOLATION2 = new Violation(rule:new StubRule(name:'RULE2', priority:2), lineNumber:LINE2, message:MESSAGE2) private static final VIOLATION3 = new Violation(rule:new StubRule(name:'RULE3', priority:3), lineNumber:LINE3, sourceLine:SOURCE_LINE3, message:MESSAGE3 ) private static final NEW_REPORT_FILE = 'target/NewXmlReport.xml' private static final TITLE = 'My Cool Project' private static final SRC_DIR1 = 'c:/MyProject/src/main/groovy' private static final SRC_DIR2 = 'c:/MyProject/src/test/groovy' private static final VERSION_FILE = 'src/main/resources/codenarc-version.txt' private static final VERSION = new File(VERSION_FILE).text private static final TIMESTAMP_DATE = new Date(1262361072497) private static final FORMATTED_TIMESTAMP = DateFormat.getDateTimeInstance().format(TIMESTAMP_DATE) @SuppressWarnings('LineLength') private static final REPORT_XML = """<?xml version='1.0'?> <CodeNarc url='http://www.codenarc.org' version='${VERSION}'> <Report timestamp='${FORMATTED_TIMESTAMP}'/> <Project title='My Cool Project'> <SourceDirectory>c:/MyProject/src/main/groovy</SourceDirectory> <SourceDirectory>c:/MyProject/src/test/groovy</SourceDirectory> </Project> <PackageSummary totalFiles='6' filesWithViolations='3' priority1='2' priority2='2' priority3='3'> </PackageSummary> <Package path='src/main' totalFiles='3' filesWithViolations='3' priority1='2' priority2='2' priority3='3'> <File name='MyAction.groovy'> <Violation ruleName='RULE1' priority='1' lineNumber='111'> <SourceLine><![CDATA[if (count < 23 && index <= 99 && name.contains('')) {]]></SourceLine> </Violation> <Violation ruleName='RULE3' priority='3' lineNumber='333'> <SourceLine><![CDATA[throw new Exception("cdata=<![CDATA[whatever]]>") // Some very long message 1234567890123456789012345678901234567890]]></SourceLine> <Message><![CDATA[Other info]]></Message> </Violation> <Violation ruleName='RULE3' priority='3' lineNumber='333'> <SourceLine><![CDATA[throw new Exception("cdata=<![CDATA[whatever]]>") // Some very long message 1234567890123456789012345678901234567890]]></SourceLine> <Message><![CDATA[Other info]]></Message> </Violation> <Violation ruleName='RULE1' priority='1' lineNumber='111'> <SourceLine><![CDATA[if (count < 23 && index <= 99 && name.contains('')) {]]></SourceLine></Violation> <Violation ruleName='RULE2' priority='2' lineNumber='222'> <Message><![CDATA[bad stuff: !@#\$%^&*()_+<>]]></Message> </Violation> </File> </Package> <Package path='src/main/dao' totalFiles='2' filesWithViolations='2' priority1='0' priority2='1' priority3='1'> <File name='MyDao.groovy'> <Violation ruleName='RULE3' priority='3' lineNumber='333'> <SourceLine><![CDATA[throw new Exception("cdata=<![CDATA[whatever]]>") // Some very long message 1234567890123456789012345678901234567890]]></SourceLine> <Message><![CDATA[Other info]]></Message> </Violation> </File> <File name='MyOtherDao.groovy'> <Violation ruleName='RULE2' priority='2' lineNumber='222'> <Message><![CDATA[bad stuff: !@#\$%^&*()_+<>]]></Message> </Violation> </File> </Package> <Package path='src/test' totalFiles='3' filesWithViolations='0' priority1='0' priority2='0' priority3='0'> </Package> <Rules> <Rule name='DuplicateImport'> <Description><![CDATA[Custom: Duplicate imports]]></Description> </Rule> <Rule name='UnnecessaryBooleanInstantiation'> <Description><![CDATA[Use Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).]]></Description> </Rule> </Rules> </CodeNarc> """ private reportWriter private analysisContext private results, srcMainDaoDirResults private ruleSet private stringWriter @Test void testWriteReport_Writer() { reportWriter.writeReport(stringWriter, analysisContext, results) def xmlAsString = stringWriter.toString() assertXml(xmlAsString) } @Test void testWriteReport_Writer_ProperPackageSummaryForPackageWithEmptyRelativePath() { final XML = """ <PackageSummary totalFiles='2' filesWithViolations='1' priority1='0' priority2='0' priority3='1'> </PackageSummary> <Package path='' totalFiles='2' filesWithViolations='1' priority1='0' priority2='0' priority3='1'> """ def dirResults = new DirectoryResults('', 2) dirResults.addChild(new FileResults('src/main/dao/MyDao.groovy', [VIOLATION3])) def rootResults = new DirectoryResults() rootResults.addChild(dirResults) reportWriter.writeReport(stringWriter, analysisContext, rootResults) assertContainsXml(stringWriter.toString(), XML) } @Test void testWriteReport_WritesToDefaultReportFile() { reportWriter.writeReport(analysisContext, results) def reportFile = new File('CodeNarcXmlReport.xml') def xmlAsString = reportFile.text reportFile.delete() // comment out to keep report file around for easy inspection assertXml(xmlAsString) } @Test void testWriteReport_WritesToConfiguredReportFile() { reportWriter.outputFile = NEW_REPORT_FILE reportWriter.writeReport(analysisContext, results) def reportFile = new File(NEW_REPORT_FILE) def xmlAsString = reportFile.text reportFile.delete() assertXml(xmlAsString) } @Test void testWriteReport_NullResults() { shouldFailWithMessageContaining('results') { reportWriter.writeReport(analysisContext, null) } } @Test void testWriteReport_NullAnalysisContext() { shouldFailWithMessageContaining('analysisContext') { reportWriter.writeReport(null, results) } } @Test void testDefaultOutputFile_CodeNarcXmlReport() { assert reportWriter.defaultOutputFile == 'CodeNarcXmlReport.xml' } //-------------------------------------------------------------------------- // Setup and helper methods //-------------------------------------------------------------------------- @Test void testRemoveIllegalCharacters() { assert reportWriter.removeIllegalCharacters('\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008') == '' assert reportWriter.removeIllegalCharacters('\uD800') == '' // Valid chars assert reportWriter.removeIllegalCharacters('') == '' assert reportWriter.removeIllegalCharacters('01234567890 ABC abc') == '01234567890 ABC abc' assert reportWriter.removeIllegalCharacters('!@#$%^&*()-_=+[]{};\'",./<>?') == '!@#$%^&*()-_=+[]{};\'",./<>?' assert reportWriter.removeIllegalCharacters('\u0009') == '\u0009' assert reportWriter.removeIllegalCharacters('\t\n\r') == '\t\n\r' assert reportWriter.removeIllegalCharacters('\uE000') == '\uE000' } @Before void setUpXmlReportWriterTest() { reportWriter = new XmlReportWriter(title:TITLE) reportWriter.getTimestamp = { TIMESTAMP_DATE } def srcMainDirResults = new DirectoryResults('src/main', 1) srcMainDaoDirResults = new DirectoryResults('src/main/dao', 2) def srcTestDirResults = new DirectoryResults('src/test', 3) def srcMainFileResults1 = new FileResults('src/main/MyAction.groovy', [VIOLATION1, VIOLATION3, VIOLATION3, VIOLATION1, VIOLATION2]) def fileResultsMainDao1 = new FileResults('src/main/dao/MyDao.groovy', [VIOLATION3]) def fileResultsMainDao2 = new FileResults('src/main/dao/MyOtherDao.groovy', [VIOLATION2]) srcMainDirResults.addChild(srcMainFileResults1) srcMainDirResults.addChild(srcMainDaoDirResults) srcMainDaoDirResults.addChild(fileResultsMainDao1) srcMainDaoDirResults.addChild(fileResultsMainDao2) results = new DirectoryResults() results.addChild(srcMainDirResults) results.addChild(srcTestDirResults) ruleSet = new ListRuleSet([ // NOT in alphabetical order new DuplicateImportRule(description:'Custom: Duplicate imports'), new UnnecessaryBooleanInstantiationRule() ]) analysisContext = new AnalysisContext(sourceDirectories:[SRC_DIR1, SRC_DIR2], ruleSet:ruleSet) stringWriter = new StringWriter() } private void assertXml(String actualXml) { log(actualXml) assert normalizeXml(REPORT_XML) == normalizeXml(actualXml) // Verify that it is valid XML new XmlSlurper().parseText(actualXml) } private void assertContainsXml(String actualXml, String expectedPartialXml) { log(actualXml) assert normalizeXml(actualXml).contains(normalizeXml(expectedPartialXml)) } private String normalizeXml(String xml) { xml.replaceAll(/\>\s*\</, '><').trim() } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������CodeNarc-0.23/src/test/groovy/org/codenarc/report/HtmlReportWriterTest.groovy�����������������������0000644�0001750�0001750�00000202770�12450012603�027024� 0����������������������������������������������������������������������������������������������������ustar �ebourg��������������������������ebourg�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 2013 the original author or 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 org.codenarc.report import static org.junit.Assert.assertEquals import static org.codenarc.test.TestUtil.assertContainsAllInOrder import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining import org.codenarc.AnalysisContext import org.codenarc.results.DirectoryResults import org.codenarc.results.FileResults import org.codenarc.rule.Rule import org.codenarc.rule.StubRule import org.codenarc.rule.Violation import org.codenarc.rule.basic.ReturnFromFinallyBlockRule import org.codenarc.rule.basic.ThrowExceptionFromFinallyBlockRule import org.codenarc.rule.imports.DuplicateImportRule import org.codenarc.rule.unnecessary.UnnecessaryBooleanInstantiationRule import org.codenarc.rule.unnecessary.UnnecessaryStringInstantiationRule import org.codenarc.ruleset.ListRuleSet import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test /** * Tests for HtmlReportWriter * * @author Chris Mair */ @SuppressWarnings('LineLength') class HtmlReportWriterTest extends AbstractTestCase { private static final LONG_LINE = 'throw new Exception() // Some very long message 1234567890123456789012345678901234567890' private static final MESSAGE = 'bad stuff' private static final LINE1 = 111 private static final LINE2 = 222 private static final LINE3 = 333 private static final VIOLATION1 = new Violation(rule:new StubRule(name:'RULE1', priority:1), lineNumber:LINE1, sourceLine:'if (file) {') private static final VIOLATION2 = new Violation(rule:new StubRule(name:'RULE2', priority:2), lineNumber:LINE2, message:MESSAGE) private static final VIOLATION3 = new Violation(rule:new StubRule(name:'RULE3', priority:3), lineNumber:LINE3, sourceLine:LONG_LINE, message: 'Other info') private static final VIOLATION4 = new Violation(rule:new StubRule(name:'RULE4', priority:4), lineNumber:LINE1, sourceLine:'if (file) {') private static final NEW_REPORT_FILE = new File('target/NewReport.html').absolutePath private static final TITLE = 'My Cool Project' private reportWriter private analysisContext private results private dirResultsMain private ruleSet private String cssFileContents @Test void testDefaultProperties() { assert new HtmlReportWriter().includeSummaryByPackage assert new HtmlReportWriter().maxPriority == 3 } @Test void testDefaultOutputFile() { assert new HtmlReportWriter().defaultOutputFile == HtmlReportWriter.DEFAULT_OUTPUT_FILE } @Test void testWriteReport_DoesNotIncludeRuleDescriptionsForDisabledRules() { ruleSet = new ListRuleSet([ new StubRule(name:'MyRuleXX', enabled:false), new StubRule(name:'MyRuleYY'), new StubRule(name:'MyRuleZZ', enabled:false)]) analysisContext.ruleSet = ruleSet def reportText = getReportText() assert !reportText.contains('MyRuleXX') assert !reportText.contains('MyRuleZZ') } @Test void testWriteReport_IncludesRuleThatDoesNotSupportGetDescription() { analysisContext.ruleSet = new ListRuleSet([ [getName:{ 'RuleABC' }, getPriority: { 2 } ] as Rule]) assertContainsAllInOrder(getReportText(), ['RuleABC', 'No description']) } @Test void testWriteReport_NullResults() { shouldFailWithMessageContaining('results') { reportWriter.writeReport(analysisContext, null) } } @Test void testWriteReport_NullAnalysisContext() { shouldFailWithMessageContaining('analysisContext') { reportWriter.writeReport(null, results) } } @Test void testIsDirectoryContainingFilesWithViolations_FileResults() { def results = new FileResults('', []) assert !reportWriter.isDirectoryContainingFilesWithViolations(results) results = new FileResults('', [VIOLATION1]) assert !reportWriter.isDirectoryContainingFilesWithViolations(results) } @Test void testIsDirectoryContainingFilesWithViolations_DirectoryResults() { def results = new DirectoryResults('') assert !reportWriter.isDirectoryContainingFilesWithViolations(results) results.addChild(new FileResults('', [])) assert !reportWriter.isDirectoryContainingFilesWithViolations(results), 'child with no violations' def child = new DirectoryResults('') child.addChild(new FileResults('', [VIOLATION1])) results.addChild(child) assert !reportWriter.isDirectoryContainingFilesWithViolations(results), 'grandchild with violations' results.addChild(new FileResults('', [VIOLATION2])) assert reportWriter.isDirectoryContainingFilesWithViolations(results) reportWriter.maxPriority = 1 assert !reportWriter.isDirectoryContainingFilesWithViolations(results) reportWriter.maxPriority = 2 assert reportWriter.isDirectoryContainingFilesWithViolations(results) reportWriter.maxPriority = 1 results.addChild(new FileResults('', [VIOLATION1])) assert reportWriter.isDirectoryContainingFilesWithViolations(results) } @Test void testIsDirectoryContainingFiles() { def results = new FileResults('', []) assert !reportWriter.isDirectoryContainingFiles(results) results = new DirectoryResults('') assert !reportWriter.isDirectoryContainingFiles(results) results.numberOfFilesInThisDirectory = 2 assert reportWriter.isDirectoryContainingFiles(results) } @Test void testFormatSourceLine() { assert reportWriter.formatSourceLine('') == null assert reportWriter.formatSourceLine('abc') == 'abc' assert reportWriter.formatSourceLine('abcdef' * 20) == 'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefab..abcdefabcdef' assert reportWriter.formatSourceLine('abc', 2) == 'abc' assert reportWriter.formatSourceLine('abcdef' * 20, 2) == 'cdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd..abcdefabcdef' } @Test void testMaxPriority_DefaultsTo3() { assert reportWriter.maxPriority == 3 } @Test void testWriteReport() { final EXPECTED = """ <html><head><title>CodeNarc Report

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages103323
src/main11212
src/main/code21--1
src/main/test3111-
src/main/test/noviolations4----

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.code

➥ src/main/MyAction2.groovy

Rule NamePriorityLine #Source Line / Message
RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

Rule Descriptions

#Rule NameDescription
1DuplicateImportDuplicate import statements are unnecessary.
2ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
3ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
4UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
5UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
""" reportWriter.writeReport(analysisContext, results) assertReportFileContents(NEW_REPORT_FILE, EXPECTED) } @Test void testWriteReport_IncludeSummaryByPackage_False() { //CodeNarc Report

CodeNarc Report

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.code

➥ src/main/MyAction2.groovy

Rule NamePriorityLine #Source Line / Message
RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

Rule Descriptions

#Rule NameDescription
1DuplicateImportDuplicate import statements are unnecessary.
2ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
3ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
4UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
5UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
final EXPECTED = """ CodeNarc Report

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages103323

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.code

➥ src/main/MyAction2.groovy

Rule NamePriorityLine #Source Line / Message
RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

Rule Descriptions

#Rule NameDescription
1DuplicateImportDuplicate import statements are unnecessary.
2ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
3ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
4UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
5UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
""" reportWriter.includeSummaryByPackage = false reportWriter.writeReport(analysisContext, results) assertReportFileContents(NEW_REPORT_FILE, EXPECTED) } @Test void testWriteReport_SetTitle() { final EXPECTED = """ CodeNarc Report: $TITLE

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages103323
src/main11212
src/main/code21--1
src/main/test3111-
src/main/test/noviolations4----

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.code

➥ src/main/MyAction2.groovy

Rule NamePriorityLine #Source Line / Message
RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

Rule Descriptions

#Rule NameDescription
1DuplicateImportDuplicate import statements are unnecessary.
2ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
3ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
4UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
5UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
""" reportWriter.title = TITLE reportWriter.writeReport(analysisContext, results) assertReportFileContents(NEW_REPORT_FILE, EXPECTED) } @Test void testWriteReport_MaxPriority1() { final EXPECTED = """ CodeNarc Report

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1
All Packages1023
src/main112
src/main/code2--
src/main/test311
src/main/test/noviolations4--

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

Rule Descriptions

#Rule NameDescription
1DuplicateImportDuplicate import statements are unnecessary.
2ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
3ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
4UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
5UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
""" reportWriter.maxPriority = 1 assertReportContents(EXPECTED) } @Test void testWriteReport_Priority4() { final EXPECTED = """ CodeNarc Report

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3Priority 4
All Packages1043231
src/main122121
src/main/code21--1-
src/main/test3111--
src/main/test/noviolations4-----

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.code

➥ src/main/MyAction2.groovy

Rule NamePriorityLine #Source Line / Message
RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

➥ MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE44111

[SRC]if (file) {

Rule Descriptions

#Rule NameDescription
1DuplicateImportDuplicate import statements are unnecessary.
2ReturnFromFinallyBlockReturning from a finally block is confusing and can hide the original exception.
3ThrowExceptionFromFinallyBlockThrowing an exception from a finally block is confusing and can hide the original exception.
4UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
5UnnecessaryStringInstantiationUse a String literal (e.g., "...") instead of calling the corresponding String constructor (new String("..")) directly.
""" def fileResults4 = new FileResults('src/main/MyActionTest.groovy', [VIOLATION4]) dirResultsMain.addChild(fileResults4) reportWriter.maxPriority = 4 assertReportContents(EXPECTED) } @Test void testWriteReport_NoDescriptionsForRuleIds() { final EXPECTED = """ CodeNarc Report

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages103323
src/main11212
src/main/code21--1
src/main/test3111-
src/main/test/noviolations4----

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.code

➥ src/main/MyAction2.groovy

Rule NamePriorityLine #Source Line / Message
RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

Rule Descriptions

#Rule NameDescription
1MyRuleXXNo description provided for rule named [MyRuleXX]
2MyRuleYYNo description provided for rule named [MyRuleYY]
""" ruleSet = new ListRuleSet([new StubRule(name:'MyRuleXX'), new StubRule(name:'MyRuleYY')]) reportWriter.customMessagesBundleName = 'DoesNotExist' analysisContext.ruleSet = ruleSet assertReportContents(EXPECTED) } @Test void testWriteReport_RuleDescriptionsProvidedInCodeNarcMessagesFile() { final EXPECTED = """ CodeNarc Report

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages103323
src/main11212
src/main/code21--1
src/main/test3111-
src/main/test/noviolations4----

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.code

➥ src/main/MyAction2.groovy

Rule NamePriorityLine #Source Line / Message
RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

Rule Descriptions

#Rule NameDescription
1MyRuleXXHTML Rule XX
2MyRuleYYMy Rule YY
3UnnecessaryBooleanInstantiationUse Boolean.valueOf() for variable values or Boolean.TRUE and Boolean.FALSE for constant values instead of calling the Boolean() constructor directly or calling Boolean.valueOf(true) or Boolean.valueOf(false).
""" def biRule = new UnnecessaryBooleanInstantiationRule() ruleSet = new ListRuleSet([new StubRule(name:'MyRuleXX'), new StubRule(name:'MyRuleYY'), biRule]) analysisContext.ruleSet = ruleSet assertReportContents(EXPECTED) } @Test void testWriteReport_RuleDescriptionsSetDirectlyOnTheRule() { final EXPECTED = """ CodeNarc Report

CodeNarc Report

Summary

PackageTotal FilesFiles with ViolationsPriority 1Priority 2Priority 3
All Packages103323
src/main11212
src/main/code21--1
src/main/test3111-
src/main/test/noviolations4----

Package: src.main

➥ MyAction.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.code

➥ src/main/MyAction2.groovy

Rule NamePriorityLine #Source Line / Message
RULE33333

[SRC]throw new Exception() // Some very long message 12345678..901234567890

[MSG]Other info

Package: src.main.test

➥ src/main/MyActionTest.groovy

Rule NamePriorityLine #Source Line / Message
RULE11111

[SRC]if (file) {

RULE22222

[MSG]bad stuff

Rule Descriptions

#Rule NameDescription
1MyRuleXXdescription77
2MyRuleYYdescription88
""" ruleSet = new ListRuleSet([ new StubRule(name:'MyRuleXX', description:'description77'), new StubRule(name:'MyRuleYY', description:'description88')]) analysisContext.ruleSet = ruleSet assertReportContents(EXPECTED) } //------------------------------------------------------------------------------------ // Setup and tear-down and helper methods //------------------------------------------------------------------------------------ @Before void setUpHtmlReportWriterTest() { log(new File('.').absolutePath) reportWriter = new HtmlReportWriter(outputFile:NEW_REPORT_FILE) reportWriter.metaClass.getFormattedTimestamp << { 'Feb 24, 2011 9:32:38 PM' } reportWriter.metaClass.getCodeNarcVersion << { '0.12' } dirResultsMain = new DirectoryResults('src/main', 1) def dirResultsCode = new DirectoryResults('src/main/code', 2) def dirResultsTest = new DirectoryResults('src/main/test', 3) def dirResultsTestSubdirNoViolations = new DirectoryResults('src/main/test/noviolations', 4) def dirResultsTestSubdirEmpty = new DirectoryResults('src/main/test/empty') def fileResults1 = new FileResults('src/main/MyAction.groovy', [VIOLATION1, VIOLATION3, VIOLATION3, VIOLATION1, VIOLATION2]) def fileResults2 = new FileResults('src/main/MyAction2.groovy', [VIOLATION3]) def fileResults3 = new FileResults('src/main/MyActionTest.groovy', [VIOLATION1, VIOLATION2]) dirResultsMain.addChild(fileResults1) dirResultsMain.addChild(dirResultsCode) dirResultsMain.addChild(dirResultsTest) dirResultsCode.addChild(fileResults2) dirResultsTest.addChild(fileResults3) dirResultsTest.addChild(dirResultsTestSubdirNoViolations) dirResultsTest.addChild(dirResultsTestSubdirEmpty) results = new DirectoryResults() results.addChild(dirResultsMain) ruleSet = new ListRuleSet([ new UnnecessaryBooleanInstantiationRule(), new ReturnFromFinallyBlockRule(), new UnnecessaryStringInstantiationRule(), new ThrowExceptionFromFinallyBlockRule(), new DuplicateImportRule() ]) analysisContext = new AnalysisContext(sourceDirectories:['/src/main'], ruleSet:ruleSet) cssFileContents = new File('src/main/resources/codenarc-htmlreport.css').text } private String getReportText() { def writer = new StringWriter() reportWriter.writeReport(writer, analysisContext, results) return writer.toString() } private void assertReportContents(String expected) { String actual = getReportText() assertEquals(normalizeXml(expected), normalizeXml(actual)) } private void assertReportFileContents(String filename, String expected) { def actual = new File(filename).text assertEquals(normalizeXml(expected), normalizeXml(actual)) } /** * Normalize the XML string. Remove all whitespace between elements, and normalize line-endings. * @param xml - the input XML string to normalize * @return the normalized XML */ static String normalizeXml(String xml) { assert xml != null def resultXml = xml.replaceAll(/\>\s*\<').trim() return resultXml.replace('\r\n', '\n') } } CodeNarc-0.23/src/test/groovy/org/codenarc/tool/0000755000175000017500000000000012623571301021061 5ustar ebourgebourgCodeNarc-0.23/src/test/groovy/org/codenarc/tool/GenerateRuleSetAllRulesByCategoryTest.groovy0000644000175000017500000000273212041642704031667 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.assertContainsAll /** * Tests for GenerateRuleSetAllRulesByCategory * * @author Chris Mair */ class GenerateRuleSetAllRulesByCategoryTest extends AbstractTestCase { @Test void testMain_GeneratesSampleRuleSetFile() { def tempFile = File.createTempFile('GenerateRuleSetAllRulesByCategoryTest', null) tempFile.deleteOnExit() GenerateRuleSetAllRulesByCategory.ruleSetFile = tempFile.path GenerateRuleSetAllRulesByCategory.main(null) def outputFileText = tempFile.text log("contents=$outputFileText") assertContainsAll(outputFileText, ['// ', 'Requires the GMetrics jar', 'unnecessary', 'UnnecessaryBigDecimalInstantiation']) } } CodeNarc-0.23/src/test/groovy/org/codenarc/tool/RunCodeNarcAgainstExternalProject.groovy0000644000175000017500000000463412324232616031044 0ustar ebourgebourg/* * Copyright 2012 the original author or 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 org.codenarc.tool /** * Runs CodeNarc against the another project's source code. * * You must set the "basedir" system property to the base directory of the external project. * You must set the "title" system property to the title of the external project. * * @author Chris Mair */ class RunCodeNarcAgainstExternalProject { private static final DEFAULT_RULESET_FILES = 'RunCodeNarcAgainstExternalProject.ruleset' static void main(String[] args) { runCodeNarc() } private static void runCodeNarc() { def baseDir = System.getProperty('basedir') def title = System.getProperty('title') assert baseDir, 'The "basedir" system property must be set to the base directory of the external project.' assert title, 'The "title" system property must be set to the title of the external project.' def rulesetfiles = System.getProperty('rulesetfiles') ?: DEFAULT_RULESET_FILES System.setProperty('codenarc.properties.file', 'Ignore') def ant = new AntBuilder() ant.taskdef(name:'codenarc', classname:'org.codenarc.ant.CodeNarcTask') ant.codenarc(ruleSetFiles:rulesetfiles) { fileset(dir:baseDir) { include(name:'**/*.groovy') } report(type:'html') { option(name:'title', value:title) option(name:'outputFile', value:'target/' + title + '-CodeNarcReport.html') } report(type:'xml') { option(name:'title', value:title) option(name:'outputFile', value:'target/' + title + '-CodeNarcReport.xml') } report(type:'text') { option(name:'writeToStandardOut', value:true) } } } } CodeNarc-0.23/src/test/groovy/org/codenarc/tool/GenerateRuleIndexPageTest.groovy0000644000175000017500000000276412041642704027350 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.assertContainsAll /** * Tests for GenerateRuleIndexPage * * @author Chris Mair */ class GenerateRuleIndexPageTest extends AbstractTestCase { @Test void testMain_GeneratesSampleRuleSetFile() { def tempFile = File.createTempFile('GenerateRuleIndexPageTest', null) tempFile.deleteOnExit() GenerateRuleIndexPage.ruleIndexFile = tempFile.path GenerateRuleIndexPage.main(null) def outputFileText = tempFile.text log("contents=$outputFileText") assertContainsAll(outputFileText, [ 'CyclomaticComplexity', 'Requires the GMetrics jar', 'Generic', 'IllegalRegex', 'Unnecessary', 'UnnecessaryBigDecimalInstantiation']) } } CodeNarc-0.23/src/test/groovy/org/codenarc/tool/RunCodeNarcAgainstGrails.groovy0000644000175000017500000000361212311373552027150 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool /** * Runs CodeNarc against the Grails source code. * * You must set the "grails.home" system property to the Grails installation directory, containing the Grails source. * * @author Chris Mair */ class RunCodeNarcAgainstGrails { private static final RULESET_FILES = 'RunCodeNarcAgainstGrails.ruleset' static void main(String[] args) { runCodeNarc() } private static void runCodeNarc() { def baseDir = System.getProperty('grails.home') assert baseDir, 'The "grails.home" system property must be set to the location of the Grails installation.' System.setProperty('codenarc.properties.file', 'Ignore') def ant = new AntBuilder() ant.taskdef(name:'codenarc', classname:'org.codenarc.ant.CodeNarcTask') ant.codenarc(ruleSetFiles:RULESET_FILES) { fileset(dir:baseDir) { include(name:'src/**/*.groovy') include(name:'scripts/**/*.groovy') exclude(name:'**/templates/**') } report(type:'html') { option(name:'title', value:"Grails ($baseDir)") option(name:'outputFile', value:'CodeNarc-Grails-Report.html') } } } } CodeNarc-0.23/src/test/groovy/org/codenarc/tool/GenerateRuleSetAllRulesTest.groovy0000644000175000017500000000256512041642704027702 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for GenerateRuleSetAllRules * * @author Chris Mair */ class GenerateRuleSetAllRulesTest extends AbstractTestCase { @Test void testMain_GeneratesSampleRuleSetFile() { def tempFile = File.createTempFile('GenerateRuleSetAllRulesTest', null) tempFile.deleteOnExit() GenerateRuleSetAllRules.ruleSetFile = tempFile.path GenerateRuleSetAllRules.main(null) def outputFileText = tempFile.text log("contents=$outputFileText") assert outputFileText.contains('UnnecessaryBigDecimalInstantiation') assert outputFileText.contains('Requires the GMetrics jar') } } CodeNarc-0.23/src/test/groovy/org/codenarc/tool/GenerateCodeNarcRulesPropertiesTest.groovy0000644000175000017500000000264112041642704031414 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.tool import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for GenerateCodeNarcRulesProperties * * @author Chris Mair */ class GenerateCodeNarcRulesPropertiesTest extends AbstractTestCase { @Test void testMain_GeneratesPropertiesFile() { def tempFile = File.createTempFile('GenerateCodeNarcRulesPropertiesTest', null) tempFile.deleteOnExit() GenerateCodeNarcRulesProperties.propertiesFile = tempFile.path GenerateCodeNarcRulesProperties.main(null) def outputFileText = tempFile.text log("contents=$outputFileText") assert outputFileText.contains('UnnecessaryBigDecimalInstantiation = org.codenarc.rule.unnecessary.UnnecessaryBigDecimalInstantiationRule') } } CodeNarc-0.23/src/test/groovy/org/codenarc/source/0000755000175000017500000000000012623571301021404 5ustar ebourgebourgCodeNarc-0.23/src/test/groovy/org/codenarc/source/SourceStringTest.groovy0000644000175000017500000001351612407277325026161 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.source import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail /** * Tests for SourceString * * @author Chris Mair */ class SourceStringTest extends AbstractTestCase { private static final SOURCE = '''class SampleFile { int count }''' private sourceString @Test void testImplementsSourceCode() { assert sourceString instanceof SourceCode } @Test void testConstructor_NullSource() { shouldFail { new SourceString(null) } } @Test void testConstructor_EmptySource() { shouldFail { new SourceString('') } } @Test void testConstructor_DefaultPathAndName() { assert sourceString.getPath() == null assert sourceString.getName() == null } @Test void testConstructor_PathAndName() { sourceString = new SourceString(SOURCE, 'Path', 'Name') assert sourceString.getPath() == 'Path' assert sourceString.getName() == 'Name' } @Test void testNormalizedPath() { def originalFileSeparator = System.getProperty('file.separator') try { System.setProperty('file.separator', '\\') sourceString.path = 'abc\\def\\ghi' assert sourceString.path == 'abc/def/ghi' assert new SourceString('src', '\\abc').path == '/abc' System.setProperty('file.separator', '~') assert new SourceString('src', '~abc~def').path == '/abc/def' System.setProperty('file.separator', '/') assert new SourceString('src', '/abc/def').path == '/abc/def' } finally { System.setProperty('file.separator', originalFileSeparator) } } @Test void testGetText() { def text = sourceString.text assert text == SOURCE // Make sure instance is cached assert sourceString.text.is(text) } @Test void testGetLines() { def lines = sourceString.lines assert lines == ['class SampleFile {', ' int count', ' }'] // Make sure instance is cached assert sourceString.lines.is(lines) } @Test void testLine() { assert sourceString.line(0) == 'class SampleFile {' assert sourceString.line(1) == 'int count' assert sourceString.line(-1) == null assert sourceString.line(3) == null } @Test void testGetAst() { def ast = sourceString.ast log("classes=${ast.classes}") assert ast.classes[0].name == 'SampleFile' // Make sure instance is cached assert sourceString.ast.is(ast) } @Test void testGetAst_ReferencesClassNotInClasspath() { final NEW_SOURCE = ''' import some.other.pkg.Processor class MyClass extends Processor { String name Processor processor } ''' sourceString = new SourceString(NEW_SOURCE) def ast = sourceString.ast assert ast.classes[0].name == 'MyClass' } @Test void testGetAst_CompilerErrorInSource() { final NEW_SOURCE = ''' class MyClass { try { } catch(MyException e) { // TODO Should do something here } } ''' sourceString = new SourceString(NEW_SOURCE) assert sourceString.ast == null } @Test void testGetLineNumberForCharacterIndex() { final NEW_SOURCE = '\nclass MyClass { \r\n try {\n} catch(MyException e) {\n// TODO \n }\n }\n' NEW_SOURCE.eachWithIndex { ch, i -> print "$i=${(int)(ch as char)} " } sourceString = new SourceString(NEW_SOURCE) assert sourceString.getLineNumberForCharacterIndex(0) == 1 assert sourceString.getLineNumberForCharacterIndex(1) == 2 assert sourceString.getLineNumberForCharacterIndex(18) == 2 assert sourceString.getLineNumberForCharacterIndex(19) == 3 assert sourceString.getLineNumberForCharacterIndex(26) == 3 assert sourceString.getLineNumberForCharacterIndex(27) == 4 assert sourceString.getLineNumberForCharacterIndex(51) == 4 assert sourceString.getLineNumberForCharacterIndex(52) == 5 assert sourceString.getLineNumberForCharacterIndex(60) == 5 assert sourceString.getLineNumberForCharacterIndex(61) == 6 assert sourceString.getLineNumberForCharacterIndex(63) == 6 assert sourceString.getLineNumberForCharacterIndex(64) == 7 assert sourceString.getLineNumberForCharacterIndex(66) == 7 assert sourceString.getLineNumberForCharacterIndex(67) == -1 assert sourceString.getLineNumberForCharacterIndex(999) == -1 assert sourceString.getLineNumberForCharacterIndex(-1) == -1 } @Test void testIsValid() { assert sourceString.valid assert !new SourceString('%^#@$').valid } @Before void setUpSourceStringTest() { sourceString = new SourceString(SOURCE) } } CodeNarc-0.23/src/test/groovy/org/codenarc/source/SourceFileTest.groovy0000644000175000017500000000625512407277406025574 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.source import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail /** * Tests for SourceFile * * @author Chris Mair */ class SourceFileTest extends AbstractTestCase { private static final FILE = 'src/test/resources/SampleFile.groovy' private static final INVALID_FILE = 'src/test/resources/SampleInvalidFile.txt' private sourceFile private file @Test void testImplementsSourceCode() { assert sourceFile instanceof SourceCode } @Test void testConstructor_NullPath() { shouldFail { new SourceFile(null) } } @Test void testConstructor_EmptyPath() { shouldFail { new SourceFile('') } } @Test void testGetName() { assert sourceFile.getName() == 'SampleFile.groovy' } @Test void testGetPath() { log("path=${sourceFile.path}") assert sourceFile.getPath() == FILE } @Test void testGetText() { def text = sourceFile.text assert text == new File(FILE).text // Make sure instance is cached assert sourceFile.text.is(text) } @Test void testGetLines() { def lines = sourceFile.lines assert lines == ['class SampleFile {', '', '}'] // Make sure instance is cached assert sourceFile.lines.is(lines) } @Test void testLine() { assert sourceFile.line(0) == 'class SampleFile {' assert sourceFile.line(-1) == null assert sourceFile.line(99) == null } @Test void testGetAst() { def ast = sourceFile.ast log("classes=${ast.classes}") assert ast.classes[0].name == 'SampleFile' // Make sure instance is cached assert sourceFile.ast.is(ast) } @Test void testGetLineNumberForCharacterIndex() { assert sourceFile.getLineNumberForCharacterIndex(0) == 1 assert sourceFile.getLineNumberForCharacterIndex(1) == 1 assert sourceFile.getLineNumberForCharacterIndex(21) == 2 assert sourceFile.getLineNumberForCharacterIndex(999) == -1 assert sourceFile.getLineNumberForCharacterIndex(-1) == -1 } @Test void testIsValid() { assert sourceFile.valid assert !new SourceFile(new File(INVALID_FILE)).valid } @Before void setUpSourceFileTest() { file = new File(FILE) sourceFile = new SourceFile(file) } } CodeNarc-0.23/src/test/groovy/org/codenarc/source/CustomCompilerPhaseSourceDecoratorTest.groovy0000644000175000017500000000377112311373552032477 0ustar ebourgebourg/* * Copyright 2013 the original author or 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 org.codenarc.source import org.codehaus.groovy.ast.ModuleNode import org.codehaus.groovy.control.Phases import org.codenarc.test.AbstractTestCase import org.codenarc.test.TestUtil import org.junit.Test /** * Tests for CustomCompilerPhaseSourceDecorator */ class CustomCompilerPhaseSourceDecoratorTest extends AbstractTestCase { private static final PHASES_CAUSING_OUTPUT = [ Phases.OUTPUT, Phases.FINALIZATION, Phases.ALL ] @Test void testEnsuresCompilerPhaseBeforeClassOutputToDisk() { def source = new SourceString('class MyClass {}') PHASES_CAUSING_OUTPUT.each { int phase -> TestUtil.shouldFail(AssertionError) { new CustomCompilerPhaseSourceDecorator(source, phase) } } } @Test void testOverridesReturnedAST() { def source = new SourceString('class SomeThrowable extends Throwable {}') def decoratedSource = new CustomCompilerPhaseSourceDecorator(source, Phases.SEMANTIC_ANALYSIS) assert decoratedSource.ast != source.ast assert interfacesOfSuperclassIn(source.ast).isEmpty() assert interfacesOfSuperclassIn(decoratedSource.ast) == [Serializable.name] } private List interfacesOfSuperclassIn(ModuleNode ast) { assert ast.classes.size() == 1 ast.classes.first().superClass.allInterfaces*.name } } CodeNarc-0.23/src/test/groovy/org/codenarc/source/SourceCodeCriteriaTest.groovy0000644000175000017500000001375212323251367027245 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.source import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test /** * Tests for SourceCodeUtil * * @author Chris Mair */ class SourceCodeCriteriaTest extends AbstractTestCase { private static final NAME = 'MyTest.groovy' private static final PATH = "src/$NAME" private static final MATCH = /.*Test\.groovy/ private static final NO_MATCH = /.*Other\.groovy/ private static final OTHER_NAME = 'OtherClass.groovy' private static final ANYTHING = 'abc' private sourceCode @Test void testMatches_NullPathAndName() { assert new SourceCodeCriteria().matches(sourceCode) assert new SourceCodeCriteria(doNotApplyToFilesMatching:ANYTHING).matches(sourceCode) assert !new SourceCodeCriteria(applyToFilesMatching:ANYTHING).matches(sourceCode) } @Test void testMatches_Path() { sourceCode.path = PATH assert new SourceCodeCriteria().matches(sourceCode) assert new SourceCodeCriteria(applyToFilesMatching:MATCH).matches(sourceCode) assert new SourceCodeCriteria(doNotApplyToFilesMatching:NO_MATCH).matches(sourceCode) assert !new SourceCodeCriteria(applyToFilesMatching:NO_MATCH).matches(sourceCode) assert !new SourceCodeCriteria(applyToFilesMatching:MATCH, doNotApplyToFilesMatching:MATCH).matches(sourceCode) } @Test void testMatches_Name() { sourceCode.name = NAME assert new SourceCodeCriteria().matches(sourceCode) assert new SourceCodeCriteria(applyToFileNames:NAME).matches(sourceCode) assert new SourceCodeCriteria(doNotApplyToFileNames:OTHER_NAME).matches(sourceCode) assert new SourceCodeCriteria(applyToFileNames:"$OTHER_NAME,$NAME").matches(sourceCode) assert new SourceCodeCriteria(doNotApplyToFileNames:"File2.groovy,$OTHER_NAME").matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:OTHER_NAME).matches(sourceCode) assert !new SourceCodeCriteria(doNotApplyToFileNames:NAME).matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:NAME, doNotApplyToFileNames:NAME).matches(sourceCode) assert !new SourceCodeCriteria(doNotApplyToFileNames:"$OTHER_NAME,$NAME").matches(sourceCode) } @Test void testMatches_Name_Wildcards() { sourceCode.name = NAME assert new SourceCodeCriteria(applyToFileNames:'*.groovy').matches(sourceCode) assert new SourceCodeCriteria(applyToFileNames:'MyT?st.groovy').matches(sourceCode) assert new SourceCodeCriteria(doNotApplyToFileNames:'*.ruby').matches(sourceCode) assert new SourceCodeCriteria(applyToFileNames:"$OTHER_NAME,My*.groovy").matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:'*View.groovy').matches(sourceCode) assert !new SourceCodeCriteria(doNotApplyToFileNames:'My*.groovy').matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:'My*.groovy', doNotApplyToFileNames:'MyT?st.groovy').matches(sourceCode) assert !new SourceCodeCriteria(doNotApplyToFileNames:"$OTHER_NAME,My*.groovy").matches(sourceCode) } @Test void testMatches_NameAndPath() { sourceCode.name = NAME sourceCode.path = PATH assert new SourceCodeCriteria().matches(sourceCode) assert new SourceCodeCriteria(applyToFileNames:NAME, applyToFilesMatching:MATCH).matches(sourceCode) assert new SourceCodeCriteria(doNotApplyToFilesMatching:NO_MATCH, doNotApplyToFileNames:OTHER_NAME).matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:OTHER_NAME, applyToFilesMatching:NO_MATCH).matches(sourceCode) assert !new SourceCodeCriteria(doNotApplyToFileNames:NAME, applyToFilesMatching:MATCH).matches(sourceCode) assert !new SourceCodeCriteria(applyToFilesMatching:MATCH, applyToFileNames:NAME, doNotApplyToFileNames:"Xyz.groovy,$NAME").matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:NAME, doNotApplyToFilesMatching:MATCH).matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:NAME, doNotApplyToFilesMatching:MATCH).matches(sourceCode) } @Test void testMatches_NameAndPath_ApplyToFileNamesSpecifiesPath() { sourceCode.name = NAME sourceCode.path = PATH assert new SourceCodeCriteria(applyToFileNames:'**/*.groovy').matches(sourceCode) assert new SourceCodeCriteria(applyToFileNames:'src/MyT?st.groovy').matches(sourceCode) assert new SourceCodeCriteria(applyToFileNames:'*/MyT?st.groovy').matches(sourceCode) assert new SourceCodeCriteria(doNotApplyToFileNames:'**/*.ruby').matches(sourceCode) assert new SourceCodeCriteria(applyToFileNames:"$OTHER_NAME,**/My*.groovy").matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:'**/*View.groovy').matches(sourceCode) assert !new SourceCodeCriteria(doNotApplyToFileNames:'**/My*.groovy').matches(sourceCode) assert !new SourceCodeCriteria(applyToFileNames:'src/My*.groovy', doNotApplyToFileNames:'MyT?st.groovy').matches(sourceCode) assert !new SourceCodeCriteria(doNotApplyToFileNames:"$OTHER_NAME,src/**My*.groovy").matches(sourceCode) } @Before void setUpSourceCodeCriteriaTest() { sourceCode = new SourceString('class ABC { }') } } CodeNarc-0.23/src/test/groovy/org/codenarc/results/0000755000175000017500000000000012623571301021605 5ustar ebourgebourgCodeNarc-0.23/src/test/groovy/org/codenarc/results/FileResultsTest.groovy0000644000175000017500000000751112145022774026165 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.results import org.codenarc.rule.StubRule import org.codenarc.rule.Violation import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for the FileResults class * * @author Chris Mair */ class FileResultsTest extends AbstractTestCase { private static final PATH = '/src/main/MyFile.groovy' private static final VIOLATION1 = new Violation(rule:new StubRule(1)) private static final VIOLATION2 = new Violation(rule:new StubRule(2)) private static final VIOLATION3 = new Violation(rule:new StubRule(3)) private static final VIOLATION4 = new Violation(rule:new StubRule(4)) private static final VIOLATION7 = new Violation(rule:new StubRule(7)) @Test void testWithNoViolations() { def results = new FileResults(PATH, []) assert results.path == PATH assert results.children == [] assert results.violations == [] assert results.getNumberOfViolationsWithPriority(1) == 0 assert results.getNumberOfViolationsWithPriority(2) == 0 assert results.getNumberOfViolationsWithPriority(3) == 0 assert results.getNumberOfFilesWithViolations(1) == 0 assert results.totalNumberOfFiles == 1 assert results.isFile() } @Test void testWithViolations() { def results = new FileResults(PATH, [VIOLATION1, VIOLATION3, VIOLATION7, VIOLATION3, VIOLATION1, VIOLATION2, VIOLATION4]) assert results.children == [] assert results.getViolations() == [VIOLATION1, VIOLATION3, VIOLATION7, VIOLATION3, VIOLATION1, VIOLATION2, VIOLATION4] assert results.violations.findAll { v -> v.rule.priority == 1 } == [VIOLATION1, VIOLATION1] assert results.violations.findAll { v -> v.rule.priority == 2 } == [VIOLATION2] assert results.violations.findAll { v -> v.rule.priority == 3 } == [VIOLATION3, VIOLATION3] assert results.getNumberOfViolationsWithPriority(1) == 2 assert results.getNumberOfViolationsWithPriority(2) == 1 assert results.getNumberOfViolationsWithPriority(3) == 2 assert results.getNumberOfViolationsWithPriority(4) == 1 assert results.getNumberOfViolationsWithPriority(7) == 1 assert results.getNumberOfFilesWithViolations(1) == 1 assert results.totalNumberOfFiles == 1 } @Test void testGetNumberOfFilesWithViolations_IgnoresViolationsWithHigherPriority() { def results = new FileResults(PATH, [VIOLATION3]) assert results.getNumberOfFilesWithViolations(3) == 1 assert results.getNumberOfFilesWithViolations(2) == 0 assert results.getNumberOfFilesWithViolations(1) == 0 } @Test void testFindResultsForPath() { def results = new FileResults(PATH, []) assert results.findResultsForPath(null) == null assert results.findResultsForPath('xx/yy') == null assert results.findResultsForPath(PATH) == results } @Test void testGetViolations_ReturnsDefensiveCopy() { def results = new FileResults(PATH, [VIOLATION1, VIOLATION3]) results.getViolations() << 123 assert results.getViolations() == [VIOLATION1, VIOLATION3] } } CodeNarc-0.23/src/test/groovy/org/codenarc/results/VirtualResultsTest.groovy0000644000175000017500000000424512140054110026715 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.results import org.codenarc.rule.Rule import org.codenarc.rule.Violation import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Test for virtual results * @author Hamlet D'Arcy */ class VirtualResultsTest extends AbstractTestCase { @Test void testViolations() { def violations = [ new Violation(rule: [getPriority : { 1 } ] as Rule), new Violation(rule: [getPriority : { 2 } ] as Rule), new Violation(rule: [getPriority : { 2 } ] as Rule), new Violation(rule: [getPriority : { 3 } ] as Rule), new Violation(rule: [getPriority : { 3 } ] as Rule), new Violation(rule: [getPriority : { 3 } ] as Rule), new Violation(rule: [getPriority : { 7 } ] as Rule), ] def results = new VirtualResults(violations) assert results.getViolations() == violations assert 1 == results.violations.findAll { v -> v.rule.priority == 1 }.size() assert 2 == results.violations.findAll { v -> v.rule.priority == 2 }.size() assert 3 == results.violations.findAll { v -> v.rule.priority == 3 }.size() assert 1 == results.violations.findAll { v -> v.rule.priority == 7 }.size() } @Test void testGetViolations_ReturnsDefensiveCopy() { def results = new VirtualResults([new Violation(rule: [getPriority : { 1 } ] as Rule)]) results.getViolations() << 123 assert results.getViolations().size() == 1 } } CodeNarc-0.23/src/test/groovy/org/codenarc/results/DirectoryResultsTest.groovy0000644000175000017500000001500012323245230027232 0ustar ebourgebourg/* * Copyright 2008 the original author or 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 org.codenarc.results import org.codenarc.rule.StubRule import org.codenarc.rule.Violation import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for DirectoryResults * * @author Chris Mair */ class DirectoryResultsTest extends AbstractTestCase { private static final PATH = '/src/main' private static final VIOLATION1 = new Violation(rule:new StubRule(1)) private static final VIOLATION2 = new Violation(rule:new StubRule(2)) private static final VIOLATION3 = new Violation(rule:new StubRule(3)) private static final VIOLATION4 = new Violation(rule:new StubRule(4)) private static final VIOLATION7 = new Violation(rule:new StubRule(7)) @Test void testNoChildren() { def results = new DirectoryResults(PATH) assert results.path == PATH assert results.children == [] assert results.violations == [] assert results.getNumberOfViolationsWithPriority(1) == 0 assert results.getNumberOfViolationsWithPriority(2) == 0 assert results.getNumberOfViolationsWithPriority(3) == 0 assert results.totalNumberOfFiles == 0 assert results.getNumberOfFilesWithViolations(1) == 0 assert results.getNumberOfFilesWithViolations(1, false) == 0 assert !results.isFile() } @Test void testWithOneChild() { def results = new DirectoryResults(PATH) assert results.path == PATH def fileResults = new FileResults('path', [VIOLATION1, VIOLATION3, VIOLATION3, VIOLATION1, VIOLATION2]) results.addChild(fileResults) results.numberOfFilesInThisDirectory = 7 assert results.children == [fileResults] assert results.violations.findAll { v -> v.rule.priority == 1 } == [VIOLATION1, VIOLATION1] assert results.violations.findAll { v -> v.rule.priority == 2 } == [VIOLATION2] assert results.violations.findAll { v -> v.rule.priority == 3 } == [VIOLATION3, VIOLATION3] assert results.getNumberOfViolationsWithPriority(1) == 2 assert results.getNumberOfViolationsWithPriority(2) == 1 assert results.getNumberOfViolationsWithPriority(3, false) == 2 assert results.getNumberOfFilesWithViolations(3) == 1 assert results.getNumberOfFilesWithViolations(1) == 1 assert results.getNumberOfFilesWithViolations(1, false) == 1 assert results.getTotalNumberOfFiles() == 7 assert results.getTotalNumberOfFiles(false) == 7 } @Test void testWithMultipleChildren() { def results = new DirectoryResults(PATH) assert results.path == PATH results.numberOfFilesInThisDirectory = 3 def fileResults1 = new FileResults('path', [VIOLATION1, VIOLATION3, VIOLATION3, VIOLATION7, VIOLATION1, VIOLATION2]) results.addChild(fileResults1) def subDirResults = new DirectoryResults('subdir') subDirResults.numberOfFilesInThisDirectory = 2 def fileResults2 = new FileResults('path', [VIOLATION2, VIOLATION3, VIOLATION4]) subDirResults.addChild(fileResults2) results.addChild(subDirResults) assert results.children == [fileResults1, subDirResults] assert results.getViolations().sort { v -> v.rule.priority } == [VIOLATION1, VIOLATION1, VIOLATION2, VIOLATION2, VIOLATION3, VIOLATION3, VIOLATION3, VIOLATION4, VIOLATION7] assert results.violations.findAll { v -> v.rule.priority == 1 } == [VIOLATION1, VIOLATION1] assert results.violations.findAll { v -> v.rule.priority == 2 } == [VIOLATION2, VIOLATION2] assert results.violations.findAll { v -> v.rule.priority == 3 } == [VIOLATION3, VIOLATION3, VIOLATION3] assert results.violations.findAll { v -> v.rule.priority == 4 } == [VIOLATION4] assert results.violations.findAll { v -> v.rule.priority == 7 } == [VIOLATION7] assert results.getNumberOfViolationsWithPriority(1) == 2 assert results.getNumberOfViolationsWithPriority(2) == 2 assert results.getNumberOfViolationsWithPriority(3) == 3 assert results.getNumberOfViolationsWithPriority(4) == 1 assert results.getNumberOfViolationsWithPriority(7) == 1 assert results.getNumberOfViolationsWithPriority(1, false) == 2 assert results.getNumberOfViolationsWithPriority(2, false) == 1 assert results.getNumberOfViolationsWithPriority(3, false) == 2 assert results.getNumberOfFilesWithViolations(1) == 1 assert results.getNumberOfFilesWithViolations(2) == 2 assert results.getNumberOfFilesWithViolations(1, false) == 1 assert subDirResults.getNumberOfFilesWithViolations(1, false) == 0 assert results.getTotalNumberOfFiles() == 5 assert results.getTotalNumberOfFiles(false) == 3 } @Test void testFindResultsForPath() { def results = new DirectoryResults(PATH) def fileResults1 = new FileResults('file1', []) def subDirResults = new DirectoryResults('subdir') def fileResults2 = new FileResults('file2', []) subDirResults.addChild(fileResults2) results.addChild(fileResults1) results.addChild(subDirResults) assert results.findResultsForPath(null) == null assert results.findResultsForPath('xx/yy') == null assert results.findResultsForPath(PATH) == results assert results.findResultsForPath('file1') == fileResults1 assert results.findResultsForPath('subdir') == subDirResults assert results.findResultsForPath('file2') == fileResults2 } @Test void testGetViolations_ReturnsDefensiveCopy() { def results = new DirectoryResults(PATH) def fileResults = new FileResults('path', [VIOLATION1, VIOLATION3]) results.addChild(fileResults) results.getViolations() << VIOLATION7 assert results.getViolations() == [VIOLATION1, VIOLATION3] } } CodeNarc-0.23/src/test/groovy/org/codenarc/ant/0000755000175000017500000000000012623571301020666 5ustar ebourgebourgCodeNarc-0.23/src/test/groovy/org/codenarc/ant/AntFileSetSourceAnalyzerTest.groovy0000644000175000017500000002253512145307142027670 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ant import org.apache.tools.ant.Project import org.apache.tools.ant.types.FileSet import org.codenarc.results.Results import org.codenarc.rule.FakeCountRule import org.codenarc.rule.FakePathRule import org.codenarc.rule.MockRule import org.codenarc.ruleset.ListRuleSet import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.captureLog4JMessages import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for AntFileSetSourceAnalyzer * * @author Chris Mair */ class AntFileSetSourceAnalyzerTest extends AbstractTestCase { private static final BASE_DIR = 'src/test/resources' private Project project private FileSet fileSet private ruleSet @Test void testConstructor_NullFileSet() { shouldFailWithMessageContaining('fileSet') { new AntFileSetSourceAnalyzer(project, (FileSet)null) } } @Test void testConstructor_NullListOfFileSets() { shouldFailWithMessageContaining('fileSet') { new AntFileSetSourceAnalyzer(project, (List)null) } } @Test void testConstructor_NullProject() { shouldFailWithMessageContaining('project') { new AntFileSetSourceAnalyzer(null, fileSet) } } @Test void testAnalyze_SimpleDirectory() { fileSet.setIncludes('source/**/*.groovy') def analyzer = new AntFileSetSourceAnalyzer(project, fileSet) def results = analyzer.analyze(ruleSet) def sourceFilePaths = results.violations*.message assert sourceFilePaths == [ 'src/test/resources/source/SourceFile1.groovy', 'src/test/resources/source/SourceFile2.groovy' ] assertResultsCounts(results, 2, 2) assert getAllResultsPaths(results) == [ 'source', 'source/SourceFile1.groovy', 'source/SourceFile2.groovy'] } @Test void testAnalyze_NestedSubdirectories() { fileSet.setIncludes('sourcewithdirs/**/*.groovy') fileSet.setExcludes('**/*File2.groovy') def analyzer = new AntFileSetSourceAnalyzer(project, fileSet) def results = analyzer.analyze(ruleSet) def sourceFilePaths = results.violations*.message final EXPECTED_PATHS = [ 'src/test/resources/sourcewithdirs/SourceFile1.groovy', 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', //'src/test/resources/sourcewithdirs/subdir1/Subdir1File2.groovy', -- EXCLUDED 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy', 'src/test/resources/sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy' ] assert sourceFilePaths == EXPECTED_PATHS assertResultsCounts(results, 4, 4) final ALL_RESULTS_PATHS = [ 'sourcewithdirs', 'sourcewithdirs/SourceFile1.groovy', 'sourcewithdirs/subdir1', 'sourcewithdirs/subdir1/Subdir1File1.groovy', 'sourcewithdirs/subdir2', 'sourcewithdirs/subdir2/Subdir2File1.groovy', 'sourcewithdirs/subdir2/subdir2a', 'sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy' ] assert getAllResultsPaths(results) == ALL_RESULTS_PATHS assertResultsCounts(results.findResultsForPath('sourcewithdirs/subdir1'), 1, 1) assertResultsCounts(results.findResultsForPath('sourcewithdirs/subdir2/subdir2a'), 1, 1) } @Test void testAnalyze_NestedSubdirectories_NoViolations() { ruleSet = new ListRuleSet([new FakeCountRule()]) fileSet.setIncludes('sourcewithdirs/**/*.groovy') def analyzer = new AntFileSetSourceAnalyzer(project, fileSet) def results = analyzer.analyze(ruleSet) assertResultsCounts(results, 5, 0) assertResultsCounts(results.findResultsForPath('sourcewithdirs/subdir1'), 2, 0) assertResultsCounts(results.findResultsForPath('sourcewithdirs/subdir2'), 2, 0) assertResultsCounts(results.findResultsForPath('sourcewithdirs/subdir2/subdir2a'), 1, 0) } @Test void testAnalyze_MultipleFileSets() { final DIR1 = 'src/test/resources/sourcewithdirs/subdir1' final DIR2 = 'src/test/resources/sourcewithdirs/subdir2' final GROOVY_FILES = '**/*.groovy' def fileSet1 = new FileSet(dir:new File(DIR1), project:project, includes:GROOVY_FILES) def fileSet2 = new FileSet(dir:new File(DIR2), project:project, includes:GROOVY_FILES) def analyzer = new AntFileSetSourceAnalyzer(project, [fileSet1, fileSet2]) def results = analyzer.analyze(ruleSet) def sourceFilePaths = results.violations*.message log("sourceFilePaths=$sourceFilePaths") final EXPECTED_PATHS = [ 'src/test/resources/sourcewithdirs/subdir1/Subdir1File1.groovy', 'src/test/resources/sourcewithdirs/subdir1/Subdir1File2.groovy', 'src/test/resources/sourcewithdirs/subdir2/Subdir2File1.groovy', 'src/test/resources/sourcewithdirs/subdir2/subdir2a/Subdir2aFile1.groovy' ] assert sourceFilePaths == EXPECTED_PATHS assertResultsCounts(results, 4, 4) } @Test void testAnalyze_EmptyFileSet() { fileSet.setExcludes('**/*') def analyzer = new AntFileSetSourceAnalyzer(project, fileSet) def results = analyzer.analyze(ruleSet) assertResultsCounts(results, 0, 0) } @Test void testAnalyze_LogsThrownExceptions() { fileSet.setIncludes('source/**/*.groovy') def analyzer = new AntFileSetSourceAnalyzer(project, fileSet) final EXCEPTION = new RuntimeException('TESTING AN EXCEPTION. Error in applyTo()') def badRule = new MockRule(applyTo: { sourceCode -> throw EXCEPTION }) def loggingEvents = captureLog4JMessages { analyzer.analyze(new ListRuleSet([badRule])) } assert loggingEvents.find { loggingEvent -> loggingEvent.throwableInformation.throwable == EXCEPTION } } @Test void testGetSourceDirectories_ReturnsEmptyListForNoFileSets() { def analyzer = new AntFileSetSourceAnalyzer(project, []) assert analyzer.sourceDirectories == [] } @Test void testGetSourceDirectories_ReturnsSingleDirectoryForSingleFileSet() { def analyzer = new AntFileSetSourceAnalyzer(project, [fileSet]) assert analyzer.sourceDirectories == [normalizedPath(BASE_DIR)] } @Test void testGetSourceDirectories_ReturnsDirectoryForEachFileSet() { def fileSet1 = new FileSet(dir:new File('abc'), project:project) def fileSet2 = new FileSet(dir:new File('def'), project:project) def analyzer = new AntFileSetSourceAnalyzer(project, [fileSet1, fileSet2]) log("sourceDirectories=${analyzer.sourceDirectories}") assert analyzer.sourceDirectories == [normalizedPath('abc'), normalizedPath('def')] } @Test void testGetSourceDirectories_ReturnsDirectoryRelativeToBaseDirectory() { def currentDir = new File('').absolutePath project = new Project(basedir:currentDir) fileSet.setProject(project) fileSet.dir = new File(currentDir + '/src/main/groovy') def analyzer = new AntFileSetSourceAnalyzer(project, [fileSet]) log("analyzer.sourceDirectories=${analyzer.sourceDirectories}") assert analyzer.sourceDirectories == [normalizedPath('src/main/groovy')] } @Before void setUpAntFileSetSourceAnalyzerTest() { fileSet = new FileSet() fileSet.dir = new File(BASE_DIR) project = new Project() project.setBasedir('.') fileSet.setProject(project) ruleSet = new ListRuleSet([new FakePathRule()]) } private String normalizedPath(String path) { new File(path).path } private void assertResultsCounts(Results results, int totalFiles, int filesWithViolations) { assert results.totalNumberOfFiles == totalFiles, "results.totalNumberOfFiles=${results.totalNumberOfFiles}" assert results.getNumberOfFilesWithViolations(3) == filesWithViolations, "results.getNumberOfFilesWithViolations(3)=${results.getNumberOfFilesWithViolations(3)}" } private List getAllResultsPaths(Results results) { def paths = [] resultsPaths(results, paths) log("allResultsPaths=$paths") paths } private void resultsPaths(Results results, List paths) { if (results.path) { paths << results.path } results.children.each { child -> resultsPaths(child, paths) } } } CodeNarc-0.23/src/test/groovy/org/codenarc/ant/CodeNarc_AntBuilderTest.groovy0000644000175000017500000000604112450014131026554 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ant import org.codenarc.test.AbstractTestCase import org.junit.Test import static org.codenarc.test.TestUtil.assertContainsAllInOrder /** * Tests for CodeNarcTask that use the Groovy AntBuilder. * * @author Chris Mair */ class CodeNarc_AntBuilderTest extends AbstractTestCase { private static final XML = 'xml' private static final HTML = 'html' private static final TEXT = 'text' private static final HTML_REPORT_FILE = 'target/AntBuilderTestHtmlReport.html' private static final XML_REPORT_FILE = 'target/AntBuilderTestXmlReport.xml' private static final TEXT_REPORT_FILE = 'target/AntBuilderTestTextReport.txt' private static final TITLE = 'Sample Project' private static final RULESET_FILES = [ 'rulesets/basic.xml', 'rulesets/imports.xml'].join(',') @Test void testAntTask_Execute_UsingAntBuilder() { def ant = new AntBuilder() ant.taskdef(name:'codenarc', classname:'org.codenarc.ant.CodeNarcTask') ant.codenarc(ruleSetFiles:RULESET_FILES) { fileset(dir:'src/test/groovy/org/codenarc/util') { include(name:'**/*.groovy') } report(type:HTML) { option(name:'title', value:TITLE) option(name:'outputFile', value:HTML_REPORT_FILE) } report(type:XML) { option(name:'title', value:TITLE) option(name:'outputFile', value:XML_REPORT_FILE) } report(type:TEXT) { option(name:'title', value:TITLE) option(name:'outputFile', value:TEXT_REPORT_FILE) } } verifyHtmlReportFile() verifyXmlReportFile() verifyTextReportFile() } private void verifyHtmlReportFile() { def file = new File(HTML_REPORT_FILE) assert file.exists() assertContainsAllInOrder(file.text, [TITLE, 'io', 'Rule Descriptions']) } private void verifyXmlReportFile() { def file = new File(XML_REPORT_FILE) assert file.exists() assertContainsAllInOrder(file.text, ['']) } private void verifyTextReportFile() { def file = new File(TEXT_REPORT_FILE) assert file.exists() assertContainsAllInOrder(file.text, ['CodeNarc Report', TITLE, 'www.codenarc.org']) } } CodeNarc-0.23/src/test/groovy/org/codenarc/ant/CodeNarcTask_CustomRuleSetTest.groovy0000644000175000017500000000373112041642704030140 0ustar ebourgebourg/* * Copyright 2011 the original author or 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 org.codenarc.ant import org.apache.tools.ant.Project import org.apache.tools.ant.types.FileSet import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.captureSystemOut /** * Run the CodeNarc Ant Task against a portion of the CodeNarc source using a custom, predefined RuleSet. * * @author Chris Mair */ class CodeNarcTask_CustomRuleSetTest extends AbstractTestCase { private static final BASE_DIR = 'src' private static final RULESET_FILES = 'rulesets/CustomRuleSet.groovy' private codeNarcTask private fileSet @Test void testExecute_UseCustomRuleSet() { codeNarcTask.addFileset(fileSet) def output = captureSystemOut { codeNarcTask.execute() } log("output: $output") assert output.contains('CyclomaticComplexity') } @Before void setUpCodeNarcTask_CustomRuleSetTest() { def project = new Project(basedir:'.') fileSet = new FileSet(dir:new File(BASE_DIR), project:project) fileSet.setIncludes('main/groovy/org/codenarc/rule/dry/*.groovy') codeNarcTask = new CodeNarcTask(project:project) codeNarcTask.addConfiguredReport(new Report(type:'console')) codeNarcTask.ruleSetFiles = RULESET_FILES } } CodeNarc-0.23/src/test/groovy/org/codenarc/ant/CodeNarcTaskAllRuleSetsTest.groovy0000644000175000017500000000412712130151260027411 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.ant import org.apache.tools.ant.Project import org.apache.tools.ant.types.FileSet import org.codenarc.ruleset.RuleSets import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test /** * Run the CodeNarc Ant Task against a portion of the CodeNarc source using all predefined RuleSets. * * @author Chris Mair */ class CodeNarcTaskAllRuleSetsTest extends AbstractTestCase { private static final BASE_DIR = 'src' private static final RULESET_FILES = RuleSets.ALL_RULESET_FILES.join(',') private static final REPORT_FILE = 'target/CodeNarcTaskAllRuleSetsReport.html' private codeNarcTask private fileSet private outputFile @Test void testExecute_MultipleRuleSetFiles() { codeNarcTask.addFileset(fileSet) codeNarcTask.execute() assertReportFileExists() } @Before void setUpCodeNarcTaskAllRuleSetsTest() { def project = new Project(basedir:'.') fileSet = new FileSet(dir:new File(BASE_DIR), project:project) fileSet.setIncludes('main/groovy/org/codenarc/rule/basic/*.groovy') codeNarcTask = new CodeNarcTask(project:project) codeNarcTask.addConfiguredReport(new Report(type:'html', toFile:REPORT_FILE)) codeNarcTask.ruleSetFiles = RULESET_FILES outputFile = new File(REPORT_FILE) } private void assertReportFileExists() { assert outputFile.exists() } } CodeNarc-0.23/src/test/groovy/org/codenarc/ant/CodeNarcTaskTest.groovy0000644000175000017500000002412712415111054025276 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ant import org.apache.tools.ant.BuildException import org.apache.tools.ant.Project import org.apache.tools.ant.types.FileSet import org.codenarc.analyzer.SourceAnalyzer import org.codenarc.report.HtmlReportWriter import org.codenarc.report.XmlReportWriter import org.codenarc.results.FileResults import org.codenarc.results.Results import org.codenarc.ruleset.RuleSet import org.codenarc.test.AbstractTestCase import org.junit.Before import org.junit.Test import static org.codenarc.test.TestUtil.shouldFail import static org.codenarc.test.TestUtil.shouldFailWithMessageContaining /** * Tests for the CodeNarc Ant Task * * @author Chris Mair */ class CodeNarcTaskTest extends AbstractTestCase { private static final BASE_DIR = 'src/test/resources' private static final RULESET_FILE = 'rulesets/RuleSet1.xml' private static final RULESET_FILES = 'rulesets/RuleSet1.xml,rulesets/RuleSet2.xml' private static final HTML_REPORT_FILE = 'CodeNarcTaskHtmlReport.html' private static final XML_REPORT_FILE = 'CodeNarcTaskXmlReport.xml' private static final RESULTS = new FileResults('path', []) private codeNarcTask private fileSet private project @Test void testMaxViolationsDefaultViolations() { assert codeNarcTask.maxPriority1Violations == Integer.MAX_VALUE assert codeNarcTask.maxPriority2Violations == Integer.MAX_VALUE assert codeNarcTask.maxPriority3Violations == Integer.MAX_VALUE } @Test void testExecute_MaxPriority1Violations() { codeNarcTask.maxPriority1Violations = 10 assertMaxViolations(1, 13) } @Test void testExecute_MaxPriority2Violations() { codeNarcTask.maxPriority2Violations = 10 assertMaxViolations(2, 12) } @Test void testExecute_MaxPriority3Violations() { codeNarcTask.maxPriority3Violations = 10 assertMaxViolations(3, 11) } private void assertMaxViolations(int priority, int numViolations) { codeNarcTask.addFileset(fileSet) def reportWriter = [ writeReport: { ctx, results -> } ] codeNarcTask.reportWriters = [reportWriter] StubSourceAnalyzerCategory.reset() StubSourceAnalyzerCategory.violationCounts[priority] = numViolations use(StubSourceAnalyzerCategory) { def errorMessage = shouldFail(BuildException) { codeNarcTask.execute() } log("errorMessage=$errorMessage") assert errorMessage.contains("p${priority}=${numViolations}") } } @Test void testExecute_CodeNarcProperties() { def analysisContext = null def reportWriter = [ writeReport: { ctx, results -> analysisContext = ctx } ] codeNarcTask.reportWriters = [reportWriter] codeNarcTask.addFileset(fileSet) codeNarcTask.execute() log("rules=${analysisContext.ruleSet.rules}") assert analysisContext.ruleSet.rules[0].priority == 3 } @Test void testExecute_SingleRuleSetFile() { def codeNarcRunner = createAndUseFakeCodeNarcRunner() codeNarcTask.addConfiguredReport(new Report(type:'html', toFile:HTML_REPORT_FILE)) codeNarcTask.addFileset(fileSet) codeNarcTask.execute() assert codeNarcRunner.sourceAnalyzer.class == AntFileSetSourceAnalyzer assert codeNarcRunner.ruleSetFiles == RULESET_FILE assertStandardHtmlReportWriter(codeNarcRunner) } @Test void testExecute_TwoRuleSetFiles() { def codeNarcRunner = createAndUseFakeCodeNarcRunner() codeNarcTask.addConfiguredReport(new Report(type:'html', toFile:HTML_REPORT_FILE)) codeNarcTask.ruleSetFiles = RULESET_FILES codeNarcTask.addFileset(fileSet) codeNarcTask.execute() assert codeNarcRunner.sourceAnalyzer.class == AntFileSetSourceAnalyzer assert codeNarcRunner.ruleSetFiles == RULESET_FILES assertStandardHtmlReportWriter(codeNarcRunner) } @Test void testExecute_TwoFileSets() { def codeNarcRunner = createAndUseFakeCodeNarcRunner() def fileSet2 = new FileSet(dir:new File('/abc'), project:project) codeNarcTask.addConfiguredReport(new Report(type:'html', toFile:HTML_REPORT_FILE)) codeNarcTask.addFileset(fileSet) codeNarcTask.addFileset(fileSet2) codeNarcTask.execute() assert codeNarcRunner.sourceAnalyzer.class == AntFileSetSourceAnalyzer assert codeNarcRunner.sourceAnalyzer.fileSets == [fileSet, fileSet2] assert codeNarcRunner.ruleSetFiles == RULESET_FILE assertStandardHtmlReportWriter(codeNarcRunner) } @Test void testExecute_RuleSetFileDoesNotExist() { codeNarcTask.addConfiguredReport(new Report(type:'html', toFile:HTML_REPORT_FILE)) codeNarcTask.ruleSetFiles = 'DoesNotExist.xml' codeNarcTask.addFileset(fileSet) shouldFailWithMessageContaining('DoesNotExist.xml') { codeNarcTask.execute() } } @Test void testExecute_NullRuleSetFiles() { codeNarcTask.ruleSetFiles = null shouldFailWithMessageContaining('ruleSetFile') { codeNarcTask.execute() } } @Test void testExecute_NullFileSet() { shouldFailWithMessageContaining('fileSet') { codeNarcTask.execute() } } @Test void testAddConfiguredReport() { codeNarcTask.addConfiguredReport(new Report(type:'html', toFile:HTML_REPORT_FILE)) assert codeNarcTask.reportWriters.size() == 1 assert codeNarcTask.reportWriters[0].class == HtmlReportWriter assert codeNarcTask.reportWriters[0].outputFile == HTML_REPORT_FILE assert codeNarcTask.reportWriters[0].title == null } @Test void testAddConfiguredReport_Second() { codeNarcTask.addConfiguredReport(new Report(type:'xml', toFile:XML_REPORT_FILE)) codeNarcTask.addConfiguredReport(new Report(type:'html', toFile:HTML_REPORT_FILE, title:'ABC')) assert codeNarcTask.reportWriters.size() == 2 assert codeNarcTask.reportWriters[0].class == XmlReportWriter assert codeNarcTask.reportWriters[0].outputFile == XML_REPORT_FILE assert codeNarcTask.reportWriters[1].class == HtmlReportWriter assert codeNarcTask.reportWriters[1].outputFile == HTML_REPORT_FILE assert codeNarcTask.reportWriters[1].title == 'ABC' } @Test void testAddConfiguredReport_SpecifyReportWriterClassname() { codeNarcTask.addConfiguredReport(new Report(type:'org.codenarc.report.HtmlReportWriter', toFile:HTML_REPORT_FILE)) assert codeNarcTask.reportWriters.size() == 1 assert codeNarcTask.reportWriters[0].class == HtmlReportWriter assert codeNarcTask.reportWriters[0].outputFile == HTML_REPORT_FILE assert codeNarcTask.reportWriters[0].title == null } @Test void testAddConfiguredReport_NullToFile() { codeNarcTask.addConfiguredReport(new Report(type:'html', title:'ABC')) assert codeNarcTask.reportWriters.size() == 1 assert codeNarcTask.reportWriters[0].title == 'ABC' assert codeNarcTask.reportWriters[0].outputFile == null } @Test void testAddConfiguredReport_InvalidReportType() { shouldFailWithMessageContaining('XXX') { codeNarcTask.addConfiguredReport(new Report(type:'XXX', toFile:HTML_REPORT_FILE)) } } @Test void testAddConfiguredReport_ReportOptionsSetPropertiesOnReportWriter() { def report = createReport('html', [title:'abc', outputFile:'def', maxPriority:'4']) codeNarcTask.addConfiguredReport(report) log(codeNarcTask.reportWriters) assert codeNarcTask.reportWriters[0].title == 'abc' assert codeNarcTask.reportWriters[0].outputFile == 'def' assert codeNarcTask.reportWriters[0].maxPriority == 4 } @Test void testAddFileSet_Null() { shouldFailWithMessageContaining('fileSet') { codeNarcTask.addFileset(null) } } @Before void setUpCodeNarcTaskTest() { project = new Project(basedir:'.') fileSet = new FileSet(dir:new File(BASE_DIR), project:project) fileSet.setIncludes('sourcewithdirs/**/*.groovy') codeNarcTask = new CodeNarcTask(project:project) codeNarcTask.ruleSetFiles = RULESET_FILE } private createAndUseFakeCodeNarcRunner() { def codeNarcRunner = [execute: { RESULTS }] codeNarcTask.createCodeNarcRunner = { codeNarcRunner } codeNarcRunner } private void assertStandardHtmlReportWriter(codeNarcRunner) { assert codeNarcRunner.reportWriters.size == 1 def reportWriter = codeNarcRunner.reportWriters[0] assert reportWriter.class == HtmlReportWriter assert reportWriter.outputFile == HTML_REPORT_FILE } private Report createReport(String type, Map options=null) { def report = new Report(type:type) options?.each { name, value -> report.addConfiguredOption(new ReportOption(name:name, value:value)) } report } } class StubSourceAnalyzerCategory { static violationCounts static void reset() { violationCounts = [1:0, 2:0, 3:0] } static SourceAnalyzer createSourceAnalyzer(CodeNarcTask self) { def results = [getNumberOfViolationsWithPriority:{ p, r -> violationCounts[p] }] as Results [analyze:{ RuleSet ruleSet -> results }, getSourceDirectories:{ [] }] as SourceAnalyzer } } CodeNarc-0.23/src/test/groovy/org/codenarc/ant/CodeNarcTaskAccessor.groovy0000644000175000017500000000250212311373552026122 0ustar ebourgebourg/* * Copyright 2009 the original author or 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 org.codenarc.ant import org.apache.tools.ant.types.FileSet /** * Test-only class for accessing protected members of CodeNarcTask from test classes in other packages * * @author Chris Mair */ class CodeNarcTaskAccessor { private final CodeNarcTask codeNarcTask CodeNarcTaskAccessor(CodeNarcTask codeNarcTask) { assert codeNarcTask this.codeNarcTask = codeNarcTask } String getRuleSetFiles() { codeNarcTask.ruleSetFiles } List getReportWriters() { codeNarcTask.reportWriters } FileSet getFileSet() { codeNarcTask.fileSet } def getRuleSet() { codeNarcTask.ruleSet } } CodeNarc-0.23/src/test/groovy/org/codenarc/ant/ReportTest.groovy0000644000175000017500000000233612041642704024254 0ustar ebourgebourg/* * Copyright 2010 the original author or 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 org.codenarc.ant import org.codenarc.test.AbstractTestCase import org.junit.Test /** * Tests for Report * * @author Chris Mair */ class ReportTest extends AbstractTestCase { private report = new Report() @Test void testAddConfiguredOption_AddsToOptions() { def option = new ReportOption(name:'a', value:'1') report.addConfiguredOption(option) assert report.options == [a:'1'] def option2 = new ReportOption(name:'b', value:'2') report.addConfiguredOption(option2) assert report.options == [a:'1', b:'2'] } } CodeNarc-0.23/src/test/java/0000755000175000017500000000000012623571301015133 5ustar ebourgebourgCodeNarc-0.23/src/test/java/Placeholder.txt0000644000175000017500000000000012464300532020103 0ustar ebourgebourgCodeNarc-0.23/src/assembly/0000755000175000017500000000000012623571301015052 5ustar ebourgebourgCodeNarc-0.23/src/assembly/assembly.xml0000644000175000017500000000416011135773012017414 0ustar ebourgebourg bin tar.gz zip false README.txt / true CHANGELOG* LICENSE* NOTICE* pom.xml target *.jar src true target/site docs apidocs/** css/** images/** *.html samples samples rulesets/** src/** *.bat *.groovy *.xml false runtime lib *:log4j CodeNarc-0.23/pom.xml0000644000175000017500000001541512471221537013773 0ustar ebourgebourg 4.0.0 org.codenarc CodeNarc CodeNarc The CodeNarc project provides a static analysis tool for Groovy code. jar 0.23 http://codenarc.sourceforge.net/ org.sonatype.oss oss-parent 7 1.5 2.1.8 scm:git:git@github.com:CodeNarc/CodeNarc.git scm:git:git@github.com:CodeNarc/CodeNarc.git scm:git:git@github.com:CodeNarc/CodeNarc.git CodeNarc-${project.version} org.codehaus.groovy groovy ${groovyVersion} org.codehaus.groovy groovy-xml ${groovyVersion} org.codehaus.groovy groovy-ant ${groovyVersion} log4j log4j 1.2.14 org.gmetrics GMetrics 0.7 junit junit 4.8.1 org.apache.maven.plugins maven-compiler-plugin 3.1 groovy-eclipse-compiler 1.6 1.6 org.codehaus.groovy groovy-eclipse-compiler 2.8.0-01 org.codehaus.groovy groovy-eclipse-batch 2.1.8-01 org.apache.maven.plugins maven-jar-plugin 2.5 ${project.version} org.apache.maven.plugins maven-javadoc-plugin 2.10.1 attach-javadocs jar maven-assembly-plugin src/assembly/assembly.xml org.apache.maven.plugins maven-release-plugin 2.3.2 org.apache.maven.plugins maven-project-info-reports-plugin 2.7 license org.codehaus.mojo cobertura-maven-plugin 2.2 org.apache.maven.plugins maven-javadoc-plugin 2.10.1 org.apache.maven.plugins maven-pmd-plugin 3.2 chrismair Chris Mair chrismair@users.sourceforge.net https://sourceforge.net/users/chrismair developer -4 Apache 2 http://www.apache.org/licenses/LICENSE-2.0.txt repo CodeNarc-0.23/LICENSE.txt0000644000175000017500000002644611325102210014266 0ustar ebourgebourg Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. CodeNarc-0.23/CHANGELOG.txt0000644000175000017500000032564612470773462014530 0ustar ebourgebourgCodeNarc Change Log ------------------------------------------------------------------------------- http://www.codenarc.org Changes in version 0.23 (Feb 2015) -------------------------------------- NEW RULES - #73: NestedForLoop rule (design) - Checks for nested for loops. (Thanks to Maciej Ziarko) - #80: ParameterCount rule (size) - Checks if the number of parameters in method/constructor exceeds the number of parameters specified by the maxParameters property. (Thanks to Maciej Ziarko) UPDATED/ENHANCED RULES AND BUG FIXES - #69: PrivateFieldCouldBeFinal rule support for JPA entities. (Thanks to Maciej Ziarko) - #70: GStringExpressionWithinString rule should ignore quasi GString expressions inside annotations. (Thanks to Maciej Ziarko) - #76: SpaceAfterClosingBrace and SpaceBeforeOpeningBrace rules: GStrings with embedded closures incorrectly cause violations. (Thanks to Maciej Ziarko) - #59: SpaceAfterClosingBrace false violation if string contains closing brace. (fixed by #76) - #79: JUnitTestMethodWithoutAssert support for JUnit's ExpectedException way to verify exceptions. (Thanks to Maciej Ziarko) - #66: SpaceAfterComma rule doesn't check constructor calls or constructor declarations. - #82: IdeTextReportWriter violation link (loc=..) does not work in Eclipse. - #81: XML Report: Escape illegal XML characters within the source line or message. - #84: XML Report: Remove illegal (non-escapable) XML characters from the source line or message. - #88: UseAssertTrueInsteadOfAssertEquals: Only check assert statements if checkAssertStatements property is true; defaults to false. FRAMEWORK AND INFRASTRUCTURE - #86: Upgrade to Groovy 2.x. (>= 2.1.0) [BREAKING CHANGE] - #67: Don't depend on groovy-all jar, but only on the specifically required groovy artifacts. - #68: Cleaned up and fixed HtmlReportWriterTest. - #74: Improved codenarc.groovy to remove Rule suffix from rule name. (Thanks to Maciej Ziarko) - #87: Switch pom.xml to use Groovy-Eclipse Compiler. - #83: HtmlReportWriter: Optionally skip violation summary by package. Add includeSummaryByPackage property; defaults to true. Changes in version 0.22 (Oct 2014) -------------------------------------- NEW RULES - #56: PackageMatchesFilePath rule (naming) - A package source file's path should match the package itself. (Thanks to Simon Tost) - #150: Instanceof rule (design) - Checks for use of the instanceof operator. Use ignoreTypeNames property to configure ignored type names. - #423: UnnecessarySafeNavigationOperator rule (unnecessary) - Check for the safe navigation operator (?.) applied to constants and literals, which can never be null. - #63: NoDef rule (convention) - Check for all uses of the def keyword. (Thanks to Dominik Przybysz) UPDATED/ENHANCED RULES AND BUG FIXES - #157: Enable optionally using Thread Context classpath for loading rule scripts. Introduce "codenarc.useCurrentThreadContextClassLoader" system property. See https://jira.grails.org/browse/GPCODENARC-32. - #55: FieldName rule - Add private static final field name regex. (Thanks to Dominik Przybysz) - #54: Invalid Cast to BigDecimal. In an XML ruleset or "codenarc.properties", specifying a BigDecimal property value throws an exception. - #51: CodeNarc command-line runner always returns 0, even for failure/error. Now return exit status of 1 for all errors. - #58: SpaceBeforeOpeningBrace rule: Allow for opening parenthesis before opening brace. (Thanks to Dominik Przybysz) - #158 SpaceAfterClosingBrace rule: allow semicolons following closing brace. - #155: SpaceAroundMapEntryColon rule: Using spread map operator (*:) causes to fail with ArrayIndexOutOfBoundsException - #154: Line numbers for violations of TrailingWhitespace rule are 0-based. Same for IllegalRegex rule. Fix AbstractSourceCode.getLineNumberForCharacterIndex() to be 1-based. - #159: ToStringReturnsNullRule: throws "No signature of method handleClosure()" exception if toString() contains a Closure. - #53: SpockIgnoreRestUsed not working in tests extending a class that descends from Specification. Add specificationSuperclassNames and specificationClassNames properties. - #160: PackageName rule: Fix to allow package name containing numbers in first part, e.g. "t3". Change package name regex to /[a-z]+[a-z0-9]*(\.[a-z0-9]+)*/. - #161: ReturnNullFromCatchBlock: Reports return statement from within a void method. Add boolean shouldVisitMethod(MethodNode node) to AbstractAstVisitor. - #62: GrailsDuplicateConstraint: consider importFrom includes: constraints when checking for duplicate constraint violations. (Thanks to Dan Tanner) - #64: SpaceAfterOpeningBrace and SpaceBeforeClosingBrace rules: Add ignoreEmptyBlock property to allow no spaces between braces for empty blocks. (Thanks to Dominik Przybysz) - #65: HtmlReportWriter and TextReportWriter do not properly parse the maxPriority report option. - #34: BooleanMethodReturnsNullRule should not flag methods that return other non-null and non-boolean types. FRAMEWORK AND INFRASTRUCTURE - #435: IdeTextReportWriter: Text report formatter that includes automatic IDE (Eclipse/Idea) hyperlinks to source code. Provide new "ide" report type in ReportWriterFactory. - #157: Enable optionally using Thread Context classloader. Also see GPCODENARC-32. Introduce codenarc.useCurrentThreadContextClassLoader system property. Changes in version 0.21 (April 2014) ------------------------------------------- NEW RULES - #30: GrailsMassAssignment rule (grails) - Checks for mass assignment from a params Map within Grails domain classes. (Thanks to Brian Soby) - #38: NoWildcardImports rule (imports) - Wildcard imports, static or otherwise, should not be used. (Thanks to Kyle Boon) - #41: ConsecutiveBlankLines rule (formatting) - Makes sure there are no consecutive lines that are either blank or whitespace only. (Thanks to Joe Sondow) - #42: BlankLineBeforePackage rule (formatting) - Makes sure there are no blank lines before the package declaration of a source code file. (Thanks to Joe Sondow) - #43: FileEndsWithoutNewline rule (formatting) - Makes sure the source code file ends with a newline character. (Thanks to Joe Sondow) - #44: MissingBlankLineAfterImports rule (formatting) - Makes sure there is a blank line after the imports of a source code file. (Thanks to Joe Sondow) - #46: MissingBlankLineAfterPackage rule (formatting) - Makes sure there is a blank line after the package statement of a source code file. (Thanks to Joe Sondow) - #47: TrailingWhitespaceRule (formatting) - Checks that no lines of source code end with whitespace characters. (Thanks to Joe Sondow) - #411: ExceptionExtendsThrowable rule (exceptions) - Checks for classes that extend Throwable. Custom exception classes should subclass Exception or one of its descendants. - #341: UnnecessaryCast rule (unnecessary) - Checks for unnecessary cast operations. - #149: IllegalSubclass rule (generic) - Checks for classes that extend one of the specified set of illegal superclasses. - #157: UnnecessaryToString rule (unnecessary) - Checks for unnecessary calls to toString(). - #152: JUnitPublicProperty rule (junit) - Checks for public properties defined on JUnit test classes. - #422: ToStringReturnsNull rule (design) - Checks for toString() methods that return null. - #143: MultipleUnaryOperators rule (basic) - Checks for multiple consecutive unary operators. UPDATED/ENHANCED RULES AND BUG FIXES - #31: UnusedImportRule: Extended to now also detect cases where the imported class name occurs as a substring in the source code. (Thanks to René Scheibe) - #36: UnnecessaryDefInMethodDeclaration: Prevent false positives from modifiers within quoted method name. (Thanks to René Scheibe) - #37: LineLengthRule: Flags to ignore import and package statements line length. (Thanks to Kyle Boon) - #35: UnnecessaryPackageReferenceRule: raises confusing violation for Script with package. - #48: Fix Method chaining breaks SpaceAfterComma. - #49: Fix SpaceBeforeOpeningBrace doesn't work on switch statements. - #50: Fix UnnecessaryDotClass doesn't work if class is qualified - #153: Fix ClosureStatementOnOpeningLineOfMultipleLineClosure does not catch multiline closure with only a single statement. Changes in version 0.20 (Dec 2013) ------------------------------------------- NEW RULES - #425: LocaleSetDefault rule (design) - Checks for calls to Locale.setDefault(), which sets the Locale across the entire JVM. (Thanks to Ming Huang and Rob Patrick) - #114: IllegalString rule (generic) - Checks for a specified illegal string within the source code. - #430: SpaceAroundMapEntryColon rule (formatting) - Check for proper formatting of whitespace around ':' for literal Map entries. - #427: ClosureStatementOnOpeningLineOfMultipleLineClosure rule (formatting) - Checks for closure logic on first line (after ->) for a multi-line closure. UPDATED/ENHANCED RULES - #426: Disable GrailsPublicControllerMethod by default. - #424: Expand SpaceAroundOperator rule to also check for "as" operator. - #432: Add checkLastStatementImplicitElse property on IfStatementCouldBeTernary and UnnecessaryIfStatement. BUG FIXES - #409: Fix bug ClassNameSameAsFilenameRule when sourceCode.name is null. - #22: Fix DuplicateStringLiteral: Allow empty strings within ignoreStrings. (Thanks to Ei Kageyama) - #21: Fix ClassJavadoc rule has no effect. Also ignore blank lines between javadoc and class declaration. - #143: Fix UnsafeImplementationAsMap - duplicate violation. - #135: Fix CoupledTestCase incorrectly thrown when referencing the current class. - #24: Enable Groovy ruleset to find custom rules (pass the current ClassLoader to the GroovyShell). (Thanks John Engelman) - #26: Fix MissingMethodException error on custom rule with recent Groovy. (Thanks to Joe Sondow) - #146: Fix SpaceAroundOperator: Does not catch some violations with elvis operator (?:) - #139: Fix JUnitPublicField to ignore interfaces. FRAMEWORK AND INFRASTRUCTURE - #23: Inline violations support within rule tests. (Thanks to Artur Gajowy) - #428: Use ClassNode if present in ImportNode to get line number and possibly source text - #431: Remove unused "samples" folder. - #434: Remove duplicate logging of CodeNarc results. - #433: Rename BaseSourceAnalyzer to AbstractSourceAnalyzer. Changes in version 0.19 (Jul 2013) ------------------------------------------- - #349: New EmptyClass rule (basic) - Reports classes without methods, fields or properties. Why would you need a class like this? - #409: New ClassNameSameAsFilename rule (naming) - Reports files containing only one top level class / enum / interface which is named differently than the file. - #214: New ThisReferenceEscapesConstructor rule (concurrency) - Reports constructors passing the 'this' reference to other methods. Thanks to Artur Gajowy. (pull request #15) - #340: New GrailsDomainReservedSqlKeywordName rule (grails) - Check for Grails domain class with class or field name which is a reserved SQL keyword. Thanks to Artur Gajowy. (pull request #13) - #339: New GrailsDomainWithServiceReference rule (grails) - Check for Grails domain class with reference to service class (field). Thanks to Artur Gajowy. (pull request #12) - #382: New JUnitPublicField rule (junit) - There is usually no reason to have a public field (even a constant) on a test class. - #407: New GStringExpressionWithinString rule (groovyism) - Check for regular (single quote) strings containing a GString-type expression (${..}). - #417: New IllegalClassMember rule (generic) - Checks for classes containing fields/properties/methods matching configured illegal member modifiers or not matching any of the configured allowed member modifiers. - #412: New EnumCustomSerializationIgnored rule (serialization) - Checks for enums that define writeObject() or writeReplace() methods, or declare serialPersistentFields or serialVersionUID fields, all of which are ignored for enums. - #421: SpaceAroundClosureArrow rule (formatting) - Checks that there is whitespace around the closure arrow (->) symbol New "Enhanced Classpath" Ruleset: These rules require application classes on CodeNarc's classpath: - #329: New UnsafeImplementationAsMap rule - Reports incomplete interface implementations created by map-to-interface coercions. By default, this rule does not apply to test files. Thanks to Artur Gajowy. (pull request #14) - #364: New CloneWithoutCloneable rule - The method clone() should only be declared if the class implements the Cloneable interface. Thanks to Artur Gajowy. (pull request #14) - #278: New JUnitAssertEqualsConstantActualValue rule - Reports usages of org.junit.Assert.assertEquals([message,] expected, actual) where the 'actual' parameter is a constant or a literal. Most likely it was intended to be the 'expected' value. UPDATED/ENHANCED RULES - #371: CouldBeElvis rule. Added support for IF statements without braces. - #408: SerialVersionUID rule: Also check that serialVersionUID field is declared private. - #414: Extend UnnecessaryIfStatement rule: if (condition){ return true }; return false. - #415: Extend IfStatementCouldBeTernary rule: if (condition) { return 1 }; return 2. - #416: Enhance JUnitAssertAlwaysSucceeds and JUnitAssertAlwaysFails to catch String or number constant or List or Map literal passed in as condition parameter; and add support for checking assertNotNull(). BUG FIXES - Fix bug in UnnecessaryDefInFieldDeclarationRule making it report false positives with 'def' on right hand side of assignment - #135: CoupledTestCase incorrect violation when referencing the current class. - #19: Fix BracesForMethod rule for single-line methods. - #20: HTML Report Anchor Fix. Thanks to Jeff Beck. - #137: Mistake in ExplicitHashSetInstantiationRule violation message. - #138: SpaceAroundOperators: Add violation for isEcpr?processRecords(records[0]):'' FRAMEWORK AND INFRASTRUCTURE - Added support for per-rule custom compilation phase, allowing for more type information in AST when required. NOTE: New rules that use a later compilation phase require that CodeNarc have the application classes being analyzed on the classpath. This adds a new int getCompilerPhase() method to Rule. Thanks to Artur Gajowy. (pull request #14) - #419: Add maxPriority property to HTML and Text ReportWriters - filter out lower priority violations. Changes in version 0.18.1 (Feb 2013) ------------------------------------------- BUG FIXES - Fix #3596256: SpaceAroundOperatorRule: False positive if source line contains unicode chars. Also affects (known limitation): SpaceAfterClosingBrace, SpaceBeforeOpeningBrace, SpaceBeforeClosingBrace - Known limitation: will not catch violations on same line following unicode char literal. - Fix #3598154: SpaceAroundOperator: bad/duplicate violation for ?: after closure. Ignore standalone elvis expression statements (known limitation). - Fix #3598717: BracesForClassRule failing on annotation types. (Known limitation: ignore for @interface). Thanks to Marcin Gryszko. - Fix #3598732: BracesForMethodRule fixed for methods with closure parameters. Thanks to Marcin Gryszko. - Fix #3596323: BracesForClassRule ignored for enums and Groovy 1.7. Thanks to Marcin Gryszko. - Fix for CodeNarc GitHub issue #10: No such property: maxMethodComplexity for class: org.codenarc.rule.size.AbcMetricRule. - Fix #3604095: AssignCollectionSort ignore calls that pass in mutate=false; add checks for two-arg calls. - Fix #3603257: UnusedVariable reported for variable used in (more than one) for loop. Changes in version 0.18 (Dec 2012 ) ------------------------------------------- NEW RULES - #3531554: New JUnitLostTest rule. Checks for classes that import JUnit 4 classes and contain a public, instance, void, no-arg method named test* that is not annotated with @Test. - #3509530: New SpaceAfterComma rule. Checks that there is at least one space or whitespace following each comma. That includes checks for method and closure declaration parameter lists, method call parameter lists, Map literals and List literals. - #3583257: New SpaceAfterSemicolon rule. Checks that there is at least one space or whitespace following a semicolon that separates classic for loop clauses and also multiple statements per line. - #3509532: New SpaceAroundOperator rule. Check that there is at least one space (blank) or whitespace around each binary operator, including: +, -, *, /, >>, <<, &&, ||, &, |, ?:, =. - #3583262: New SpaceBeforeOpeningBrace rule. Check that there is at least one space (blank) or whitespace before each opening brace ("{"). This checks method/class/interface declarations, closure expressions and block statements. - #3583262: New SpaceAfterOpeningBrace rule. Check that there is at least one space (blank) or whitespace after each opening brace ("{"). This checks method/class/interface declarations, closure expressions and block statements. - #3583262: New SpaceAfterClosingBrace rule. Check that there is at least one space (blank) or whitespace after each closing brace ("}"). This checks method/class/interface declarations, closure expressions and block statements. - #3583262: New SpaceBeforeClosingBrace rule. Check that there is at least one space (blank) or whitespace before each closing brace ("}"). This checks method/class/interface declarations, closure expressions and block statements. - #3589701: New SpaceAfterIf rule. Check that there is exactly one space (blank) after the if keyword and before the opening parenthesis. - #3589701: New SpaceAfterWhile rule. Check that there is exactly one space (blank) after the while keyword and before the opening parenthesis. - #3589701: New SpaceAfterFor rule. Check that there is exactly one space (blank) after the for keyword and before the opening parenthesis. - #3589701: New SpaceAfterSwitch rule. Check that there is exactly one space (blank) after the switch keyword and before the opening parenthesis. - #3589701: New SpaceAfterCatch rule. Check that there is exactly one space (blank) after the catch keyword and before the opening parenthesis. - #3581377: New JUnitUnnecessaryThrowsException rule. Check for throws clauses on JUnit test methods. That is not necessary in Groovy. - #3575859: New GrailsDuplicateMapping rule. Check for duplicate entry in a domain class mapping. - #3575861: New GrailsDuplicateConstraint rule. Check for duplicate constraints entry - #3592678: New IfStatementCouldBeTernary rule - Checks for if statements where both the if and else blocks contain only a single return statement with a value - #3581378: New ExceptionNotThrown rule - Checks for an exception constructor call without a throw as the last statement within a catch block. UPDATED/ENHANCED RULES - Pull request #2: Adding support for catch, finally, and else brace placement validation. Thanks to Matias Bjarland. - #3521130: PrintStackTrace: Also check for StackTraceUtils.printSanitizedStackTrace(). - #3589971: Add threshold for max class metric value for CyclomaticComplexity, AbcMetric and CrapMetric. - #3574257: Rename AbcComplexity rule to AbcMetric. Deprecate old AbcComplexity rule and set enabled=false. Rename properties, e.g. maxMethodAbcScore. - Pull request #5: Enhanced UnusedVariableRule to enable ignoring some variables (ignoreVariableNames). Thanks to René Scheibe. BUG FIXES - Fix #3555096: UnusedPrivateMethod - StringIndexOutOfBoundsException for zero-length method name. - Fix #3524882: False positive UnnecessaryPackageReference violation for Enums. - Fix #3558623: UnnecessarySemicolon - violations inside classes were ignored. Thanks to Marcin Erdmann. - Fix #3574259: CyclomaticComplexity, CrapMetric and AbcComplexity: Do not check class-level metric value if maxClassAverageMethodXX value is null or 0. - Fix #3526749: The FieldName rule should ignore serialVersionUID fields by default. - Fix #3543848: Online docs; formatting on Naming rules doc. - Fix #3441842: Online docs; UnnecessarySubstring documentation is misleading. - Fix #3511004: PrivateFieldCouldBeFinal false positive (-- and ++ operators). - Fix Pull request #4: parseReport doesn't work with absolute paths on windows. Thanks to Gavin Matthews. FRAMEWORK AND INFRASTRUCTURE - #3546737: Migrate source code from Subversion to GitHub. Many thanks to Marcin Erdmann. - #3578372: Add notes to rule index and sample rule sets that ABC/CC rules require the GMetrics jar. - #3578909: Move helper methods from AbstractTestCase into new TestUtil class (to enable use by other test frameworks, e.g. Spock) - #3578909: Upgrade tests and test framework to JUnit 4. - #3578909: Move test framework classes into src/main/groovy, so that they are included in the CodeNarc jar: AbstractTestCase, InMemoryAppender, TestUtil, AbstractRuleTestCase, StubRule - Switch to Sonatype OSS Maven Repository Changes in version 0.17 (March 2012) ------------------------------------------- NEW RULES - #3433042: New PrivateFieldCouldBeFinal rule: Checks for private fields that are only set within a constructor or field initializer. Such fields can safely be made final. - #3432991: New ParameterReassignment rule: Checks for a method or closure parameter being reassigned to a new value within the body of the method/closure, which is a confusing, bad practice. Use a temporary variable instead. - #3108331: New TernaryCouldBeElvis rule: Checks for ternary with boolean and true expressions are the same; can be simplified to an Elvis expression. - #3489801: New AssertWithinFinallyBlock rule: Checks for assert statements within a finally block. An assert can throw an exception, hiding the original exception, if there is one. - #3489800: New ConstantAssertExpression rule: Checks for assert statements where the assert condition expressions is a constant value or literal value. - #3161693: New BrokenNullCheck rule: Looks for faulty checks for null that can cause a NullPointerException. - #3495466: New VectorIsObsolete rule: Checks for references to the (effectively) obsolete java.util.Vector class. Use the Java Collections Framework classes instead including ArrayList or Collections.synchronizedList(). - #3495466: New HashtableIsObsolete rule: Checks for references to the (effectively) obsolete java.util.Hashtable class. Use the Java Collections Framework classes instead including HashMap or ConcurrentHashMap. - #3485545: New CrapMetric rule: Checks the CRAP metric score for methods. This metric is based on the cyclomatic complexity and test coverage for individual methods. Requires a Cobertura XML coverage file and GMetrics 0.5. UPDATED/ENHANCED RULES - #3476844: Extend GetterMethodCouldBeProperty to also check static getter methods. - #3477351: UnnecessaryConstructor: Also catch constructor containing only call to super(). - #3460463: StatelessClassRule and GrailsStatelessServiceRule: Ignore fields annotated with @Inject. - #3460463: GrailsStatelessServiceRule: Ignore non-static properties (i.e., no visibility modifier specified) declared with "def". - #3485544: AssignmentInConditional: Also catch nested binary expressions, e.g. if (x==1 || x=3) - #3488705: GrailsDomainHasToString: Ignore classes annotated with @ToString or @Canonical. - #3488704: GrailsDomainHasEquals: Ignore classes annotated with @EqualsAndHashCode or @Canonical. - #3501349: UnnecessaryPackageReference: Also check for explicitly-imported classes. - #3509542: UnnecessaryPackageReference: Also check for package references in "as ". BUG FIXES - #3463408: Remove dependency on Java 1.6 (String.isEmpty()). - #3475170: Fix duplicate violations for SimpleDateFormatMissingLocale. - #3477085. Fix UnusedImport violations missing line numbers for imports with semicolons. - #3477162: Fix duplicate violations for UnnecessaryDotClass. - #3487448: Fix UnnecessaryNullCheckBeforeInstanceOf should also check standalone binary (boolean) expressions, e.g. boolean ready = x != null && x instanceof Integer - #3496557: Fix UseCollectNestedRule: GroovyCastException: Cannot cast object VariableExpression to class ClosureExpression - #3496696: Fix UnusedPrivateFieldRule: GroovyCastException: Cannot cast object with class 'org.codehaus.groovy.ast.FieldNode' to class 'groovy.lang.MetaClass'. FRAMEWORK AND INFRASTRUCTURE - #3495841: Support Groovy 2.x. - #3496463: Support GMetrics 0.5. - #3476394: Include PMD report in project reports; Fix/resolve violations. - Introduce AbstractSharedAstVisitorRule. Refactor UnusedPrivateFieldRule and UnusedPrivateMethodRule to use it. - Add exists() method to org.codenarc.util.io.Resource and implementations Changes in version 0.16.1 (November 2011) ------------------------------------------- - Fix #3436461: StackOverflowError when running CodeNarc with a Groovy 1.8 runtime. Use ClassCodeVisitorSupportHack for all AstVisitor classes. This is a workaround for a known groovy issue: http://jira.codehaus.org/browse/GROOVY-4922 Changes in version 0.16 (November 2011) ------------------------------------------- NEW FEATURES - Performance Improvements (3394481) - There are big performance improvements in this release. - Upgrade to GMetrics 0.4. (3424121) - This upgrade is optional for users, but may provide performance improvements. - Rule Index page: Rule name is now a link to the rule description web page. (3434063) NEW AND UPDATED RULES - @SuppressWarnings Support - The support for @SuppressWarnings was redesigned so that it is more reliable. @SuppressWarnings no works on *all* rules at the Class, Field, and Method level. - CouldBeElvis rule (convention) - Catch an if block that could be written as an elvis expression. - LongLiteralWithLowerCaseL rule (convention) - In Java and Groovy, you can specify long literals with the L or l character, for instance 55L or 24l. It is best practice to always use an uppercase L and never a lowercase l. This is because 11l rendered in some fonts may look like 111 instead of 11L. - ConfusingMultipleReturns rule (groovyism) - Multiple return values can be used to set several variables at once. To use multiple return values, the left hand side of the assignment must be enclosed in parenthesis. If not, then you are not using multiple return values, you're only assigning the last element. - GetterMethodCouldBeProperty rule (groovyism) - If a class defines a public method that follows the Java getter notation, and returns a constant, then it is cleaner to provide a Groovy property for the value rather than a Groovy method. - UnnecessaryDefInMethodDeclaration rule (unnecessary) - 3176230 - Rule now catches when you try to add the def keyword to constructor declarations. Also expanded to catch more instances of in method declarations with explicit return types. - UnnecessaryDefInFieldDeclaration rule (unnecessary) - If a field has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance, 'static def constraints = {}' is redundant and can be simplified to 'static constraints = {}. - UnnecessaryDefInVariableDeclaration rule (unnecessary) - Expanded rule to catch more instances of unneeded defs. - UnusedMethodParameter rule (unused) - This rule finds instances of method parameters not being used. It does not analyze private methods (that is done by the UnusedPrivateMethodParameter rule) or methods marked @Override. - BuilderMethodWithSideEffects rule (design) - 3408045 - A builder method is defined as one that creates objects. As such, they should never be of void return type. If a method is named build, create, or make, then it should always return a value. - MisorderedStaticImportRule - 3392892 - The rule now allows you to specify that static imports come after the other imports, not just before. This rule has one property comesBefore, which defaults to true. If you like your static imports to come after the others, then set this property to false. - FactoryMethodName rule (naming) - A factory method is a method that creates objects, and they are typically named either buildFoo(), makeFoo(), or createFoo(). This rule enforces that only one naming convention is used. It defaults to makeFoo(), but that can be changed using the property 'regex'. - UseCollectMany rule (groovyism) - 3411722 - In many case collectMany() yields the same result as collect{}.flatten. It is easier to understand and more clearly conveys the intent. - CollectAllIsDeprecated rule (groovyism) - 3411724 - collectAll is deprecated since Groovy 1.8.1. Use collectNested instead - UseCollectNested rule (groovyism) - 3411724 - Instead of nested collect{}-calls use collectNested{} - DuplicateMapLiteral (dry) - 3413600 - Check for multiple instances of the same Map literal; limited to Maps where the keys and values are all constants or literals. - DuplicateListLiteral (dry) - 3413601 - Check for multiple instances of the same List literal; limited to Lists where the values are all constants or literals. BUG FIXES - #3393179: Fix for JUnitPublicNonTestMethod reporting violations for public non-test methods that are annotated @Override - #3394313: Fixed UnusedPrivateField to honor the @SuppressWarnings annotation. - #3397468: Fixed CyclomaticComplexity rule to honor the @SuppressWarnings annotation. - #3392768: The UnnecessaryDefInVariableDeclaration no longer checks fields. That work is done in the UnnecessaryDefInFieldDeclaration rule. - #3401516: Fixed FinalClassWithProtectedMember to ignore methods with @Override - #3408106: Fixed UnnecessaryDefInMethod to ignore parameters that have the def keyword - #3393184: Fixed ExplicitCallToEqualsMethod to suggest a better rewrite, which works better with negation - #3408108: Fixed UnnecessaryDefInMethodDeclaration to not flag generic methods with a required def as an error - #3410261: Fixed UnusedImport - confuses import of similar class names - #3408440: Fixed UnnecessaryObjectReferences rule to not track references across methods. - #3393144: Fixed unnecessaryObjectReferences rule to not track references across fields. - #3394312: Fixed UnusedPrivateField rule to search for usages based on super class references. - #3423987: BracesFor* rules should not produce violations if there are no braces. - #3429658: False positive for UnusedPrivateMethod rule - #3387422: ClosureAsLastMethodParameter - false positive BREAKING CHANGES *** The HardcodedWindowsRootDirectory has been renamed to HardCodedWindowsRootDirectory. (#3433741) *** Major Reorganization of the "Basic" RuleSet. (#3432475) This included moving several rules from the "Basic" ruleset to other rulesets, as well as adding two new rulesets: 1. "Groovyism" - Groovy idiomatic usage, and Groovy-specific bad practices 2. "Convention" - Coding conventions; not typically errors. The following rules were moved out of the "Basic" ruleset: - AddEmptyString (unnecessary) - AssignCollectionSort (groovyism) - AssignCollectionUnique (groovyism) - BooleanMethodReturnsNull (design) - CloneableWithoutClone (design) - ClosureAsLastMethodParameter (groovyism) - CollectAllIsDeprecated (groovyism) - CompareToWithoutComparable (design) - ConfusingMultipleReturns (groovyism) - ConfusingTernary (convention) - ConsecutiveLiteralAppends (unnecessary) - ConsecutiveStringConcatenation (unnecessary) - CouldBeElvis (convention) - ExplicitArrayListInstantiation (groovyism) - ExplicitCallToAndMethod (groovyism) - ExplicitCallToCompareToMethod (groovyism) - ExplicitCallToDivMethod (groovyism) - ExplicitCallToEqualsMethod (groovyism) - ExplicitCallToGetAtMethod (groovyism) - ExplicitCallToLeftShiftMethod (groovyism) - ExplicitCallToMinusMethod (groovyism) - ExplicitCallToModMethod (groovyism) - ExplicitCallToMultiplyMethod (groovyism) - ExplicitCallToOrMethod (groovyism) - ExplicitCallToPlusMethod (groovyism) - ExplicitCallToPowerMethod (groovyism) - ExplicitCallToRightShiftMethod (groovyism) - ExplicitCallToXorMethod (groovyism) - ExplicitHashMapInstantiation (groovyism) - ExplicitHashSetInstantiation (groovyism) - ExplicitLinkedHashMapInstantiation (groovyism) - ExplicitLinkedListInstantiation (groovyism) - ExplicitStackInstantiation (groovyism) - ExplicitTreeSetInstantiation (groovyism) - GStringAsMapKey (groovyism) - GroovyLangImmutable (groovyism) - InvertedIfElse (convention) - LongLiteralWithLowerCaseL (convention) - ReturnsNullInsteadOfEmptyArray (design) - ReturnsNullInsteadOfEmptyCollection (design) - SimpleDateFormatMissingLocale (design) - UseCollectMany (groovyism) - UseCollectNested (groovyism) The ruleset parser classes have been modified to print a helpful error message for moved and renamed rules (see MovedRules helper class). *** In a previous version, method names on AbstractAstVisitor were changed to add @SuppressWarnings support. visitField became visitFieldEx, visitProperty became visitPropertyEx, and visitConstructor became visitConstructorEx. These were changed back to the default names used by Groovy visitors. THANKS - Thanks to the Groovy Users of Minnesota for the CouldBeElvis rule. Thanks Jeff Beck, Doug Sabers, Ryan Applegate, and Mike Minner. - Thanks to Joachim Baumann for UseCollectMany, CollectAllIsDeprecated, UseCollectNested. Changes in version 0.15 (August 2011) ------------------------------------------- NEW AND UPDATED RULES - UnnecessaryDefInVariableDeclaration rule (unnecessary) - If a variable has a visibility modifier or a type declaration, then the def keyword is unneeded. For instance 'def private n = 2' is redundant and can be simplified to 'private n = 2'. - UnnecessaryDefInMethodDeclaration rule (unnecessary) - Added more checked modifiers: final, synchronized, abstract, strictfp. Multiple method declarations in a single line are handled correctly. - AssignCollectionUnique rule (basic) - The Collections.unique() method mutates the list and returns the list as a value. If you are assigning the result of unique() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. - AssignCollectionSort rule (basic) - The Collections.sort() method mutates the list and returns the list as a value. If you are assigning the result of sort() to a variable, then you probably don't realize that you're also modifying the original list as well. This is frequently the cause of subtle bugs. - UnnecessaryDotClass rule (unnecessary) - To make a reference to a class, it is unnecessary to specify the '.class' identifier. For instance String.class can be shortened to String. - BitwiseOperatorInConditional rule (basic) - Checks for bitwise operations in conditionals, if you need to do a bitwise operation then it is best practive to extract a temp variable. - UnnecessaryInstanceOfCheck rule (unnecessary) - This rule finds instanceof checks that cannot possibly evaluate to true. For instance, checking that (!variable instanceof String) will never be true because the result of a not expression is always a boolean. - UnnecessarySubstring rule (unnecessary) - This rule finds usages of String.substring(int) and String.substring(int, int) that can be replaced by use of the subscript operator. For instance, var.substring(5) can be replaced with var[5..-1]. - HardcodedWindowsRootDirectory rule (basic) - This rule find cases where a File object is constructed with a windows-based path. This is not portable, and using the File.listRoots() method is a better alternative. - HardCodedWindowsFileSeparator rule (basic) - This rule finds usages of a Windows file separator within the constructor call of a File object. It is better to use the Unix file separator or use the File.separator constant. - RandomDoubleCoercedToZero rule (basic) - The Math.random() method returns a double result greater than or equal to 0.0 and less than 1.0. If you coerce this result into an Integer or int, then it is coerced to zero. Casting the result to int, or assigning it to an int field is probably a bug. - BracesForClass rule (formatting) - Checks the location of the opening brace ({) for classes. By default, requires them on the same line, but the sameLine property can be set to false to override this. - LineLength rule (formatting) - Checks the maximum length for each line of source code. It checks for number of characters, so lines that include tabs may appear longer than the allowed number when viewing the file. The maximum line length can be configured by setting the length property, which defaults to 120. - GrailsDomainHasToString rule (grails) - Checks that Grails domain classes redefine toString() - GrailsDomainHasEquals rule (grails) - Checks that Grails domain classes redefine equals(). - BracesForForLoop rule (formatting) - Checks the location of the opening brace ({) for for loops. By default, requires them on the same line, but the sameLine property can be set to false to override this. - BracesForIfElse rule (formatting) - Checks the location of the opening brace ({) for if statements. By default, requires them on the same line, but the sameLine property can be set to false to override this. - BracesForMethod rule (formatting) - Checks the location of the opening brace ({) for constructors and methods. By default, requires them on the same line, but the sameLine property can be set to false to override this. - BracesForTryCatchFinally rule (formatting) - Checks the location of the opening brace ({) for try statements. By default, requires them on the line, but the sameLine property can be set to false to override this. - ClassJavadoc rule (formatting) - Makes sure each class and interface definition is preceded by javadoc. Enum definitions are not checked, due to strange behavior in the Groovy AST. - JdbcConnectionReference rule (jdbc) - Check for direct use of java.sql.Connection, which is discouraged and almost never necessary in application code. - JdbcResultSetReference rule (jdbc) - Check for direct use of java.sql.ResultSet, which is not necessary if using the Groovy Sql facility or an ORM framework such as Hibernate. - JdbcStatementReference rule (jdbc) - Check for direct use of java.sql.Statement, java.sql.PreparedStatement, or java.sql.CallableStatement, which is not necessary if using the Groovy Sql facility or an ORM framework such as Hibernate. - IllegalClassReference rule (generic) - Checks for reference to any of the classes configured in classNames. BUG FIXES and NEW FEATURES - #3325147: Fix for running CodeNarc with a Groovy 1.8 runtime. There should no longer be StackOverflowExceptions. - #3317632: CloneableWithoutClone - false positive. - #3315990: StaticXxxField false positive on initializer: StaticSimpleDateFormatField, StaticDateFormatField, StaticCalendarField. - #3314773: UnnecessaryGroovyImportRule: false positive on static imports - #3315992: ClosureAsLastMethodParameter - false positive, when method call surrounded by parentheses. - #3307699: Fixed a typo and made some "Violation" strings lowercase, so the log messages are consistent. (Fixed by René Scheibe) - #3315946: Cmdline runner does not respect -includes and -excludes. (Fixed by René Scheibe) - #3314576: UnnecessaryPublicModifierRule: MissingPropertyException. (Fixed by René Scheibe) - #3322395: JUnitTestMethodWithoutAssert - Added support for parameters in the @Test annotation. E.g.: @Test(expected = IllegalArgumentException) and @Test(timeout = 1000). (Fixed by René Scheibe) - #3310381: Added test for all rules (in AbstractRuleTestCase) to verify that any values specified for (doNot)applyToFilesMatching are valid regular expressions. - #3325049: Change StatelessClassRule (generic) to require applyToClassNames, applyToFileNames or applyToFilesMatching to be configured. - #3361263: IllegalPackageReferenceRule: Also check constructor parameter types and type coercion (x as Type). - #3315991: Unnecessary*Instantiation (including UnnecessaryBigDecimalInstantiation): Duplicate violations. - #3351964: Include rules w/ priority > 4 in HTML report. Add getViolations() to Results interface. - #3375718: UnusedPrivateField: Recognize references to static fields through the class name. - #3380494: Automatically create report output folders. - #3376518: UnnecessaryBigDecimalInstantiation should not produce violations for new BigDecimal(42), new BigDecimal(42L) or new BigDecimal("42") - i.e., when the parameter evaluates to an integer/long. - #3376576: UnnecessaryParenthesesForMethodCallWithClosureRule: IllegalArgumentException: Start and end indexes are one based and have to be greater than zero. - #3384056: Unnecessary* rules should be priority 3. THANKS - Thanks to René Scheibe for the UnnecessaryDefInVariableDeclarationRule and enhancements to UnnecessaryDefInMethodDeclarationRule; as well as the many bug fixes. - Thanks to Dean Del Ponte for the UnnecessaryDotClass rule. - Thanks to Nick Larson, Juan Vazquez, and Jon DeJong for the AssignCollectionUnique rule. - Thanks to Jeff Beck for the BitwiseOperatorInConditional rule. - Thanks to Geli Crick and Rafael Luque for the BracesForClass, LineLength, GrailsDomainHasToString,GrailsDomainHasEquals, BracesForIfElseRule, BracesForMethod, BracesForTryCatchFinally and ClassJavadoc rules. Changes in version 0.14 (June 2011) ------------------------------------------- NEW AND UPDATED RULES - ExplicitLinkedHashMapInstantiation rule (basic) - This rule checks for the explicit instantiation of a LinkedHashMap using the no-arg constructor. In Groovy, it is best to write "new LinkedHashMap()" as "[:]", which creates the same object. - DuplicateMapKey rule (basic) - A map literal is created with duplicated key. The map entry will be overwritten. - DuplicateSetValue rule (basic) - A Set literal is created with duplicate constant value. A set cannot contain two elements with the same value. - EqualsOverloaded rule (basic) - The class has an equals method, but the parameter of the method is not of type Object. It is not overriding equals but instead overloading it. - ForLoopShouldBeWhileLoop (basic) - A for-loop without an init and an update statement can be simplified to a while loop. - NonFinalSubclassOfSensitiveInterface rule (security) - The permissions classes such as java.security.Permission and java.security.BasicPermission are designed to be extended. Classes that derive from these permissions classes, however, must prohibit extension. This prohibition ensures that malicious subclasses cannot change the properties of the derived class. Classes that implement sensitive interfaces such as java.security.PrivilegedAction and java.security.PrivilegedActionException must also be declared final for analogous reasons. - ImportFromSunPackages rule (imports) - Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change. - UnnecessaryFinalOnPrivateMethod rule (unnecessary) - A private method is marked final. Private methods cannot be overridden, so marking it final is unnecessary. - InsecureRandom rule (security) - Reports usages of java.util.Random, which can produce very predictable results. If two instances of Random are created with the same seed and sequence of method calls, they will generate the exact same results. Use java.security.SecureRandom instead, which provides a cryptographically strong random number generator. SecureRandom uses PRNG, which means they are using a deterministic algorithm to produce a pseudo-random number from a true random seed. SecureRandom produces non-deterministic output. - DirectConnectionManagement rule (jdbc) - The J2EE standard requires that applications use the container's resource management facilities to obtain connections to resources. Every major web application container provides pooled database connection management as part of its resource management framework. Duplicating this functionality in an application is difficult and error prone, which is part of the reason it is forbidden under the J2EE standard. - ComparisonWithSelf (basic) - Checks for using a comparison operator or equals() or compareTo() to compare a variable to itself, e.g.: x == x, x != x, x <=> x, x < x, x > x, x <= x, x >= x, x.equals(x), or x.compareTo(x), where x is a variable. - ComparisonOfTwoConstants (basic) - Checks for using a comparison operator or equals() or compareTo() to compare two constants to each other or two literals that contain only constant values. - FileCreateTempFile rule (security) - The File.createTempFile() method is insecure, and has been deprecated by the ESAPI secure coding library. It has been replaced by the ESAPI Randomizer.getRandomFilename(String) method. - SystemExit rule (security) - Web applications should never call System.exit(). A call to System.exit() is probably part of leftover debug code or code imported from a non-J2EE application. - ObjectFinalize rule (security) - The finalize() method should only be called by the JVM after the object has been garbage collected. - JavaIoPackageAccess rule (security) - This rule reports violations of the Enterprise JavaBeans specification by using the java.io package to access files or the file system. - UnsafeArrayDeclaration rule (security) - Triggers a violation when an array is declared public, final, and static. Secure coding principles state that, in most cases, an array declared public, final and static is a bug because arrays are mutable objects. - PublicFinalizeMethod rule (security) - Creates a violation when the program violates secure coding principles by declaring a finalize() method public. - NonFinalPublicField rule (security) - Finds code that violates secure coding principles for mobile code by declaring a member variable public but not final. - UnnecessaryElseStatement rule (unnecessary) - When an if statement block ends with a return statement the else is unnecessary. The logic in the else branch can be run without being in a new scope. - StaticConnection rule (concurrency) - Creates violations when a java.sql.Connection object is used as a static field. Database connections stored in static fields will be shared between threads, which is unsafe and can lead to race conditions. - UnnecessaryPackageReference (unnecessary) - Checks for explicit package reference for classes that Groovy imports by default, such as java.lang.String, java.util.Map and groovy.lang.Closure. - AbstractClassWithPublicConstructor (design) - Checks for abstract classes that define a public constructor, which is useless and confusing. - StaticSimpleDateFormatField (concurrency) - Checks for static SimpleDateFormat fields. SimpleDateFormat objects are not threadsafe, and should not be shared across threads. - IllegalPackageReference (generic) - Checks for reference to any of the packages configured in packageNames. - SpockIgnoreRestUsed rule (junit) - If Spock's @IgnoreRest appears on any method, then all non-annotated test methods are not executed. This behaviour is almost always unintended. It's fine to use @IgnoreRest locally during development, but when committing code, it should be removed. - SwallowThreadDeath rule (exceptions) - Detects code that catches java.lang.ThreadDeath without rethrowing it - MisorderedStaticImports rule (imports) - Static imports should never be declared after nonstatic imports. - ConfusingMethodName (naming) - Existing rule updated to analyze fields and field names as well as just methods. - PublicInstanceField rule (design) - Using public fields is considered to be a bad design. Use properties instead. - UnnecessaryNullCheck (unnecessary) - Updated rule to flag null and not-null checks against the this reference. The this reference can never be null. - ClassForName rule (basic) - Using Class.forName(...) is a common way to add dynamic behavior to a system. However, using this method can cause resource leaks because the classes can be pinned in memory for long periods of time. - StatelessSingleton rule (design) - Rule finds occurrences of the Singleton pattern where the object has no state (mutable or otherwise). There is no point in creating a stateless Singleton, just make a new instance with the new keyword instead. - InconsistentPropertySynchronization rule (concurrency) - The rule is a little smarter now and flags code that defines a synchronized getter without any setter and vice versa. Those methods will be generated in unsynchronized from by the Groovy compiler later. - ClosureAsLastMethodParameter rule (basic) - If a method is called and the last parameter is an inline closure then it can be declared outside of the method call brackets. - SerialPersistentFields rule (serialization) - To use a Serializable object's serialPersistentFields correctly, it must be declared private, static, and final. - UnnecessaryParenthesesForMethodCallWithClosure rule (unnecessary) - If a method is called and the only parameter to that method is an inline closure then the brackets of the method call can be omitted. BUG FIXES and NEW FEATURES - Groovy 1.8 Support - CodeNarc continues to be built with Groovy 1.7, but should be able to be run with a Groovy 1.8 Runtime. - #3290486 - AbstractClassWithoutAbstractMethod no longer flags marker interfaces as abstract classes that do not define a method. - #3202691 - ClassNameRule rule is changed to handle $ in the class name, which is in Inner and Nested classes by default. - #3206167 - VariableNameRule now has a violation message that states the name of the variable and the regex it did not match. - #3206667 - FieldName, VariableName, MethodName, ParameterName, UnusedVariable, PropertyName, and UnusedPrivateField violations message now contains the class name of the enclosing class. This helps you configure an exclude. - #3206258 - LoggerForDifferentClass rule now accepts MyClass.name as a valid name for the logger. - #3206238 - The DuplicateNumberLiteral rule now allows you to ignore literals in the 1.2d, 1.2f, and 1.2G format. - #3207628 - The UnusedPrivateMethodParameter rule now allows you to ignore parameters by name. By default, parameters named 'ignore' and 'ignored' do not trigger a violation. You can configure this with the 'ignoreRegex' property on the rule. - #3205696 - The ConsecutiveStringConcatenation rule no longer suggesting that you join numbers together, it only suggests joining strings together. - #3206150 - Fixed UnusedGroovyImport rule so that imports with aliases are ignored and do not cause violations. - #3207605 - Fixed UnusedPrivateMethod rule to recognize static method references. - #3207607 - Fixed UnusedPrivateMethod rule to recognize access of privately defined getters and setters as properties. - #3205697 - Fixed bug where the source line displayed for annotated nodes was sometimes showing just the annotation and not the node. - #3288895 - Expand default test file regex pattern to include *TestCase - #3291474 - Enhance StaticDateFormatFieldRule to also check for static fields initialized to a DateFormat, e.g. static final DATE_FORMAT = DateFormat.getDateInstance(DateFormat.LONG) - #3291559 - Enhance StaticCalendarFieldRule to also check for untyped static fields that are initialized to a Calendar, e.g. static final CALENDAR = Calendar.getInstance() - #3293429 - Fix UnnecessaryNullCheck duplicate violations. - #3295887 - Fix AddEmptyString duplicate violations. - #3299713 - Fix ImportFromSamePackage, UnnecessaryGroovyImport: Star import. - #3300225 - Fix UnnecessaryGroovyImport: Check static imports. - #3290324 - Fix UnnecessarySemicolon: the contents of multiline strings and GStrings are no longer checked, just the strings themselves. For example, embedding JavaScript or Java within a Multi-line String would previously trigger the violation. - #3305896 - Fix LoggerForDifferentClass: The rule now correctly handles inner classes (that are not static) - #3305019 - Updated the EmptyCatchBlockRule so that exceptions named ignore or ignored will not trigger errors. The name is configurable. - #3309062 - UnnecessaryGroovyImportRule handles static imports incorrectly - - Fixed the Explicit[Collection]Instantiation rules so that the error messages are more descriptive. - - Fixed the InconsistentPropertySynchronization rule so that it recognizes the new @Synchronized annotation. - #3308930 - LoggerWithWrongModifiersRule now contains a parameter 'allowProtectedLogger' so that loggers can also be instantiated as 'protected final LOG = Logger.getLogger(this.class)'. Also, it has a 'allowNonStatic' logger property, that allows you to create a non static logger. - #3308930 - LoggerForDifferentClassRule now contains a parameter 'allowDerivedClasses'. When set, a logger may be created about this.getClass(). - #3309748 - FieldName:Do not treat non-static final fields as constants - #3310413 - Fix UnnecessaryPublicModifier does not catch public on constructors. - #3310521 - For all ExplicitCallToXxxMethod rules: Ignore calls to super.Xxx(). Patch from René Scheibe - #3313550 - Some HTML violation descriptions in the properties files were not well-formed HTML. This has been fixed. - #3205688 - Fixed false positives in UseAssertEqualsInsteadOfAssertTrue when using the JUnit assertFalse method. BREAKING CHANGES *** Moved the following rules out of the "basic" ruleset into the new "serialization" ruleset: - SerialVersionUID - SerializableClassMustDefineSerialVersionUID *** Moved import-specific helper methods out of AbstractRule into ImportUtil. *** The ExplicitTypeInstantiationAstVisitor is now an abstract class that requires you to specify a custom violation message. This should affect no one, but it is a backwards breaking change. ppp THANKS Thank you to Victor Savkin for sending in a patch with the ForLoopShouldBeWhileLoop, UnnecessaryElse, StatelessSingleton, PublicInstanceField, and EmptyCatchBlock rules. Thank you to Jan Ahrens and Stefan Armbruster for the SpockIgnoreRestUsed rule. Thank you to Rob Fletcher and Klaus Baumecker for the SwallowThreadDeath rule. Thank you to Erik Pragt for the MisorderedStaticImports rule. Thank you to Marcin Erdmann for the MisorderedStaticImports, ClosureAsLastMethodParameterInBracketsRule, and UnnecessaryBracketsForMethodWithClosureCall rules. Thank you to Hubert 'Mr. Haki' Klein Ikkink for updating the ConfusingMethodName rule. Thank you to René Scheibe for the ExplicitLinkedHashMapInstantiation rule and UnnecessaryGroovyImportRule and ExplicitCallToXxxMethod patches. Changes in version 0.13 (February 2011) ------------------------------------------- NEW FEATURES - New and improved syntax for defining custom rulesets. Just list the rule names you want. No need to specify ruleset filename or rule class. No more tweaking your custom rulesets with every CodeNarc release when we add new rules to the "basic" ruleset or one of the others. Feature #3193684. - Better support for command line runners. You can now specify the report type "console" as a command line parameter, and the CodeNarc text report is output to the console instead of a file. Feature #3162487 - All rules now provide a nicely formatted message. This makes console tools and the CodeNarc Web Console much more user friendly. Feature #3162847 - Greatly improved styling of the HTML report. Feature #3192593 - Improved error messages when CodeNarc is mis-configured and configuration file does not compile. Feature #3193468 - Improved println rule. If a class defines a println method, then it is OK to call this method because it won't dispatch to System.out.println. Feature #3194121 - Improved NestedBlockDepth rule. Method calls on builder objects are now ignored, so you can nest builder calls arbitrarily deep. What constitutes a builder is exposed in the ignoreRegex property, which defaults to '.*(b|B)uilder'. NEW RULES Dead/Unnecessary Code - EmptyInstanceInitializer rule (basic) - Feature #3163464 - An empty instance initializer. It is safe to remove it. - EmptyStaticInitializer rule (basic) - Feature #3161685 - An empty static initializer was found. It is safe to remove it. - EmptyMethod rule (basic) - Feature #3163806 - A method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation. - UnnecessaryCallToSubstring rule (unnecessary) - Feature #3164688 - Calling String.substring(0) always returns the original string. This code is meaningless. - UnnecessaryModOne rule (unnecessary) - Feature #3164684 - Any expression mod 1 (exp % 1) is guaranteed to always return zero. This code is probably an error, and should be either (exp & 1) or (exp % 2). - UnnecessarySelfAssignment rule (unnecessary) - Feature #3164674 - Method contains a pointless self-assignment to a variable or property. - UnnecessaryTransientModifier rule (unnecessary) - Feature #3164672 - The field is marked as transient, but the class isn't Serializable, so marking it as transient has no effect. - UnnecessaryFail rule (junit) - Feature #3105925 - In a unit test, catching an exception and immediately calling Assert.fail() is pointless and hides the stack trace. It is better to rethrow the exception or not catch the exception at all. - UnnecessaryPublicModifier rule (unnecessary) - Feature #3166320 - The 'public' modifier is not required on methods or classes. - UnnecessaryDefInMethodDeclaration rule (unnecessary) - Feature #3165469 - If a method has a visibility modifier, then the def keyword is unneeded. For instance 'def private method() {}' is redundant and can be simplified to 'private method() {}'. - UnnecessarySemicolon rule (unnecessary) - Feature #3176207 - Semicolons as line terminators are not required in Groovy: remove them. Do not use a semicolon as a replacement for empty braces on for and while loops; this is a confusing practice. - UnnecessaryGString rule (unnecessary) - Feature #3183521 - String objects should be created with single quotes, and GString objects created with double quotes. Creating normal String objects with double quotes is confusing to readers. Bugs/Bad Practices - AssignmentInConditional rule (basic) - An assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended. - SerializableClassMustDefineSerialVersionUID rule (basic) - Feature #3161076 - Classes that implement Serializable should define a serialVersionUID. - ConsecutiveStringConcatenation rule (basic) - Feature #3163826 - Catches concatenation of two string literals on the same line. These can safely by joined. - ConsecutiveLiteralAppends rule (basic) - Feature #3161779 - Violations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation. - AddEmptyString rule (basic) - Feature #3161763 - Finds empty string literals which are being added. This is an inefficient way to convert any type to a String. - BrokenOddnessCheck rule (basic) - Feature #3164687 - The code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0. - ExceptionExtendsError rule (exceptions) - Feature #3161749 - Errors are system exceptions. Do not extend them. - MissingNewInThrowStatementRule (exceptions) - Feature #3166115 - Improved existing rule to catch throwing a class literal, which always causes a RuntimeException. - UseAssertTrueInsteadOfAssertEquals (junit) - Feature #3172959 - This rule was expanded to handle assert statements as well as JUnit style assertions. - GroovyLangImmutable rule (basic) - Feature #3175158 - The groovy.lang.Immutable annotation has been deprecated and replaced by groovy.transform.Immutable. Do not use the Immutable in groovy.lang. - IntegerGetInteger rule (basic) - Feature #3174771 - This rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop']. - BooleanGetBoolean rule (basic) - Feature #3174770 - This rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop?']. - ChainedTest rule (junit) - Feature #3175647 - A test methodency that invokes another test method is a chained test; the methods are dependent on one another. Tests should be isolated, and not be dependent on one another. - CoupledTestCase rule (junit) - Feature #3175645 - This rule finds test cases that are coupled to other test cases, either by invoking static methods on another test case or by creating instances of another test case. If you require shared logic in test cases then extract that logic to a new class where it can properly be reused. Concurrency Problems - BusyWait rule (concurrency) - Feature #3170271 - Busy waiting (forcing a Thread.sleep() while waiting on a condition) should be avoided. Prefer using the gate and barrier objects in the java.util.concurrent package. - DoubleCheckedLocking rule (concurrency) - Feature #3170263 - This rule detects double checked locking, where a 'lock hint' is tested for null before initializing an object within a synchronized block. Double checked locking does not guarantee correctness and is an anti-pattern. - InconsistentPropertyLocking rule (concurrency) - Feature #3164700 - Class contains similarly-named get and set methods where one method of the pair is marked either @WithReadLock or @WithWriteLock and the other is not locked at all. - InconsistentPropertySynchronization rule (concurrency) - Feature #3164699 - Class contains similarly-named get and set methods where the set method is synchronized and the get method is not, or the get method is synchronized and the set method is not. - StaticCalendarField rule (concurrency) - Feature #3164702 - Calendar objects should not be used as static fields. Calendars are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. - StaticDateFormatField rule (concurrency) - DateFormat objects should not be used as static fields. DateFormat are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. - StaticMatcherField rule (concurrency) - Feature #3170276 - Matcher objects should not be used as static fields. Calendars are inherently unsafe for multithreaded use. Sharing a single instance across thread boundaries without proper synchronization will result in erratic behavior of the application. - SynchronizedOnBoxedPrimitive rule (concurrency) - Feature #3164708 - The code synchronizes on a boxed primitive constant, such as an Integer. Since Integer objects can be cached and shared, this code could be synchronizing on the same object as other, unrelated code, leading to unresponsiveness and possible deadlock - SynchronizedOnReentrantLock rule (concurrency) - Feature #3170262 - Synchronizing on a ReentrantLock field is almost never the intended usage. A ReentrantLock should be obtained using the lock() method and released in a finally block using the unlock() method. - SynchronizedOnString rule (concurrency) - Feature #3164707 - Synchronization on a String field can lead to deadlock because Strings are interned by the JVM and can be shared. - SynchronizedReadObjectMethod rule (concurrency) - Feature #3164704 - Catches Serializable classes that define a synchronized readObject method. By definition, an object created by deserialization is only reachable by one thread, and thus there is no need for readObject() to be synchronized. If the readObject() method itself is causing the object to become visible to another thread, that is an example of very dubious coding style. - ThreadGroup rule (concurrency) - Feature #3161692 - Avoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe. - VolatileArrayField rule (concurrency) - Feature #3170265 - Volatile array fields are unsafe because the contents of the array are not treated as volatile. Changing the entire array reference is visible to other threads, but changing an array element is not. - WaitOutsideOfWhileLoop rule (concurrency) - Feature #3127703 - Calls to Object.wait() must be within a while loop. This ensures that the awaited condition has not already been satisfied by another thread before the wait() is invoked. It also ensures that the proper thread was resumed and guards against incorrect notification. BUG FIXES - Fix Bug #3162499 UnnecessaryObjectReferences: This rule was not ignoring 'this' references, leading to false positives. - Fix Bug #3164150 UnnecessaryReturnKeyword: Rule is no longer triggered if the return is for a closure. - Fix Bug #3165139 LoggingSwallowsStacktrace: No longer reports multiple logger errors. - Fix bug #3166311: Error on numeric/boolean property values if they contain leading or trailing whitespace in "codenarc.properties" or in XML ruleset file. - Fix bug #3170295: @SuppressWarnings does not work with GMetrics-based rules (CC and ABC). - Fix bug #3190483: The UnusedPrivateField rule now ignores fields named serialVersionUID. The rule has a property called ignoreFieldNames that can be used to add other ignores as well. - Fix bug #3162975: The UnusedPrivate* rules now correctly read anonymous classes. - Fix bug #3155974: The UnusedPrivate* rules now correctly read inner classes. - Fix bug #3183443: Restricted the ConfusingTernary rule to reduce false positives. The rule looks for inverted conditionals in ternary statements. It did not account for Groovy Truth, and suggested 'x != null' be inverted to 'x', but that is not the inverse. So the rule was relaxed. - Fix bug #3195027: The violation message for "Replace Getter with Property Access" suggests converting ".getURLs()" to ".uRLs". This has been corrected to ".URLs". - Fix bug #3196019: Compiling files with unresolved Grapes dependencies no longer causes an error. POTENTIAL BREAKING CHANGES - addViolation(ASTNode) is deprecated. Instead use addViolation(ASTNode, String) when adding violations to the output. THANKS - Many thanks to Mathilde Lemée, Guillaume Laforge, and Tim Yates for helping us redesign our HTML report. - Big thanks to Evgeny Goldin and Cédric Champeau for reporting bugs which helps us improve the product so much faster. Changes in version 0.12 (January 2011) ------------------------------------------- NEW FEATURES - Improved performance of the CodeNarc Ant Task (by multi-threading source code analysis) - Feature #3150044 - Add support for message parameter substitution in Rule descriptions - Feature #3133988 NEW RULES - AbstractClassWithoutAbstractMethod rule (design) - Feature #3160204 - Adds a violation when an abstract class does not contain any abstract methods - CompareToWithoutComparable rule (basic) - Adds violation if you implement a compare method without implementing the Comparable interface - ExplicitGarbageCollection rule (basic) - Feature #3106689 - Adds a violation if you try to manually trigger a garbage collection run - CloseWithoutCloseable rule (design) - Feature #3138445 - Adds a violation if you implement a close method without imlpementing the Closeable interface - FinalClassWithProtectedMember rule (design) - Feature #3137650 - Adds violation if you have a protected member in a final class - CatchArrayIndexOutOfBoundsException rule (exceptions) - Feature #3122979 - Adds violation if you explicitly catch ArrayIndexOutOfBoundsException - CatchIndexOutOfBoundsException rule (exceptions) - Feature #3122979 - Adds violation if you explicitly catch IndexOutOfBoundsException - ConfusingTernary rule (basic) - Feature #3158945 - Adds violation if you use unnecessary negation within a ternary expression - ConstantsOnlyInterface rule (design) - Feature #3159134 - Adds violation if an interface contains constants but no methods - EmptyMethodInAbstractClass rule (design) - Feature #3159180 - Adds violation if an abstract class contains an empty method - RequiredString rule (generic) - Feature #3122980 - Adds violation if a user-defined String is not found. For example, a copyright notice may be required. - UseAssertFalseInsteadOfNegation rule (junit) - Feature #3114728 - Adds violation if JUnit's assertEquals is used with the boolean literal 'false' - UseAssertTrueInsteadOfNegation rule (junit) - Feature #3114728 - Adds violation if JUnit's assertEquals is used with the boolean literal 'true' - JUnitTestMethodWithoutAssert. rule (junit) - Feature #3111443 - Adds violation if a JUnit test method contains no assert statements - LoggerForDifferentClass rule (logging) - Feature #3114736 - Adds violation if a Logger is created based on a Class that is not the enclosing class - LoggerWithWrongModifiers rule (logging) - Adds violation if a Logger is not private, final, and static. - LoggingSwallowsStacktrace rule (logging) - Adds violation if a log statement logs an exception without the accompanying stack trace - MultipleLoggers rule (logging) - Adds a violation if a class declares more than one logger field - MissingNewInThrowStatement (exceptions) - Feature #3140762 -Adds a violation if a throw statement is used to throw a class literal - SimpleDateFormatMissingLocale rule (basic) - Feature #3160227 - Adds a violation if SimpleDateFormat is used without a Locale. - UnnecessaryBigDecimalInstantiation rule (unnecessary) - Adds a violation for explicit instantiation of BigDecimal - UnnecessaryBigIntegerInstantiation rule (unnecessary) - Adds a violation for explicit instantiation of BigInteger - UnnecessaryCatchBlock rule (unnecessary) - Feature #3107168 - Adds violation if catch block does nothing but throw original exception - UnnecessaryDoubleInstantiation rule (unnecessary) - Adds a violation for explicit instantiation of Double - UnnecessaryFloatInstantiation rule (unnecessary) - Adds a violation for explicit instantiation of Float - UnnecessaryInstantiationToGetClass (unnecessary) - Feature #3158935 - Adds a violation if a new instance is created in order to invoke getClass() - UnnecessaryIntegerInstantiation rule (unnecessary) - Adds a violation for explicit instantiation of Integer - UnnecessaryLongInstantiation rule (unnecessary) - Adds a violation for explicit instantiation of Long - UnnecessaryNullCheck Rule (unnecessary) - Feature #3160184 - Adds violation when a null-safe dereference can be used instead of an explicit null check - UnnecessaryNullCheckBeforeInstanceOf rule (unnecessary) - Feature #3159274 - Adds a violation for an unnecessary null check before using the instanceof operator - UnnecessaryObjectReferences rule (unnecessary) - Feature #3107838 - Adds a violation for a chain of setters being invoked, which can be converted into a with or identity block - UnnecessaryCallForLastElement rule (unnecessary) - Feature #3107884 - Adds violation if accessing the last element of a list without using the .last() method or -1th index - UnnecessaryCollectCall rule (unnecessary) - Feature #3110317 - Adds a violation if a collect method call can be replaced with the spread operator - UnnecessaryCatchBlock rule (unnecessary)- Feature #3110318 - Adds a violation if a catch block does nothing but throw the original exception - UnnecessaryGetter rule (unnecessary)- Feature #3110321 - Adds a violation if a a getter method is called explicitly instead of using property syntax - UnusedPrivateMethodParameter rule (unused) - Feature #3151598 - Adds a violation if the parameter to a private method is never used within that method BUG FIXES - Fix Bug #3127967: DuplicateImportRule: Fix for Groovy 1.7. Resort to parsing source code. - Fix Bug #3146678: UnnecessaryGetter false positive, e.g. def allPaths = resultsMap.keySet() ??? keySet() can probably be rewritten as set. - Fix Bug #3111189: "StatelessClassRule - Honor @Immutable". - Fix Bug #3111181: "UnnecessaryIfStatement - misses if without explicit return". - Fix Bug #3108126: "assertNoViolations still passes when compile fails" - Fix Bug #3111439: "Synchronized on getClass() rule gives double warnings". - Fix Bug #3111438: "Lines with annotations have the wrong source line". - Fix Bug #3109909: DuplicateStringLiteralRule: Add "" as default ignoreStringLiteral. - Fix Bug #3110308: "Rules to catch null returns ignore ternary expressions". - Fix Bug #3110303: "ExplicitCallToXMethod rules should ignore spread statements". - Fix Bug #3109917: "DuplicateStringLiteralRule - enum names". - Fix Bug #3109628: "Exceptions are thrown with CodeNarc v0.11" ? "GString as map key checking classes that do not exist yet?? and ?unnecessary ctor rule breaks for anonymous classes". - Fix Bug #3190754: Don't use default ClassLoader for loading rule scripts. POTENTIAL BREAKING CHANGES - Moved the existing StringInstantiation and BooleanInstantiation rules from the Basic ruleset into the Unnecessary ruleset. Also renamed the rules to UnnecessaryStringInstantiationRule and UnnecessaryBooleanInstantiation). Likewise, the rule classes were moved from the org.codenarc.rule.basic package into org.codenarc.rule.unnecessary. NOTE: This should only affect users if * You configured one of these rules specifically by rule name or by class name within a custom ruleset * You configured one of these rules (by rule name) within "codenarc.properties" * You configured one of these rules (by rule name) within a @SuppressWarnings annotation * You configured one of these rules (by rule name) within "codenarc-message.properties". - Removed deprecated applyToFilenames and doNotApplyToFilenames properties of AbstractRule. OTHER CHANGES - UnnecessaryIfStatementRule: Expand the rule to also catch if/else statements that contain only single constant/literal expressions for the if and/or else blocks, if the if is not the last statement in the block. - Feature #3108153: Expand ReturnNull* rules to catch elvis operators - Feature #3111442: "add better error messages to the ReturnsNull*Rules" - Feature #3111440: "added better violation messages to BigDecimalInstantiationRule, BooleanInstantiationRule, and StringInstantiationRule". - Add isValid() to SourceCode (and AbstractSourceCode). Changes in version 0.11 (November 2010) ------------------------------------------- NEW FEATURES - @SuppressWarnings support. All rules now recognize the java.lang.SuppressWarnings annotation on fields, methods, and classes. If this annotation is added then there will be no violations produced. Just as in Java, the annotation requires a String or List parameter. For example, annotating a class with @SuppressWarnings('UnusedPrivateField') will ignore the rule for that class. Annotating a method with @SuppressWarnings(['UnusedPrivateField', 'UnnecessaryIfStatementRule']) will ignore both rules for the annotated method. - Better "codenarc create-rule" support. You can create a new rule by running "codenarc create-rule" from the root of the CodeNarc codebase. This script has been updated to properly format Javadoc, prompt for the author name, and update the Maven Site .apt documentation. NEW RULES BooleanMethodReturnsNull Rule (basic) : Checks for a method with Boolean return type that returns an explicit null. DeadCode Rule (basic) : Checks for dead code that appears after a return statement or after an exception is thrown. DoubleNegative Rule (basic) : Checks for using a double negative, which is always positive. DuplicateCaseStatement Rule (basic) : Check for duplicate case statements in a switch block, such as two equal integers or strings. ExplicitCallToAndMethod Rule (basic) : This rule detects when the and(Object) method is called directly in code instead of using the & operator. ExplicitCallToCompareToMethod Rule (basic) : This rule detects when the compareTo(Object) method is called directly in code instead of using the <=>, >, >=, <, and <= operators. ExplicitCallToDivMethod Rule (basic) : This rule detects when the div(Object) method is called directly in code instead of using the / operator. ExplicitCallToEqualsMethod Rule (basic) : This rule detects when the equals(Object) method is called directly in code instead of using the == or != operator. ExplicitCallToGetAtMethod Rule (basic) : This rule detects when the getAt(Object) method is called directly in code instead of using the [] index operator. ExplicitCallToLeftShiftMethod Rule (basic) : This rule detects when the leftShift(Object) method is called directly in code instead of using the \<\< operator. ExplicitCallToMinusMethod Rule (basic) : This rule detects when the minus(Object) method is called directly in code instead of using the - operator. ExplicitCallToMultiplyMethod Rule (basic) : This rule detects when the multiply(Object) method is called directly in code instead of using the * operator. ExplicitCallToModMethod Rule (basic) : This rule detects when the mod(Object) method is called directly in code instead of using the % operator. ExplicitCallToOrMethod Rule (basic) : This rule detects when the or(Object) method is called directly in code instead of using the | operator. ExplicitCallToPlusMethod Rule (basic) : This rule detects when the plus(Object) method is called directly in code instead of using the + operator. ExplicitCallToPowerMethod Rule (basic) : This rule detects when the power(Object) method is called directly in code instead of using the ** operator. ExplicitCallToRightShiftMethod Rule (basic) : This rule detects when the rightShift(Object) method is called directly in code instead of using the \>\> operator. ExplicitCallToXorMethod Rule (basic) : This rule detects when the xor(Object) method is called directly in code instead of using the ^ operator. ExplicitArrayListInstantiation Rule (basic) : This rule checks for the explicit instantiation of an ArrayList. In Groovy, it is best to write new ArrayList() as [], which creates the same object. ExplicitHashMapInstantiation Rule (basic) : This rule checks for the explicit instantiation of a HashMap. In Groovy, it is best to write new HashMap() as [:], which creates the same object. ExplicitHashSetInstantiation Rule (basic) : This rule checks for the explicit instantiation of a HashSet. In Groovy, it is best to write new HashSet() as [] as Set, which creates the same object. ExplicitLinkedListInstantiation Rule (basic) : This rule checks for the explicit instantiation of a LinkedList. In Groovy, it is best to write new LinkedList() as [] as Queue, which creates the same object. ExplicitStackInstantiation Rule (basic) : This rule checks for the explicit instantiation of a Stack. In Groovy, it is best to write new Stack() as [] as Stack, which creates the same object. ExplicitTreeSetInstantiation Rule (basic) : This rule checks for the explicit instantiation of a TreeSet. In Groovy, it is best to write new TreeSet()>> as [] as SortedSet, which creates the same object. GStringAsMapKey Rule A GString should not be used as a map key since its hashcode is not guaranteed to be stable. InvertedIfElse Rule (basic) : An inverted if-else statement is one in which there is a single if statement with a single else branch and the boolean test of the if is negated. RemoveAllOnSelf Rule (basic) : Don't use removeAll to clear a collection. ReturnsNullInsteadOfEmptyArray Rule (basic) : If you have a method or closure that returns an array, then when there are no results return a zero-length (empty) array rather than null. ReturnsNullInsteadOfEmptyCollection Rule (basic) : If you have a method or closure that returns a collection, then when there are no results return a zero-length (empty) collection rather than null. SerialVersionUID Rule (basic) : A serialVersionUID is normally intended to be used with Serialization. It needs to be of type long, static, and final. UnnecessaryConstructor Rule (unnecessary) : This rule detects when a constructor is not necessary; i.e., when there's only one constructor, it's public, has an empty body, and takes no arguments. UnnecessaryCollectionCall Rule (unnecessary) : Checks for useless calls to collections. UnnecessaryOverridingMethod Rule (unnecessary) : Checks for an overriding method that merely calls the same method defined in a superclass. UnnecessaryReturnKeyword Rule (unnecessary) : In Groovy, the return keyword is often optional. SynchronizedOnGetClass Rule (concurrency) : Checks for synchronization on getClass() rather than class literal. UseOfNotifyMethod Rule (concurrency) : Checks for code that calls notify() rather than notifyAll(). DuplicateNumberLiteral Rule (dry) : This rule checks for duplicate number literals within the current class. DuplicateStringLiteral Rule (dry) : This rule checks for duplicate String literals within the current class. CatchIllegalMonitorStateException Rule (exceptions) : Dubious catching of IllegalMonitorStateException. ConfusingClassNamedException Rule (exceptions) : This class is not derived from another exception, but ends with 'Exception'. ReturnNullFromCatchBlock Rule (exceptions) : Returning null from a catch block often masks errors and requires the client to handle error codes. UseAssertEqualsInsteadOfAssertTrue Rule (junit) : This rule detects JUnit assertions in object equality. UseAssertTrueInsteadOfAssertEqualsRule Rule (junit) : This rule detects JUnit calling assertEquals where the first parameter is a boolean. UseAssertNullInsteadOfAssertEquals Rule (junit) : This rule detects JUnit calling assertEquals where the first or second parameter is null. UseAssertSameInsteadOfAssertTrue Rule (junit) : This rule detects JUnit calling assertTrue or assertFalse where the first or second parameter is an Object#is() call testing for reference equality. JUnitFailWithoutMessage Rule (junit) : This rule detects JUnit calling the fail() method without an argument. JUnitStyleAssertions Rule (junit) : This rule detects calling JUnit style assertions like assertEquals, assertTrue, assertFalse, assertNull, assertNotNull. ConfusingMethodName Rule (naming) : Checks for very confusing method names. The referenced methods have names that differ only by capitalization. ObjectOverrideMisspelledMethodName Rule (naming) : Verifies that the names of the most commonly overridden methods of Object: equals, hashCode and toString, are correct. MethodCount Rule (size) : Checks if the number of methods within a class exceeds the number of lines specified by the maxMethod property. BUG FIXES - None reported, none fixed! POTENTIAL BREAKING CHANGES - AbstractAstVisitor - If you implemented your own rule by subclassing AbstractAstVisitor then your code might break. It is a compile error and the breakage will be clear and obvious. In order to support @SuppressWarnings, we needed to change AbstractAstVisitor. The method visitMethodNode became visitMethodNodeEx, visitClass became visitClassEx, visitConstructorOrMethod became visitConstructorOrMethodEx, visitField became visitFieldEx, visitProperty became visitPropertyEx, and visitConstructor became visitConstructorEx. From within these new methods there is no need to call super.visitX. In the rare case that the simple renaming does not fix your problem then please contact the mailing list. - The following three classes were moved from the org.codenarc.rule.basic package into org.codenarc.rule.unnecessary. Likewise, the associated rules were moved from the "basic" ruleset into the new "unnecessary" ruleset. You will need to adjust your ruleset configuration if you included one of these rules specifically in a custom ruleset, or configured them as part of the "basic" ruleset. * UnnecessaryBooleanExpressionRule * UnnecessaryIfStatementRule * UnnecessaryTernaryExpressionRule OTHER CHANGES - CodeNarc now requires Groovy 1.7 to run. Keep in mind that it can still run against (analyze) older Groovy code. - There is a new rule set (category) called "dry", meaning "do not repeat yourself". - There is a new "unnecessary" rule set (category). - AstUtil enhancements - For writers of rules: there are new utility methods in the AstUtil class. See the javadoc for more details. Changes in version 0.10 (26 September 2010) ------------------------------------------- BUG FIXES - Fix Bug #3071531: "Unused rules don't recognized method closures". https://sourceforge.net/tracker/?func=detail&atid=1126573&aid=3071531&group_id=250145. e.g. private def bar() { } .. return this.&bar; - Fix: UnusedPrivateField: Don't produce violation if field is a Closure field and is executed. - Fix: ImportFromSamePackage: Fix for (ignore) alias imports within same package. package org.xyz; import org.xyz.MyBigClass as MBC. NEW RULES - New UnnecessaryIfStatementRule (basic): Checks for if statements where the if and else blocks are only returning true and false constants. if(x) { return true } else { return false }. - New UnnecessaryBooleanExpressionRule (basic): Check for unnecessary boolean expressions, including ANDing (&&) or ORing (||) with true, false, null, or Map/List/String/Number literal. Also checks for negation of true, false, null, or Map/List/String/Number literal. - New BigDecimalInstantiationRule (basic): Avoid creating BigDecimal with a decimal (float/double) literal. Use a String literal. From PMD. See http://pmd.sourceforge.net/rules/basic.html#AvoidDecimalLiteralsInBigDecimalConstructor. Note that println new BigDecimal(0.1) prints out 0.1000000000000000055511151231257827021181583404541015625. - UnusedObjectRule (unused): Checks for object allocations that are not assigned or used, unless it is the last statement within a block (because it may be the intentional return value). - New UnusedArrayRule (unused): This inspection reports any instances of Groovy array allocation where the array allocated is ignored. Such allocation expressions are legal Groovy, but are usually either inadvertent, or evidence of a very odd object initialization strategy. (IntelliJ). When an ExpressionStatement has as its expression an ArrayExpression. - Implement ImplementationAsTypeRule (design): Checks that particular classes are never used as types in variable declarations, return values or parameters. GregorianCalendar, HashMap, HashSet, Hashtable, LinkedList, LinkedHashMap, LinkedHashSet, TreeSet, TreeMap, Vector, ArrayList, CopyOnWriteArrayList, CopyOnWriteArraySet, ConcurrentHashMap, ArrayBlockingQueue, ConcurrentLinkedQueue, DelayQueue, LinkedBlockingQueue, PriorityBlockingQueue, PriorityQueue, SynchronousQueue (see Checkstyle). (design) - New JUnitUnnecessaryTearDownRule (junit). Checks for tearDown() methods that only call super.tearDown(). - New JUnitUnnecessarySetUpRule (junit). Checks for setUp() methods that only call super.setUp(). NEW REPORT WRITER - New InlineXmlReportWriter (from Robin Bramley) for improved integration with the Hudson Violations plugin. See http://wiki.hudson-ci.org/display/HUDSON/Violations. OTHER CHANGES - CodeNarc now requires Groovy 1.6 to run. Keep in mind that it can still run against (analyze) older Groovy code. - Upgrade to GMetrics 0.3 for AbcComplexityRule and CyclomaticComplexityRule. Violations now include line number and source line. - All JUnit rules (JUnit*Rule): Also apply to classes with names ending in *TestCase. - Add codenarc create-rule script to create a new rule and associated classes/tests. https://sourceforge.net/tracker/?func=detail&aid=3005873&group_id=250145&atid=1126575. (Hamlet D'Arcy) - ConstantTernaryExpressionRule: Also flag constant Map and List expressions. - ConstantIfExpressionRule: Also flag constant Map and List expressions. - GrailsPublicControllerMethod: add ignoreMethodNames property. - Add reference to Sonar plugin. http://docs.codehaus.org/display/SONAR/Groovy+Plugin to web site. - Add reference to Hudson Violations Plugin. http://wiki.hudson-ci.org/display/HUDSON/Violations to web site. Changes in version 0.9 (10 May 2010) ------------------------------------ BUG FIXES - Fix bug #2985592: "MissingPropertyException: No such property: W3C_XML_SCHEMA_NS_URI". - XML RuleSet: Allow wildcards (*) in and . - WildcardPattern: Escape plus sign ('+'). - NestedBlockDepthRule: Ignore first level of closure for Closure Fields (since they are really equivalent to methods). NEW SIZE/COMPLEXITY RULES - AbcComplexityRule - Check ABC size/complexity score against threshold for method and class average (size) - CyclomaticComplexityRule - Check Cyclomatic Complexity against threshold for method and class average (size) NEW CONCURRENCY RULES - NestedSynchronizationRule (concurrency - Hamlet D'Arcy) - RunFinalizersOnExitRule (concurrency - Hamlet D'Arcy) - SynchronizedMethodRule (concurrency - Hamlet D'Arcy) - SynchronizedOnThisRule (concurrency - Hamlet D'Arcy) - ThreadLocalNotStaticFinalRule (concurrency - Hamlet D'Arcy) - ThreadYieldRule: (concurrency - Hamlet D'Arcy) - VolatileLongOrDoubleFieldRule: (concurrency - Hamlet D'Arcy) NEW BASIC RULES - CloneableWithoutCloneRule (basic - Hamlet D'Arcy & René Groeschke) - ConstantIfExpressionRule: if(true) or if(false). Or literal constant. (basic) - ConstantTernaryExpressionRule: true ? x : y or false, null or literal.(basic) - UnnecessaryTernaryExpressionRule: x ? true : false. Or Boolean.TRUE. Or where both expressions are the same. (basic) OTHER CHANGES - Deprecate GrailsSessionReferenceRule. Default enabled to false. Note in online docs. - StatelessClassRule: Add setAddToIgnoreFieldNames() method (adds to ignoreFieldNames). - Add new .description.html property for each rule. Change the HtmlReportWriter to look for *.description.html first; if not defined, use *.description. Continue to use *.description in XML report. Potential BREAKAGE: If you have overridden the ".description" message for a predefined rule in a "codenarc-messages.properties" file, you will have to change those message keys to ".description.html". - Do not include disabled rules in list of rules at bottom of HTML/XML report. - HtmlReportWriter: Don?t log warning if "codenarc-messages.properties" contains *.description but not *.description.html. - UnusedVariableRule: Fix limitation: Does not recognize variable references on the same line as the variable declaration. - GroovyDslRuleSet: Throw MissingPropertyException if a non-existent property is set within a Groovy RuleSet DSL. - CodeNarcRunner: Add System.out println of summary counts. - MethodSizeRule: Apply to constructors as well. - WildcardPattern: Trim pattern values. This includes property values such as common rule properties applyToFileNames/doNotApplyToFileNames, applyToClassNames/doNotApplyToClassNames. Or many rule-specific properties such as ignoreMethodNames for the MethodSizeRule. - PropertiesFileRuleSetConfigurer: Log warning if rule name not found. - TESTS: AbstractRuleTestCase: Add assertViolations(String source, Map[] violationMaps) helper method. - TESTS: Fix tests broken on Linux. Changes in version 0.8.1 (2 Feb 2010) ------------------------------------ BUG FIXES - Fix Bug #2943025: "NestedBlockDepthRule: Produces erroneous results on Groovy 1.6.x." https://sourceforge.net/tracker/?func=detail&aid=2943025&group_id=250145&atid=1126573 - Fix Bug #2943028: "PackageNameRule may show incorrect violations for classes within the default package when running in Groovy 1.6.x." https://sourceforge.net/tracker/?func=detail&aid=2943028&group_id=250145&atid=1126573 - Fix Bug #2935587 "Building CodeNarc 0.8 fails." - Problem from Joern Huxhorn (Jan 18, 2010) ? Unable to build from the downloaded CodeNarc-0.8-bin.tar.gz. http://sourceforge.net/tracker/?func=detail&aid=2935587&group_id=250145&atid=1126573. See CodeNarc - Unable to Build From TarGZip.doc. Remove platform/locale dependencies: AbstractReportWriterTest, UrlResourceTest, GrailsSessionReferenceRuleTest, GrailsPublicControllerMethodRuleTest, GrailsServletContextReferenceRuleTest, GrailsStatelessServiceRuleTest. [Jan 24] - Fix StackOverflow in Groovy 1.7.0 for some rules: All rules that implement the visitVariableExpression(VariableExpression expression) visitor method: UnusedVariableRule, UnusedPrivateFieldRule, GrailsSessionReferenceRule, GrailsServletContextReferenceRule ? Removed call to super.visitVariableExpression(expression) since that seems to cause problems (StackOverflow) in Groovy 1.7.0. - Fix tests broken when running in Groovy 1.6 or Groovy 1.7. - DuplicateImportRule: Document that this rule does not work when running under Groovy 1.7 (i.e., will not produce any violations), and does not distinguish between multiple duplicate imports for the same class. Changes in version 0.8 (17 Jan 2010) ------------------------------------ BUG FIXES - Fix Bug #2930886: "Cannot load rules when groovy is in different classloader". XmlReaderRuleSet, ReportWriterFactory: Replace calls to Class.forName() with getClass().classLoader.loadClass(). https://sourceforge.net/tracker/?func=detail&atid=1126573&aid=2930886&group_id=250145. - Fix Bug #2847520: "UnusedVariableRule: Closure variable must be invoked". UnusedVariableRule: Referencing an (explicit) Closure variable without invoking it is not recognized as a valid reference. e.g., final CLOSURE = { .. }; return CLOSURE. https://sourceforge.net/tracker/?func=detail&aid=2847520&group_id=250145&atid=1126573 - Fix false positive: Local closures: If a closure is assigned to a local variable, then used later in the method, CodeNarc report the variable unused. [I think this has already been resolved, perhaps as part of Bug #2847520]. (reported by Donal Murtagh) - Fix false positive: Default arguments: If a constant is only used as the value of a default argument, CodeNarc reports this constant unused. (reported by Donal Murtagh) REPORTS - Create XmlReportWriter for wrting out an XML report ("xml"). (beta) - Create TextReportWriter. Writes out text report with violations by file and priority and summary counts. - Enable configuring all provided ReportWriters (HtmlReportWriter, XmlReportWriter, TextReportWriter) to write to the stdout (console). - Enable specifying the full class name of a custom ReportWriter class. - CodeNarcTask: Add support for

Package: <Root>