Commit 611820c1 authored by Jaden Diefenbaugh's avatar Jaden Diefenbaugh

updated alg schema to v3 & added editor support

Updated the schema & extended the editor to support the new fields

See #174 & #140
parent b4b9c12c
......@@ -11,6 +11,7 @@ import testAlgs from '@test/test_algs.json';
import testLibs from '@test/test_libs.json';
import testDfs from '@test/test_dfs.json';
import testDbs from '@test/test_dbs.json';
import { getValidAlgorithmObj as getValidObj } from '@helpers/beat';
describe('<ValidSchemaBadge />', () => {
let wrapper;
......@@ -92,9 +93,12 @@ describe('<ValidSchemaBadge />', () => {
},
// non-analyzer
splittable: false,
schema_version: 3.0,
api_version: 2.0,
type: 'sequential',
}
}
].concat(testAlgs);
].concat(testAlgs.map(a => getValidObj(a)));
algs.forEach(function(alg) {
it(`${ alg.name }`, () => {
......
......@@ -577,6 +577,59 @@ export class AlgorithmEditor extends React.Component<Props, State> {
onChange={(e) => this.changeContentsVal('description', e.target.value)}
/>
</FormGroup>
<FormGroup row>
<Col sm={4}>
<Label>API Version</Label>
<Input
required
type='select'
className='custom-select'
name='apiversion'
id='apiversion'
placeholder='Algorithm API Version...'
value={this.props.data.contents.api_version}
onChange={(e) => this.changeContentsVal('api_version', e.target.value)}
>
<option value={1.0}>1.0</option>
<option value={2.0}>2.0</option>
</Input>
</Col>
<Col sm={4}>
<Label>Schema Version</Label>
<Input
required
type='select'
className='custom-select'
name='schemaversion'
id='schemaversion'
placeholder='Algorithm Schema Version...'
value={this.props.data.contents.schema_version}
onChange={(e) => this.changeContentsVal('schema_version', e.target.value)}
>
<option value={1.0}>1.0</option>
<option value={2.0}>2.0</option>
<option value={3.0}>3.0</option>
</Input>
</Col>
<Col sm={4}>
<Label>Algorithm Type</Label>
<Input
required
type='select'
className='custom-select'
name='algtype'
id='algtype'
placeholder='Algorithm Type...'
value={this.props.data.contents.type}
onChange={(e) => this.changeContentsVal('type', e.target.value)}
>
<option value={'legacy'}>Legacy</option>
<option value={'sequential'}>Sequential</option>
<option value={'autonomous'}>Autonomous</option>
</Input>
</Col>
</FormGroup>
<FormGroup check>
<Label check>
<Input
......
......@@ -23,43 +23,48 @@ describe('<AlgorithmEditor />', () => {
wrapper.unmount();
});
describe('accepts', () => {
const algs = [
{
name: 'test/non-analyzer-alg/1',
contents: {
language: 'python',
description: 'A basic algorithm as a sanity test for the AlgorithmEditor',
groups: [
{
name: 'group_1',
inputs: {
'input_1': { type: 'test/df/1' },
},
outputs: {
'output_1': { type: 'test/df/2' },
},
}
],
uses: {
'library_1': 'a/lib/1',
const aTestAlg = {
name: 'test/non-analyzer-alg/1',
contents: {
language: 'python',
description: 'A basic algorithm as a sanity test for the AlgorithmEditor',
groups: [
{
name: 'group_1',
inputs: {
'input_1': { type: 'test/df/1' },
},
parameters: {
'parameter_1': {
type: 'string',
choice: [
'choice_1',
'choice_2',
'choice_3',
],
default: 'choice_1',
}
outputs: {
'output_1': { type: 'test/df/2' },
},
// non-analyzer
splittable: false,
}
],
uses: {
'library_1': 'a/lib/1',
},
parameters: {
'parameter_1': {
type: 'string',
choice: [
'choice_1',
'choice_2',
'choice_3',
],
default: 'choice_1',
}
},
// non-analyzer
splittable: false,
schema_version: 3.0,
api_version: 2.0,
type: 'sequential',
}
};
}
describe('accepts', () => {
const algs = [
aTestAlg,
].concat(testAlgs.map(a => getValidObj(a)));
algs.forEach(function(alg){
......@@ -156,7 +161,10 @@ describe('<AlgorithmEditor />', () => {
parameters: {},
uses: {},
'splittable': true,
'language': 'python'
'language': 'python',
schema_version: 3.0,
api_version: 2.0,
type: 'sequential',
});
});
......@@ -266,7 +274,10 @@ describe('<AlgorithmEditor />', () => {
'lib': 'user/thelib/1'
},
'splittable': true,
'language': 'python'
'language': 'python',
schema_version: 3.0,
api_version: 2.0,
type: 'sequential',
});
});
......@@ -386,7 +397,10 @@ describe('<AlgorithmEditor />', () => {
'type': 'plot/bar/1',
'display': false
}
}
},
schema_version: 3.0,
api_version: 2.0,
type: 'sequential',
});
});
......@@ -475,7 +489,10 @@ describe('<AlgorithmEditor />', () => {
parameters: {},
uses: {},
'splittable': true,
'language': 'python'
'language': 'python',
schema_version: 3.0,
api_version: 2.0,
type: 'sequential',
});
});
......@@ -569,7 +586,10 @@ describe('<AlgorithmEditor />', () => {
'type': 'uint32',
'description': 'Time to sleep in seconds'
}
}
},
schema_version: 3.0,
api_version: 2.0,
type: 'sequential',
});
});
......@@ -665,7 +685,10 @@ describe('<AlgorithmEditor />', () => {
'type': 'plot/scatter/1',
'display': false
}
}
},
schema_version: 3.0,
api_version: 2.0,
type: 'sequential',
});
});
});
......@@ -735,6 +758,40 @@ describe('<AlgorithmEditor />', () => {
type: ''
});
});
});
it(`properly sets schema_version, api_version, and "type"`, () => {
const saveFunc = sinon.spy();
const _updateFunc = (obj) => {
wrapper.setProps && wrapper.setProps({ data: obj });
};
const updateFunc = sinon.spy(_updateFunc);
const algName = aTestAlg.name;
wrapper = mount(
<C
data={aTestAlg}
algorithms={[]}
dataformats={testDfs}
libraries={testLibs}
saveFunc={saveFunc}
updateFunc={updateFunc}
/>
);
wrapper.find('Input[type="select"]#schemaversion').prop('onChange')({ target: { value: 2.0 }});
wrapper.find('Input[type="select"]#apiversion').prop('onChange')({ target: { value: 1.0 }});
wrapper.find('Input[type="select"]#algtype').prop('onChange')({ target: { value: 'autonomous' }});
expect(wrapper.props().data.contents.schema_version).to.equal(2.0);
expect(wrapper.props().data.contents.api_version).to.equal(1.0);
expect(wrapper.props().data.contents.type).to.equal('autonomous');
expect(wrapper.props().data.contents).to.deep.equal({
...aTestAlg.contents,
schema_version: 2.0,
api_version: 1.0,
type: 'autonomous',
});
expect(wrapper.find('.badge-success').exists());
});
});
});
......@@ -278,6 +278,9 @@ export const getValidAlgorithmObj = (data: BeatObject = {name: '', contents: {}}
],
description: '',
language: 'python',
type: 'sequential',
api_version: 2.0,
schema_version: 3.0,
...getObj.contents,
},
};
......
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "algorithm_1",
"title": "Algorithm v1 descriptor",
"description": "This schema defines the properties of an algorithm",
"oneOf": [
{ "$ref": "#/definitions/block" },
{ "$ref": "#/definitions/analyzer" }
],
"definitions": {
"block": {
"type": "object",
"properties": {
"schema_version": { "$ref": "algorithm_common#/definitions/schema_version" },
"language": { "$ref": "common#/definitions/language" },
"description": { "$ref": "common#/definitions/description" },
"groups": { "$ref": "algorithm_common#/definitions/block_groups" },
"parameters": { "$ref": "algorithm_common#/definitions/parameters" },
"splittable": { "type": "boolean" },
"uses": { "$ref": "common#/definitions/uses" }
},
"required": [
"language",
"groups",
"splittable"
],
"additionalProperties": false
},
"analyzer": {
"type": "object",
"properties": {
"schema_version": { "$ref": "algorithm_common#/definitions/schema_version" },
"language": { "$ref": "common#/definitions/language" },
"description": { "$ref": "common#/definitions/description" },
"groups": { "$ref": "algorithm_common#/definitions/analyzer_groups" },
"parameters": { "$ref": "algorithm_common#/definitions/parameters" },
"results": { "$ref": "algorithm_common#/definitions/results" },
"uses": { "$ref": "common#/definitions/uses" }
},
"required": [
"language",
"groups",
"results"
],
"additionalProperties": false
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "algorithm_2",
"title": "Algorithm v2 descriptor",
"description": "This schema defines the properties of a v2 algorithm",
"oneOf": [
{ "$ref": "#/definitions/block" },
{ "$ref": "#/definitions/analyzer" }
],
"definitions": {
"type": {
"type": "string",
"enum": [
"legacy",
"sequential",
"autonomous"
]
},
"block": {
"type": "object",
"properties": {
"language": { "$ref": "common#/definitions/language" },
"description": { "$ref": "common#/definitions/description" },
"groups": { "$ref": "algorithm_common#/definitions/block_groups" },
"parameters": { "$ref": "algorithm_common#/definitions/parameters" },
"splittable": { "type": "boolean" },
"uses": { "$ref": "common#/definitions/uses" },
"schema_version": { "$ref": "algorithm_common#/definitions/schema_version" },
"api_version": { "$ref": "algorithm_common#/definitions/api_version" },
"type": { "$ref": "#/definitions/type" }
},
"required": [
"language",
"groups",
"splittable"
],
"additionalProperties": false
},
"analyzer": {
"type": "object",
"properties": {
"language": { "$ref": "common#/definitions/language" },
"description": { "$ref": "common#/definitions/description" },
"groups": { "$ref": "algorithm_common#/definitions/analyzer_groups" },
"parameters": { "$ref": "algorithm_common#/definitions/parameters" },
"results": { "$ref": "algorithm_common#/definitions/results" },
"uses": { "$ref": "common#/definitions/uses" },
"schema_version": { "$ref": "algorithm_common#/definitions/schema_version" },
"api_version": { "$ref": "algorithm_common#/definitions/api_version" },
"type": { "$ref": "#/definitions/type" }
},
"required": [
"language",
"groups",
"results"
],
"additionalProperties": false
}
},
"required": ["type", "api_version", "schema_version"]
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "algorithm_3",
"title": "Algorithm v3 descriptor",
"description": "This schema defines the properties of a v3 algorithm",
"oneOf": [
{ "$ref": "algorithm_2#/definitions/block" },
{ "$ref": "algorithm_2#/definitions/analyzer" },
{ "$ref": "#/definitions/loop_user" },
{ "$ref": "#/definitions/loop" }
],
"definitions": {
"loop_io_group": {
"type": "object",
"properties": {
"request": { "$ref": "algorithm_common#/definitions/endpoint" },
"answer": { "$ref": "algorithm_common#/definitions/endpoint" }
},
"required": [
"request",
"answer"
],
"additionalProperties": false
},
"loop_user_io_group": {
"type": "object",
"properties": {
"name": { "type": "string" },
"inputs": { "$ref": "algorithm_common#/definitions/endpoints" },
"outputs": { "$ref": "algorithm_common#/definitions/endpoints" },
"loop": { "$ref": "#/definitions/loop_io_group" }
},
"required": [
"inputs",
"outputs",
"loop"
],
"additionalProperties": false
},
"block_groups": {
"type": "array",
"items": [
{ "$ref": "#/definitions/loop_user_io_group" }
],
"additionalItems": { "$ref": "algorithm_common#/definitions/input_group" },
"minItems": 1
},
"loop_group": {
"type": "object",
"properties": {
"name": { "type": "string" },
"inputs": { "$ref": "algorithm_common#/definitions/endpoints" },
"loop": { "$ref": "#/definitions/loop_io_group" }
},
"required": [
"inputs",
"loop"
],
"additionalProperties": false
},
"loop_groups": {
"type": "array",
"items": [
{ "$ref": "#/definitions/loop_group" }
],
"additionalItems": { "$ref": "algorithm_common#/definitions/input_group" },
"minItems": 1
},
"loop_user": {
"type": "object",
"properties": {
"language": { "$ref": "common#/definitions/language" },
"description": { "$ref": "common#/definitions/description" },
"groups": { "$ref": "#/definitions/block_groups" },
"parameters": { "$ref": "algorithm_common#/definitions/parameters" },
"splittable": { "type": "boolean" },
"uses": { "$ref": "common#/definitions/uses" },
"schema_version": { "$ref": "algorithm_common#/definitions/schema_version" },
"api_version": { "$ref": "algorithm_common#/definitions/api_version" },
"type": {
"$comment": "Change enum to const when tools allow v6 json schema",
"type": "string",
"enum": ["loop_user"]
}
},
"required": [
"language",
"groups",
"splittable"
],
"additionalProperties": false
},
"loop": {
"type": "object",
"properties": {
"language": { "$ref": "common#/definitions/language" },
"description": { "$ref": "common#/definitions/description" },
"groups": { "$ref": "#/definitions/loop_groups" },
"parameters": { "$ref": "algorithm_common#/definitions/parameters" },
"uses": { "$ref": "common#/definitions/uses" },
"schema_version": { "$ref": "algorithm_common#/definitions/schema_version" },
"api_version": { "$ref": "algorithm_common#/definitions/api_version" },
"type": {
"$comment": "Change enum to const when tools allow v6 json schema",
"type": "string",
"enum": ["loop"]
}
},
"required": [
"language",
"groups"
],
"additionalProperties": false
}
},
"required": ["type", "api_version", "schema_version"]
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "algorithm_common",
"title": "Algorithm common components descriptor",
"description": "This schema defines the components used in one or more versions of the Algorithm",
"definitions": {
"endpoint": {
"type": "object",
"properties": {
"type": { "$ref": "common#/definitions/reference" },
"description": { "type": "string" }
},
"required": [
"type"
],
"additionalProperties": false
},
"endpoints": {
"type": "object",
"patternProperties": {
"^[a-zA-Z_][a-zA-Z0-9_-]*$": {
"$ref": "#/definitions/endpoint"
}
},
"uniqueItems": true,
"additionalProperties": false
},
"io_group": {
"type": "object",
"properties": {
"name": { "type": "string" },
"inputs": { "$ref": "#/definitions/endpoints" },
"outputs": { "$ref": "#/definitions/endpoints" }
},
"required": [
"inputs",
"outputs"
],
"additionalProperties": false
},
"input_group": {
"type": "object",
"properties": {
"name": { "type": "string" },
"inputs": { "$ref": "#/definitions/endpoints" }
},
"required": [
"inputs"
],
"additionalProperties": false
},
"block_groups": {
"type": "array",
"items": [
{ "$ref": "#/definitions/io_group" }
],
"additionalItems": { "$ref": "#/definitions/input_group" },
"minItems": 1
},
"range": {
"type": "array",
"items": { "$ref": "common#/definitions/value" },
"minItems": 2,
"maxItems": 2
},
"choice": {
"type": "array",
"items": { "$ref": "common#/definitions/value" },
"minItems": 3
},
"parameter": {
"type": "object",
"properties": {
"type": { "$ref": "common#/definitions/basetype" },
"default": { "$ref": "common#/definitions/value" },
"description": { "type": "string" }
},
"required": [
"type"
]
},
"range_parameter": {
"allOf": [
{ "$ref": "#/definitions/parameter" },
{
"properties": {
"range": { "$ref": "#/definitions/range" }
},
"required": [
"range"
]
}
],
"additionalProperties": false
},
"choice_parameter": {
"allOf": [
{ "$ref": "#/definitions/parameter" },
{
"properties": {
"range": { "$ref": "#/definitions/choice" }
},