Skip to content
This repository has been archived by the owner on Jun 10, 2024. It is now read-only.

Commit

Permalink
New: Built-in merge strategies
Browse files Browse the repository at this point in the history
  • Loading branch information
nzakas committed Nov 27, 2020
1 parent 9dea4c0 commit 93cdd05
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
28 changes: 25 additions & 3 deletions src/object-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

"use strict";

//-----------------------------------------------------------------------------
// Requirements
//-----------------------------------------------------------------------------

const { MergeStrategy } = require("./merge-strategy");

//-----------------------------------------------------------------------------
// Private
//-----------------------------------------------------------------------------
Expand All @@ -29,12 +35,20 @@ const requiredKeys = Symbol("requiredKeys");
*/
function validateDefinition(name, strategy) {

if (typeof strategy.merge === "string") {
if (!(strategy.merge in MergeStrategy)) {
throw new TypeError(`Definition for key "${name}" missing valid merge strategy.`);
}

return;
}

if (typeof strategy.merge !== "function") {
throw new Error(`Definition for key "${name}" must have a merge() method.`);
throw new TypeError(`Definition for key "${name}" must have a merge property.`);
}

if (typeof strategy.validate !== "function") {
throw new Error(`Definition for key "${name}" must have a validate() method.`);
throw new TypeError(`Definition for key "${name}" must have a validate() method.`);
}
}

Expand Down Expand Up @@ -75,6 +89,14 @@ class ObjectSchema {
for (const key of Object.keys(definitions)) {
validateDefinition(key, definitions[key]);

// normalize the merge method in case there's a string
if (typeof definitions[key].merge === "string") {
definitions[key] = {
...definitions[key],
merge: MergeStrategy[definitions[key].merge]
};
};

this[strategies].set(key, definitions[key]);

if (definitions[key].required) {
Expand Down Expand Up @@ -177,4 +199,4 @@ class ObjectSchema {
}
}

exports.ObjectSchema = ObjectSchema;
exports.ObjectSchema = ObjectSchema;
34 changes: 33 additions & 1 deletion tests/object-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe("ObjectSchema", () => {
validate() { }
}
});
}, /Definition for key "foo" must have a merge\(\) method/);
}, /Definition for key "foo" must have a merge property/);
});

it("should throw an error when a strategy is missing a merge() method", () => {
Expand Down Expand Up @@ -179,6 +179,38 @@ describe("ObjectSchema", () => {
assert.propertyVal(result, "bar", "baz");
});

it("should call the merge() strategy when defined as 'overwrite'", () => {
schema = new ObjectSchema({
foo: {
merge: "overwrite",
validate() { }
}
});

const result = schema.merge(
{ foo: true },
{ foo: false }
);
assert.propertyVal(result, "foo", false);
});

it("should call the merge() strategy when defined as 'assign'", () => {
schema = new ObjectSchema({
foo: {
merge: "assign",
validate() { }
}
});

const result = schema.merge(
{ foo: { bar: true } },
{ foo: { baz: false } }
);

assert.strictEqual(result.foo.bar, true);
assert.strictEqual(result.foo.baz, false);
});

});

describe("validate()", () => {
Expand Down

0 comments on commit 93cdd05

Please sign in to comment.