mirror of
https://github.com/chenasraf/schemastore.git
synced 2026-05-17 17:58:02 +00:00
add: grunt task 'local_coverage' (#2095)
* Add: 'js-beautify' and 'c8' in package.json And update other package to the latest version. * eslint must ignore generated "schema.json.translated.to.js" * .gitignore must ignore src/temp This directory will be autogenerated by make file "coverage" * add: grunt task 'local_coverage' This task will can be called via the makefile And generate a HTML report files stored in 'src/temp/coverage/report/index.html'
This commit is contained in:
committed by
GitHub
parent
879c52c6eb
commit
cbfcc17f80
1
.gitignore
vendored
1
.gitignore
vendored
@@ -126,6 +126,7 @@ ClientBin/
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
.DS_Store
|
||||
src/temp
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
11
Makefile
11
Makefile
@@ -1,4 +1,4 @@
|
||||
.PHONY: build remote
|
||||
.PHONY: build remote maintenance coverage
|
||||
|
||||
build: # Run the local build process
|
||||
cd src && \
|
||||
@@ -18,3 +18,12 @@ maintenance: # Run the maintenance check
|
||||
cd src && \
|
||||
npm install && \
|
||||
npm run maintenance
|
||||
|
||||
# For a specific schema, generate a coverage report in src/temp/coverage/report/index.html
|
||||
# Example: via 'make' to generate coverage report for schema-catalog.json
|
||||
# make coverage schema=schema-catalog.json
|
||||
coverage: # generate HTML coverage report
|
||||
cd src && \
|
||||
npx c8 --temp-directory temp/coverage -x 'Gruntfile.js' grunt local_coverage --SchemaName=$(schema) && \
|
||||
npx c8 --temp-directory temp/coverage report -r html -o temp/coverage/report -x 'Gruntfile.js' && \
|
||||
echo "Full HTML report files stored in 'src/temp/coverage/report/index.html'"
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
{
|
||||
"env": {
|
||||
"es2020": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"standard"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 11
|
||||
},
|
||||
"rules": {
|
||||
}
|
||||
"env": {
|
||||
"es2020": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"standard"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 11
|
||||
},
|
||||
"rules": {
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"schema.json.translated.to.js"
|
||||
]
|
||||
}
|
||||
|
||||
145
src/Gruntfile.js
145
src/Gruntfile.js
@@ -7,6 +7,7 @@ const Ajv2019 = require('ajv/dist/2019')
|
||||
const Ajv2020 = require('ajv/dist/2020')
|
||||
const pt = require('path')
|
||||
const fs = require('fs')
|
||||
const temporaryCoverageDir = 'temp'
|
||||
const schemaDir = 'schemas/json'
|
||||
const testPositiveDir = 'test'
|
||||
const testNegativeDir = 'negative_test'
|
||||
@@ -26,7 +27,6 @@ const countSchemasType = [
|
||||
{ schemaName: 'draft-03', schemaStr: 'json-schema.org/draft-03/schema', totalCount: 0, active: false },
|
||||
{ schemaName: 'draft without version', schemaStr: 'json-schema.org/schema', totalCount: 0, active: false }
|
||||
]
|
||||
|
||||
module.exports = function (grunt) {
|
||||
'use strict'
|
||||
|
||||
@@ -129,7 +129,8 @@ module.exports = function (grunt) {
|
||||
{
|
||||
fullScanAllFiles = false,
|
||||
calledByTV4Validator = false,
|
||||
skipReadFile = true
|
||||
skipReadFile = true,
|
||||
processOnlyThisOneSchemaFile = undefined
|
||||
} = {}) {
|
||||
/**
|
||||
* @summary Check if the present json schema file must be tested or not
|
||||
@@ -162,6 +163,9 @@ module.exports = function (grunt) {
|
||||
}
|
||||
// Process all the schema files one by one via callback.
|
||||
schemasToBeTested.forEach((schemaFileName) => {
|
||||
if (processOnlyThisOneSchemaFile) {
|
||||
if (schemaFileName !== processOnlyThisOneSchemaFile) return
|
||||
}
|
||||
const schemaFullPathName = pt.join(schemaDir, schemaFileName)
|
||||
|
||||
// Some schema files must be ignored.
|
||||
@@ -332,9 +336,11 @@ module.exports = function (grunt) {
|
||||
* @param {string} schemaName
|
||||
* @param {string[]} unknownFormatsList
|
||||
* @param {boolean} fullStrictMode
|
||||
* @param {boolean} standAloneCode
|
||||
* @param {string[]} standAloneCodeWithMultipleSchema
|
||||
* @returns {Object}
|
||||
*/
|
||||
function factoryAJV (schemaName, unknownFormatsList = [], fullStrictMode = true) {
|
||||
function factoryAJV ({ schemaName, unknownFormatsList = [], fullStrictMode = true, standAloneCode = false, standAloneCodeWithMultipleSchema = [] } = {}) {
|
||||
// some AJV default setting are [true, false or log]
|
||||
// Some options are default: 'log'
|
||||
// 'log' will generate a lot of noise in the build log. So make it true or false.
|
||||
@@ -350,6 +356,13 @@ module.exports = function (grunt) {
|
||||
}
|
||||
const ajvOptions = fullStrictMode ? ajvOptionsStrictMode : ajvOptionsNotStrictMode
|
||||
|
||||
// Stand-alone code need some special options parameters
|
||||
if (standAloneCode) {
|
||||
ajvOptions.code = { source: true }
|
||||
if (standAloneCodeWithMultipleSchema.length) {
|
||||
ajvOptions.schemas = standAloneCodeWithMultipleSchema
|
||||
}
|
||||
}
|
||||
let ajvSelected
|
||||
// There are multiple AJV version for each $schema version.
|
||||
// Create the correct one.
|
||||
@@ -455,7 +468,11 @@ module.exports = function (grunt) {
|
||||
versionObj = schemaVersion.getObj(schemaJson)
|
||||
|
||||
// Get the correct AJV version
|
||||
ajvSelected = factoryAJV(versionObj?.schemaName, unknownFormatsList, fullStrictMode)
|
||||
ajvSelected = factoryAJV({
|
||||
schemaName: versionObj?.schemaName,
|
||||
unknownFormatsList: unknownFormatsList,
|
||||
fullStrictMode: fullStrictMode
|
||||
})
|
||||
|
||||
// AJV must ignore these keywords
|
||||
unknownKeywordsList?.forEach((x) => {
|
||||
@@ -597,7 +614,7 @@ module.exports = function (grunt) {
|
||||
|
||||
grunt.registerTask('local_catalog', 'Catalog validation', function () {
|
||||
const catalogSchema = require(pt.resolve('.', schemaDir, 'schema-catalog.json'))
|
||||
const ajvInstance = factoryAJV('draft-04', [])
|
||||
const ajvInstance = factoryAJV({ schemaName: 'draft-04' })
|
||||
if (ajvInstance.validate(catalogSchema, catalog)) {
|
||||
grunt.log.ok('catalog.json OK')
|
||||
} else {
|
||||
@@ -790,7 +807,11 @@ module.exports = function (grunt) {
|
||||
|
||||
const validateViaAjv = (schemaJson, schemaName, option) => {
|
||||
try {
|
||||
const ajvSelected = factoryAJV(schemaName, option.unknownFormatsList, false)
|
||||
const ajvSelected = factoryAJV({
|
||||
schemaName: schemaName,
|
||||
unknownFormatsList: option.unknownFormatsList,
|
||||
fullStrictMode: false
|
||||
})
|
||||
|
||||
// AJV must ignore these keywords
|
||||
option.unknownKeywordsList?.forEach((x) => {
|
||||
@@ -1068,6 +1089,118 @@ module.exports = function (grunt) {
|
||||
grunt.log.ok(`Total schema-validation.json items check: ${countSchemaValidationItems}`)
|
||||
})
|
||||
|
||||
grunt.registerTask('local_coverage', 'Run one selected schema in coverage mode', function () {
|
||||
const javaScriptCoverageName = 'schema.json.translated.to.js'
|
||||
const javaScriptCoverageNameWithPath = pt.join(__dirname, `${temporaryCoverageDir}/${javaScriptCoverageName}`)
|
||||
|
||||
/**
|
||||
* Translate one JSON schema file to javascript via AJV validator.
|
||||
* And run the positive and negative test files with it.
|
||||
* @param {string} processOnlyThisOneSchemaFile The schema file that need to process
|
||||
*/
|
||||
const generateCoverage = (processOnlyThisOneSchemaFile) => {
|
||||
const standaloneCode = require('ajv/dist/standalone').default
|
||||
const schemaVersion = showSchemaVersions()
|
||||
let jsonName
|
||||
let mainSchema
|
||||
let mainSchemaJsonId
|
||||
let isThisWithExternalSchema
|
||||
let validations
|
||||
|
||||
// Compile JSON schema to javascript and write it to disk.
|
||||
const processSchemaFile = (callbackParameter) => {
|
||||
jsonName = callbackParameter.jsonName
|
||||
// Get possible options define in schema-validation.json
|
||||
const {
|
||||
unknownFormatsList,
|
||||
unknownKeywordsList,
|
||||
externalSchemaWithPathList
|
||||
} = getOption(callbackParameter.jsonName)
|
||||
|
||||
// select the correct AJV object for this schema
|
||||
mainSchema = JSON.parse(callbackParameter.rawFile)
|
||||
const versionObj = schemaVersion.getObj(mainSchema)
|
||||
|
||||
// External schema present to be included?
|
||||
const multipleSchema = []
|
||||
isThisWithExternalSchema = externalSchemaWithPathList.length > 0
|
||||
if (isThisWithExternalSchema) {
|
||||
// There is an external schema that need to be included.
|
||||
externalSchemaWithPathList.forEach((x) => {
|
||||
multipleSchema.push(require(x.toString()))
|
||||
})
|
||||
// Also add the 'root' schema
|
||||
multipleSchema.push(mainSchema)
|
||||
}
|
||||
|
||||
// Get the correct AJV version
|
||||
const ajvSelected = factoryAJV({
|
||||
schemaName: versionObj?.schemaName,
|
||||
unknownFormatsList: unknownFormatsList,
|
||||
fullStrictMode: schemaValidation.ajvFullStrictMode.includes(jsonName),
|
||||
standAloneCode: true,
|
||||
standAloneCodeWithMultipleSchema: multipleSchema
|
||||
})
|
||||
|
||||
// AJV must ignore these keywords
|
||||
unknownKeywordsList?.forEach((x) => {
|
||||
ajvSelected.addKeyword(x)
|
||||
})
|
||||
|
||||
let moduleCode
|
||||
if (isThisWithExternalSchema) {
|
||||
// Multiple schemas are combine to one JavaScript file.
|
||||
// Must use the root $id/id to call the correct 'main' schema in JavaScript code
|
||||
mainSchemaJsonId = schemaVersion.getObj(mainSchema).schemaName === 'draft-04' ? mainSchema.id : mainSchema.$id
|
||||
if (!mainSchemaJsonId) {
|
||||
throwWithErrorText([`Missing $id or id in ${jsonName}`])
|
||||
}
|
||||
moduleCode = standaloneCode(ajvSelected)
|
||||
} else { // Single schema
|
||||
mainSchemaJsonId = undefined
|
||||
moduleCode = standaloneCode(ajvSelected, ajvSelected.compile(mainSchema))
|
||||
}
|
||||
|
||||
// Write the javascript module code to file + 'js-beautify' it
|
||||
fs.writeFileSync(javaScriptCoverageNameWithPath, require('js-beautify').js(moduleCode, { indent_size: 2 }))
|
||||
// Now use this JavaScript as validation in the positive and negative test
|
||||
validations = require(javaScriptCoverageNameWithPath)
|
||||
}
|
||||
|
||||
// Load the Javascript file from the disk and run it with the JSON test file.
|
||||
// This will generate the NodeJS coverage data in the background.
|
||||
const processTestFile = (callbackParameter) => {
|
||||
// Test only for the code coverage. Not for the validity of the test.
|
||||
if (isThisWithExternalSchema) {
|
||||
// Must use the root $id/id to call the correct schema JavaScript code
|
||||
const validateRootSchema = validations[mainSchemaJsonId]
|
||||
validateRootSchema?.(JSON.parse(callbackParameter.rawFile))
|
||||
} else {
|
||||
// Single schema does not need $id
|
||||
validations(JSON.parse(callbackParameter.rawFile))
|
||||
}
|
||||
}
|
||||
|
||||
localSchemaFileAndTestFile({
|
||||
schemaForTestScan: processSchemaFile,
|
||||
positiveTestScan: processTestFile,
|
||||
negativeTestScan: processTestFile
|
||||
}, { skipReadFile: false, processOnlyThisOneSchemaFile: processOnlyThisOneSchemaFile })
|
||||
}
|
||||
|
||||
// Generate the schema via option parameter 'SchemaName'
|
||||
const schemaNameToBeCoverage = grunt.option('SchemaName')
|
||||
if (!schemaNameToBeCoverage) {
|
||||
throwWithErrorText(['Must start "make" file with schema name parameter.'])
|
||||
}
|
||||
// Not for tv4 schema files
|
||||
if (schemaValidation.tv4test.includes(schemaNameToBeCoverage)) {
|
||||
throwWithErrorText([`Coverage is not possible for tv4-validator schema file :${schemaNameToBeCoverage}`])
|
||||
}
|
||||
generateCoverage(schemaNameToBeCoverage)
|
||||
grunt.log.ok('OK')
|
||||
})
|
||||
|
||||
grunt.registerTask('local_test',
|
||||
[
|
||||
'local_check_duplicate_list_in_schema-validation.json',
|
||||
|
||||
1628
src/package-lock.json
generated
1628
src/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/schemastore/SchemaStore"
|
||||
},
|
||||
"type": "commonjs",
|
||||
"scripts": {
|
||||
"build": "npm run eslint_check && grunt",
|
||||
"eslint_check": "eslint Gruntfile.js",
|
||||
@@ -21,18 +22,20 @@
|
||||
"maintenance": "grunt local_maintenance"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ajv": "^8.9.0",
|
||||
"ajv-draft-04": "^0.1.0",
|
||||
"ajv": "^8.10.0",
|
||||
"ajv-draft-04": "^1.0.0",
|
||||
"ajv-formats": "^2.1.1",
|
||||
"ajv-formats-draft2019": "^1.6.1",
|
||||
"eslint": "^7.32.0",
|
||||
"c8": "^7.11.0",
|
||||
"eslint": "^8.9.0",
|
||||
"eslint-config-standard": "^16.0.3",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.2.0",
|
||||
"eslint-plugin-promise": "^6.0.0",
|
||||
"find-duplicated-property-keys": "^1.2.7",
|
||||
"got": "^11.8.3",
|
||||
"grunt": "^1.4.1",
|
||||
"grunt-tv4": "^5.0.1"
|
||||
"grunt-tv4": "^5.0.1",
|
||||
"js-beautify": "^1.14.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user