{
  "$schema": "../cases.schema.json",
  "format": 1,
  "domain": "email",
  "title": {
    "en": "Email",
    "pt-BR": "E-mail"
  },
  "functions": [
    {
      "id": "email.isValid",
      "level": "core",
      "summary": "Checks whether an email address is valid.",
      "description": "Validates an email address: a practical subset of the WHATWG HTML \"valid e-mail address\".\n\n- Local part: letters, digits and `_'+-.`, with no leading or trailing dot, no trailing apostrophe and no two dots in a row, at most 64 characters. The whole address is capped at 254 characters (RFC 5321, section 4.5.3.1). Until 2.4.0 there was no cap on either.\n- Domain: at least one dot, labels of up to 63 characters that neither start nor end with a hyphen, the final label 2 to 63 letters or a punycode label (`xn--`, up to 63 characters, so `user@example.xn--p1ai` is valid). A punycode label with nothing after `xn--`, ending in a hyphen or over 63 characters is rejected. Until 2.4.0 a punycode final label was rejected.\n- Quoted local parts, address literals, single-label domains such as `user@localhost` and the local part characters `! # $ % & * = ? ^ { | } ~`, the slash and the backtick are rejected, although WHATWG allows some of them.\n- The check ignores case. A value that is not a string is invalid.\n- A Pix email key does not use this function. `pixKey.isValid` follows the pattern of the DICT API, which is wider in some places: it accepts `fulano@example`, `a@localhost` and `a{b}@example.com`, which this function rejects.",
      "params": [
        {
          "name": "value",
          "type": "string"
        }
      ],
      "returns": "boolean",
      "cases": [
        {
          "id": "email.isValid#[\"\"]",
          "args": [
            ""
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "email.isValid#[\"   \"]",
          "args": [
            "   "
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "email.isValid#[\"abc\"]",
          "args": [
            "abc"
          ],
          "expect": {
            "returns": false
          },
          "note": "consensus of 5 libs (go, javascript, python, ruby, rust)"
        },
        {
          "id": "email.isValid#[\"invalid.email\"]",
          "args": [
            "invalid.email"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it is missing @"
        },
        {
          "id": "email.isValid#[\"user@\"]",
          "args": [
            "user@"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it is missing domain"
        },
        {
          "id": "email.isValid#[\"@domain.com\"]",
          "args": [
            "@domain.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when it is missing user"
        },
        {
          "id": "email.isValid#[\"!!!user@example.com\"]",
          "args": [
            "!!!user@example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when there is garbage before an otherwise valid email"
        },
        {
          "id": "email.isValid#[\"user@example.com!!!\"]",
          "args": [
            "user@example.com!!!"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when there is garbage after an otherwise valid email"
        },
        {
          "id": "email.isValid#[\"ab..c@example.com\"]",
          "args": [
            "ab..c@example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when the local part has consecutive dots that are not at the very start"
        },
        {
          "id": "email.isValid#[\"user@example-.com\"]",
          "args": [
            "user@example-.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a domain label ends with a hyphen"
        },
        {
          "id": "email.isValid#[\"user@-example.com\"]",
          "args": [
            "user@-example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: should return false when a domain label starts with a hyphen"
        },
        {
          "id": "email.isValid#[\"user@example.com\"]",
          "args": [
            "user@example.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a valid email"
        },
        {
          "id": "email.isValid#[\"user__@example.com\"]",
          "args": [
            "user__@example.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a valid email"
        },
        {
          "id": "email.isValid#[\"user__user@example.com\"]",
          "args": [
            "user__user@example.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a valid email"
        },
        {
          "id": "email.isValid#[\"test@subdomain.example.com\"]",
          "args": [
            "test@subdomain.example.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a valid email with subdomain"
        },
        {
          "id": "email.isValid#[\"user@ex-ample.com\"]",
          "args": [
            "user@ex-ample.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when a domain label carries an inner hyphen"
        },
        {
          "id": "email.isValid#[\"user+tag@example.co.uk\"]",
          "args": [
            "user+tag@example.co.uk"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a valid email with special characters"
        },
        {
          "id": "email.isValid#[\"fulano@example\"]",
          "args": [
            "fulano@example"
          ],
          "expect": {
            "returns": false
          },
          "note": "a single-label domain is rejected here, although it is a Pix email key (#593, pixKey.isValid)"
        },
        {
          "id": "email.isValid#[\"a@localhost\"]",
          "args": [
            "a@localhost"
          ],
          "expect": {
            "returns": false
          },
          "note": "a single-label domain is rejected here, although it is a Pix email key (#593, pixKey.isValid)"
        },
        {
          "id": "email.isValid#[\"a{b}@example.com\"]",
          "args": [
            "a{b}@example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "outside the local-part characters of this function, although it is a Pix email key (#593, pixKey.isValid)"
        },
        {
          "id": "email.isValid#[\".ab@example.com\"]",
          "args": [
            ".ab@example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "a leading dot is rejected"
        },
        {
          "id": "email.isValid#[\"ab.@example.com\"]",
          "args": [
            "ab.@example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "a trailing dot in the local part is rejected"
        },
        {
          "id": "email.isValid#[\"a&b@example.com\"]",
          "args": [
            "a&b@example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "& is outside the local-part characters of this function"
        },
        {
          "id": "email.isValid#[\"user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com\"]",
          "args": [
            "user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when a domain label is longer than the 63 characters WHATWG allows"
        },
        {
          "id": "email.isValid#[\"user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com\"]",
          "args": [
            "user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: when a domain label is exactly 63 characters long"
        },
        {
          "id": "email.isValid#[\"user@example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"]",
          "args": [
            "user@example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the final domain label is longer than the 63 characters WHATWG allows"
        },
        {
          "id": "email.isValid#[\"User@Example.COM\"]",
          "args": [
            "User@Example.COM"
          ],
          "expect": {
            "returns": true
          },
          "note": "the check ignores case"
        },
        {
          "id": "email.isValid#[\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com\"]",
          "args": [
            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part is longer than 64 characters"
        },
        {
          "id": "email.isValid#[\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@a.com\"]",
          "args": [
            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part is longer than 64 characters"
        },
        {
          "id": "email.isValid#[\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com\"]",
          "args": [
            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: when the local part has exactly 64 characters"
        },
        {
          "id": "email.isValid#[\"user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com\"]",
          "args": [
            "user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the whole address is longer than 254 characters"
        },
        {
          "id": "email.isValid#[\"user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com\"]",
          "args": [
            "user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: when the address has exactly 254 characters"
        },
        {
          "id": "email.isValid#[\"user@example.xn--p1ai\"]",
          "args": [
            "user@example.xn--p1ai"
          ],
          "expect": {
            "returns": true
          },
          "note": "when the final label is punycode (JavaScript docs example)"
        },
        {
          "id": "email.isValid#[\"user@example.XN--P1AI\"]",
          "args": [
            "user@example.XN--P1AI"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: when the final label is punycode"
        },
        {
          "id": "email.isValid#[\"user@example.xn--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"]",
          "args": [
            "user@example.xn--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: when the final label is punycode"
        },
        {
          "id": "email.isValid#[\"user@example.xn--\"]",
          "args": [
            "user@example.xn--"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the punycode final label is malformed"
        },
        {
          "id": "email.isValid#[\"user@example.xn---\"]",
          "args": [
            "user@example.xn---"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the punycode final label is malformed"
        },
        {
          "id": "email.isValid#[\"user@example.xn--p1ai-\"]",
          "args": [
            "user@example.xn--p1ai-"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the punycode final label is malformed"
        },
        {
          "id": "email.isValid#[\"user@example.xn--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"]",
          "args": [
            "user@example.xn--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the punycode final label is malformed"
        },
        {
          "id": "email.isValid#[\"a%b@example.com\"]",
          "args": [
            "a%b@example.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "when the local part holds a character outside the accepted set (JavaScript docs example)"
        },
        {
          "id": "email.isValid#[\"a=b@a.com\"]",
          "args": [
            "a=b@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part holds a character outside the accepted set"
        },
        {
          "id": "email.isValid#[\"a?b@a.com\"]",
          "args": [
            "a?b@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part holds a character outside the accepted set"
        },
        {
          "id": "email.isValid#[\"a/b@a.com\"]",
          "args": [
            "a/b@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part holds a character outside the accepted set"
        },
        {
          "id": "email.isValid#[\"a!b@a.com\"]",
          "args": [
            "a!b@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part holds a character outside the accepted set"
        },
        {
          "id": "email.isValid#[\"a#b@a.com\"]",
          "args": [
            "a#b@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part holds a character outside the accepted set"
        },
        {
          "id": "email.isValid#[\"a$b@a.com\"]",
          "args": [
            "a$b@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part holds a character outside the accepted set"
        },
        {
          "id": "email.isValid#[\"a*b@a.com\"]",
          "args": [
            "a*b@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part holds a character outside the accepted set"
        },
        {
          "id": "email.isValid#[\"x'@a.com\"]",
          "args": [
            "x'@a.com"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the local part holds a character outside the accepted set (a trailing apostrophe)"
        },
        {
          "id": "email.isValid#[\"user@localhost\"]",
          "args": [
            "user@localhost"
          ],
          "expect": {
            "returns": false
          },
          "note": "JavaScript's own test: when the domain has a single label"
        },
        {
          "id": "email.isValid#[\"john.doe@hotmail.com\"]",
          "args": [
            "john.doe@hotmail.com"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript docs example"
        },
        {
          "id": "email.isValid#[\"test@domain.co.uk\"]",
          "args": [
            "test@domain.co.uk"
          ],
          "expect": {
            "returns": true
          },
          "note": "JavaScript's own test: should return true when is a valid email with subdomain"
        }
      ]
    }
  ]
}
