{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "cno",
  "title": {
    "en": "CNO",
    "pt-BR": "CNO"
  },
  "functions": [
    {
      "id": "cno.format",
      "level": "extended",
      "summary": "Formats a CNO number with the official mask.",
      "description": "Formats a CNO with the mask `00.000.00000/00` (the CEI numbering).\n\n- Same rules as `cei.format`: the mask is applied as far as the digits go, and digits beyond the 12th are dropped. `options.pad` first left-pads with zeros to 12 digits.\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number gives an empty string (2.4.0 read the digits of any number, sign and decimal point dropped).\n- `options.pad` on a value with no digits (`\"\"`, `\"---\"`, `null`) still gives an empty string. Until 2.4.0 `\"\"` and `\"---\"` gave the whole zero mask.",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        },
        {
          "name": "options",
          "type": "FormatCnoOptions",
          "optional": true
        }
      ],
      "returns": "string",
      "cases": [
        {
          "id": "cno.format#[\"111130137368\"]",
          "args": [
            "111130137368"
          ],
          "expect": {
            "returns": "11.113.01373/68"
          }
        },
        {
          "id": "cno.format#already-formatted",
          "args": [
            "11.084.01680/62"
          ],
          "expect": {
            "returns": "11.084.01680/62"
          }
        },
        {
          "id": "cno.format#partial",
          "args": [
            "11113"
          ],
          "expect": {
            "returns": "11.113"
          }
        },
        {
          "id": "cno.format#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          }
        },
        {
          "id": "cno.format#[401800097960]",
          "args": [
            401800097960
          ],
          "expect": {
            "returns": "40.180.00979/60"
          },
          "note": "JavaScript's own test: should format a number input"
        },
        {
          "id": "cno.format#[\"1\"]",
          "args": [
            "1"
          ],
          "expect": {
            "returns": "1"
          },
          "note": "JavaScript's own test: should format progressively as digits are typed"
        },
        {
          "id": "cno.format#[\"11\"]",
          "args": [
            "11"
          ],
          "expect": {
            "returns": "11"
          },
          "note": "JavaScript's own test: should format progressively as digits are typed"
        },
        {
          "id": "cno.format#[\"111\"]",
          "args": [
            "111"
          ],
          "expect": {
            "returns": "11.1"
          },
          "note": "JavaScript's own test: should format progressively as digits are typed"
        },
        {
          "id": "cno.format#[\"1111\"]",
          "args": [
            "1111"
          ],
          "expect": {
            "returns": "11.11"
          },
          "note": "JavaScript's own test: should format progressively as digits are typed"
        },
        {
          "id": "cno.format#[\"111130\"]",
          "args": [
            "111130"
          ],
          "expect": {
            "returns": "11.113.0"
          },
          "note": "JavaScript's own test: should format progressively as digits are typed"
        },
        {
          "id": "cno.format#[\"1111301373680000\"]",
          "args": [
            "1111301373680000"
          ],
          "expect": {
            "returns": "11.113.01373/68"
          },
          "note": "JavaScript's own test: should truncate values longer than 12 digits"
        },
        {
          "id": "cno.format#[\"979\",{\"pad\":true}]",
          "args": [
            "979",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": "00.000.00009/79"
          },
          "note": "JavaScript's own test: should pad the value with leading zeros when options.pad is true"
        },
        {
          "id": "cno.format#[-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": "cno.format#[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": "cno.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 (#593 number rule)"
        },
        {
          "id": "cno.format#[\"\",{\"pad\":true}]",
          "args": [
            "",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "changed in 2.5.0 (#615): should return an empty string for a value without digits even when padding; 2.4.0 returned the zero mask"
        },
        {
          "id": "cno.format#[\"---\",{\"pad\":true}]",
          "args": [
            "---",
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "changed in 2.5.0 (#615): a value with no digits gives an empty string even with pad"
        },
        {
          "id": "cno.format#[null,{\"pad\":true}]",
          "args": [
            null,
            {
              "pad": true
            }
          ],
          "expect": {
            "returns": ""
          },
          "note": "a null value gives an empty string even with pad (2.4.0 did the same)"
        },
        {
          "id": "cno.format#[-249859674386]",
          "args": [
            -249859674386
          ],
          "expect": {
            "returns": ""
          },
          "note": "JavaScript docs example: not a non-negative safe integer"
        },
        {
          "id": "cno.format#[\"979\"]",
          "args": [
            "979"
          ],
          "expect": {
            "returns": "97.9"
          },
          "note": "JavaScript docs example: no padding by default"
        }
      ]
    },
    {
      "id": "cno.isValid",
      "level": "extended",
      "summary": "Validates a CNO number, the registration of a construction work with the Receita Federal.",
      "description": "Validates a CNO. The CNO replaced the CEI for construction works and kept its numbering.\n\n- Same rules as `cei.isValid`.\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number is invalid.\n- No official source publishes the check digit rule. Only the 12 positions and the CNO keeping the CEI number (Manual de Orientação do eSocial S-1.3, item 9.1) are official. The IN RFB 2.061/2021 has no check digit, and the eSocial only checks that the number exists in the Receita Federal base. The rule comes from third-party reference implementations, cross-checked against the CNO open data and SERPRO's example `000000336854`.\n- A number loses its leading zeros, so a value that starts with `0` is only accepted as a string: `\"000000336854\"` is valid and `336854` is not.",
      "params": [
        {
          "name": "value",
          "type": "string | number"
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "cno.isValid#[\"110840168062\"]",
          "args": [
            "110840168062"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "cno.isValid#masked",
          "args": [
            "11.084.01680/62"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "cno.isValid#[\"401800097960\"]",
          "args": [
            "401800097960"
          ],
          "expect": {
            "returns": true
          }
        },
        {
          "id": "cno.isValid#wrong-check-digit",
          "args": [
            "110840168063"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cno.isValid#zeros",
          "args": [
            "000000000000"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cno.isValid#too-short",
          "args": [
            "1234567890"
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cno.isValid#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          }
        },
        {
          "id": "cno.isValid#[\"1234567890123\"]",
          "args": [
            "1234567890123"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it does not have 12 digits"
        },
        {
          "id": "cno.isValid#[\"11#084#01680#62\"]",
          "args": [
            "11#084#01680#62"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has 12 digits but an unsupported separator"
        },
        {
          "id": "cno.isValid#[\"110.840.16806/2\"]",
          "args": [
            "110.840.16806/2"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it has 12 digits grouped outside the 2-3-5-2 mask"
        },
        {
          "id": "cno.isValid#[\"401800097961\"]",
          "args": [
            "401800097961"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a check digit of 0 is replaced by another digit (401800097960 of the Receita Federal CNO dataset)"
        },
        {
          "id": "cno.isValid#[\"111130137368\"]",
          "args": [
            "111130137368"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for 111130137368, an obra in Campo do Meio/MG of the Receita Federal CNO open dataset"
        },
        {
          "id": "cno.isValid#[\"112772388267\"]",
          "args": [
            "112772388267"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for 112772388267 and 113381018769 of the Receita Federal CNO open dataset"
        },
        {
          "id": "cno.isValid#[\"113381018769\"]",
          "args": [
            "113381018769"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for 112772388267 and 113381018769 of the Receita Federal CNO open dataset"
        },
        {
          "id": "cno.isValid#[401800097960]",
          "args": [
            401800097960
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for 401800097960, whose check digit is 0 (Receita Federal CNO open dataset, Frutal/MG)"
        },
        {
          "id": "cno.isValid#[\"512070915160\"]",
          "args": [
            "512070915160"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for 512070915160, whose check digit is 0 (Receita Federal CNO open dataset, Capitólio/MG)"
        },
        {
          "id": "cno.isValid#[\"11.583.00249/85\"]",
          "args": [
            "11.583.00249/85"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for a legacy CEI number kept by the CNO (11.583.00249/85, yiibr/yii2-br-validator)"
        },
        {
          "id": "cno.isValid#[\" 11 084 01680 62 \"]",
          "args": [
            " 11 084 01680 62 "
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for a whitespace mask and surrounding whitespace"
        },
        {
          "id": "cno.isValid#[-110840168062]",
          "args": [
            -110840168062
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it is a negative or fractional number (#593 number rule)"
        },
        {
          "id": "cno.isValid#[1108401680.62]",
          "args": [
            1108401680.62
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it is a negative or fractional number (#593 number rule)"
        },
        {
          "id": "cno.isValid#[\"000000336854\"]",
          "args": [
            "000000336854"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true for 000000336854, the example of SERPRO's documentation of the Receita Federal's CNO cadastro"
        },
        {
          "id": "cno.isValid#[336854]",
          "args": [
            336854
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript docs example: a number loses its leading zeros"
        }
      ]
    },
    {
      "id": "cno.parse",
      "level": "extended",
      "summary": "Removes the formatting characters of a CNO and returns only the digits.",
      "description": "Removes CNO formatting and keeps only digits, capped at 12 digits.\n\n- A number is read only when it is a safe non-negative integer. A negative, fractional, non-finite or unsafe number gives 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": "cno.parse#masked",
          "args": [
            "11.113.01373/68"
          ],
          "expect": {
            "returns": "111130137368"
          }
        },
        {
          "id": "cno.parse#unmasked",
          "args": [
            "111130137368"
          ],
          "expect": {
            "returns": "111130137368"
          }
        },
        {
          "id": "cno.parse#strips-non-digits",
          "args": [
            "11.?ABC113.01373/68abc"
          ],
          "expect": {
            "returns": "111130137368"
          }
        },
        {
          "id": "cno.parse#empty",
          "args": [
            ""
          ],
          "expect": {
            "returns": ""
          }
        },
        {
          "id": "cno.parse#caps-length",
          "args": [
            "111130137368999"
          ],
          "expect": {
            "returns": "111130137368"
          },
          "note": "reference truncates to the 12 characters of the document; asserted by the reference (JS) unit tests"
        },
        {
          "id": "cno.parse#[111130137368]",
          "args": [
            111130137368
          ],
          "expect": {
            "returns": "111130137368"
          },
          "note": "JavaScript's own test: should read a number as the string of its digits"
        },
        {
          "id": "cno.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": "cno.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": "cno.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)"
        }
      ]
    }
  ]
}
