{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "licensePlate",
  "title": {
    "en": "License plate",
    "pt-BR": "Placa de veículo"
  },
  "functions": [
    {
      "id": "licensePlate.convertToMercosul",
      "level": "core",
      "summary": "Converts an old-format Brazilian license plate (\"LLLNNNN\") to the Mercosul format (\"LLLNLNN\").",
      "description": "Converts an old-format plate (`LLLNNNN`) to the Mercosul format (`LLLNLNN`). The 5th character, a digit, becomes a letter, with `0` to `9` mapping to `A` to `J` (`ABC1234` becomes `ABC1C34`). The result is upper-cased and has no mask.\n\nThe conversion follows the table of Anexo II of Resolução CONTRAN nº 969/2022. Every other character stays as it is.\n\n- The plate is read like `licensePlate.isValid` reads it: any case, the mask (`ABC-1234`, `ABC 1234`) accepted, whitespace around it ignored, and a mask character or any other character in another position makes it invalid. Until 2.4.0 such characters were stripped, so `A-BC1234` was converted.\n- It returns an empty string, not `null`, when the value is not a valid old-format plate: a plate that is already Mercosul (`ABC1D23`), the withdrawn `LLLNNLN` sequence, a wrong length or an invalid value.\n- Pending decision (findings §1b): the reference (JS) also accepts the hyphen mask (`ABC-1234`). Other libraries reject it.\n- Pending decision (findings §2 #5): for a plate that is already Mercosul or is not a valid old-format plate, the reference (JS) returns an empty string. Most libraries return `null`.",
      "params": [
        {
          "name": "value",
          "type": "string"
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "licensePlate.convertToMercosul#old-format",
          "args": [
            "ABC1234"
          ],
          "expect": {
            "returns": "ABC1C34"
          }
        },
        {
          "id": "licensePlate.convertToMercosul#digit-0-to-A",
          "args": [
            "ABC0000"
          ],
          "expect": {
            "returns": "ABC0A00"
          }
        },
        {
          "id": "licensePlate.convertToMercosul#digit-9-to-J",
          "args": [
            "ABC9999"
          ],
          "expect": {
            "returns": "ABC9J99"
          }
        },
        {
          "id": "licensePlate.convertToMercosul#lowercase",
          "args": [
            "abc1234"
          ],
          "expect": {
            "returns": "ABC1C34"
          }
        },
        {
          "id": "licensePlate.convertToMercosul#hyphen-mask",
          "args": [
            "ABC-1234"
          ],
          "expect": {
            "returns": "ABC1C34"
          }
        },
        {
          "id": "licensePlate.convertToMercosul#already-mercosul",
          "args": [
            "ABC1D23"
          ],
          "expect": {
            "returns": ""
          },
          "note": "no conversion possible; the reference returns an empty string (asserted by its tests), several libs return null/None instead"
        },
        {
          "id": "licensePlate.convertToMercosul#invalid",
          "args": [
            "invalid"
          ],
          "expect": {
            "returns": ""
          },
          "note": "the reference returns an empty string (asserted by its tests), several libs return null/None instead"
        },
        {
          "id": "licensePlate.convertToMercosul#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          },
          "note": "the reference returns an empty string (asserted by its tests), several libs return null/None instead"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC12D3\"]",
          "args": [
            "ABC12D3"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is the withdrawn LLLNNLN sequence"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC1234EXTRA\"]",
          "args": [
            "ABC1234EXTRA"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is an old format plate followed by extra characters"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC12345\"]",
          "args": [
            "ABC12345"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is an old format plate followed by extra characters"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC123\"]",
          "args": [
            "ABC123"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is too short"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC1111\"]",
          "args": [
            "ABC1111"
          ],
          "expect": {
            "returns": "ABC1B11"
          },
          "note": "JavaScript's own test: should return the converted plate for a plate ending in each digit, per the official conversion table"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC2222\"]",
          "args": [
            "ABC2222"
          ],
          "expect": {
            "returns": "ABC2C22"
          },
          "note": "JavaScript's own test: should return the converted plate for a plate ending in each digit, per the official conversion table"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC3333\"]",
          "args": [
            "ABC3333"
          ],
          "expect": {
            "returns": "ABC3D33"
          },
          "note": "JavaScript's own test: should return the converted plate for a plate ending in each digit, per the official conversion table"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC4444\"]",
          "args": [
            "ABC4444"
          ],
          "expect": {
            "returns": "ABC4E44"
          },
          "note": "JavaScript's own test: should return the converted plate for a plate ending in each digit, per the official conversion table"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC5555\"]",
          "args": [
            "ABC5555"
          ],
          "expect": {
            "returns": "ABC5F55"
          },
          "note": "JavaScript's own test: should return the converted plate for a plate ending in each digit, per the official conversion table"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC6666\"]",
          "args": [
            "ABC6666"
          ],
          "expect": {
            "returns": "ABC6G66"
          },
          "note": "JavaScript's own test: should return the converted plate for a plate ending in each digit, per the official conversion table"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC7777\"]",
          "args": [
            "ABC7777"
          ],
          "expect": {
            "returns": "ABC7H77"
          },
          "note": "JavaScript's own test: should return the converted plate for a plate ending in each digit, per the official conversion table"
        },
        {
          "id": "licensePlate.convertToMercosul#[\"ABC8888\"]",
          "args": [
            "ABC8888"
          ],
          "expect": {
            "returns": "ABC8I88"
          },
          "note": "JavaScript's own test: should return the converted plate for a plate ending in each digit, per the official conversion table"
        }
      ]
    },
    {
      "id": "licensePlate.format",
      "level": "core",
      "summary": "Formats a Brazilian license plate.",
      "description": "Formats a license plate in upper case. Old-format plates (`LLLNNNN`) get a hyphen (`ABC-1234`). Mercosul plates (`LLLNLNN`) have no separator.\n\n- A partial value is formatted as far as it goes, so the function works as an input mask: the hyphen shows up as soon as the fourth character is a digit (`abc1` gives `ABC-1`), and a fifth character that is a letter keeps the Mercosul form (`abc1d` gives `ABC1D`).\n- Any character that is not an ASCII letter or digit is dropped first, and only the first 7 remain. Unlike `licensePlate.isValid`, the mask may sit anywhere.\n- Returns an empty string when the value cannot start a valid plate (`1234567`, `abc12d3`, `abc1da2`).\n- A value that is not a string returns an empty string.",
      "params": [
        {
          "name": "value",
          "type": "string"
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "licensePlate.format#[\"WDG1S21\"]",
          "args": [
            "WDG1S21"
          ],
          "expect": {
            "returns": "WDG1S21"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"WDG1S22\"]",
          "args": [
            "WDG1S22"
          ],
          "expect": {
            "returns": "WDG1S22"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"wdg1s21\"]",
          "args": [
            "wdg1s21"
          ],
          "expect": {
            "returns": "WDG1S21"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"GJG8U81\"]",
          "args": [
            "GJG8U81"
          ],
          "expect": {
            "returns": "GJG8U81"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"GJG8U82\"]",
          "args": [
            "GJG8U82"
          ],
          "expect": {
            "returns": "GJG8U82"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"gjg8u81\"]",
          "args": [
            "gjg8u81"
          ],
          "expect": {
            "returns": "GJG8U81"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"KDS4W15\"]",
          "args": [
            "KDS4W15"
          ],
          "expect": {
            "returns": "KDS4W15"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"KDS4W16\"]",
          "args": [
            "KDS4W16"
          ],
          "expect": {
            "returns": "KDS4W16"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"kds4w15\"]",
          "args": [
            "kds4w15"
          ],
          "expect": {
            "returns": "KDS4W15"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.format#[\"\"]",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test"
        },
        {
          "id": "licensePlate.format#[\"a\"]",
          "args": [
            "a"
          ],
          "expect": {
            "returns": "A"
          },
          "note": "JavaScript's own test"
        },
        {
          "id": "licensePlate.format#[\"ab\"]",
          "args": [
            "ab"
          ],
          "expect": {
            "returns": "AB"
          },
          "note": "JavaScript's own test"
        },
        {
          "id": "licensePlate.format#[\"abc\"]",
          "args": [
            "abc"
          ],
          "expect": {
            "returns": "ABC"
          },
          "note": "JavaScript's own test"
        },
        {
          "id": "licensePlate.format#[\"abc1\"]",
          "args": [
            "abc1"
          ],
          "expect": {
            "returns": "ABC-1"
          },
          "note": "JavaScript's own test"
        },
        {
          "id": "licensePlate.format#[\"abc12\"]",
          "args": [
            "abc12"
          ],
          "expect": {
            "returns": "ABC-12"
          },
          "note": "JavaScript's own test: should format old pattern license plates"
        },
        {
          "id": "licensePlate.format#[\"abc123\"]",
          "args": [
            "abc123"
          ],
          "expect": {
            "returns": "ABC-123"
          },
          "note": "JavaScript's own test: should format old pattern license plates"
        },
        {
          "id": "licensePlate.format#[\"abc1234\"]",
          "args": [
            "abc1234"
          ],
          "expect": {
            "returns": "ABC-1234"
          },
          "note": "JavaScript's own test: should format old pattern license plates"
        },
        {
          "id": "licensePlate.format#[\"abc1d\"]",
          "args": [
            "abc1d"
          ],
          "expect": {
            "returns": "ABC1D"
          },
          "note": "JavaScript's own test: should keep mercosul plates normalized"
        },
        {
          "id": "licensePlate.format#[\"abc1d2\"]",
          "args": [
            "abc1d2"
          ],
          "expect": {
            "returns": "ABC1D2"
          },
          "note": "JavaScript's own test: should keep mercosul plates normalized"
        },
        {
          "id": "licensePlate.format#[\"abc1d23\"]",
          "args": [
            "abc1d23"
          ],
          "expect": {
            "returns": "ABC1D23"
          },
          "note": "JavaScript's own test: should keep mercosul plates normalized"
        },
        {
          "id": "licensePlate.format#[\"abc-1234\"]",
          "args": [
            "abc-1234"
          ],
          "expect": {
            "returns": "ABC-1234"
          },
          "note": "JavaScript's own test: should remove non alphanumeric characters"
        },
        {
          "id": "licensePlate.format#[\"abc1-d23\"]",
          "args": [
            "abc1-d23"
          ],
          "expect": {
            "returns": "ABC1D23"
          },
          "note": "JavaScript's own test: should remove non alphanumeric characters"
        },
        {
          "id": "licensePlate.format#[\"abc1da2\"]",
          "args": [
            "abc1da2"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when the tail matches no supported format"
        },
        {
          "id": "licensePlate.format#[\"abc12d\"]",
          "args": [
            "abc12d"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when the tail matches no supported format"
        },
        {
          "id": "licensePlate.format#[\"abc12d3\"]",
          "args": [
            "abc12d3"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when the tail matches no supported format"
        },
        {
          "id": "licensePlate.format#[\"1\"]",
          "args": [
            "1"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when a digit appears within the first three characters"
        },
        {
          "id": "licensePlate.format#[\"1ab4\"]",
          "args": [
            "1ab4"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when a digit appears within the first three characters"
        },
        {
          "id": "licensePlate.format#[\"ab14\"]",
          "args": [
            "ab14"
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when a digit appears within the first three characters"
        }
      ]
    },
    {
      "id": "licensePlate.generate",
      "level": "core",
      "summary": "Generates a valid random Brazilian license plate.",
      "description": "Generates a valid random license plate, unformatted.\n\n- `format` is `LLLNLNN` (Mercosul, the default) or `LLLNNNN` (old format). Any other value falls back to the default.\n- The fifth character of a Mercosul plate is drawn from `K` to `Z`. `A` to `J` is used only to convert an old-format plate (Resolução CONTRAN nº 969/2022, Anexo II, item 2), so a new plate never carries it. Until 2.4.0 it could be any letter.\n- A format outside the two literals falls back to the default, so the result is always a plate `licensePlate.isValid` accepts. Version 2.3.0 used an unknown string verbatim.\n- It uses a non-cryptographic random source.",
      "params": [
        {
          "name": "format",
          "type": "\"LLLNNNN\" | \"LLLNLNN\"",
          "optional": true
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "licensePlate.generate#generated-is-valid",
          "args": [],
          "expect": {
            "satisfies": "licensePlate.isValid"
          },
          "repeat": 5,
          "note": "every generated value must pass the lib's own validator"
        },
        {
          "id": "licensePlate.generate#mercosul-fifth-char-k-to-z",
          "args": [],
          "expect": {
            "matches": "^[A-Z]{3}[0-9][K-Z][0-9]{2}$"
          },
          "repeat": 30,
          "note": "changed in 2.5.0 (#615): the fifth character of a new Mercosul plate is K to Z"
        },
        {
          "id": "licensePlate.generate#explicit-mercosul",
          "args": [
            "LLLNLNN"
          ],
          "expect": {
            "matches": "^[A-Z]{3}[0-9][K-Z][0-9]{2}$"
          },
          "repeat": 30,
          "note": "JavaScript's own test: the Mercosul format draws the fifth character from K to Z"
        },
        {
          "id": "licensePlate.generate#old-format",
          "args": [
            "LLLNNNN"
          ],
          "expect": {
            "matches": "^[A-Z]{3}[0-9]{4}$"
          },
          "repeat": 10,
          "note": "JavaScript docs example: generateLicensePlate(\"LLLNNNN\")"
        },
        {
          "id": "licensePlate.generate#unknown-format-falls-back",
          "args": [
            "LLLNNLN"
          ],
          "expect": {
            "matches": "^[A-Z]{3}[0-9][K-Z][0-9]{2}$"
          },
          "repeat": 30,
          "note": "an unknown format falls back to the Mercosul default (the withdrawn motorcycle sequence is not generated)"
        },
        {
          "id": "licensePlate.generate#bogus-format-falls-back",
          "args": [
            "bogus"
          ],
          "expect": {
            "satisfies": "licensePlate.isValid"
          },
          "repeat": 5,
          "note": "an unknown format falls back to the default"
        }
      ]
    },
    {
      "id": "licensePlate.getFormat",
      "level": "core",
      "summary": "Identifies the format of a Brazilian license plate.",
      "description": "Detects the format of a license plate: `LLLNNNN` for the old format, `LLLNLNN` for Mercosul.\n\n- The plate is read like `licensePlate.isValid` reads it: any case, whitespace around it ignored, and the mask (whitespace, `.`, `-` or `/`) accepted only between the third character and the last four. A mask character anywhere else, or any other character, makes the value invalid. Until 2.4.0 such characters were stripped, so `A-BC1234` gave `LLLNNNN`.\n- Returns `null` when the value is not 7 letters and digits in one of the two formats, including the withdrawn `LLLNNLN` sequence.\n- It returns `null` exactly when `licensePlate.isValid` returns `false`.\n- Pending decision (findings §1): Erlang returns named formats instead of the patterns.",
      "params": [
        {
          "name": "value",
          "type": "string"
        }
      ],
      "returns": "string?",
      "cases": [
        {
          "id": "licensePlate.getFormat#[\"WDG1S21\"]",
          "args": [
            "WDG1S21"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"WDG1S22\"]",
          "args": [
            "WDG1S22"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"wdg1s21\"]",
          "args": [
            "wdg1s21"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"GJG8U81\"]",
          "args": [
            "GJG8U81"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"GJG8U82\"]",
          "args": [
            "GJG8U82"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"gjg8u81\"]",
          "args": [
            "gjg8u81"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"KDS4W15\"]",
          "args": [
            "KDS4W15"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"KDS4W16\"]",
          "args": [
            "KDS4W16"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"kds4w15\"]",
          "args": [
            "kds4w15"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "licensePlate.getFormat#[\"ABC1234\"]",
          "args": [
            "ABC1234"
          ],
          "expect": {
            "returns": "LLLNNNN"
          },
          "note": "JavaScript's own test: should identify supported formats"
        },
        {
          "id": "licensePlate.getFormat#[\"ABC1D23\"]",
          "args": [
            "ABC1D23"
          ],
          "expect": {
            "returns": "LLLNLNN"
          },
          "note": "JavaScript's own test: should identify supported formats"
        },
        {
          "id": "licensePlate.getFormat#[\"ABC12D3\"]",
          "args": [
            "ABC12D3"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null for the withdrawn motorcycle sequence"
        },
        {
          "id": "licensePlate.getFormat#[\"ABC1234EXTRA\"]",
          "args": [
            "ABC1234EXTRA"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null when the value has extra characters beyond the license plate length"
        },
        {
          "id": "licensePlate.getFormat#[\"invalid\"]",
          "args": [
            "invalid"
          ],
          "expect": {
            "returns": null
          },
          "note": "JavaScript's own test: should return null when the value does not match any supported format"
        }
      ]
    },
    {
      "id": "licensePlate.isValid",
      "level": "core",
      "summary": "Checks whether a Brazilian license plate is valid.",
      "description": "Validates a license plate in the old format (`ABC1234`) or the Mercosul format (`ABC1D23`), in any case, with or without a hyphen or space.\n\n- `options.format` restricts the check to one format: `\"LLLNNNN\"` (old, `ABC1234`) or `\"LLLNLNN\"` (Mercosul, `ABC1D23`), the codes `licensePlate.getFormat` returns and `licensePlate.generate` takes. Without it, or with any other value, both formats are accepted. Until 2.4.0 the option did not exist and both formats were always accepted.\n- Any other sequence of letters and digits, or extra characters, makes it invalid.\n- The mask (whitespace, `.`, `-` or `/`, alone or in a run) is accepted only between the third character and the last four, whitespace around the plate is ignored, and the check is case-insensitive.\n- A mask character anywhere else, or any other character (`A@BC1234`, an emoji), makes the plate invalid instead of being stripped. Until 2.4.0 such characters were stripped (`A@B#C1$2%3^4` was `true`).\n- `licensePlate.getFormat` returns `null` exactly when this returns `false`.\n- The withdrawn motorcycle sequence `LLLNNLN` (`ABC12D3`) is invalid.",
      "params": [
        {
          "name": "value",
          "type": "string"
        },
        {
          "name": "options",
          "type": "IsValidLicensePlateOptions",
          "optional": true
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "licensePlate.isValid#[\"WDG1S21\"]",
          "args": [
            "WDG1S21"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"WDG1S22\"]",
          "args": [
            "WDG1S22"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"wdg1s21\"]",
          "args": [
            "wdg1s21"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"GJG8U81\"]",
          "args": [
            "GJG8U81"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"GJG8U82\"]",
          "args": [
            "GJG8U82"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"gjg8u81\"]",
          "args": [
            "gjg8u81"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"KDS4W15\"]",
          "args": [
            "KDS4W15"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"KDS4W16\"]",
          "args": [
            "KDS4W16"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"kds4w15\"]",
          "args": [
            "kds4w15"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"\"]",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"   \"]",
          "args": [
            "   "
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"abc\"]",
          "args": [
            "abc"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 3 libs (javascript, python, ruby)"
        },
        {
          "id": "licensePlate.isValid#[\"abc12345\"]",
          "args": [
            "abc12345"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when brazilian license plate format is invalid"
        },
        {
          "id": "licensePlate.isValid#[\"5abc1234\"]",
          "args": [
            "5abc1234"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when brazilian license plate format is invalid"
        },
        {
          "id": "licensePlate.isValid#[\"abcd1234\"]",
          "args": [
            "abcd1234"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when brazilian license plate format is invalid"
        },
        {
          "id": "licensePlate.isValid#[\"abcd234\"]",
          "args": [
            "abcd234"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when brazilian license plate format is invalid"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1234EXTRA\"]",
          "args": [
            "ABC1234EXTRA"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has extra characters beyond the license plate length"
        },
        {
          "id": "licensePlate.isValid#[\"ABC12D3\"]",
          "args": [
            "ABC12D3"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it uses the withdrawn motorcycle sequence"
        },
        {
          "id": "licensePlate.isValid#[\"abc12d3\"]",
          "args": [
            "abc12d3"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it uses the withdrawn motorcycle sequence"
        },
        {
          "id": "licensePlate.isValid#[\"abc1234\"]",
          "args": [
            "abc1234"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when brazilian license plate format is valid"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1234\"]",
          "args": [
            "ABC1234"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when brazilian license plate format is valid"
        },
        {
          "id": "licensePlate.isValid#[\"abc-1234\"]",
          "args": [
            "abc-1234"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when brazilian license plate format is valid"
        },
        {
          "id": "licensePlate.isValid#[\"ABC-1234\"]",
          "args": [
            "ABC-1234"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when brazilian license plate format is valid"
        },
        {
          "id": "licensePlate.isValid#[\"abc1d23\"]",
          "args": [
            "abc1d23"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when mercosul license plate format is valid"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1D23\"]",
          "args": [
            "ABC1D23"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when mercosul license plate format is valid"
        },
        {
          "id": "licensePlate.isValid#[\"ABC 1234\"]",
          "args": [
            "ABC 1234"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when it has a whitespace mask"
        },
        {
          "id": "licensePlate.isValid#[\"  abc1234 \"]",
          "args": [
            "  abc1234 "
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when it has a whitespace mask"
        },
        {
          "id": "licensePlate.isValid#[\"ABC-1D23\"]",
          "args": [
            "ABC-1D23"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when the mercosul format has a hyphen mask"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1D23\",{\"format\":\"LLLNLNN\"}]",
          "args": [
            "ABC1D23",
            {
              "format": "LLLNLNN"
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "options.format restricts the check to one format"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1D23\",{\"format\":\"LLLNNNN\"}]",
          "args": [
            "ABC1D23",
            {
              "format": "LLLNNNN"
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "options.format restricts the check to one format"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1234\",{\"format\":\"LLLNNNN\"}]",
          "args": [
            "ABC1234",
            {
              "format": "LLLNNNN"
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "options.format restricts the check to one format"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1234\",{\"format\":\"LLLNLNN\"}]",
          "args": [
            "ABC1234",
            {
              "format": "LLLNLNN"
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "options.format restricts the check to one format"
        },
        {
          "id": "licensePlate.isValid#[\"abc1d23\",{\"format\":\"LLLNLNN\"}]",
          "args": [
            "abc1d23",
            {
              "format": "LLLNLNN"
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "options.format restricts the check to one format, in any case"
        },
        {
          "id": "licensePlate.isValid#[\"ABC12D3\",{\"format\":\"LLLNLNN\"}]",
          "args": [
            "ABC12D3",
            {
              "format": "LLLNLNN"
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "the withdrawn motorcycle sequence stays invalid with a format"
        },
        {
          "id": "licensePlate.isValid#[\"abc\",{\"format\":\"LLLNNNN\"}]",
          "args": [
            "abc",
            {
              "format": "LLLNNNN"
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "an invalid plate stays invalid with a format"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1D23\",{\"format\":\"mercosul\"}]",
          "args": [
            "ABC1D23",
            {
              "format": "mercosul"
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "any other format value is ignored: both formats are accepted"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1234\",{}]",
          "args": [
            "ABC1234",
            {}
          ],
          "expect": {
            "returns": true
          },
          "note": "no format: both formats are accepted"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1234!\"]",
          "args": [
            "ABC1234!"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#615): a character outside the mask makes the plate invalid; JavaScript docs example"
        },
        {
          "id": "licensePlate.isValid#[\"A@BC1234\"]",
          "args": [
            "A@BC1234"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#615): a character outside the mask makes the plate invalid"
        },
        {
          "id": "licensePlate.isValid#[\"A@B#C1$2%3^4\"]",
          "args": [
            "A@B#C1$2%3^4"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#615): was true in 2.4.0 (the characters were stripped)"
        },
        {
          "id": "licensePlate.isValid#[\"ABC1234😀\"]",
          "args": [
            "ABC1234😀"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#615): an emoji makes the plate invalid"
        },
        {
          "id": "licensePlate.isValid#[\"A-BC1234\"]",
          "args": [
            "A-BC1234"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#615): the mask sits after the third character only; JavaScript docs example"
        },
        {
          "id": "licensePlate.isValid#[\"AB-C1234\"]",
          "args": [
            "AB-C1234"
          ],
          "expect": {
            "returns": false
          },
          "note": "the mask sits after the third character only"
        },
        {
          "id": "licensePlate.isValid#[\"ABC12-34\"]",
          "args": [
            "ABC12-34"
          ],
          "expect": {
            "returns": false
          },
          "note": "the mask sits after the third character only"
        },
        {
          "id": "licensePlate.isValid#[\"ABC.1234\"]",
          "args": [
            "ABC.1234"
          ],
          "expect": {
            "returns": true
          },
          "note": "the dot is a mask character"
        },
        {
          "id": "licensePlate.isValid#[\"ABC/1234\"]",
          "args": [
            "ABC/1234"
          ],
          "expect": {
            "returns": true
          },
          "note": "the slash is a mask character"
        },
        {
          "id": "licensePlate.isValid#[\"ABC - 1234\"]",
          "args": [
            "ABC - 1234"
          ],
          "expect": {
            "returns": true
          },
          "note": "a run of mask characters is accepted"
        },
        {
          "id": "licensePlate.isValid#[\"ABC-1234\",{\"format\":\"LLLNNNN\"}]",
          "args": [
            "ABC-1234",
            {
              "format": "LLLNNNN"
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript docs example"
        }
      ]
    },
    {
      "id": "licensePlate.parse",
      "level": "extended",
      "summary": "Removes the formatting characters of a license plate and returns only the letters and digits, in upper case.",
      "description": "Removes every character that is not an ASCII letter or digit from a license plate, upper-cases it and caps it at 7 characters (`abc-1234` gives `ABC1234`).\n\n- It does not validate: use `licensePlate.isValid` for that. The mask may sit anywhere, unlike in `licensePlate.isValid`.\n- A value that is not a string returns an empty string.",
      "params": [
        {
          "name": "value",
          "type": "string"
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "licensePlate.parse#old-format-masked",
          "args": [
            "abc-1234"
          ],
          "expect": {
            "returns": "ABC1234"
          }
        },
        {
          "id": "licensePlate.parse#mercosul-lowercase",
          "args": [
            "abc1d23"
          ],
          "expect": {
            "returns": "ABC1D23"
          }
        },
        {
          "id": "licensePlate.parse#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          }
        },
        {
          "id": "licensePlate.parse#caps-length",
          "args": [
            "abc123456"
          ],
          "expect": {
            "returns": "ABC1234"
          },
          "note": "reference truncates to 7 characters; asserted by the reference (JS) unit tests"
        },
        {
          "id": "licensePlate.parse#[\"WDG1S21\"]",
          "args": [
            "WDG1S21"
          ],
          "expect": {
            "returns": "WDG1S21"
          },
          "note": "consensus of 3 libs (python, ruby, rust)"
        },
        {
          "id": "licensePlate.parse#[\"WDG1S22\"]",
          "args": [
            "WDG1S22"
          ],
          "expect": {
            "returns": "WDG1S22"
          },
          "note": "consensus of 3 libs (python, ruby, rust)"
        },
        {
          "id": "licensePlate.parse#[\"GJG8U81\"]",
          "args": [
            "GJG8U81"
          ],
          "expect": {
            "returns": "GJG8U81"
          },
          "note": "consensus of 3 libs (python, ruby, rust)"
        },
        {
          "id": "licensePlate.parse#[\"GJG8U82\"]",
          "args": [
            "GJG8U82"
          ],
          "expect": {
            "returns": "GJG8U82"
          },
          "note": "consensus of 3 libs (python, ruby, rust)"
        },
        {
          "id": "licensePlate.parse#[\"KDS4W15\"]",
          "args": [
            "KDS4W15"
          ],
          "expect": {
            "returns": "KDS4W15"
          },
          "note": "consensus of 3 libs (python, ruby, rust)"
        },
        {
          "id": "licensePlate.parse#[\"KDS4W16\"]",
          "args": [
            "KDS4W16"
          ],
          "expect": {
            "returns": "KDS4W16"
          },
          "note": "consensus of 3 libs (python, ruby, rust)"
        },
        {
          "id": "licensePlate.parse#[\"abc1d23xyz\"]",
          "args": [
            "abc1d23xyz"
          ],
          "expect": {
            "returns": "ABC1D23"
          },
          "note": "JavaScript's own test: should ignore characters after the license plate length"
        }
      ]
    }
  ]
}
