Skip to content

Instantly share code, notes, and snippets.

@bbody
Last active January 8, 2019 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bbody/0cd99962f72a5a4d3e437995e65e8651 to your computer and use it in GitHub Desktop.
Save bbody/0cd99962f72a5a4d3e437995e65e8651 to your computer and use it in GitHub Desktop.
Schema Compare
// jest.config.js
module.exports = {
verbose: true,
};
const isObjectMappedToSchema = (comparison, schema, throwError = false) => {
// Validate arguments are valid
var areArgumentsValid = true;
try {
validateArguments(comparison, schema);
} catch (error) {
if (throwError) {
throw error;
} else {
return false;
}
}
return compareObjectSchema(comparison, schema);
};
const validateArguments = (comparison, schema) => {
if (!comparison || typeof comparison !== 'object') {
throw 'Invalid comparison object';
}
if (!schema || typeof schema !== 'object') {
throw 'Invalid schema object';
}
};
const compareObjectSchema = (comparison, schema) => {
var schemaKeys = Object.keys(schema);
for (let i = 0; i < schemaKeys.length; i++) {
let schemaKey = schemaKeys[i];
// If schema wants a value then ensure it is defined
if (schema[schemaKey] !== false && typeof comparison[schemaKey] === 'undefined') {
return false;
}
// If schema doesn't want a value ensure it is not defined
if (schema[schemaKey] === false && typeof comparison[schemaKey] !== 'undefined') {
return false;
}
// Check is sub object exists
if (typeof schema[schemaKey] !== 'boolean') {
if (!compareObjectSchema(comparison[schemaKey], schema[schemaKey])) {
return false
}
}
}
return true;
};
module.exports = isObjectMappedToSchema;
const isObjectMappedToSchema = require('./schema-compare');
describe('Argument error handling', () => {
describe('Throwing error', () => {
test('Null object', () => {
expect(isObjectMappedToSchema.bind(null, null, {}, true)).toThrow('Invalid comparison object');
});
test('Undefined object', () => {
expect(isObjectMappedToSchema.bind(null, undefined, {}, true)).toThrow('Invalid comparison object');
});
test('String object', () => {
expect(isObjectMappedToSchema.bind(null, "string", {}, true)).toThrow('Invalid comparison object');
});
test('Null schema', () => {
expect(isObjectMappedToSchema.bind(null, {}, null, true)).toThrow('Invalid schema object');
});
test('Undefined schema', () => {
expect(isObjectMappedToSchema.bind(null, {}, undefined, true)).toThrow('Invalid schema object');
});
test('String schema', () => {
expect(isObjectMappedToSchema.bind(null, {}, "string", true)).toThrow('Invalid schema object');
});
test('No arguments', () => {
expect(isObjectMappedToSchema.bind(null, undefined, undefined, true)).toThrow('Invalid comparison object');
});
});
describe('Returning boolean', () => {
test('Null object', () => {
expect(isObjectMappedToSchema({}, null)).toBeFalsy();
});
test('Undefined object', () => {
expect(isObjectMappedToSchema(undefined, {})).toBeFalsy();
});
test('String object', () => {
expect(isObjectMappedToSchema("string", {})).toBeFalsy();
});
test('Null schema', () => {
expect(isObjectMappedToSchema({}, null)).toBeFalsy();
});
test('Undefined schema', () => {
expect(isObjectMappedToSchema({}, undefined)).toBeFalsy();
});
test('String schema', () => {
expect(isObjectMappedToSchema({}, "string")).toBeFalsy();
});
test('No arguments', () => {
expect(isObjectMappedToSchema()).toBeFalsy();
});
});
});
describe('Basic schema mapping', () => {
test('Empty objects', () => {
expect(isObjectMappedToSchema({}, {})).toBeTruthy();
});
test('Schema and comparison have the same keys', () => {
expect(isObjectMappedToSchema({key: "value"}, {key: true})).toBeTruthy();
});
test('Schema and comparison have the same keys and sub-object', () => {
expect(isObjectMappedToSchema({key: {}}, {key: true})).toBeTruthy();
});
test('Comparison is missing schema objects', () => {
expect(isObjectMappedToSchema({}, {key: true})).toBeFalsy();
});
test('Comparison is missing schema objects but key is false mapped', () => {
expect(isObjectMappedToSchema({}, {key: false})).toBeTruthy();
});
test('Comparison has more keys than schema', () => {
expect(isObjectMappedToSchema({key: {}, key1: {}, key2: {}}, {key: true})).toBeTruthy();
});
test('Comparison and schema have multiple keys', () => {
expect(isObjectMappedToSchema({key1: {}, key2: {}, key3: true}, {key1: true, key2: true, key3: true})).toBeTruthy();
});
test('Comparison and schema have multiple keys with one key missing', () => {
expect(isObjectMappedToSchema({key1: {}, key2: {}}, {key1: true, key2: true, key3: true})).toBeFalsy();
});
});
describe('Nested schema mapping', () => {
test('Sub key is expects a value', () => {
expect(isObjectMappedToSchema({key: {sub_key: {}}}, {key: {sub_key: true}})).toBeTruthy();
});
test('Sub key not in comparison object', () => {
expect(isObjectMappedToSchema({key: {}}, {key: {sub_key: true}})).toBeFalsy();
});
test('Sub key is expects no value', () => {
expect(isObjectMappedToSchema({key: {sub_key: {}}}, {key: {sub_key: false}})).toBeFalsy();
});
test('Schema has complicated mapping but object is empty', () => {
expect(isObjectMappedToSchema({}, {key: {sub_key: {sub_sub_key: {}}}})).toBeFalsy();
});
test('Schema has multiple trees', () => {
const comparison = {
key1: {
sub_key1: {
sub_sub_key1: "hello"
}
},
key2: {
sub_key2: {
sub_sub_key2: "hello"
}
},
key3: {
sub_key3: {
sub_sub_key3: "hello"
}
}
};
const schema = {
key1: {
sub_key1: {
sub_sub_key1: true
}
},
key2: {
sub_key2: {
sub_sub_key2: true
}
},
key3: {
sub_key3: {
sub_sub_key3: true
}
}
};
expect(isObjectMappedToSchema(comparison, schema)).toBeTruthy();
});
test('Schema has multiple trees with a missing subkey', () => {
const comparison = {
key1: {
sub_key1: {
sub_sub_key1: "hello"
}
},
key2: {
sub_key2: {
sub_sub_key2: "hello"
}
},
key3: {
sub_key3: "hello"
}
};
const schema = {
key1: {
sub_key1: {
sub_sub_key1: true
}
},
key2: {
sub_key2: {
sub_sub_key2: true
}
},
key3: {
sub_key3: {
sub_sub_key3: true
}
}
};
expect(isObjectMappedToSchema(comparison, schema)).toBeFalsy();
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment