diff --git a/.gitignore b/.gitignore index 1521c8b..3b9923c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ dist +node_modules/ diff --git a/lib/__tests__/index-test.js b/lib/__tests__/index-test.js index de14b21..1c98fa3 100644 --- a/lib/__tests__/index-test.js +++ b/lib/__tests__/index-test.js @@ -8,7 +8,7 @@ var k = () => {}; var captureWarnings = (fn) => { var _warn = console.warn; var msgs = {}; - console.warn = (msg) => msgs[msg] = true; + console.warn = (id, msg) => msgs[msg] = true; fn(); console.warn = _warn; return msgs; diff --git a/lib/index.js b/lib/index.js index 1dd4a86..8ca8432 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,42 +1,51 @@ var React = require('react'); var assertions = require('./assertions'); -var assertAccessibility = (tagName, props, children, log) => { +var assertAccessibility = (tagName, props, children) => { var key; + var failures = []; - var tagTests = assertions.tags[tagName]; - if (tagTests) - for (key in tagTests) - log(tagTests[key].test(tagName, props, children), tagTests[key].msg); + var tagTests = assertions.tags[tagName] || []; + for (key in tagTests) + if (tagTests[key] && !tagTests[key].test(tagName, props, children)) + failures.push(tagTests[key].msg); var propTests; for (var propName in props) { if (props[propName] === null || props[propName] === undefined) continue; - propTests = assertions.props[propName]; - if (propTests) - for (key in propTests) - log(propTests[key].test(tagName, props, children), propTests[key].msg); + propTests = assertions.props[propName] || []; + for (key in propTests) + if (propTests[key] && !propTests[key].test(tagName, props, children)) + failures.push(propTests[key].msg); } + return failures; }; -var error = (passed, msg) => { - if (!passed) - throw new Error(msg); +var error = (id, msg) => { + throw new Error('#' + id + ": " + msg); }; -var warn = (passed, msg) => { - if (!passed) - console.warn(msg); +var warn = (id, msg) => { + console.warn('#' + id, msg); }; +var nextId = 0; module.exports = (options) => { var _createElement = React.createElement; var log = options && options.throw ? error : warn; React.createElement = function (type, _props, ...children) { + var props = _props || {}; if (typeof type === 'string') { - var props = _props || {}; - assertAccessibility(type, props, children, log); + var failures = assertAccessibility(type, props, children); + if (failures.length) { + // Generate an id if one doesn't exist + props.id = (props.id || 'a11y-' + nextId++); + + for (var i = 0; i < failures.length; i++) + log(props.id, failures[i]); + } } - return _createElement.apply(this, arguments); + // make sure props with the id is passed down, even if no props were passed in. + return _createElement.apply(this, [type, props].concat(children)); }; };