Skip to content

Commit

Permalink
Additional tests, refactoring and bug fixes (e.g. #2)
Browse files Browse the repository at this point in the history
  • Loading branch information
m-mohr committed Aug 14, 2020
1 parent f8a6202 commit 7529680
Show file tree
Hide file tree
Showing 19 changed files with 1,931 additions and 819 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"assets/subtype-schemas.json"
],
"dependencies": {
"@openeo/js-commons": "^1.1.0",
"@openeo/js-commons": "^1.1.1",
"ajv": "^6.12.0"
},
"devDependencies": {
Expand All @@ -44,7 +44,7 @@
"docs": "jsdoc src -r -d docs/ -P package.json -R README.md",
"build": "npx webpack",
"compat": "jshint src",
"test": "jest --testPathIgnorePatterns assets/ --env=jsdom",
"test_node": "jest --testPathIgnorePatterns assets/ --env=node"
"test": "jest --env=jsdom",
"test_node": "jest --env=node"
}
}
13 changes: 10 additions & 3 deletions src/error.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const Utils = require('@openeo/js-commons/src/utils.js');
const Utils = require('./utils');

const MESSAGES = {
"MultipleResultNodes": "Multiple result nodes specified for process graph.",
Expand All @@ -20,7 +20,12 @@ const MESSAGES = {
"ProcessMissing": "No process specified"
};

module.exports = class ProcessGraphError extends Error {
/**
* An error class for this library.
*
* @class
*/
class ProcessGraphError extends Error {

constructor(codeOrMsg, variables = {}) {
super();
Expand All @@ -42,4 +47,6 @@ module.exports = class ProcessGraphError extends Error {
};
}

};
}

module.exports = ProcessGraphError;
11 changes: 9 additions & 2 deletions src/errorlist.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
module.exports = class ErrorList {
/**
* A list of errors.
*
* @class
*/
class ErrorList {

constructor() {
this.errors = [];
Expand Down Expand Up @@ -50,4 +55,6 @@ module.exports = class ErrorList {
return this.errors;
}

};
}

module.exports = ErrorList;
58 changes: 49 additions & 9 deletions src/jsonschema.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
const ajv = require('ajv');
const Utils = require('@openeo/js-commons/src/utils.js');
const Utils = require('./utils');
const ProcessUtils = require('@openeo/js-commons/src/processUtils.js');
const keywords = require('./keywords');

var geoJsonSchema = require("../assets/GeoJSON.json");
var subtypeSchemas = require("../assets/subtype-schemas.json");

module.exports = class JsonSchemaValidator {
/**
* JSON Schema Validator.
*
* @class
*/
class JsonSchemaValidator {

constructor() {
this.ajv = new ajv({
Expand All @@ -32,6 +37,7 @@ module.exports = class JsonSchemaValidator {
output: null
};
this.epsgCodes = null;
this.processRegistry = null;
}

getFunctionName(subtype) {
Expand Down Expand Up @@ -173,8 +179,24 @@ module.exports = class JsonSchemaValidator {

async validateWkt2Definition(data) {
// To be overridden by end-user application, just doing a very basic check here based on code ported over from proj4js
var codeWords = ['PROJECTEDCRS', 'PROJCRS', 'GEOGCS','GEOCCS','PROJCS','LOCAL_CS', 'GEODCRS', 'GEODETICCRS', 'GEODETICDATUM', 'ENGCRS', 'ENGINEERINGCRS'];
return codeWords.some(word => data.indexOf(word) > -1);
var codeWords = [
'BOUNDCRS',
'COMPOUNDCRS',
'ENGCRS', 'ENGINEERINGCRS',
'GEODCRS', 'GEODETICCRS',
'GEOGCRS', 'GEOGRAPHICCRS',
'PARAMETRICCRS',
'PROJCRS', 'PROJECTEDCRS',
'TIMECRS',
'VERTCRS', 'VERTICALCRS'
];
data = data.toUpperCase();
if (!codeWords.some(word => data.indexOf(word) !== -1)) {
throw new ajv.ValidationError([{
message: "Invalid WKT2 string specified."
}]);
}
return true;
}

async validateTemporalInterval(data) {
Expand Down Expand Up @@ -203,11 +225,27 @@ module.exports = class JsonSchemaValidator {
return true;
}

setProcessGraphParser(processGraph) {
this.processGraph = processGraph;
}

async validateProcessGraph(data) {
const ProcessGraph = require('./processgraph'); // Avoid circular reference
var parser = new ProcessGraph(data);
parser.parse();
return true;
try {
var parser;
if (this.processGraph) {
this.processGraph.createProcessGraphInstance(data);
}
else {
const ProcessGraph = require('./processgraph');
parser = new ProcessGraph(data, null, this);
}
parser.parse();
return true;
} catch (error) {
throw new ajv.ValidationError([{
message: error.message
}]);
}
}

// Checks whether the valueSchema is compatible to the paramSchema.
Expand Down Expand Up @@ -255,4 +293,6 @@ module.exports = class JsonSchemaValidator {
return compatible !== -1;
}

};
}

module.exports = JsonSchemaValidator;
4 changes: 3 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const ProcessGraph = require('./processgraph');
const ProcessGraphError = require('./error');
const ProcessGraphNode = require('./node');
const ProcessRegistry = require('./registry');
const Utils = require('./utils');

module.exports = {
BaseProcess,
Expand All @@ -13,5 +14,6 @@ module.exports = {
ProcessGraph,
ProcessGraphError,
ProcessGraphNode,
ProcessRegistry
ProcessRegistry,
Utils
};
108 changes: 41 additions & 67 deletions src/node.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
const ProcessGraphError = require('./error');
const Utils = require('@openeo/js-commons/src/utils.js');
const Utils = require('./utils');

module.exports = class ProcessGraphNode {
/**
* A Process graph node.
*
* @class
*/
class ProcessGraphNode {

constructor(node, id, parent = null) {
if (typeof id !== 'string' || id.length === 0) {
Expand All @@ -24,7 +29,7 @@ module.exports = class ProcessGraphNode {
this.expectsFrom = []; // From which node do we expect results from
this.receivedFrom = []; // From which node have received results from so far
this.passesTo = [];
this.computedResult = null;
this.computedResult = undefined;
}

toJSON() {
Expand Down Expand Up @@ -57,7 +62,7 @@ module.exports = class ProcessGraphNode {
}

getArgumentType(name) {
return ProcessGraphNode.getType(this.arguments[name]);
return Utils.getType(this.arguments[name]);
}

getRawArgument(name) {
Expand All @@ -66,7 +71,7 @@ module.exports = class ProcessGraphNode {

getRawArgumentValue(name) {
var arg = this.getRawArgument(name);
switch(ProcessGraphNode.getType(arg)) {
switch(Utils.getType(arg)) {
case 'result':
return arg.from_node;
case 'callback':
Expand All @@ -86,32 +91,11 @@ module.exports = class ProcessGraphNode {
}

getArgumentRefs(name) {
return ProcessGraphNode.getValueRefs(this.arguments[name]);
return Utils.getRefs(this.arguments[name], false);
}

getRefs() {
return ProcessGraphNode.getValueRefs(this.arguments);
}

static getValueRefs(value) {
var store = [];
var type = ProcessGraphNode.getType(value);
switch(type) {
case 'result':
case 'parameter':
store.push(value);
break;
case 'callback':
// ToDo
break;
case 'array':
case 'object':
for(var i in value) {
store = store.concat(ProcessGraphNode.getValueRefs(value[i]));
}
break;
}
return store;
return Utils.getRefs(this.arguments, false);
}

getProcessGraphParameter(name) {
Expand All @@ -135,15 +119,17 @@ module.exports = class ProcessGraphNode {
return defaultValue;
}

throw new ProcessGraphError('ProcessGraphParameterMissing', {
argument: name,
node_id: this.id,
process_id: this.process_id
});
if (!this.processGraph.allowUndefinedParameterRefs) {
throw new ProcessGraphError('ProcessGraphParameterMissing', {
argument: name,
node_id: this.id,
process_id: this.process_id
});
}
}

evaluateArgument(arg) {
var type = ProcessGraphNode.getType(arg);
var type = Utils.getType(arg);
switch(type) {
case 'result':
return this.processGraph.getNode(arg.from_node).getResult();
Expand All @@ -153,65 +139,51 @@ module.exports = class ProcessGraphNode {
return this.getProcessGraphParameter(arg.from_parameter);
case 'array':
case 'object':
let copy = type === 'array' ? [] : {};
for(var i in arg) {
arg[i] = this.evaluateArgument(arg[i]);
copy[i] = this.evaluateArgument(arg[i]);
}
return arg;
return copy;
default:
return arg;
}
}

static getType(obj, reportNullAs = 'null') {
const ProcessGraph = require('./processgraph');
if (typeof obj === 'object') {
if (obj === null) {
return reportNullAs;
}
else if (Array.isArray(obj)) {
return 'array';
}
else if(obj.hasOwnProperty("process_graph") || obj instanceof ProcessGraph) {
return 'callback';
}
else if(obj.hasOwnProperty("from_node")) {
return 'result';
}
else if(obj.hasOwnProperty("from_parameter")) {
return 'parameter';
}
else {
return 'object';
}
}
return (typeof obj);
}

isStartNode() {
return (this.expectsFrom.length === 0);
}

addPreviousNode(node) {
this.expectsFrom.push(node);
if (!this.expectsFrom.find(other => other.id === node.id)) {
this.expectsFrom.push(node);
}
}

getPreviousNodes() {
return this.expectsFrom;
// Sort nodes to ensure a consistent execution order
return this.expectsFrom.sort((a,b) => a.id.localeCompare(b.id));
}

addNextNode(node) {
this.passesTo.push(node);
if (!this.passesTo.find(other => other.id === node.id)) {
this.passesTo.push(node);
}
}

getNextNodes() {
return this.passesTo;
// Sort nodes to ensure a consistent execution order
return this.passesTo.sort((a,b) => a.id.localeCompare(b.id));
}

reset() {
this.computedResult = null;
this.computedResult = undefined;
this.receivedFrom = [];
}

getDescription() {
return this.description;
}

setDescription(description) {
if (typeof description === 'string') {
this.description = description;
Expand All @@ -236,4 +208,6 @@ module.exports = class ProcessGraphNode {
return (this.expectsFrom.length === this.receivedFrom.length); // all dependencies solved?
}

};
}

module.exports = ProcessGraphNode;
Loading

0 comments on commit 7529680

Please sign in to comment.