@@ -14,6 +14,7 @@ | |||
}, | |||
"homepage": "https://github.com/VCVRack/community#readme", | |||
"devDependencies": { | |||
"ajv": "^5.5.2", | |||
"jasmine": "^2.8.0", | |||
"node-virustotal": "^2.4.2", | |||
"request": "^2.83.0" | |||
@@ -0,0 +1,27 @@ | |||
# Jasmine Tests | |||
[Jasmine Intro](https://jasmine.github.io/2.8/introduction.html) | |||
To run all tests: | |||
``` | |||
npm test | |||
``` | |||
To run only the zip tests for example: | |||
``` | |||
./node_modules/.bin/jasmine --filter=zip | |||
``` | |||
# Virus Total | |||
**Rate Limit: 4 per minute** | |||
`VT_API_KEY` env var is required and already set in travisci settings | |||
[Public API](https://www.virustotal.com/en/documentation/public-api/v2/) | |||
[Node Module](https://github.com/natewatson999/node-virustotal) | |||
@@ -0,0 +1,59 @@ | |||
const CUR_VER_PREFIX = '0.5'; | |||
const fs = require("fs"); | |||
const Ajv = require('ajv'); //https://github.com/epoberezkin/ajv | |||
const ajv = new Ajv({}); | |||
const validate = ajv.compile(require('./manifest.json')); | |||
describe("json", function() { | |||
it("manifest files should be valid against the schema", function(done) { | |||
fs.readdir('plugins', function(err, files) { | |||
if (err){ | |||
fail("unable to read plugins dir"); | |||
} | |||
for (let index in files) { | |||
const fileName = files[index]; | |||
const filePath = `plugins/${fileName}`; | |||
if(!filePath.toLowerCase().endsWith('.json')){ | |||
fail("manifests should have .json extension"); | |||
} | |||
fs.readFile(filePath, 'utf8', (err, fileContent) => { | |||
if (err){ | |||
fail("unable to read manifest file"); | |||
} | |||
let manifestObj; | |||
try { | |||
const obj = JSON.parse(fileContent); | |||
const valid = validate(obj); | |||
if (!valid) { | |||
validate.errors.map(e=>e.message+=` in ${filePath}`) | |||
fail(validate.errors); | |||
} | |||
if(!(/^[a-zA-Z0-9_\-]*$/).test(obj.slug)){ | |||
fail(`slug does not match regex in ${filePath}`); | |||
} | |||
if(fileName.replace('.json','') !== obj.slug){ | |||
fail(`slug '${obj.slug}' does not match fileName: ${fileName}`); | |||
} | |||
if(obj.version && !obj.version.startsWith(CUR_VER_PREFIX)){ | |||
fail(`version '${obj.version}' must start with '${CUR_VER_PREFIX}'`); | |||
} | |||
done(); | |||
} catch(err){ | |||
fail(`Invalid JSON: ${filePath}\n${err}`); | |||
} | |||
}); | |||
} | |||
}); | |||
}); | |||
}); |
@@ -1,35 +0,0 @@ | |||
//Jasmine Test - https://jasmine.github.io/2.8/introduction.html | |||
const fs = require("fs"); | |||
describe("json", function() { | |||
it("manifest files should be valid parsable json", function(done) { | |||
fs.readdir('plugins', function(err, files) { | |||
if (err){ | |||
fail("unable to read plugins dir"); | |||
} | |||
for (let index in files) { | |||
const filePath = `plugins/${files[index]}`; | |||
if(!filePath.toLowerCase().endsWith('.json')){ | |||
fail("manifests should have .json extension"); | |||
} | |||
fs.readFile(filePath, 'utf8', (err, fileContent) => { | |||
if (err){ | |||
fail("unable to read manifest file"); | |||
} | |||
let manifestObj; | |||
try { | |||
manifestObj = JSON.parse(fileContent); | |||
done(); | |||
} catch(err){ | |||
fail(`Invalid JSON: ${filePath}\n${err}`); | |||
} | |||
}); | |||
} | |||
}); | |||
}); | |||
}); |
@@ -0,0 +1,100 @@ | |||
{ | |||
"id": "manifest.json", | |||
"type": "object", | |||
"required": [ | |||
"slug", | |||
"version" | |||
], | |||
"description": "A plugin manifest file for VCV Rack.", | |||
"properties": { | |||
"slug": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"name": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"author": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"license": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"version": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"homepage": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"donation": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"manual": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"source": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"disabled": { | |||
"type": "boolean", | |||
"description": "used when a plugin needs to be disabled" | |||
}, | |||
"productId": { | |||
"type": "number", | |||
"description": "only used by vcv rack website" | |||
}, | |||
"downloads": { | |||
"type": "object", | |||
"properties": { | |||
"win": { | |||
"type": "object", | |||
"properties": { | |||
"download": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"sha256": { | |||
"type": "string", | |||
"description": "" | |||
} | |||
} | |||
}, | |||
"lin": { | |||
"type": "object", | |||
"properties": { | |||
"download": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"sha256": { | |||
"type": "string", | |||
"description": "" | |||
} | |||
} | |||
}, | |||
"mac": { | |||
"type": "object", | |||
"properties": { | |||
"download": { | |||
"type": "string", | |||
"description": "" | |||
}, | |||
"sha256": { | |||
"type": "string", | |||
"description": "" | |||
} | |||
} | |||
} | |||
} | |||
} | |||
}, | |||
"additionalProperties": false | |||
} |