<?xml version="1.0" encoding="UTF-8"?>
<test-data
    xmlns="http://pmd.sourceforge.net/rule-tests"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">
    <!-- All these tests have been validated against JavaNCSS. -->

    <code-fragment id="full-example"><![CDATA[
package com
        .company
        .money;

import com
        .company
        .money.Bar;
import com.company.Carrot;
import com.company.ScaryException;
import com.company.ThemAll;
import java.util.Random;

public class Foo extends Bar {
    int y, z, t;
    String q;

    {
        bar();
        int x;
        switch
        (x) {
        case 1: foo(); break;
        case 2:
        case 3: bar();
            break;
        default: break;
        }
    }

    public Foo() {
        this(2);
    }

    public Foo(int z) {

        Random r = new Random();
        label: for (int j = -12; i < z; i++) {
            theNonsense: for (int k = -20; k < 20; k += j) {
                if (r.nextInt() == 42) {
                    System
                            .out
                            .println("Bye");
                    break label;
                } else if (k > 12) {
                    continue theNonsense;
                }
            }
        }

        super.f(z);
    }

    public void foo() {
        int x = 0;
        synchronized (x) {
            x++;
        }

        do {
            if (x == 0) {
                synchronized (x) {
                    x++;
                }
            } else if (x == 1) {
                x = 0;
            } else {
                System.out.println("Bonjour");
                throw new ScaryException("Surprise!");
            }
        } while (x != 2);
    }

    public static void main(String args[]) throws ScaryException {
        String k, l, m;
        int x;

        bar();

        do {
            x++;
        } while (x < 2);

        while (x < 4) {
            x++;
        }

        for (int i = 1; x < 6; ) {
            x += i;
        }

        {
            x++;;;;;
        }

        int p =
                2 + 4 + 5;

        try {
            x++;
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (ThemAll pokemon) {
            pokemon.train();
        } finally {
            // Do nothing
        }

        bar();
        x = (int) bar();
        /*
         * This is
         * a comment
         */
        x.foobar();
    }
}
    ]]></code-fragment>

    <test-code>
        <description>Full example - Standard version</description>
        <rule-property name="reportClasses">true</rule-property>
        <expected-problems>5</expected-problems>
        <expected-messages>
            <message>'com.company.money.Foo' has value 66.</message>
            <message>'com.company.money.Foo#Foo()' has value 2.</message>
            <message>'com.company.money.Foo#Foo(int)' has value 13.</message>
            <message>'com.company.money.Foo#foo()' has value 14.</message>
            <message>'com.company.money.Foo#main(String[])' has value 21.</message>
        </expected-messages>
        <code-ref id="full-example"/>
    </test-code>

    <test-code>
        <description>Full example - JavaNcss version</description>
        <rule-property name="reportClasses">true</rule-property>
        <rule-property name="metricOptions">countImports</rule-property>
        <expected-problems>5</expected-problems>
        <expected-messages>
            <message>'com.company.money.Foo' has value 72.</message>
            <message>'com.company.money.Foo#Foo()' has value 2.</message>
            <message>'com.company.money.Foo#Foo(int)' has value 13.</message>
            <message>'com.company.money.Foo#foo()' has value 14.</message>
            <message>'com.company.money.Foo#main(String[])' has value 21.</message>
        </expected-messages>
        <code-ref id="full-example"/>
    </test-code>

    <test-code>
        <description>Empty method</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#foo()' has value 1.</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void foo() {
        // Comment not counted
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Empty class</description>
        <rule-property name="reportClasses">true</rule-property>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo' has value 1.</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Switch</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#foo()' has value 11.</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void foo() {
        int x;
        switch (x) {
            case 1:
            case 2:
            case 3:
            case 4: foo(); break;
            default: break;
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Multiple local variable declarations</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#foo()' has value 2.</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void foo() {
        int x, y = 2, z;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>First catch is not counted</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#foo()' has value 3.</message>
        </expected-messages>
        <code><![CDATA[
public class Foo {
    void foo() {
        try {
        } catch (java.io.IOException e) {
        } catch (Exception e) {
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Empty statements are not counted</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Boo#foo()' has value 2.</message>
        </expected-messages>
        <code><![CDATA[
public class Boo {
    void foo() {
        foo();;;
        ;
        ;
        ;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Blocks are not counted</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Boo#foo()' has value 3.</message>
        </expected-messages>
        <code><![CDATA[
public class Boo {
    void foo() {
        foo();
        {
        }
        {
            bar();
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>For initialisations are not counted</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Hoo#foo()' has value 3.</message>
        </expected-messages>
        <code><![CDATA[
public class Hoo {
    void foo() {
        for (int x = 0; x < 2; x++) {

        }

        for (;;) {

        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Nested classes are counted</description>
        <rule-property name="reportClasses">true</rule-property>
        <expected-problems>4</expected-problems>
        <expected-messages>
            <message>'Boo' has value 8.</message>
            <message>'Boo#foo()' has value 2.</message>
            <message>'Boo$Barnabee' has value 5.</message>
            <message>'Boo$Barnabee#getX()' has value 2.</message>
        </expected-messages>
        <code><![CDATA[
public class Boo {
    void foo() {
        bar();
    }

    class Barnabee {
        int x;
        int y;

        getX() {
            return x;
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Enum constants are not counted</description>
        <rule-property name="reportClasses">true</rule-property>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Shoo' has value 1.</message>
        </expected-messages>
        <code><![CDATA[
public enum Shoo {
    BAR, NA, BEE;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Annotation declarations are counted</description>
        <rule-property name="reportClasses">true</rule-property>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Moo' has value 1.</message>
        </expected-messages>
        <code><![CDATA[
public @interface Moo {
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Abstract methods are counted</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Koo#bar()' has value 1.</message>
        </expected-messages>
        <code><![CDATA[
public abstract class Koo {
    abstract void bar();
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Lambdas themselves don't count, only the code within</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Koo#bar()' has value 2.</message>
        </expected-messages>
        <code><![CDATA[
import java.util.function.Consumer;
public abstract class Koo {
    void bar() {
        Consumer<Integer> i = i -> {

        };
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Code inside lambdas is counted by default</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Koo#bar()' has value 4.</message>
        </expected-messages>
        <code><![CDATA[
import java.util.function.Consumer;
public abstract class Koo {
    void bar() {
        Consumer<Integer> i = i -> {
            int j = 0;
            j = i;
        };
    }
}
        ]]></code>
    </test-code>
</test-data>
