Skip to content

Commit

Permalink
Merge pull request #174 from willosborne/generate-ref-lookup
Browse files Browse the repository at this point in the history
Follow refs when generating definitions
  • Loading branch information
willosborne authored Apr 29, 2024
2 parents 19a0dd2 + 1b0d22c commit b2b4362
Show file tree
Hide file tree
Showing 17 changed files with 984 additions and 434 deletions.
9 changes: 5 additions & 4 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ Usage: calm generate [options]
Generate an instantiation from a CALM pattern file.

Options:
-p, --pattern <source> Path to the pattern file to use. May be a file path or a URL.
-o, --output <output> Path location at which to output the generated file.
-v, --verbose Enable verbose logging. (default: false)
-h, --help display help for command
-p, --pattern <source> Path to the pattern file to use. May be a file path or a URL.
-o, --output <output> Path location at which to output the generated file.
-s, --schemaDirectory <path> Path to a directory of schemas to be used when instantiating patterns.
-v, --verbose Enable verbose logging. (default: false)
-h, --help display help for command
```

### Validating a CALM instantiation
Expand Down
35 changes: 33 additions & 2 deletions cli/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
"commander": "^12.0.0",
"fetch-mock": "^9.11.0",
"graphviz-cli": "^2.0.0",
"json-pointer": "^0.6.2",
"lodash": "^4.17.21",
"mkdirp": "^3.0.1",
"ts-graphviz": "^2.1.1",
"tsconfig-paths": "^4.2.0",
Expand All @@ -33,6 +35,8 @@
"devDependencies": {
"@jest/globals": "^29.7.0",
"@types/jest": "^29.5.12",
"@types/json-pointer": "^1.0.34",
"@types/lodash": "^4.17.0",
"@types/node": "^20.11.30",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"eslint": "^8.57.0",
Expand Down
259 changes: 259 additions & 0 deletions cli/src/commands/generate/components/node.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { SchemaDirectory } from '../schema-directory';
import { instantiateNodeInterfaces, instantiateNodes } from './node';

jest.mock('../../helper', () => {
return {
initLogger: () => {
return {
info: () => { },
debug: () => { }
};
}
};
});

jest.mock('../schema-directory');

let mockSchemaDir;

beforeEach(() => {
mockSchemaDir = new SchemaDirectory('directory');
});

function getSamplePatternNode(properties: any): any {
return {
properties: {
nodes: {
type: 'array',
prefixItems: [
{
properties: properties
}
]
}
}
};
}


describe('instantiateNodes', () => {
it('return instantiated node with array property', () => {
const pattern = getSamplePatternNode({
'property-name': {
type: 'array'
}
});
expect(instantiateNodes(pattern, mockSchemaDir))
.toEqual(
[{
'property-name': [
'{{ PROPERTY_NAME }}'
]
}]
);
});

it('return instantiated node with string property', () => {
const pattern = getSamplePatternNode({
'property-name': {
type: 'string'
}
});

expect(instantiateNodes(pattern, mockSchemaDir))
.toEqual([
{
'property-name': '{{ PROPERTY_NAME }}'
}
]);
});

it('return instantiated node with const property', () => {
const pattern = getSamplePatternNode({
'property-name': {
const: 'value here'
}
});

expect(instantiateNodes(pattern, mockSchemaDir))
.toEqual([
{
'property-name': 'value here'
}
]);
});

it('call schema directory to resolve $ref nodes`', () => {
const reference = 'https://calm.com/core.json#/node';
const pattern = {
properties: {
nodes: {
type: 'array',
prefixItems: [
{
'$ref': reference
}
]
}
}
};

const spy = jest.spyOn(mockSchemaDir, 'getDefinition');
spy.mockReturnValue({
properties: {
'property-name': {
const: 'value here'
}
}
});

expect(instantiateNodes(pattern, mockSchemaDir))
.toEqual([
{
'property-name': 'value here'
}
]);
expect(spy).toHaveBeenCalledWith(reference);
});

it('return instantiated node with interface', () => {
const pattern = {
properties: {
nodes: {
type: 'array',
prefixItems: [
{
properties: {
'unique-id': {
'const': 'unique-id'
},
// interfaces should be inserted
'interfaces': {
'prefixItems': [
{
properties: {
// should insert placeholder {{ INTERFACE_PROPERTY }}
'interface-property': {
'type': 'string'
}
}
}
]
}
}
}
]
}

}

};

const expected = [
{
'unique-id': 'unique-id',
'interfaces': [
{
'interface-property': '{{ INTERFACE_PROPERTY }}'
}
]
}
];

expect(instantiateNodes(pattern, mockSchemaDir))
.toEqual(expected);

});
});


function getSampleNodeInterfaces(properties: any): any {
return {
prefixItems: [
{
properties: properties
}
]
};
}


describe('instantiateNodeInterfaces', () => {

it('return instantiated node with array property', () => {
const pattern = getSampleNodeInterfaces({
'property-name': {
type: 'array'
}
});
expect(instantiateNodeInterfaces(pattern, mockSchemaDir))
.toEqual(
[{
'property-name': [
'{{ PROPERTY_NAME }}'
]
}]
);
});

it('return instantiated node with string property', () => {
const pattern = getSampleNodeInterfaces({
'property-name': {
type: 'string'
}
});

expect(instantiateNodeInterfaces(pattern, mockSchemaDir))
.toEqual([
{
'property-name': '{{ PROPERTY_NAME }}'
}
]);
});

it('return instantiated node with const property', () => {
const pattern = getSampleNodeInterfaces({
'property-name': {
const: 'value here'
}
});

expect(instantiateNodeInterfaces(pattern, mockSchemaDir))
.toEqual([
{
'property-name': 'value here'
}
]);
});

it('call schema directory to resolve $ref interfaces`', () => {
const reference = 'https://calm.com/core.json#/interface';

const pattern = {
prefixItems: [
{
'$ref': reference
}
]
};

const spy = jest.spyOn(mockSchemaDir, 'getDefinition');
spy.mockReturnValue({
properties: {
'property-name': {
const: 'value here'
}
}
});

expect(instantiateNodeInterfaces(pattern, mockSchemaDir))
.toEqual([
{
'property-name': 'value here'
}
]);
expect(spy).toHaveBeenCalledWith(reference);
});
});
Loading

0 comments on commit b2b4362

Please sign in to comment.