From a284cbf4eb21292c4cff87f02be0bfb82764757f Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 2 Sep 2024 23:49:42 -0700 Subject: [PATCH] [Tests] switch from jest to tape This allows us to: - drop all the jest mocks - no longer be stuck on an EOL version nor be forced to raise the engines.node threshold - run tests 4x faster: jest takes 27.365s, tape takes 7.086s --- .github/workflows/node-4+.yml | 2 +- __tests__/__util__/nodeReexports/assert.js | 3 - .../__util__/nodeReexports/fs-promises.js | 3 - __tests__/__util__/nodeReexports/fs.js | 3 - __tests__/__util__/nodeReexports/path.js | 3 - __tests__/__util__/nodeReexports/url.js | 3 - __tests__/__util__/nodeReexports/util.js | 3 - __tests__/index-test.js | 39 +-- .../src/rules/anchor-ambiguous-text-test.js | 1 - __tests__/src/rules/aria-proptypes-test.js | 18 +- .../src/util/attributesComparator-test.js | 196 ++++++------ .../src/util/getAccessibleChildText-test.js | 157 ++++++---- __tests__/src/util/getComputedRole-test.js | 132 ++++---- __tests__/src/util/getElementType-test.js | 107 ++++--- __tests__/src/util/getExplicitRole-test.js | 57 ++-- __tests__/src/util/getImplicitRole-test.js | 40 +-- __tests__/src/util/getSuggestion-test.js | 75 ++--- __tests__/src/util/getTabIndex-test.js | 158 +++++----- __tests__/src/util/hasAccessibleChild-test.js | 220 +++++++------ .../src/util/implicitRoles/input-test.js | 109 +++++-- __tests__/src/util/implicitRoles/menu-test.js | 24 +- .../src/util/implicitRoles/menuitem-test.js | 51 ++-- __tests__/src/util/isAbstractRole-test.js | 48 +-- __tests__/src/util/isContentEditable-test.js | 93 +++--- __tests__/src/util/isDOMElement-test.js | 36 ++- __tests__/src/util/isDisabledElement-test.js | 157 +++++----- __tests__/src/util/isFocusable-test.js | 105 ++++--- .../src/util/isInteractiveElement-test.js | 104 ++++--- __tests__/src/util/isInteractiveRole-test.js | 61 ++-- .../src/util/isNonInteractiveElement-test.js | 93 ++++-- .../src/util/isNonInteractiveRole-test.js | 61 ++-- .../src/util/isNonLiteralProperty-test.js | 72 +++-- .../src/util/isSemanticRoleElement-test.js | 77 +++-- .../src/util/mayContainChildComponent-test.js | 225 ++++++++------ .../src/util/mayHaveAccessibleLabel-test.js | 288 +++++++++++------- .../src/util/parserOptionsMapper-test.js | 125 ++++---- __tests__/src/util/schemas-test.js | 44 +-- package.json | 40 +-- scripts/boilerplate/test.js | 3 +- setup.jest.js | 2 - 40 files changed, 1723 insertions(+), 1315 deletions(-) delete mode 100644 __tests__/__util__/nodeReexports/assert.js delete mode 100644 __tests__/__util__/nodeReexports/fs-promises.js delete mode 100644 __tests__/__util__/nodeReexports/fs.js delete mode 100644 __tests__/__util__/nodeReexports/path.js delete mode 100644 __tests__/__util__/nodeReexports/url.js delete mode 100644 __tests__/__util__/nodeReexports/util.js delete mode 100644 setup.jest.js diff --git a/.github/workflows/node-4+.yml b/.github/workflows/node-4+.yml index a21d5c9d3..fba82fd3b 100644 --- a/.github/workflows/node-4+.yml +++ b/.github/workflows/node-4+.yml @@ -128,7 +128,7 @@ jobs: skip-ls-check: true - run: rm __tests__/src/util/getComputedRole-test.js if: ${{ matrix.node-version < 7 }} - - run: npm run test:ci + - run: npm run tests-only - uses: codecov/codecov-action@v3.1.5 node: diff --git a/__tests__/__util__/nodeReexports/assert.js b/__tests__/__util__/nodeReexports/assert.js deleted file mode 100644 index 78f8d741f..000000000 --- a/__tests__/__util__/nodeReexports/assert.js +++ /dev/null @@ -1,3 +0,0 @@ -import assert from 'assert'; - -export default assert; diff --git a/__tests__/__util__/nodeReexports/fs-promises.js b/__tests__/__util__/nodeReexports/fs-promises.js deleted file mode 100644 index c0d0215b9..000000000 --- a/__tests__/__util__/nodeReexports/fs-promises.js +++ /dev/null @@ -1,3 +0,0 @@ -import fs from 'fs/promises'; - -export default fs; diff --git a/__tests__/__util__/nodeReexports/fs.js b/__tests__/__util__/nodeReexports/fs.js deleted file mode 100644 index 6b9cf6a67..000000000 --- a/__tests__/__util__/nodeReexports/fs.js +++ /dev/null @@ -1,3 +0,0 @@ -import fs from 'fs'; - -export default fs; diff --git a/__tests__/__util__/nodeReexports/path.js b/__tests__/__util__/nodeReexports/path.js deleted file mode 100644 index 7b411d509..000000000 --- a/__tests__/__util__/nodeReexports/path.js +++ /dev/null @@ -1,3 +0,0 @@ -import path from 'path'; - -export default path; diff --git a/__tests__/__util__/nodeReexports/url.js b/__tests__/__util__/nodeReexports/url.js deleted file mode 100644 index e851de2b4..000000000 --- a/__tests__/__util__/nodeReexports/url.js +++ /dev/null @@ -1,3 +0,0 @@ -import url from 'url'; - -export default url; diff --git a/__tests__/__util__/nodeReexports/util.js b/__tests__/__util__/nodeReexports/util.js deleted file mode 100644 index 1e9ac4b66..000000000 --- a/__tests__/__util__/nodeReexports/util.js +++ /dev/null @@ -1,3 +0,0 @@ -import util from 'util'; - -export default util; diff --git a/__tests__/index-test.js b/__tests__/index-test.js index e782b4947..f8bbe5381 100644 --- a/__tests__/index-test.js +++ b/__tests__/index-test.js @@ -2,36 +2,39 @@ import fs from 'fs'; import path from 'path'; -import expect from 'expect'; +import test from 'tape'; + import plugin from '../src'; const rules = fs.readdirSync(path.resolve(__dirname, '../src/rules/')) .map((f) => path.basename(f, '.js')); -describe('all rule files should be exported by the plugin', () => { +test('all rule files should be exported by the plugin', (t) => { rules.forEach((ruleName) => { - it(`should export ${ruleName}`, () => { - expect(plugin.rules[ruleName]).toEqual( - require(path.join('../src/rules', ruleName)) // eslint-disable-line - ); - }); + t.equal( + plugin.rules[ruleName], + require(path.join('../src/rules', ruleName)), // eslint-disable-line import/no-dynamic-require + `exports ${ruleName}`, + ); }); + + t.end(); }); -describe('configurations', () => { - it('should export a \'recommended\' configuration', () => { - expect(plugin.configs.recommended).toBeDefined(); - }); +test('configurations', (t) => { + t.notEqual(plugin.configs.recommended, undefined, 'exports a \'recommended\' configuration'); + + t.end(); }); -describe('schemas', () => { +test('schemas', (t) => { rules.forEach((ruleName) => { - it(`${ruleName} should export a schema with type object`, () => { - const rule = require(path.join('../src/rules', ruleName)); // eslint-disable-line - const schema = rule.meta && rule.meta.schema && rule.meta.schema[0]; - const { type } = schema; + const rule = require(path.join('../src/rules', ruleName)); // eslint-disable-line import/no-dynamic-require + const schema = rule.meta && rule.meta.schema && rule.meta.schema[0]; + const { type } = schema; - expect(type).toEqual('object'); - }); + t.equal(type, 'object', `${ruleName} exports a schema with type object`); }); + + t.end(); }); diff --git a/__tests__/src/rules/anchor-ambiguous-text-test.js b/__tests__/src/rules/anchor-ambiguous-text-test.js index cbbc39501..12769d9ad 100644 --- a/__tests__/src/rules/anchor-ambiguous-text-test.js +++ b/__tests__/src/rules/anchor-ambiguous-text-test.js @@ -1,4 +1,3 @@ -/* eslint-env jest */ /** * @fileoverview Enforce `` text to not exactly match "click here", "here", "link", or "a link". * @author Matt Wang diff --git a/__tests__/src/rules/aria-proptypes-test.js b/__tests__/src/rules/aria-proptypes-test.js index 67be3304a..851cd7b30 100644 --- a/__tests__/src/rules/aria-proptypes-test.js +++ b/__tests__/src/rules/aria-proptypes-test.js @@ -9,7 +9,8 @@ import { aria } from 'aria-query'; import { RuleTester } from 'eslint'; -import expect from 'expect'; +import test from 'tape'; + import parserOptionsMapper from '../../__util__/parserOptionsMapper'; import parsers from '../../__util__/helpers/parsers'; import rule from '../../../src/rules/aria-proptypes'; @@ -51,13 +52,14 @@ tokens from the following: ${permittedValues}.`, } }; -describe('validityCheck', () => { - it('should false for an unknown expected type', () => { - expect(validityCheck( - null, - null, - )).toBe(false); - }); +test('validityCheck', (t) => { + t.equal( + validityCheck(null, null), + false, + 'is false for an unknown expected type', + ); + + t.end(); }); ruleTester.run('aria-proptypes', rule, { diff --git a/__tests__/src/util/attributesComparator-test.js b/__tests__/src/util/attributesComparator-test.js index 0fe706cb7..aad0038f1 100644 --- a/__tests__/src/util/attributesComparator-test.js +++ b/__tests__/src/util/attributesComparator-test.js @@ -1,115 +1,91 @@ -import expect from 'expect'; +import test from 'tape'; + import attributesComparator from '../../../src/util/attributesComparator'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; import JSXElementMock from '../../../__mocks__/JSXElementMock'; -describe('attributesComparator', () => { - describe('base attributes', () => { - let baseAttributes; - let attributes; - describe('are undefined', () => { - describe('and attributes are undefined', () => { - it('should return true', () => { - expect(attributesComparator()).toBe(true); - }); - }); - }); - describe('are empty', () => { - beforeEach(() => { - baseAttributes = []; - }); - describe('and attributes', () => { - describe('are empty', () => { - attributes = []; - it('should return true', () => { - expect(attributesComparator(baseAttributes, attributes)) - .toBe(true); - }); - }); - describe('have values', () => { - attributes = [ - JSXAttributeMock('foo', 0), - JSXAttributeMock('bar', 'baz'), - ]; - it('should return true', () => { - expect(attributesComparator(baseAttributes, attributes)) - .toBe(true); - }); - }); - }); - }); - describe('have values', () => { - beforeEach(() => { - baseAttributes = [ - { - name: 'biz', - value: 1, - }, { - name: 'fizz', - value: 'pop', - }, { - name: 'fuzz', - value: 'lolz', - }, - ]; - }); - describe('and attributes', () => { - describe('are empty', () => { - attributes = []; - it('should return false', () => { - expect(attributesComparator(baseAttributes, attributes)) - .toBe(false); - }); - }); - describe('have values', () => { - describe('and the values are the different', () => { - it('should return false', () => { - attributes = [ - JSXElementMock(), - JSXAttributeMock('biz', 2), - JSXAttributeMock('ziff', 'opo'), - JSXAttributeMock('far', 'lolz'), - ]; - expect(attributesComparator(baseAttributes, attributes)) - .toBe(false); - }); - }); - describe('and the values are a subset', () => { - it('should return true', () => { - attributes = [ - JSXAttributeMock('biz', 1), - JSXAttributeMock('fizz', 'pop'), - JSXAttributeMock('goo', 'gazz'), - ]; - expect(attributesComparator(baseAttributes, attributes)) - .toBe(false); - }); - }); - describe('and the values are the same', () => { - it('should return true', () => { - attributes = [ - JSXAttributeMock('biz', 1), - JSXAttributeMock('fizz', 'pop'), - JSXAttributeMock('fuzz', 'lolz'), - ]; - expect(attributesComparator(baseAttributes, attributes)) - .toBe(true); - }); - }); - describe('and the values are a superset', () => { - it('should return true', () => { - attributes = [ - JSXAttributeMock('biz', 1), - JSXAttributeMock('fizz', 'pop'), - JSXAttributeMock('fuzz', 'lolz'), - JSXAttributeMock('dar', 'tee'), - ]; - expect(attributesComparator(baseAttributes, attributes)) - .toBe(true); - }); - }); - }); - }); - }); - }); +test('attributesComparator', (t) => { + t.equal( + attributesComparator(), + true, + 'baseAttributes are undefined and attributes are undefined -> true', + ); + + t.equal( + attributesComparator([], []), + true, + 'baseAttributes are empty and attributes are empty -> true', + ); + + t.equal( + attributesComparator([], [ + JSXAttributeMock('foo', 0), + JSXAttributeMock('bar', 'baz'), + ]), + true, + 'baseAttributes are empty and attributes have values -> true', + ); + + const baseAttributes = [ + { + name: 'biz', + value: 1, + }, { + name: 'fizz', + value: 'pop', + }, { + name: 'fuzz', + value: 'lolz', + }, + ]; + + t.equal( + attributesComparator(baseAttributes, []), + false, + 'baseAttributes have values and attributes are empty -> false', + ); + + t.equal( + attributesComparator(baseAttributes, [ + JSXElementMock(), + JSXAttributeMock('biz', 2), + JSXAttributeMock('ziff', 'opo'), + JSXAttributeMock('far', 'lolz'), + ]), + false, + 'baseAttributes have values and attributes have values, and the values are different -> false', + ); + + t.equal( + attributesComparator(baseAttributes, [ + JSXAttributeMock('biz', 1), + JSXAttributeMock('fizz', 'pop'), + JSXAttributeMock('goo', 'gazz'), + ]), + false, + 'baseAttributes have values and attributes have values, and the values are a subset -> false', + ); + + t.equal( + attributesComparator(baseAttributes, [ + JSXAttributeMock('biz', 1), + JSXAttributeMock('fizz', 'pop'), + JSXAttributeMock('fuzz', 'lolz'), + ]), + true, + 'baseAttributes have values and attributes have values, and the values are the same -> true', + ); + + t.equal( + attributesComparator(baseAttributes, [ + JSXAttributeMock('biz', 1), + JSXAttributeMock('fizz', 'pop'), + JSXAttributeMock('fuzz', 'lolz'), + JSXAttributeMock('dar', 'tee'), + ]), + true, + 'baseAttributes have values and attributes have values, and the values are a superset -> true', + ); + + t.end(); }); diff --git a/__tests__/src/util/getAccessibleChildText-test.js b/__tests__/src/util/getAccessibleChildText-test.js index a77d9d270..11edc4694 100644 --- a/__tests__/src/util/getAccessibleChildText-test.js +++ b/__tests__/src/util/getAccessibleChildText-test.js @@ -1,95 +1,116 @@ -import expect from 'expect'; +import test from 'tape'; import { elementType } from 'jsx-ast-utils'; + import getAccessibleChildText from '../../../src/util/getAccessibleChildText'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; import JSXElementMock from '../../../__mocks__/JSXElementMock'; -describe('getAccessibleChildText', () => { - it('returns the aria-label when present', () => { - expect(getAccessibleChildText(JSXElementMock( +test('getAccessibleChildText', (t) => { + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [JSXAttributeMock('aria-label', 'foo')], - ), elementType)).toBe('foo'); - }); + ), elementType), + 'foo', + 'returns the aria-label when present', + ); - it('returns the aria-label instead of children', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [JSXAttributeMock('aria-label', 'foo')], [{ type: 'JSXText', value: 'bar' }], - ), elementType)).toBe('foo'); - }); + ), elementType), + 'foo', + 'returns the aria-label instead of children', + ); - it('skips elements with aria-hidden=true', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [JSXAttributeMock('aria-hidden', 'true')], - ), elementType)).toBe(''); - }); + ), elementType), + '', + 'skips elements with aria-hidden=true', + ); - it('returns literal value for JSXText child', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [{ type: 'JSXText', value: 'bar' }], - ), elementType)).toBe('bar'); - }); + ), elementType), + 'bar', + 'returns literal value for JSXText child', + ); - it('returns alt text for img child', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [JSXElementMock('img', [ JSXAttributeMock('src', 'some/path'), JSXAttributeMock('alt', 'a sensible label'), ])], - ), elementType)).toBe('a sensible label'); - }); + ), elementType), + 'a sensible label', + 'returns alt text for img child', + ); - it('returns blank when alt tag is used on arbitrary element', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [JSXElementMock('span', [ JSXAttributeMock('alt', 'a sensible label'), ])], - ), elementType)).toBe(''); - }); + ), elementType), + '', + 'returns blank when alt tag is used on arbitrary element', + ); - it('returns literal value for JSXText child', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [{ type: 'Literal', value: 'bar' }], - ), elementType)).toBe('bar'); - }); + ), elementType), + 'bar', + 'returns literal value for JSXText child', + ); - it('returns trimmed literal value for JSXText child', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [{ type: 'Literal', value: ' bar ' }], - ), elementType)).toBe('bar'); - }); + ), elementType), + 'bar', + 'returns trimmed literal value for JSXText child', + ); - it('returns space-collapsed literal value for JSXText child', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [{ type: 'Literal', value: 'foo bar' }], - ), elementType)).toBe('foo bar'); - }); + ), elementType), + 'foo bar', + 'returns space-collapsed literal value for JSXText child', + ); - it('returns punctuation-stripped literal value for JSXText child', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [{ type: 'Literal', value: 'foo, bar. baz? foo; bar:' }], - ), elementType)).toBe('foo bar baz foo bar'); - }); + ), elementType), + 'foo bar baz foo bar', + 'returns punctuation-stripped literal value for JSXText child', + ); - it('returns recursive value for JSXElement child', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [JSXElementMock( @@ -97,11 +118,13 @@ describe('getAccessibleChildText', () => { [], [{ type: 'Literal', value: 'bar' }], )], - ), elementType)).toBe('bar'); - }); + ), elementType), + 'bar', + 'returns recursive value for JSXElement child', + ); - it('skips children with aria-hidden-true', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [JSXElementMock( @@ -112,30 +135,40 @@ describe('getAccessibleChildText', () => { [JSXAttributeMock('aria-hidden', 'true')], )], )], - ), elementType)).toBe(''); - }); + ), elementType), + '', + 'skips children with aria-hidden-true', + ); - it('joins multiple children properly - no spacing', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [{ type: 'Literal', value: 'foo' }, { type: 'Literal', value: 'bar' }], - ), elementType)).toBe('foo bar'); - }); + ), elementType), + 'foo bar', + 'joins multiple children properly - no spacing', + ); - it('joins multiple children properly - with spacing', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [{ type: 'Literal', value: ' foo ' }, { type: 'Literal', value: ' bar ' }], - ), elementType)).toBe('foo bar'); - }); + ), elementType), + 'foo bar', + 'joins multiple children properly - with spacing', + ); - it('skips unknown elements', () => { - expect(getAccessibleChildText(JSXElementMock( + t.equal( + getAccessibleChildText(JSXElementMock( 'a', [], [{ type: 'Literal', value: 'foo' }, { type: 'Unknown' }, { type: 'Literal', value: 'bar' }], - ), elementType)).toBe('foo bar'); - }); + ), elementType), + 'foo bar', + 'skips unknown elements', + ); + + t.end(); }); diff --git a/__tests__/src/util/getComputedRole-test.js b/__tests__/src/util/getComputedRole-test.js index 33a2d8e0a..29e6b8492 100644 --- a/__tests__/src/util/getComputedRole-test.js +++ b/__tests__/src/util/getComputedRole-test.js @@ -1,71 +1,71 @@ -import expect from 'expect'; +import test from 'tape'; + import getComputedRole from '../../../src/util/getComputedRole'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; -describe('getComputedRole', () => { - describe('explicit role', () => { - describe('valid role', () => { - it('should return the role', () => { - expect(getComputedRole( - 'div', - [JSXAttributeMock('role', 'button')], - )).toBe('button'); - }); - }); - describe('invalid role', () => { - describe('has implicit', () => { - it('should return the implicit role', () => { - expect(getComputedRole( - 'li', - [JSXAttributeMock('role', 'beeswax')], - )).toBe('listitem'); - }); - }); - describe('lacks implicit', () => { - it('should return null', () => { - expect(getComputedRole( - 'div', - [JSXAttributeMock('role', 'beeswax')], - )).toBeNull(); - }); - }); - }); +test('getComputedRole', (t) => { + t.equal( + getComputedRole( + 'div', + [JSXAttributeMock('role', 'button')], + ), + 'button', + 'explicit role + valid role -> returns the role', + ); + + t.equal( + getComputedRole( + 'li', + [JSXAttributeMock('role', 'beeswax')], + ), + 'listitem', + 'explicit role + invalid role + has implicit -> returns the implicit role', + ); + + t.equal( + getComputedRole( + 'div', + [JSXAttributeMock('role', 'beeswax')], + ), + null, + 'explicit role + invalid role + lacks implicit -> returns null', + ); + + t.equal( + getComputedRole( + 'li', + [], + ), + 'listitem', + 'explicit role + no role + has implicit -> returns the implicit role', + ); + + t.equal( + getComputedRole( + 'div', + [], + ), + null, + 'explicit role + no role + lacks implicit -> returns null', + ); + + t.equal( + getComputedRole( + 'li', + [JSXAttributeMock('role', 'beeswax')], + ), + 'listitem', + 'implicit role + has implicit -> returns the implicit role', + ); + + t.equal( + getComputedRole( + 'div', + [], + ), + null, + 'implicit role + lacks implicit -> returns null', + ); - describe('no role', () => { - describe('has implicit', () => { - it('should return the implicit role', () => { - expect(getComputedRole( - 'li', - [], - )).toBe('listitem'); - }); - }); - describe('lacks implicit', () => { - it('should return null', () => { - expect(getComputedRole( - 'div', - [], - )).toBeNull(); - }); - }); - }); - }); - describe('implicit role', () => { - describe('has implicit', () => { - it('should return the implicit role', () => { - expect(getComputedRole( - 'li', - [JSXAttributeMock('role', 'beeswax')], - )).toBe('listitem'); - }); - }); - describe('lacks implicit', () => { - it('should return null', () => { - expect(getComputedRole( - 'div', - [], - )).toBeNull(); - }); - }); - }); + t.end(); }); diff --git a/__tests__/src/util/getElementType-test.js b/__tests__/src/util/getElementType-test.js index ab8aae728..971276872 100644 --- a/__tests__/src/util/getElementType-test.js +++ b/__tests__/src/util/getElementType-test.js @@ -1,30 +1,41 @@ -import expect from 'expect'; +import test from 'tape'; + import getElementType from '../../../src/util/getElementType'; import JSXElementMock from '../../../__mocks__/JSXElementMock'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; -describe('getElementType', () => { - describe('no settings in context', () => { +test('getElementType', (t) => { + t.test('no settings in context', (st) => { const elementType = getElementType({ settings: {} }); - it('should return the exact tag name for a DOM element', () => { - expect(elementType(JSXElementMock('input').openingElement)).toBe('input'); - }); + st.equal( + elementType(JSXElementMock('input').openingElement), + 'input', + 'returns the exact tag name for a DOM element', + ); - it('should return the exact tag name for a custom element', () => { - expect(elementType(JSXElementMock('CustomInput').openingElement)).toBe('CustomInput'); - }); + st.equal( + elementType(JSXElementMock('CustomInput').openingElement), + 'CustomInput', + 'returns the exact tag name for a custom element', + ); - it('should return the exact tag name for names that are in Object.prototype', () => { - expect(elementType(JSXElementMock('toString').openingElement)).toBe('toString'); - }); + st.equal( + elementType(JSXElementMock('toString').openingElement), + 'toString', + 'returns the exact tag name for names that are in Object.prototype', + ); - it('should return the default tag name provided', () => { - expect(elementType(JSXElementMock('span', [JSXAttributeMock('as', 'h1')]).openingElement)).toBe('span'); - }); + st.equal( + elementType(JSXElementMock('span', [JSXAttributeMock('as', 'h1')]).openingElement), + 'span', + 'returns the default tag name provided', + ); + + st.end(); }); - describe('components settings in context', () => { + t.test('components settings in context', (st) => { const elementType = getElementType({ settings: { 'jsx-a11y': { @@ -35,24 +46,34 @@ describe('getElementType', () => { }, }); - it('should return the exact tag name for a DOM element', () => { - expect(elementType(JSXElementMock('input').openingElement)).toBe('input'); - }); + st.equal( + elementType(JSXElementMock('input').openingElement), + 'input', + 'returns the exact tag name for a DOM element', + ); - it('should return the mapped tag name for a custom element', () => { - expect(elementType(JSXElementMock('CustomInput').openingElement)).toBe('input'); - }); + st.equal( + elementType(JSXElementMock('CustomInput').openingElement), + 'input', + 'returns the mapped tag name for a custom element', + ); - it('should return the exact tag name for a custom element not in the components map', () => { - expect(elementType(JSXElementMock('CityInput').openingElement)).toBe('CityInput'); - }); + st.equal( + elementType(JSXElementMock('CityInput').openingElement), + 'CityInput', + 'returns the exact tag name for a custom element not in the components map', + ); - it('should return the default tag name since not polymorphicPropName was provided', () => { - expect(elementType(JSXElementMock('span', [JSXAttributeMock('as', 'h1')]).openingElement)).toBe('span'); - }); + st.equal( + elementType(JSXElementMock('span', [JSXAttributeMock('as', 'h1')]).openingElement), + 'span', + 'return the default tag name since not polymorphicPropName was provided', + ); + + st.end(); }); - describe('polymorphicPropName settings in context', () => { + t.test('polymorphicPropName settings in context', (st) => { const elementType = getElementType({ settings: { 'jsx-a11y': { @@ -64,16 +85,26 @@ describe('getElementType', () => { }, }); - it('should return the tag name provided by the polymorphic prop, "asChild", defined in the settings', () => { - expect(elementType(JSXElementMock('span', [JSXAttributeMock('asChild', 'h1')]).openingElement)).toBe('h1'); - }); + st.equal( + elementType(JSXElementMock('span', [JSXAttributeMock('asChild', 'h1')]).openingElement), + 'h1', + 'returns the tag name provided by the polymorphic prop, "asChild", defined in the settings', + ); - it('should return the tag name provided by the polymorphic prop, "asChild", defined in the settings instead of the component mapping tag', () => { - expect(elementType(JSXElementMock('CustomButton', [JSXAttributeMock('asChild', 'a')]).openingElement)).toBe('a'); - }); + st.equal( + elementType(JSXElementMock('CustomButton', [JSXAttributeMock('asChild', 'a')]).openingElement), + 'a', + 'returns the tag name provided by the polymorphic prop, "asChild", defined in the settings instead of the component mapping tag', + ); - it('should return the tag name provided by the componnet mapping if the polymorphic prop, "asChild", defined in the settings is not set', () => { - expect(elementType(JSXElementMock('CustomButton', [JSXAttributeMock('as', 'a')]).openingElement)).toBe('button'); - }); + st.equal( + elementType(JSXElementMock('CustomButton', [JSXAttributeMock('as', 'a')]).openingElement), + 'button', + 'returns the tag name provided by the componnet mapping if the polymorphic prop, "asChild", defined in the settings is not set', + ); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/getExplicitRole-test.js b/__tests__/src/util/getExplicitRole-test.js index 102628c23..a49edfe51 100644 --- a/__tests__/src/util/getExplicitRole-test.js +++ b/__tests__/src/util/getExplicitRole-test.js @@ -1,30 +1,35 @@ -import expect from 'expect'; +import test from 'tape'; + import getExplicitRole from '../../../src/util/getExplicitRole'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; -describe('getExplicitRole', () => { - describe('valid role', () => { - it('should return the role', () => { - expect(getExplicitRole( - 'div', - [JSXAttributeMock('role', 'button')], - )).toBe('button'); - }); - }); - describe('invalid role', () => { - it('should return null', () => { - expect(getExplicitRole( - 'div', - [JSXAttributeMock('role', 'beeswax')], - )).toBeNull(); - }); - }); - describe('no role', () => { - it('should return null', () => { - expect(getExplicitRole( - 'div', - [], - )).toBeNull(); - }); - }); +test('getExplicitRole', (t) => { + t.equal( + getExplicitRole( + 'div', + [JSXAttributeMock('role', 'button')], + ), + 'button', + 'valid role returns the role', + ); + + t.equal( + getExplicitRole( + 'div', + [JSXAttributeMock('role', 'beeswax')], + ), + null, + 'invalid role returns null', + ); + + t.equal( + getExplicitRole( + 'div', + [], + ), + null, + 'no role returns null', + ); + + t.end(); }); diff --git a/__tests__/src/util/getImplicitRole-test.js b/__tests__/src/util/getImplicitRole-test.js index 76176ab6a..4d8028d2a 100644 --- a/__tests__/src/util/getImplicitRole-test.js +++ b/__tests__/src/util/getImplicitRole-test.js @@ -1,21 +1,25 @@ -import expect from 'expect'; +import test from 'tape'; + import getImplicitRole from '../../../src/util/getImplicitRole'; -describe('getImplicitRole', () => { - describe('has implicit', () => { - it('should return the implicit role', () => { - expect(getImplicitRole( - 'li', - [], - )).toBe('listitem'); - }); - }); - describe('lacks implicit', () => { - it('should return null', () => { - expect(getImplicitRole( - 'div', - [], - )).toBeNull(); - }); - }); +test('getImplicitRole', (t) => { + t.equal( + getImplicitRole( + 'li', + [], + ), + 'listitem', + 'has implicit, returns implicit role', + ); + + t.equal( + getImplicitRole( + 'div', + [], + ), + null, + 'lacks implicit, returns null', + ); + + t.end(); }); diff --git a/__tests__/src/util/getSuggestion-test.js b/__tests__/src/util/getSuggestion-test.js index 2f5e1c1b3..41b2d4736 100644 --- a/__tests__/src/util/getSuggestion-test.js +++ b/__tests__/src/util/getSuggestion-test.js @@ -1,48 +1,33 @@ -import expect from 'expect'; -import getSuggestion from '../../../src/util/getSuggestion'; - -describe('spell check suggestion API', () => { - it('should return no suggestions given empty word and no dictionary', () => { - const word = ''; - const expected = []; - const actual = getSuggestion(word); - - expect(expected).toEqual(actual); - }); - - it('should return no suggestions given real word and no dictionary', () => { - const word = 'foo'; - const expected = []; - const actual = getSuggestion(word); - - expect(expected).toEqual(actual); - }); +import test from 'tape'; - it('should return correct suggestion given real word and a dictionary', () => { - const word = 'fo'; - const dictionary = ['foo', 'bar', 'baz']; - const expected = ['foo']; - const actual = getSuggestion(word, dictionary); - - expect(expected).toEqual(actual); - }); - - it('should return multiple correct suggestions given real word and a dictionary', () => { - const word = 'theer'; - const dictionary = ['there', 'their', 'foo', 'bar']; - const expected = ['there', 'their']; - const actual = getSuggestion(word, dictionary); - - expect(expected).toEqual(actual); - }); - - it('should return correct # of suggestions given the limit argument', () => { - const word = 'theer'; - const dictionary = ['there', 'their', 'foo', 'bar']; - const limit = 1; - const expected = 1; - const actual = getSuggestion(word, dictionary, limit).length; +import getSuggestion from '../../../src/util/getSuggestion'; - expect(expected).toEqual(actual); - }); +test('spell check suggestion API', (t) => { + t.deepEqual([], getSuggestion('foo'), 'returns no suggestions given empty word and no dictionary'); + + t.deepEqual( + getSuggestion('foo'), + [], + 'returns no suggestions given real word and no dictionary', + ); + + t.deepEqual( + getSuggestion('fo', ['foo', 'bar', 'baz']), + ['foo'], + 'returns correct suggestion given real word and a dictionary', + ); + + t.deepEqual( + getSuggestion('theer', ['there', 'their', 'foo', 'bar']), + ['there', 'their'], + 'returns multiple correct suggestions given real word and a dictionary', + ); + + t.deepEqual( + getSuggestion('theer', ['there', 'their', 'foo', 'bar'], 1), + ['there'], + 'returns correct # of suggestions given the limit argument', + ); + + t.end(); }); diff --git a/__tests__/src/util/getTabIndex-test.js b/__tests__/src/util/getTabIndex-test.js index 6174ae9b1..23fb95e75 100644 --- a/__tests__/src/util/getTabIndex-test.js +++ b/__tests__/src/util/getTabIndex-test.js @@ -1,83 +1,85 @@ -import expect from 'expect'; +import test from 'tape'; + import getTabIndex from '../../../src/util/getTabIndex'; import IdentifierMock from '../../../__mocks__/IdentifierMock'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; -describe('getTabIndex', () => { - describe('tabIndex is defined', () => { - describe('as a number ', () => { - describe('zero', () => { - it('should return zero', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', 0))).toBe(0); - }); - }); - describe('positive integer', () => { - it('should return the integer', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', 1))).toBe(1); - }); - }); - describe('negative integer', () => { - it('should return the integer', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', -1))).toBe(-1); - }); - }); - describe('float', () => { - it('should return undefined', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', 9.1))).toBeUndefined(); - }); - }); - }); - describe('as a string', () => { - describe('empty', () => { - it('should return undefined', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', ''))).toBeUndefined(); - }); - }); - describe('which converts to a number', () => { - it('should return an integer', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', '0'))).toBe(0); - }); - }); - describe('which is NaN', () => { - it('should return undefined', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', '0a'))).toBeUndefined(); - }); - }); - }); - describe('as a boolean', () => { - describe('true', () => { - it('should return undefined', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', true))).toBeUndefined(); - }); - }); - describe('false', () => { - it('should return undefined', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', false))).toBeUndefined(); - }); - }); - }); - describe('as an expression', () => { - describe('function expression', () => { - it('should return the correct type', () => { - const attr = function mockFn() { return 0; }; - expect(typeof getTabIndex(JSXAttributeMock('tabIndex', attr))).toEqual('function'); - }); - }); - describe('variable expression', () => { - it('should return the Identifier name', () => { - const name = 'identName'; - expect(getTabIndex(JSXAttributeMock( - 'tabIndex', - IdentifierMock(name), - true, - ))).toEqual(name); - }); - }); - }); - }); - describe('tabIndex is not defined', () => { - it('should return undefined', () => { - expect(getTabIndex(JSXAttributeMock('tabIndex', undefined))).toBeUndefined(); - }); - }); +test('getTabIndex', (t) => { + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', 0)), + 0, + 'tabIndex is defined as zero -> zero', + ); + + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', 1)), + 1, + 'tabIndex is defined as a positive integer -> returns it', + ); + + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', -1)), + -1, + 'tabIndex is defined as a negative integer -> returns it', + ); + + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', '')), + undefined, + 'tabIndex is defined as an empty string -> undefined', + ); + + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', 9.1)), + undefined, + 'tabIndex is defined as a float -> undefined', + ); + + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', '0')), + 0, + 'tabIndex is defined as a string which converts to a number -> returns the integer', + ); + + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', '0a')), + undefined, + 'tabIndex is defined as a string which is NaN -> returns undefined', + ); + + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', true)), + undefined, + 'tabIndex is defined as true -> returns undefined', + ); + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', false)), + undefined, + 'tabIndex is defined as false -> returns undefined', + ); + + t.equal( + typeof getTabIndex(JSXAttributeMock('tabIndex', () => 0)), + 'function', + 'tabIndex is defined as a function expression -> returns the correct type', + ); + + const name = 'identName'; + t.equal( + getTabIndex(JSXAttributeMock( + 'tabIndex', + IdentifierMock(name), + true, + )), + name, + 'tabIndex is defined as a variable expression -> returns the Identifier name', + ); + + t.equal( + getTabIndex(JSXAttributeMock('tabIndex', undefined)), + undefined, + 'tabIndex is not defined -> returns undefined', + ); + + t.end(); }); diff --git a/__tests__/src/util/hasAccessibleChild-test.js b/__tests__/src/util/hasAccessibleChild-test.js index 5309ae9c5..82ba88cfc 100644 --- a/__tests__/src/util/hasAccessibleChild-test.js +++ b/__tests__/src/util/hasAccessibleChild-test.js @@ -1,107 +1,157 @@ -import expect from 'expect'; +import test from 'tape'; import { elementType } from 'jsx-ast-utils'; + import hasAccessibleChild from '../../../src/util/hasAccessibleChild'; import JSXElementMock from '../../../__mocks__/JSXElementMock'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; import JSXExpressionContainerMock from '../../../__mocks__/JSXExpressionContainerMock'; -describe('hasAccessibleChild', () => { - describe('has no children and does not set dangerouslySetInnerHTML', () => { - it('returns false', () => { - expect(hasAccessibleChild(JSXElementMock('div', []), elementType)).toBe(false); - }); - }); +test('hasAccessibleChild', (t) => { + t.equal( + hasAccessibleChild(JSXElementMock('div', []), elementType), + false, + 'has no children and does not set dangerouslySetInnerHTML -> false', + ); - describe('has no children and sets dangerouslySetInnerHTML', () => { - it('Returns true', () => { - const prop = JSXAttributeMock('dangerouslySetInnerHTML', true); - const element = JSXElementMock('div', [prop], []); - expect(hasAccessibleChild(element, elementType)).toBe(true); - }); - }); + t.equal( + hasAccessibleChild( + JSXElementMock('div', [JSXAttributeMock('dangerouslySetInnerHTML', true)], []), + elementType, + ), + true, + 'has no children and sets dangerouslySetInnerHTML -> true', + ); - describe('has children', () => { - it('Returns true for a Literal child', () => { - const child = { - type: 'Literal', - value: 'foo', - }; - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(true); - }); + t.equal( + hasAccessibleChild( + JSXElementMock( + 'div', + [], + [{ + type: 'Literal', + value: 'foo', + }], + ), + elementType, + ), + true, + 'has children + Literal child -> true', + ); - it('Returns true for visible child JSXElement', () => { - const child = JSXElementMock('div', []); - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(true); - }); + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [JSXElementMock('div', [])]), + elementType, + ), + true, + 'has children + visible JSXElement child -> true', + ); - it('Returns true for JSXText Element', () => { - const child = { + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [{ type: 'JSXText', value: 'foo', - }; - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(true); - }); + }]), + elementType, + ), + true, + 'has children + JSText element -> true', + ); - it('Returns false for hidden child JSXElement', () => { - const ariaHiddenAttr = JSXAttributeMock('aria-hidden', true); - const child = JSXElementMock('div', [ariaHiddenAttr]); - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(false); - }); + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [ + JSXElementMock('div', [ + JSXAttributeMock('aria-hidden', true), + ]), + ]), + elementType, + ), + false, + 'has children + hidden child JSXElement -> false', + ); - it('Returns true for defined JSXExpressionContainer', () => { - const expression = { - type: 'Identifier', - name: 'foo', - }; - const child = JSXExpressionContainerMock(expression); - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(true); - }); + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [ + JSXExpressionContainerMock({ + type: 'Identifier', + name: 'foo', + }), + ]), + elementType, + ), + true, + 'defined JSXExpressionContainer -> true', + ); - it('Returns false for undefined JSXExpressionContainer', () => { - const expression = { - type: 'Identifier', - name: 'undefined', - }; - const child = JSXExpressionContainerMock(expression); - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(false); - }); + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [ + JSXExpressionContainerMock({ + type: 'Identifier', + name: 'undefined', + }), + ]), + elementType, + ), + false, + 'has children + undefined JSXExpressionContainer -> false', + ); - it('Returns false for unknown child type', () => { - const child = { + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [{ type: 'Unknown', - }; - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(false); - }); + }]), + elementType, + ), + false, + 'unknown child type -> false', + ); + + t.equal( + hasAccessibleChild( + JSXElementMock('div', [JSXAttributeMock('children', true)], []), + elementType, + ), + true, + 'children passed as a prop -> true', + ); - it('Returns true with children passed as a prop', () => { - const children = JSXAttributeMock('children', true); - const element = JSXElementMock('div', [children], []); - expect(hasAccessibleChild(element, elementType)).toBe(true); - }); + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [ + JSXElementMock('input', [JSXAttributeMock('type', 'hidden')]), + ]), + elementType, + ), + false, + 'has chidren -> hidden child input JSXElement -> false', + ); - it('Returns false for hidden child input JSXElement', () => { - const child = JSXElementMock('input', [JSXAttributeMock('type', 'hidden')]); - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(false); - }); + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [ + JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]), + ]), + elementType, + ), + true, + 'has children + custom JSXElement of type hidden -> true', + ); - it('Returns true for a custom JSXElement even if type hidden', () => { - const child = JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]); - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, elementType)).toBe(true); - }); + t.equal( + hasAccessibleChild( + JSXElementMock('div', [], [ + JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]), + ]), + () => 'input', + ), + false, + 'custom JSXElement mapped to input if type is hidden -> false', + ); - it('Returns false for a custom JSXElement mapped to input if type is hidden', () => { - const child = JSXElementMock('CustomInput', [JSXAttributeMock('type', 'hidden')]); - const element = JSXElementMock('div', [], [child]); - expect(hasAccessibleChild(element, () => 'input')).toBe(false); - }); - }); + t.end(); }); diff --git a/__tests__/src/util/implicitRoles/input-test.js b/__tests__/src/util/implicitRoles/input-test.js index c5bc26009..a0c4277f6 100644 --- a/__tests__/src/util/implicitRoles/input-test.js +++ b/__tests__/src/util/implicitRoles/input-test.js @@ -1,34 +1,87 @@ -import expect from 'expect'; +import test from 'tape'; + import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock'; import getImplicitRoleForInput from '../../../../src/util/implicitRoles/input'; -describe('isAbstractRole', () => { - it('works for buttons', () => { - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'button')])).toBe('button'); - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'image')])).toBe('button'); - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'reset')])).toBe('button'); - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'submit')])).toBe('button'); - }); - it('works for checkboxes', () => { - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'checkbox')])).toBe('checkbox'); - }); - it('works for radios', () => { - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'radio')])).toBe('radio'); - }); - it('works for ranges', () => { - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'range')])).toBe('slider'); - }); - it('works for textboxes', () => { - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'email')])).toBe('textbox'); - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'password')])).toBe('textbox'); - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'search')])).toBe('textbox'); - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'tel')])).toBe('textbox'); - expect(getImplicitRoleForInput([JSXAttributeMock('type', 'url')])).toBe('textbox'); - }); - it('works for the default case', () => { - expect(getImplicitRoleForInput([JSXAttributeMock('type', '')])).toBe('textbox'); +test('isAbstractRole', (t) => { + t.test('works for buttons', (st) => { + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'button')]), + 'button', + ); + + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'image')]), + 'button', + ); + + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'reset')]), + 'button', + ); + + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'submit')]), + 'button', + ); + + st.end(); }); - it('works for the true case', () => { - expect(getImplicitRoleForInput([JSXAttributeMock('type', true)])).toBe('textbox'); + + t.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'checkbox')]), + 'checkbox', + 'works for checkboxes', + ); + + t.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'radio')]), + 'radio', + 'works for radios', + ); + + t.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'range')]), + 'slider', + 'works for ranges', + ); + + t.test('works for textboxes', (st) => { + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'email')]), + 'textbox', + ); + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'password')]), + 'textbox', + ); + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'search')]), + 'textbox', + ); + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'tel')]), + 'textbox', + ); + st.equal( + getImplicitRoleForInput([JSXAttributeMock('type', 'url')]), + 'textbox', + ); + + st.end(); }); + + t.equal( + getImplicitRoleForInput([JSXAttributeMock('type', '')]), + 'textbox', + 'works for the default case', + ); + + t.equal( + getImplicitRoleForInput([JSXAttributeMock('type', true)]), + 'textbox', + 'works for the true case', + ); + + t.end(); }); diff --git a/__tests__/src/util/implicitRoles/menu-test.js b/__tests__/src/util/implicitRoles/menu-test.js index e0bc6059a..773392e93 100644 --- a/__tests__/src/util/implicitRoles/menu-test.js +++ b/__tests__/src/util/implicitRoles/menu-test.js @@ -1,12 +1,20 @@ -import expect from 'expect'; +import test from 'tape'; + import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock'; import getImplicitRoleForMenu from '../../../../src/util/implicitRoles/menu'; -describe('isAbstractRole', () => { - it('works for toolbars', () => { - expect(getImplicitRoleForMenu([JSXAttributeMock('type', 'toolbar')])).toBe('toolbar'); - }); - it('works for non-toolbars', () => { - expect(getImplicitRoleForMenu([JSXAttributeMock('type', '')])).toBe(''); - }); +test('isAbstractRole', (t) => { + t.equal( + getImplicitRoleForMenu([JSXAttributeMock('type', 'toolbar')]), + 'toolbar', + 'works for toolbars', + ); + + t.equal( + getImplicitRoleForMenu([JSXAttributeMock('type', '')]), + '', + 'works for non-toolbars', + ); + + t.end(); }); diff --git a/__tests__/src/util/implicitRoles/menuitem-test.js b/__tests__/src/util/implicitRoles/menuitem-test.js index 835eca2ba..4a7ba84b8 100644 --- a/__tests__/src/util/implicitRoles/menuitem-test.js +++ b/__tests__/src/util/implicitRoles/menuitem-test.js @@ -1,21 +1,38 @@ -import expect from 'expect'; +import test from 'tape'; + import JSXAttributeMock from '../../../../__mocks__/JSXAttributeMock'; import getImplicitRoleForMenuitem from '../../../../src/util/implicitRoles/menuitem'; -describe('isAbstractRole', () => { - it('works for menu items', () => { - expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', 'command')])).toBe('menuitem'); - }); - it('works for menu item checkboxes', () => { - expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', 'checkbox')])).toBe('menuitemcheckbox'); - }); - it('works for menu item radios', () => { - expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', 'radio')])).toBe('menuitemradio'); - }); - it('works for non-toolbars', () => { - expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', '')])).toBe(''); - }); - it('works for the true case', () => { - expect(getImplicitRoleForMenuitem([JSXAttributeMock('type', true)])).toBe(''); - }); +test('isAbstractRole', (t) => { + t.equal( + getImplicitRoleForMenuitem([JSXAttributeMock('type', 'command')]), + 'menuitem', + 'works for menu items', + ); + + t.equal( + getImplicitRoleForMenuitem([JSXAttributeMock('type', 'checkbox')]), + 'menuitemcheckbox', + 'works for menu item checkboxes', + ); + + t.equal( + getImplicitRoleForMenuitem([JSXAttributeMock('type', 'radio')]), + 'menuitemradio', + 'works for menu item radios', + ); + + t.equal( + getImplicitRoleForMenuitem([JSXAttributeMock('type', '')]), + '', + 'works for non-toolbars', + ); + + t.equal( + getImplicitRoleForMenuitem([JSXAttributeMock('type', true)]), + '', + 'works for the true case', + ); + + t.end(); }); diff --git a/__tests__/src/util/isAbstractRole-test.js b/__tests__/src/util/isAbstractRole-test.js index bafc959d7..8fa204dba 100644 --- a/__tests__/src/util/isAbstractRole-test.js +++ b/__tests__/src/util/isAbstractRole-test.js @@ -1,5 +1,6 @@ -import expect from 'expect'; +import test from 'tape'; import { elementType } from 'jsx-ast-utils'; + import isAbstractRole from '../../../src/util/isAbstractRole'; import { genElementSymbol, @@ -7,33 +8,44 @@ import { genNonAbstractRoleElements, } from '../../../__mocks__/genInteractives'; -describe('isAbstractRole', () => { - describe('JSX Components (no tagName)', () => { - it('should NOT identify them as abstract role elements', () => { - expect(isAbstractRole(undefined, [])) - .toBe(false); - }); - }); - describe('elements with an abstract role', () => { +test('isAbstractRole', (t) => { + t.equal( + isAbstractRole(undefined, []), + false, + 'does NOT identify JSX Components (no tagName) as abstract role elements', + ); + + t.test('elements with an abstract role', (st) => { genAbstractRoleElements().forEach(({ openingElement }) => { const { attributes } = openingElement; - it(`should identify \`${genElementSymbol(openingElement)}\` as an abstract role element`, () => { - expect(isAbstractRole( + st.equal( + isAbstractRole( elementType(openingElement), attributes, - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` as an abstract role element`, + ); }); + + st.end(); }); - describe('elements with a non-abstract role', () => { + + t.test('elements with a non-abstract role', (st) => { genNonAbstractRoleElements().forEach(({ openingElement }) => { const { attributes } = openingElement; - it(`should NOT identify \`${genElementSymbol(openingElement)}\` as an abstract role element`, () => { - expect(isAbstractRole( + st.equal( + isAbstractRole( elementType(openingElement), attributes, - )).toBe(false); - }); + ), + false, + `does NOT identify \`${genElementSymbol(openingElement)}\` as an abstract role element`, + ); }); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/isContentEditable-test.js b/__tests__/src/util/isContentEditable-test.js index f738d5ed7..841e06f6a 100644 --- a/__tests__/src/util/isContentEditable-test.js +++ b/__tests__/src/util/isContentEditable-test.js @@ -1,51 +1,52 @@ -import expect from 'expect'; +import test from 'tape'; + import isContentEditable from '../../../src/util/isContentEditable'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; -describe('isContentEditable', () => { - describe('HTML5', () => { - describe('content editable', () => { - it('should identify HTML5 contentEditable elements', () => { - const attributes = [ - JSXAttributeMock('contentEditable', 'true'), - ]; - expect(isContentEditable('some tag', attributes)) - .toBe(true); - }); - }); - - describe('not content editable', () => { - it('should not identify HTML5 content editable elements with null as the value', () => { - const attributes = [ - JSXAttributeMock('contentEditable', null), - ]; - expect(isContentEditable('some tag', attributes)) - .toBe(false); - }); - - it('should not identify HTML5 content editable elements with undefined as the value', () => { - const attributes = [ - JSXAttributeMock('contentEditable', undefined), - ]; - expect(isContentEditable('some tag', attributes)) - .toBe(false); - }); - - it('should not identify HTML5 content editable elements with true as the value', () => { - const attributes = [ - JSXAttributeMock('contentEditable', true), - ]; - expect(isContentEditable('some tag', attributes)) - .toBe(false); - }); - - it('should not identify HTML5 content editable elements with "false" as the value', () => { - const attributes = [ - JSXAttributeMock('contentEditable', 'false'), - ]; - expect(isContentEditable('some tag', attributes)) - .toBe(false); - }); - }); +test('isContentEditable - HTML5', (t) => { + t.equal( + isContentEditable('some tag', [ + JSXAttributeMock('contentEditable', 'true'), + ]), + true, + 'identifies HTML5 contentEditable elements', + ); + + t.test('not content editable', (st) => { + st.equal( + isContentEditable('some tag', [ + JSXAttributeMock('contentEditable', null), + ]), + false, + 'does not identify HTML5 content editable elements with null as the value', + ); + + st.equal( + isContentEditable('some tag', [ + JSXAttributeMock('contentEditable', undefined), + ]), + false, + 'does not identify HTML5 content editable elements with undefined as the value', + ); + + st.equal( + isContentEditable('some tag', [ + JSXAttributeMock('contentEditable', true), + ]), + false, + 'does not identify HTML5 content editable elements with true as the value', + ); + + st.equal( + isContentEditable('some tag', [ + JSXAttributeMock('contentEditable', 'false'), + ]), + false, + 'does not identify HTML5 content editable elements with "false" as the value', + ); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/isDOMElement-test.js b/__tests__/src/util/isDOMElement-test.js index ff1e24e49..b0c587881 100644 --- a/__tests__/src/util/isDOMElement-test.js +++ b/__tests__/src/util/isDOMElement-test.js @@ -1,24 +1,30 @@ -import expect from 'expect'; +import test from 'tape'; import { dom } from 'aria-query'; import { elementType } from 'jsx-ast-utils'; + import isDOMElement from '../../../src/util/isDOMElement'; import JSXElementMock from '../../../__mocks__/JSXElementMock'; -describe('isDOMElement', () => { - describe('DOM elements', () => { +test('isDOMElement', (t) => { + t.test('DOM elements', (st) => { dom.forEach((_, el) => { - it(`should identify ${el} as a DOM element`, () => { - const element = JSXElementMock(el); - expect(isDOMElement(elementType(element.openingElement))) - .toBe(true); - }); - }); - }); - describe('Custom Element', () => { - it('should not identify a custom element', () => { - const element = JSXElementMock('CustomElement'); - expect(isDOMElement(element)) - .toBe(false); + const element = JSXElementMock(el); + + st.equal( + isDOMElement(elementType(element.openingElement)), + true, + `identifies ${el} as a DOM element`, + ); }); + + st.end(); }); + + t.equal( + isDOMElement(JSXElementMock('CustomElement')), + false, + 'does not identify a custom element', + ); + + t.end(); }); diff --git a/__tests__/src/util/isDisabledElement-test.js b/__tests__/src/util/isDisabledElement-test.js index b225d7838..795bfbf4f 100644 --- a/__tests__/src/util/isDisabledElement-test.js +++ b/__tests__/src/util/isDisabledElement-test.js @@ -1,81 +1,88 @@ -import expect from 'expect'; +import test from 'tape'; + import isDisabledElement from '../../../src/util/isDisabledElement'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; -describe('isDisabledElement', () => { - describe('HTML5', () => { - describe('disabled', () => { - it('should identify HTML5 disabled elements', () => { - const attributes = [ - JSXAttributeMock('disabled', 'disabled'), - ]; - expect(isDisabledElement(attributes)) - .toBe(true); - }); - }); - describe('not disabled', () => { - it('should identify HTML5 disabled elements with null as the value', () => { - const attributes = [ - JSXAttributeMock('disabled', null), - ]; - expect(isDisabledElement(attributes)) - .toBe(true); - }); - it('should not identify HTML5 disabled elements with undefined as the value', () => { - const attributes = [ - JSXAttributeMock('disabled', undefined), - ]; - expect(isDisabledElement(attributes)) - .toBe(false); - }); - }); +test('isDisabledElement', (t) => { + t.test('HTML5', (st) => { + st.equal( + isDisabledElement([ + JSXAttributeMock('disabled', 'disabled'), + ]), + true, + 'identifies HTML5 disabled elements', + ); + + st.equal( + isDisabledElement([ + JSXAttributeMock('disabled', null), + ]), + true, + 'identifies HTML5 disabled elements with null as the value', + ); + + st.equal( + isDisabledElement([ + JSXAttributeMock('disabled', undefined), + ]), + false, + 'does not identify HTML5 disabled elements with undefined as the value', + ); + + st.end(); }); - describe('ARIA', () => { - describe('disabled', () => { - it('should not identify ARIA disabled elements', () => { - const attributes = [ - JSXAttributeMock('aria-disabled', 'true'), - ]; - expect(isDisabledElement(attributes)) - .toBe(true); - }); - it('should not identify ARIA disabled elements', () => { - const attributes = [ - JSXAttributeMock('aria-disabled', true), - ]; - expect(isDisabledElement(attributes)) - .toBe(true); - }); - }); - describe('not disabled', () => { - it('should not identify ARIA disabled elements', () => { - const attributes = [ - JSXAttributeMock('aria-disabled', 'false'), - ]; - expect(isDisabledElement(attributes)) - .toBe(false); - }); - it('should not identify ARIA disabled elements', () => { - const attributes = [ - JSXAttributeMock('aria-disabled', false), - ]; - expect(isDisabledElement(attributes)) - .toBe(false); - }); - it('should not identify ARIA disabled elements with null as the value', () => { - const attributes = [ - JSXAttributeMock('aria-disabled', null), - ]; - expect(isDisabledElement(attributes)) - .toBe(false); - }); - it('should not identify ARIA disabled elements with undefined as the value', () => { - const attributes = [ - JSXAttributeMock('aria-disabled', undefined), - ]; - expect(isDisabledElement(attributes)) - .toBe(false); - }); - }); + + t.test('ARIA', (st) => { + st.equal( + isDisabledElement([ + JSXAttributeMock('aria-disabled', 'true'), + ]), + true, + 'does not identify ARIA disabled elements', + ); + + st.equal( + isDisabledElement([ + JSXAttributeMock('aria-disabled', true), + ]), + true, + 'does not identify ARIA disabled elements', + ); + + st.equal( + isDisabledElement([ + JSXAttributeMock('aria-disabled', 'false'), + ]), + false, + 'does not identify ARIA disabled elements', + ); + + st.equal( + isDisabledElement([ + JSXAttributeMock('aria-disabled', false), + ]), + false, + 'does not identify ARIA disabled elements', + ); + + st.equal( + isDisabledElement([ + JSXAttributeMock('aria-disabled', null), + ]), + false, + 'does not identify ARIA disabled elements with null as the value', + ); + + st.equal( + isDisabledElement([ + JSXAttributeMock('aria-disabled', undefined), + ]), + false, + 'does not identify ARIA disabled elements with undefined as the value', + ); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/isFocusable-test.js b/__tests__/src/util/isFocusable-test.js index 76819c297..30da75fd6 100644 --- a/__tests__/src/util/isFocusable-test.js +++ b/__tests__/src/util/isFocusable-test.js @@ -1,5 +1,6 @@ -import expect from 'expect'; +import test from 'tape'; import { elementType } from 'jsx-ast-utils'; + import isFocusable from '../../../src/util/isFocusable'; import { genElementSymbol, @@ -12,75 +13,99 @@ function mergeTabIndex(index, attributes) { return [].concat(attributes, JSXAttributeMock('tabIndex', index)); } -describe('isFocusable', () => { - describe('interactive elements', () => { +test('isFocusable', (t) => { + t.test('interactive elements', (st) => { genInteractiveElements().forEach(({ openingElement }) => { - it(`should identify \`${genElementSymbol(openingElement)}\` as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), openingElement.attributes, - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` as a focusable element`, + ); - it(`should not identify \`${genElementSymbol(openingElement)}\` with tabIndex of -1 as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), mergeTabIndex(-1, openingElement.attributes), - )).toBe(false); - }); + ), + false, + `does NOT identify \`${genElementSymbol(openingElement)}\` with tabIndex of -1 as a focusable element`, + ); - it(`should identify \`${genElementSymbol(openingElement)}\` with tabIndex of 0 as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), mergeTabIndex(0, openingElement.attributes), - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` with tabIndex of 0 as a focusable element`, + ); - it(`should identify \`${genElementSymbol(openingElement)}\` with tabIndex of 1 as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), mergeTabIndex(1, openingElement.attributes), - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` with tabIndex of 1 as a focusable element`, + ); }); + + st.end(); }); - describe('non-interactive elements', () => { + t.test('non-interactive elements', (st) => { genNonInteractiveElements().forEach(({ openingElement }) => { - it(`should not identify \`${genElementSymbol(openingElement)}\` as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); + ), + false, + `does NOT identify \`${genElementSymbol(openingElement)}\` as a focusable element`, + ); - it(`should not identify \`${genElementSymbol(openingElement)}\` with tabIndex of -1 as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), mergeTabIndex(-1, openingElement.attributes), - )).toBe(false); - }); + ), + false, + `does NOT identify \`${genElementSymbol(openingElement)}\` with tabIndex of -1 as a focusable element`, + ); - it(`should identify \`${genElementSymbol(openingElement)}\` with tabIndex of 0 as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), mergeTabIndex(0, openingElement.attributes), - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` with tabIndex of 0 as a focusable element`, + ); - it(`should identify \`${genElementSymbol(openingElement)}\` with tabIndex of 1 as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), mergeTabIndex(1, openingElement.attributes), - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` with tabIndex of 1 as a focusable element`, + ); - it(`should not identify \`${genElementSymbol(openingElement)}\` with tabIndex of 'bogus' as a focusable element`, () => { - expect(isFocusable( + st.equal( + isFocusable( elementType(openingElement), mergeTabIndex('bogus', openingElement.attributes), - )).toBe(false); - }); + ), + false, + `does NOT identify \`${genElementSymbol(openingElement)}\` with tabIndex of 'bogus' as a focusable element`, + ); }); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/isInteractiveElement-test.js b/__tests__/src/util/isInteractiveElement-test.js index 8fa28e8f2..fecab59b9 100644 --- a/__tests__/src/util/isInteractiveElement-test.js +++ b/__tests__/src/util/isInteractiveElement-test.js @@ -1,5 +1,6 @@ -import expect from 'expect'; +import test from 'tape'; import { elementType } from 'jsx-ast-utils'; + import isInteractiveElement from '../../../src/util/isInteractiveElement'; import JSXElementMock from '../../../__mocks__/JSXElementMock'; import { @@ -11,66 +12,93 @@ import { genNonInteractiveRoleElements, } from '../../../__mocks__/genInteractives'; -describe('isInteractiveElement', () => { - describe('JSX Components (no tagName)', () => { - it('should identify them as interactive elements', () => { - expect(isInteractiveElement(undefined, [])) - .toBe(false); - }); - }); - describe('interactive elements', () => { +test('isInteractiveElement', (t) => { + t.equal( + isInteractiveElement(undefined, []), + false, + 'identifies them as interactive elements', + ); + + t.test('interactive elements', (st) => { genInteractiveElements().forEach(({ openingElement }) => { - it(`should identify \`${genElementSymbol(openingElement)}\` as an interactive element`, () => { - expect(isInteractiveElement( + st.equal( + isInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` as an interactive element`, + ); }); + + st.end(); }); - describe('interactive role elements', () => { + + t.test('interactive role elements', (st) => { genInteractiveRoleElements().forEach(({ openingElement }) => { - it(`should NOT identify \`${genElementSymbol(openingElement)}\` as an interactive element`, () => { - expect(isInteractiveElement( + st.equal( + isInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); + ), + false, + `identifies \`${genElementSymbol(openingElement)}\` as an interactive element`, + ); }); + + st.end(); }); - describe('non-interactive elements', () => { + + t.test('non-interactive elements', (st) => { genNonInteractiveElements().forEach(({ openingElement }) => { - it(`should NOT identify \`${genElementSymbol(openingElement)}\` as an interactive element`, () => { - expect(isInteractiveElement( + st.equal( + isInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); + ), + false, + `identifies \`${genElementSymbol(openingElement)}\` as an interactive element`, + ); }); + + st.end(); }); - describe('non-interactive role elements', () => { + + t.test('non-interactive role elements', (st) => { genNonInteractiveRoleElements().forEach(({ openingElement }) => { - it(`should NOT identify \`${genElementSymbol(openingElement)}\` as an interactive element`, () => { - expect(isInteractiveElement( + st.equal( + isInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); + ), + false, + `identifies \`${genElementSymbol(openingElement)}\` as an interactive element`, + ); }); + + st.end(); }); - describe('indeterminate elements', () => { + + t.test('indeterminate elements', (st) => { genIndeterminantInteractiveElements().forEach(({ openingElement }) => { - it(`should NOT identify \`${openingElement.name.name}\` as an interactive element`, () => { - expect(isInteractiveElement( + st.equal( + isInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); - }); - }); - describe('JSX elements', () => { - it('is not interactive', () => { - expect(isInteractiveElement('CustomComponent', JSXElementMock())).toBe(false); + ), + false, + `identifies \`${genElementSymbol(openingElement)}\` as an interactive element`, + ); }); + + st.end(); }); + + t.equal( + isInteractiveElement('CustomComponent', JSXElementMock()), + false, + 'JSX elements are not interactive', + ); + + t.end(); }); diff --git a/__tests__/src/util/isInteractiveRole-test.js b/__tests__/src/util/isInteractiveRole-test.js index e7cd0559d..667bf8b6b 100644 --- a/__tests__/src/util/isInteractiveRole-test.js +++ b/__tests__/src/util/isInteractiveRole-test.js @@ -1,5 +1,6 @@ -import expect from 'expect'; +import test from 'tape'; import { elementType } from 'jsx-ast-utils'; + import isInteractiveRole from '../../../src/util/isInteractiveRole'; import { genElementSymbol, @@ -7,38 +8,52 @@ import { genNonInteractiveRoleElements, } from '../../../__mocks__/genInteractives'; -describe('isInteractiveRole', () => { - describe('JSX Components (no tagName)', () => { - it('should identify them as interactive role elements', () => { - expect(isInteractiveRole(undefined, [])) - .toBe(false); - }); - }); - describe('elements with a non-interactive role', () => { +test('isInteractiveRole', (t) => { + t.equal( + isInteractiveRole(undefined, []), + false, + 'identifies JSX Components (no tagName) as interactive role elements', + ); + + t.test('elements with a non-interactive role', (st) => { genNonInteractiveRoleElements().forEach(({ openingElement }) => { const { attributes } = openingElement; - it(`should not identify \`${genElementSymbol(openingElement)}\` as an interactive role element`, () => { - expect(isInteractiveRole( + + st.equal( + isInteractiveRole( elementType(openingElement), attributes, - )).toBe(false); - }); - }); - }); - describe('elements without a role', () => { - it('should not identify them as interactive role elements', () => { - expect(isInteractiveRole('div', [])).toBe(false); + ), + false, + `does NOT identify \`${genElementSymbol(openingElement)}\` as an interactive role element`, + ); }); + + st.end(); }); - describe('elements with an interactive role', () => { + + t.equal( + isInteractiveRole('div', []), + false, + 'does NOT identify elements without a role as interactive role elements', + ); + + t.test('elements with an interactive role', (st) => { genInteractiveRoleElements().forEach(({ openingElement }) => { const { attributes } = openingElement; - it(`should identify \`${genElementSymbol(openingElement)}\` as an interactive role element`, () => { - expect(isInteractiveRole( + + st.equal( + isInteractiveRole( elementType(openingElement), attributes, - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` as an interactive role element`, + ); }); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/isNonInteractiveElement-test.js b/__tests__/src/util/isNonInteractiveElement-test.js index f9e2bd5aa..cb5b3ff7e 100644 --- a/__tests__/src/util/isNonInteractiveElement-test.js +++ b/__tests__/src/util/isNonInteractiveElement-test.js @@ -1,5 +1,6 @@ -import expect from 'expect'; +import test from 'tape'; import { elementType } from 'jsx-ast-utils'; + import isNonInteractiveElement from '../../../src/util/isNonInteractiveElement'; import { genElementSymbol, @@ -10,61 +11,87 @@ import { genNonInteractiveRoleElements, } from '../../../__mocks__/genInteractives'; -describe('isNonInteractiveElement', () => { - describe('JSX Components (no tagName)', () => { - it('should identify them as interactive elements', () => { - expect(isNonInteractiveElement(undefined, [])) - .toBe(false); - }); - }); - describe('non-interactive elements', () => { +test('isNonInteractiveElement', (t) => { + t.equal( + isNonInteractiveElement(undefined, []), + false, + 'identifies JSX Components (no tagName) as non-interactive elements', + ); + + t.test('non-interactive elements', (st) => { genNonInteractiveElements().forEach(({ openingElement }) => { - it(`should identify \`${genElementSymbol(openingElement)}\` as a non-interactive element`, () => { - expect(isNonInteractiveElement( + st.equal( + isNonInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(true); - }); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`, + ); }); + + st.end(); }); - describe('non-interactive role elements', () => { + + t.test('non-interactive role elements', (st) => { genNonInteractiveRoleElements().forEach(({ openingElement }) => { - it(`should NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive element`, () => { - expect(isNonInteractiveElement( + st.equal( + isNonInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); + ), + false, + `identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`, + ); }); + + st.end(); }); - describe('interactive elements', () => { + + t.test('interactive elements', (st) => { genInteractiveElements().forEach(({ openingElement }) => { - it(`should NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive element`, () => { - expect(isNonInteractiveElement( + st.equal( + isNonInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); + ), + false, + `identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`, + ); }); + + st.end(); }); - describe('interactive role elements', () => { + + t.test('interactive role elements', (st) => { genInteractiveRoleElements().forEach(({ openingElement }) => { - it(`should NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive element`, () => { - expect(isNonInteractiveElement( + st.equal( + isNonInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); + ), + false, + `identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`, + ); }); + + st.end(); }); - describe('indeterminate elements', () => { + + t.test('indeterminate elements', (st) => { genIndeterminantInteractiveElements().forEach(({ openingElement }) => { - it(`should NOT identify \`${openingElement.name.name}\` as a non-interactive element`, () => { - expect(isNonInteractiveElement( + st.equal( + isNonInteractiveElement( elementType(openingElement), openingElement.attributes, - )).toBe(false); - }); + ), + false, + `identifies \`${genElementSymbol(openingElement)}\` as a non-interactive element`, + ); }); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/isNonInteractiveRole-test.js b/__tests__/src/util/isNonInteractiveRole-test.js index 93f9068c1..258c64cd7 100644 --- a/__tests__/src/util/isNonInteractiveRole-test.js +++ b/__tests__/src/util/isNonInteractiveRole-test.js @@ -1,5 +1,6 @@ -import expect from 'expect'; +import test from 'tape'; import { elementType } from 'jsx-ast-utils'; + import isNonInteractiveRole from '../../../src/util/isNonInteractiveRole'; import { genElementSymbol, @@ -7,38 +8,52 @@ import { genNonInteractiveRoleElements, } from '../../../__mocks__/genInteractives'; -describe('isNonInteractiveRole', () => { - describe('JSX Components (no tagName)', () => { - it('should identify them as interactive role elements', () => { - expect(isNonInteractiveRole(undefined, [])) - .toBe(false); - }); - }); - describe('elements with a non-interactive role', () => { +test('isNonInteractiveRole', (t) => { + t.equal( + isNonInteractiveRole(undefined, []), + false, + 'identifies JSX Components (no tagName) as non-interactive elements', + ); + + t.test('elements with a non-interactive role', (st) => { genNonInteractiveRoleElements().forEach(({ openingElement }) => { const { attributes } = openingElement; - it(`should identify \`${genElementSymbol(openingElement)}\` as non-interactive role element`, () => { - expect(isNonInteractiveRole( + + st.equal( + isNonInteractiveRole( elementType(openingElement), attributes, - )).toBe(true); - }); - }); - }); - describe('elements without a role', () => { - it('should not identify them as non-interactive role elements', () => { - expect(isNonInteractiveRole('div', [])).toBe(false); + ), + true, + `identifies \`${genElementSymbol(openingElement)}\` as a non-interactive role element`, + ); }); + + st.end(); }); - describe('elements with an interactive role', () => { + + t.equal( + isNonInteractiveRole('div', []), + false, + 'does NOT identify elements without a role as non-interactive role elements', + ); + + t.test('elements with an interactive role', (st) => { genInteractiveRoleElements().forEach(({ openingElement }) => { const { attributes } = openingElement; - it(`should NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive role element`, () => { - expect(isNonInteractiveRole( + + st.equal( + isNonInteractiveRole( elementType(openingElement), attributes, - )).toBe(false); - }); + ), + false, + `does NOT identify \`${genElementSymbol(openingElement)}\` as a non-interactive role element`, + ); }); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/isNonLiteralProperty-test.js b/__tests__/src/util/isNonLiteralProperty-test.js index 8ee0921c5..f160a432b 100644 --- a/__tests__/src/util/isNonLiteralProperty-test.js +++ b/__tests__/src/util/isNonLiteralProperty-test.js @@ -1,4 +1,5 @@ -import expect from 'expect'; +import test from 'tape'; + import isNonLiteralProperty from '../../../src/util/isNonLiteralProperty'; import IdentifierMock from '../../../__mocks__/IdentifierMock'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; @@ -10,35 +11,42 @@ const theProp = 'theProp'; const spread = JSXSpreadAttributeMock('theSpread'); -describe('isNonLiteralProperty', () => { - describe('elements without the property', () => { - it('should not identify them as non-literal role elements', () => { - expect(isNonLiteralProperty([], theProp)).toBe(false); - }); - }); - describe('elements with a literal property', () => { - it('should not identify them as non-literal role elements without spread operator', () => { - expect(isNonLiteralProperty([JSXAttributeMock(theProp, LiteralMock('theRole'))], theProp)).toBe(false); - }); - it('should not identify them as non-literal role elements with spread operator', () => { - expect(isNonLiteralProperty([spread, JSXAttributeMock(theProp, LiteralMock('theRole'))], theProp)).toBe(false); - }); - }); - describe('elements with a JSXText property', () => { - it('should not identify them as non-literal role elements', () => { - expect(isNonLiteralProperty([JSXAttributeMock(theProp, JSXTextMock('theRole'))], theProp)).toBe(false); - }); - }); - describe('elements with a property of undefined', () => { - it('should not identify them as non-literal role elements', () => { - const undefinedExpression = IdentifierMock('undefined'); - expect(isNonLiteralProperty([JSXAttributeMock(theProp, undefinedExpression)], theProp)).toBe(false); - }); - }); - describe('elements with a expression property', () => { - it('should identify them as non-literal role elements', () => { - const identifierExpression = IdentifierMock('theIdentifier'); - expect(isNonLiteralProperty([JSXAttributeMock(theProp, identifierExpression)], theProp)).toBe(true); - }); - }); +test('isNonLiteralProperty', (t) => { + t.equal( + isNonLiteralProperty([], theProp), + false, + 'does not identify them as non-literal role elements', + ); + + t.equal( + isNonLiteralProperty([JSXAttributeMock(theProp, LiteralMock('theRole'))], theProp), + false, + 'does not identify elements with a literal property as non-literal role elements without spread operator', + ); + + t.equal( + isNonLiteralProperty([spread, JSXAttributeMock(theProp, LiteralMock('theRole'))], theProp), + false, + 'does not identify elements with a literal property as non-literal role elements with spread operator', + ); + + t.equal( + isNonLiteralProperty([JSXAttributeMock(theProp, JSXTextMock('theRole'))], theProp), + false, + 'identifies elements with a JSXText property as non-literal role elements', + ); + + t.equal( + isNonLiteralProperty([JSXAttributeMock(theProp, IdentifierMock('undefined'))], theProp), + false, + 'does not identify elements with a property of undefined as non-literal role elements', + ); + + t.equal( + isNonLiteralProperty([JSXAttributeMock(theProp, IdentifierMock('theIdentifier'))], theProp), + true, + 'identifies elements with an expression property as non-literal role elements', + ); + + t.end(); }); diff --git a/__tests__/src/util/isSemanticRoleElement-test.js b/__tests__/src/util/isSemanticRoleElement-test.js index 9f2dfdfa8..f57c2239e 100644 --- a/__tests__/src/util/isSemanticRoleElement-test.js +++ b/__tests__/src/util/isSemanticRoleElement-test.js @@ -1,33 +1,55 @@ -import expect from 'expect'; +import test from 'tape'; + import isSemanticRoleElement from '../../../src/util/isSemanticRoleElement'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; -describe('isSemanticRoleElement', () => { - it('should identify semantic role elements', () => { - expect(isSemanticRoleElement('input', [ +test('isSemanticRoleElement', (t) => { + t.equal( + isSemanticRoleElement('input', [ JSXAttributeMock('type', 'checkbox'), JSXAttributeMock('role', 'switch'), - ])).toBe(true); - }); - it('should reject non-semantic role elements', () => { - expect(isSemanticRoleElement('input', [ - JSXAttributeMock('type', 'radio'), - JSXAttributeMock('role', 'switch'), - ])).toBe(false); - expect(isSemanticRoleElement('input', [ - JSXAttributeMock('type', 'text'), - JSXAttributeMock('role', 'combobox'), - ])).toBe(false); - expect(isSemanticRoleElement('button', [ - JSXAttributeMock('role', 'switch'), - JSXAttributeMock('aria-pressed', 'true'), - ])).toBe(false); - expect(isSemanticRoleElement('input', [ - JSXAttributeMock('role', 'switch'), - ])).toBe(false); + ]), + true, + 'identifies semantic role elements', + ); + + t.test('rejects non-semantics role elements', (st) => { + st.equal( + isSemanticRoleElement('input', [ + JSXAttributeMock('type', 'radio'), + JSXAttributeMock('role', 'switch'), + ]), + false, + ); + + st.equal( + isSemanticRoleElement('input', [ + JSXAttributeMock('type', 'text'), + JSXAttributeMock('role', 'combobox'), + ]), + false, + ); + + st.equal( + isSemanticRoleElement('button', [ + JSXAttributeMock('role', 'switch'), + JSXAttributeMock('aria-pressed', 'true'), + ]), + false, + ); + + st.equal( + isSemanticRoleElement('input', [ + JSXAttributeMock('role', 'switch'), + ]), + false, + ); + + st.end(); }); - it('should not throw on JSXSpreadAttribute', () => { - expect(() => { + + t.doesNotThrow( + () => { isSemanticRoleElement('input', [ JSXAttributeMock('type', 'checkbox'), JSXAttributeMock('role', 'checkbox'), @@ -42,6 +64,9 @@ describe('isSemanticRoleElement', () => { }, }, ]); - }).not.toThrow(); - }); + }, + 'does not throw on JSXSpreadAttribute', + ); + + t.end(); }); diff --git a/__tests__/src/util/mayContainChildComponent-test.js b/__tests__/src/util/mayContainChildComponent-test.js index 0bea7c8ad..e671de3a9 100644 --- a/__tests__/src/util/mayContainChildComponent-test.js +++ b/__tests__/src/util/mayContainChildComponent-test.js @@ -1,62 +1,73 @@ -import expect from 'expect'; +import test from 'tape'; + import mayContainChildComponent from '../../../src/util/mayContainChildComponent'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; import JSXElementMock from '../../../__mocks__/JSXElementMock'; import JSXExpressionContainerMock from '../../../__mocks__/JSXExpressionContainerMock'; -describe('mayContainChildComponent', () => { - describe('no FancyComponent', () => { - it('should return false', () => { - expect(mayContainChildComponent( +test('mayContainChildComponent', (t) => { + t.equal( + mayContainChildComponent( + JSXElementMock('div', [], [ JSXElementMock('div', [], [ - JSXElementMock('div', [], [ + JSXElementMock('span', [], []), + JSXElementMock('span', [], [ JSXElementMock('span', [], []), JSXElementMock('span', [], [ JSXElementMock('span', [], []), - JSXElementMock('span', [], [ - JSXElementMock('span', [], []), - ]), ]), ]), - JSXElementMock('span', [], []), - JSXElementMock('img', [ - JSXAttributeMock('src', 'some/path'), - ]), ]), - 'FancyComponent', - 5, - )).toBe(false); - }); - }); - describe('contains an indicated component', () => { - it('should return true', () => { - expect(mayContainChildComponent( + JSXElementMock('span', [], []), + JSXElementMock('img', [ + JSXAttributeMock('src', 'some/path'), + ]), + ]), + 'FancyComponent', + 5, + ), + false, + 'no FancyComponent returns false', + ); + + t.test('contains an indicated component', (st) => { + st.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('input'), ]), 'input', - )).toBe(true); - }); - it('should return true', () => { - expect(mayContainChildComponent( + ), + true, + 'returns true', + ); + + st.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('FancyComponent'), ]), 'FancyComponent', - )).toBe(true); - }); - it('FancyComponent is outside of default depth, should return false', () => { - expect(mayContainChildComponent( + ), + true, + 'returns true', + ); + + st.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('div', [], [ JSXElementMock('FancyComponent'), ]), ]), 'FancyComponent', - )).toBe(false); - }); - it('FancyComponent is inside of custom depth, should return true', () => { - expect(mayContainChildComponent( + ), + false, + 'FancyComponent is outside of default depth, should return false', + ); + + st.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('div', [], [ JSXElementMock('FancyComponent'), @@ -64,10 +75,13 @@ describe('mayContainChildComponent', () => { ]), 'FancyComponent', 2, - )).toBe(true); - }); - it('deep nesting, should return true', () => { - expect(mayContainChildComponent( + ), + true, + 'FancyComponent is inside of custom depth, should return true', + ); + + st.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('div', [], [ JSXElementMock('span', [], []), @@ -89,90 +103,117 @@ describe('mayContainChildComponent', () => { ]), 'FancyComponent', 6, - )).toBe(true); - }); - }); - describe('Intederminate situations', () => { - describe('expression container children', () => { - it('should return true', () => { - expect(mayContainChildComponent( - JSXElementMock('div', [], [ - JSXExpressionContainerMock('mysteryBox'), - ]), - 'FancyComponent', - )).toBe(true); - }); - }); + ), + true, + 'deep nesting, returns true', + ); + + st.end(); }); - describe('Glob name matching', () => { - describe('component name contains question mark ? - match any single character', () => { - it('should return true', () => { - expect(mayContainChildComponent( - JSXElementMock('div', [], [ - JSXElementMock('FancyComponent'), - ]), - 'Fanc?Co??onent', - )).toBe(true); - }); - it('should return false', () => { - expect(mayContainChildComponent( - JSXElementMock('div', [], [ - JSXElementMock('FancyComponent'), - ]), - 'FancyComponent?', - )).toBe(false); - }); - }); + t.equal( + mayContainChildComponent( + JSXElementMock('div', [], [ + JSXExpressionContainerMock('mysteryBox'), + ]), + 'FancyComponent', + ), + true, + 'Intederminate situations + expression container children - returns true', + ); + + t.test('Glob name matching - component name contains question mark ? - match any single character', (st) => { + st.equal( + mayContainChildComponent( + JSXElementMock('div', [], [ + JSXElementMock('FancyComponent'), + ]), + 'Fanc?Co??onent', + ), + true, + 'returns true', + ); - describe('component name contains asterisk * - match zero or more characters', () => { - it('should return true', () => { - expect(mayContainChildComponent( + st.equal( + mayContainChildComponent( + JSXElementMock('div', [], [ + JSXElementMock('FancyComponent'), + ]), + 'FancyComponent?', + ), + false, + 'returns false', + ); + + st.test('component name contains asterisk * - match zero or more characters', (s2t) => { + s2t.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('FancyComponent'), ]), 'Fancy*', - )).toBe(true); - }); - it('should return true', () => { - expect(mayContainChildComponent( + ), + true, + 'returns true', + ); + + s2t.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('FancyComponent'), ]), '*Component', - )).toBe(true); - }); - it('should return true', () => { - expect(mayContainChildComponent( + ), + true, + 'returns true', + ); + + s2t.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('FancyComponent'), ]), 'Fancy*C*t', - )).toBe(true); - }); + ), + true, + 'returns true', + ); + + s2t.end(); }); + + st.end(); }); - describe('using a custom elementType function', () => { - it('should return true when the custom elementType returns the proper name', () => { - expect(mayContainChildComponent( + t.test('using a custom elementType function', (st) => { + st.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('CustomInput'), ]), 'input', 2, () => 'input', - )).toBe(true); - }); - it('should return false when the custom elementType returns a wrong name', () => { - expect(mayContainChildComponent( + ), + true, + 'returns true when the custom elementType returns the proper name', + ); + + st.equal( + mayContainChildComponent( JSXElementMock('div', [], [ JSXElementMock('CustomInput'), ]), 'input', 2, () => 'button', - )).toBe(false); - }); + ), + false, + 'returns false when the custom elementType returns a wrong name', + ); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/mayHaveAccessibleLabel-test.js b/__tests__/src/util/mayHaveAccessibleLabel-test.js index ee85669f7..f1c0026e8 100644 --- a/__tests__/src/util/mayHaveAccessibleLabel-test.js +++ b/__tests__/src/util/mayHaveAccessibleLabel-test.js @@ -1,4 +1,5 @@ -import expect from 'expect'; +import test from 'tape'; + import mayHaveAccessibleLabel from '../../../src/util/mayHaveAccessibleLabel'; import JSXAttributeMock from '../../../__mocks__/JSXAttributeMock'; import JSXElementMock from '../../../__mocks__/JSXElementMock'; @@ -7,117 +8,165 @@ import JSXSpreadAttributeMock from '../../../__mocks__/JSXSpreadAttributeMock'; import JSXTextMock from '../../../__mocks__/JSXTextMock'; import LiteralMock from '../../../__mocks__/LiteralMock'; -describe('mayHaveAccessibleLabel', () => { - describe('no label', () => { - it('should return false', () => { - expect(mayHaveAccessibleLabel( +test('mayHaveAccessibleLabel', (t) => { + t.equal( + mayHaveAccessibleLabel( + JSXElementMock('div', [], [ JSXElementMock('div', [], [ - JSXElementMock('div', [], [ + JSXElementMock('span', [], []), + JSXElementMock('span', [], [ JSXElementMock('span', [], []), JSXElementMock('span', [], [ JSXElementMock('span', [], []), - JSXElementMock('span', [], [ - JSXElementMock('span', [], []), - ]), ]), ]), - JSXElementMock('span', [], []), - JSXElementMock('img', [ - JSXAttributeMock('src', 'some/path'), - ]), ]), - 5, - )).toBe(false); - }); - }); - describe('label via attributes', () => { - it('aria-label, should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + JSXElementMock('span', [], []), + JSXElementMock('img', [ + JSXAttributeMock('src', 'some/path'), + ]), + ]), + 5, + ), + false, + 'no label returns false', + ); + + t.test('label via attributes', (st) => { + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [ JSXAttributeMock('aria-label', 'A delicate label'), - ], []))).toBe(true); - }); - it('aria-label without content, should return false', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + ], [])), + true, + 'aria-label returns true', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [ JSXAttributeMock('aria-label', ''), - ], []))).toBe(false); - }); - it('aria-label with only whitespace, should return false', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + ], [])), + false, + 'aria-label without content returns false', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [ JSXAttributeMock('aria-label', ' '), - ], []))).toBe(false); - expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + ], [])), + false, + 'aria-label with only spaces whitespace, should return false', + ); + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [ JSXAttributeMock('aria-label', '\n'), - ], []))).toBe(false); - }); - it('aria-labelledby, should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + ], [])), + false, + 'aria-label with only newline whitespace, should return false', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [ JSXAttributeMock('aria-labelledby', 'elementId'), - ], []))).toBe(true); - }); - it('aria-labelledby without content, should return false', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + ], [])), + true, + 'aria-labelledby returns true', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [ JSXAttributeMock('aria-labelledby', ''), - ], []))).toBe(false); - }); - it('aria-labelledby with an expression container, should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + ], [])), + false, + 'aria-labelledby without content returns false', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [ JSXAttributeMock('aria-labelledby', 'elementId', true), - ], []))).toBe(true); - }); + ], [])), + true, + 'aria-labelledby with an expression container, should return true', + ); + + st.end(); }); - describe('label via custom label attribute', () => { - let customLabelProp; - beforeEach(() => { - customLabelProp = 'cowbell'; - }); - it('aria-label, should return true', () => { - expect(mayHaveAccessibleLabel( + + t.test('label via custom label attribute', (st) => { + const customLabelProp = 'cowbell'; + + st.equal( + mayHaveAccessibleLabel( JSXElementMock('div', [ JSXAttributeMock(customLabelProp, 'A delicate label'), ], []), 1, [customLabelProp], - )).toBe(true); - }); + ), + true, + 'aria-label returns true', + ); + + st.end(); }); - describe('text label', () => { - it('Literal text, should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + + t.test('text label', (st) => { + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ LiteralMock('A fancy label'), - ]))).toBe(true); - }); - it('Literal whitespace, should return false', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + ])), + true, + 'Literal text, returns true', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ LiteralMock(' '), - ]))).toBe(false); - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + ])), + false, + 'Literal spaces whitespace, returns false', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ LiteralMock('\n'), - ]))).toBe(false); - }); - it('JSXText, should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + ])), + false, + 'Literal newline whitespace, returns false', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ JSXTextMock('A fancy label'), - ]))).toBe(true); - }); - it('label is outside of default depth, should return false', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + ])), + true, + 'JSXText, returns true', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ JSXElementMock('div', [], [ JSXTextMock('A fancy label'), ]), - ]))).toBe(false); - }); - it('label is inside of custom depth, should return true', () => { - expect(mayHaveAccessibleLabel( + ])), + false, + 'label is outside of default depth, returns false', + ); + + st.equal( + mayHaveAccessibleLabel( JSXElementMock('div', [], [ JSXElementMock('div', [], [ JSXTextMock('A fancy label'), ]), ]), 2, - )).toBe(true); - }); - it('deep nesting, should return true', () => { - expect(mayHaveAccessibleLabel( + ), + true, + 'label is inside of custom depth, returns true', + ); + + st.equal( + mayHaveAccessibleLabel( JSXElementMock('div', [], [ JSXElementMock('div', [], [ JSXElementMock('span', [], []), @@ -138,49 +187,70 @@ describe('mayHaveAccessibleLabel', () => { ]), ]), 6, - )).toBe(true); - }); + ), + true, + 'deep nesting, returns true', + ); + + st.end(); }); - describe('image content', () => { - it('without alt, should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + + t.test('image content', (st) => { + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ JSXElementMock('img', [ JSXAttributeMock('src', 'some/path'), ]), - ]))).toBe(false); - }); - it('with alt, should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + ])), + false, + 'without alt, returns true', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ JSXElementMock('img', [ JSXAttributeMock('src', 'some/path'), JSXAttributeMock('alt', 'A sensible label'), ]), - ]))).toBe(true); - }); - it('with aria-label, should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + ])), + true, + 'with alt, returns true', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ JSXElementMock('img', [ JSXAttributeMock('src', 'some/path'), JSXAttributeMock('aria-label', 'A sensible label'), ]), - ]))).toBe(true); - }); + ])), + true, + 'with aria-label, returns true', + ); + + st.end(); }); - describe('Intederminate situations', () => { - describe('expression container children', () => { - it('should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ - JSXExpressionContainerMock('mysteryBox'), - ]))).toBe(true); - }); - }); - describe('spread operator in attributes', () => { - it('should return true', () => { - expect(mayHaveAccessibleLabel(JSXElementMock('div', [ - JSXAttributeMock('style', 'some-junk'), - JSXSpreadAttributeMock('props'), - ], []))).toBe(true); - }); - }); + + t.test('Intederminate situations', (st) => { + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [], [ + JSXExpressionContainerMock('mysteryBox'), + ])), + true, + 'expression container children, returns true', + ); + + st.equal( + mayHaveAccessibleLabel(JSXElementMock('div', [ + JSXAttributeMock('style', 'some-junk'), + JSXSpreadAttributeMock('props'), + ], [])), + true, + 'spread operator in attributes, returns true', + ); + + st.end(); }); + + t.end(); }); diff --git a/__tests__/src/util/parserOptionsMapper-test.js b/__tests__/src/util/parserOptionsMapper-test.js index d22b6b647..b746698e7 100644 --- a/__tests__/src/util/parserOptionsMapper-test.js +++ b/__tests__/src/util/parserOptionsMapper-test.js @@ -1,88 +1,93 @@ import { version as eslintVersion } from 'eslint/package.json'; -import expect from 'expect'; +import test from 'tape'; import semver from 'semver'; + import parserOptionsMapper from '../../__util__/parserOptionsMapper'; const usingLegacy = semver.major(eslintVersion) < 9; -describe('parserOptionsMapper', () => { - it('should return an test case object', () => { - const testCase = { +test('parserOptionsMapper', (t) => { + const expectedResult = usingLegacy + ? { code: '
', errors: [], options: {}, - }; - - const expectedResult = usingLegacy - ? { - code: '
', - errors: [], - options: {}, + parserOptions: { + ecmaVersion: 2018, + ecmaFeatures: { + experimentalObjectRestSpread: true, + jsx: true, + }, + }, + settings: {}, + } + : { + code: '
', + errors: [], + options: {}, + languageOptions: { + ecmaVersion: 'latest', parserOptions: { - ecmaVersion: 2018, ecmaFeatures: { experimentalObjectRestSpread: true, jsx: true, }, }, - settings: {}, - } - : { - code: '
', - errors: [], - options: {}, - languageOptions: { - ecmaVersion: 'latest', - parserOptions: { - ecmaFeatures: { - experimentalObjectRestSpread: true, - jsx: true, - }, - }, + }, + settings: {}, + }; + + t.deepEqual( + parserOptionsMapper({ + code: '
', + errors: [], + options: {}, + }), + expectedResult, + 'returns a test case object', + ); + + const expectedResult2 = usingLegacy + ? { + code: '
', + errors: [], + options: {}, + parserOptions: { + ecmaVersion: 5, + ecmaFeatures: { + experimentalObjectRestSpread: true, + jsx: true, }, - settings: {}, - }; - expect(parserOptionsMapper(testCase)).toEqual(expectedResult); - }); - it('should allow for overriding parserOptions', () => { - const testCase = { + }, + settings: {}, + } + : { code: '
', errors: [], options: {}, languageOptions: { ecmaVersion: 5, - }, - }; - - const expectedResult = usingLegacy - ? { - code: '
', - errors: [], - options: {}, parserOptions: { - ecmaVersion: 5, ecmaFeatures: { experimentalObjectRestSpread: true, jsx: true, }, }, - settings: {}, - } - : { - code: '
', - errors: [], - options: {}, - languageOptions: { - ecmaVersion: 5, - parserOptions: { - ecmaFeatures: { - experimentalObjectRestSpread: true, - jsx: true, - }, - }, - }, - settings: {}, - }; - expect(parserOptionsMapper(testCase)).toEqual(expectedResult); - }); + }, + settings: {}, + }; + t.deepEqual( + parserOptionsMapper({ + code: '
', + errors: [], + options: {}, + languageOptions: { + ecmaVersion: 5, + }, + }), + expectedResult2, + 'allows for overriding parserOptions', + ); + + t.end(); }); diff --git a/__tests__/src/util/schemas-test.js b/__tests__/src/util/schemas-test.js index fb944efb2..dfdb2f3f2 100644 --- a/__tests__/src/util/schemas-test.js +++ b/__tests__/src/util/schemas-test.js @@ -1,29 +1,35 @@ -import expect from 'expect'; +import test from 'tape'; + import { generateObjSchema, arraySchema, enumArraySchema } from '../../../src/util/schemas'; -describe('schemas', () => { - it('should generate an object schema with correct properties', () => { +test('schemas', (t) => { + t.test('should generate an object schema with correct properties', (st) => { const schema = generateObjSchema({ foo: 'bar', baz: arraySchema, }); const properties = schema.properties || {}; - expect(properties.foo).toEqual(properties.foo, 'bar'); - expect(properties.baz.type).toEqual('array'); - }); - describe('enumArraySchema', () => { - it('works with no arguments', () => { - expect(enumArraySchema()).toEqual({ - additionalItems: false, - items: { - enum: [], - type: 'string', - }, - minItems: 0, - type: 'array', - uniqueItems: true, - }); - }); + st.deepEqual(properties.foo, properties.foo, 'bar'); + st.deepEqual(properties.baz.type, 'array'); + + st.end(); }); + + t.deepEqual( + enumArraySchema(), + { + additionalItems: false, + items: { + enum: [], + type: 'string', + }, + minItems: 0, + type: 'array', + uniqueItems: true, + }, + 'enumArraySchema works with no arguments', + ); + + t.end(); }); diff --git a/package.json b/package.json index d4d8aff01..5e550c3cb 100644 --- a/package.json +++ b/package.json @@ -24,17 +24,16 @@ "lint:fix": "npm run lint -- --fix", "lint": "npx eslint@8 --ext=js,mjs,cjs,ts,tsx .", "prepublish": "not-in-publish || npm run prepublishOnly", - "prepublishOnly": "safe-publish-latest && npm run lint && npm run flow && npm run jest", + "prepublishOnly": "safe-publish-latest && npm run lint && npm run flow && npm run tests-only", "pretest": "npm run lint:fix && npm run flow", - "test": "npm run jest", + "test": "npm run tests-only", + "tests-only": "tape --require=@babel/register '__tests__/**/*.js'", "posttest": "npx npm@'>=10.2' audit --production", - "test:ci": "npm run jest -- --ci --runInBand", "pretest:examples": "npm run build", "test:examples": "npm run test-example:legacy && npm run test-example:flat-esm && npm run test-example:flat-cjs", "test-example:legacy": "cd examples/legacy && npm install && npm run lint", "test-example:flat-esm": "cd examples/flat-esm && npm install && npm run lint", "test-example:flat-cjs": "cd examples/flat-cjs && npm install && npm run lint", - "jest": "jest --coverage __tests__", "pregenerate-list-of-rules": "npm run build", "generate-list-of-rules": "eslint-doc-generator --rule-doc-title-format prefix-name --rule-doc-section-options false --config-emoji recommended,☑️ --ignore-config flat/recommended --ignore-config flat/strict", "generate-list-of-rules:check": "npm run generate-list-of-rules -- --check", @@ -51,7 +50,6 @@ "babel-jest": "^24.9.0", "babel-plugin-add-module-exports": "^1.0.4", "babel-preset-airbnb": "^5.0.0", - "core-js": "^3.38.1", "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9", "eslint-config-airbnb-base": "^15.0.0", "eslint-doc-generator": "^1.7.1", @@ -59,11 +57,9 @@ "eslint-plugin-flowtype": "^5.8.0 || ^8.0.3", "eslint-plugin-import": "^2.29.1", "estraverse": "^5.3.0", - "expect": "^24.9.0", "flow-bin": "^0.147.0", "in-publish": "^2.0.1", "jackspeak": "=2.1.1", - "jest": "^24.9.0", "jscodeshift": "^0.7.1", "minimist": "^1.2.8", "npmignore": "^0.3.1", @@ -72,6 +68,7 @@ "rimraf": "^3.0.2", "safe-publish-latest": "^2.0.0", "semver": "^6.3.1", + "tape": "^5.8.1", "to-ast": "^1.0.0" }, "engines": { @@ -99,32 +96,6 @@ "peerDependencies": { "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" }, - "jest": { - "coverageReporters": [ - "lcov", - "json", - "html" - ], - "coverageDirectory": "coverage", - "roots": [ - "__tests__" - ], - "testPathIgnorePatterns": [ - "__tests__/__util__/" - ], - "testEnvironment": "node", - "moduleNameMapper": { - "@eslint/config-array": "/node_modules/@eslint/config-array/dist/cjs/index.cjs", - "@eslint/object-schema": "/node_modules/@eslint/object-schema/dist/cjs/index.cjs", - "node:assert": "/__tests__/__util__/nodeReexports/assert.js", - "node:fs/promises": "/__tests__/__util__/nodeReexports/fs-promises.js", - "node:fs": "/__tests__/__util__/nodeReexports/fs.js", - "node:path": "/__tests__/__util__/nodeReexports/path.js", - "node:url": "/__tests__/__util__/nodeReexports/url.js", - "node:util": "/__tests__/__util__/nodeReexports/util.js" - }, - "setupFilesAfterEnv": ["/setup.jest.js"] - }, "auto-changelog": { "output": "CHANGELOG.md", "template": "keepachangelog", @@ -144,8 +115,7 @@ "/flow", "scripts/", "CONTRIBUTING.md", - "/examples", - "setup.jest.js" + "/examples" ] } } diff --git a/scripts/boilerplate/test.js b/scripts/boilerplate/test.js index 14da7cdd8..ae1444adb 100644 --- a/scripts/boilerplate/test.js +++ b/scripts/boilerplate/test.js @@ -1,5 +1,4 @@ -const testBoilerplate = (name, author, description) => `/* eslint-env jest */ -/** +const testBoilerplate = (name, author, description) => `/** * @fileoverview ${description} * @author ${author} */ diff --git a/setup.jest.js b/setup.jest.js deleted file mode 100644 index d906eae00..000000000 --- a/setup.jest.js +++ /dev/null @@ -1,2 +0,0 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -import 'core-js/stable/structured-clone';