diff --git a/packages/metal-state/src/Config.js b/packages/metal-state/src/Config.js index 2e460902..e76c745c 100644 --- a/packages/metal-state/src/Config.js +++ b/packages/metal-state/src/Config.js @@ -233,11 +233,12 @@ function destructShapeOfConfigs(shape) { */ function mergeConfig(context, config) { let obj = context; - if (obj === Config) { - obj = Object.create(Config); - obj.config = {}; - } - object.mixin(obj.config, config); + const objConfig = obj.config || {}; + + obj = Object.create(Config); + obj.config = {}; + + Object.assign(obj.config, objConfig, config); return obj; } diff --git a/packages/metal-state/test/Config.js b/packages/metal-state/test/Config.js index 3e3dcea0..2a4e67da 100644 --- a/packages/metal-state/test/Config.js +++ b/packages/metal-state/test/Config.js @@ -284,4 +284,26 @@ describe('Config', function() { assert.ok(config.config.validator(10)); assert.ok(config.config.validator('test') instanceof Error); }); + + it('should not mutate config object with subsequent method calls', function() { + const config = Config.string(); + const config2 = config.oneOf(['1', '2']); + const config3 = config2.required(); + + assert.notDeepEqual(config, config2); + assert.notDeepEqual(config, config3); + assert.notDeepEqual(config2, config3); + + assert.ok(config.config.validator(1) instanceof Error); + assert.ok(config2.config.validator(1) instanceof Error); + assert.ok(config3.config.validator(1) instanceof Error); + + assert.ok(config.config.validator('1')); + assert.ok(config2.config.validator('1')); + assert.ok(config3.config.validator('3') instanceof Error); + + assert.isTrue(config3.config.required); + assert.isUndefined(config.config.required); + assert.isUndefined(config2.config.required); + }); });