<?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>fail, == 0</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>5</expected-linenumbers>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static boolean bar(List lst) {
        if(lst.size() == 0){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>ok, isEmpty</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static boolean bar(List lst) {
        if(lst.isEmpty()){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>fail, != 0</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>5</expected-linenumbers>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static boolean bar(List lst) {
        if(lst.size() != 0){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>ok, !isEmpty</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static boolean bar(List lst) {
        if(!lst.isEmpty()){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>fail, != 0</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>5</expected-linenumbers>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static boolean bar(List lst, boolean b) {
        if(lst.size() == 0 && b){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>ok, !isEmpty</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static boolean bar(List lst, boolean b) {
        if(lst.isEmpty() && b){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>fail, 0 ==</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>5</expected-linenumbers>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static boolean bar(List lst) {
        if(0 == lst.size()){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>fail, &gt; 0</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>5</expected-linenumbers>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static boolean bar(List lst) {
        if(lst.size() > 0){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>ok, in expression</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;

public class Foo {
    public static int modulo = 2;
    public static boolean bar(List lst) {
        if(lst.size() % modulo == 0){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>ok, in expression</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.Map;

public class Foo {
    final Map map;
    public boolean bar(Foo other) {
        if (this.map.size() != other.map.size()){
            return true;
        }
        return false;
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1214 UseCollectionIsEmpty misses some usage</description>
        <expected-problems>10</expected-problems>
        <expected-linenumbers>8,11,14,17,20,23,26,29,32,35</expected-linenumbers>
        <code><![CDATA[
import java.util.*;

public class TestIsEmpty {
    public static void main(String args[]) {
        ArrayList<String> testObject = new ArrayList<String>();

        // These should be flagged
        if (testObject.size() == 0) {
            System.out.println("List is empty");
        }
        if (testObject.size() != 0) {
            System.out.println("List is empty");
        }
        if (0 == testObject.size()) {
            System.out.println("List is empty");
        }
        if (0 != testObject.size()) {
            System.out.println("List is empty");
        }
        if (testObject.size() > 0) {
            System.out.println("List is empty");
        }
        if (testObject.size() < 1) {
            System.out.println("List is empty");
        }
        if (0 < testObject.size()) {
            System.out.println("List is empty");
        }
        if (1 > testObject.size()) {
            System.out.println("List is empty");
        }
        if (new ArrayList().size() == 0) {
            System.out.println("New list starts empty");
        }
        if (GetArrayList().size() == 0) {
            System.out.println("List returned from function is empty");
        }

        // These should not be flagged
        if (GetBar().size() == 0) {
            System.out.println("This should not be flagged as it is not a list");
        }
    }
    public static ArrayList<String> GetArrayList() {
        return new ArrayList<String>();
    }
    public static SomeOtherObjectWithSizeMethod GetBar() {
        return new SomeOtherObjectWithSizeMethod();
    }
    class SomeOtherObjectWithSizeMethod {
        int size() {}
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1230 UseCollectionIsEmpty gets false positives</description>
        <expected-problems>4</expected-problems>
        <expected-linenumbers>8,11,24,27</expected-linenumbers>
        <code><![CDATA[
import java.util.ArrayList;

public class IsEmptyTest {
    public static void main(String args[]) {
        ArrayList<String> testObject = new ArrayList<String>();

        // These should be flagged
        if (testObject.size() < 1) { // line 8
            System.out.println("List is empty");
        }
        if (1 > testObject.size()) { // line 11
            System.out.println("List is empty");
        }

        // These should not be flagged
        if (testObject.size() <= 1) { // line 16
            System.out.println("List may or may not be empty");
        }
        if (1 >= testObject.size()) { // line 19
            System.out.println("List may or may not be empty");
        }

        // These should be flagged (as they are equivalent to != 0) and are not
        if (testObject.size() >= 1) { // line 24
            System.out.println("List is not empty");
        }
        if (1 <= testObject.size()) { // line 27
            System.out.println("List is not empty");
        }

        // These should not be flagged
        if (testObject.size() > 1) { // line 32
            System.out.println("List is not empty, but not all non-empty lists will trigger this");
        }
        if (1 < testObject.size()) { // line 35
            System.out.println("List is not empty, but not all non-empty lists will trigger this");
        }
        if (testObject.size() != 1) { // line 38
            System.out.println("List may or may not be empty");
        }
        if (1 != testObject.size()) { // line 41
            System.out.println("List may or may not be empty");
        }
        if (testObject.size() == 1) { // line 44
            System.out.println("List is not empty, but not all non-empty lists will trigger this");
        }
        if (1 == testObject.size()) { // line 47
            System.out.println("List is not empty, but not all non-empty lists will trigger this");
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1304 UseCollectionIsEmpty false positive comparing to 1</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.*;

public class PMDIsEmptyFalsePositive {
    public void falsePositive() {
        Collection<String> c = new ArrayList<String>();

        if (c.size() <= 1) // false positive
        {
            // do something
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1345 UseCollectionIsEmpty throws NullPointerException</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package org.oikarinen.pmdbugbait;
import java.util.List;

public class PmdBugBait {
    public int getSize() {
        return 0;
    }

    /**
     * "this." before the method call triggers the bug
     */
    public void compareSizeToThisPointMethod(List<String> list) {
        if (list.size() < this.getSize()) {
            throw new IllegalArgumentException();
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#2543 false negative on this.collection.size</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>10</expected-linenumbers>
        <code><![CDATA[
import java.util.List;
import java.util.ArrayList;

public class Foo {

    private List<String> list = new ArrayList<>();
    private Bar notACollection = new Bar();

    public void bar() {
        if (this.list.size() == 0) {
            throw new RuntimeException("Empty list");
        }
        if (notACollection.size() == 0) { }
        if (this.notACollection.size() == 0) { }
    }

    public int size() {
        return 0;
    }
    class Bar { int size() { return 0; } }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#2542 UseCollectionIsEmpty can not detect the case foo.bar().size()</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.List;
import java.util.ArrayList;

public class Foo {

    private List<String> list = new ArrayList<>();

    Foo foo() { return this; }
    Foo bar() { return this; }
    List<String> list() { return list; }

    public void bar() {
        if (foo().bar().foo().list().size() == 0) {
            throw new RuntimeException("Empty list");
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#2833 NPE in UseCollectionIsEmptyRule with enums</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
public enum ComponentSize {

    S("s");

    private String size;

    ComponentSize(String size) {
        this.size = size;
    }

    @Override
    public String toString() {
        return size;
    }

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

    <test-code>
        <description>#2833 NPE in UseCollectionIsEmptyRule with enums (sanity check)</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>11</expected-linenumbers>
        <code><![CDATA[
import java.util.List;

public enum ComponentSize {

    S("s");

    private List<String> list;
    private String size;

    ComponentSize(String size) {
        if (list.size() == 0) {
            this.size = size;
        }
    }

    @Override
    public String toString() {
        return size;
    }

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

    <test-code>
        <description>#2833 test with records</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>5</expected-linenumbers>
        <code><![CDATA[
import java.util.List;

public record CollectionRecord(List<String> theList) {
    public CollectionRecord {
        if (theList.size() == 0) throw new IllegalArgumentException("empty list");
        if (theList.isEmpty()) throw new IllegalArgumentException("empty list");
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#2833 test local var</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>6</expected-linenumbers>
        <code><![CDATA[
import java.util.ArrayList;

public class Foo {
    public static void main(String[] args) {
        var theList = new ArrayList<String>();
        if (theList.size() == 0) throw new IllegalArgumentException("empty list");
        if (theList.isEmpty()) throw new IllegalArgumentException("empty list");
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>With nested classes</description>
        <expected-problems>3</expected-problems>
        <expected-linenumbers>7,15,21</expected-linenumbers>
        <code><![CDATA[
import java.util.List;

public class Foo {
    void myMethod() {
        Object anonymous = new Object() {
            public boolean check(List lst) {
                if (lst.size() == 0) {
                    return true;
                }
                return false;
            }
        };
        class Local {
            public boolean check2(List lst) {
                return lst.size() == 0;
            }
        }
    }
    class Inner {
        public static boolean bar(List lst) {
            if(lst.size() == 0){
                return true;
            }
            return false;
        }
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>With records</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.Set;

public record Record(Set<String> stringSet) {

    public boolean hasMoreThanOneItem() {
        return this.stringSet.size() > 1;
    }
}        ]]></code>
    </test-code>
    <test-code>
        <description>With records and size check</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>6</expected-linenumbers>
        <code><![CDATA[
import java.util.Set;

public record Record(Set<String> stringSet) {

    public boolean hasMoreThanOneItem() {
        return this.stringSet.size() == 0;
    }
}        ]]></code>
    </test-code>

    <test-code>
        <description>[java] UseCollectionIsEmpty should infer local variable type from method invocation #3858</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>8</expected-linenumbers>
        <code><![CDATA[
import java.util.ArrayList;
import java.util.List;

public class Example {

    public void func() {
        var list = getList();
        if (list.size()>0) { // point 1:  false negative
            System.out.println("!list.isEmpty() is better!");
            // ...
        }
    }

    private List<String> getList() { // mock
        return new ArrayList<>();
    }
}
]]></code>
    </test-code>
</test-data>
