Skip to content

Commit

Permalink
the extend function should handle the new defaultProps option
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti committed May 30, 2016
1 parent 8f15c40 commit e84ee65
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
18 changes: 13 additions & 5 deletions lib/extend.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,37 @@ function getProps(type) {
return isObject(type) ? type : type.meta.props;
}

function getDefaultProps(type) {
return isObject(type) ? null : type.meta.defaultProps;
}

function pushAll(arr, elements) {
Array.prototype.push.apply(arr, elements);
}

function extend(combinator, mixins, name) {
function extend(combinator, mixins, options) {
if (process.env.NODE_ENV !== 'production') {
assert(isFunction(combinator), function () { return 'Invalid argument combinator supplied to extend(combinator, mixins, name), expected a function'; });
assert(isArray(mixins), function () { return 'Invalid argument mixins supplied to extend(combinator, mixins, name), expected an array'; });
assert(isFunction(combinator), function () { return 'Invalid argument combinator supplied to extend(combinator, mixins, options), expected a function'; });
assert(isArray(mixins), function () { return 'Invalid argument mixins supplied to extend(combinator, mixins, options), expected an array'; });
}
var props = {};
var prototype = {};
var predicates = [];
var defaultProps = {};
mixins.forEach(function (x, i) {
var decomposition = decompose(x);
var unrefinedType = decomposition.unrefinedType;
if (process.env.NODE_ENV !== 'production') {
assert(isObject(unrefinedType) || isStruct(unrefinedType) || isInterface(unrefinedType), function () { return 'Invalid argument mixins[' + i + '] supplied to extend(combinator, mixins, name), expected an object, struct, interface or a refinement (of struct or interface)'; });
assert(isObject(unrefinedType) || isStruct(unrefinedType) || isInterface(unrefinedType), function () { return 'Invalid argument mixins[' + i + '] supplied to extend(combinator, mixins, options), expected an object, struct, interface or a refinement (of struct or interface)'; });
}
pushAll(predicates, decomposition.predicates);
mixin(props, getProps(unrefinedType));
mixin(prototype, unrefinedType.prototype);
mixin(defaultProps, getDefaultProps(unrefinedType));
});
var result = compose(predicates, combinator(props, name));
options = combinator.getOptions(options);
mixin(options.defaultProps, defaultProps);
var result = compose(predicates, combinator(props, options));
mixin(result.prototype, prototype);
return result;
}
Expand Down
33 changes: 31 additions & 2 deletions test/extend.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,39 @@ describe('extend(combinator, mixins, [name])', function () {
it('should throw if used with wrong arguments', function () {
throwsWithMessage(function () {
t.struct.extend();
}, '[tcomb] Invalid argument mixins supplied to extend(combinator, mixins, name), expected an array');
}, '[tcomb] Invalid argument mixins supplied to extend(combinator, mixins, options), expected an array');
throwsWithMessage(function () {
t.struct.extend([1]);
}, '[tcomb] Invalid argument mixins[0] supplied to extend(combinator, mixins, name), expected an object, struct, interface or a refinement (of struct or interface)');
}, '[tcomb] Invalid argument mixins[0] supplied to extend(combinator, mixins, options), expected an object, struct, interface or a refinement (of struct or interface)');
});

it('should handle defaultProps', function () {
var A1 = t.struct({ a: t.String }, { defaultProps: { a: 'default-a' } });
var B1 = t.struct({ b: t.String }, { defaultProps: { b: 'default-b' } });
var C1 = t.struct.extend([A1, B1, { z: t.Number }], { defaultProps: { z: 1 } });
assert.deepEqual(C1.meta.defaultProps, {
a: 'default-a',
b: 'default-b',
z: 1
});
assert.deepEqual(C1({}), {
a: 'default-a',
b: 'default-b',
z: 1
});

var A2 = t.struct({ a: t.String }, { defaultProps: { a: 'default-a' } });
var B2 = t.struct({ b: t.String }, { defaultProps: { b: 'default-b' } });
var C2 = t.struct.extend([A2, B2, { z: t.Number }], 'C2');
assert.deepEqual(C2.meta.defaultProps, {
a: 'default-a',
b: 'default-b'
});
assert.deepEqual(C2({ z: 2 }), {
a: 'default-a',
b: 'default-b',
z: 2
});
});

describe('struct.extend(mixins, [name])', function () {
Expand Down

0 comments on commit e84ee65

Please sign in to comment.