{
  "schema": "https://bars.commonsware.com/conformance/schema/render-fixture.schema.json",
  "version": "0.1.0",
  "cases": [
    {
      "name": "truncate-default-ellipsis",
      "spotlight": true,
      "description": "Default ellipsis is \"...\"; ellipsis is included in the total length.",
      "template": "{{ phrase | truncate: 11 }}",
      "context": {
        "phrase": "Ground control to Major Tom"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "Ground c..."
      }
    },
    {
      "name": "truncate-custom-ellipsis",
      "spotlight": true,
      "description": "Custom ellipsis replaces the default and is counted toward total length.",
      "template": "{{ phrase | truncate: 11 \", and so on\" }}",
      "context": {
        "phrase": "Ground control to Major Tom"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": ", and so on"
      }
    },
    {
      "name": "truncate-input-shorter-than-length",
      "description": "When input is shorter than length, return input unchanged.",
      "template": "{{ phrase | truncate: 100 }}",
      "context": {
        "phrase": "short"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "short"
      }
    },
    {
      "name": "truncate-length-equals-input-length",
      "description": "When input length exactly matches the requested length, return input unchanged.",
      "template": "{{ phrase | truncate: 5 }}",
      "context": {
        "phrase": "short"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "short"
      }
    },
    {
      "name": "truncate-length-smaller-than-ellipsis",
      "description": "When length is smaller than the ellipsis length, return the first `length` chars of the ellipsis.",
      "template": "{{ phrase | truncate: 2 }}",
      "context": {
        "phrase": "hello world"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": ".."
      }
    },
    {
      "name": "truncate-empty-ellipsis",
      "description": "Empty ellipsis means a plain `take(length)` truncation.",
      "template": "{{ phrase | truncate: 5 \"\" }}",
      "context": {
        "phrase": "hello world"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "hello"
      }
    },
    {
      "name": "truncate-zero-args-is-error",
      "description": "Zero arguments is an arity error.",
      "template": "{{ phrase | truncate }}",
      "context": {
        "phrase": "hi"
      },
      "expect": {
        "kind": "error",
        "errorCode": "KB-2002"
      }
    },
    {
      "name": "truncate-three-args-is-error",
      "description": "Three arguments is an arity error.",
      "template": "{{ phrase | truncate: 1 \"a\" \"b\" }}",
      "context": {
        "phrase": "hi"
      },
      "expect": {
        "kind": "error",
        "errorCode": "KB-2002"
      }
    },
    {
      "name": "truncate-non-integer-length-is-null",
      "description": "Non-integer length is a soft failure, so truncate yields null.",
      "template": "{{ phrase | truncate: \"nope\" }}",
      "context": {
        "phrase": "hi"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "null"
      }
    },
    {
      "name": "truncate-negative-length-is-null",
      "description": "Negative length is a soft failure, so truncate yields null.",
      "template": "{{ phrase | truncate: -1 }}",
      "context": {
        "phrase": "hi"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "null"
      }
    },
    {
      "name": "truncate-astral-counts-code-points",
      "description": "Length counts code points, so truncating an all-astral string keeps whole characters rather than splitting a surrogate pair.",
      "template": "{{ s | truncate: 2 \"\" }}",
      "context": {
        "s": "😀😁😂🤣"
      },
      "expect": {
        "kind": "output",
        "expectedOutput": "😀😁"
      }
    }
  ]
}
