Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ There must be at least one assertion on the test to be valid. These are all the
- `assert.that(collection).includes(object)`
- `assert.that(collection).doesNotInclude(object)`
- `assert.that(collection).includesExactly(...objects)`
- when the collection is a `String`, `includes`, `doesNotInclude`, `isIncludedIn` and `isNotIncludedIn` work with
substrings, e.g. `assert.that('hello').includes('ell')`
- Emptiness
- `assert.that(collection).isEmpty()` or `assert.isEmpty(collection)`
- `assert.that(collection).isNotEmpty()` or `assert.isNotEmpty(collection)`
Expand Down
28 changes: 16 additions & 12 deletions lib/core/assertion.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,15 @@ export class Assertion extends TestResultReporter {
* assert.that(new Set([1, 2, 3])).includes(3)
*
* @example string
* assert.that('42').includes('4')
* assert.that('hello').includes('ell')
*
* @param {*} expectedObject the object that you are expecting to be included.
* @param {Function} [equalityCriteria] a two-argument function to be used to compare elements from the `actual` collection and `expectedObject`. Optional.
*
* @returns {void}
*/
includes(expectedObject, equalityCriteria) {
const resultIsSuccessful = convertToArray(this.#actual).find(element =>
this.#areConsideredEqual(element, expectedObject, equalityCriteria));
const resultIsSuccessful = this.#collectionIncludes(this.#actual, expectedObject, equalityCriteria);
const failureMessage = () => I18nMessage.of('expectation_include', this.#actualResultAsString(), prettyPrint(expectedObject));
this.#reportAssertionResult(resultIsSuccessful, failureMessage);
}
Expand All @@ -290,7 +289,7 @@ export class Assertion extends TestResultReporter {
* assert.that(3).isIncludedIn(new Set([1, 2, 3]))
*
* @example string
* assert.that('l').isIncludedIn('hello')
* assert.that('ell').isIncludedIn('hello')
*
* @param {Array|Set|Map|String} expectedCollection the collection that you are expecting the `actual` to be included in.
* @param {Function} [equalityCriteria] a two-argument function to be used to compare elements from the
Expand All @@ -299,8 +298,7 @@ export class Assertion extends TestResultReporter {
* @returns {void}
*/
isIncludedIn(expectedCollection, equalityCriteria) {
const resultIsSuccessful = convertToArray(expectedCollection).find(element =>
this.#areConsideredEqual(element, this.#actual, equalityCriteria));
const resultIsSuccessful = this.#collectionIncludes(expectedCollection, this.#actual, equalityCriteria);
const failureMessage = () => I18nMessage.of('expectation_be_included_in', this.#actualResultAsString(), prettyPrint(expectedCollection));
this.#reportAssertionResult(resultIsSuccessful, failureMessage);
}
Expand All @@ -316,7 +314,7 @@ export class Assertion extends TestResultReporter {
* assert.that(new Set([1, 2, 3])).doesNotInclude(4)
*
* @example string
* assert.that('42').doesNotInclude('5')
* assert.that('hello').doesNotInclude('xyz')
*
* @param {*} expectedObject the object that you are expecting to not be included.
* @param {Function} [equalityCriteria] a two-argument function to be used to compare elements from the `actual`
Expand All @@ -325,8 +323,7 @@ export class Assertion extends TestResultReporter {
* @returns {void}
*/
doesNotInclude(expectedObject, equalityCriteria) {
const resultIsSuccessful = !convertToArray(this.#actual).find(element =>
this.#areConsideredEqual(element, expectedObject, equalityCriteria));
const resultIsSuccessful = !this.#collectionIncludes(this.#actual, expectedObject, equalityCriteria);
const failureMessage = () => I18nMessage.of('expectation_not_include', this.#actualResultAsString(), prettyPrint(expectedObject));
this.#reportAssertionResult(resultIsSuccessful, failureMessage);
}
Expand All @@ -342,7 +339,7 @@ export class Assertion extends TestResultReporter {
* assert.that(4).isNotIncludedIn(new Set([1, 2, 3]))
*
* @example string
* assert.that('x').isNotIncludedIn('hello')
* assert.that('xyz').isNotIncludedIn('hello')
*
* @param {*} expectedCollection the collection that you are expecting the `actual` to not be included in.
* @param {Function} [equalityCriteria] a two-argument function to be used to compare elements from the
Expand All @@ -351,8 +348,7 @@ export class Assertion extends TestResultReporter {
* @returns {void}
*/
isNotIncludedIn(expectedCollection, equalityCriteria) {
const resultIsSuccessful = !convertToArray(expectedCollection).find(element =>
this.#areConsideredEqual(element, this.#actual, equalityCriteria));
const resultIsSuccessful = !this.#collectionIncludes(expectedCollection, this.#actual, equalityCriteria);
const failureMessage = () => I18nMessage.of('expectation_be_not_included_in', this.#actualResultAsString(), prettyPrint(expectedCollection));
this.#reportAssertionResult(resultIsSuccessful, failureMessage);
}
Expand Down Expand Up @@ -635,6 +631,14 @@ export class Assertion extends TestResultReporter {
return EqualityAssertionStrategy.evaluate(objectOne, objectTwo, equalityCriteria).comparisonResult;
}

#collectionIncludes(collection, object, equalityCriteria) {
if (isString(collection) && isString(object) && isUndefined(equalityCriteria)) {
return collection.includes(object);
}
return convertToArray(collection).some(element =>
this.#areConsideredEqual(element, object, equalityCriteria));
}

#checkIfErrorMatchesExpectation(errorExpectation, actualError) {
if (isRegex(errorExpectation)) {
return errorExpectation.test(actualError);
Expand Down
61 changes: 61 additions & 0 deletions tests/core/assertions/collection_assertions_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,31 @@ suite('collection assertions', () => {
expectSuccess(result);
});

test('includes works with substrings of Strings', async() => {
const result = await resultOfATestWith(assert => assert.that('hello').includes('ell'));

expectSuccess(result);
});

test('includes works when the matching element is falsy', async() => {
const result = await resultOfATestWith(assert => assert.that([0, 1]).includes(0));

expectSuccess(result);
});

test('includes fails when a String does not contain the substring', async() => {
const result = await resultOfATestWith(assert => assert.that('hello').includes('xyz'));

expectFailureOn(result, I18nMessage.of('expectation_include', '\'hello\'', '\'xyz\''));
});

test('includes on Strings uses the equality criteria when given, comparing character by character', async() => {
const result = await resultOfATestWith(assert =>
assert.that('hello').includes('L', (character, expected) => character.toLowerCase() === expected.toLowerCase()));

expectSuccess(result);
});

test('includes using the equality criteria for a positive case', async() => {
const result = await resultOfATestWith(assert => {
assert.that([{ hello: 'world' }]).includes(
Expand Down Expand Up @@ -110,6 +135,18 @@ suite('collection assertions', () => {
expectSuccess(result);
});

test('doesNotInclude is successful when a String does not contain the substring', async() => {
const result = await resultOfATestWith(assert => assert.that('hello').doesNotInclude('xyz'));

expectSuccess(result);
});

test('doesNotInclude fails when a String contains the substring', async() => {
const result = await resultOfATestWith(assert => assert.that('hello').doesNotInclude('ell'));

expectFailureOn(result, I18nMessage.of('expectation_not_include', '\'hello\'', '\'ell\''));
});

// includesExactly() assertion tests

test('includesExactly passes with a single object included', async() => {
Expand Down Expand Up @@ -280,6 +317,18 @@ suite('collection assertions', () => {
expectSuccess(result);
});

test('isIncludedIn works with substrings of Strings', async() => {
const result = await resultOfATestWith(assert => assert.that('ell').isIncludedIn('hello'));

expectSuccess(result);
});

test('isIncludedIn fails when the String does not contain the substring', async() => {
const result = await resultOfATestWith(assert => assert.that('xyz').isIncludedIn('hello'));

expectFailureOn(result, I18nMessage.of('expectation_be_included_in', '\'xyz\'', '\'hello\''));
});

// isNotIncludedIn() assertion tests

test('isNotIncludedIn is successful when the actual object is not part of the expected list', async() => {
Expand Down Expand Up @@ -311,4 +360,16 @@ suite('collection assertions', () => {

expectSuccess(result);
});

test('isNotIncludedIn is successful when the String does not contain the substring', async() => {
const result = await resultOfATestWith(assert => assert.that('xyz').isNotIncludedIn('hello'));

expectSuccess(result);
});

test('isNotIncludedIn fails when the String contains the substring', async() => {
const result = await resultOfATestWith(assert => assert.that('ell').isNotIncludedIn('hello'));

expectFailureOn(result, I18nMessage.of('expectation_be_not_included_in', '\'ell\'', '\'hello\''));
});
});
Loading