From 7755150cf3c216619e5641268e170dea584794cb Mon Sep 17 00:00:00 2001 From: Lukas Taegert Date: Sat, 27 May 2017 23:37:59 +0200 Subject: [PATCH 1/4] feat(bundle): Switch to using a rollup ES6 bundle --- .gitignore | 61 +------------ build.js | 34 ++++++++ package.json | 24 +++-- src/constructors.js | 108 ++++++++++------------- src/index.js | 75 ++++++++-------- test/index.spec.js | 208 ++++++++++++++++++++++---------------------- 6 files changed, 239 insertions(+), 271 deletions(-) create mode 100644 build.js diff --git a/.gitignore b/.gitignore index d23365d..67ccce4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,60 +1,3 @@ -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - +node_modules/ .idea/ - -## File-based project format: -*.iws -*.iml - -## Plugin-specific files: - -# IntelliJ -/out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -### Node template -# Logs -logs -*.log -npm-debug.log* - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules -jspm_packages - -# Optional npm cache directory -.npm - -# Optional REPL history -.node_repl_history - +dist/ diff --git a/build.js b/build.js new file mode 100644 index 0000000..f3cf310 --- /dev/null +++ b/build.js @@ -0,0 +1,34 @@ +const rollup = require('rollup') +const resolve = require('rollup-plugin-node-resolve') +const commonjs = require('rollup-plugin-commonjs') +const babel = require('rollup-plugin-babel') + +rollup.rollup({ + entry: 'src/index.js', + external: ['sinon'], + plugins: [ + resolve({jsnext: true, module: true}), + commonjs(), + babel({ + presets: [ + ['env', { + modules: false, + targets: {node: 4} + }] + ], + plugins: [ + 'ramda', + 'external-helpers' + ] + }) + ] +}).then(bundle => { + bundle.write({ + dest: 'dist/index.js', + format: 'cjs' + }) + bundle.write({ + dest: 'dist/index.mjs', + format: 'es' + }) +}) diff --git a/package.json b/package.json index c453975..9c69ec0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,12 @@ "description": "Create easily configurable sinon stubs that mimic constructors and keep track of their instances", "author": "Lukas Taegert ", "license": "MIT", - "main": "src/index.js", + "main": "dist/index.js", + "module": "dist/index.mjs", + "jsnext:main": "dist/index.mjs", + "files": [ + "dist" + ], "config": { "validate-commit-msg": { "types": [ @@ -36,25 +41,32 @@ "sinon": ">=1.15.0" }, "dependencies": { - "fluent-arguments": ">= 1.0.6", - "ramda": ">= 0.23.0" + "fluent-arguments": "^1.0.7", + "ramda": "^0.23.0" }, "devDependencies": { + "babel-plugin-external-helpers": "^6.22.0", + "babel-plugin-ramda": "^1.2.0", + "babel-preset-env": "^1.5.1", "chai": "^4.0.0", "codecov": "^2.2.0", "husky": "^0.13.3", "istanbul": "^0.4.5", "lint-staged": "^3.5.0", "mocha": "^3.4.2", + "rollup": "^0.41.6", + "rollup-plugin-babel": "^2.7.1", + "rollup-plugin-commonjs": "^8.0.2", + "rollup-plugin-node-resolve": "^3.0.0", "semantic-release": "^6.3.6", - "standard": "^10.0.2", "sinon": "^2.3.2", + "standard": "^10.0.2", "validate-commit-msg": "^2.12.1" }, "scripts": { - "test": "mocha", + "test": "node build && mocha", "lint": "standard", - "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "semantic-release": "npm install && node build && semantic-release pre && npm publish && semantic-release post", "precommit": "lint-staged", "commitmsg": "validate-commit-msg", "prepush": "npm test", diff --git a/src/constructors.js b/src/constructors.js index ee48de0..40166f6 100644 --- a/src/constructors.js +++ b/src/constructors.js @@ -1,31 +1,27 @@ -var R = require('ramda') -var fa = require('fluent-arguments') +import fa from 'fluent-arguments' +import R from 'ramda' -function getArrayFromArrayLikeObject (args) { - return Array.prototype.slice.call(args) -} +const getArrayFromArrayLikeObject = args => Array.prototype.slice.call(args) -var isMethod = R.curry(function (object, propName) { - return !Object.getOwnPropertyDescriptor(object, propName).get && - typeof object[propName] === 'function' && !(propName === 'constructor') -}) +const isMethod = R.curry((object, propName) => +!Object.getOwnPropertyDescriptor(object, propName).get && +typeof object[propName] === 'function' && +!(propName === 'constructor')) -var applyToEachFunctionKeyInObject = function (appliedFunction, object) { - R.compose( - R.forEach(appliedFunction), - R.filter(isMethod(object)) - )(Object.getOwnPropertyNames(object)) -} +const applyToEachFunctionKeyInObject = (appliedFunction, object) => R.compose( + R.forEach(appliedFunction), + R.filter(isMethod(object)) +)(Object.getOwnPropertyNames(object)) -var applyToEachFunctionKeyInPrototypeChain = function (appliedFunction, object) { +const applyToEachFunctionKeyInPrototypeChain = (appliedFunction, object) => { if (object) { applyToEachFunctionKeyInObject(appliedFunction, object) applyToEachFunctionKeyInPrototypeChain(appliedFunction, Object.getPrototypeOf(object)) } } -var getInstanceIndexWithValidation = function (index, numInstances) { - var instanceIndex = index || 0 +const getInstanceIndexWithValidation = (index, numInstances) => { + const instanceIndex = index || 0 if (typeof index === 'undefined') { if (numInstances > 1) { @@ -40,56 +36,44 @@ var getInstanceIndexWithValidation = function (index, numInstances) { return instanceIndex } -module.exports = function getStubOrSpyConstructor (getConstructorProperties) { - return function (Target) { - var constructorProps = getConstructorProperties(Target) - var instances = [] - var instanceArgs = [] - var methodParams = [] - var afterCreation - - function StubOrSpyConstructor () { - constructorProps.SourceConstructor.apply(this, arguments) - instanceArgs.push(getArrayFromArrayLikeObject(arguments)) - instances.push(this) - - Target && applyToEachFunctionKeyInPrototypeChain( - constructorProps.processMethodOfInstance(this), constructorProps.getInstanceMethodNameSource(this)) - methodParams.forEach(constructorProps.configureMethodOfInstance(this)) - afterCreation && afterCreation(this) - } - - StubOrSpyConstructor.prototype = constructorProps.SourceConstructor.prototype +export default getConstructorProperties => Target => { + const constructorProps = getConstructorProperties(Target) + const instances = [] + const instanceArgs = [] + let methodParams = [] + let afterCreation + + function StubOrSpyConstructor () { + constructorProps.SourceConstructor.apply(this, arguments) + instanceArgs.push(getArrayFromArrayLikeObject(arguments)) + instances.push(this) + + Target && applyToEachFunctionKeyInPrototypeChain( + constructorProps.processMethodOfInstance(this), constructorProps.getInstanceMethodNameSource(this)) + methodParams.forEach(constructorProps.configureMethodOfInstance(this)) + afterCreation && afterCreation(this) + } - function configureMethods (methods) { - methodParams = methods - return this - } + StubOrSpyConstructor.prototype = constructorProps.SourceConstructor.prototype - StubOrSpyConstructor[constructorProps.configureMethodsKey] = fa.createFunc(configureMethods) + StubOrSpyConstructor[constructorProps.configureMethodsKey] = fa.createFunc(function (methods) { + methodParams = methods + return this + }) - StubOrSpyConstructor.afterCreation = function (onAfterCreation) { - afterCreation = onAfterCreation - return this - } + StubOrSpyConstructor.afterCreation = function (onAfterCreation) { + afterCreation = onAfterCreation + return this + } - StubOrSpyConstructor.getInstances = function () { - return instances - } + StubOrSpyConstructor.getInstances = () => instances - StubOrSpyConstructor.getInstance = function (index) { - return instances[getInstanceIndexWithValidation(index, instances.length)] - } + StubOrSpyConstructor.getInstance = index => instances[getInstanceIndexWithValidation(index, instances.length)] - StubOrSpyConstructor.getInstancesArgs = function () { - return instanceArgs - } + StubOrSpyConstructor.getInstancesArgs = () => instanceArgs - StubOrSpyConstructor.getInstanceArgs = function (index) { - return instanceArgs[getInstanceIndexWithValidation(index, instances.length)] - } + StubOrSpyConstructor.getInstanceArgs = index => instanceArgs[getInstanceIndexWithValidation(index, instances.length)] - Target && applyToEachFunctionKeyInObject(constructorProps.processMethodOfConstructor(StubOrSpyConstructor), Target) - return StubOrSpyConstructor - } + Target && applyToEachFunctionKeyInObject(constructorProps.processMethodOfConstructor(StubOrSpyConstructor), Target) + return StubOrSpyConstructor } diff --git a/src/index.js b/src/index.js index 7ccb5a7..add55c9 100644 --- a/src/index.js +++ b/src/index.js @@ -1,39 +1,40 @@ -var getStubOrSpyConstructor = require('./constructors') -var R = require('ramda') -var fa = require('fluent-arguments') -var sinon = require('sinon') -var ARG_RETURN_VAL = 'returnVal' -var ARG_RETURN_THIS = 'returnThis' +import fa from 'fluent-arguments' +import R from 'ramda' +import sinon from 'sinon' +import getStubOrSpyConstructor from './constructors' -var setMethodToStub = R.curry(function (object, methodName) { +const ARG_RETURN_VAL = 'returnVal' +const ARG_RETURN_THIS = 'returnThis' + +const setMethodToStub = R.curry((object, methodName) => { object[methodName] = sinon.stub() }) -function configureStub (object, params) { +const configureStub = (object, params) => { if (params.hasOwnProperty(ARG_RETURN_THIS)) { object[params.value].returnsThis() } else if (params.hasOwnProperty(ARG_RETURN_VAL)) { object[params.value].returns(params[ARG_RETURN_VAL]) } } -var setMethodToStubWithParams = R.curry(function (object, params) { +const setMethodToStubWithParams = R.curry((object, params) => { setMethodToStub(object, params.value) configureStub(object, params) }) -var stubMethodWithParams = R.curry(function (object, params) { +const stubMethodWithParams = R.curry((object, params) => { object[params.value] && object[params.value].restore && object[params.value].restore() sinon.stub(object, params.value) configureStub(object, params) }) -var spyOnMethod = R.curry(function (object, methodName) { +const spyOnMethod = R.curry((object, methodName) => { if (!(object[methodName] && object[methodName].isSinonProxy)) { sinon.spy(object, methodName) } }) -var copyAndSpyOnMethod = R.curry(function (object, source, methodName) { +const copyAndSpyOnMethod = R.curry((object, source, methodName) => { if (source[methodName].isSinonProxy) { object[methodName] = source[methodName] } else { @@ -41,39 +42,33 @@ var copyAndSpyOnMethod = R.curry(function (object, source, methodName) { } }) -function getStubConstructorProperties (Target) { - return { - SourceConstructor: function () {}, - processMethodOfInstance: setMethodToStub, - getInstanceMethodNameSource: function () { return Target.prototype }, - processMethodOfConstructor: function (TheConstructor) { return setMethodToStub(TheConstructor) }, - configureMethodsKey: 'withMethods', - configureMethodOfInstance: setMethodToStubWithParams - } -} +const getStubConstructorProperties = Target => ({ + SourceConstructor: function () {}, + processMethodOfInstance: setMethodToStub, + getInstanceMethodNameSource: () => Target.prototype, + processMethodOfConstructor: TheConstructor => setMethodToStub(TheConstructor), + configureMethodsKey: 'withMethods', + configureMethodOfInstance: setMethodToStubWithParams +}) -function getSpyConstructorProperties (Target) { - return { - SourceConstructor: Target, - processMethodOfInstance: spyOnMethod, - getInstanceMethodNameSource: function (instance) { return instance }, - processMethodOfConstructor: function (TheConstructor) { return copyAndSpyOnMethod(TheConstructor, Target) }, - configureMethodsKey: 'withStubs', - configureMethodOfInstance: stubMethodWithParams - } -} +const getSpyConstructorProperties = Target => ({ + SourceConstructor: Target, + processMethodOfInstance: spyOnMethod, + getInstanceMethodNameSource: instance => instance, + processMethodOfConstructor: TheConstructor => copyAndSpyOnMethod(TheConstructor, Target), + configureMethodsKey: 'withStubs', + configureMethodOfInstance: stubMethodWithParams +}) -function getMethodStubs (methodParams) { +function getMethodStubsHandler (methodParams) { var result = {} methodParams.forEach(setMethodToStubWithParams(result)) return result } -module.exports = { - getStubConstructor: getStubOrSpyConstructor(getStubConstructorProperties), - getSpyConstructor: getStubOrSpyConstructor(getSpyConstructorProperties), - getMethodStubs: fa.createFunc(getMethodStubs), - returning: fa.createArg({args: [ARG_RETURN_VAL], extendsPrevious: true}), - returningThis: fa.createArg({extra: {returnThis: true}, extendsPrevious: true}) -} +export const getStubConstructor = getStubOrSpyConstructor(getStubConstructorProperties) +export const getSpyConstructor = getStubOrSpyConstructor(getSpyConstructorProperties) +export const getMethodStubs = fa.createFunc(getMethodStubsHandler) +export const returning = fa.createArg({args: [ARG_RETURN_VAL], extendsPrevious: true}) +export const returningThis = fa.createArg({extra: {returnThis: true}, extendsPrevious: true}) diff --git a/test/index.spec.js b/test/index.spec.js index 2ea7c03..4dc0e2e 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -1,64 +1,64 @@ /* eslint-env mocha */ /* eslint-disable no-unused-expressions,no-new */ -var sinonHelpers = require('../src/index') -var getStubConstructor = sinonHelpers.getStubConstructor -var getSpyConstructor = sinonHelpers.getSpyConstructor -var getMethodStubs = sinonHelpers.getMethodStubs -var returning = sinonHelpers.returning -var returningThis = sinonHelpers.returningThis +const sinonHelpers = require('../dist/index') +const getStubConstructor = sinonHelpers.getStubConstructor +const getSpyConstructor = sinonHelpers.getSpyConstructor +const getMethodStubs = sinonHelpers.getMethodStubs +const returning = sinonHelpers.returning +const returningThis = sinonHelpers.returningThis -var expect = require('chai').expect -var sinon = require('sinon') +const expect = require('chai').expect +const sinon = require('sinon') -var TestConstructor +let TestConstructor -beforeEach(function () { +beforeEach(() => { global.sinon = sinon - var testPrototype2 = { - proto2: function () { return 'p2' }, - field1: function () { return 'pf1' } + const testPrototype2 = { + proto2: () => 'p2', + field1: () => 'pf1' } - var testPrototype1 = Object.create(testPrototype2, { - proto1: {writable: true, enumerable: false, value: function () { return 'p1' }} + const testPrototype1 = Object.create(testPrototype2, { + proto1: {writable: true, enumerable: false, value: () => 'p1'} }) // if this were defined in the object literal, it would be evaluated by Object.create Object.defineProperty(testPrototype1, 'protoGetter', - {get: function () { throw new Error('inherited getter was evaluated') }}) + {get: () => { throw new Error('inherited getter was evaluated') }}) - var testPrototype = Object.create(testPrototype1, { - field1: {writable: true, enumerable: true, value: function () { return 1 }}, - field2: {writable: true, enumerable: false, value: function () { return 2 }} + const testPrototype = Object.create(testPrototype1, { + field1: {writable: true, enumerable: true, value: () => 1}, + field2: {writable: true, enumerable: false, value: () => 2} }) TestConstructor = function () { this.args = Array.prototype.slice.call(arguments) - this.field3 = function () { return 3 } + this.field3 = () => 3 this.field4 = sinon.stub() - Object.defineProperty(this, 'getter', {get: function () { throw new Error('getter was evaluated') }}) + Object.defineProperty(this, 'getter', {get: () => { throw new Error('getter was evaluated') }}) } TestConstructor.prototype = testPrototype - TestConstructor.instanceMethod1 = function () { return 'i1' } + TestConstructor.instanceMethod1 = () => 'i1' TestConstructor.instanceMethod2 = sinon.stub() }) -afterEach(function () { +afterEach(() => { delete global.sinon }) -describe('getStubConstructor', function () { - var StubConstructor +describe('getStubConstructor', () => { + let StubConstructor - beforeEach(function () { + beforeEach(() => { StubConstructor = getStubConstructor(TestConstructor) }) - it('should return a constructor that creates an object with all methods of the prototype object', function () { - var stubbedObject = new StubConstructor() + it('should return a constructor that creates an object with all methods of the prototype object', () => { + const stubbedObject = new StubConstructor() expect(stubbedObject.field1).to.be.a('function', 'field1') expect(stubbedObject.field2).to.be.a('function', 'field2') @@ -66,61 +66,61 @@ describe('getStubConstructor', function () { expect(stubbedObject.proto2).to.be.a('function', 'proto2') }) - it('should not call through to the original constructor', function () { - var stubbedObject = new StubConstructor() + it('should not call through to the original constructor', () => { + const stubbedObject = new StubConstructor() expect(stubbedObject.field3).to.be.undefined }) - it('should create stubs for all instance methods', function () { + it('should create stubs for all instance methods', () => { expect(StubConstructor.instanceMethod1).to.have.property('isSinonProxy', true) expect(StubConstructor.instanceMethod1()).to.be.undefined expect(StubConstructor.instanceMethod2).to.have.property('isSinonProxy', true) }) - it('should create an empty constructor if no arguments are supplied', function () { + it('should create an empty constructor if no arguments are supplied', () => { StubConstructor = getStubConstructor() - var stubbedObject = new StubConstructor() + const stubbedObject = new StubConstructor() expect(stubbedObject).to.be.an('object') }) - describe('withMethods', function () { - it('should allow specifying additional methods', function () { + describe('withMethods', () => { + it('should allow specifying additional methods', () => { StubConstructor = StubConstructor.withMethods('m1', 'm2') - var stubbedObject = new StubConstructor() + const stubbedObject = new StubConstructor() expect(stubbedObject.m1).to.be.a('function', 'm1') expect(stubbedObject.m2).to.be.a('function', 'm2') }) - it('should allow specifying method return values', function () { + it('should allow specifying method return values', () => { StubConstructor = StubConstructor.withMethods('m1', returning(1), 'field1', returning(2), 'm2') - var stubbedObject = new StubConstructor() + const stubbedObject = new StubConstructor() expect(stubbedObject.m1()).to.equal(1, 'm1') expect(stubbedObject.field1()).to.equal(2, 'field1') expect(stubbedObject.m2()).to.be.undefined }) - it('should allow for methods to return their this value', function () { + it('should allow for methods to return their this value', () => { StubConstructor = StubConstructor.withMethods('m1', returningThis, 'field1', returningThis, 'm2') - var stubbedObject = new StubConstructor() + const stubbedObject = new StubConstructor() expect(stubbedObject.m1().field1().m2).to.be.a('function') }) }) }) -describe('getSpyConstructor', function () { - var SpyConstructor +describe('getSpyConstructor', () => { + let SpyConstructor - beforeEach(function () { + beforeEach(() => { SpyConstructor = getSpyConstructor(TestConstructor) }) - it('should return a constructor that creates an object with all methods the constructor creates', function () { - var spiedObject = new SpyConstructor() + it('should return a constructor that creates an object with all methods the constructor creates', () => { + const spiedObject = new SpyConstructor() expect(spiedObject.field1()).to.equal(1) expect(spiedObject.field2()).to.equal(2) @@ -129,18 +129,18 @@ describe('getSpyConstructor', function () { expect(spiedObject.proto2()).to.equal('p2') }) - it('should create instances of the original constructor', function () { - var spiedObject = new SpyConstructor() + it('should create instances of the original constructor', () => { + const spiedObject = new SpyConstructor() expect(spiedObject).to.be.an.instanceof(TestConstructor) }) - it('should create instances using the right arguments', function () { - var spiedObject = new SpyConstructor('Var 1', 2) + it('should create instances using the right arguments', () => { + const spiedObject = new SpyConstructor('Var 1', 2) expect(spiedObject.args).to.deep.equal(['Var 1', 2]) }) - it('should put spies on all methods', function () { - var spiedObject = new SpyConstructor() + it('should put spies on all methods', () => { + const spiedObject = new SpyConstructor() expect(spiedObject.field1).to.have.property('isSinonProxy', true, 'field1') expect(spiedObject.field2).to.have.property('isSinonProxy', true, 'field2') @@ -150,16 +150,16 @@ describe('getSpyConstructor', function () { expect(spiedObject.proto2).to.have.property('isSinonProxy', true, 'proto2') }) - it('should spy on all instance methods', function () { + it('should spy on all instance methods', () => { expect(SpyConstructor.instanceMethod1).to.have.property('isSinonProxy', true) expect(SpyConstructor.instanceMethod1()).to.equal('i1') expect(SpyConstructor.instanceMethod2).to.have.property('isSinonProxy', true) }) - describe('withStubs', function () { - it('should allow stubbing methods', function () { + describe('withStubs', () => { + it('should allow stubbing methods', () => { SpyConstructor = SpyConstructor.withStubs('field1', 'field3', 'proto1') - var spiedObject = new SpyConstructor() + const spiedObject = new SpyConstructor() expect(spiedObject.field1).to.have.property('isSinonProxy', true) expect(spiedObject.field3).to.have.property('isSinonProxy', true) @@ -169,26 +169,26 @@ describe('getSpyConstructor', function () { expect(spiedObject.proto1()).to.be.undefined }) - it('should allow specifying stub return values', function () { + it('should allow specifying stub return values', () => { SpyConstructor = SpyConstructor.withStubs('field1', returning(10), 'field3', returning(20), 'proto1') - var spiedObject = new SpyConstructor() + const spiedObject = new SpyConstructor() expect(spiedObject.field1()).to.equal(10, 'field1') expect(spiedObject.field3()).to.equal(20, 'field3') expect(spiedObject.proto1()).to.be.undefined }) - it('should allow for methods to return their this value', function () { + it('should allow for methods to return their this value', () => { SpyConstructor = SpyConstructor.withStubs('field1', returningThis, 'field3', returningThis, 'proto1') - var spiedObject = new SpyConstructor() + const spiedObject = new SpyConstructor() expect(spiedObject.field1().field3().proto1).to.be.a('function') }) }) }) -describe('getSpy- and getStubConstructor', function () { - var dataProvider = [{ +describe('getSpy- and getStubConstructor', () => { + const dataProvider = [{ description: 'getStubConstrucor', getConstructor: getStubConstructor }, { @@ -196,86 +196,86 @@ describe('getSpy- and getStubConstructor', function () { getConstructor: getSpyConstructor }] - dataProvider.forEach(function (testData) { - describe(testData.description, function () { - var NewConstructor + dataProvider.forEach(testData => { + describe(testData.description, () => { + let NewConstructor - beforeEach(function () { + beforeEach(() => { NewConstructor = testData.getConstructor(TestConstructor) }) - it('should create instances of itself', function () { - var instance = new NewConstructor() + it('should create instances of itself', () => { + const instance = new NewConstructor() expect(instance).to.be.an.instanceof(NewConstructor) }) - describe('afterCreation', function () { - it('should allow for manual post-processing before an instance is created', function () { - NewConstructor.afterCreation(function (instance) { + describe('afterCreation', () => { + it('should allow for manual post-processing before an instance is created', () => { + NewConstructor.afterCreation(instance => { instance.extraField = 7 }) - var instance = new NewConstructor() + const instance = new NewConstructor() expect(instance.extraField).to.equal(7) }) - it('should return the constructor', function () { - expect(NewConstructor.afterCreation(function (instance) { + it('should return the constructor', () => { + expect(NewConstructor.afterCreation(instance => { instance.extraField = 7 })).to.equal(NewConstructor) }) }) - describe('getInstances', function () { - it('should return an empty list if there are no instances', function () { + describe('getInstances', () => { + it('should return an empty list if there are no instances', () => { expect(NewConstructor.getInstances()).to.deep.equal([]) }) - it('should return a list of instances', function () { - var instance1 = new NewConstructor() - var instance2 = new NewConstructor() + it('should return a list of instances', () => { + const instance1 = new NewConstructor() + const instance2 = new NewConstructor() expect(NewConstructor.getInstances()).to.deep.equal([instance1, instance2]) }) }) - describe('getInstance', function () { - it('should return a single instance if one has been created', function () { - var instance = new NewConstructor() + describe('getInstance', () => { + it('should return a single instance if one has been created', () => { + const instance = new NewConstructor() expect(NewConstructor.getInstance()).to.equal(instance) }) - it('should throw an error if no instance has been created', function () { + it('should throw an error if no instance has been created', () => { expect(NewConstructor.getInstance).to.throw(/0 instances/) }) - it('should throw an error if more than one instance has been created', function () { + it('should throw an error if more than one instance has been created', () => { new NewConstructor() new NewConstructor() expect(NewConstructor.getInstance).to.throw(/2 instances/) }) - it('should return an instance with a given index', function () { + it('should return an instance with a given index', () => { new NewConstructor() - var instance2 = new NewConstructor() + const instance2 = new NewConstructor() expect(NewConstructor.getInstance(1)).to.equal(instance2) }) - it('should throw an error if not enough instances exist', function () { + it('should throw an error if not enough instances exist', () => { new NewConstructor() - expect(function () { NewConstructor.getInstance(1) }).to.throw(/1 instances/) + expect(() => NewConstructor.getInstance(1)).to.throw(/1 instances/) }) }) - describe('getInstancesArgs', function () { - it('should return an empty list if there are no instances', function () { + describe('getInstancesArgs', () => { + it('should return an empty list if there are no instances', () => { expect(NewConstructor.getInstancesArgs()).to.deep.equal([]) }) - it('should return a list of constructor arguments', function () { + it('should return a list of constructor arguments', () => { new NewConstructor('foo', 'bar') new NewConstructor('baz', 'bla') @@ -283,58 +283,58 @@ describe('getSpy- and getStubConstructor', function () { }) }) - describe('getInstanceArgs', function () { - it('should return the arguments of a single instance if one has been created', function () { + describe('getInstanceArgs', () => { + it('should return the arguments of a single instance if one has been created', () => { new NewConstructor('foo', 'bar') expect(NewConstructor.getInstanceArgs()).to.deep.equal(['foo', 'bar']) }) - it('should throw an error if no instance has been created', function () { + it('should throw an error if no instance has been created', () => { expect(NewConstructor.getInstanceArgs).to.throw(/0 instances/) }) - it('should throw an error if more than one instance has been created', function () { + it('should throw an error if more than one instance has been created', () => { new NewConstructor('foo', 'bar') new NewConstructor('baz', 'bla') expect(NewConstructor.getInstanceArgs).to.throw(/2 instances/) }) - it('should return the arguments of an instance with a given index', function () { + it('should return the arguments of an instance with a given index', () => { new NewConstructor('foo', 'bar') new NewConstructor('baz', 'bla') expect(NewConstructor.getInstanceArgs(1)).to.deep.equal(['baz', 'bla']) }) - it('should throw an error if not enough instances exist', function () { + it('should throw an error if not enough instances exist', () => { new NewConstructor('foo', 'bar') - expect(function () { NewConstructor.getInstanceArgs(1) }).to.throw(/1 instances/) + expect(() => { NewConstructor.getInstanceArgs(1) }).to.throw(/1 instances/) }) }) }) }) }) -describe('getMethodStubs', function () { - it('should create an object with stubs', function () { - var methodStubs = getMethodStubs('method1', 'method2') +describe('getMethodStubs', () => { + it('should create an object with stubs', () => { + const methodStubs = getMethodStubs('method1', 'method2') expect(methodStubs.method1.isSinonProxy).to.be.true expect(methodStubs.method2.isSinonProxy).to.be.true }) - it('should allow specifying stub return values', function () { - var methodStubs = getMethodStubs('method1', returning(10), 'method2', returning(20), 'method3') + it('should allow specifying stub return values', () => { + const methodStubs = getMethodStubs('method1', returning(10), 'method2', returning(20), 'method3') expect(methodStubs.method1()).to.equal(10, 'method1') expect(methodStubs.method2()).to.equal(20, 'method2') expect(methodStubs.method3()).to.be.undefined }) - it('should allow for methods to return their this value', function () { - var methodStubs = getMethodStubs('method1', returningThis, 'method2', returningThis, 'method3') + it('should allow for methods to return their this value', () => { + const methodStubs = getMethodStubs('method1', returningThis, 'method2', returningThis, 'method3') expect(methodStubs.method1().method2().method3).to.be.a('function') }) From 147c4f49f91f9eec8470f048489e8828c3f7aba8 Mon Sep 17 00:00:00 2001 From: Lukas Taegert Date: Sat, 27 May 2017 23:42:20 +0200 Subject: [PATCH 2/4] test(compatibility): Revert test to a node 4 compatible syntax --- test/index.spec.js | 208 ++++++++++++++++++++++----------------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/test/index.spec.js b/test/index.spec.js index 4dc0e2e..d0b3f64 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -1,64 +1,64 @@ /* eslint-env mocha */ /* eslint-disable no-unused-expressions,no-new */ -const sinonHelpers = require('../dist/index') -const getStubConstructor = sinonHelpers.getStubConstructor -const getSpyConstructor = sinonHelpers.getSpyConstructor -const getMethodStubs = sinonHelpers.getMethodStubs -const returning = sinonHelpers.returning -const returningThis = sinonHelpers.returningThis +var sinonHelpers = require('../dist/index') +var getStubConstructor = sinonHelpers.getStubConstructor +var getSpyConstructor = sinonHelpers.getSpyConstructor +var getMethodStubs = sinonHelpers.getMethodStubs +var returning = sinonHelpers.returning +var returningThis = sinonHelpers.returningThis -const expect = require('chai').expect -const sinon = require('sinon') +var expect = require('chai').expect +var sinon = require('sinon') -let TestConstructor +var TestConstructor -beforeEach(() => { +beforeEach(function () { global.sinon = sinon - const testPrototype2 = { - proto2: () => 'p2', - field1: () => 'pf1' + var testPrototype2 = { + proto2: function () { return 'p2' }, + field1: function () { return 'pf1' } } - const testPrototype1 = Object.create(testPrototype2, { - proto1: {writable: true, enumerable: false, value: () => 'p1'} + var testPrototype1 = Object.create(testPrototype2, { + proto1: {writable: true, enumerable: false, value: function () { return 'p1' }} }) // if this were defined in the object literal, it would be evaluated by Object.create Object.defineProperty(testPrototype1, 'protoGetter', - {get: () => { throw new Error('inherited getter was evaluated') }}) + {get: function () { throw new Error('inherited getter was evaluated') }}) - const testPrototype = Object.create(testPrototype1, { - field1: {writable: true, enumerable: true, value: () => 1}, - field2: {writable: true, enumerable: false, value: () => 2} + var testPrototype = Object.create(testPrototype1, { + field1: {writable: true, enumerable: true, value: function () { return 1 }}, + field2: {writable: true, enumerable: false, value: function () { return 2 }} }) TestConstructor = function () { this.args = Array.prototype.slice.call(arguments) - this.field3 = () => 3 + this.field3 = function () { return 3 } this.field4 = sinon.stub() - Object.defineProperty(this, 'getter', {get: () => { throw new Error('getter was evaluated') }}) + Object.defineProperty(this, 'getter', {get: function () { throw new Error('getter was evaluated') }}) } TestConstructor.prototype = testPrototype - TestConstructor.instanceMethod1 = () => 'i1' + TestConstructor.instanceMethod1 = function () { return 'i1' } TestConstructor.instanceMethod2 = sinon.stub() }) -afterEach(() => { +afterEach(function () { delete global.sinon }) -describe('getStubConstructor', () => { - let StubConstructor +describe('getStubConstructor', function () { + var StubConstructor - beforeEach(() => { + beforeEach(function () { StubConstructor = getStubConstructor(TestConstructor) }) - it('should return a constructor that creates an object with all methods of the prototype object', () => { - const stubbedObject = new StubConstructor() + it('should return a constructor that creates an object with all methods of the prototype object', function () { + var stubbedObject = new StubConstructor() expect(stubbedObject.field1).to.be.a('function', 'field1') expect(stubbedObject.field2).to.be.a('function', 'field2') @@ -66,61 +66,61 @@ describe('getStubConstructor', () => { expect(stubbedObject.proto2).to.be.a('function', 'proto2') }) - it('should not call through to the original constructor', () => { - const stubbedObject = new StubConstructor() + it('should not call through to the original constructor', function () { + var stubbedObject = new StubConstructor() expect(stubbedObject.field3).to.be.undefined }) - it('should create stubs for all instance methods', () => { + it('should create stubs for all instance methods', function () { expect(StubConstructor.instanceMethod1).to.have.property('isSinonProxy', true) expect(StubConstructor.instanceMethod1()).to.be.undefined expect(StubConstructor.instanceMethod2).to.have.property('isSinonProxy', true) }) - it('should create an empty constructor if no arguments are supplied', () => { + it('should create an empty constructor if no arguments are supplied', function () { StubConstructor = getStubConstructor() - const stubbedObject = new StubConstructor() + var stubbedObject = new StubConstructor() expect(stubbedObject).to.be.an('object') }) - describe('withMethods', () => { - it('should allow specifying additional methods', () => { + describe('withMethods', function () { + it('should allow specifying additional methods', function () { StubConstructor = StubConstructor.withMethods('m1', 'm2') - const stubbedObject = new StubConstructor() + var stubbedObject = new StubConstructor() expect(stubbedObject.m1).to.be.a('function', 'm1') expect(stubbedObject.m2).to.be.a('function', 'm2') }) - it('should allow specifying method return values', () => { + it('should allow specifying method return values', function () { StubConstructor = StubConstructor.withMethods('m1', returning(1), 'field1', returning(2), 'm2') - const stubbedObject = new StubConstructor() + var stubbedObject = new StubConstructor() expect(stubbedObject.m1()).to.equal(1, 'm1') expect(stubbedObject.field1()).to.equal(2, 'field1') expect(stubbedObject.m2()).to.be.undefined }) - it('should allow for methods to return their this value', () => { + it('should allow for methods to return their this value', function () { StubConstructor = StubConstructor.withMethods('m1', returningThis, 'field1', returningThis, 'm2') - const stubbedObject = new StubConstructor() + var stubbedObject = new StubConstructor() expect(stubbedObject.m1().field1().m2).to.be.a('function') }) }) }) -describe('getSpyConstructor', () => { - let SpyConstructor +describe('getSpyConstructor', function () { + var SpyConstructor - beforeEach(() => { + beforeEach(function () { SpyConstructor = getSpyConstructor(TestConstructor) }) - it('should return a constructor that creates an object with all methods the constructor creates', () => { - const spiedObject = new SpyConstructor() + it('should return a constructor that creates an object with all methods the constructor creates', function () { + var spiedObject = new SpyConstructor() expect(spiedObject.field1()).to.equal(1) expect(spiedObject.field2()).to.equal(2) @@ -129,18 +129,18 @@ describe('getSpyConstructor', () => { expect(spiedObject.proto2()).to.equal('p2') }) - it('should create instances of the original constructor', () => { - const spiedObject = new SpyConstructor() + it('should create instances of the original constructor', function () { + var spiedObject = new SpyConstructor() expect(spiedObject).to.be.an.instanceof(TestConstructor) }) - it('should create instances using the right arguments', () => { - const spiedObject = new SpyConstructor('Var 1', 2) + it('should create instances using the right arguments', function () { + var spiedObject = new SpyConstructor('Var 1', 2) expect(spiedObject.args).to.deep.equal(['Var 1', 2]) }) - it('should put spies on all methods', () => { - const spiedObject = new SpyConstructor() + it('should put spies on all methods', function () { + var spiedObject = new SpyConstructor() expect(spiedObject.field1).to.have.property('isSinonProxy', true, 'field1') expect(spiedObject.field2).to.have.property('isSinonProxy', true, 'field2') @@ -150,16 +150,16 @@ describe('getSpyConstructor', () => { expect(spiedObject.proto2).to.have.property('isSinonProxy', true, 'proto2') }) - it('should spy on all instance methods', () => { + it('should spy on all instance methods', function () { expect(SpyConstructor.instanceMethod1).to.have.property('isSinonProxy', true) expect(SpyConstructor.instanceMethod1()).to.equal('i1') expect(SpyConstructor.instanceMethod2).to.have.property('isSinonProxy', true) }) - describe('withStubs', () => { - it('should allow stubbing methods', () => { + describe('withStubs', function () { + it('should allow stubbing methods', function () { SpyConstructor = SpyConstructor.withStubs('field1', 'field3', 'proto1') - const spiedObject = new SpyConstructor() + var spiedObject = new SpyConstructor() expect(spiedObject.field1).to.have.property('isSinonProxy', true) expect(spiedObject.field3).to.have.property('isSinonProxy', true) @@ -169,26 +169,26 @@ describe('getSpyConstructor', () => { expect(spiedObject.proto1()).to.be.undefined }) - it('should allow specifying stub return values', () => { + it('should allow specifying stub return values', function () { SpyConstructor = SpyConstructor.withStubs('field1', returning(10), 'field3', returning(20), 'proto1') - const spiedObject = new SpyConstructor() + var spiedObject = new SpyConstructor() expect(spiedObject.field1()).to.equal(10, 'field1') expect(spiedObject.field3()).to.equal(20, 'field3') expect(spiedObject.proto1()).to.be.undefined }) - it('should allow for methods to return their this value', () => { + it('should allow for methods to return their this value', function () { SpyConstructor = SpyConstructor.withStubs('field1', returningThis, 'field3', returningThis, 'proto1') - const spiedObject = new SpyConstructor() + var spiedObject = new SpyConstructor() expect(spiedObject.field1().field3().proto1).to.be.a('function') }) }) }) -describe('getSpy- and getStubConstructor', () => { - const dataProvider = [{ +describe('getSpy- and getStubConstructor', function () { + var dataProvider = [{ description: 'getStubConstrucor', getConstructor: getStubConstructor }, { @@ -196,86 +196,86 @@ describe('getSpy- and getStubConstructor', () => { getConstructor: getSpyConstructor }] - dataProvider.forEach(testData => { - describe(testData.description, () => { - let NewConstructor + dataProvider.forEach(function (testData) { + describe(testData.description, function () { + var NewConstructor - beforeEach(() => { + beforeEach(function () { NewConstructor = testData.getConstructor(TestConstructor) }) - it('should create instances of itself', () => { - const instance = new NewConstructor() + it('should create instances of itself', function () { + var instance = new NewConstructor() expect(instance).to.be.an.instanceof(NewConstructor) }) - describe('afterCreation', () => { - it('should allow for manual post-processing before an instance is created', () => { - NewConstructor.afterCreation(instance => { + describe('afterCreation', function () { + it('should allow for manual post-processing before an instance is created', function () { + NewConstructor.afterCreation(function (instance) { instance.extraField = 7 }) - const instance = new NewConstructor() + var instance = new NewConstructor() expect(instance.extraField).to.equal(7) }) - it('should return the constructor', () => { - expect(NewConstructor.afterCreation(instance => { + it('should return the constructor', function () { + expect(NewConstructor.afterCreation(function (instance) { instance.extraField = 7 })).to.equal(NewConstructor) }) }) - describe('getInstances', () => { - it('should return an empty list if there are no instances', () => { + describe('getInstances', function () { + it('should return an empty list if there are no instances', function () { expect(NewConstructor.getInstances()).to.deep.equal([]) }) - it('should return a list of instances', () => { - const instance1 = new NewConstructor() - const instance2 = new NewConstructor() + it('should return a list of instances', function () { + var instance1 = new NewConstructor() + var instance2 = new NewConstructor() expect(NewConstructor.getInstances()).to.deep.equal([instance1, instance2]) }) }) - describe('getInstance', () => { - it('should return a single instance if one has been created', () => { - const instance = new NewConstructor() + describe('getInstance', function () { + it('should return a single instance if one has been created', function () { + var instance = new NewConstructor() expect(NewConstructor.getInstance()).to.equal(instance) }) - it('should throw an error if no instance has been created', () => { + it('should throw an error if no instance has been created', function () { expect(NewConstructor.getInstance).to.throw(/0 instances/) }) - it('should throw an error if more than one instance has been created', () => { + it('should throw an error if more than one instance has been created', function () { new NewConstructor() new NewConstructor() expect(NewConstructor.getInstance).to.throw(/2 instances/) }) - it('should return an instance with a given index', () => { + it('should return an instance with a given index', function () { new NewConstructor() - const instance2 = new NewConstructor() + var instance2 = new NewConstructor() expect(NewConstructor.getInstance(1)).to.equal(instance2) }) - it('should throw an error if not enough instances exist', () => { + it('should throw an error if not enough instances exist', function () { new NewConstructor() - expect(() => NewConstructor.getInstance(1)).to.throw(/1 instances/) + expect(function () { NewConstructor.getInstance(1) }).to.throw(/1 instances/) }) }) - describe('getInstancesArgs', () => { - it('should return an empty list if there are no instances', () => { + describe('getInstancesArgs', function () { + it('should return an empty list if there are no instances', function () { expect(NewConstructor.getInstancesArgs()).to.deep.equal([]) }) - it('should return a list of constructor arguments', () => { + it('should return a list of constructor arguments', function () { new NewConstructor('foo', 'bar') new NewConstructor('baz', 'bla') @@ -283,58 +283,58 @@ describe('getSpy- and getStubConstructor', () => { }) }) - describe('getInstanceArgs', () => { - it('should return the arguments of a single instance if one has been created', () => { + describe('getInstanceArgs', function () { + it('should return the arguments of a single instance if one has been created', function () { new NewConstructor('foo', 'bar') expect(NewConstructor.getInstanceArgs()).to.deep.equal(['foo', 'bar']) }) - it('should throw an error if no instance has been created', () => { + it('should throw an error if no instance has been created', function () { expect(NewConstructor.getInstanceArgs).to.throw(/0 instances/) }) - it('should throw an error if more than one instance has been created', () => { + it('should throw an error if more than one instance has been created', function () { new NewConstructor('foo', 'bar') new NewConstructor('baz', 'bla') expect(NewConstructor.getInstanceArgs).to.throw(/2 instances/) }) - it('should return the arguments of an instance with a given index', () => { + it('should return the arguments of an instance with a given index', function () { new NewConstructor('foo', 'bar') new NewConstructor('baz', 'bla') expect(NewConstructor.getInstanceArgs(1)).to.deep.equal(['baz', 'bla']) }) - it('should throw an error if not enough instances exist', () => { + it('should throw an error if not enough instances exist', function () { new NewConstructor('foo', 'bar') - expect(() => { NewConstructor.getInstanceArgs(1) }).to.throw(/1 instances/) + expect(function () { NewConstructor.getInstanceArgs(1) }).to.throw(/1 instances/) }) }) }) }) }) -describe('getMethodStubs', () => { - it('should create an object with stubs', () => { - const methodStubs = getMethodStubs('method1', 'method2') +describe('getMethodStubs', function () { + it('should create an object with stubs', function () { + var methodStubs = getMethodStubs('method1', 'method2') expect(methodStubs.method1.isSinonProxy).to.be.true expect(methodStubs.method2.isSinonProxy).to.be.true }) - it('should allow specifying stub return values', () => { - const methodStubs = getMethodStubs('method1', returning(10), 'method2', returning(20), 'method3') + it('should allow specifying stub return values', function () { + var methodStubs = getMethodStubs('method1', returning(10), 'method2', returning(20), 'method3') expect(methodStubs.method1()).to.equal(10, 'method1') expect(methodStubs.method2()).to.equal(20, 'method2') expect(methodStubs.method3()).to.be.undefined }) - it('should allow for methods to return their this value', () => { - const methodStubs = getMethodStubs('method1', returningThis, 'method2', returningThis, 'method3') + it('should allow for methods to return their this value', function () { + var methodStubs = getMethodStubs('method1', returningThis, 'method2', returningThis, 'method3') expect(methodStubs.method1().method2().method3).to.be.a('function') }) From 5f886d5f97dc7a6eed321159a282c2f3cace431a Mon Sep 17 00:00:00 2001 From: Lukas Taegert Date: Sat, 27 May 2017 23:46:01 +0200 Subject: [PATCH 3/4] chore(coverage): Add build script to coverage --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c4688cf..2d13975 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ before_install: before_script: - npm prune script: - - istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -R spec + - node build && istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -R spec - codecov after_success: - 'curl -Lo travis_after_all.py https://git.io/travis_after_all' From fefaeca019826fba6a42c8b1a6222bfa3d3752d6 Mon Sep 17 00:00:00 2001 From: Lukas Taegert Date: Sat, 27 May 2017 23:58:44 +0200 Subject: [PATCH 4/4] chore(build): Actually make all external dependencies external again --- build.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/build.js b/build.js index f3cf310..3587c2e 100644 --- a/build.js +++ b/build.js @@ -1,13 +1,18 @@ const rollup = require('rollup') -const resolve = require('rollup-plugin-node-resolve') const commonjs = require('rollup-plugin-commonjs') const babel = require('rollup-plugin-babel') rollup.rollup({ entry: 'src/index.js', - external: ['sinon'], + external: [ + 'sinon', + 'fluent-arguments', + 'ramda/src/compose', + 'ramda/src/curry', + 'ramda/src/filter', + 'ramda/src/forEach' + ], plugins: [ - resolve({jsnext: true, module: true}), commonjs(), babel({ presets: [