diff --git a/.ava.browser.config.js b/.ava.browser.config.js new file mode 100644 index 0000000..231f06b --- /dev/null +++ b/.ava.browser.config.js @@ -0,0 +1,9 @@ +/* eslint-disable import/no-anonymous-default-export */ + +export default { + files: ["src/__tests__/index.test.js"], + verbose: true, + ignoredByWatcher: ["{coverage,examples/**"], + require: ["esm", "./src/__tests__/_setup-browser-env.js"], + nodeArguments: ["--experimental-modules"], +}; diff --git a/.ava.node.config.js b/.ava.node.config.js new file mode 100644 index 0000000..9e4f5f3 --- /dev/null +++ b/.ava.node.config.js @@ -0,0 +1,9 @@ +/* eslint-disable import/no-anonymous-default-export */ + +export default { + files: ["src/__tests__/index.node.test.js"], + verbose: true, + ignoredByWatcher: ["{coverage,examples/**"], + require: ["esm"], + nodeArguments: ["--experimental-modules"], +}; diff --git a/ava.config.js b/ava.config.js deleted file mode 100644 index 53b7ad7..0000000 --- a/ava.config.js +++ /dev/null @@ -1,11 +0,0 @@ -/* eslint-disable import/no-anonymous-default-export */ - -export default { - files: [ - 'src/__tests__/**' - ], - verbose: true, - ignoredByWatcher: ['{coverage,examples/**'], - require: ['esm', './src/__tests__/_setup-browser-env.js'], - nodeArguments: ['--experimental-modules'] -}; diff --git a/package.json b/package.json index 17f5973..17f1a55 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,13 @@ "all": "npm-run-all --sequential build lint cover", "lint": "xo", "lint:fix": "xo --fix", - "test": "ava", - "cover": "nyc npm run test", + "test:node": "ava --config .ava.node.config.js", + "test:browser": "ava --config .ava.browser.config.js", + "cover": "npm-run-all --sequential cover:browser cover:node cover:report", + "cover:all": "npm-run-all --sequential cover:browser cover:node", + "cover:node": "nyc --no-clean npm run test:node", + "cover:browser": "nyc npm run test:browser", + "cover:report": "nyc report --reporter=text-lcov | coveralls", "build": "babel --plugins '@babel/plugin-transform-modules-umd' src --out-file ./dist/index.js --no-comments" }, "browserslist": [ diff --git a/src/__tests__/_setup-browser-env.js b/src/__tests__/_setup-browser-env.js index 001a9bd..cf49b3f 100644 --- a/src/__tests__/_setup-browser-env.js +++ b/src/__tests__/_setup-browser-env.js @@ -1,2 +1,2 @@ const browserEnv = require('browser-env'); -browserEnv(['window', 'document']); +browserEnv(['window', 'document', 'DOMParser']); diff --git a/src/__tests__/index.node.test.js b/src/__tests__/index.node.test.js new file mode 100644 index 0000000..5247d21 --- /dev/null +++ b/src/__tests__/index.node.test.js @@ -0,0 +1,25 @@ +import test from 'ava'; +import getAttributes from '..'; + +test('`getAttributes.parse()` parses attributes from a string', t => { + const string = '
'; + const attrs = getAttributes.parse(string); + + t.deepEqual(attrs, { + 'data-brand-icon': 'ava', + 'data-brand-color': 'dark', + id: 'ava' + }); +}); + +test('`getAttributes.parse()` handles empty attributes from a string', t => { + const string = ''; + const attrs = getAttributes.parse(string); + + t.deepEqual(attrs, { + 'data-brand-icon': 'ava', + 'data-brand-color': 'dark', + 'empty-attribute': '', + id: 'ava' + }); +}); diff --git a/src/__tests__/index.test.js b/src/__tests__/index.test.js new file mode 100644 index 0000000..f499de4 --- /dev/null +++ b/src/__tests__/index.test.js @@ -0,0 +1,85 @@ +/* eslint-disable no-undef */ + +import test from 'ava'; +import getAttributes from '..'; + +test('`getAttributes.parse()` parses attributes from a DOM element', t => { + const div = document.createElement('div'); + div.dataset.brandIcon = 'ava'; + div.dataset.brandColor = 'dark'; + div.id = 'ava'; + + document.body.append(div); + + const attrs = getAttributes.parse(document.querySelector('#ava')); + + t.deepEqual(attrs, { + 'data-brand-icon': 'ava', + 'data-brand-color': 'dark', + id: 'ava' + }); +}); + +test('`getAttributes.parse()` parses attributes from a string', t => { + const string = ''; + const attrs = getAttributes.parse(string); + + t.deepEqual(attrs, { + 'data-brand-icon': 'ava', + 'data-brand-color': 'dark', + id: 'ava' + }); +}); + +test('`getAttributes.parse()` fails when given an empty string', t => { + const error = t.throws(() => { + getAttributes.parse(''); + }, {instanceOf: ReferenceError}); + + t.is(error.message, 'The string given to `getAttributes.parse()` is empty.'); +}); + +test('`getAttributes.parse()` fails when given a type other than string or node', t => { + const types = [[], {}, true, 3]; + + // Two assertions per item: `t.throws()` and `t.is()`. + t.plan(types.length * 2); + + types.forEach(type => { + const error = t.throws(() => { + getAttributes.parse(type); + }, {instanceOf: TypeError}); + + t.is(error.message, '`getAttributes.parse()` only accepts strings and nodes. An ' + typeof type + ' was given.'); + }); +}); + +test('`getAttributes.stringify()` returns a string when given a string', t => { + const attrString = getAttributes.stringify('Wow cool test'); + + t.is(attrString, 'Wow cool test'); +}); + +test('`getAttributes.stringify()` returns a string when given array', t => { + const arrayToString = getAttributes.stringify(['Wow', 'cool', 'test']); + + t.is(arrayToString, 'Wow cool test'); +}); + +test('`getAttributes.stringify()` returns a string when given object', t => { + const objectToString = getAttributes.stringify({ + 'data-brand-icon': 'ava', + 'data-brand-color': 'dark', + 'empty-attribute': '' + }); + + t.is(objectToString, 'data-brand-icon="ava" data-brand-color="dark" empty-attribute'); +}); + +test('`getAttributes.stringify()` fails when given an empty string', t => { + const error = t.throws(() => { + getAttributes.stringify(''); + }, {instanceOf: ReferenceError}); + + t.is(error.message, 'Cannot stringify undefined.'); +});