Skip to content

Commit

Permalink
feat(ns-workflows-1): add support for Criterion Object (#3407)
Browse files Browse the repository at this point in the history
Refs #3392
  • Loading branch information
frankkilcommins committed Nov 20, 2023
1 parent 79d657f commit f6b053e
Show file tree
Hide file tree
Showing 12 changed files with 180 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 @@ -194,6 +194,6 @@ Only fully implemented specification objects should be checked here.
- [ ] [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)
- [ ] [Criterion Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#criterion-object)
- [x] [Criterion Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#criterion-object)
- [ ] [Reference Object](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#reference-object)
- [x] [Specification extensions](https://github.com/OAI/sig-workflows/blob/main/versions/1.0.0.md#specification-extensions)
34 changes: 34 additions & 0 deletions packages/apidom-ns-workflows-1/src/elements/Criterion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { StringElement, ObjectElement, Attributes, Meta } from '@swagger-api/apidom-core';

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

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

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

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

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

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

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

export default Criterion;
2 changes: 2 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,7 @@ export {
isInfoElement,
isSourceDescriptionElement,
isSourceDescriptionsElement,
isCriterionElement,
} from './predicates';

export { isWorkflowsSpecificationExtension } from './refractor/predicates';
Expand All @@ -46,6 +47,7 @@ export {
WorkflowsSpecElement,
InfoElement,
SourceDescriptionElement,
CriterionElement,
} from './refractor/registration';
// NCE types
export { default as SourceDescriptionsElement } from './elements/nces/SourceDescriptions';
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 CriterionElement from './elements/Criterion';

const workflows1 = {
namespace: (options: NamespacePluginOptions) => {
Expand All @@ -13,6 +14,7 @@ const workflows1 = {
base.register('workflowsSpec', WorkflowsSpecElement);
base.register('info', InfoElement);
base.register('sourceDescription', SourceDescriptionElement);
base.register('criterion', CriterionElement);

return base;
},
Expand Down
11 changes: 11 additions & 0 deletions packages/apidom-ns-workflows-1/src/predicates.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 CriterionElement from './elements/Criterion';
// NCE types
import SourceDescriptionsElement from './elements/nces/SourceDescriptions';

Expand Down Expand Up @@ -60,3 +61,13 @@ export const isSourceDescriptionsElement = createPredicate(
hasClass('sourceDescriptions', element));
},
);

export const isCriterionElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
return (element: unknown): element is CriterionElement =>
element instanceof CriterionElement ||
(hasBasicElementProps(element) &&
isElementType('criterion', element) &&
primitiveEq('object', 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 CriterionElement from '../elements/Criterion';
import { createRefractor } from './index';

InfoElement.refract = createRefractor(['visitors', 'document', 'objects', 'Info', '$visitor']);
Expand All @@ -27,10 +28,18 @@ SourceDescriptionElement.refract = createRefractor([
'SourceDescription',
'$visitor',
]);
CriterionElement.refract = createRefractor([
'visitors',
'document',
'objects',
'Criterion',
'$visitor',
]);

export {
WorkflowsSpecification1Element,
WorkflowsSpecElement,
InfoElement,
SourceDescriptionElement,
CriterionElement,
};
9 changes: 9 additions & 0 deletions packages/apidom-ns-workflows-1/src/refractor/specification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import InfoVersionVisitor from './visitors/workflows-1/info/VersionVisitor';
import SourceDescriptionVisitor from './visitors/workflows-1/source-description';
import SourceDescriptionUrlVisitor from './visitors/workflows-1/source-description/UrlVisitor';
import SourceDescriptionsVisitor from './visitors/workflows-1/SourceDescriptionsVisitor';
import CriterionVisitor from './visitors/workflows-1/criterion';
import FallbackVisitor from './visitors/FallbackVisitor';
import SpecificationExtensionVisitor from './visitors/SpecificationExtensionVisitor';

Expand Down Expand Up @@ -49,6 +50,14 @@ const specification = {
type: { $ref: '#/visitors/value' },
},
},
Criterion: {
$visitor: CriterionVisitor,
fixedFields: {
context: { $ref: '#/visitors/value' },
condition: { $ref: '#/visitors/value' },
type: { $ref: '#/visitors/value' },
},
},
},
extension: {
$visitor: SpecificationExtensionVisitor,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import stampit from 'stampit';
import { always } from 'ramda';

import CriterionElement from '../../../../elements/Criterion';
import FallbackVisitor from '../../FallbackVisitor';
import FixedFieldsVisitor from '../../generics/FixedFieldsVisitor';

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

export default CriterionVisitor;
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,5 +16,6 @@ export const keyMap = {
WorkflowsSpecification1Element: ['content'],
InfoElement: ['content'],
SourceDescriptionElement: ['content'],
CriterionElement: ['content'],
...keyMapBase,
};
59 changes: 59 additions & 0 deletions packages/apidom-ns-workflows-1/test/predicates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import {
isInfoElement,
isSourceDescriptionElement,
isSourceDescriptionsElement,
isCriterionElement,
WorkflowsSpecification1Element,
WorkflowsSpecElement,
InfoElement,
SourceDescriptionElement,
SourceDescriptionsElement,
CriterionElement,
} from '../src';

describe('predicates', function () {
Expand Down Expand Up @@ -287,4 +289,61 @@ describe('predicates', function () {
assert.isFalse(isSourceDescriptionsElement(sourceDescriptionsElementSwan));
});
});

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

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

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

assert.isTrue(isCriterionElement(new CriterionSubElement()));
});
});

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

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

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

assert.isTrue(isCriterionElement(CriterionElementDuck));
assert.isFalse(isCriterionElement(CriterionElementSwan));
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`refractor elements CriterionElement should refract to semantic ApiDOM tree 1`] = `
(CriterionElement
(MemberElement
(StringElement)
(StringElement))
(MemberElement
(StringElement)
(StringElement))
(MemberElement
(StringElement)
(StringElement)))
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect } from 'chai';
import { sexprs } from '@swagger-api/apidom-core';

import { CriterionElement } from '../../../../src';

describe('refractor', function () {
context('elements', function () {
context('CriterionElement', function () {
specify('should refract to semantic ApiDOM tree', function () {
const criterionElement = CriterionElement.refract({
context: '$statusCode',
condition: '^200$',
type: 'regex',
});

expect(sexprs(criterionElement)).toMatchSnapshot();
});
});
});
});

0 comments on commit f6b053e

Please sign in to comment.