is_email.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. var fs = require("fs"),
  2. libxmljs = require("libxmljs"),
  3. test = require("tap").test;
  4. var addrs = require("../lib/email-addresses");
  5. var TESTS_FILE = "tests.xml",
  6. TESTS_FILE_ENCODING = "utf8";
  7. var ISEMAIL_ERR = "ISEMAIL_ERR",
  8. ISEMAIL_ERR_DOMAINHYPHENSTART = "ISEMAIL_ERR_DOMAINHYPHENSTART",
  9. ISEMAIL_ERR_DOMAINHYPHENEND = "ISEMAIL_ERR_DOMAINHYPHENEND";
  10. function isEmailTest(t, data) {
  11. var nodes = getNodes(data, "//test");
  12. nodes.forEach(function (node) {
  13. var id = getAttr(node, "id"),
  14. address = getChildValue(node, "address"),
  15. diagnosis = getChildValue(node, "diagnosis");
  16. var result = addrs(convertAddress(address)),
  17. ast = null;
  18. if (result !== null) {
  19. ast = result.addresses[0].node;
  20. }
  21. var isValid = ast !== null,
  22. expectedToBeValid = shouldParse(diagnosis);
  23. t.equal(isValid, expectedToBeValid,
  24. "[test " + id + "] address: " + address + ", expects: " + expectedToBeValid);
  25. });
  26. t.end();
  27. }
  28. function shouldParse(diagnosis) {
  29. var isOk = !startsWith(diagnosis, ISEMAIL_ERR) ||
  30. // is_email considers address with a domain beginning
  31. // or ending with "-" to be incorrect because they are not
  32. // valid domains, but we are only concerned with rfc5322.
  33. // From rfc5322's perspective, this is OK.
  34. diagnosis === ISEMAIL_ERR_DOMAINHYPHENSTART ||
  35. diagnosis === ISEMAIL_ERR_DOMAINHYPHENEND;
  36. return isOk;
  37. }
  38. // the is_email tests encode control characters
  39. // in the U+2400 block for display purposes
  40. function convertAddress(s) {
  41. var chars = [];
  42. for (var i = 0; i < s.length; i += 1) {
  43. var code = s.charCodeAt(i);
  44. if (code >= 0x2400) {
  45. code -= 0x2400;
  46. }
  47. chars.push(String.fromCharCode(code));
  48. }
  49. return chars.join('');
  50. }
  51. function getChildValue(parent, nodeName) {
  52. return parent.find(nodeName)[0].text();
  53. }
  54. function getAttr(node, attrName) {
  55. return node.attr(attrName).value();
  56. }
  57. function getNodes(xml, xpath) {
  58. var doc = libxmljs.parseXml(xml);
  59. return doc.find(xpath);
  60. }
  61. function startsWith(s, t) {
  62. return s.substring(0, t.length) === t;
  63. }
  64. test("isemail tests", function (t) {
  65. fs.readFile(TESTS_FILE, TESTS_FILE_ENCODING, function (err, data) {
  66. if (err) {
  67. t.end();
  68. return console.error(err);
  69. }
  70. isEmailTest(t, data);
  71. });
  72. });