Skip to content

Commit

Permalink
fix(defaults): handle nested defaults correctly
Browse files Browse the repository at this point in the history
Fix #16
  • Loading branch information
vkarpov15 committed Jan 27, 2019
1 parent 5352e1a commit c02b89b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const shouldSkipPath = require('./util').shouldSkipPath;

function applyDefaults(obj, schema, projection) {
_.each(Object.keys(schema._obj), key => {
const def = defaults(obj, obj[key], schema, key, projection)
const def = defaults(obj, obj[key], schema, key, projection);
if (def !== void 0 && obj[key] == null) {
obj[key] = def;
}
Expand All @@ -33,12 +33,20 @@ function defaults(root, v, schema, path, projection) {
}

if (schemaPath.$type === Object && schemaPath.$schema) {
_.each(schemaPath.$schema, (value, key) => {
const def = defaults(root, _.get(v, key), schema, join(fakePath, key), projection);
_.each(schemaPath.$schema, (childSchemaPath, key) => {
const fullPath = join(fakePath, key);
const value = _.get(v, key);
// Might have nested defaults even if this level isn't nullish
const def = defaults(root, value, schema, fullPath, projection);
if (def !== void 0 && value == null) {
if (v == null) {
v = {};
}
v[key] = def;
}
});

return v;
}
if (schemaPath.$type === Array) {
_.each(v || [], (value, index) => {
Expand All @@ -47,6 +55,8 @@ function defaults(root, v, schema, path, projection) {
v[index] = def;
}
});

return v;
}
}

Expand Down
30 changes: 30 additions & 0 deletions test/unit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,36 @@ describe('unmarshal()', function() {
assert.ok(val.createdAt.getTime() >= now, `${val.createdAt}, ${now}`);
});

it('deep defaults', function() {
const C = new Archetype({
firstName: {
$type: 'string',
$default: () => 'test'
},
name: {
first: {
$type: 'string',
$default: () => 'test'
}
},
multiple: {
a: {
$type: 'string',
$default: () => 'test'
},
b: {
$type: 'string'
}
}
}).compile('c');

let v = new C({ multiple: { b: 'foo' } });
assert.equal(v.firstName, 'test');
assert.equal(v.name.first, 'test');
assert.equal(v.multiple.a, 'test');
assert.equal(v.multiple.b, 'foo');
});

it('no defaults for projecton', function() {
const now = Date.now();
const Model = new Archetype({
Expand Down

0 comments on commit c02b89b

Please sign in to comment.