From 44cc617b2550bb105a8d75f9e94e3c762e942aec Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Thu, 15 Mar 2018 16:41:25 -0700 Subject: [PATCH 1/9] Adding assertion for isRequired --- .vscode/launch.json | 11 ++++++++ lib/__tests__/is-required.js | 47 +++++++++++++++++++++++++++++++++++ lib/assertions.js | 5 ++++ lib/assertions/is-required.js | 16 ++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 lib/__tests__/is-required.js create mode 100644 lib/assertions/is-required.js diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..677d00eda --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node" + } + ] +} \ No newline at end of file diff --git a/lib/__tests__/is-required.js b/lib/__tests__/is-required.js new file mode 100644 index 000000000..721393e3a --- /dev/null +++ b/lib/__tests__/is-required.js @@ -0,0 +1,47 @@ +/* eslint-env jest */ + +import TestAssertions from "../helpers/test-assertions"; + +describe('assert.dom(...).isRequired()', () => { + let assert; + + beforeEach(() => { + assert = new TestAssertions(); + }); + + test('with custom message', () => { + document.body.innerHTML = ''; + + assert.dom('input').isRequired('custom message'); + + expect(assert.results).toEqual([{ + actual: 'not required', + expected: 'required', + message: 'custom message', + result: false, + }]); + }); + + describe('with selector', () => { + beforeEach(() => { + document.body.innerHTML = ''; + }); + + test('fails for missing element', () => { + assert.dom('input[type="password"]').isRequired(); + + expect(assert.results).toEqual([{ + message: 'Element input[type="password"] exists', + result: false, + }]); + }); + }); + + test('throws for unexpected parameter types', () => { + expect(() => assert.dom(5).isRequired()).toThrow('Unexpected Parameter: 5'); + expect(() => assert.dom(true).isRequired()).toThrow('Unexpected Parameter: true'); + expect(() => assert.dom(undefined).isRequired()).toThrow('Unexpected Parameter: undefined'); + expect(() => assert.dom({}).isRequired()).toThrow('Unexpected Parameter: [object Object]'); + expect(() => assert.dom(document).isRequired()).toThrow('Unexpected Parameter: [object HTMLDocument]'); + }); +}); diff --git a/lib/assertions.js b/lib/assertions.js index 0e1946926..b61cd514f 100644 --- a/lib/assertions.js +++ b/lib/assertions.js @@ -3,6 +3,7 @@ import focused from './assertions/focused'; import notFocused from './assertions/not-focused'; import isChecked from './assertions/is-checked'; import isNotChecked from './assertions/is-not-checked'; +import isRequired from './assertions/is-required'; import elementToString from './helpers/element-to-string'; import collapseWhitespace from './helpers/collapse-whitespace'; @@ -104,6 +105,10 @@ export default class DOMAssertions { notFocused.call(this, message); } + isRequired(message) { + isRequired.call(this, message); + } + /** * Assert that the [HTMLElement][] has an attribute with the provided `name` * and optionally checks if the attribute `value` matches the provided text diff --git a/lib/assertions/is-required.js b/lib/assertions/is-required.js new file mode 100644 index 000000000..379230a6f --- /dev/null +++ b/lib/assertions/is-required.js @@ -0,0 +1,16 @@ +import elementToString from '../helpers/element-to-string'; + +export default function required(message) { + let element = this.findTargetElement(); + if (!element) return; +debugger; + let result = element.required === true; + let actual = element.required === true ? 'required' : 'not required'; + let expected = 'required'; + + if (!message) { + message = `Element ${elementToString(this.target)} is required`; + } + + this.pushResult({ result, actual, expected, message }); +} \ No newline at end of file From 286b20be99ded92415da569aad4d928c21be56f2 Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Thu, 15 Mar 2018 17:02:21 -0700 Subject: [PATCH 2/9] Adding tests --- lib/__tests__/is-required.js | 64 +++++++++++++++++++++++++++++++++++ lib/assertions/is-required.js | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/__tests__/is-required.js b/lib/__tests__/is-required.js index 721393e3a..a624ebaad 100644 --- a/lib/__tests__/is-required.js +++ b/lib/__tests__/is-required.js @@ -22,11 +22,75 @@ describe('assert.dom(...).isRequired()', () => { }]); }); + describe('with HTMLElement', () => { + let element; + + beforeEach(() => { + document.body.innerHTML = ''; + element = document.querySelector('input'); + }); + + test('succeeds if element is required', () => { + assert.dom(element).isRequired(); + + expect(assert.results).toEqual([{ + actual: 'required', + expected: 'required', + message: 'Element input[type=\"text\"][required] is required', + result: true, + }]); + }); + + test('fails if element is not required', () => { + element.required = false; + assert.dom(element).isRequired(); + + expect(assert.results).toEqual([{ + actual: 'not required', + expected: 'required', + message: 'Element input[type=\"text\"] is required', + result: false, + }]); + }); + + test('fails for missing element', () => { + assert.dom(null).isRequired(); + + expect(assert.results).toEqual([{ + message: 'Element exists', + result: false, + }]); + }); + }); + describe('with selector', () => { beforeEach(() => { document.body.innerHTML = ''; }); + test('succeeds if element is required', () => { + assert.dom('input').isRequired(); + + expect(assert.results).toEqual([{ + actual: 'required', + expected: 'required', + message: 'Element input is required', + result: true, + }]); + }); + + test('fails if element is not required', () => { + document.querySelector('input').required = false; + assert.dom('input').isRequired(); + + expect(assert.results).toEqual([{ + actual: 'not required', + expected: 'required', + message: 'Element input is required', + result: false, + }]); + }); + test('fails for missing element', () => { assert.dom('input[type="password"]').isRequired(); diff --git a/lib/assertions/is-required.js b/lib/assertions/is-required.js index 379230a6f..cb4c43461 100644 --- a/lib/assertions/is-required.js +++ b/lib/assertions/is-required.js @@ -3,7 +3,7 @@ import elementToString from '../helpers/element-to-string'; export default function required(message) { let element = this.findTargetElement(); if (!element) return; -debugger; + let result = element.required === true; let actual = element.required === true ? 'required' : 'not required'; let expected = 'required'; From 93aaf8891f9a13dd1653a6d8509f98e4344eb758 Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Thu, 15 Mar 2018 17:05:41 -0700 Subject: [PATCH 3/9] oops --- .vscode/launch.json | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 677d00eda..000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "node" - } - ] -} \ No newline at end of file From 0ec1efcf5d047e1d42dd55f97dce53a577831a75 Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Thu, 15 Mar 2018 17:13:21 -0700 Subject: [PATCH 4/9] Adding isNotRequired --- lib/__tests__/is-not-required.js | 112 ++++++++++++++++++++++++++++++ lib/assertions.js | 27 +++++++ lib/assertions/is-not-required.js | 16 +++++ 3 files changed, 155 insertions(+) create mode 100644 lib/__tests__/is-not-required.js create mode 100644 lib/assertions/is-not-required.js diff --git a/lib/__tests__/is-not-required.js b/lib/__tests__/is-not-required.js new file mode 100644 index 000000000..a645f64cb --- /dev/null +++ b/lib/__tests__/is-not-required.js @@ -0,0 +1,112 @@ +/* eslint-env jest */ + +import TestAssertions from "../helpers/test-assertions"; + +describe('assert.dom(...).isNotRequired()', () => { + let assert; + + beforeEach(() => { + assert = new TestAssertions(); + }); + + test('with custom message', () => { + document.body.innerHTML = ''; + + assert.dom('input').isNotRequired('custom message'); + + expect(assert.results).toEqual([{ + actual: 'required', + expected: 'not required', + message: 'custom message', + result: false, + }]); + }); + + describe('with HTMLElement', () => { + let element; + + beforeEach(() => { + document.body.innerHTML = ''; + element = document.querySelector('input'); + }); + + test('succeeds if element is not required', () => { + assert.dom(element).isNotRequired(); + + expect(assert.results).toEqual([{ + actual: 'not required', + expected: 'not required', + message: 'Element input[type=\"text\"] is not required', + result: true, + }]); + }); + + test('fails if element is required', () => { + element.required = true; + assert.dom(element).isNotRequired(); + + expect(assert.results).toEqual([{ + actual: 'required', + expected: 'not required', + message: 'Element input[type=\"text\"][required] is not required', + result: false, + }]); + }); + + test('fails for missing element', () => { + assert.dom(null).isNotRequired(); + + expect(assert.results).toEqual([{ + message: 'Element exists', + result: false, + }]); + }); + }); + + describe('with selector', () => { + beforeEach(() => { + document.body.innerHTML = ''; + }); + + test('succeeds if element is not required', () => { + assert.dom('input').isNotRequired(); + + expect(assert.results).toEqual([{ + actual: 'not required', + expected: 'not required', + message: 'Element input is not required', + result: true, + }]); + }); + + test('fails if element is required', () => { + document.querySelector('input').required = true; + assert.dom('input').isNotRequired(); + + expect(assert.results).toEqual([{ + actual: 'required', + expected: 'not required', + message: 'Element input is not required', + result: false, + }]); + }); + + test('fails for missing element', () => { + assert.dom('input[type="password"]').isNotRequired(); + + expect(assert.results).toEqual([{ + message: 'Element input[type="password"] exists', + result: false, + }]); + }); + }); + + test('throws for unexpected parameter types', () => { + expect(() => assert.dom(5).isNotRequired()).toThrow('Unexpected Parameter: 5'); + expect(() => assert.dom(true).isNotRequired()).toThrow('Unexpected Parameter: true'); + expect(() => assert.dom(undefined).isNotRequired()).toThrow('Unexpected Parameter: undefined'); + expect(() => assert.dom({}).isNotRequired()).toThrow('Unexpected Parameter: [object Object]'); + expect(() => assert.dom(document).isNotRequired()).toThrow('Unexpected Parameter: [object HTMLDocument]'); + }); + +}); diff --git a/lib/assertions.js b/lib/assertions.js index b61cd514f..294c2e88f 100644 --- a/lib/assertions.js +++ b/lib/assertions.js @@ -4,6 +4,7 @@ import notFocused from './assertions/not-focused'; import isChecked from './assertions/is-checked'; import isNotChecked from './assertions/is-not-checked'; import isRequired from './assertions/is-required'; +import isNotRequired from './assertions/is-not-required'; import elementToString from './helpers/element-to-string'; import collapseWhitespace from './helpers/collapse-whitespace'; @@ -105,10 +106,36 @@ export default class DOMAssertions { notFocused.call(this, message); } + /** + * Assert that the [HTMLElement][] or an [HTMLElement][] matching the + * `selector` is currently required. + * + * @param {string?} message + * + * @example + * assert.dom('input type="text"').isRequired(); + * + * @see {@link #isNotRequired} + */ isRequired(message) { isRequired.call(this, message); } + /** + * Assert that the [HTMLElement][] or an [HTMLElement][] matching the + * `selector` is currently not required. + * + * @param {string?} message + * + * @example + * assert.dom('input.active').isNotRequired(); + * + * @see {@link #isRequired} + */ + isNotRequired(message) { + isNotRequired.call(this, message); + } + /** * Assert that the [HTMLElement][] has an attribute with the provided `name` * and optionally checks if the attribute `value` matches the provided text diff --git a/lib/assertions/is-not-required.js b/lib/assertions/is-not-required.js new file mode 100644 index 000000000..9cb17d981 --- /dev/null +++ b/lib/assertions/is-not-required.js @@ -0,0 +1,16 @@ +import elementToString from '../helpers/element-to-string'; + +export default function notRequired(message) { + let element = this.findTargetElement(); + if (!element) return; + + let result = element.required === false; + let actual = element.required === true ? 'required' : 'not required'; + let expected = 'not required'; + + if (!message) { + message = `Element ${elementToString(this.target)} is not required`; + } + + this.pushResult({ result, actual, expected, message }); +} From 5640d353174dc95a158d86b47cd1ded1a082225e Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Thu, 15 Mar 2018 17:16:42 -0700 Subject: [PATCH 5/9] Fixing doc string --- lib/assertions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/assertions.js b/lib/assertions.js index 294c2e88f..3eb723ed1 100644 --- a/lib/assertions.js +++ b/lib/assertions.js @@ -113,7 +113,7 @@ export default class DOMAssertions { * @param {string?} message * * @example - * assert.dom('input type="text"').isRequired(); + * assert.dom('input[type="text"]').isRequired(); * * @see {@link #isNotRequired} */ @@ -128,7 +128,7 @@ export default class DOMAssertions { * @param {string?} message * * @example - * assert.dom('input.active').isNotRequired(); + * assert.dom('input[type="text"]').isNotRequired(); * * @see {@link #isRequired} */ From 3470f2e776206017ad6fb080256a20a43147ecae Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Thu, 15 Mar 2018 17:18:39 -0700 Subject: [PATCH 6/9] Regenerating docs --- API.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/API.md b/API.md index 1bd37eee4..1c6cc969e 100644 --- a/API.md +++ b/API.md @@ -61,6 +61,40 @@ Assert an [HTMLElement][] matching the `selector` does not exists. assert.dom('.should-not-exist').doesNotExist(); ``` +### isChecked + +- **See: [#isNotChecked](#isnotchecked)** + +Assert that the [HTMLElement][] or an [HTMLElement][] matching the +`selector` is currently checked. + +**Parameters** + +- `message` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** + +**Examples** + +```javascript +assert.dom('input.active').isChecked(); +``` + +### isNotChecked + +- **See: [#isChecked](#ischecked)** + +Assert that the [HTMLElement][] or an [HTMLElement][] matching the +`selector` is currently unchecked. + +**Parameters** + +- `message` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** + +**Examples** + +```javascript +assert.dom('input.active').isNotChecked(); +``` + ### isFocused - **See: [#isNotFocused](#isnotfocused)** @@ -95,6 +129,40 @@ Assert that the [HTMLElement][] or an [HTMLElement][] matching the assert.dom('input[type="password"]').isNotFocused(); ``` +### isRequired + +- **See: [#isNotRequired](#isnotrequired)** + +Assert that the [HTMLElement][] or an [HTMLElement][] matching the +`selector` is currently required. + +**Parameters** + +- `message` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** + +**Examples** + +```javascript +assert.dom('input[type="text"]').isRequired(); +``` + +### isNotRequired + +- **See: [#isRequired](#isrequired)** + +Assert that the [HTMLElement][] or an [HTMLElement][] matching the +`selector` is currently not required. + +**Parameters** + +- `message` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** + +**Examples** + +```javascript +assert.dom('input[type="text"]').isNotRequired(); +``` + ### hasAttribute - **See: [#doesNotHaveAttribute](#doesnothaveattribute)** From 8a330753a66fdf3a67faab78c118f412d1fc5a4b Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Sat, 17 Mar 2018 14:01:17 -0700 Subject: [PATCH 7/9] Reusing cached value --- lib/assertions/is-not-required.js | 2 +- lib/assertions/is-required.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/assertions/is-not-required.js b/lib/assertions/is-not-required.js index 9cb17d981..7b6b26fae 100644 --- a/lib/assertions/is-not-required.js +++ b/lib/assertions/is-not-required.js @@ -5,7 +5,7 @@ export default function notRequired(message) { if (!element) return; let result = element.required === false; - let actual = element.required === true ? 'required' : 'not required'; + let actual = !result ? 'required' : 'not required'; let expected = 'not required'; if (!message) { diff --git a/lib/assertions/is-required.js b/lib/assertions/is-required.js index cb4c43461..d1571b03c 100644 --- a/lib/assertions/is-required.js +++ b/lib/assertions/is-required.js @@ -5,7 +5,7 @@ export default function required(message) { if (!element) return; let result = element.required === true; - let actual = element.required === true ? 'required' : 'not required'; + let actual = result ? 'required' : 'not required'; let expected = 'required'; if (!message) { From 0eae31fda7ca6b3408bf72f02d17a9279ee32d3a Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Sun, 18 Mar 2018 16:25:10 -0700 Subject: [PATCH 8/9] Adding check to ensure correct element type is passed. --- lib/__tests__/is-not-required.js | 2 +- lib/__tests__/is-required.js | 1 + lib/assertions/is-not-required.js | 4 ++++ lib/assertions/is-required.js | 4 ++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/__tests__/is-not-required.js b/lib/__tests__/is-not-required.js index a645f64cb..aa0a8a5fd 100644 --- a/lib/__tests__/is-not-required.js +++ b/lib/__tests__/is-not-required.js @@ -107,6 +107,6 @@ describe('assert.dom(...).isNotRequired()', () => { expect(() => assert.dom(undefined).isNotRequired()).toThrow('Unexpected Parameter: undefined'); expect(() => assert.dom({}).isNotRequired()).toThrow('Unexpected Parameter: [object Object]'); expect(() => assert.dom(document).isNotRequired()).toThrow('Unexpected Parameter: [object HTMLDocument]'); + expect(() => assert.dom(document.createElement('div')).isRequired()).toThrow('Unexpected Element Type: [object HTMLDivElement]'); }); - }); diff --git a/lib/__tests__/is-required.js b/lib/__tests__/is-required.js index a624ebaad..d991c671a 100644 --- a/lib/__tests__/is-required.js +++ b/lib/__tests__/is-required.js @@ -107,5 +107,6 @@ describe('assert.dom(...).isRequired()', () => { expect(() => assert.dom(undefined).isRequired()).toThrow('Unexpected Parameter: undefined'); expect(() => assert.dom({}).isRequired()).toThrow('Unexpected Parameter: [object Object]'); expect(() => assert.dom(document).isRequired()).toThrow('Unexpected Parameter: [object HTMLDocument]'); + expect(() => assert.dom(document.createElement('div')).isRequired()).toThrow('Unexpected Element Type: [object HTMLDivElement]'); }); }); diff --git a/lib/assertions/is-not-required.js b/lib/assertions/is-not-required.js index 7b6b26fae..f1c8468a9 100644 --- a/lib/assertions/is-not-required.js +++ b/lib/assertions/is-not-required.js @@ -4,6 +4,10 @@ export default function notRequired(message) { let element = this.findTargetElement(); if (!element) return; + if (!(element instanceof HTMLInputElement)) { + throw new TypeError(`Unexpected Element Type: ${element.toString()}`); + } + let result = element.required === false; let actual = !result ? 'required' : 'not required'; let expected = 'not required'; diff --git a/lib/assertions/is-required.js b/lib/assertions/is-required.js index d1571b03c..52e991f55 100644 --- a/lib/assertions/is-required.js +++ b/lib/assertions/is-required.js @@ -4,6 +4,10 @@ export default function required(message) { let element = this.findTargetElement(); if (!element) return; + if (!(element instanceof HTMLInputElement)) { + throw new TypeError(`Unexpected Element Type: ${element.toString()}`); + } + let result = element.required === true; let actual = result ? 'required' : 'not required'; let expected = 'required'; From 82548e2cbb24105e663c2585a2a6807461322d76 Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Sun, 18 Mar 2018 16:34:06 -0700 Subject: [PATCH 9/9] Covering all types that support required --- lib/assertions/is-not-required.js | 6 +++++- lib/assertions/is-required.js | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/assertions/is-not-required.js b/lib/assertions/is-not-required.js index f1c8468a9..34b5fd91d 100644 --- a/lib/assertions/is-not-required.js +++ b/lib/assertions/is-not-required.js @@ -4,7 +4,11 @@ export default function notRequired(message) { let element = this.findTargetElement(); if (!element) return; - if (!(element instanceof HTMLInputElement)) { + if (!( + element instanceof HTMLInputElement || + element instanceof HTMLTextAreaElement || + element instanceof HTMLSelectElement + )) { throw new TypeError(`Unexpected Element Type: ${element.toString()}`); } diff --git a/lib/assertions/is-required.js b/lib/assertions/is-required.js index 52e991f55..6f4f81c43 100644 --- a/lib/assertions/is-required.js +++ b/lib/assertions/is-required.js @@ -4,7 +4,11 @@ export default function required(message) { let element = this.findTargetElement(); if (!element) return; - if (!(element instanceof HTMLInputElement)) { + if (!( + element instanceof HTMLInputElement || + element instanceof HTMLTextAreaElement || + element instanceof HTMLSelectElement + )) { throw new TypeError(`Unexpected Element Type: ${element.toString()}`); }