{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "vin",
  "title": {
    "en": "VIN (chassis)",
    "pt-BR": "Chassi (VIN)"
  },
  "functions": [
    {
      "id": "vin.isValid",
      "level": "extended",
      "summary": "Checks whether a VIN (Vehicle Identification Number / chassi) is valid.",
      "description": "Validates a VIN (chassi): 17 characters in the three sections of Resolução CONTRAN nº 968/2022, art. 3º (WMI, VDS and VIS), each a digit or a letter other than `I`, `O` and `Q`. The check ignores case and surrounding whitespace.\n\n- The Brazilian rule does not require a check digit, and many Brazilian-built VINs do not carry one, so by default the function does not check it: `9BWZZZ377VT004251` is valid. 2.4.0 always required the North American check digit.\n- `options.checkDigit: true` adds the North American rules of 49 CFR 565.15: the 9th character must be the weighted modulus 11 check digit (`0` to `9` or `X`), and the 10th (model year) cannot be `U`, `Z` or `0`. Use it for a vehicle built for the United States or Canada, or to keep the 2.4.0 result.\n- The `I`, `O` and `Q` exclusion comes from ISO 3779:2009, not from the resolution: the resolution lists no forbidden character and leaves the engraving to ABNT NBR 6066:2022 (art. 5º). The regularization VINs of its Anexo II (WMI `XXX`) are written without those letters, so they pass.\n- A VIN has no printed grouping, so a space, `.`, `-` or `/` inside it makes the value invalid.\n- A VIN whose characters are all the same is rejected.\n- Only the ASCII letters and digits count. A non-ASCII letter that upper-cases into an ASCII one (`ß`, `ſ`) is rejected. Until 2.4.0 these characters were folded into ASCII letters.\n- `options.checkDigit` defaults to `false`.",
      "params": [
        {
          "name": "value",
          "type": "string"
        },
        {
          "name": "options",
          "type": "IsValidVinOptions",
          "optional": true
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "vin.isValid#[\"1HGCM82633A004352\"]",
          "args": [
            "1HGCM82633A004352"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "vin.isValid#check-digit-x",
          "args": [
            "1M8GDM9AXKP042788"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "vin.isValid#lowercase",
          "args": [
            "1m8gdm9axkp042788"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "vin.isValid#wrong-check-digit",
          "args": [
            "1HGCM82633A004353"
          ],
          "expect": {
            "returns": true
          },
          "note": "changed in 2.5.0 (#593): the North American check digit is enforced only with { checkDigit: true }, since the Brazilian rule (Resolução CONTRAN nº 968/2022) does not require it. 2.4.0 returned false"
        },
        {
          "id": "vin.isValid#letter-i",
          "args": [
            "1HGCM8263IA004352"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "vin.isValid#too-short",
          "args": [
            "1HGCM82633A00435"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "vin.isValid#zeros",
          "args": [
            "00000000000000000"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "vin.isValid#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "vin.isValid#[\"JH4TB2H26CC000000\"]",
          "args": [
            "JH4TB2H26CC000000"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for a second known valid VIN"
        },
        {
          "id": "vin.isValid#[\" 1HGCM82633A004352 \"]",
          "args": [
            " 1HGCM82633A004352 "
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for a value with leading/trailing whitespace"
        },
        {
          "id": "vin.isValid#[\"55555555555555555\"]",
          "args": [
            "55555555555555555"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when every character is the same"
        },
        {
          "id": "vin.isValid#[\"99999999999999999\"]",
          "args": [
            "99999999999999999"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when every character is the same"
        },
        {
          "id": "vin.isValid#[\" 00000000000000000 \"]",
          "args": [
            " 00000000000000000 "
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when every character is the same"
        },
        {
          "id": "vin.isValid#[\"1HICM82633A004352\"]",
          "args": [
            "1HICM82633A004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when the excluded letter I replaces a non-check-digit position"
        },
        {
          "id": "vin.isValid#[\"1HGCM8263OA004352\"]",
          "args": [
            "1HGCM8263OA004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it contains the excluded letter O"
        },
        {
          "id": "vin.isValid#[\"1HGCM8263QA004352\"]",
          "args": [
            "1HGCM8263QA004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it contains the excluded letter Q"
        },
        {
          "id": "vin.isValid#[\"Z92D746W7W5N6SFH\"]",
          "args": [
            "Z92D746W7W5N6SFH"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has 16 characters"
        },
        {
          "id": "vin.isValid#[\"1HGCM82633A0043522\"]",
          "args": [
            "1HGCM82633A0043522"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has more than 17 characters"
        },
        {
          "id": "vin.isValid#[\"1HGCM826C3A004352\"]",
          "args": [
            "1HGCM826C3A004352"
          ],
          "expect": {
            "returns": true
          },
          "note": "changed in 2.5.0 (#593): C is an allowed character and the check digit is not enforced by default. 2.4.0 returned false. JavaScript's own test: when the check digit character is a letter other than X and checkDigit is true"
        },
        {
          "id": "vin.isValid#[\"1HGCM82633A00435-\"]",
          "args": [
            "1HGCM82633A00435-"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it contains a symbol"
        },
        {
          "id": "vin.isValid#[\"1HGCM8 2633A004352\"]",
          "args": [
            "1HGCM8 2633A004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a mask character splits it, since a VIN has no printed grouping"
        },
        {
          "id": "vin.isValid#[\"1HGCM8-2633A004352\"]",
          "args": [
            "1HGCM8-2633A004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a mask character splits it, since a VIN has no printed grouping"
        },
        {
          "id": "vin.isValid#[\"1HGCM8.2633A004352\"]",
          "args": [
            "1HGCM8.2633A004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a mask character splits it, since a VIN has no printed grouping"
        },
        {
          "id": "vin.isValid#[\"1HGCM8/2633A004352\"]",
          "args": [
            "1HGCM8/2633A004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a mask character splits it, since a VIN has no printed grouping"
        },
        {
          "id": "vin.isValid#[\"                 \"]",
          "args": [
            "                 "
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it is only whitespace"
        },
        {
          "id": "vin.isValid#wrong-check-digit-enforced",
          "args": [
            "1HGCM82633A004353",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the check digit does not match and checkDigit is true"
        },
        {
          "id": "vin.isValid#[\"1HGCM826C3A004352\",{\"checkDigit\":true}]",
          "args": [
            "1HGCM826C3A004352",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the check digit character is a letter other than X and checkDigit is true"
        },
        {
          "id": "vin.isValid#[\"9BWZZZ377VT004251\"]",
          "args": [
            "9BWZZZ377VT004251"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: for a Brazilian VIN that carries no 49 CFR 565.15 check digit (changed in 2.5.0, #593; 2.4.0 returned false)"
        },
        {
          "id": "vin.isValid#[\"9BWZZZ377VT004251\",{\"checkDigit\":false}]",
          "args": [
            "9BWZZZ377VT004251",
            {
              "checkDigit": false
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: for a Brazilian VIN that carries no 49 CFR 565.15 check digit"
        },
        {
          "id": "vin.isValid#[\"9BWZZZ377VT004251\",{\"checkDigit\":true}]",
          "args": [
            "9BWZZZ377VT004251",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the check digit does not match and checkDigit is true"
        },
        {
          "id": "vin.isValid#[\"1HGCM82633A004352\",{\"checkDigit\":true}]",
          "args": [
            "1HGCM82633A004352",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: for a known valid VIN with a numeric check digit"
        },
        {
          "id": "vin.isValid#[\"1M8GDM9AXKP042788\",{\"checkDigit\":true}]",
          "args": [
            "1M8GDM9AXKP042788",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: for a known valid VIN with an X check digit"
        },
        {
          "id": "vin.isValid#[\"1m8gdm9axkp042788\",{\"checkDigit\":true}]",
          "args": [
            "1m8gdm9axkp042788",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: for a lowercase value"
        },
        {
          "id": "vin.isValid#[\"JH4TB2H26CC000000\",{\"checkDigit\":true}]",
          "args": [
            "JH4TB2H26CC000000",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: for a second known valid VIN"
        },
        {
          "id": "vin.isValid#[\"1HGCM8261UA004352\",{\"checkDigit\":true}]",
          "args": [
            "1HGCM8261UA004352",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the model year code is U, Z or 0 and checkDigit is true, even with a matching check digit"
        },
        {
          "id": "vin.isValid#[\"1HGCM8262ZA004352\",{\"checkDigit\":true}]",
          "args": [
            "1HGCM8262ZA004352",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the model year code is U, Z or 0 and checkDigit is true, even with a matching check digit"
        },
        {
          "id": "vin.isValid#[\"1HGCM82690A004352\",{\"checkDigit\":true}]",
          "args": [
            "1HGCM82690A004352",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the model year code is U, Z or 0 and checkDigit is true, even with a matching check digit"
        },
        {
          "id": "vin.isValid#[\"1HGCM8261UA004352\"]",
          "args": [
            "1HGCM8261UA004352"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: the model year code is checked only with checkDigit"
        },
        {
          "id": "vin.isValid#[\"00000000000000000\",{\"checkDigit\":true}]",
          "args": [
            "00000000000000000",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": false
          },
          "note": "every character the same is rejected under both rules"
        },
        {
          "id": "vin.isValid#[\"1HGCM8263ſA004352\"]",
          "args": [
            "1HGCM8263ſA004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#615): `ſ` (long s) is no longer folded into `S`"
        },
        {
          "id": "vin.isValid#[\"1HGCM8263ßA004352\"]",
          "args": [
            "1HGCM8263ßA004352"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#615): `ß` is no longer folded into ASCII letters"
        },
        {
          "id": "vin.isValid#[\"ſ9BWZZZ377VT00425\"]",
          "args": [
            "ſ9BWZZZ377VT00425"
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#615): `ſ` is no longer folded into `S`"
        },
        {
          "id": "vin.isValid#[\"1HGCM82633A004352 \",{\"checkDigit\":true}]",
          "args": [
            "1HGCM82633A004352 ",
            {
              "checkDigit": true
            }
          ],
          "expect": {
            "returns": true
          },
          "note": "surrounding whitespace is trimmed"
        }
      ]
    }
  ]
}
