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

    <code-fragment id="full-example"><![CDATA[
public class Foo {
  public static void bar() {
    boolean a, b = true;
    try { // total 8
      if (true) { // 2
        List buz = new ArrayList();
      }

      for(int i = 0; i < 19; i++) { // 3
        List buz = a ? new ArrayList() : null;
      }
    } catch(Exception e) {
      if (true) { // 2
        e.printStackTrace();
      }
    }

    int j = 0;
    if (true || a && b) { // 4
      j = 10;
      return;
    } else {
      j = 12;
    }

    j = a || b ? j + 1 : j; // 3

    while (j++ < 20) { // 2
      List buz = new ArrayList();
    }

    switch(j) { // 7
      case 1:
      case 2: break;
      case 3: j = 5; break;
      case 4: if (b && a) { bar(); } break;
      default: break;
    }

    do { // 3
        List buz = new ArrayList();
    } while (a && j++ < 30);

    if (b) { // 2
      return;
    }
  }
}
     ]]></code-fragment>


    <test-code>
        <description>Full example</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 8064.</message>
        </expected-messages>
        <code-ref id="full-example"/>
    </test-code>

    <test-code>
        <description>If with no else</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 2.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            boolean a;
            if (a) {
              bar();
            }
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>Nested if with no else</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 3.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            boolean a, b;
            if (a) {
              if (b) {
                bar();
              } else {
                a = true;
              }
            }
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>Nested if with else</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 4.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            boolean a, b;
            if (a) {
              if (b) {
                bar();
              } else {
                a = true;
              }
            } else {
              if (b) {
                b = false;
              } else {
                a = true;
              }
            }
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>Two ifs</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 4.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            boolean a, b;
            if (a) {}
            else {}

            if (b) {}
            else {}
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>Two ifs one else</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 4.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            boolean a, b;
            if (a) {}
            else {}

            if (b) {}
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>Two ifs and nested</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 6.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            boolean a, b;
            if (a) {
              if (b) {}
            } else {}

            if (b) {}
            else {}
          }
        }
        ]]></code>
    </test-code>


    <test-code>
        <description>Full switch</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 7.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            boolean a, b;
            int j = 23;
            switch(j) {
              case 1:
              case 2: break;
              case 3: j = 5; break;
              case 4: if (b && a) { bar(); } break;
              default: break;
            }
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>Ensure switch has same complexity as equivalent ifs</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 7.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            boolean a, b;
            int j = 23;
            if (j == 1 || j == 2) {
            } else if (j == 3) {
              j = 5;
            } else if (j == 4) {
              if (b && a) { bar(); }
            }
          }
        }
        ]]></code>
    </test-code>


    <test-code>
        <description>Boolean operators</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#bar()' has value 4.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          void bar() {
            if (a && b || c);
          }
        }
        ]]></code>
    </test-code>


    <code-fragment id="bug3484404"><![CDATA[
class Bar {
  public void x(boolean x, boolean y) {
    z((x ? 1 : 2), (y ? 3 : 4));
  }

  public int y(boolean x, boolean y) {
    return z((x ? 1 : 2), (y ? 3 : 4));
  }

  public int z(int x, int y) {
    return x + y;
  }
}
    ]]></code-fragment>

    <test-code>
        <description>Test case for bug 3484404 (Invalid NPath calculation in return statement)</description>
        <expected-problems>3</expected-problems>
        <expected-messages>
            <message>'Bar#x(boolean, boolean)' has value 4.</message>
            <message>'Bar#y(boolean, boolean)' has value 4.</message>
            <message>'Bar#z(int, int)' has value 1.</message>
        </expected-messages>
        <code-ref id="bug3484404"/>
    </test-code>


    <test-code>
        <description>NPath supports constructors</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Foo#Foo()' has value 7.</message>
        </expected-messages>
        <code><![CDATA[
        class Foo {
          Foo() {
            boolean a, b;
            int j = 23;
            switch(j) {
              case 1:
              case 2: break;
              case 3: j = 5; break;
              case 4: if (b && a) { bar(); } break;
              default: break;
            }
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>NPath should count the boolean complexity of ternaries</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Test#method(Date)' has value 4.</message>
        </expected-messages>
        <code><![CDATA[
        public class Test {
          public void method(Date a) {
            final long aTime = (a == null && a || b) ? 0L : a.getTime();
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>#01 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Test#method(Date)' has value 2.</message>
        </expected-messages>
        <code><![CDATA[
        public class Test {
          private static final long UNKNOWN = -1;

          public void method(Date a) {
            long aTime;

            if (a == null) {
              aTime = UNKNOWN;
            } else {
              aTime = a.getTime();
            }
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>#02 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'Test#method(Date)' has value 2.</message>
        </expected-messages>
        <code><![CDATA[
        public class Test {

          private static final long UNKNOWN = -1;

          public void method(Date a) {
            final long aTime = a == null ? UNKNOWN : a.getTime();
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>#1 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)</description>
        <rule-property name="reportLevel">6</rule-property>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'SOFExample#usefulMethod(List)' has value 272.</message>
        </expected-messages>
        <code><![CDATA[
        public class SOFExample {

          private final Map<String, Date> magicMap = new HashMap<String, Date>();
          protected static final long UNKNOWN = 0L;
          private static final class MyCal { long aTime; long bTime; long cTime; long dTime;}

          public void usefulMethod(final List<MyCal> myCals) {

            final Date a = magicMap.get("a");
            final Date b = magicMap.get("b");
            final Date c = magicMap.get("c");
            final Date d = magicMap.get("d");

            final long aTime = a == null ? UNKNOWN : a.getTime();
            final long bTime = b == null ? UNKNOWN : b.getTime();
            final long cTime = c == null ? UNKNOWN : c.getTime();
            final long dTime = d == null ? UNKNOWN : d.getTime();

            for (MyCal myCal : myCals) {
              if(myCal.aTime == UNKNOWN) myCal.aTime = aTime;
              if(myCal.bTime == UNKNOWN) myCal.bTime = bTime;
              if(myCal.cTime == UNKNOWN) myCal.cTime = cTime;
              if(myCal.dTime == UNKNOWN) myCal.dTime = dTime;
            }
          }
        }
        ]]></code>
    </test-code>

    <test-code>
        <description>#2 NPath should count ternaries like if - else constructs (https://stackoverflow.com/q/5079923/6245827)</description>
        <rule-property name="reportLevel">6</rule-property>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>'SOFExample#usefulMethod(List)' has value 272.</message>
        </expected-messages>
        <code><![CDATA[
        public class SOFExample {

          private final Map<String, Date> magicMap = new HashMap<String, Date>();
          protected static final long UNKNOWN = 0L;
          private static final class MyCal { long aTime; long bTime; long cTime; long dTime;}

          public void usefulMethod(final List<MyCal> myCals) {

            final Date a = magicMap.get("a");
            final Date b = magicMap.get("b");
            final Date c = magicMap.get("c");
            final Date d = magicMap.get("d");

            final long aTime;
            if (a == null) {
             aTime = a.getTime();
            } else {
             aTime = UNKNOWN;
            }

            final long bTime;
            if (b == null) {
             bTime = b.getTime();
            } else {
             bTime = UNKNOWN;
            }

            final long cTime;
            if (c == null) {
             cTime = c.getTime();
            } else {
             cTime = UNKNOWN;
            }

            final long dTime;
            if (d == null) {
             dTime = d.getTime();
            } else {
             dTime = UNKNOWN;
            }

            for (MyCal myCal : myCals) {
              if(myCal.aTime == UNKNOWN) myCal.aTime = aTime;
              if(myCal.bTime == UNKNOWN) myCal.bTime = bTime;
              if(myCal.cTime == UNKNOWN) myCal.cTime = cTime;
              if(myCal.dTime == UNKNOWN) myCal.dTime = dTime;
            }
          }
        }
        ]]></code>
    </test-code>
</test-data>
