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', () => {