{
  "schema": "https://bars.commonsware.com/conformance/schema/render-fixture.schema.json",
  "version": "0.1.0",
  "cases": [
    {
      "name": "lt-numbers",
      "description": "Rule (2) numeric: 1 < 2.",
      "template": "{{ a < b }}",
      "context": {
        "a": 1,
        "b": 2
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "lt-equal-numbers",
      "description": "Rule (2) numeric: 2 < 2 is false (strict).",
      "template": "{{ a < b }}",
      "context": {
        "a": 2,
        "b": 2
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      }
    },
    {
      "name": "le-equal-numbers",
      "description": "Rule (2) numeric: 2 <= 2 is true (inclusive).",
      "template": "{{ a <= b }}",
      "context": {
        "a": 2,
        "b": 2
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "gt-numbers",
      "description": "Rule (2) numeric: 3 > 2.",
      "template": "{{ a > b }}",
      "context": {
        "a": 3,
        "b": 2
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "ge-equal-numbers",
      "description": "Rule (2) numeric: 2 >= 2 is true.",
      "template": "{{ a >= b }}",
      "context": {
        "a": 2,
        "b": 2
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "lt-int-vs-double",
      "description": "Rule (2) numeric: mixed integer/decimal numeric comparison via Double.",
      "template": "{{ a < b }}",
      "context": {
        "a": 1,
        "b": 1.5
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "lt-strings",
      "description": "Rule (1) string side: lexicographic ordering.",
      "template": "{{ a < b }}",
      "context": {
        "a": "apple",
        "b": "banana"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "gt-strings",
      "description": "Rule (1) string side: lexicographic ordering.",
      "template": "{{ a > b }}",
      "context": {
        "a": "z",
        "b": "a"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "lt-string-vs-number",
      "description": "Rule (1) wins over rule (2): when one side is a string, both render to strings. '9'.compareTo('10') > 0, so '9' < 10 is false.",
      "template": "{{ a < b }}",
      "context": {
        "a": "9",
        "b": 10
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      }
    },
    {
      "name": "gt-string-vs-number",
      "description": "Mirror of lt-string-vs-number: '9' > 10 is true under string compare.",
      "template": "{{ a > b }}",
      "context": {
        "a": "9",
        "b": 10
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "lt-bool-vs-bool",
      "description": "Rule (3) fallback: no string operand, not both numeric; result is false and a KB-5004 ComparisonMismatch soft failure is reported.",
      "template": "{{ a < b }}",
      "context": {
        "a": true,
        "b": false
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      },
      "expectedSoftFails": ["KB-5004"]
    },
    {
      "name": "gt-null-vs-number",
      "description": "Rule (3) fallback: null operand without a string side; result is false and a KB-5004 ComparisonMismatch soft failure is reported.",
      "template": "{{ a > b }}",
      "context": {
        "a": null,
        "b": 5
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      },
      "expectedSoftFails": ["KB-5004"]
    },
    {
      "name": "ge-null-vs-null",
      "description": "Rule (3) fallback: ordered comparisons do not coalesce equal nulls to true; result is false and a KB-5004 ComparisonMismatch soft failure is reported.",
      "template": "{{ a >= b }}",
      "context": {
        "a": null,
        "b": null
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      },
      "expectedSoftFails": ["KB-5004"]
    },
    {
      "name": "ge-string-vs-null",
      "description": "Rule (1) string side wins: 'x'.compareTo('null') > 0, so 'x' >= null is true.",
      "template": "{{ a >= b }}",
      "context": {
        "a": "x",
        "b": null
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "lt-block-each-else",
      "description": "An #each whose expression resolves to a boolean (not array/object) renders the else arm.",
      "template": "{{#each a < b }}body{{else}}else{{/each}}",
      "context": {
        "a": 1,
        "b": 2
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "else"
      }
    },
    {
      "name": "gt-in-if-block",
      "description": "Comparison operator inside an #if expression slot.",
      "template": "{{#if count > 0 }}HAS{{else}}NONE{{/if}}",
      "context": {
        "count": 3
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "HAS"
      }
    },
    {
      "name": "le-block-with",
      "description": "LE operator inside a #with block.",
      "template": "{{#with item }}{{#if /price <= 100 }}AFFORDABLE{{else}}EXPENSIVE{{/if}}{{/with}}",
      "context": {
        "item": {
          "price": 50
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "AFFORDABLE"
      }
    },
    {
      "name": "gt-block-each-iteration",
      "description": "GT operator inside an #each block, filtering items.",
      "template": "{{#each items }}{{#if /quantity > 0 }}(yes){{else}}(no){{/if}}{{/each}}",
      "context": {
        "items": [
          {
            "quantity": 1
          },
          {
            "quantity": 0
          },
          {
            "quantity": 5
          }
        ]
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "(yes)(no)(yes)"
      }
    },
    {
      "name": "ge-with-numeric",
      "description": "GE operator in an interpolation with numeric literals.",
      "template": "{{ 100 >= 50 }}",
      "context": {},
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "le-string-literal",
      "description": "LE operator comparing string literals lexicographically.",
      "template": "{{ \"apple\" <= \"banana\" }}",
      "context": {},
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "gt-larger-number",
      "description": "GT operator with first operand larger.",
      "template": "{{ a > b }}",
      "context": {
        "a": 10,
        "b": 5
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "le-smaller-number",
      "description": "LE operator with first operand smaller.",
      "template": "{{ a <= b }}",
      "context": {
        "a": 3,
        "b": 8
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "ge-boolean-operand-false-result",
      "description": "GE with boolean operand returns false (fallback rule) and reports a KB-5004 ComparisonMismatch soft failure.",
      "template": "{{ a >= false }}",
      "context": {
        "a": true
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      },
      "expectedSoftFails": ["KB-5004"]
    },
    {
      "name": "le-with-string-right",
      "description": "LE with string on the right side for branch coverage.",
      "template": "{{ 5 <= \"10\" }}",
      "context": {},
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      }
    },
    {
      "name": "ge-with-string-right",
      "description": "GE with string on the right side for branch coverage.",
      "template": "{{ \"50\" >= 100 }}",
      "context": {},
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "ge-numbers-less-than",
      "description": "GE with numeric operands where first is less than second.",
      "template": "{{ 5 >= 10 }}",
      "context": {},
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      }
    },
    {
      "name": "le-explicit-numeric-comparison",
      "description": "LE with explicit numeric context variables.",
      "template": "{{ a <= b }}",
      "context": {
        "a": 100,
        "b": 200
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "true"
      }
    },
    {
      "name": "lt-with-identifier-null-fallback",
      "description": "LT with an unresolved identifier reports KB-5005 UnresolvedReference for the miss, then the resulting null participates in the Rule (3) fallback comparison and reports KB-5004 ComparisonMismatch; result is false.",
      "template": "{{ missing < 5 }}",
      "context": {},
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      },
      "expectedSoftFails": ["KB-5005", "KB-5004"]
    },
    {
      "name": "lt-numeric-vs-null",
      "description": "Rule (3) fallback when one side is numeric and the other is JsonNull: no string side, only one side is numeric; result is false and a KB-5004 ComparisonMismatch soft failure is reported.",
      "template": "{{ a < b }}",
      "context": {
        "a": 5,
        "b": null
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "false"
      },
      "expectedSoftFails": ["KB-5004"]
    }
  ]
}
