diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a04da6..58faa58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,15 @@ - -## [0.1.4](https://github.com/roalcantara/factory-bot-ts/compare/v0.1.3...v0.1.4) (2018-08-07) + +## [0.1.5](https://github.com/roalcantara/factory-bot-ts/compare/v0.1.4...v0.1.5) (2018-08-07) ### Bug Fixes +* **factories:** Fix extend method ([e53905d](https://github.com/roalcantara/factory-bot-ts/commit/e53905d)) * **factories:** Fix the clear method ([4d96588](https://github.com/roalcantara/factory-bot-ts/commit/4d96588)) * **factories:** Fix the count method ([9b29a62](https://github.com/roalcantara/factory-bot-ts/commit/9b29a62)) * **factories:** Require partial attributes ([22f55c6](https://github.com/roalcantara/factory-bot-ts/commit/22f55c6)) * **release:** Add dist folder ([8754133](https://github.com/roalcantara/factory-bot-ts/commit/8754133)) -* **release:** Update dist folder ([a237927](https://github.com/roalcantara/factory-bot-ts/commit/a237927)) +* **release:** Update dist folder ([40f15f8](https://github.com/roalcantara/factory-bot-ts/commit/40f15f8)) ### Features diff --git a/dist/factory-bot.js b/dist/factory-bot.js index f4e9369..d857e2a 100644 --- a/dist/factory-bot.js +++ b/dist/factory-bot.js @@ -1,4 +1,12 @@ "use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; Object.defineProperty(exports, "__esModule", { value: true }); var lodash_1 = require("lodash"); var FactoryBot = /** @class */ (function () { @@ -31,7 +39,7 @@ var FactoryBot = /** @class */ (function () { throw new Error("Factory '" + name + "' has not been defined!"); if (this.has(trait)) throw new Error("Factory '" + name + "'`s trait '" + trait + "' has already been defined!"); - this.factories[trait] = this.factories[name]; + this.factories[trait] = __assign({}, this.factories[name]); this.factories[trait].attributes = Object.assign.apply(Object, [{}].concat(this.factories[name].attributes, [attributes])); }; FactoryBot.prototype.instantiate = function (type) { diff --git a/dist/factory-bot.js.map b/dist/factory-bot.js.map index 200d484..108e3a8 100644 --- a/dist/factory-bot.js.map +++ b/dist/factory-bot.js.map @@ -1 +1 @@ -{"version":3,"file":"factory-bot.js","sourceRoot":"","sources":["../src/factory-bot.ts"],"names":[],"mappings":"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","sourcesContent":["import { isFunction, sample } from 'lodash'\n\nexport type FactoryParam = () => any\n\nexport type FactoryAttribute = string | number | boolean | Date | FactoryParam\n\nexport type Factory = {\n clazz: any\n attributes: Map\n}\n\nexport class FactoryBot {\n private factories = new Map()\n private sequences = 0\n\n has(name: string): boolean {\n return this.factories[name] !== undefined\n }\n\n count(): number {\n return Object.keys(this.factories).length\n }\n\n clear(): void {\n this.factories = new Map()\n this.sequences = 0\n }\n\n define(name: string, attributes: Partial, clazz?: { new(): T; } | any): void {\n this.factories[name] = {\n clazz, attributes\n }\n }\n\n extend(name: string, trait: string, attributes: Partial): void {\n if (!this.has(name)) throw new Error(`Factory '${name}' has not been defined!`)\n if (this.has(trait)) throw new Error(`Factory '${name}'\\`s trait '${trait}' has already been defined!`)\n\n this.factories[trait] = this.factories[name]\n\n this.factories[trait].attributes = Object.assign({},\n ...this.factories[name].attributes, attributes\n )\n }\n\n instantiate(type: (new () => T)): T {\n return new type()\n }\n\n build (name: string, attributes ?: Partial): T {\n const factory = this.factories[name] as Factory\n const instance = factory.clazz ? this.instantiate(factory.clazz) : {}\n\n Object.keys(factory.attributes)\n .forEach(attribute => {\n instance[attribute] = this.parse(factory.attributes[attribute])\n })\n\n // tslint:disable-next-line\n return Object.assign(instance, attributes) as T\n }\n\n buildList(name: string, length = 1, attributes?: Partial): Array {\n return Array(length)\n .fill(undefined)\n .map(() => this.build(name, attributes))\n }\n\n rand(enumInstance: T): T {\n return sample(Object.keys(enumInstance)\n .map(key => enumInstance[key] as T))\n }\n\n seq(callbackfn: (seq: number) => FactoryAttribute): FactoryAttribute {\n this.sequences ++\n\n return callbackfn(this.sequences)\n }\n\n private parse = val => {\n if (isFunction(val)) return val()\n\n return val\n }\n}\n"]} \ No newline at end of file +{"version":3,"file":"factory-bot.js","sourceRoot":"","sources":["../src/factory-bot.ts"],"names":[],"mappings":"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","sourcesContent":["import { isFunction, sample } from 'lodash'\n\nexport type FactoryParam = () => any\n\nexport type FactoryAttribute = string | number | boolean | Date | FactoryParam\n\nexport type Factory = {\n clazz: any\n attributes: Map\n}\n\nexport class FactoryBot {\n private factories = new Map()\n private sequences = 0\n\n has(name: string): boolean {\n return this.factories[name] !== undefined\n }\n\n count(): number {\n return Object.keys(this.factories).length\n }\n\n clear(): void {\n this.factories = new Map()\n this.sequences = 0\n }\n\n define(name: string, attributes: Partial, clazz?: { new(): T; } | any): void {\n this.factories[name] = {\n clazz, attributes\n }\n }\n\n extend(name: string, trait: string, attributes: Partial): void {\n if (!this.has(name)) throw new Error(`Factory '${name}' has not been defined!`)\n if (this.has(trait)) throw new Error(`Factory '${name}'\\`s trait '${trait}' has already been defined!`)\n\n this.factories[trait] = { ...this.factories[name] }\n\n this.factories[trait].attributes = Object.assign({},\n ...this.factories[name].attributes, attributes\n )\n }\n\n instantiate(type: (new () => T)): T {\n return new type()\n }\n\n build (name: string, attributes ?: Partial): T {\n const factory = this.factories[name] as Factory\n const instance = factory.clazz ? this.instantiate(factory.clazz) : {}\n\n Object.keys(factory.attributes)\n .forEach(attribute => {\n instance[attribute] = this.parse(factory.attributes[attribute])\n })\n\n // tslint:disable-next-line\n return Object.assign(instance, attributes) as T\n }\n\n buildList(name: string, length = 1, attributes?: Partial): Array {\n return Array(length)\n .fill(undefined)\n .map(() => this.build(name, attributes))\n }\n\n rand(enumInstance: T): T {\n return sample(Object.keys(enumInstance)\n .map(key => enumInstance[key] as T))\n }\n\n seq(callbackfn: (seq: number) => FactoryAttribute): FactoryAttribute {\n this.sequences ++\n\n return callbackfn(this.sequences)\n }\n\n private parse = val => {\n if (isFunction(val)) return val()\n\n return val\n }\n}\n"]} \ No newline at end of file diff --git a/package.json b/package.json index ef8ec56..01e399c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "factory-bot-ts", - "version": "0.1.4", + "version": "0.1.5", "description": "A simple library for setting up TypeScript objects as test data - heavily inspired by the awesome Ruby's factory_bot", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/factory-bot.ts b/src/factory-bot.ts index 1771885..4c43112 100644 --- a/src/factory-bot.ts +++ b/src/factory-bot.ts @@ -36,7 +36,7 @@ export class FactoryBot { if (!this.has(name)) throw new Error(`Factory '${name}' has not been defined!`) if (this.has(trait)) throw new Error(`Factory '${name}'\`s trait '${trait}' has already been defined!`) - this.factories[trait] = this.factories[name] + this.factories[trait] = { ...this.factories[name] } this.factories[trait].attributes = Object.assign({}, ...this.factories[name].attributes, attributes diff --git a/tests/factory-bot.spec.ts b/tests/factory-bot.spec.ts index 2e56e87..a725a79 100644 --- a/tests/factory-bot.spec.ts +++ b/tests/factory-bot.spec.ts @@ -270,6 +270,11 @@ describe('FactoryBot', () => { FactoryBot.extend('ninja', 'jōnin', { level: NinjaRank.JONIN }) + + FactoryBot.extend('ninja', 'chuunin:sensor', { + level: NinjaRank.CHUUNIN, + sensor: true + }) }) it('extends existing factories in order to generate specialized data', () => { @@ -281,6 +286,15 @@ describe('FactoryBot', () => { level: NinjaRank.JONIN, sensor: false })) + + expect(FactoryBot.build('chuunin:sensor')).to.deep + .eq(new Ninja({ + id: 1, + name: 'Kakashi Hatake', + username: 'kakashi', + level: NinjaRank.CHUUNIN, + sensor: true + })) }) context('when the trait already exists', () => {