#######################################################
#
# Test the 'cancel' attribute of classes promises (CFE-4686).
#
# 'cancel' is a boolean (cfbool). A classes promise using 'cancel => "true"'
# undefines its promiser class. The triggering condition is the promise's own
# class-context guard, not an expression of its own. Unlike the class-defining
# attributes, a cancel promise must be evaluated even when the class is already
# defined.
#
#######################################################
body common control
{
  inputs => { "../../default.sub.cf" };
  bundlesequence => { default("$(this.promise_filename)") };
  version => "1.0";
}

#######################################################
bundle agent init
{
}

#######################################################
bundle agent test
{
  meta:
    "description" -> { "CFE-4686" }
      string => "classes promise 'cancel' attribute (cfbool) undefines a defined class when the promise guard is met";

  classes:
    # Define global classes so the check bundle can observe the outcome.
    "to_cancel"
      expression => "any",
      scope => "namespace";

    "to_cancel_alias"
      expression => "any",
      scope => "namespace";

    "to_keep_guard"
      expression => "any",
      scope => "namespace";

    "to_keep_false"
      expression => "any",
      scope => "namespace";

    "trigger"
      expression => "any",
      scope => "namespace";

    trigger::
      # Guard satisfied and cancel => "true": to_cancel must be undefined.
      "to_cancel" cancel => "true";

      # "yes" is an accepted boolean alias for "true".
      "to_cancel_alias" cancel => "yes";

    class_that_is_not_defined::
      # Guard not satisfied: to_keep_guard must be retained.
      "to_keep_guard" cancel => "true";

    any::
      # Guard satisfied but cancel => "false": no-op, to_keep_false retained.
      "to_keep_false" cancel => "false";

      # Cancelling a class that was never defined is a harmless no-op.
      "never_defined" cancel => "true";
}

#######################################################
bundle agent check
{
  classes:
    "ok"
      expression => "!to_cancel.!to_cancel_alias.to_keep_guard.to_keep_false.!never_defined.trigger";

  reports:
    ok::
      "$(this.promise_filename) Pass";

    !ok::
      "$(this.promise_filename) FAIL";
}
