Always wait for subtasks unless already failed

While it is valuable to be able to define tasks without
a pass criteria which can assume to be passed when they
are not failing, this probably does not quite make sense
when this task has subtasks, as it is expected that a
task will never pass unless its subtasks already passed.
Correct this behavior, and no longer ignore the state of
subtasks when there is a fail but no pass key defined.
If the task has not failed, but the subtasks have not
passed, then show the task as WAITING just as we would
if there were both a pass and a fail key defined.

Change-Id: Icf428ebe6099bc03fdb42942c88aee21b787dd76
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
index 7b1faf0..65cd203 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskAttributeFactory.java
@@ -204,11 +204,6 @@
           // to make a task have a FAIL status.
           return Status.FAIL;
         }
-        if (definition.pass == null) {
-          // A task with a FAIL but no PASS criteria is a PASS-FAIL task
-          // (they are never "READY").  It didn't fail, so pass.
-          return Status.PASS;
-        }
       }
 
       if (attribute.subTasks != null && !isAll(attribute.subTasks, Status.PASS)) {
diff --git a/src/main/resources/Documentation/task.md b/src/main/resources/Documentation/task.md
index 4a38c61..2b01f31 100644
--- a/src/main/resources/Documentation/task.md
+++ b/src/main/resources/Documentation/task.md
@@ -119,6 +119,12 @@
 one subtask is applicable. Setting this to "True" is useful for defining
 informational tasks that are not really expected to execute.
 
+A task with a `fail` key but no pass key has an implied `pass` key which is
+the opposite of the `fail` key as if the fail had a `NOT` in front of it.
+Such tasks can only pass, fail, or be waiting for their subtasks, they
+can never be ready! If they have not failed, and their subtasks have
+passed, they have passed also.
+
 Example:
 ```
     pass = label:verified+1
diff --git a/src/main/resources/Documentation/task_states.md b/src/main/resources/Documentation/task_states.md
index 0c29233..1365769 100644
--- a/src/main/resources/Documentation/task_states.md
+++ b/src/main/resources/Documentation/task_states.md
@@ -38,6 +38,21 @@
   applicable = is:open
   fail = is:open
 
+[root "Root PASS-waiting-fail"]
+  applicable = is:open
+  fail = NOT is:open
+  subtask = Subtask PASS
+
+[root "Root pass-WAITING-fail"]
+  applicable = is:open
+  fail = NOT is:open
+  subtask = Subtask FAIL
+
+[root "Root pass-waiting-FAIL"]
+  applicable = is:open
+  fail = is:open
+  subtask = Subtask PASS
+
 [root "Root grouping PASS (subtask PASS)"]
   subtask = Subtask PASS
 
@@ -488,6 +503,42 @@
                "status" : "FAIL"
             },
             {
+               "hasPass" : true,
+               "name" : "Root PASS-waiting-fail",
+               "status" : "PASS",
+               "subTasks" : [
+                  {
+                     "hasPass" : true,
+                     "name" : "Subtask PASS",
+                     "status" : "PASS"
+                  }
+               ]
+            },
+            {
+               "hasPass" : true,
+               "name" : "Root pass-WAITING-fail",
+               "status" : "WAITING",
+               "subTasks" : [
+                  {
+                     "hasPass" : true,
+                     "name" : "Subtask FAIL",
+                     "status" : "FAIL"
+                  }
+               ]
+            },
+            {
+               "hasPass" : true,
+               "name" : "Root pass-waiting-FAIL",
+               "status" : "FAIL",
+               "subTasks" : [
+                  {
+                     "hasPass" : true,
+                     "name" : "Subtask PASS",
+                     "status" : "PASS"
+                  }
+               ]
+            },
+            {
                "hasPass" : false,
                "name" : "Root grouping PASS (subtask PASS)",
                "status" : "PASS",
diff --git a/test/all b/test/all
index 6c4f10e..0a04577 100644
--- a/test/all
+++ b/test/all
@@ -60,6 +60,48 @@
             },
             {
                "applicable" : true,
+               "hasPass" : true,
+               "name" : "Root PASS-waiting-fail",
+               "status" : "PASS",
+               "subTasks" : [
+                  {
+                     "applicable" : true,
+                     "hasPass" : true,
+                     "name" : "Subtask PASS",
+                     "status" : "PASS"
+                  }
+               ]
+            },
+            {
+               "applicable" : true,
+               "hasPass" : true,
+               "name" : "Root pass-WAITING-fail",
+               "status" : "WAITING",
+               "subTasks" : [
+                  {
+                     "applicable" : true,
+                     "hasPass" : true,
+                     "name" : "Subtask FAIL",
+                     "status" : "FAIL"
+                  }
+               ]
+            },
+            {
+               "applicable" : true,
+               "hasPass" : true,
+               "name" : "Root pass-waiting-FAIL",
+               "status" : "FAIL",
+               "subTasks" : [
+                  {
+                     "applicable" : true,
+                     "hasPass" : true,
+                     "name" : "Subtask PASS",
+                     "status" : "PASS"
+                  }
+               ]
+            },
+            {
+               "applicable" : true,
                "hasPass" : false,
                "name" : "Root grouping PASS (subtask PASS)",
                "status" : "PASS",