raml-typesystem
Advanced tools
Comparing version 0.0.48 to 0.0.49
@@ -118,3 +118,3 @@ "use strict"; | ||
var rfc2616 = false; | ||
c.allCustomFacets().forEach(function (x) { | ||
c.allFacets().forEach(function (x) { | ||
if (x.facetName() == "format") { | ||
@@ -121,0 +121,0 @@ if (x.value() === "rfc2616") { |
@@ -26,3 +26,11 @@ "use strict"; | ||
FacetPrototype.prototype.isApplicable = function (t) { | ||
return t.isSubTypeOf(this.newInstance().requiredType()); | ||
var instance = this.newInstance(); | ||
var requiredType = instance.requiredType(); | ||
var requiredTypes = instance.requiredTypes(); | ||
if (requiredTypes && requiredTypes.length > 0) { | ||
return requiredTypes.some(function (currentRType) { return t.isSubTypeOf(currentRType); }); | ||
} | ||
else { | ||
return t.isSubTypeOf(requiredType); | ||
} | ||
}; | ||
@@ -59,2 +67,3 @@ FacetPrototype.prototype.isInheritable = function () { | ||
new FacetPrototype(function () { return new restrictions_1.Pattern("."); }, function (x) { return new restrictions_1.Pattern(x); }), | ||
new FacetPrototype(function () { return new restrictions_1.Format(""); }, function (x) { return new restrictions_1.Format(x); }), | ||
new FacetPrototype(function () { return new restrictions_1.PropertyIs("x", ts.ANY); }, null), | ||
@@ -61,0 +70,0 @@ new FacetPrototype(function () { return new restrictions_1.AdditionalPropertyIs(ts.ANY); }, null), |
@@ -572,2 +572,36 @@ "use strict"; | ||
/** | ||
* Analogue of type.isSubTypeOf(), but also checks through unions | ||
* @param potentialSubtype | ||
* @param potentialSupertype | ||
*/ | ||
function isSubtypeOf(potentialSubtype, potentialSupertype) { | ||
//TODO this algorithm should be moved to type.isSubTypeOf() after release (now leaving it here for safety) | ||
if (potentialSupertype === ts.ANY || | ||
potentialSubtype === potentialSupertype || | ||
potentialSubtype.superTypes().some(function (currentSuperType) { return isSubtypeOf(currentSuperType, potentialSupertype); })) { | ||
return true; | ||
} | ||
if (potentialSubtype.isUnion() && potentialSubtype.options) { | ||
var options = potentialSubtype.options(); | ||
if (options.some(function (option) { return isSubtypeOf(option, potentialSupertype); })) | ||
return true; | ||
} | ||
if (potentialSupertype.isUnion() && potentialSupertype.options) { | ||
var options = potentialSupertype.options(); | ||
if (options.some(function (option) { return potentialSubtype == option; })) | ||
return true; | ||
} | ||
return false; | ||
} | ||
function testFacetAgainstType(facet, type) { | ||
var requiredType = facet.requiredType(); | ||
var requiredTypes = facet.requiredTypes(); | ||
if (requiredTypes && requiredTypes.length > 0) { | ||
return requiredTypes.some(function (currentRType) { return isSubtypeOf(type, currentRType); }); | ||
} | ||
else { | ||
return isSubtypeOf(type, requiredType); | ||
} | ||
} | ||
/** | ||
* parses a type from a JSON structure | ||
@@ -711,3 +745,4 @@ * @param name | ||
var vl = facetR.getInstance().buildFacet(key, x.value()); | ||
if (vl /*&&result.isSubTypeOf(vl.requiredType())*/) { | ||
//TODO remove "format" condition and use this check for all facets | ||
if (vl && (key != "format" || testFacetAgainstType(vl, result))) { | ||
vl.setNode(x); | ||
@@ -714,0 +749,0 @@ result.addMeta(vl); |
@@ -116,2 +116,11 @@ /// <reference path="../../typings/main.d.ts" /> | ||
abstract value(): T; | ||
/** | ||
* Extension of requiredType() method for the case when there are more than a single type | ||
* hierarchy roots to cover. | ||
* requiredType() should return the common superclass for the list. | ||
* | ||
* @returns {Array} of types or empty list of there is only a single type set by requiredType() method | ||
*/ | ||
requiredTypes(): ts.AbstractType[]; | ||
private checkOwner(requiredType); | ||
validateSelf(registry: ts.TypeRegistry): ts.Status; | ||
@@ -264,2 +273,17 @@ } | ||
/** | ||
* regular expression (pattern) constraint | ||
*/ | ||
export declare class Format extends FacetRestriction<string> { | ||
private _value; | ||
constructor(_value: string); | ||
facetName(): string; | ||
requiredType(): ts.InheritedType; | ||
requiredTypes(): ts.InheritedType[]; | ||
check(i: any): ts.Status; | ||
composeWith(r: ts.Constraint): ts.Constraint; | ||
value(): string; | ||
checkValue(): any; | ||
toString(): string; | ||
} | ||
/** | ||
* enum constraint | ||
@@ -266,0 +290,0 @@ */ |
@@ -535,6 +535,16 @@ "use strict"; | ||
} | ||
FacetRestriction.prototype.validateSelf = function (registry) { | ||
/** | ||
* Extension of requiredType() method for the case when there are more than a single type | ||
* hierarchy roots to cover. | ||
* requiredType() should return the common superclass for the list. | ||
* | ||
* @returns {Array} of types or empty list of there is only a single type set by requiredType() method | ||
*/ | ||
FacetRestriction.prototype.requiredTypes = function () { | ||
return []; | ||
}; | ||
FacetRestriction.prototype.checkOwner = function (requiredType) { | ||
var ownerIsCorrect = false; | ||
if (this.requiredType().isUnion()) { | ||
var family = this.requiredType().typeFamily(); | ||
if (requiredType.isUnion()) { | ||
var family = requiredType.typeFamily(); | ||
for (var _i = 0, family_1 = family; _i < family_1.length; _i++) { | ||
@@ -549,6 +559,27 @@ var tp = family_1[_i]; | ||
else { | ||
ownerIsCorrect = this.owner().isSubTypeOf(this.requiredType()); | ||
ownerIsCorrect = this.owner().isSubTypeOf(requiredType); | ||
} | ||
return ownerIsCorrect; | ||
}; | ||
FacetRestriction.prototype.validateSelf = function (registry) { | ||
var _this = this; | ||
var ownerIsCorrect = false; | ||
if (this.checkOwner(this.requiredType())) { | ||
if (this.requiredTypes() && this.requiredTypes().length > 0) { | ||
var owner = this.owner(); | ||
var correctRequiredSuperType = _.find(this.requiredTypes(), function (requiredType) { return _this.checkOwner(requiredType); }); | ||
if (correctRequiredSuperType) { | ||
ownerIsCorrect = true; | ||
} | ||
} | ||
else { | ||
ownerIsCorrect = true; | ||
} | ||
} | ||
if (!ownerIsCorrect) { | ||
var rs = ts.error(this.facetName() + " facet can only be used with " + this.requiredType().name() + " types", this); | ||
var typeNames = this.requiredType().name(); | ||
if (this.requiredTypes() && this.requiredTypes().length > 0) { | ||
typeNames = "[" + this.requiredTypes().map(function (requiredType) { return requiredType.name(); }).join() + "]"; | ||
} | ||
var rs = ts.error(this.facetName() + " facet can only be used with " + typeNames + " types", this); | ||
rs.setValidationPath({ name: this.facetName() }); | ||
@@ -896,2 +927,5 @@ return rs; | ||
UniqueItems.prototype.check = function (i) { | ||
if (!this._value) { | ||
return ts.ok(); | ||
} | ||
if (Array.isArray(i)) { | ||
@@ -945,3 +979,3 @@ var r = i; | ||
for (var j = 0; j < ar.length; j++) { | ||
var ss = this.type.validate(ar[j], false); | ||
var ss = this.type.validate(ar[j], false, false); | ||
if (!ss.isOk()) { | ||
@@ -1080,2 +1114,65 @@ var t = this.type; | ||
/** | ||
* regular expression (pattern) constraint | ||
*/ | ||
var Format = (function (_super) { | ||
__extends(Format, _super); | ||
function Format(_value) { | ||
_super.call(this); | ||
this._value = _value; | ||
} | ||
Format.prototype.facetName = function () { return "format"; }; | ||
Format.prototype.requiredType = function () { | ||
return ts.SCALAR; | ||
}; | ||
Format.prototype.requiredTypes = function () { | ||
return [ts.NUMBER, ts.INTEGER, ts.DATETIME]; | ||
}; | ||
Format.prototype.check = function (i) { | ||
return ts.ok(); | ||
}; | ||
Format.prototype.composeWith = function (r) { | ||
if (r instanceof Format) { | ||
var v = r; | ||
if (v._value === this._value) { | ||
return this; | ||
} | ||
return this.nothing(r, "Format restrictions can not be composed at one type"); | ||
} | ||
return null; | ||
}; | ||
Format.prototype.value = function () { | ||
return this._value; | ||
}; | ||
Format.prototype.checkValue = function () { | ||
var _this = this; | ||
try { | ||
var allowedValues = []; | ||
if (this.owner().isSubTypeOf(ts.INTEGER)) { | ||
allowedValues = ["int32", "int64", "int", "int16", "int8"]; | ||
} | ||
else if (this.owner().isSubTypeOf(ts.NUMBER)) { | ||
allowedValues = ["int32", "int64", "int", "long", "float", "double", "int16", "int8"]; | ||
} | ||
else if (this.owner().isSubTypeOf(ts.DATETIME)) { | ||
allowedValues = ["rfc3339", "rfc2616"]; | ||
} | ||
else | ||
return null; | ||
var found = _.find(allowedValues, function (allowedValue) { return allowedValue == _this.value(); }); | ||
if (!found) { | ||
return "Following format values are allowed: " + allowedValues.join(); | ||
} | ||
} | ||
catch (e) { | ||
return e.message; | ||
} | ||
return null; | ||
}; | ||
Format.prototype.toString = function () { | ||
return "should have format:" + this.value; | ||
}; | ||
return Format; | ||
}(FacetRestriction)); | ||
exports.Format = Format; | ||
/** | ||
* enum constraint | ||
@@ -1122,2 +1219,10 @@ */ | ||
} | ||
if (this.requiredTypes() && this.requiredTypes().length > 0) { | ||
var owner = this.owner(); | ||
var requiredSuperType = _.find(this.requiredTypes(), function (requiredType) { return owner.isSubTypeOf(requiredType); }); | ||
if (!requiredSuperType) { | ||
var typeNames = "[" + this.requiredTypes().map(function (requiredType) { return requiredType.name(); }).join() + "]"; | ||
return "enum facet can only be used with: " + typeNames; | ||
} | ||
} | ||
if (!Array.isArray(this._value)) { | ||
@@ -1124,0 +1229,0 @@ return "enum facet value must be defined by array"; |
@@ -58,2 +58,10 @@ /// <reference path="../../typings/main.d.ts" /> | ||
abstract requiredType(): AbstractType; | ||
/** | ||
* Extension of requiredType() method for the case when there are more than a single type | ||
* hierarchy roots to cover. | ||
* requiredType() should return the common superclass for the list. | ||
* | ||
* @returns {Array} of types or empty list of there is only a single type set by requiredType() method | ||
*/ | ||
requiredTypes(): AbstractType[]; | ||
abstract kind(): tsInterfaces.MetaInformationKind; | ||
@@ -60,0 +68,0 @@ } |
@@ -506,3 +506,4 @@ /// <reference path="../typings/main.d.ts" /> | ||
it("All facets", function () { | ||
assert.equal(facetRegistry.getInstance().allPrototypes().length, 30); | ||
assert.equal(facetRegistry.getInstance().allPrototypes().length, 31); | ||
// assert.equal(facetRegistry.getInstance().allPrototypes().length,30); | ||
}); | ||
@@ -509,0 +510,0 @@ it("All object facets", function () { |
@@ -236,2 +236,146 @@ "use strict"; | ||
}); | ||
it("validating number format positive 1", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int32" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 1", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int64" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 2", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 3", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "long" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 5", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "float" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 6", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "double" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 7", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int16" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 8", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int8" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format negative", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "blah" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(!st.isOk()); | ||
}); | ||
it("validating integer format positive 1", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "int64" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating integer format positive 2", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "int" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating integer format positive 3", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "int16" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating integer format positive 4", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "int8" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating integer format negative", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "blah" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(!st.isOk()); | ||
}); | ||
it("validating integer format negative 2", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "double" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(!st.isOk()); | ||
}); | ||
it("validating datetime format positive 1", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "datetime", | ||
format: "rfc2616" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating datetime format positive 2", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "datetime", | ||
format: "rfc3339" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating datetime format negative", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "datetime", | ||
format: "blah" | ||
}); | ||
var st = tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(!st.isOk()); | ||
}); | ||
}); | ||
@@ -238,0 +382,0 @@ describe("Type hierarchy validation", function () { |
{ | ||
"name": "raml-typesystem", | ||
"version": "0.0.48", | ||
"version": "0.0.49", | ||
"main": "dist/src/index.js", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -105,3 +105,3 @@ declare function require(path:string):any | ||
var rfc2616=false; | ||
c.allCustomFacets().forEach(x=>{ | ||
c.allFacets().forEach(x=>{ | ||
if (x.facetName()=="format") { | ||
@@ -108,0 +108,0 @@ if (x.value()==="rfc2616"){ |
@@ -10,3 +10,4 @@ import ts=require("./typesystem") | ||
Maximum, Enum, Pattern, UniqueItems, | ||
PropertyIs, AdditionalPropertyIs , MapPropertyIs, HasProperty, KnownPropertyRestriction, ComponentShouldBeOfType} from "./restrictions"; | ||
PropertyIs, AdditionalPropertyIs , MapPropertyIs, HasProperty, | ||
KnownPropertyRestriction, ComponentShouldBeOfType, Format} from "./restrictions"; | ||
@@ -37,3 +38,10 @@ import {Default, Example, Description, DisplayName} from "./metainfo"; | ||
isApplicable(t:ts.AbstractType):boolean{ | ||
return t.isSubTypeOf(this.newInstance().requiredType()); | ||
var instance = this.newInstance(); | ||
var requiredType = instance.requiredType() | ||
var requiredTypes = instance.requiredTypes(); | ||
if (requiredTypes && requiredTypes.length > 0) { | ||
return requiredTypes.some(currentRType=>t.isSubTypeOf(currentRType)) | ||
} else { | ||
return t.isSubTypeOf(requiredType); | ||
} | ||
} | ||
@@ -71,2 +79,3 @@ | ||
new FacetPrototype(()=>new Pattern("."), (x)=>new Pattern(x)),//X | ||
new FacetPrototype(()=>new Format(""), (x)=>new Format(x)),//X | ||
new FacetPrototype(()=>new PropertyIs("x", ts.ANY), null),//X | ||
@@ -73,0 +82,0 @@ new FacetPrototype(()=>new AdditionalPropertyIs(ts.ANY), null),//X |
@@ -625,2 +625,43 @@ import ts=require("./typesystem") | ||
/** | ||
* Analogue of type.isSubTypeOf(), but also checks through unions | ||
* @param potentialSubtype | ||
* @param potentialSupertype | ||
*/ | ||
function isSubtypeOf(potentialSubtype : ts.AbstractType, potentialSupertype : ts.AbstractType) : boolean { | ||
//TODO this algorithm should be moved to type.isSubTypeOf() after release (now leaving it here for safety) | ||
if (potentialSupertype===ts.ANY || | ||
potentialSubtype===potentialSupertype || | ||
potentialSubtype.superTypes().some( | ||
currentSuperType=>isSubtypeOf(currentSuperType,potentialSupertype))) { | ||
return true; | ||
} | ||
if (potentialSubtype.isUnion() && (<any>potentialSubtype).options) { | ||
var options = (<ts.UnionType>potentialSubtype).options(); | ||
if (options.some( | ||
option=>isSubtypeOf(option,potentialSupertype))) return true; | ||
} | ||
if (potentialSupertype.isUnion() && (<any>potentialSupertype).options) { | ||
var options = (<ts.UnionType>potentialSupertype).options(); | ||
if (options.some( | ||
option=>potentialSubtype==option)) return true; | ||
} | ||
return false; | ||
} | ||
function testFacetAgainstType(facet : ts.TypeInformation, type : ts.AbstractType) : boolean { | ||
var requiredType = facet.requiredType(); | ||
var requiredTypes = facet.requiredTypes(); | ||
if (requiredTypes && requiredTypes.length > 0) { | ||
return requiredTypes.some(currentRType=>isSubtypeOf(type, currentRType)) | ||
} else { | ||
return isSubtypeOf(type, requiredType); | ||
} | ||
} | ||
/** | ||
* parses a type from a JSON structure | ||
@@ -777,3 +818,5 @@ * @param name | ||
var vl=facetR.getInstance().buildFacet(key, x.value()); | ||
if (vl/*&&result.isSubTypeOf(vl.requiredType())*/){ | ||
//TODO remove "format" condition and use this check for all facets | ||
if (vl && (key != "format" || testFacetAgainstType(vl, result))){ | ||
vl.setNode(x); | ||
@@ -780,0 +823,0 @@ result.addMeta(vl); |
@@ -541,8 +541,18 @@ /// <reference path="../typings/main.d.ts" /> | ||
/** | ||
* Extension of requiredType() method for the case when there are more than a single type | ||
* hierarchy roots to cover. | ||
* requiredType() should return the common superclass for the list. | ||
* | ||
* @returns {Array} of types or empty list of there is only a single type set by requiredType() method | ||
*/ | ||
requiredTypes():ts.AbstractType[] { | ||
return []; | ||
} | ||
validateSelf(registry:ts.TypeRegistry):ts.Status{ | ||
private checkOwner(requiredType : ts.AbstractType) : boolean { | ||
var ownerIsCorrect = false; | ||
if(this.requiredType().isUnion()){ | ||
var family = (<ts.UnionType>this.requiredType()).typeFamily(); | ||
if(requiredType.isUnion()){ | ||
var family = (<ts.UnionType>requiredType).typeFamily(); | ||
for(var tp of family){ | ||
@@ -556,6 +566,32 @@ if(this.owner().isSubTypeOf(tp)){ | ||
else{ | ||
ownerIsCorrect = this.owner().isSubTypeOf(this.requiredType()); | ||
ownerIsCorrect = this.owner().isSubTypeOf(requiredType); | ||
} | ||
return ownerIsCorrect; | ||
} | ||
validateSelf(registry:ts.TypeRegistry):ts.Status{ | ||
var ownerIsCorrect = false; | ||
if (this.checkOwner(this.requiredType())) { | ||
if (this.requiredTypes() && this.requiredTypes().length > 0) { | ||
var owner = this.owner(); | ||
var correctRequiredSuperType = _.find(this.requiredTypes(), requiredType=>this.checkOwner(requiredType)); | ||
if (correctRequiredSuperType) { | ||
ownerIsCorrect = true; | ||
} | ||
} else { | ||
ownerIsCorrect = true; | ||
} | ||
} | ||
if (!ownerIsCorrect){ | ||
var rs= ts.error(this.facetName()+" facet can only be used with "+this.requiredType().name()+" types",this); | ||
var typeNames = this.requiredType().name(); | ||
if (this.requiredTypes() && this.requiredTypes().length > 0) { | ||
typeNames = "[" + this.requiredTypes().map(requiredType=>requiredType.name()).join() + "]" | ||
} | ||
var rs= ts.error(this.facetName()+" facet can only be used with "+ typeNames +" types",this); | ||
rs.setValidationPath({name:this.facetName()}); | ||
@@ -910,2 +946,6 @@ return rs; | ||
check(i:any):ts.Status{ | ||
if(!this._value) { | ||
return ts.ok(); | ||
} | ||
if (Array.isArray(i)){ | ||
@@ -919,4 +959,3 @@ var r:any[]=i; | ||
} | ||
composeWith(r:ts.Constraint):ts.Constraint{ | ||
@@ -962,3 +1001,3 @@ if (r instanceof UniqueItems){ | ||
for (var j=0;j<ar.length;j++){ | ||
var ss=this.type.validate(ar[j],false); | ||
var ss=this.type.validate(ar[j],false,false); | ||
if (!ss.isOk()){ | ||
@@ -1098,3 +1137,66 @@ var t=this.type; | ||
} | ||
/** | ||
* regular expression (pattern) constraint | ||
*/ | ||
export class Format extends FacetRestriction<string>{ | ||
constructor(private _value:string){ | ||
super(); | ||
} | ||
facetName(){return "format"} | ||
requiredType(){ | ||
return ts.SCALAR | ||
} | ||
requiredTypes() { | ||
return [ts.NUMBER, ts.INTEGER, ts.DATETIME]; | ||
} | ||
check(i:any):ts.Status{ | ||
return ts.ok() | ||
} | ||
composeWith(r:ts.Constraint):ts.Constraint{ | ||
if (r instanceof Format){ | ||
var v=<Format>r; | ||
if (v._value===this._value){ | ||
return this; | ||
} | ||
return this.nothing(r,"Format restrictions can not be composed at one type"); | ||
} | ||
return null; | ||
} | ||
value(){ | ||
return this._value; | ||
} | ||
checkValue(){ | ||
try{ | ||
var allowedValues : string[] = []; | ||
if (this.owner().isSubTypeOf(ts.INTEGER)) { | ||
allowedValues = ["int32", "int64", "int", "int16", "int8"]; | ||
} else if (this.owner().isSubTypeOf(ts.NUMBER)) { | ||
allowedValues = ["int32", "int64", "int", "long", "float", "double", "int16", "int8"]; | ||
} else if (this.owner().isSubTypeOf(ts.DATETIME)) { | ||
allowedValues = ["rfc3339", "rfc2616"]; | ||
} else return null; | ||
var found = _.find(allowedValues, allowedValue=>allowedValue==this.value()); | ||
if (!found) { | ||
return "Following format values are allowed: " + allowedValues.join(); | ||
} | ||
} | ||
catch (e){ | ||
return e.message; | ||
} | ||
return null; | ||
} | ||
toString(){ | ||
return "should have format:"+this.value; | ||
} | ||
} | ||
/** | ||
* enum constraint | ||
@@ -1144,4 +1246,11 @@ */ | ||
return "enum facet can only be used with: "+this.requiredType().name(); | ||
} | ||
if (this.requiredTypes() && this.requiredTypes().length > 0) { | ||
var owner = this.owner(); | ||
var requiredSuperType = _.find(this.requiredTypes(), requiredType=>owner.isSubTypeOf(requiredType)); | ||
if (!requiredSuperType) { | ||
var typeNames = "[" + this.requiredTypes().map(requiredType=>requiredType.name()).join() + "]"; | ||
return "enum facet can only be used with: " + typeNames; | ||
} | ||
} | ||
if(!Array.isArray(this._value)){ | ||
@@ -1148,0 +1257,0 @@ return "enum facet value must be defined by array"; |
@@ -211,2 +211,14 @@ /// <reference path="../typings/main.d.ts" /> | ||
abstract requiredType():AbstractType | ||
/** | ||
* Extension of requiredType() method for the case when there are more than a single type | ||
* hierarchy roots to cover. | ||
* requiredType() should return the common superclass for the list. | ||
* | ||
* @returns {Array} of types or empty list of there is only a single type set by requiredType() method | ||
*/ | ||
requiredTypes():AbstractType[] { | ||
return []; | ||
} | ||
abstract kind() : tsInterfaces.MetaInformationKind | ||
@@ -213,0 +225,0 @@ } |
@@ -516,3 +516,4 @@ /// <reference path="../typings/main.d.ts" /> | ||
it ("All facets",function (){ | ||
assert.equal(facetRegistry.getInstance().allPrototypes().length,30); | ||
assert.equal(facetRegistry.getInstance().allPrototypes().length,31); | ||
// assert.equal(facetRegistry.getInstance().allPrototypes().length,30); | ||
}); | ||
@@ -519,0 +520,0 @@ it ("All object facets",function (){ |
@@ -239,2 +239,148 @@ import ps= require("./actualParse") | ||
}); | ||
it("validating number format positive 1", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int32" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 1", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int64" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 2", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 3", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "long" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 5", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "float" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 6", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "double" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 7", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int16" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format positive 8", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "int8" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating number format negative", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "number", | ||
format: "blah" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(!st.isOk()); | ||
}); | ||
it("validating integer format positive 1", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "int64" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating integer format positive 2", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "int" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating integer format positive 3", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "int16" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating integer format positive 4", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "int8" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating integer format negative", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "blah" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(!st.isOk()); | ||
}); | ||
it("validating integer format negative 2", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "integer", | ||
format: "double" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(!st.isOk()); | ||
}); | ||
it("validating datetime format positive 1", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "datetime", | ||
format: "rfc2616" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating datetime format positive 2", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "datetime", | ||
format: "rfc3339" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(st.isOk()); | ||
}); | ||
it("validating datetime format negative", function () { | ||
var tp = ps.parseJSON("TestType", { | ||
type: "datetime", | ||
format: "blah" | ||
}) | ||
var st= tp.validateType(ts.builtInRegistry()); | ||
assert.isTrue(!st.isOk()); | ||
}); | ||
}); | ||
@@ -241,0 +387,0 @@ describe("Type hierarchy validation",function() { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1895557
42240