Skip to content

Commit

Permalink
Merge pull request #65 from scalvert/required-assertion
Browse files Browse the repository at this point in the history
Add isRequired and isNotRequired assertions
  • Loading branch information
Turbo87 authored Mar 21, 2018
2 parents d7fc0d6 + 82548e2 commit 0297e1e
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 0 deletions.
34 changes: 34 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,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)**
Expand Down
112 changes: 112 additions & 0 deletions lib/__tests__/is-not-required.js
Original file line number Diff line number Diff line change
@@ -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 = '<input type="text" required>';

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 = '<input type="text">';
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 <unknown> exists',
result: false,
}]);
});
});

describe('with selector', () => {
beforeEach(() => {
document.body.innerHTML = '<input type="text">';
});

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]');
expect(() => assert.dom(document.createElement('div')).isRequired()).toThrow('Unexpected Element Type: [object HTMLDivElement]');
});
});
112 changes: 112 additions & 0 deletions lib/__tests__/is-required.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* 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 = '<input>';

assert.dom('input').isRequired('custom message');

expect(assert.results).toEqual([{
actual: 'not required',
expected: 'required',
message: 'custom message',
result: false,
}]);
});

describe('with HTMLElement', () => {
let element;

beforeEach(() => {
document.body.innerHTML = '<input type="text" required>';
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 <unknown> exists',
result: false,
}]);
});
});

describe('with selector', () => {
beforeEach(() => {
document.body.innerHTML = '<input type="text" required>';
});

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();

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]');
expect(() => assert.dom(document.createElement('div')).isRequired()).toThrow('Unexpected Element Type: [object HTMLDivElement]');
});
});
32 changes: 32 additions & 0 deletions lib/assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ 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 isNotRequired from './assertions/is-not-required';

import elementToString from './helpers/element-to-string';
import collapseWhitespace from './helpers/collapse-whitespace';
Expand Down Expand Up @@ -104,6 +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[type="text"]').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
Expand Down
24 changes: 24 additions & 0 deletions lib/assertions/is-not-required.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import elementToString from '../helpers/element-to-string';

export default function notRequired(message) {
let element = this.findTargetElement();
if (!element) return;

if (!(
element instanceof HTMLInputElement ||
element instanceof HTMLTextAreaElement ||
element instanceof HTMLSelectElement
)) {
throw new TypeError(`Unexpected Element Type: ${element.toString()}`);
}

let result = element.required === false;
let actual = !result ? 'required' : 'not required';
let expected = 'not required';

if (!message) {
message = `Element ${elementToString(this.target)} is not required`;
}

this.pushResult({ result, actual, expected, message });
}
24 changes: 24 additions & 0 deletions lib/assertions/is-required.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import elementToString from '../helpers/element-to-string';

export default function required(message) {
let element = this.findTargetElement();
if (!element) return;

if (!(
element instanceof HTMLInputElement ||
element instanceof HTMLTextAreaElement ||
element instanceof HTMLSelectElement
)) {
throw new TypeError(`Unexpected Element Type: ${element.toString()}`);
}

let result = element.required === true;
let actual = result ? 'required' : 'not required';
let expected = 'required';

if (!message) {
message = `Element ${elementToString(this.target)} is required`;
}

this.pushResult({ result, actual, expected, message });
}

0 comments on commit 0297e1e

Please sign in to comment.