<?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">

    <test-code>
        <description>basic test</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class HelloWorldBean {
    private String _thing;

    public String getMessage() {
        return "Hello World!";
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>basic test, not OK</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class HelloWorldBean {

    public String getMessage() {
        return "Hello World!";
    }
    private String _fieldInWrongLocation;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>inner class, OK</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class HelloWorldBean {

    public String getMessage() {
        return "Hello World!";
    }

    public class Foo {
        private String _fieldInWrongLocation;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Initial report where rule was introduced, [ 2487971 ] False positive with field-level annotations</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import org.springframework.beans.factory.annotation.Autowired;
public class MyTest {
    @Autowired
    protected String _first;
    @Autowired
    protected String _second;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Empty declaration is allowed</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.logging.Logger;
public class Foo {
    private static final Logger LOGGER = Logger.getLogger(Foo.class);

    ;

    private int id;
    private Foo myType;
    private String name;

    // OK, now constructors, getters, setters, etc.
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1126 False positive with FieldDeclarationsShouldBeAtStartOfClass for static enums</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.logging.Logger;
public class Foo {
    private static final Logger LOGGER = Logger.getLogger(Foo.class);

    public static enum MyType {
        ABC, DEF, GHI, JHK
    }

    private int id;
    private MyType myType;
    private String name;

    // OK, now constructors, getters, setters, etc.
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1126 Do not ignore enums</description>
        <rule-property name="ignoreEnumDeclarations">false</rule-property>
        <expected-problems>3</expected-problems>
        <code><![CDATA[
import java.util.logging.Logger;
public class Foo {
    private static final Logger LOGGER = Logger.getLogger(Foo.class);

    public static enum MyType {
        ABC, DEF, GHI, JHK
    }

    private int id;
    private MyType myType;
    private String name;

    // OK, now constructors, getters, setters, etc.
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1244 FieldDeclarationsShouldBeAtStartOfClass and anonymous classes, ok</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class MyClass {
    private final String name;
    public MyClass() {
        this.name = "whatever";
    }
    public void onCreate() {
        // someView.setListener(onSomeViewClick);
    }
    private final OnClickListener onSomeViewClick = new OnClickListener() {
        @Override
        public void onClick(Object view) {
            // something
        }
    };
}
interface OnClickListener { void onClick(Object view); }
        ]]></code>
    </test-code>

    <test-code>
        <description>#1244 FieldDeclarationsShouldBeAtStartOfClass and anonymous classes, fail</description>
        <rule-property name="ignoreAnonymousClassDeclarations">false</rule-property>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>9</expected-linenumbers>
        <code><![CDATA[
public class MyClass {
    private final String name;
    public MyClass() {
        this.name = "whatever";
    }
    public void onCreate() {
        // someView.setListener(onSomeViewClick);
    }
    private final OnClickListener onSomeViewClick = new OnClickListener() {
        @Override
        public void onClick(Object v) {
            // something
        }
    };
}
interface OnClickListener { void onClick(Object view); }
        ]]></code>
    </test-code>

    <test-code>
        <description>#1354 Complex FieldDeclarationsShouldBeAtStartOfClass false positive with Spring annotations</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Bean;
public class MyClass {
    private static final String MY_STRING = "STRING";

    @Autowired
    private MyPrivate myPrivate;

    @Bean
    public void myPublicBean() {}

    private static void myPrivateStatic() {}
    static class MyPrivate {}
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1364 FieldDeclarationsShouldBeAtStartOfClass false positive using multiple annotations</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import javax.persistence.ManyToOne;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.JoinColumn;
public class MyEntity {

    private static final String MY_STRING = "STRING";

    @Id
    @Column
    private Long id;

    @ManyToOne
    @JoinColumn("")
    private MyEntity relation;

    public MyEntity() {
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#345 [java] FieldDeclarationsShouldBeAtStartOfClass: Add ability to ignore interfaces - default case</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>6</expected-linenumbers>
        <code><![CDATA[
public class TestFieldDeclarations {
    public interface StartCaptureListener {
        void onStartCapture(boolean shouldUploadMediaToTba);
    }

    private static final int TAKE_PHOTO_RC = 334; // line 6
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#345 [java] FieldDeclarationsShouldBeAtStartOfClass: Add ability to ignore interfaces - ignore interfaces</description>
        <rule-property name="ignoreInterfaceDeclarations">true</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public class TestFieldDeclarations {
    public interface StartCaptureListener {
        void onStartCapture(boolean shouldUploadMediaToTba);
    }

    private static final int TAKE_PHOTO_RC = 334; // line 6
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False negative with anon classes (1)</description>
        <rule-property name="ignoreAnonymousClassDeclarations">false</rule-property>
        <expected-problems>3</expected-problems>
        <expected-linenumbers>4,5,7</expected-linenumbers>
        <code><![CDATA[
public class TestFieldDeclarations {
    class Inner {
        void method1() { }
        private int field1; // violation 1
        private Inner anon = new Inner() { // violation 2 - field "anon"
            void method2() { }
            private int field2; // violation 3
        };
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False negative with anon classes (2)</description>
        <rule-property name="ignoreAnonymousClassDeclarations">true</rule-property>
        <expected-problems>2</expected-problems>
        <expected-linenumbers>4,7</expected-linenumbers>
        <code><![CDATA[
public class TestFieldDeclarations {
    class Inner {
        void method1() { }
        private int field1; // violation 1
        private Inner anon = new Inner() { // ignored due to ignoreAnonymousClassDeclarations
            void method2() { }
            private int field2; // violation 2
        };
    }
}
        ]]></code>
    </test-code>


    <test-code>
        <description>Initializers don't count</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public class MyClass {
                private static final String NAME;
                static {
                    NAME = "";
                }

                private final String name;
                {
                    name = "";
                }
                private String name2;

                public MyClass() {
                    this.name = "whatever";
                }
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>Check inside enums</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public enum MyClass {
                A,
                B;

                private final String name;

                public MyClass() {
                    this.name = "whatever";
                }
            }
            ]]></code>
    </test-code>
</test-data>
