{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "renavam",
  "title": {
    "en": "RENAVAM",
    "pt-BR": "RENAVAM"
  },
  "functions": [
    {
      "id": "renavam.generate",
      "level": "extended",
      "summary": "Generates a valid random RENAVAM number.",
      "description": "Generates a valid random RENAVAM in the 11-digit form: 10 base digits plus the check digit.",
      "params": [],
      "returns": "string",
      "cases": [
        {
          "id": "renavam.generate#generated-is-valid",
          "args": [],
          "expect": {
            "satisfies": "renavam.isValid"
          },
          "repeat": 5,
          "note": "every generated value must pass the lib's own validator"
        }
      ]
    },
    {
      "id": "renavam.isValid",
      "level": "core",
      "summary": "Checks whether a RENAVAM is valid.",
      "description": "Validates a RENAVAM: the old format (9 digits, left-padded to 11) or the new format (11 digits), with a modulus 11 check digit.\n\n- The function ignores spaces, dots, hyphens and slashes, alone or in a run, so every punctuated form is accepted (`0063988.4962`, `0063988/4962`, `00639884-962`). Any other character, in particular a letter or an underscore, makes the value invalid. Until 2.4.0 a slash was rejected.\n- Check digit: the ten base digits, read from right to left, are multiplied by 2, 3, 4, 5, 6, 7, 8, 9, 2 and 3. The digit is the remainder by 11 of ten times the sum, with a remainder of 10 read as 0.\n- A value whose digits are all the same is rejected.\n- A number is read only when it is a safe non-negative integer. A negative or fractional number is invalid: 2.4.0 accepted `-639884962` and `63988496.2`. Strings and non-negative integers give the same result as before.\n- Portaria DENATRAN nº 27/2013 gives 10 digits and a check digit \"calculado através do módulo 11, peso 9\". It does not write out the weights, the handling of a remainder of 0, 1 or 10, or how a 9-digit code is read as 11 digits. Those parts follow community references and market practice.\n- A number loses its leading zeros, so an 11-digit RENAVAM that starts with `0` is only accepted as a string: `\"08794266580\"` is valid and `8794266580` is not.\n- A value that is not a string or a number returns `false`.",
      "params": [
        {
          "name": "renavam",
          "type": "string | number"
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "renavam.isValid#[\"72028649661\"]",
          "args": [
            "72028649661"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"72028649662\"]",
          "args": [
            "72028649662"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"00000000000\"]",
          "args": [
            "00000000000"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"88380465616\"]",
          "args": [
            "88380465616"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"88380465617\"]",
          "args": [
            "88380465617"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"03894104700\"]",
          "args": [
            "03894104700"
          ],
          "expect": {
            "returns": true
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"03894104701\"]",
          "args": [
            "03894104701"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"\"]",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"   \"]",
          "args": [
            "   "
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"abc\"]",
          "args": [
            "abc"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "renavam.isValid#[\"00639884962\"]",
          "args": [
            "00639884962"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return false when a valid registration carries an extra digit"
        },
        {
          "id": "renavam.isValid#[\"006398849620\"]",
          "args": [
            "006398849620"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a valid registration carries an extra digit"
        },
        {
          "id": "renavam.isValid#[\"0639884962\"]",
          "args": [
            "0639884962"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a valid registration carries an extra digit"
        },
        {
          "id": "renavam.isValid#[\"12345678\"]",
          "args": [
            "12345678"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has less than 9 digits"
        },
        {
          "id": "renavam.isValid#[\"123456789012\"]",
          "args": [
            "123456789012"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has more than 11 digits"
        },
        {
          "id": "renavam.isValid#[\"abcdefghij\"]",
          "args": [
            "abcdefghij"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it contains only letters or special characters"
        },
        {
          "id": "renavam.isValid#[\"639884963\"]",
          "args": [
            "639884963"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it is a RENAVAM with invalid checksum (639884963 has its last digit changed from the valid 639884962)"
        },
        {
          "id": "renavam.isValid#[\"12345678901\"]",
          "args": [
            "12345678901"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it is a RENAVAM with invalid checksum (639884963 has its last digit changed from the valid 639884962)"
        },
        {
          "id": "renavam.isValid#[\"12345678901abc\"]",
          "args": [
            "12345678901abc"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has mixed characters that sanitize to an invalid RENAVAM (invalid checksum)"
        },
        {
          "id": "renavam.isValid#[\"639884963xyz\"]",
          "args": [
            "639884963xyz"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has mixed characters that sanitize to an invalid RENAVAM (invalid checksum)"
        },
        {
          "id": "renavam.isValid#[\"639884962abc\"]",
          "args": [
            "639884962abc"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when letters are attached to an otherwise valid RENAVAM"
        },
        {
          "id": "renavam.isValid#[\"ab00639884962\"]",
          "args": [
            "ab00639884962"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when letters are attached to an otherwise valid RENAVAM"
        },
        {
          "id": "renavam.isValid#[\"0063988/4962\"]",
          "args": [
            "0063988/4962"
          ],
          "expect": {
            "returns": true
          },
          "note": "changed in 2.5.0 (#615): the slash is a mask character, like in cpf.isValid. 2.4.0 returned false. JavaScript's own test: should return true when is a RENAVAM valid with the usual mask characters"
        },
        {
          "id": "renavam.isValid#[\"000000000\"]",
          "args": [
            "000000000"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when every digit is the same"
        },
        {
          "id": "renavam.isValid#[\"1234567890\"]",
          "args": [
            "1234567890"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when is a RENAVAM with invalid length: 8 digits (too short), 10 digits (invalid), or 12 digits (too long)"
        },
        {
          "id": "renavam.isValid#[\"639884962\"]",
          "args": [
            "639884962"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a RENAVAM valid with 9 digits (old format)"
        },
        {
          "id": "renavam.isValid#[639884962]",
          "args": [
            639884962
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a RENAVAM valid as number"
        },
        {
          "id": "renavam.isValid#[\"0063988.4962\"]",
          "args": [
            "0063988.4962"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a RENAVAM valid with the usual mask characters"
        },
        {
          "id": "renavam.isValid#[\"00639884-962\"]",
          "args": [
            "00639884-962"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a RENAVAM valid with the usual mask characters"
        },
        {
          "id": "renavam.isValid#[\" 00639884962 \"]",
          "args": [
            " 00639884962 "
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a RENAVAM valid with the usual mask characters"
        },
        {
          "id": "renavam.isValid#[\"12345678900\"]",
          "args": [
            "12345678900"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when the multiplier cycle wraps from 9 back to 2 on non-zero digits"
        },
        {
          "id": "renavam.isValid#[\"00000000060\"]",
          "args": [
            "00000000060"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when the checksum remainder is exactly 1 (expected digit 0, not 10)"
        },
        {
          "id": "renavam.isValid#[-639884962]",
          "args": [
            -639884962
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#592): a negative number is not a safe non-negative integer. 2.4.0 returned true. From the maintainer briefing, #592"
        },
        {
          "id": "renavam.isValid#[63988496.2]",
          "args": [
            63988496.2
          ],
          "expect": {
            "returns": false
          },
          "note": "changed in 2.5.0 (#592): a fractional number is not a safe non-negative integer. 2.4.0 returned true. From the maintainer briefing, #592"
        },
        {
          "id": "renavam.isValid#[9007199254740992]",
          "args": [
            9007199254740992
          ],
          "expect": {
            "returns": false
          },
          "note": "#593 number rule: 2^53 is past Number.MAX_SAFE_INTEGER"
        },
        {
          "id": "renavam.isValid#[12345678900]",
          "args": [
            12345678900
          ],
          "expect": {
            "returns": true
          },
          "note": "a safe non-negative integer is read as before"
        },
        {
          "id": "renavam.isValid#[\"0063988_4962\"]",
          "args": [
            "0063988_4962"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when the mask uses a character other than whitespace, a dot, a hyphen or a slash"
        },
        {
          "id": "renavam.isValid#[\"08794266580\"]",
          "args": [
            "08794266580"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript docs example: an 11-digit RENAVAM that starts with 0 is valid as a string"
        },
        {
          "id": "renavam.isValid#[8794266580]",
          "args": [
            8794266580
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript docs example: as a number it lost its leading zero"
        }
      ]
    }
  ]
}
