2 * @filedescription Object Schema Tests
4 /* global it, describe, beforeEach */
8 //-----------------------------------------------------------------------------
10 //-----------------------------------------------------------------------------
12 const assert = require("chai").assert;
13 const { ObjectSchema } = require("../src/");
15 //-----------------------------------------------------------------------------
17 //-----------------------------------------------------------------------------
19 describe("ObjectSchema", () => {
23 describe("new ObjectSchema()", () => {
25 it("should add a new key when a strategy is passed", () => {
26 schema = new ObjectSchema({
33 assert.isTrue(schema.hasKey("foo"));
36 it("should throw an error when a strategy is missing a merge() method", () => {
38 schema = new ObjectSchema({
43 }, /Definition for key "foo" must have a merge property/);
46 it("should throw an error when a strategy is missing a merge() method", () => {
48 schema = new ObjectSchema();
49 }, /Schema definitions missing/);
52 it("should throw an error when a strategy is missing a validate() method", () => {
54 schema = new ObjectSchema({
59 }, /Definition for key "foo" must have a validate\(\) method/);
62 it("should throw an error when merge is an invalid string", () => {
70 }, /key "foo" missing valid merge strategy/);
73 it("should throw an error when validate is an invalid string", () => {
81 }, /key "foo" missing valid validation strategy/);
87 describe("merge()", () => {
89 it("should throw an error when an unexpected key is found", () => {
90 let schema = new ObjectSchema({});
93 schema.merge({ foo: true }, { foo: true });
94 }, /Unexpected key "foo"/);
97 it("should throw an error when merge() throws an error", () => {
98 let schema = new ObjectSchema({
101 throw new Error("Boom!");
107 assert.throws(() => {
108 schema.merge({ foo: true }, { foo: true });
109 }, /Key "foo": Boom!/);
113 it("should call the merge() strategy for one key when called", () => {
115 schema = new ObjectSchema({
124 const result = schema.merge({ foo: true }, { foo: false });
125 assert.propertyVal(result, "foo", "bar");
128 it("should not call the merge() strategy when both objects don't contain the key", () => {
132 schema = new ObjectSchema({
141 schema.merge({}, {});
142 assert.isFalse(called, "The merge() strategy should not have been called.");
145 it("should omit returning the key when the merge() strategy returns undefined", () => {
146 schema = new ObjectSchema({
155 const result = schema.merge({ foo: true }, { foo: false });
156 assert.notProperty(result, "foo");
159 it("should call the merge() strategy for two keys when called", () => {
160 schema = new ObjectSchema({
175 const result = schema.merge({ foo: true, bar: 1 }, { foo: true, bar: 2 });
176 assert.propertyVal(result, "foo", "bar");
177 assert.propertyVal(result, "bar", "baz");
180 it("should call the merge() strategy for two keys when called on three objects", () => {
181 schema = new ObjectSchema({
196 const result = schema.merge(
197 { foo: true, bar: 1 },
198 { foo: true, bar: 3 },
199 { foo: false, bar: 2 }
201 assert.propertyVal(result, "foo", "bar");
202 assert.propertyVal(result, "bar", "baz");
205 it("should call the merge() strategy when defined as 'overwrite'", () => {
206 schema = new ObjectSchema({
213 const result = schema.merge(
217 assert.propertyVal(result, "foo", false);
220 it("should call the merge() strategy when defined as 'assign'", () => {
221 schema = new ObjectSchema({
228 const result = schema.merge(
229 { foo: { bar: true } },
230 { foo: { baz: false } }
233 assert.strictEqual(result.foo.bar, true);
234 assert.strictEqual(result.foo.baz, false);
237 it("should call the merge strategy when there's a subschema", () => {
239 schema = new ObjectSchema({
254 const result = schema.merge({
265 assert.strictEqual(result.name.first, "g");
266 assert.strictEqual(result.name.last, "z");
269 it("should return separate objects when using subschema", () => {
271 schema = new ObjectSchema({
308 const result = schema.merge(baseObject, {
312 assert.notStrictEqual(result.address.street, baseObject.address.street);
313 assert.deepStrictEqual(result.address, baseObject.address);
316 it("should not error when calling the merge strategy when there's a subschema and no matching key in second object", () => {
318 schema = new ObjectSchema({
333 const result = schema.merge({
341 assert.strictEqual(result.name.first, "n");
342 assert.strictEqual(result.name.last, "z");
345 it("should not error when calling the merge strategy when there's multiple subschemas and no matching key in second object", () => {
347 schema = new ObjectSchema({
367 const result = schema.merge({
377 assert.strictEqual(result.user.name.first, "n");
378 assert.strictEqual(result.user.name.last, "z");
384 describe("validate()", () => {
386 it("should throw an error when an unexpected key is found", () => {
387 let schema = new ObjectSchema({});
388 assert.throws(() => {
389 schema.validate({ foo: true });
390 }, /Unexpected key "foo"/);
393 it("should not throw an error when an expected key is found", () => {
394 schema = new ObjectSchema({
403 schema.validate({ foo: true });
406 it("should pass the property value into validate() when key is found", () => {
407 schema = new ObjectSchema({
413 assert.isTrue(value);
418 schema.validate({ foo: true });
421 it("should not throw an error when expected keys are found", () => {
422 schema = new ObjectSchema({
437 schema.validate({ foo: true, bar: true });
440 it("should not throw an error when expected keys are found with required keys", () => {
441 schema = new ObjectSchema({
457 schema.validate({ foo: true, bar: true });
460 it("should throw an error when expected keys are found without required keys", () => {
461 schema = new ObjectSchema({
476 requires: ["foo", "baz"],
482 assert.throws(() => {
483 schema.validate({ bar: true });
484 }, /Key "bar" requires keys "foo", "baz"./);
488 it("should throw an error when an expected key is found but is invalid", () => {
490 schema = new ObjectSchema({
496 throw new Error("Invalid key.");
501 assert.throws(() => {
502 schema.validate({ foo: true });
503 }, /Key "foo": Invalid key/);
506 it("should throw an error when an expected key is found but is invalid with a string validator", () => {
508 schema = new ObjectSchema({
517 assert.throws(() => {
518 schema.validate({ foo: true });
519 }, /Key "foo": Expected a string/);
522 it("should throw an error when an expected key is found but is invalid with a number validator", () => {
524 schema = new ObjectSchema({
533 assert.throws(() => {
534 schema.validate({ foo: true });
535 }, /Key "foo": Expected a number/);
538 it("should throw an error when a required key is missing", () => {
540 schema = new ObjectSchema({
550 assert.throws(() => {
552 }, /Missing required key "foo"/);
555 it("should throw an error when a subschema is provided and the value doesn't validate", () => {
557 schema = new ObjectSchema({
572 assert.throws(() => {
580 }, /Key "name": Key "first": Expected a string/);
583 it("should not throw an error when a subschema is provided and the value validates", () => {
585 schema = new ObjectSchema({