{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "ncm",
  "title": {
    "en": "NCM",
    "pt-BR": "NCM"
  },
  "functions": [
    {
      "id": "ncm.format",
      "level": "extended",
      "summary": "Formats an NCM code.",
      "description": "Formats an NCM code with the mask `NNNN.NN.NN`. Only the structure changes (use `ncm.isValid` to check the code).\n\n- Same rules as `cnae.format`. `options.pad` first left-pads the value with zeros to 8 digits. A value without digits, and `null` or `undefined`, returns an empty string even with `pad`; until 2.4.0 `pad` turned an empty value into the zero mask (`0000.00.00`).\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number returns an empty string (2.4.0 read the digits of any number, sign and decimal point dropped).",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        },
        {
          "name": "options",
          "type": "FormatNcmOptions",
          "optional": true
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "ncm.format#[\"84713012\"]",
          "args": [
            "84713012"
          ],
          "expect": {
            "returns": "8471.30.12"
          }
        },
        {
          "id": "ncm.format#already-formatted",
          "args": [
            "8471.30.12"
          ],
          "expect": {
            "returns": "8471.30.12"
          }
        },
        {
          "id": "ncm.format#partial",
          "args": [
            "84713"
          ],
          "expect": {
            "returns": "8471.3"
          }
        },
        {
          "id": "ncm.format#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          }
        },
        {
          "id": "ncm.format#[84713012]",
          "args": [
            84713012
          ],
          "expect": {
            "returns": "8471.30.12"
          },
          "note": "JavaScript's own test: should format an NCM code given as a number"
        },
        {
          "id": "ncm.format#[\"8\"]",
          "args": [
            "8"
          ],
          "expect": {
            "returns": "8"
          },
          "note": "JavaScript's own test: should mask a partial value progressively by default"
        },
        {
          "id": "ncm.format#[\"84\"]",
          "args": [
            "84"
          ],
          "expect": {
            "returns": "84"
          },
          "note": "JavaScript's own test: should mask a partial value progressively by default"
        },
        {
          "id": "ncm.format#[\"847\"]",
          "args": [
            "847"
          ],
          "expect": {
            "returns": "847"
          },
          "note": "JavaScript's own test: should mask a partial value progressively by default"
        },
        {
          "id": "ncm.format#[\"8471\"]",
          "args": [
            "8471"
          ],
          "expect": {
            "returns": "8471"
          },
          "note": "JavaScript's own test: should mask a partial value progressively by default"
        },
        {
          "id": "ncm.format#[\"847130\"]",
          "args": [
            "847130"
          ],
          "expect": {
            "returns": "8471.30"
          },
          "note": "JavaScript's own test: should mask a partial value progressively by default"
        },
        {
          "id": "ncm.format#[\"8471301\"]",
          "args": [
            "8471301"
          ],
          "expect": {
            "returns": "8471.30.1"
          },
          "note": "JavaScript's own test: should mask a partial value progressively by default"
        },
        {
          "id": "ncm.format#[8471]",
          "args": [
            8471
          ],
          "expect": {
            "returns": "8471"
          },
          "note": "JavaScript's own test: should mask a partial number progressively by default"
        },
        {
          "id": "ncm.format#[847130]",
          "args": [
            847130
          ],
          "expect": {
            "returns": "8471.30"
          },
          "note": "JavaScript's own test: should mask a partial number progressively by default"
        },
        {
          "id": "ncm.format#[\"00000000\"]",
          "args": [
            "00000000"
          ],
          "expect": {
            "returns": "0000.00.00"
          },
          "note": "JavaScript's own test: should not validate whether the code exists in the official table"
        },
        {
          "id": "ncm.format#[\"847130120000\"]",
          "args": [
            "847130120000"
          ],
          "expect": {
            "returns": "8471.30.12"
          },
          "note": "JavaScript's own test: should not add digits after the NCM length"
        },
        {
          "id": "ncm.format#[\"\",{\"pad\":true}]",
          "args": [
            "",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "changed in 2.5.0 (#615): a value without digits gives an empty string even with pad (2.4.0: \"0000.00.00\"). JavaScript's own test: pad option should left pad a short code with zeros up to the full NCM length"
        },
        {
          "id": "ncm.format#[\"1\",{\"pad\":true}]",
          "args": [
            "1",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0000.00.01"
          },
          "note": "JavaScript's own test: pad option should left pad a short code with zeros up to the full NCM length"
        },
        {
          "id": "ncm.format#[\"8471\",{\"pad\":true}]",
          "args": [
            "8471",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0000.84.71"
          },
          "note": "JavaScript's own test: pad option should left pad a short code with zeros up to the full NCM length"
        },
        {
          "id": "ncm.format#[\"847130\",{\"pad\":true}]",
          "args": [
            "847130",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0084.71.30"
          },
          "note": "JavaScript's own test: pad option should left pad a short code with zeros up to the full NCM length"
        },
        {
          "id": "ncm.format#[\"84713012\",{\"pad\":true}]",
          "args": [
            "84713012",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "8471.30.12"
          },
          "note": "JavaScript's own test: pad option should left pad a short code with zeros up to the full NCM length"
        },
        {
          "id": "ncm.format#[8471,{\"pad\":true}]",
          "args": [
            8471,
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "0000.84.71"
          },
          "note": "JavaScript's own test: pad option should left pad a number the same way as its digits"
        },
        {
          "id": "ncm.format#[84713012,{\"pad\":true}]",
          "args": [
            84713012,
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "8471.30.12"
          },
          "note": "JavaScript's own test: pad option should left pad a number the same way as its digits"
        },
        {
          "id": "ncm.format#[\"8471\",{\"pad\":false}]",
          "args": [
            "8471",
            {
              "pad": false
            }
          ],
          "expect": {
            "returns": "8471"
          },
          "note": "JavaScript's own test: pad option should mask progressively for an explicit false"
        },
        {
          "id": "ncm.format#[\"abc8471\"]",
          "args": [
            "abc8471"
          ],
          "expect": {
            "returns": "8471"
          },
          "note": "JavaScript's own test: should read only the digits of a value with other characters, like formatCpf"
        },
        {
          "id": "ncm.format#[\"8471.30-12\"]",
          "args": [
            "8471.30-12"
          ],
          "expect": {
            "returns": "8471.30.12"
          },
          "note": "JavaScript's own test: should read only the digits of a value with other characters, like formatCpf"
        },
        {
          "id": "ncm.format#[-84713012]",
          "args": [
            -84713012
          ],
          "expect": {
            "returns": ""
          },
          "note": "changed in 2.5.0 (#593): a negative or fractional number is not a non-negative safe integer, so it gives \"\"; 2.4.0 read the digits of its string. JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number"
        },
        {
          "id": "ncm.format#[8471301.2]",
          "args": [
            8471301.2
          ],
          "expect": {
            "returns": ""
          },
          "note": "changed in 2.5.0 (#593): a negative or fractional number is not a non-negative safe integer, so it gives \"\"; 2.4.0 read the digits of its string. JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number"
        },
        {
          "id": "ncm.format#[9007199254740992]",
          "args": [
            9007199254740992
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number (2 ** 53)"
        },
        {
          "id": "ncm.format#[null]",
          "args": [
            null
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string for null and undefined"
        },
        {
          "id": "ncm.format#[null,{\"pad\":true}]",
          "args": [
            null,
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string for null and undefined even under pad, instead of a zero-filled code"
        },
        {
          "id": "ncm.format#[\"abc\",{\"pad\":true}]",
          "args": [
            "abc",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "an input with no digit stays empty under pad"
        }
      ]
    },
    {
      "id": "ncm.isValid",
      "level": "extended",
      "summary": "Checks whether an NCM code exists in the official table.",
      "description": "Checks whether an NCM code exists in the current table that Siscomex publishes.\n\n- A value written as bare digits, as a string or as a number, is left-padded with zeros to 8: `1012100`, `\"1012100\"` and `\"01012100\"` are the same code. A masked value is read as written (`101.21.00` is invalid).\n- Same input rules as `cbo.isValid`, with 8 digits and the `NNNN.NN.NN` mask, including a run of separators between the groups: `2203..00.00` is valid. Until 2.4.0 a single separator was accepted and `2203..00.00` was rejected.\n- The table is the file \"Vigente em 26/09/2026\" of the Portal Único Siscomex (Resolução Gecex nº 926/2026), with 10,515 codes.",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "ncm.isValid#[\"22030000\"]",
          "args": [
            "22030000"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "ncm.isValid#masked",
          "args": [
            "2203.00.00"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "ncm.isValid#leading-zero",
          "args": [
            "01012100"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "ncm.isValid#nonexistent",
          "args": [
            "12345678"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "ncm.isValid#too-short",
          "args": [
            "2203000"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "ncm.isValid#letters",
          "args": [
            "abcdefgh"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "ncm.isValid#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "ncm.isValid#[22030000]",
          "args": [
            22030000
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate an NCM code given as a number"
        },
        {
          "id": "ncm.isValid#[\"0101.21.00\"]",
          "args": [
            "0101.21.00"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate a leading zero NCM code (cavalos reprodutores de raça pura)"
        },
        {
          "id": "ncm.isValid#[1012100]",
          "args": [
            1012100
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should pad a value to eight digits, as a number or as a string (1012100 is 01012100)"
        },
        {
          "id": "ncm.isValid#[\"1012100\"]",
          "args": [
            "1012100"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should pad a value to eight digits, as a number or as a string (1012100 is 01012100)"
        },
        {
          "id": "ncm.isValid#[\"101.21.00\"]",
          "args": [
            "101.21.00"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should not pad a masked value, which already carries its separators"
        },
        {
          "id": "ncm.isValid#[\" 22030000 \"]",
          "args": [
            " 22030000 "
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should validate an NCM code with surrounding whitespace"
        },
        {
          "id": "ncm.isValid#[\"220300000\"]",
          "args": [
            "220300000"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a padded short value no code carries and for a wider value"
        },
        {
          "id": "ncm.isValid#[\"        \"]",
          "args": [
            "        "
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for whitespace only"
        },
        {
          "id": "ncm.isValid#[\"abc01012100\"]",
          "args": [
            "abc01012100"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a string that is not a documented form"
        },
        {
          "id": "ncm.isValid#[\"2203..00.00\"]",
          "args": [
            "2203..00.00"
          ],
          "expect": {
            "returns": true
          },
          "note": "changed in 2.5.0 (#615): a run of separators between the groups is accepted (2.4.0 rejected it). JavaScript's own test: should accept a group boundary written with a run of separators"
        },
        {
          "id": "ncm.isValid#[-22030000]",
          "args": [
            -22030000
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a number that is not a non-negative safe integer"
        },
        {
          "id": "ncm.isValid#[2203000.01]",
          "args": [
            2203000.01
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false for a number that is not a non-negative safe integer"
        }
      ]
    },
    {
      "id": "ncm.parse",
      "level": "extended",
      "summary": "Removes the formatting characters of an NCM code and returns only the digits.",
      "description": "Removes NCM formatting and keeps only digits, capped at 8 digits.\n\n- The function does not left-pad the value. It keeps a partial code as written.\n- Returns an empty string when there is no digit at all (`null` and `undefined` included).\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number returns an empty string (2.4.0 read the digits of any number, sign and decimal point dropped).",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "ncm.parse#masked",
          "args": [
            "8471.30.12"
          ],
          "expect": {
            "returns": "84713012"
          }
        },
        {
          "id": "ncm.parse#unmasked",
          "args": [
            "84713012"
          ],
          "expect": {
            "returns": "84713012"
          }
        },
        {
          "id": "ncm.parse#strips-non-digits",
          "args": [
            "84?ABC71.30.12abc"
          ],
          "expect": {
            "returns": "84713012"
          }
        },
        {
          "id": "ncm.parse#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          }
        },
        {
          "id": "ncm.parse#caps-length",
          "args": [
            "84713012999"
          ],
          "expect": {
            "returns": "84713012"
          },
          "note": "reference truncates to the 8 characters of the document; asserted by the reference (JS) unit tests"
        },
        {
          "id": "ncm.parse#[84713012]",
          "args": [
            84713012
          ],
          "expect": {
            "returns": "84713012"
          },
          "note": "JavaScript's own test: should read a number as the string of its digits"
        },
        {
          "id": "ncm.parse#[\"8471\"]",
          "args": [
            "8471"
          ],
          "expect": {
            "returns": "8471"
          },
          "note": "JavaScript's own test: should keep a partial code as written, without padding it"
        },
        {
          "id": "ncm.parse#[-1]",
          "args": [
            -1
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number (#593 number rule)"
        },
        {
          "id": "ncm.parse#[1.5]",
          "args": [
            1.5
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number (#593 number rule)"
        },
        {
          "id": "ncm.parse#[9007199254740992]",
          "args": [
            9007199254740992
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript's own test: should return an empty string when it is a negative, fractional or unsafe number (#593 number rule)"
        }
      ]
    }
  ]
}
