diff --git a/.github/workflows/expectHelper.yml b/.github/workflows/expectHelper.yml new file mode 100644 index 000000000..320089f5d --- /dev/null +++ b/.github/workflows/expectHelper.yml @@ -0,0 +1,34 @@ +name: Expect Helper Tests + +on: + push: + branches: + - 3.x + pull_request: + branches: + - '**' + +env: + CI: true + # Force terminal colors. @see https://www.npmjs.com/package/colors + FORCE_COLOR: 1 + +jobs: + build: + + runs-on: ubuntu-22.04 + + strategy: + matrix: + node-version: [18.x] + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: npm install + run: npm i --legacy-peer-deps + - name: run unit tests + run: ./node_modules/.bin/mocha test/helper/Expect_test.js --timeout 5000 diff --git a/docs/helpers/Expect.md b/docs/helpers/Expect.md new file mode 100644 index 000000000..39110098b --- /dev/null +++ b/docs/helpers/Expect.md @@ -0,0 +1,275 @@ +--- +permalink: /helpers/Expect +editLink: false +sidebar: auto +title: Expect +--- + + + +## ExpectHelper + +This helper allows performing assertions based on Chai. + +### Examples + +Zero-configuration when paired with other helpers like REST, Playwright: + +```js +// inside codecept.conf.js +{ + helpers: { + Playwright: {...}, + ExpectHelper: {}, + } +} +``` + +## Methods + +### expectAbove + +#### Parameters + +- `targetData` **any** +- `aboveThan` **any** number | Date +- `customErrorMsg` **any** + +### expectBelow + +#### Parameters + +- `targetData` **any** +- `belowThan` **any** number | Date +- `customErrorMsg` **any** + +### expectContain + +#### Parameters + +- `actualValue` **any** +- `expectedValueToContain` **any** +- `customErrorMsg` **any** + +### expectDeepEqual + +#### Parameters + +- `actualValue` **any** +- `expectedValue` **any** +- `customErrorMsg` **any** + +### expectDeepEqualExcluding + +expects members of two JSON objects are deeply equal excluding some properties + +#### Parameters + +- `actualValue` **any** +- `expectedValue` **any** +- `fieldsToExclude` **any** +- `customErrorMsg` **any** + +### expectDeepIncludeMembers + +expects an array to be a superset of another array + +#### Parameters + +- `superset` **any** +- `set` **any** +- `customErrorMsg` **any** + +### expectDeepMembers + +expects members of two arrays are deeply equal + +#### Parameters + +- `actualValue` **any** +- `expectedValue` **any** +- `customErrorMsg` **any** + +### expectEmpty + +#### Parameters + +- `targetData` **any** +- `customErrorMsg` **any** + +### expectEndsWith + +#### Parameters + +- `actualValue` **any** +- `expectedValueToEndWith` **any** +- `customErrorMsg` **any** + +### expectEqual + +#### Parameters + +- `actualValue` **any** +- `expectedValue` **any** +- `customErrorMsg` **any** + +### expectEqualIgnoreCase + +#### Parameters + +- `actualValue` **any** +- `expectedValue` **any** +- `customErrorMsg` **any** + +### expectFalse + +#### Parameters + +- `targetData` **any** +- `customErrorMsg` **any** + +### expectHasAProperty + +#### Parameters + +- `targetData` **any** +- `propertyName` **any** +- `customErrorMsg` **any** + +### expectHasProperty + +#### Parameters + +- `targetData` **any** +- `propertyName` **any** +- `customErrorMsg` **any** + +### expectJsonSchema + +#### Parameters + +- `targetData` **any** +- `jsonSchema` **any** +- `customErrorMsg` **any** + +### expectJsonSchemaUsingAJV + +#### Parameters + +- `targetData` **any** +- `jsonSchema` **any** +- `customErrorMsg` **any** +- `ajvOptions` **any** Pass AJV options + +### expectLengthAboveThan + +#### Parameters + +- `targetData` **any** +- `lengthAboveThan` **any** +- `customErrorMsg` **any** + +### expectLengthBelowThan + +#### Parameters + +- `targetData` **any** +- `lengthBelowThan` **any** +- `customErrorMsg` **any** + +### expectLengthOf + +#### Parameters + +- `targetData` **any** +- `length` **any** +- `customErrorMsg` **any** + +### expectMatchesPattern + +expects a JSON object matches a provided pattern + +#### Parameters + +- `actualValue` **any** +- `expectedPattern` **any** +- `customErrorMsg` **any** + +### expectMatchRegex + +#### Parameters + +- `targetData` **any** +- `regex` **any** +- `customErrorMsg` **any** + +### expectNotContain + +#### Parameters + +- `actualValue` **any** +- `expectedValueToNotContain` **any** +- `customErrorMsg` **any** + +### expectNotDeepEqual + +#### Parameters + +- `actualValue` **any** +- `expectedValue` **any** +- `customErrorMsg` **any** + +### expectNotEndsWith + +#### Parameters + +- `actualValue` **any** +- `expectedValueToNotEndWith` **any** +- `customErrorMsg` **any** + +### expectNotEqual + +#### Parameters + +- `actualValue` **any** +- `expectedValue` **any** +- `customErrorMsg` **any** + +### expectNotStartsWith + +#### Parameters + +- `actualValue` **any** +- `expectedValueToNotStartWith` **any** +- `customErrorMsg` **any** + +### expectStartsWith + +#### Parameters + +- `actualValue` **any** +- `expectedValueToStartWith` **any** +- `customErrorMsg` **any** + +### expectToBeA + +#### Parameters + +- `targetData` **any** +- `type` **any** +- `customErrorMsg` **any** + +### expectToBeAn + +#### Parameters + +- `targetData` **any** +- `type` **any** +- `customErrorMsg` **any** + +### expectTrue + +#### Parameters + +- `targetData` **any** +- `customErrorMsg` **any** diff --git a/lib/cli.js b/lib/cli.js index 0537be8e2..832f755db 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -106,7 +106,9 @@ class Cli extends Base { } currentMetaStep = metaSteps; output.stepShift = 3 + 2 * shift; - output.step(step); + if (step.helper.constructor.name !== 'ExpectHelper') { + output.step(step); + } }); event.dispatcher.on(event.step.finished, () => { diff --git a/lib/helper/Expect.js b/lib/helper/Expect.js new file mode 100644 index 000000000..4a385f505 --- /dev/null +++ b/lib/helper/Expect.js @@ -0,0 +1,422 @@ +const chai = require('chai'); +const output = require('../output'); + +const { expect } = chai; + +chai.use(require('chai-string')); +// @ts-ignore +chai.use(require('chai-exclude')); +chai.use(require('chai-match-pattern')); + +/** + * This helper allows performing assertions based on Chai. + * + * ### Examples + * + * Zero-configuration when paired with other helpers like REST, Playwright: + * + * ```js + * // inside codecept.conf.js + *{ + * helpers: { + * Playwright: {...}, + * ExpectHelper: {}, + * } + *} + * ``` + * + * ## Methods + */ +class ExpectHelper { + /** + * + * @param {*} actualValue + * @param {*} expectedValue + * @param {*} customErrorMsg + */ + expectEqual(actualValue, expectedValue, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to equal "${JSON.stringify(expectedValue)}"`); + return expect(actualValue, customErrorMsg).to.equal(expectedValue); + } + + /** + * + * @param {*} actualValue + * @param {*} expectedValue + * @param {*} customErrorMsg + */ + expectNotEqual(actualValue, expectedValue, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to not equal "${JSON.stringify(expectedValue)}"`); + return expect(actualValue, customErrorMsg).not.to.equal(expectedValue); + } + + /** + * + * @param {*} actualValue + * @param {*} expectedValue + * @param {*} customErrorMsg + + */ + expectDeepEqual(actualValue, expectedValue, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to deep equal "${JSON.stringify(expectedValue)}"`); + return expect(actualValue, customErrorMsg).to.deep.equal(expectedValue); + } + + /** + * + * @param {*} actualValue + * @param {*} expectedValue + * @param {*} customErrorMsg + */ + expectNotDeepEqual(actualValue, expectedValue, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to not deep equal "${JSON.stringify(expectedValue)}"`); + return expect(actualValue, customErrorMsg).to.not.deep.equal(expectedValue); + } + + /** + * + * @param {*} actualValue + * @param {*} expectedValueToContain + * @param {*} customErrorMsg + */ + expectContain(actualValue, expectedValueToContain, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to contain "${JSON.stringify(expectedValueToContain)}"`); + return expect(actualValue, customErrorMsg).to.contain( + expectedValueToContain, + ); + } + + /** + * + * @param {*} actualValue + * @param {*} expectedValueToNotContain + * @param {*} customErrorMsg + */ + expectNotContain( + actualValue, + expectedValueToNotContain, + customErrorMsg = '', + ) { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to not contain "${JSON.stringify(expectedValueToNotContain)}"`); + return expect(actualValue, customErrorMsg).not.to.contain( + expectedValueToNotContain, + ); + } + + /** + * + * @param {*} actualValue + * @param {*} expectedValueToStartWith + * @param {*} customErrorMsg + */ + expectStartsWith(actualValue, expectedValueToStartWith, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to start with "${JSON.stringify(expectedValueToStartWith)}"`); + return expect(actualValue, customErrorMsg).to.startsWith( + expectedValueToStartWith, + ); + } + + /** + * + * @param {*} actualValue + * @param {*} expectedValueToNotStartWith + * @param {*} customErrorMsg + */ + expectNotStartsWith( + actualValue, + expectedValueToNotStartWith, + customErrorMsg = '', + ) { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to not start with "${JSON.stringify(expectedValueToNotStartWith)}"`); + return expect(actualValue, customErrorMsg).not.to.startsWith( + expectedValueToNotStartWith, + ); + } + + /** + * @param {*} actualValue + * @param {*} expectedValueToEndWith + * @param {*} customErrorMsg + */ + expectEndsWith(actualValue, expectedValueToEndWith, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to end with "${JSON.stringify(expectedValueToEndWith)}"`); + return expect(actualValue, customErrorMsg).to.endsWith( + expectedValueToEndWith, + ); + } + + /** + * @param {*} actualValue + * @param {*} expectedValueToNotEndWith + * @param {*} customErrorMsg + */ + expectNotEndsWith( + actualValue, + expectedValueToNotEndWith, + customErrorMsg = '', + ) { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to not end with "${JSON.stringify(expectedValueToNotEndWith)}"`); + return expect(actualValue, customErrorMsg).not.to.endsWith( + expectedValueToNotEndWith, + ); + } + + /** + * @param {*} targetData + * @param {*} jsonSchema + * @param {*} customErrorMsg + */ + expectJsonSchema(targetData, jsonSchema, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to match this JSON schema "${JSON.stringify(jsonSchema)}"`); + chai.use(require('chai-json-schema')); + return expect(targetData, customErrorMsg).to.be.jsonSchema(jsonSchema); + } + + /** + * @param {*} targetData + * @param {*} jsonSchema + * @param {*} customErrorMsg + * @param {*} ajvOptions Pass AJV options + */ + expectJsonSchemaUsingAJV( + targetData, + jsonSchema, + customErrorMsg = '', + ajvOptions = { allErrors: true }, + ) { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to match this JSON schema using AJV "${JSON.stringify(jsonSchema)}"`); + chai.use(require('chai-json-schema-ajv').create(ajvOptions)); + return expect(targetData, customErrorMsg).to.be.jsonSchema(jsonSchema); + } + + /** + * @param {*} targetData + * @param {*} propertyName + * @param {*} customErrorMsg + */ + expectHasProperty(targetData, propertyName, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to have property: "${JSON.stringify(propertyName)}"`); + return expect(targetData, customErrorMsg).to.have.property(propertyName); + } + + /** + * @param {*} targetData + * @param {*} propertyName + * @param {*} customErrorMsg + */ + expectHasAProperty(targetData, propertyName, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to have a property: "${JSON.stringify(propertyName)}"`); + return expect(targetData, customErrorMsg).to.have.a.property(propertyName); + } + + /** + * @param {*} targetData + * @param {*} type + * @param {*} customErrorMsg + */ + expectToBeA(targetData, type, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to be a "${JSON.stringify(type)}"`); + return expect(targetData, customErrorMsg).to.be.a(type); + } + + /** + * @param {*} targetData + * @param {*} type + * @param {*} customErrorMsg + */ + expectToBeAn(targetData, type, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to be an "${JSON.stringify(type)}"`); + return expect(targetData, customErrorMsg).to.be.an(type); + } + + /** + * @param {*} targetData + * @param {*} regex + * @param {*} customErrorMsg + */ + expectMatchRegex(targetData, regex, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to match the regex "${JSON.stringify(regex)}"`); + return expect(targetData, customErrorMsg).to.match(regex); + } + + /** + * @param {*} targetData + * @param {*} length + * @param {*} customErrorMsg + */ + expectLengthOf(targetData, length, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to have length of "${JSON.stringify(length)}"`); + return expect(targetData, customErrorMsg).to.have.lengthOf(length); + } + + /** + * @param {*} targetData + * @param {*} customErrorMsg + */ + expectEmpty(targetData, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to be empty`); + return expect(targetData, customErrorMsg).to.be.empty; + } + + /** + * @param {*} targetData + * @param {*} customErrorMsg + */ + expectTrue(targetData, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to be true`); + return expect(targetData, customErrorMsg).to.be.true; + } + + /** + * @param {*} targetData + * @param {*} customErrorMsg + */ + expectFalse(targetData, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to be false`); + return expect(targetData, customErrorMsg).to.be.false; + } + + /** + * @param {*} targetData + * @param {*} aboveThan number | Date + * @param {*} customErrorMsg + */ + expectAbove(targetData, aboveThan, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to be above ${JSON.stringify(aboveThan)}`); + return expect(targetData, customErrorMsg).to.be.above(aboveThan); + } + + /** + * @param {*} targetData + * @param {*} belowThan number | Date + * @param {*} customErrorMsg + */ + expectBelow(targetData, belowThan, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to be below ${JSON.stringify(belowThan)}`); + return expect(targetData, customErrorMsg).to.be.below(belowThan); + } + + /** + * @param {*} targetData + * @param {*} lengthAboveThan + * @param {*} customErrorMsg + */ + expectLengthAboveThan(targetData, lengthAboveThan, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to have length of above ${JSON.stringify(lengthAboveThan)}`); + return expect(targetData, customErrorMsg).to.have.lengthOf.above( + lengthAboveThan, + ); + } + + /** + * @param {*} targetData + * @param {*} lengthBelowThan + * @param {*} customErrorMsg + */ + expectLengthBelowThan(targetData, lengthBelowThan, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(targetData)}" to have length of below ${JSON.stringify(lengthBelowThan)}`); + return expect(targetData, customErrorMsg).to.have.lengthOf.below( + lengthBelowThan, + ); + } + + /** + * @param {*} actualValue + * @param {*} expectedValue + * @param {*} customErrorMsg + */ + expectEqualIgnoreCase(actualValue, expectedValue, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect and ingore case "${JSON.stringify(actualValue)}" to equal "${JSON.stringify(expectedValue)}"`); + return expect(actualValue, customErrorMsg).to.equalIgnoreCase( + expectedValue, + ); + } + + /** + * expects members of two arrays are deeply equal + * @param {*} actualValue + * @param {*} expectedValue + * @param {*} customErrorMsg + */ + expectDeepMembers(actualValue, expectedValue, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect members of "${JSON.stringify(actualValue)}" and "${JSON.stringify(expectedValue)}" arrays are deeply equal`); + return expect(actualValue, customErrorMsg).to.have.deep.members( + expectedValue, + ); + } + + /** + * expects an array to be a superset of another array + * @param {*} superset + * @param {*} set + * @param {*} customErrorMsg + */ + expectDeepIncludeMembers(superset, set, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(superset)}" array to be a superset of "${JSON.stringify(set)}" array`); + return expect(superset, customErrorMsg).to.deep.include.members( + set, + ); + } + + /** + * expects members of two JSON objects are deeply equal excluding some properties + * @param {*} actualValue + * @param {*} expectedValue + * @param {*} fieldsToExclude + * @param {*} customErrorMsg + */ + expectDeepEqualExcluding( + actualValue, + expectedValue, + fieldsToExclude, + customErrorMsg = '', + ) { + // @ts-ignore + output.step(`I expect members of "${JSON.stringify(actualValue)}" and "${JSON.stringify(expectedValue)}" JSON objects are deeply equal excluding properties: ${JSON.stringify(fieldsToExclude)}`); + return expect(actualValue, customErrorMsg) + .excludingEvery(fieldsToExclude) + .to.deep.equal(expectedValue); + } + + /** + * expects a JSON object matches a provided pattern + * @param {*} actualValue + * @param {*} expectedPattern + * @param {*} customErrorMsg + */ + expectMatchesPattern(actualValue, expectedPattern, customErrorMsg = '') { + // @ts-ignore + output.step(`I expect "${JSON.stringify(actualValue)}" to match the ${JSON.stringify(expectedPattern)} pattern`); + return expect(actualValue, customErrorMsg).to.matchPattern(expectedPattern); + } +} + +module.exports = ExpectHelper; diff --git a/lib/output.js b/lib/output.js index b20830fd8..72aa3a053 100644 --- a/lib/output.js +++ b/lib/output.js @@ -106,7 +106,7 @@ module.exports = { if (!step) return; // Avoid to print non-gherkin steps, when gherkin is running for --steps mode if (outputLevel === 1) { - if (step.hasBDDAncestor()) { + if (typeof step === 'object' && step.hasBDDAncestor()) { return; } } diff --git a/package.json b/package.json index 2c3dadd72..fdaff3ea0 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "test:unit:webbapi:puppeteer": "mocha test/helper/Puppeteer_test.js", "test:unit:webbapi:webDriver": "mocha test/helper/WebDriver_test.js", "test:unit:webbapi:testCafe": "mocha test/helper/TestCafe_test.js", + "test:unit:expect": "mocha test/helper/Expect_test.js", "def": "./runok.js def", "dev:graphql": "node test/data/graphql/index.js", "publish:site": "./runok.js publish:site", @@ -70,6 +71,11 @@ "axios": "1.3.3", "chai": "4.3.8", "chai-deep-match": "1.2.1", + "chai-exclude": "^2.1.0", + "chai-json-schema": "^1.5.1", + "chai-json-schema-ajv": "^5.2.4", + "chai-match-pattern": "^1.3.0", + "chai-string": "^1.5.0", "chalk": "4.1.2", "commander": "11.0.0", "cross-spawn": "7.0.3", @@ -104,6 +110,7 @@ "@faker-js/faker": "7.6.0", "@pollyjs/adapter-puppeteer": "6.0.6", "@pollyjs/core": "5.1.0", + "@types/chai": "^4.3.7", "@types/inquirer": "9.0.3", "@types/node": "20.4.4", "@wdio/sauce-service": "8.3.8", @@ -153,4 +160,4 @@ "npm": ">=5.6.0" }, "es6": true -} \ No newline at end of file +} diff --git a/test/helper/Expect_test.js b/test/helper/Expect_test.js new file mode 100644 index 000000000..75f9e02ec --- /dev/null +++ b/test/helper/Expect_test.js @@ -0,0 +1,421 @@ +const path = require('path'); +const { expect } = require('chai'); +const ExpectHelper = require('../../lib/helper/Expect'); + +global.codeceptjs = require('../../lib'); + +let I; + +const goodApple = { + skin: 'thin', + colors: ['red', 'green', 'yellow'], + taste: 10, +}; +const badApple = { + colors: ['brown'], + taste: 0, + worms: 2, +}; +const fruitSchema = { + title: 'fresh fruit schema v1', + type: 'object', + required: ['skin', 'colors', 'taste'], + properties: { + colors: { + type: 'array', + minItems: 1, + uniqueItems: true, + items: { + type: 'string', + }, + }, + skin: { + type: 'string', + }, + taste: { + type: 'number', + minimum: 5, + }, + }, +}; + +describe('Expect Helper', function () { + this.timeout(3000); + this.retries(1); + + before(() => { + global.codecept_dir = path.join(__dirname, '/../data'); + + I = new ExpectHelper(); + }); + + describe('#expectEqual', () => { + it('should not show error', () => { + I.expectEqual('a', 'a'); + }); + + it('should show error', () => { + try { + I.expectEqual('a', 'b'); + } catch (e) { + expect(e.message).to.eq('expected \'a\' to equal \'b\''); + } + }); + }); + + describe('#expectNotEqual', () => { + it('should not show error', () => { + I.expectNotEqual('a', 'b'); + }); + + it('should show error', () => { + try { + I.expectNotEqual('a', 'a'); + } catch (e) { + expect(e.message).to.eq('expected \'a\' to not equal \'a\''); + } + }); + }); + + describe('#expectContain', () => { + it('should not show error', () => { + I.expectContain('abc', 'a'); + }); + + it('should show error', () => { + try { + I.expectContain('abc', 'd'); + } catch (e) { + expect(e.message).to.eq('expected \'abc\' to include \'d\''); + } + }); + }); + + describe('#expectNotContain', () => { + it('should not show error', () => { + I.expectNotContain('abc', 'd'); + }); + + it('should show error', () => { + try { + I.expectNotContain('abc', 'a'); + } catch (e) { + expect(e.message).to.eq('expected \'abc\' to not include \'a\''); + } + }); + }); + + describe('#expectStartsWith', () => { + it('should not show error', () => { + I.expectStartsWith('abc', 'a'); + }); + + it('should show error', () => { + try { + I.expectStartsWith('abc', 'b'); + } catch (e) { + expect(e.message).to.eq('expected abc to start with b'); + } + }); + }); + + describe('#expectNotStartsWith', () => { + it('should not show error', () => { + I.expectNotStartsWith('abc', 'b'); + }); + + it('should show error', () => { + try { + I.expectNotStartsWith('abc', 'a'); + } catch (e) { + expect(e.message).to.eq('expected abc not to start with a'); + } + }); + }); + + describe('#expectEndsWith', () => { + it('should not show error', () => { + I.expectEndsWith('abc', 'c'); + }); + + it('should show error', () => { + try { + I.expectEndsWith('abc', 'd'); + } catch (e) { + expect(e.message).to.eq('expected abc to end with d'); + } + }); + }); + + describe('#expectNotEndsWith', () => { + it('should not show error', () => { + I.expectNotEndsWith('abc', 'd'); + }); + + it('should show error', () => { + try { + I.expectNotEndsWith('abc', 'd'); + } catch (e) { + expect(e.message).to.eq('expected abc not to end with c'); + } + }); + }); + + describe('#expectJsonSchema', () => { + it('should not show error', () => { + I.expectJsonSchema(goodApple, fruitSchema); + }); + + it('should show error', () => { + try { + I.expectJsonSchema(badApple, fruitSchema); + } catch (e) { + expect(e.message).to.contain('expected value to match json-schema'); + } + }); + }); + + describe('#expectHasProperty', () => { + it('should not show error', () => { + I.expectHasProperty(goodApple, 'skin'); + }); + + it('should show error', () => { + try { + I.expectHasProperty(badApple, 'skin'); + } catch (e) { + expect(e.message).to.contain('expected { Object (colors, taste'); + } + }); + }); + + describe('#expectHasAProperty', () => { + it('should not show error', () => { + I.expectHasAProperty(goodApple, 'skin'); + }); + + it('should show error', () => { + try { + I.expectHasAProperty(badApple, 'skin'); + } catch (e) { + expect(e.message).to.contain('expected { Object (colors, taste'); + } + }); + }); + + describe('#expectToBeA', () => { + it('should not show error', () => { + I.expectToBeA(goodApple, 'object'); + }); + }); + + describe('#expectToBeAn', () => { + it('should not show error', () => { + I.expectToBeAn(goodApple, 'object'); + }); + + it('should show error', () => { + try { + I.expectToBeAn(badApple, 'skin'); + } catch (e) { + expect(e.message).to.contain('expected { Object (colors, taste'); + } + }); + }); + + describe('#expectMatchRegex', () => { + it('should not show error', () => { + I.expectMatchRegex('goodApple', /good/); + }); + + it('should show error', () => { + try { + I.expectMatchRegex('Apple', /good/); + } catch (e) { + expect(e.message).to.contain('to match /good/'); + } + }); + }); + + describe('#expectLengthOf', () => { + it('should not show error', () => { + I.expectLengthOf('good', 4); + }); + + it('should show error', () => { + try { + I.expectLengthOf('Apple', 4); + } catch (e) { + expect(e.message).to.contain('to have a length'); + } + }); + }); + + describe('#expectTrue', () => { + it('should not show error', () => { + I.expectTrue(true); + }); + + it('should show error', () => { + try { + I.expectTrue(false); + } catch (e) { + expect(e.message).to.contain('expected false to be true'); + } + }); + }); + + describe('#expectEmpty', () => { + it('should not show error', () => { + I.expectEmpty(''); + }); + + it('should show error', () => { + try { + I.expectEmpty('false'); + } catch (e) { + expect(e.message).to.contain('expected \'false\' to be empty'); + } + }); + }); + + describe('#expectFalse', () => { + it('should not show error', () => { + I.expectFalse(false); + }); + + it('should show error', () => { + try { + I.expectFalse(true); + } catch (e) { + expect(e.message).to.contain('expected true to be false'); + } + }); + }); + + describe('#expectAbove', () => { + it('should not show error', () => { + I.expectAbove(2, 1); + }); + + it('should show error', () => { + try { + I.expectAbove(1, 2); + } catch (e) { + expect(e.message).to.contain('expected 1 to be above 2'); + } + }); + }); + + describe('#expectBelow', () => { + it('should not show error', () => { + I.expectBelow(1, 2); + }); + + it('should show error', () => { + try { + I.expectBelow(2, 1); + } catch (e) { + expect(e.message).to.contain('expected 2 to be below 1'); + } + }); + }); + + describe('#expectLengthAboveThan', () => { + it('should not show error', () => { + I.expectLengthAboveThan('hello', 4); + }); + + it('should show error', () => { + try { + I.expectLengthAboveThan('hello', 5); + } catch (e) { + expect(e.message).to.contain('to have a length above 5'); + } + }); + }); + + describe('#expectLengthBelowThan', () => { + it('should not show error', () => { + I.expectLengthBelowThan('hello', 6); + }); + + it('should show error', () => { + try { + I.expectLengthBelowThan('hello', 4); + } catch (e) { + expect(e.message).to.contain('to have a length below 4'); + } + }); + }); + + describe('#expectLengthBelowThan', () => { + it('should not show error', () => { + I.expectEqualIgnoreCase('hEllo', 'hello'); + }); + + it('should show error', () => { + try { + I.expectEqualIgnoreCase('hEllo', 'hell0'); + } catch (e) { + expect(e.message).to.contain('expected hEllo to equal hell0'); + } + }); + }); + + describe('#expectDeepMembers', () => { + it('should not show error', () => { + I.expectDeepMembers([1, 2, 3], [1, 2, 3]); + }); + + it('should show error', () => { + try { + I.expectDeepMembers([1, 2, 3], [3]); + } catch (e) { + expect(e.message).to.contain('expected [ 1, 2, 3 ] to have the same members'); + } + }); + }); + + describe('#expectDeepIncludeMembers', () => { + it('should not show error', () => { + I.expectDeepIncludeMembers([3, 4, 5, 6], [3, 4, 5]); + }); + + it('should show error', () => { + try { + I.expectDeepIncludeMembers([3, 4, 5], [3, 4, 5, 6]); + } catch (e) { + expect(e.message).to.contain('expected [ 3, 4, 5 ] to be a superset of [ 3, 4, 5, 6 ]'); + } + }); + }); + + describe('#expectDeepEqualExcluding', () => { + it('should not show error', () => { + I.expectDeepEqualExcluding({ a: 1, b: 2 }, { b: 2, a: 1, c: 3 }, 'c'); + }); + + it('should show error', () => { + try { + I.expectDeepEqualExcluding({ a: 1, b: 2 }, { b: 2, a: 1, c: 3 }, 'a'); + } catch (e) { + expect(e.message).to.contain('expected { b: 2 } to deeply equal'); + } + }); + }); + + describe('#expectLengthBelowThan', () => { + it('should not show error', () => { + I.expectMatchesPattern('123', /123/); + }); + + it('should show error', () => { + try { + I.expectMatchesPattern('123', /1235/); + } catch (e) { + expect(e.message).to.contain('didn\'t match target /1235/'); + } + }); + }); +});