diff --git a/package.json b/package.json index 2919d14..e5108e9 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,8 @@ "mocha": "~1.8.2", "rimraf": "~2.1.1", "zfill": "0.0.1", - "batch": "~0.3.1" + "batch": "~0.3.1", + "jsonschema": "~1.0.1" }, "dependencies": { "buffer-equal": "0.0.0", diff --git a/protocol/protocol_schema.json b/protocol/protocol_schema.json new file mode 100644 index 0000000..7cd75fe --- /dev/null +++ b/protocol/protocol_schema.json @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "protocol", + + "definitions": { + "directions": { + "type": "object", + "properties":{ + "toClient":{"$ref" : "#/definitions/packets"}, + "toServer":{"$ref" : "#/definitions/packets"} + }, + "required":["toClient","toServer"], + "additionalProperties": false + }, + "packets": { + "type": "object", + "patternProperties": { + "^[a-z_]+$": {"$ref" : "#/definitions/packet"} + }, + "additionalProperties": false + }, + "packet": { + "type": "object", + "properties":{ + "id": {"$ref" : "#/definitions/id"}, + "fields": {"$ref" : "#/definitions/fields"} + }, + "required":["id","fields"], + "additionalProperties": false + }, + "id": { + "type": "string", + "pattern": "^0x[0-9a-f]{2}$" + }, + "fields" : { + "type": "array", + "items": {"$ref" : "#/definitions/field"}, + "additionalItems": false + }, + "field": { + "type": "object", + "properties": { + "name": {"$ref" : "#/definitions/fieldName"}, + "type": {"$ref" : "#/definitions/fieldType"}, + "typeArgs": {"$ref" : "#/definitions/fieldTypeArgs"}, + "condition": {"$ref" : "#/definitions/fieldCondition"} + }, + "required":["name","type"], + "additionalProperties": false + }, + "fieldName": { + "type":"string", + "pattern": "^[a-zA-Z0-9_]+$" + }, + "fieldType": { + "type":"string", + "pattern": "^[a-zA-Z]+$" + }, + "fieldTypeArgs": { + "type":"object", + "properties":{ + "type": {"$ref" : "#/definitions/fieldType"}, + "countFor": {"$ref" : "#/definitions/fieldTypeArgsCountFor"}, + "count": {"$ref" : "#/definitions/fieldTypeArgsCount"}, + "fields": {"$ref" : "#/definitions/fields"}, + "typeArgs": {"$ref" : "#/definitions/fieldTypeArgs"} + }, + "additionalProperties": false + }, + "fieldTypeArgsCountFor": { + "type":"string", + "pattern": "^(this\\.)?[a-zA-Z0-9_]+$" + }, + "fieldTypeArgsCount": { + "oneOf": [ + {"$ref" : "#/definitions/fieldTypeArgsCountFor"}, + { + "type":"object", + "properties":{ + "field":{"$ref" : "#/definitions/fieldName"}, + "map":{ + "type":"object", + "patternProperties":{ + "^[0-9]+$":{ + "type":"integer" + } + }, + "additionalProperties": false + }, + "default":{ + "type":"integer" + } + }, + "required":["field","map","default"], + "additionalProperties": false + } + ] + }, + "fieldCondition": { + "type": "object", + "properties":{ + "field": {"$ref" : "#/definitions/fieldName"}, + "values": { + "type": "array", + "items": { + "type": ["integer","boolean"] + }, + "additionalItems": false, + "minItems": 1 + }, + "different": { + "type": "boolean" + }, + "this": { + "type": "boolean" + } + }, + "required": ["field","values"], + "additionalProperties": false + } + }, + + "type": "object", + "patternProperties": { + "^[a-z]+$":{"$ref" : "#/definitions/directions"} + }, + "additionalProperties": false +} diff --git a/test/validate.js b/test/validate.js new file mode 100644 index 0000000..7447f9c --- /dev/null +++ b/test/validate.js @@ -0,0 +1,16 @@ +var assert = require('assert'); + +var Validator = require('jsonschema').Validator; +var v = new Validator(); + +Error.stackTraceLimit=0; + +describe("protocol schema", function() { + this.timeout(60 * 1000); + it("protocol.json is valid",function(){ + var instance = require('../protocol/protocol.json'); + var schema = require('../protocol/protocol_schema.json'); + var result = v.validate(instance, schema); + assert.strictEqual(result.errors.length,0,require('util').inspect(result.errors,{'depth':4})); + }); +});