Skip to content

Commit

Permalink
fix: update .labels() fn to support subschemas
Browse files Browse the repository at this point in the history
fixes #400
  • Loading branch information
aldeed committed Aug 31, 2020
1 parent 555b262 commit d8ae4a9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 10 deletions.
44 changes: 41 additions & 3 deletions package/lib/SimpleSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,42 @@ class SimpleSchema {
});
}

/**
* @param {String} key One specific or generic key for which to get the schema.
* @returns {[SimpleSchema, String]} Returns a 2-tuple.
*
* First item: The SimpleSchema instance that actually defines the given key.
*
* For example, if you have several nested objects, each their own SimpleSchema
* instance, and you pass in 'outerObj.innerObj.innerestObj.name' as the key, you'll
* get back the SimpleSchema instance for `outerObj.innerObj.innerestObj` key.
*
* But if you pass in 'outerObj.innerObj.innerestObj.name' as the key and that key is
* defined in the main schema without use of subschemas, then you'll get back the main schema.
*
* Second item: The part of the key that is in the found schema.
*
* Always returns a tuple (array) but the values may be `null`.
*/
nearestSimpleSchemaInstance(key) {
if (!key) return [null, null];

const genericKey = MongoObject.makeKeyGeneric(key);
if (this._schema[genericKey]) return [this, genericKey];

// If not defined in this schema, see if it's defined in a subschema
let innerKey;
let nearestSimpleSchemaInstance;
this.forEachAncestorSimpleSchema(key, (simpleSchema, ancestor, subSchemaKey) => {
if (!nearestSimpleSchemaInstance && simpleSchema._schema[subSchemaKey]) {
nearestSimpleSchemaInstance = simpleSchema;
innerKey = subSchemaKey;
}
});

return innerKey ? [nearestSimpleSchemaInstance, innerKey] : [null, null];
}

/**
* @param {String} [key] One specific or generic key for which to get the schema.
* @returns {Object} The entire schema object or just the definition for one key.
Expand Down Expand Up @@ -702,10 +738,12 @@ class SimpleSchema {
Object.keys(labels).forEach((key) => {
const label = labels[key];
if (typeof label !== 'string' && typeof label !== 'function') return;
if (!Object.prototype.hasOwnProperty.call(this._schema, key)) return;

this._schema[key].label = label;
this._depsLabels[key] && this._depsLabels[key].changed();
const [schemaInstance, innerKey] = this.nearestSimpleSchemaInstance(key);
if (!schemaInstance) return;

schemaInstance._schema[innerKey].label = label;
schemaInstance._depsLabels[innerKey] && schemaInstance._depsLabels[innerKey].changed();
});
}

Expand Down
32 changes: 25 additions & 7 deletions package/lib/SimpleSchema_labels.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ describe('SimpleSchema - label', function () {
'obj.someString': { type: String },
});

expect(schema.label('minMaxNumber')).toEqual('Min max number');
expect(schema.label('obj.someString')).toEqual('Some string');
expect(schema.label('minMaxNumber')).toBe('Min max number');
expect(schema.label('obj.someString')).toBe('Some string');
});

it('dynamic', function () {
Expand All @@ -22,13 +22,13 @@ describe('SimpleSchema - label', function () {
'obj.someString': { type: String },
});

expect(schema.label('obj.someString')).toEqual('Some string');
expect(schema.label('obj.someString')).toBe('Some string');

schema.labels({
'obj.someString': 'A different label',
});

expect(schema.label('obj.someString')).toEqual('A different label');
expect(schema.label('obj.someString')).toBe('A different label');
});

it('callback', function () {
Expand All @@ -38,13 +38,13 @@ describe('SimpleSchema - label', function () {
'obj.someString': { type: String },
});

expect(schema.label('obj.someString')).toEqual('Some string');
expect(schema.label('obj.someString')).toBe('Some string');

schema.labels({
'obj.someString': () => 'A callback label',
});

expect(schema.label('obj.someString')).toEqual('A callback label');
expect(schema.label('obj.someString')).toBe('A callback label');
});

it('should allow apostrophes ("\'") in labels', () => {
Expand All @@ -54,6 +54,24 @@ describe('SimpleSchema - label', function () {
label: 'Manager/supervisor\'s name',
},
});
expect(schema.label('foo')).toEqual('Manager/supervisor\'s name');
expect(schema.label('foo')).toBe('Manager/supervisor\'s name');
});

it('can set label of field in nested schema', function () {
const objSchema = new SimpleSchema({
someString: String,
});

const schema = new SimpleSchema({
obj: objSchema,
});

expect(schema.label('obj.someString')).toBe('Some string');

schema.labels({
'obj.someString': 'New label',
});

expect(schema.label('obj.someString')).toBe('New label');
});
});

0 comments on commit d8ae4a9

Please sign in to comment.