{
  "schema": "https://bars.commonsware.com/conformance/schema/render-fixture.schema.json",
  "version": "0.1.0",
  "cases": [
    {
      "name": "with-pushes-object-context",
      "description": "A {{#with}} block pushes a resolved object onto the context stack.",
      "template": "{{#with user }}{{ name }}{{/with}}",
      "context": {
        "user": {
          "name": "Alice"
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "Alice"
      }
    },
    {
      "name": "with-this-renders-pushed-context",
      "description": "{{this}} inside a with block renders the pushed context as JSON (unescaped, as it is not a string primitive).",
      "template": "{{#with user }}{{ this }}{{/with}}",
      "context": {
        "user": {
          "name": "Alice"
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "{\"name\":\"Alice\"}"
      }
    },
    {
      "name": "with-dot-shortcut",
      "description": "{{ . }} inside a with block renders the pushed context the same as {{this}} (unescaped, as it is not a string primitive).",
      "template": "{{#with user }}{{ . }}{{/with}}",
      "context": {
        "user": {
          "name": "Alice"
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "{\"name\":\"Alice\"}"
      }
    },
    {
      "name": "with-pop-restores-outer-context",
      "description": "After a with block ends, the outer context is restored and available to subsequent interpolations.",
      "template": "{{ /name }}|{{#with user }}{{ name }}{{/with}}|{{ /name }}",
      "context": {
        "name": "Outer",
        "user": {
          "name": "Inner"
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "Outer|Inner|Outer"
      }
    },
    {
      "name": "with-nested",
      "description": "With blocks can be nested, each pushing a new context onto the stack.",
      "template": "{{#with a }}{{#with b }}{{ c }}{{/with}}{{/with}}",
      "context": {
        "a": {
          "b": {
            "c": "deep"
          }
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "deep"
      }
    },
    {
      "name": "with-rfc6901-identifier",
      "description": "The identifier in a {{#with}} can be an RFC 6901 pointer.",
      "template": "{{#with /a/b }}{{ c }}{{/with}}",
      "context": {
        "a": {
          "b": {
            "c": "deep"
          }
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "deep"
      }
    },
    {
      "name": "with-dot-notation-identifier",
      "description": "The identifier in a {{#with}} can be dot-notation.",
      "template": "{{#with a.b }}{{ c }}{{/with}}",
      "context": {
        "a": {
          "b": {
            "c": "deep"
          }
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "deep"
      }
    },
    {
      "name": "with-this-identifier",
      "description": "{{#with this}} pushes the root context again, making it available to subsequent identifiers.",
      "template": "{{#with this }}{{ name }}{{/with}}",
      "context": {
        "name": "Alice"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "Alice"
      }
    },
    {
      "name": "with-array-top-rfc6901",
      "description": "When the pushed context is a JsonArray, RFC 6901 pointers into it work correctly.",
      "template": "{{#with items }}{{ /0/name }}{{/with}}",
      "context": {
        "items": [
          {
            "name": "first"
          }
        ]
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "first"
      }
    },
    {
      "name": "with-array-top-this",
      "description": "When the pushed context is a JsonArray, {{this}} renders it as JSON.",
      "template": "{{#with items }}{{ this }}{{/with}}",
      "context": {
        "items": [
          1,
          2,
          3
        ]
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "[1,2,3]"
      }
    },
    {
      "name": "with-missing-key-pushes-null-this-renders-null",
      "description": "When the identifier resolves to a missing key, null is pushed; {{this}} renders \"null\".",
      "template": "{{#with absent }}{{ this }}{{/with}}",
      "context": {
        "name": "Alice"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "null"
      }
    },
    {
      "name": "with-missing-key-then-identifier-is-null",
      "description": "When the pushed context is null, any non-this identifier yields null.",
      "template": "{{#with absent }}{{ x }}{{/with}}",
      "context": {
        "name": "Alice"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "null"
      }
    },
    {
      "name": "with-primitive-then-identifier-is-null",
      "description": "When the pushed context is a JsonPrimitive, any non-this identifier yields null.",
      "template": "{{#with name }}{{ x }}{{/with}}",
      "context": {
        "name": "Alice"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "null"
      }
    },
    {
      "name": "with-primitive-then-this-renders",
      "description": "When the pushed context is a JsonPrimitive, {{this}} renders it as a string.",
      "template": "{{#with name }}{{ this }}{{/with}}",
      "context": {
        "name": "Alice"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "Alice"
      }
    },
    {
      "name": "with-peer-blocks",
      "description": "Multiple with blocks at the same level each push and pop correctly, restoring the outer context between them.",
      "template": "{{#with a }}{{ n }}{{/with}}-{{#with b }}{{ n }}{{/with}}",
      "context": {
        "a": {
          "n": "A"
        },
        "b": {
          "n": "B"
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "A-B"
      }
    },
    {
      "name": "with-doubled-adjacent-with-same-key",
      "description": "Two adjacent {{#with}} blocks over the same key each push and pop independently; the second is unaffected by the first.",
      "template": "{{#with u }}{{ n }}{{/with}}{{#with u }}{{ n }}{{/with}}",
      "context": {
        "u": {
          "n": "Q"
        }
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "QQ"
      }
    }
  ]
}
