mirror of
https://github.com/LukeHagar/redocly-cli.git
synced 2025-12-09 12:47:48 +00:00
refactor: split in two packages: core and cli (#223)
This commit is contained in:
367
packages/core/__tests__/resolve.test.ts
Normal file
367
packages/core/__tests__/resolve.test.ts
Normal file
@@ -0,0 +1,367 @@
|
||||
import { outdent } from 'outdent';
|
||||
import * as path from 'path';
|
||||
|
||||
import { resolveDocument, BaseResolver, Document } from '../src/resolve';
|
||||
import { parseYamlToDocument } from './utils';
|
||||
import { Oas3Types } from '../src/types/oas3';
|
||||
import { normalizeTypes } from '../src/types';
|
||||
|
||||
describe('collect refs', () => {
|
||||
it('should resolve local refs', async () => {
|
||||
const rootDocument = parseYamlToDocument(
|
||||
outdent`
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
$ref: "#/defs/info"
|
||||
defs:
|
||||
info:
|
||||
contact: {}
|
||||
license: {}
|
||||
`,
|
||||
'foobar.yaml',
|
||||
);
|
||||
|
||||
const resolvedRefs = await resolveDocument({
|
||||
rootDocument,
|
||||
externalRefResolver: new BaseResolver(),
|
||||
rootType: normalizeTypes(Oas3Types).DefinitionRoot,
|
||||
});
|
||||
|
||||
expect(resolvedRefs).toBeDefined();
|
||||
expect(resolvedRefs.size).toEqual(1);
|
||||
expect(Array.from(resolvedRefs.keys())).toMatchInlineSnapshot(
|
||||
[`foobar.yaml::#/defs/info`],
|
||||
`
|
||||
Array [
|
||||
"foobar.yaml::#/defs/info",
|
||||
]
|
||||
`,
|
||||
);
|
||||
expect(Array.from(resolvedRefs.values()).map((info) => info.node)).toEqual([
|
||||
{ contact: {}, license: {} },
|
||||
]);
|
||||
});
|
||||
|
||||
// Or using async/await.
|
||||
it('should throw on self-circular refs', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const rootDocument = parseYamlToDocument(
|
||||
outdent`
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
$ref: "#/info"
|
||||
defs:
|
||||
info:
|
||||
contact: {}
|
||||
license: {}
|
||||
`,
|
||||
'',
|
||||
);
|
||||
|
||||
try {
|
||||
await resolveDocument({
|
||||
rootDocument,
|
||||
externalRefResolver: new BaseResolver(),
|
||||
rootType: normalizeTypes(Oas3Types).DefinitionRoot,
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('Self-referencing circular pointer');
|
||||
}
|
||||
});
|
||||
|
||||
it('should resolve local transitive refs', async () => {
|
||||
const rootDocument = parseYamlToDocument(
|
||||
outdent`
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
$ref: "#/tmp/info"
|
||||
tmp:
|
||||
$ref: '#/defs'
|
||||
prop:
|
||||
$ref: '#/propTrans'
|
||||
propTrans:
|
||||
$ref: '#/propDest'
|
||||
propDest:
|
||||
type: string
|
||||
defs:
|
||||
info:
|
||||
contact: {}
|
||||
license: {}
|
||||
`,
|
||||
'foobar.yaml',
|
||||
);
|
||||
|
||||
const resolvedRefs = await resolveDocument({
|
||||
rootDocument,
|
||||
externalRefResolver: new BaseResolver(),
|
||||
rootType: normalizeTypes(Oas3Types).DefinitionRoot,
|
||||
});
|
||||
|
||||
expect(resolvedRefs).toBeDefined();
|
||||
expect(resolvedRefs.size).toEqual(4);
|
||||
expect(Array.from(resolvedRefs.keys())).toEqual([
|
||||
'foobar.yaml::#/defs',
|
||||
'foobar.yaml::#/propDest',
|
||||
'foobar.yaml::#/tmp/info',
|
||||
'foobar.yaml::#/propTrans',
|
||||
]);
|
||||
expect(Array.from(resolvedRefs.values()).map((info) => info.node)).toEqual([
|
||||
{ info: { contact: {}, license: {} } },
|
||||
{ type: 'string' },
|
||||
{ contact: {}, license: {} },
|
||||
{ type: 'string' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should throw on ref loop', async () => {
|
||||
const rootDocument = parseYamlToDocument(
|
||||
outdent`
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
$ref: "#/loop"
|
||||
loop:
|
||||
$ref: '#/loop2'
|
||||
loop2:
|
||||
$ref: '#/info'
|
||||
`,
|
||||
'foobar.yaml',
|
||||
);
|
||||
|
||||
try {
|
||||
await resolveDocument({
|
||||
rootDocument,
|
||||
externalRefResolver: new BaseResolver(),
|
||||
rootType: normalizeTypes(Oas3Types).DefinitionRoot,
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('Self-referencing circular pointer');
|
||||
}
|
||||
});
|
||||
|
||||
it('should resolve external ref', async () => {
|
||||
const cwd = path.join(__dirname, 'fixtures/resolve');
|
||||
const rootDocument = parseYamlToDocument(
|
||||
outdent`
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
$ref: "./externalInfo.yaml#/info"
|
||||
`,
|
||||
path.join(cwd, 'foobar.yaml'),
|
||||
);
|
||||
|
||||
const resolvedRefs = await resolveDocument({
|
||||
rootDocument,
|
||||
externalRefResolver: new BaseResolver(),
|
||||
rootType: normalizeTypes(Oas3Types).DefinitionRoot,
|
||||
});
|
||||
|
||||
expect(resolvedRefs).toBeDefined();
|
||||
// expect(resolvedRefs.size).toEqual(2);
|
||||
expect(Array.from(resolvedRefs.keys()).map((ref) => ref.substring(cwd.length + 1))).toEqual([
|
||||
'foobar.yaml::./externalInfo.yaml#/info',
|
||||
'externalInfo.yaml::./externalLicense.yaml',
|
||||
]);
|
||||
|
||||
expect(Array.from(resolvedRefs.values()).map((info) => info.node)).toEqual([
|
||||
{
|
||||
contact: {},
|
||||
license: {
|
||||
$ref: './externalLicense.yaml',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'MIT',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should resolve back references', async () => {
|
||||
const cwd = path.join(__dirname, 'fixtures/resolve');
|
||||
const externalRefResolver = new BaseResolver();
|
||||
const rootDocument = await externalRefResolver.resolveDocument(
|
||||
null,
|
||||
`${cwd}/openapi-with-back.yaml`,
|
||||
);
|
||||
|
||||
const resolvedRefs = await resolveDocument({
|
||||
rootDocument: rootDocument as Document,
|
||||
externalRefResolver: externalRefResolver,
|
||||
rootType: normalizeTypes(Oas3Types).DefinitionRoot,
|
||||
});
|
||||
|
||||
expect(resolvedRefs).toBeDefined();
|
||||
|
||||
expect(Array.from(resolvedRefs.keys()).map((ref) => ref.substring(cwd.length + 1)))
|
||||
.toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"openapi-with-back.yaml::./schemas/type-a.yaml#/",
|
||||
"openapi-with-back.yaml::./schemas/type-b.yaml#/",
|
||||
"schemas/type-a.yaml::../openapi-with-back.yaml#/components/schemas/TypeB",
|
||||
]
|
||||
`);
|
||||
|
||||
expect(Array.from(resolvedRefs.values()).map((val) => val.node)).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"allOf": Array [
|
||||
Object {
|
||||
"properties": Object {
|
||||
"integration_type": Object {
|
||||
"$ref": "../openapi-with-back.yaml#/components/schemas/TypeB",
|
||||
},
|
||||
"name": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": Array [
|
||||
"name",
|
||||
"integration_type",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"enum": Array [
|
||||
"webhook",
|
||||
"api_key",
|
||||
"sftp",
|
||||
"netsuite",
|
||||
],
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"enum": Array [
|
||||
"webhook",
|
||||
"api_key",
|
||||
"sftp",
|
||||
"netsuite",
|
||||
],
|
||||
"type": "string",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should resolve external refs with circular', async () => {
|
||||
const cwd = path.join(__dirname, 'fixtures/resolve');
|
||||
const externalRefResolver = new BaseResolver();
|
||||
const rootDocument = await externalRefResolver.resolveDocument(null, `${cwd}/openapi.yaml`);
|
||||
|
||||
const resolvedRefs = await resolveDocument({
|
||||
rootDocument: rootDocument as Document,
|
||||
externalRefResolver: externalRefResolver,
|
||||
rootType: normalizeTypes(Oas3Types).DefinitionRoot,
|
||||
});
|
||||
|
||||
expect(resolvedRefs).toBeDefined();
|
||||
expect(Array.from(resolvedRefs.keys()).map((ref) => ref.substring(cwd.length + 1)))
|
||||
.toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"openapi.yaml::#/components/schemas/Local",
|
||||
"openapi.yaml::#/components/schemas/Local/properties/string",
|
||||
"openapi.yaml::./External.yaml#/properties/string",
|
||||
"openapi.yaml::./External.yaml",
|
||||
"External.yaml::./External2.yaml",
|
||||
"External2.yaml::./External.yaml#/properties",
|
||||
]
|
||||
`);
|
||||
|
||||
expect(Array.from(resolvedRefs.values()).map((val) => val.node)).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"properties": Object {
|
||||
"localCircular": Object {
|
||||
"$ref": "#/components/schemas/Local",
|
||||
},
|
||||
"number": Object {
|
||||
"type": "number",
|
||||
},
|
||||
"string": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"properties": Object {
|
||||
"external": Object {
|
||||
"$ref": "./External2.yaml",
|
||||
},
|
||||
"number": Object {
|
||||
"type": "number",
|
||||
},
|
||||
"string": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"unknown": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"type": "object",
|
||||
},
|
||||
Object {
|
||||
"properties": Object {
|
||||
"circularParent": Object {
|
||||
"$ref": "./External.yaml#/properties",
|
||||
},
|
||||
},
|
||||
"type": "object",
|
||||
},
|
||||
Object {
|
||||
"external": Object {
|
||||
"$ref": "./External2.yaml",
|
||||
},
|
||||
"number": Object {
|
||||
"type": "number",
|
||||
},
|
||||
"string": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"unknown": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should resolve referenceable scalars', async () => {
|
||||
const cwd = path.join(__dirname, 'fixtures/resolve');
|
||||
const externalRefResolver = new BaseResolver();
|
||||
const rootDocument = await externalRefResolver.resolveDocument(
|
||||
null,
|
||||
`${cwd}/openapi-with-md-description.yaml`,
|
||||
);
|
||||
|
||||
expect(rootDocument).toBeDefined();
|
||||
|
||||
const resolvedRefs = await resolveDocument({
|
||||
rootDocument: rootDocument as Document,
|
||||
externalRefResolver: externalRefResolver,
|
||||
rootType: normalizeTypes(Oas3Types).DefinitionRoot,
|
||||
});
|
||||
|
||||
expect(resolvedRefs).toBeDefined();
|
||||
// expect(resolvedRefs.size).toEqual(2);
|
||||
expect(Array.from(resolvedRefs.keys()).map((ref) => ref.substring(cwd.length + 1)))
|
||||
.toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"openapi-with-md-description.yaml::./description.md",
|
||||
]
|
||||
`);
|
||||
expect(Array.from(resolvedRefs.values()).map((val) => val.node)).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
"# Hello World
|
||||
|
||||
Lorem ipsum",
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user