Add support for registry-based type aliases

master
Sven Slootweg 6 years ago
parent 7118d696bb
commit 1c295a4402

@ -5,6 +5,7 @@ const mapObj = require("map-obj");
const typeRules = require("./type-rules");
const generateDescriptor = require("./generate-descriptor");
const generateValidator = require("./generate-validator");
const getSchemaKeys = require("./util/get-schema-keys");
const nullMissingFields = require("./util/null-missing-fields");

@ -72,13 +72,33 @@ module.exports = function generateValidator(rule, name = "<unknown>", registry)
}
};
} else if (rule._isCustomRegistryType) {
/* HACK: We performantly memoize the validator for a registry-stored alias, by storing it in the validator generation scope. */
let aliasValidator;
baseRule = function (value) {
/* FIXME: Better error when the type is unknown */
if (registry._types.get(rule._name)._validator.call(this, value) === true) {
return true;
let actualType = registry._types.get(rule._name);
if (actualType._isCustomType) {
if (actualType._validator.call(this, value) === true) {
return true;
} else {
return new errors.ValidationError(`Expected ${getValueType(rule)}, got ${getValueType(value)} instead`);
}
} else {
/* FIXME: Add support for registry rules to getValueType */
return new errors.ValidationError(`Expected ${getValueType(rule)}, got ${getValueType(value)} instead`);
if (aliasValidator == null) {
aliasValidator = generateValidator(actualType._alias, name, registry);
}
let validatorResult = aliasValidator.call(this, value);
if (validatorResult === true) {
return true;
} else {
// return new errors.ValidationError(`Expected ${getValueType(actualType._alias)}, got ${getValueType(value)} instead`);
/* FIXME: Possible this is done wrong elsewhere too, swallowing the actual validation error? */
return validatorResult;
}
}
};
} else if (rule._isTrait === true) {

@ -4,6 +4,8 @@ const expect = require("chai").expect;
const dm = require("../src");
/* FIXME: setOf/mapOf? */
describe("registry", () => {
let registry = dm.createRegistry();
@ -123,5 +125,25 @@ describe("registry", () => {
flowers.to = flowers;
}).to.throw("Expected an instance of Person, got an instance of Gift instead");
});
it("should work correctly for type aliases", () => {
let CheckedString = registry.createType("CheckedString", dm.string({ matches: /^[a-z]+$/ }));
let SomeType = registry.createType("SomeType", {
value: registry.type("CheckedString")
});
let instance = SomeType({
value: "foo"
});
expect(instance.value).to.equal("foo");
expect(() => {
SomeType({
value: "bar42"
});
}).to.throw("Value for property 'value' failed `matches` condition");
})
});
});

Loading…
Cancel
Save