From 3d40238795218fa93a09abf4b2311c912acd081c Mon Sep 17 00:00:00 2001 From: Zach Rose Date: Thu, 22 Feb 2024 15:30:49 -0500 Subject: [PATCH 1/4] Validate one sample with current schemas and ajv --- package.json | 2 ++ test/ajv.js | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 test/ajv.js diff --git a/package.json b/package.json index d20ebc4b..08915a0a 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,8 @@ "tv4-formats": "^3.0.3" }, "devDependencies": { + "ajv": "^8.12.0", + "ajv-draft-04": "^1.0.0", "babel-cli": "^6.24.1", "babel-preset-es2015": "^6.24.1", "chai": "^1.9.2", diff --git a/test/ajv.js b/test/ajv.js new file mode 100644 index 00000000..f3659bd3 --- /dev/null +++ b/test/ajv.js @@ -0,0 +1,66 @@ +const Ajv = require('ajv-draft-04') +const fs = require('fs') +const path = require('path') + +var subSchemas = { + 'notifications': require('../schemas/groups/notifications.json'), + 'communication': require('../schemas/groups/communication.json'), + 'design': require('../schemas/groups/design.json'), + 'navigation': require('../schemas/groups/navigation.json'), + 'electrical': require('../schemas/groups/electrical.json'), + 'environment': require('../schemas/groups/environment.json'), + 'performance': require('../schemas/groups/performance.json'), + 'propulsion': require('../schemas/groups/propulsion.json'), + 'resources': require('../schemas/groups/resources.json'), + 'sails': require('../schemas/groups/sails.json'), + 'sensors': require('../schemas/groups/sensors.json'), + 'sources': require('../schemas/groups/sources.json'), + 'steering': require('../schemas/groups/steering.json'), + 'tanks': require('../schemas/groups/tanks.json') + }; + +var vesselSchema = require('../schemas/vessel.json'); +var aircraftSchema = require('../schemas/aircraft.json'); +var sarSchema = require('../schemas/sar.json'); +var definitions = require('../schemas/definitions.json'); + +function getAjv() { + var ajv = new Ajv({strict: false}) + ajv.addSchema(vesselSchema, 'https://signalk.org/specification/1.5.1/schemas/vessel.json'); + ajv.addSchema(aircraftSchema, 'https://signalk.org/specification/1.5.1/schemas/aircraft.json') + ajv.addSchema(sarSchema, 'https://signalk.org/specification/1.5.1/schemas/sar.json'); + ajv.addSchema(definitions, 'https://signalk.org/specification/1.5.1/schemas/definitions.json'); + + for (var schema in subSchemas) { + ajv.addSchema(subSchemas[schema], 'https://signalk.org/specification/1.5.1/schemas/groups/' + schema + '.json') + } + + // HACK no longer necessary? + var externalGeometry = require('../schemas/external/geojson/geometry.json'); + ajv.addSchema(externalGeometry, 'https://signalk.org/specification/1.5.1/schemas/external/geojson/geometry.json'); + + const tv4Formats = require('tv4-formats'); + for(format in tv4Formats) { + ajv.addFormat(format, tv4Formats[format]) + } + + return ajv; + } + + +describe('the ajv library', () => { + + it('can build a validator out of all the schema files', () => { + const ajv = getAjv() + }) + + describe('validating samples', () => { + it('does this', () => { + const ajv = getAjv() + + const signalKSchema = require('../schemas/signalk.json') + const sampleFull0183RMC = require('../samples/full/0183-RMC-full.json') + ajv.validate(signalKSchema, sampleFull0183RMC) + }) + }) +}) From 08d199bd6fcd5d3968a80aca9f2af5edb412cb16 Mon Sep 17 00:00:00 2001 From: Zach Rose Date: Sat, 24 Feb 2024 13:59:01 -0500 Subject: [PATCH 2/4] Introduce USE_AJV as a seam for testing ajv and tv4 --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 08915a0a..c46a4e16 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "main": "dist/index.js", "scripts": { "test": "babel src --out-dir dist --copy-files && mocha", + "testWithAjv": "babel src --out-dir dist --copy-files && USE_AJV=1 mocha", "prepublish": "npm run docs:keys && npm run js:dist", "js:watch": "babel --watch src --out-dir dist --copy-files", "js:dist": "babel src --out-dir dist --copy-files", From af8121b0257f029cf2833c8d67cd30ab7ee4ab9a Mon Sep 17 00:00:00 2001 From: Zach Rose Date: Fri, 15 Mar 2024 22:37:48 -0400 Subject: [PATCH 3/4] Progress on expanding seam for testing with Ajv --- src/index.js | 141 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 103 insertions(+), 38 deletions(-) diff --git a/src/index.js b/src/index.js index 25d24244..2a4c5aaa 100644 --- a/src/index.js +++ b/src/index.js @@ -18,35 +18,67 @@ var _ = require('lodash'); var FullSignalK = require('./fullsignalk'); - var subSchemas = { - 'notifications': require('../schemas/groups/notifications.json'), - 'communication': require('../schemas/groups/communication.json'), - 'design': require('../schemas/groups/design.json'), - 'navigation': require('../schemas/groups/navigation.json'), - 'electrical': require('../schemas/groups/electrical.json'), - 'environment': require('../schemas/groups/environment.json'), - 'performance': require('../schemas/groups/performance.json'), - 'propulsion': require('../schemas/groups/propulsion.json'), - 'resources': require('../schemas/groups/resources.json'), - 'sails': require('../schemas/groups/sails.json'), - 'sensors': require('../schemas/groups/sensors.json'), - 'sources': require('../schemas/groups/sources.json'), - 'steering': require('../schemas/groups/steering.json'), - 'tanks': require('../schemas/groups/tanks.json') - }; +var subSchemas = { + 'notifications': require('../schemas/groups/notifications.json'), + 'communication': require('../schemas/groups/communication.json'), + 'design': require('../schemas/groups/design.json'), + 'navigation': require('../schemas/groups/navigation.json'), + 'electrical': require('../schemas/groups/electrical.json'), + 'environment': require('../schemas/groups/environment.json'), + 'performance': require('../schemas/groups/performance.json'), + 'propulsion': require('../schemas/groups/propulsion.json'), + 'resources': require('../schemas/groups/resources.json'), + 'sails': require('../schemas/groups/sails.json'), + 'sensors': require('../schemas/groups/sensors.json'), + 'sources': require('../schemas/groups/sources.json'), + 'steering': require('../schemas/groups/steering.json'), + 'tanks': require('../schemas/groups/tanks.json') +}; + +const Ajv = require('ajv-draft-04') +const addAjvFormats = require('ajv-formats') +const tv4Formats = require('tv4-formats'); +const fs = require('fs') +const path = require('path') + +var vesselSchema = require('../schemas/vessel.json'); +var aircraftSchema = require('../schemas/aircraft.json'); +var atonSchema = require('../schemas/aton.json'); +var sarSchema = require('../schemas/sar.json'); +var definitions = require('../schemas/definitions.json'); +var externalGeometry = require('../schemas/external/geojson/geometry.json'); + +function getAjv() { + var ajv = new Ajv({strict: false}) + ajv.addSchema(vesselSchema, 'https://signalk.org/specification/1.5.1/schemas/vessel.json'); + ajv.addSchema(aircraftSchema, 'https://signalk.org/specification/1.5.1/schemas/aircraft.json') + ajv.addSchema(atonSchema, 'https://signalk.org/specification/1.5.1/schemas/aton.json'); + ajv.addSchema(sarSchema, 'https://signalk.org/specification/1.5.1/schemas/sar.json'); + ajv.addSchema(definitions, 'https://signalk.org/specification/1.5.1/schemas/definitions.json'); + for (var schema in subSchemas) { + if(schema == 'sources') { + } + ajv.addSchema(subSchemas[schema], 'https://signalk.org/specification/1.5.1/schemas/groups/' + schema + '.json') + } + ajv.addSchema(externalGeometry, 'https://signalk.org/specification/1.5.1/schemas/external/geojson/geometry.json'); + addAjvFormats(ajv) + + + console.log("################") + console.log(Object.keys(ajv.schemas)) + console.log("################") + return ajv; +} + function getTv4() { var tv4 = require('tv4'); var vesselSchema = require('../schemas/vessel.json'); tv4.addSchema('https://signalk.org/specification/1.5.1/schemas/vessel.json', vesselSchema); - var aircraftSchema = require('../schemas/aircraft.json'); tv4.addSchema('https://signalk.org/specification/1.5.1/schemas/aircraft.json', aircraftSchema); - var atonSchema = require('../schemas/aton.json'); tv4.addSchema('https://signalk.org/specification/1.5.1/schemas/aton.json', atonSchema); - var sarSchema = require('../schemas/sar.json'); tv4.addSchema('https://signalk.org/specification/1.5.1/schemas/sar.json', sarSchema); - var definitions = require('../schemas/definitions.json'); tv4.addSchema('https://signalk.org/specification/1.5.1/schemas/definitions.json', definitions); for (var schema in subSchemas) { @@ -58,23 +90,40 @@ function getTv4() { tv4.addSchema('https://signalk.org/specification/1.5.1/schemas/external/geojson/geometry.json', externalGeometry); tv4.addSchema('http://json-schema.org/geojson/geometry.json', externalGeometry); - tv4.addFormat(require('tv4-formats')) + tv4.addFormat(tv4Formats) return tv4; } +/* + USE_AJV + */ function validateFull(tree) { var signalkSchema = require('../schemas/signalk.json'); - var tv4 = getTv4(); - var valid = getTv4().validateMultiple(tree, signalkSchema, true, true); - var result = tv4.validateResult(tree, signalkSchema, true, true); - //Hack: validateMultiple marks anyOf last match incorrectly as not valid with banUnknownProperties - //https://github.com/geraintluff/tv4/issues/128 - valid.valid = result.valid; - return valid; + if(process.env.USE_AJV) { + var ajv = getAjv(); + const validate = ajv.compile(signalkSchema) + const valid = validate(tree) + return { + valid: valid, + errors: validate.errors + }; + + } else { + var tv4 = getTv4(); + var valid = getTv4().validateMultiple(tree, signalkSchema, true, true); + var result = tv4.validateResult(tree, signalkSchema, true, true); + //Hack: validateMultiple marks anyOf last match incorrectly as not valid with banUnknownProperties + //https://github.com/geraintluff/tv4/issues/128 + valid.valid = result.valid; + return valid; + } } +/* + USE_AJV +*/ function validateDelta(delta, ignoreContext) { var tv4 = require('tv4'); var deltaSchema = require('../schemas/delta.json'); @@ -88,6 +137,9 @@ function validateDelta(delta, ignoreContext) { return valid; } +/* + USE_AJV +*/ function validateWithSchema(msg, schemaName) { var tv4 = require('tv4'); var schema = require('../schemas/' + schemaName); @@ -100,18 +152,30 @@ function chaiAsPromised(chai, utils) { var Assertion = chai.Assertion + /* + Wrangle AJV errors to same format? + */ function checkValidFullSignalK () { var result = validateFull(this._obj); - - var message = result.errors.reduce(function(msgBuilder, error) { - msgBuilder += error.dataPath + ":" + error.message + "\n"; - return msgBuilder; - }, {}); - this.assert( - result.valid - , message - , 'expected #{this} to not be valid SignalK' - ); + if(process.env.USE_AJV) { + var message = "googoogaagaa"; + if(result.valid === false) { + console.log('heres the problem') + console.log(JSON.stringify(this._obj, null, ' ')); + } + message = JSON.stringify(result.errors, null, 2); + this.assert(result.valid, message, 'expected #{this} to not be valid SignalK') + } else { + var message = result.errors.reduce(function(msgBuilder, error) { + msgBuilder += error.dataPath + ":" + error.message + "\n"; + return msgBuilder; + }, {}); + this.assert( + result.valid + , message + , 'expected #{this} to not be valid SignalK' + ); + } } Assertion.addProperty('validSignalK', checkValidFullSignalK); Assertion.addProperty('validFullSignalK', checkValidFullSignalK); @@ -315,6 +379,7 @@ module.exports.fillIdentity = fillIdentity; module.exports.validateDelta = validateDelta; module.exports.chaiModule = chaiAsPromised; module.exports.getTv4 = getTv4; +module.exports.getAjv = getAjv; module.exports.subSchemas = subSchemas; module.exports.units = require('../schemas/definitions').definitions.units; module.exports.metadata = require('./keyswithmetadata.json'); From b67b4f5a9030c61f6491fb39f694efc81255f15e Mon Sep 17 00:00:00 2001 From: Zach Rose Date: Fri, 15 Mar 2024 22:59:01 -0400 Subject: [PATCH 4/4] Fix id for sar schema (seems like this was a typo?) --- schemas/sar.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/sar.json b/schemas/sar.json index 32848514..810ebf52 100644 --- a/schemas/sar.json +++ b/schemas/sar.json @@ -1,7 +1,7 @@ { "type": "object", "$schema": "http://json-schema.org/draft-04/schema#", - "id": "https://signalk.org/specification/1.5.1/schemas/aton.json#", + "id": "https://signalk.org/specification/1.5.1/schemas/sar.json#", "description": "An object describing an individual SAR beacon, eg EPIRB or transponser. It should be an object in sar, named using MMSI or a UUID", "title": "Search and rescue beacons", "anyOf": [