Skip to content

Commit

Permalink
feat(ns-workflows-1): add support for Success Action Object (#3408)
Browse files Browse the repository at this point in the history
Refs #3392
  • Loading branch information
frankkilcommins committed Nov 21, 2023
1 parent 66acc1b commit 28b81ac
Show file tree
Hide file tree
Showing 14 changed files with 328 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/apidom-ns-workflows-1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Only fully implemented specification objects should be checked here.
- [ ] [Workflow Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#workflow-object)
- [ ] [Step Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#step-object)
- [ ] [Parameter Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#parameter-object)
- [ ] [Success Action Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#success-action-object)
- [x] [Success Action Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#success-action-object)
- [ ] [Failure Action Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#failure-action-object)
- [ ] [Component Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#component-object)
- [x] [Criterion Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#criterion-object)
Expand Down
48 changes: 48 additions & 0 deletions packages/apidom-ns-workflows-1/src/elements/SuccessAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
ObjectElement,
ArrayElement,
StringElement,
Attributes,
Meta,
} from '@swagger-api/apidom-core';

class SuccessAction extends ObjectElement {
constructor(content?: Record<string, unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.element = 'successAction';
}

get type(): StringElement | undefined {
return this.get('type');
}

set type(type: StringElement | undefined) {
this.set('type', type);
}

get workflowId(): StringElement | undefined {
return this.get('workflowId');
}

set workflowId(workflowId: StringElement | undefined) {
this.set('workflowId', workflowId);
}

get stepId(): StringElement | undefined {
return this.get('stepId');
}

set stepId(stepId: StringElement | undefined) {
this.set('stepId', stepId);
}

get criteria(): ArrayElement | undefined {
return this.get('criteria');
}

set criteria(criteria: ArrayElement | undefined) {
this.set('criteria', criteria);
}
}

export default SuccessAction;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ArrayElement, Attributes, Meta } from '@swagger-api/apidom-core';

class SuccessActionCriteria extends ArrayElement {
static primaryClass = 'success-action-criteria';

constructor(content?: Array<unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.classes.push(SuccessActionCriteria.primaryClass);
this.classes.push('criteria');
}
}

export default SuccessActionCriteria;
4 changes: 4 additions & 0 deletions packages/apidom-ns-workflows-1/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export {
isInfoElement,
isSourceDescriptionElement,
isSourceDescriptionsElement,
isSuccessActionElement,
isSuccessActionCriteriaElement,
isCriterionElement,
} from './predicates';

Expand All @@ -47,7 +49,9 @@ export {
WorkflowsSpecElement,
InfoElement,
SourceDescriptionElement,
SuccessActionElement,
CriterionElement,
} from './refractor/registration';
// NCE types
export { default as SourceDescriptionsElement } from './elements/nces/SourceDescriptions';
export { default as SuccessActionCriteriaElement } from './elements/nces/SuccessActionCriteria';
2 changes: 2 additions & 0 deletions packages/apidom-ns-workflows-1/src/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import WorkflowsSpecification1Element from './elements/WorkflowsSpecification1';
import WorkflowsSpecElement from './elements/WorkflowsSpec';
import InfoElement from './elements/Info';
import SourceDescriptionElement from './elements/SourceDescription';
import SuccessActionElement from './elements/SuccessAction';
import CriterionElement from './elements/Criterion';

const workflows1 = {
Expand All @@ -14,6 +15,7 @@ const workflows1 = {
base.register('workflowsSpec', WorkflowsSpecElement);
base.register('info', InfoElement);
base.register('sourceDescription', SourceDescriptionElement);
base.register('successAction', SuccessActionElement);
base.register('criterion', CriterionElement);

return base;
Expand Down
24 changes: 24 additions & 0 deletions packages/apidom-ns-workflows-1/src/predicates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import WorkflowsSpecification1Element from './elements/WorkflowsSpecification1';
import WorkflowsSpecElement from './elements/WorkflowsSpec';
import InfoElement from './elements/Info';
import SourceDescriptionElement from './elements/SourceDescription';
import SuccessActionElement from './elements/SuccessAction';
import CriterionElement from './elements/Criterion';
// NCE types
import SourceDescriptionsElement from './elements/nces/SourceDescriptions';
import SuccessActionCriteriaElement from './elements/nces/SuccessActionCriteria';

export const isWorkflowsSpecElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
Expand Down Expand Up @@ -62,6 +64,16 @@ export const isSourceDescriptionsElement = createPredicate(
},
);

export const isSuccessActionElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
return (element: unknown): element is SuccessActionElement =>
element instanceof SuccessActionElement ||
(hasBasicElementProps(element) &&
isElementType('successAction', element) &&
primitiveEq('object', element));
},
);

export const isCriterionElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
return (element: unknown): element is CriterionElement =>
Expand All @@ -71,3 +83,15 @@ export const isCriterionElement = createPredicate(
primitiveEq('object', element));
},
);

export const isSuccessActionCriteriaElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq, hasClass }) => {
return (element: unknown): element is SuccessActionCriteriaElement =>
element instanceof SuccessActionCriteriaElement ||
(hasBasicElementProps(element) &&
isElementType('array', element) &&
primitiveEq('array', element) &&
hasClass('success-action-criteria', element) &&
hasClass('criteria', element));
},
);
9 changes: 9 additions & 0 deletions packages/apidom-ns-workflows-1/src/refractor/registration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import WorkflowsSpecification1Element from '../elements/WorkflowsSpecification1'
import WorkflowsSpecElement from '../elements/WorkflowsSpec';
import InfoElement from '../elements/Info';
import SourceDescriptionElement from '../elements/SourceDescription';
import SuccessActionElement from '../elements/SuccessAction';
import CriterionElement from '../elements/Criterion';
import { createRefractor } from './index';

Expand All @@ -28,6 +29,13 @@ SourceDescriptionElement.refract = createRefractor([
'SourceDescription',
'$visitor',
]);
SuccessActionElement.refract = createRefractor([
'visitors',
'document',
'objects',
'SuccessAction',
'$visitor',
]);
CriterionElement.refract = createRefractor([
'visitors',
'document',
Expand All @@ -41,5 +49,6 @@ export {
WorkflowsSpecElement,
InfoElement,
SourceDescriptionElement,
SuccessActionElement,
CriterionElement,
};
11 changes: 11 additions & 0 deletions packages/apidom-ns-workflows-1/src/refractor/specification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import SourceDescriptionsVisitor from './visitors/workflows-1/SourceDescriptions
import CriterionVisitor from './visitors/workflows-1/criterion';
import FallbackVisitor from './visitors/FallbackVisitor';
import SpecificationExtensionVisitor from './visitors/SpecificationExtensionVisitor';
import SuccessActionVisitor from './visitors/workflows-1/success-action';
import SuccessActionCriteriaVisitor from './visitors/workflows-1/SuccessActionCriteriaVisitor';

/**
* Specification object allows us to have complete control over visitors
Expand Down Expand Up @@ -50,6 +52,15 @@ const specification = {
type: { $ref: '#/visitors/value' },
},
},
SuccessAction: {
$visitor: SuccessActionVisitor,
fixedFields: {
type: { $ref: '#/visitors/value' },
workflowId: { $ref: '#/visitors/value' },
stepId: { $ref: '#/visitors/value' },
criteria: SuccessActionCriteriaVisitor,
},
},
Criterion: {
$visitor: CriterionVisitor,
fixedFields: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import stampit from 'stampit';
import { ArrayElement, Element, BREAK } from '@swagger-api/apidom-core';

import SuccessActionCriteriaElement from '../../../elements/nces/SuccessActionCriteria';
import SpecificationVisitor from '../SpecificationVisitor';
import FallbackVisitor from '../FallbackVisitor';

const SuccessActionCriteriaVisitor = stampit(SpecificationVisitor, FallbackVisitor, {
init() {
this.element = new SuccessActionCriteriaElement();
},
methods: {
ArrayElement(arrayElement: ArrayElement) {
arrayElement.forEach((item: Element): void => {
const specPath = ['document', 'objects', 'Criterion'];
const element = this.toRefractedElement(specPath, item);

this.element.push(element);
});

this.copyMetaAndAttributes(arrayElement, this.element);

return BREAK;
},
},
});

export default SuccessActionCriteriaVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import stampit from 'stampit';
import { always } from 'ramda';

import SuccessActionElement from '../../../../elements/SuccessAction';
import FallbackVisitor from '../../FallbackVisitor';
import FixedFieldsVisitor from '../../generics/FixedFieldsVisitor';

const SuccessActionVisitor = stampit(FixedFieldsVisitor, FallbackVisitor, {
props: {
specPath: always(['document', 'objects', 'SuccessAction']),
canSupportSpecificationExtensions: true,
},
init() {
this.element = new SuccessActionElement();
},
});

export default SuccessActionVisitor;
1 change: 1 addition & 0 deletions packages/apidom-ns-workflows-1/src/traversal/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const keyMap = {
WorkflowsSpecification1Element: ['content'],
InfoElement: ['content'],
SourceDescriptionElement: ['content'],
SuccessActionElement: ['content'],
CriterionElement: ['content'],
...keyMapBase,
};
115 changes: 115 additions & 0 deletions packages/apidom-ns-workflows-1/test/predicates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ import {
isInfoElement,
isSourceDescriptionElement,
isSourceDescriptionsElement,
isSuccessActionElement,
isSuccessActionCriteriaElement,
isCriterionElement,
WorkflowsSpecification1Element,
WorkflowsSpecElement,
InfoElement,
SourceDescriptionElement,
SourceDescriptionsElement,
SuccessActionElement,
SuccessActionCriteriaElement,
CriterionElement,
} from '../src';

Expand Down Expand Up @@ -346,4 +350,115 @@ describe('predicates', function () {
assert.isFalse(isCriterionElement(CriterionElementSwan));
});
});

context('isCriteriaElement', function () {
context('given CriteriaElement instance value', function () {
specify('should return true', function () {
const element = new SuccessActionCriteriaElement();

assert.isTrue(isSuccessActionCriteriaElement(element));
});
});

context('given subtype instance value', function () {
specify('should return true', function () {
class SuccessActionCriteriaSubElement extends SuccessActionCriteriaElement {}

assert.isTrue(isSuccessActionCriteriaElement(new SuccessActionCriteriaSubElement()));
});
});

context('given non Criteria instance value', function () {
specify('should return false', function () {
assert.isFalse(isSuccessActionCriteriaElement(1));
assert.isFalse(isSuccessActionCriteriaElement(null));
assert.isFalse(isSuccessActionCriteriaElement(undefined));
assert.isFalse(isSuccessActionCriteriaElement({}));
assert.isFalse(isSuccessActionCriteriaElement([]));
assert.isFalse(isSuccessActionCriteriaElement('string'));
});
});

specify('should support duck-typing', function () {
const criteriaElementDuck = {
_storedElement: 'array',
_content: [],
classes: new ArrayElement(['criteria', 'success-action-criteria']),
primitive() {
return 'array';
},
get element() {
return this._storedElement;
},
};

const criteriaElementSwan = {
_storedElement: undefined,
_content: undefined,
primitive() {
return 'swan';
},
};

assert.isTrue(isSuccessActionCriteriaElement(criteriaElementDuck));
assert.isFalse(isSuccessActionCriteriaElement(criteriaElementSwan));
});
});

context('isSuccessActionElement', function () {
context('given SuccessActionElement instance value', function () {
specify('should return true', function () {
const element = new SuccessActionElement();

assert.isTrue(isSuccessActionElement(element));
});
});

context('given subtype instance value', function () {
specify('should return true', function () {
// eslint-disable-next-line @typescript-eslint/naming-convention
class SuccessActionSubElement extends SuccessActionElement {}

assert.isTrue(isSuccessActionElement(new SuccessActionSubElement()));
});
});

context('given non SuccessActionSubElement instance value', function () {
specify('should return false', function () {
assert.isFalse(isSuccessActionElement(1));
assert.isFalse(isSuccessActionElement(null));
assert.isFalse(isSuccessActionElement(undefined));
assert.isFalse(isSuccessActionElement({}));
assert.isFalse(isSuccessActionElement([]));
assert.isFalse(isSuccessActionElement('string'));
});
});

specify('should support duck-typing', function () {
const SuccessActionElementDuck = {
_storedElement: 'successAction',
_content: [],
primitive() {
return 'object';
},
get element() {
return this._storedElement;
},
};

const SuccessActionElementSwan = {
_storedElement: undefined,
_content: undefined,
primitive() {
return 'swan';
},
get length() {
return 0;
},
};

assert.isTrue(isSuccessActionElement(SuccessActionElementDuck));
assert.isFalse(isSuccessActionElement(SuccessActionElementSwan));
});
});
});

0 comments on commit 28b81ac

Please sign in to comment.