From ba9598d6b0d4a03a69ccd4fee10cec7b266ce30a Mon Sep 17 00:00:00 2001 From: roy Date: Tue, 10 Jan 2017 21:31:29 +0200 Subject: [PATCH 1/9] adding support to es6 Set --- modules/Expectation.js | 10 ++++++++-- modules/TestUtils.js | 14 ++++++++++++++ modules/__tests__/toExclude-test.js | 26 +++++++++++++++++++++---- modules/__tests__/toInclude-test.js | 30 ++++++++++++++++++++++++++--- 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/modules/Expectation.js b/modules/Expectation.js index 6db296f..6aa8d1a 100644 --- a/modules/Expectation.js +++ b/modules/Expectation.js @@ -6,9 +6,11 @@ import { isA, isFunction, isArray, + isSet, isEqual, isObject, functionThrows, + setContains, arrayContains, objectContains, stringContains @@ -286,6 +288,8 @@ class Expectation { if (isArray(this.actual)) { contains = arrayContains(this.actual, value, compareValues) + } else if (isSet(this.actual)) { + contains = setContains(this.actual, value, compareValues) } else if (isObject(this.actual)) { contains = objectContains(this.actual, value, compareValues) } else if (typeof this.actual === 'string') { @@ -293,7 +297,7 @@ class Expectation { } else { assert( false, - 'The "actual" argument in expect(actual).toInclude() must be an array, object, or a string' + 'The "actual" argument in expect(actual).toInclude() must be an array, set, object, or a string' ) } @@ -320,6 +324,8 @@ class Expectation { if (isArray(this.actual)) { contains = arrayContains(this.actual, value, compareValues) + } else if (isSet(this.actual)) { + contains = setContains(this.actual, value, compareValues) } else if (isObject(this.actual)) { contains = objectContains(this.actual, value, compareValues) } else if (typeof this.actual === 'string') { @@ -327,7 +333,7 @@ class Expectation { } else { assert( false, - 'The "actual" argument in expect(actual).toExclude() must be an array, object, or a string' + 'The "actual" argument in expect(actual).toExclude() must be an array, set, object, or a string' ) } diff --git a/modules/TestUtils.js b/modules/TestUtils.js index 7d7ea31..e5f8f0e 100644 --- a/modules/TestUtils.js +++ b/modules/TestUtils.js @@ -27,6 +27,12 @@ export const isFunction = (object) => export const isArray = (object) => Array.isArray(object) +/** + * Returns true if the given object is a set. + */ +export const isSet = (object) => + object instanceof Set + /** * Returns true if the given object is an object. */ @@ -88,6 +94,14 @@ export const functionThrows = (fn, context, args, value) => { export const arrayContains = (array, value, compareValues) => array.some(item => compareValues(item, value) !== false) +/** + * Returns true if the given array contains the value, false + * otherwise. The compareValues function must return false to + * indicate a non-match. + */ +export const setContains = (set, value, compareValues) => + arrayContains([ ...set ], value, compareValues) + const ownEnumerableKeys = (object) => { if (typeof Reflect === 'object' && typeof Reflect.ownKeys === 'function') { return Reflect.ownKeys(object) diff --git a/modules/__tests__/toExclude-test.js b/modules/__tests__/toExclude-test.js index 40a10a2..30c3bab 100644 --- a/modules/__tests__/toExclude-test.js +++ b/modules/__tests__/toExclude-test.js @@ -1,10 +1,10 @@ import expect from '../index' describe('toExclude', () => { - it('requires the actual value to be an array or string', () => { + it('requires the actual value to be an array, set, object or string', () => { expect(() => { expect(1).toExclude(2) - }).toThrow(/must be an array, object, or a string/) + }).toThrow(/must be an array, set, object, or a string/) }) it('does not throw when an array does not contain the expected value', () => { @@ -19,9 +19,21 @@ describe('toExclude', () => { }).toThrow(/to exclude/) }) + it('does not throw when an array does not contain the expected value', () => { + expect(() => { + expect(new Set([ 1, 2, 3 ])).toExclude(4) + }).toNotThrow() + }) + + it('throws when a set contains the expected value', () => { + expect(() => { + expect(new Set([ 1, 2, 3 ])).toExclude(2) + }).toThrow(/to exclude/) + }) + it('throws when an object contains an expected object', () => { expect(() => { - expect({ a: 1 }).toExclude({ a: 1 }) + expect( { a: 1 }).toExclude({ a: 1 }) }).toThrow(/to exclude/) }) @@ -31,13 +43,19 @@ describe('toExclude', () => { }).toNotThrow() }) + it('does not throw when a set contains an unexpected object', () => { + expect(() => { + expect(new Set([ { a: 1 } ])).toExclude({ b: 2 }) + }).toNotThrow() + }) + it('does not throw when an object contains an expected object with an unexpected value', () => { expect(() => { expect({ a: 1 }).toExclude({ a: 2 }) }).toNotThrow() }) - it('does not throw when an array does not contain the expected value', () => { + it('does not throw when an string does not contain the expected value', () => { expect(() => { expect('hello world').toExclude('goodbye') }).toNotThrow() diff --git a/modules/__tests__/toInclude-test.js b/modules/__tests__/toInclude-test.js index bfec6eb..affa697 100644 --- a/modules/__tests__/toInclude-test.js +++ b/modules/__tests__/toInclude-test.js @@ -1,10 +1,10 @@ import expect from '../index' describe('toInclude', () => { - it('requires the actual value to be an array, object, or a string', () => { + it('requires the actual value to be an array, set, object, or a string', () => { expect(() => { expect(1).toInclude(2) - }).toThrow(/must be an array, object, or a string/) + }).toThrow(/must be an array, set, object, or a string/) }) it('does not throw when an array contains an expected integer', () => { @@ -19,7 +19,19 @@ describe('toInclude', () => { expect([ { a: 1 }, { c: 2 } ]).toInclude({ c: 2 }) }).toNotThrow() }) - + + it('does not throw when a set contains an expected integer', () => { + expect(() => { + expect(new Set([ 1, 2, 3 ])).toInclude(2) + }).toNotThrow() + }) + + it('does not throw when a set contains an expected object', () => { + expect(() => { + expect(new Set([ { a: 1 }, { c: 2} ])).toInclude({ c: 2 }) + }).toNotThrow() + }) + it('does not throw when an object contains an expected object', () => { expect(() => { expect({ a: 1, b: 2, c: 3 }).toInclude({ b: 2 }) @@ -118,6 +130,18 @@ describe('toInclude', () => { }).toThrow(/to include/) }) + it('throws when a set does not contain an expected integer', () => { + expect(() => { + expect(new Set([ 1, 2, 3 ])).toInclude(4) + }).toThrow(/to include/) + }) + + it('throws when a set does not contain an expected object', () => { + expect(() => { + expect(new Set([ { a: 1 }, { c: 2 } ])).toInclude({ a: 2 }) + }).toThrow(/to include/) + }) + it('does not throw when a string contains the expected value', () => { expect(() => { expect('hello world').toInclude('world') From 92945c8d34d01c32dd59988d1dee05640c716abb Mon Sep 17 00:00:00 2001 From: roy Date: Tue, 10 Jan 2017 23:10:18 +0200 Subject: [PATCH 2/9] change error message to original --- modules/Expectation.js | 4 ++-- modules/__tests__/toExclude-test.js | 4 ++-- modules/__tests__/toInclude-test.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/Expectation.js b/modules/Expectation.js index 6aa8d1a..240d395 100644 --- a/modules/Expectation.js +++ b/modules/Expectation.js @@ -297,7 +297,7 @@ class Expectation { } else { assert( false, - 'The "actual" argument in expect(actual).toInclude() must be an array, set, object, or a string' + 'The "actual" argument in expect(actual).toInclude() must be an array, object, or a string' ) } @@ -333,7 +333,7 @@ class Expectation { } else { assert( false, - 'The "actual" argument in expect(actual).toExclude() must be an array, set, object, or a string' + 'The "actual" argument in expect(actual).toExclude() must be an array, object, or a string' ) } diff --git a/modules/__tests__/toExclude-test.js b/modules/__tests__/toExclude-test.js index 30c3bab..a93ee39 100644 --- a/modules/__tests__/toExclude-test.js +++ b/modules/__tests__/toExclude-test.js @@ -1,10 +1,10 @@ import expect from '../index' describe('toExclude', () => { - it('requires the actual value to be an array, set, object or string', () => { + it('requires the actual value to be an array, object or string', () => { expect(() => { expect(1).toExclude(2) - }).toThrow(/must be an array, set, object, or a string/) + }).toThrow(/must be an array, object, or a string/) }) it('does not throw when an array does not contain the expected value', () => { diff --git a/modules/__tests__/toInclude-test.js b/modules/__tests__/toInclude-test.js index affa697..dfb789c 100644 --- a/modules/__tests__/toInclude-test.js +++ b/modules/__tests__/toInclude-test.js @@ -1,10 +1,10 @@ import expect from '../index' describe('toInclude', () => { - it('requires the actual value to be an array, set, object, or a string', () => { + it('requires the actual value to be an array, object, or a string', () => { expect(() => { expect(1).toInclude(2) - }).toThrow(/must be an array, set, object, or a string/) + }).toThrow(/must be an array, object, or a string/) }) it('does not throw when an array contains an expected integer', () => { From e74af00b1e2d5da6ad4527218608e1ef1e2610ca Mon Sep 17 00:00:00 2001 From: roy Date: Tue, 10 Jan 2017 23:11:22 +0200 Subject: [PATCH 3/9] Change isSet method to not use the instanceof operator --- modules/TestUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/TestUtils.js b/modules/TestUtils.js index e5f8f0e..51290fe 100644 --- a/modules/TestUtils.js +++ b/modules/TestUtils.js @@ -31,7 +31,7 @@ export const isArray = (object) => * Returns true if the given object is a set. */ export const isSet = (object) => - object instanceof Set + Object.prototype.toString.call(object) === '[object Set]' /** * Returns true if the given object is an object. From 8a9c0161037df6161a84e215f3e8e5dda94ccb0a Mon Sep 17 00:00:00 2001 From: roy Date: Wed, 11 Jan 2017 08:32:57 +0200 Subject: [PATCH 4/9] Fixing typo --- modules/__tests__/toExclude-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/__tests__/toExclude-test.js b/modules/__tests__/toExclude-test.js index a93ee39..2c0db71 100644 --- a/modules/__tests__/toExclude-test.js +++ b/modules/__tests__/toExclude-test.js @@ -55,7 +55,7 @@ describe('toExclude', () => { }).toNotThrow() }) - it('does not throw when an string does not contain the expected value', () => { + it('does not throw when a string does not contain the expected value', () => { expect(() => { expect('hello world').toExclude('goodbye') }).toNotThrow() From 84ca9bcfebf060546e1077ebb030774fbd2a99ef Mon Sep 17 00:00:00 2001 From: roy Date: Sat, 14 Jan 2017 10:45:45 +0200 Subject: [PATCH 5/9] Adding babel-polyfill for the tests to support IE8 --- karma.conf.js | 3 ++- package.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/karma.conf.js b/karma.conf.js index d0a7683..86a618e 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -50,11 +50,12 @@ module.exports = (config) => { config.set({ customLaunchers: customLaunchers, - browsers: [ 'Chrome' ], + browsers: [ 'Chrome', 'IE10 - Win8' ], frameworks: [ 'mocha' ], reporters: [ 'mocha' ], files: [ + 'node_modules/babel-polyfill/dist/polyfill.js', 'tests.webpack.js' ], diff --git a/package.json b/package.json index a6f66d3..6cd37f2 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "babel-cli": "^6.6.5", "babel-eslint": "^6.1.2", "babel-loader": "^6.2.4", + "babel-polyfill": "^6.20.0", "babel-preset-es2015": "^6.6.0", "eslint": "^3.2.2", "eslint-plugin-import": "^1.12.0", From d5c537ddc586212b2a04fd1a2777146d0c383dff Mon Sep 17 00:00:00 2001 From: roy Date: Sat, 14 Jan 2017 10:46:03 +0200 Subject: [PATCH 6/9] Changing name of test --- modules/__tests__/toExclude-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/__tests__/toExclude-test.js b/modules/__tests__/toExclude-test.js index 2c0db71..9b69fd0 100644 --- a/modules/__tests__/toExclude-test.js +++ b/modules/__tests__/toExclude-test.js @@ -19,7 +19,7 @@ describe('toExclude', () => { }).toThrow(/to exclude/) }) - it('does not throw when an array does not contain the expected value', () => { + it('does not throw when a set does not contain the expected value', () => { expect(() => { expect(new Set([ 1, 2, 3 ])).toExclude(4) }).toNotThrow() From e96bbc17a5c3e57808ba0fb12c9250157d279753 Mon Sep 17 00:00:00 2001 From: roy Date: Sat, 14 Jan 2017 10:46:37 +0200 Subject: [PATCH 7/9] Change logic on identifying Set object --- modules/TestUtils.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/modules/TestUtils.js b/modules/TestUtils.js index 51290fe..6638d70 100644 --- a/modules/TestUtils.js +++ b/modules/TestUtils.js @@ -27,11 +27,28 @@ export const isFunction = (object) => export const isArray = (object) => Array.isArray(object) + +const hasSet = typeof Set === 'function' && Set.prototype +const setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? + Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null +const setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' + ? setSizeDescriptor.get : null + /** * Returns true if the given object is a set. */ -export const isSet = (object) => - Object.prototype.toString.call(object) === '[object Set]' +export const isSet = (object) => { + if (!setSize) { + return false + } + try { + setSize.call(object) + return true + } catch (err) { + return false + } +} + /** * Returns true if the given object is an object. @@ -99,8 +116,14 @@ export const arrayContains = (array, value, compareValues) => * otherwise. The compareValues function must return false to * indicate a non-match. */ -export const setContains = (set, value, compareValues) => - arrayContains([ ...set ], value, compareValues) +export const setContains = (set, value, compareValues) => { + for (let item of set) { + if (compareValues(value, item)) { + return true + } + } + return false +} const ownEnumerableKeys = (object) => { if (typeof Reflect === 'object' && typeof Reflect.ownKeys === 'function') { From 5b3c102a59090d644601c5e3f6252d10b5d14682 Mon Sep 17 00:00:00 2001 From: roy Date: Sat, 14 Jan 2017 10:48:52 +0200 Subject: [PATCH 8/9] Revert local configuration --- karma.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/karma.conf.js b/karma.conf.js index 86a618e..285233c 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -50,7 +50,7 @@ module.exports = (config) => { config.set({ customLaunchers: customLaunchers, - browsers: [ 'Chrome', 'IE10 - Win8' ], + browsers: [ 'Chrome' ], frameworks: [ 'mocha' ], reporters: [ 'mocha' ], From 32991738b6cc431d73f74058be7dbb2099a100b6 Mon Sep 17 00:00:00 2001 From: roy Date: Mon, 16 Jan 2017 20:48:26 +0200 Subject: [PATCH 9/9] Change the use of babel-polyfill with es6-shim. --- karma.conf.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 285233c..782da3a 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -55,7 +55,7 @@ module.exports = (config) => { reporters: [ 'mocha' ], files: [ - 'node_modules/babel-polyfill/dist/polyfill.js', + 'node_modules/es6-shim/es6-shim.js', 'tests.webpack.js' ], diff --git a/package.json b/package.json index 6cd37f2..fdd0e03 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ "babel-cli": "^6.6.5", "babel-eslint": "^6.1.2", "babel-loader": "^6.2.4", - "babel-polyfill": "^6.20.0", "babel-preset-es2015": "^6.6.0", + "es6-shim": "^0.35.2", "eslint": "^3.2.2", "eslint-plugin-import": "^1.12.0", "gzip-size": "^3.0.0",