Merge branch 'split/develop/multiFileSupport' into fix/formatForEachroot

This commit is contained in:
Luis Tejeda
2022-06-09 11:50:38 -05:00
30 changed files with 1173 additions and 193 deletions

View File

@@ -0,0 +1,72 @@
const COMPONENTS_KEYS_30 = [
'schemas',
'responses',
'parameters',
'examples',
'requestBodies',
'headers',
'securitySchemes',
'links',
'callbacks'
],
SCHEMA_CONTAINERS = [
'allOf',
'oneOf',
'anyOf',
'not',
'additionalProperties',
'items',
'schema'
],
EXAMPLE_CONTAINERS = [
'example'
],
PROPERTY_DEFINITION = [
'properties'
];
module.exports = {
/**
* Generates the trace to the key that will wrap de component using 3.0 version
* @param {array} traceFromParent - The trace from the parent key
* @param {string} filePathName - The filePath name from the file
* @param {string} localPart - The local path part
* @param {function} jsonPointerDecodeAndReplace - Function to decode a json pointer
* @returns {array} The trace to the container key
*/
getKeyInComponents30: function (traceFromParent, filePathName, localPart, jsonPointerDecodeAndReplace) {
let res = traceFromParent,
trace = [],
traceToKey = [],
matchFound = false,
isInComponents = traceFromParent[0] === 'components';
if (isInComponents) {
return [];
}
res.push(jsonPointerDecodeAndReplace(`${filePathName}${localPart}`));
trace = [...res].reverse();
for (let [index, item] of trace.entries()) {
if (SCHEMA_CONTAINERS.includes(item)) {
item = 'schemas';
}
if (EXAMPLE_CONTAINERS.includes(item)) {
item = 'examples';
}
if (PROPERTY_DEFINITION.includes(trace[index + 2])) {
trace[index + 1] = 'schemas';
}
traceToKey.push(item);
if (COMPONENTS_KEYS_30.includes(item)) {
matchFound = true;
break;
}
}
return matchFound ?
traceToKey.reverse() :
[];
},
COMPONENTS_KEYS_30
};

View File

@@ -6,10 +6,12 @@ const {
removeLocalReferenceFromPath, removeLocalReferenceFromPath,
localPointer, localPointer,
jsonPointerLevelSeparator, jsonPointerLevelSeparator,
isLocalRef isLocalRef,
jsonPointerDecodeAndReplace
} = require('./jsonPointer'), } = require('./jsonPointer'),
traverseUtility = require('traverse'), traverseUtility = require('traverse'),
parse = require('./parse.js'); parse = require('./parse.js'),
{ ParseError } = require('./common/ParseError');
let path = require('path'), let path = require('path'),
pathBrowserify = require('path-browserify'), pathBrowserify = require('path-browserify'),
@@ -40,6 +42,18 @@ function comparePaths(path1, path2) {
return path1 === path2; return path1 === path2;
} }
/**
* Parses a node content or throw ParseError if there's any error
* @param {string} fileContent The content from the current node
* @returns {object} The parsed content
*/
function parseFileOrThrow(fileContent) {
const result = parse.getOasObject(fileContent);
if (result.result === false) {
throw new ParseError(result.reason);
}
return result;
}
/** /**
* Calculates the path relative to parent * Calculates the path relative to parent
@@ -136,7 +150,9 @@ function getContentFromTrace(content, partial) {
return content; return content;
} }
partial = partial[0] === jsonPointerLevelSeparator ? partial.substring(1) : partial; partial = partial[0] === jsonPointerLevelSeparator ? partial.substring(1) : partial;
const trace = partial.split(jsonPointerLevelSeparator); const trace = partial.split(jsonPointerLevelSeparator).map((item) => {
return jsonPointerDecodeAndReplace(item);
});
let currentValue = content; let currentValue = content;
currentValue = deref._getEscaped(content, trace, undefined); currentValue = deref._getEscaped(content, trace, undefined);
return currentValue; return currentValue;
@@ -196,8 +212,8 @@ function getTraceFromParentKeyInComponents(nodeContext, property) {
[key, ...parentKeys], [key, ...parentKeys],
nodeTrace = getRootFileTrace(nodeParentsKey), nodeTrace = getRootFileTrace(nodeParentsKey),
[file, local] = property.split(localPointer), [file, local] = property.split(localPointer),
[keyTraceInComponents, inComponents] = getKeyInComponents(nodeTrace, file, local); keyTraceInComponents = getKeyInComponents(nodeTrace, file, local);
return [keyTraceInComponents, inComponents]; return keyTraceInComponents;
} }
/** /**
@@ -227,7 +243,7 @@ function getReferences (currentNode, isOutOfRoot, pathSolver, parentFilename) {
); );
if (hasReferenceTypeKey) { if (hasReferenceTypeKey) {
const tempRef = calculatePath(parentFilename, property.$ref), const tempRef = calculatePath(parentFilename, property.$ref),
[nodeTrace] = getTraceFromParentKeyInComponents(this, tempRef), nodeTrace = getTraceFromParentKeyInComponents(this, tempRef),
referenceInDocument = getJsonPointerRelationToRoot( referenceInDocument = getJsonPointerRelationToRoot(
jsonPointerEncodeAndReplace, jsonPointerEncodeAndReplace,
tempRef, tempRef,
@@ -281,7 +297,7 @@ function getNodeContentAndReferences (currentNode, allData, specRoot) {
nodeContent = currentNode.parsed.oasObject; nodeContent = currentNode.parsed.oasObject;
} }
else { else {
nodeContent = parse.getOasObject(currentNode.content).oasObject; nodeContent = parseFileOrThrow(currentNode.content).oasObject;
} }
const { referencesInNode, nodeReferenceDirectory } = getReferences( const { referencesInNode, nodeReferenceDirectory } = getReferences(
@@ -321,6 +337,17 @@ function getNodeContentAndReferences (currentNode, allData, specRoot) {
* @returns {object} The components object related to the file * @returns {object} The components object related to the file
*/ */
function generateComponentsObject (documentContext, rootContent, refTypeResolver, components) { function generateComponentsObject (documentContext, rootContent, refTypeResolver, components) {
let notInLine = Object.entries(documentContext.globalReferences).filter(([, value]) => {
return value.keyInComponents.length !== 0;
});
notInLine.forEach(([key, value]) => {
let [, partial] = key.split('#');
setValueInComponents(
value.keyInComponents,
components,
getContentFromTrace(documentContext.nodeContents[key], partial)
);
});
[rootContent, components].forEach((contentData) => { [rootContent, components].forEach((contentData) => {
traverseUtility(contentData).forEach(function (property) { traverseUtility(contentData).forEach(function (property) {
if (property) { if (property) {
@@ -375,6 +402,22 @@ function generateComponentsObject (documentContext, rootContent, refTypeResolver
}); });
} }
/**
* Generates the components object wrapper
* @param {object} parsedOasObject The parsed root
* @param {string} version - The current version
* @returns {object} The components object wrapper
*/
function generateComponentsWrapper(parsedOasObject) {
let components = {};
if (parsedOasObject.hasOwnProperty('components')) {
components = parsedOasObject.components;
}
return components;
}
module.exports = { module.exports = {
/** /**
* Takes in an spec root file and an array of data files * Takes in an spec root file and an array of data files
@@ -396,15 +439,19 @@ module.exports = {
rootContextData = algorithm.traverseAndBundle(specRoot, (currentNode) => { rootContextData = algorithm.traverseAndBundle(specRoot, (currentNode) => {
return getNodeContentAndReferences(currentNode, allData, specRoot); return getNodeContentAndReferences(currentNode, allData, specRoot);
}); });
if (specRoot.parsed.oasObject.hasOwnProperty('components')) { components = generateComponentsWrapper(specRoot.parsed.oasObject);
components = specRoot.parsed.oasObject.components; generateComponentsObject(
} rootContextData,
generateComponentsObject(rootContextData, rootContextData.nodeContents[specRoot.fileName], isExtRef, components); rootContextData.nodeContents[specRoot.fileName],
isExtRef,
components
);
return { return {
fileContent: rootContextData.nodeContents[specRoot.fileName], fileContent: rootContextData.nodeContents[specRoot.fileName],
components, components,
fileName: specRoot.fileName fileName: specRoot.fileName
}; };
}, },
getReferences getReferences,
parseFileOrThrow
}; };

View File

@@ -6,26 +6,7 @@ const slashes = /\//g,
escapedTilde = /~0/g, escapedTilde = /~0/g,
jsonPointerLevelSeparator = '/', jsonPointerLevelSeparator = '/',
escapedTildeString = '~0', escapedTildeString = '~0',
COMPONENTS_KEYS = [ { getKeyInComponents30 } = require('./30XUtils/componentsParentMatcher');
'schemas',
'responses',
'parameters',
'examples',
'requestBodies',
'headers',
'securitySchemes',
'links',
'callbacks'
],
SCHEMA_PARENT_KEYS_IN_DOC = [
'allOf',
'oneOf',
'anyOf',
'not',
'additionalProperties',
'items',
'schema'
];
/** /**
* Encodes a filepath name so it can be a json pointer * Encodes a filepath name so it can be a json pointer
@@ -52,49 +33,14 @@ function jsonPointerDecodeAndReplace(filePathName) {
* @param {string} traceFromParent the node trace from root. * @param {string} traceFromParent the node trace from root.
* @param {string} filePathName the filePathName of the file * @param {string} filePathName the filePathName of the file
* @param {string} localPath the local path that the pointer will reach * @param {string} localPath the local path that the pointer will reach
* @param {string} version - The current spec version
* @returns {Array} - the calculated keys in an array representing each nesting property name * @returns {Array} - the calculated keys in an array representing each nesting property name
*/ */
function getKeyInComponents(traceFromParent, filePathName, localPath) { function getKeyInComponents(traceFromParent, filePathName, localPath) {
const localPart = localPath ? `${localPointer}${localPath}` : ''; const localPart = localPath ? `${localPointer}${localPath}` : '';
let res = traceFromParent, let result;
trace = [], result = getKeyInComponents30(traceFromParent, filePathName, localPart, jsonPointerDecodeAndReplace);
traceToKey = [], return result;
matchFound = false,
inComponents = false;
if (traceFromParent[0] === 'components') {
inComponents = true;
return [[], inComponents];
}
res.push(jsonPointerDecodeAndReplace(`${filePathName}${localPart}`));
trace = [...res].reverse();
for (let item of trace) {
if (SCHEMA_PARENT_KEYS_IN_DOC.includes(item)) {
item = 'schemas';
}
traceToKey.push(item);
if (COMPONENTS_KEYS.includes(item)) {
matchFound = true;
break;
}
}
return [matchFound ?
traceToKey.reverse() :
[], inComponents];
}
/**
* returns the local path of a pointer #/definitions/dog etc.
* @param {string} jsonPointer the complet pointer
* @returns {string} - the calculated key
*/
function getLocalPath(jsonPointer) {
if (jsonPointer.includes(localPointer)) {
return jsonPointer.split(localPointer)[1];
}
return '';
} }
/** /**
@@ -102,13 +48,14 @@ function getLocalPath(jsonPointer) {
* @constructor * @constructor
* @param {Function} encodeFunction function to encode url * @param {Function} encodeFunction function to encode url
* @param {string} traceFromParent the trace from parent. * @param {string} traceFromParent the trace from parent.
* @param {string} targetInRoot - The root element where we will point
* @returns {string} - the concatenated json pointer * @returns {string} - the concatenated json pointer
*/ */
function concatJsonPointer(encodeFunction, traceFromParent) { function concatJsonPointer(encodeFunction, traceFromParent, targetInRoot) {
const traceFromParentAsString = traceFromParent.map((trace) => { const traceFromParentAsString = traceFromParent.map((trace) => {
return encodeFunction(trace); return encodeFunction(trace);
}).join('/'); }).join('/');
return localPointer + '/components' + jsonPointerLevelSeparator + traceFromParentAsString; return localPointer + targetInRoot + jsonPointerLevelSeparator + traceFromParentAsString;
} }
/** /**
@@ -117,14 +64,15 @@ function concatJsonPointer(encodeFunction, traceFromParent) {
* @param {Function} encodeFunction function to encode url * @param {Function} encodeFunction function to encode url
* @param {string} refValue the type of component e.g. schemas, parameters, etc. * @param {string} refValue the type of component e.g. schemas, parameters, etc.
* @param {string} traceFromKey the trace from the parent node. * @param {string} traceFromKey the trace from the parent node.
* @param {string} version - The version we are working on
* @returns {string} - the concatenated json pointer * @returns {string} - the concatenated json pointer
*/ */
function getJsonPointerRelationToRoot(encodeFunction, refValue, traceFromKey) { function getJsonPointerRelationToRoot(encodeFunction, refValue, traceFromKey) {
let targetInRoot = '/components';
if (refValue.startsWith(localPointer)) { if (refValue.startsWith(localPointer)) {
return refValue; return refValue;
} }
const localPath = getLocalPath(refValue); return concatJsonPointer(encodeFunction, traceFromKey, targetInRoot);
return concatJsonPointer(encodeFunction, traceFromKey, localPath);
} }
/** /**

View File

@@ -92,7 +92,7 @@ const { formatDataPath, checkIsCorrectType, isKnownType } = require('./common/sc
{ getRelatedFiles } = require('./relatedFiles'), { getRelatedFiles } = require('./relatedFiles'),
{ compareVersion } = require('./common/versionUtils.js'), { compareVersion } = require('./common/versionUtils.js'),
parse = require('./parse'), parse = require('./parse'),
{ getBundleContentAndComponents } = require('./bundle.js'), { getBundleContentAndComponents, parseFileOrThrow } = require('./bundle.js'),
MULTI_FILE_API_TYPE_ALLOWED_VALUE = 'multiFile'; MULTI_FILE_API_TYPE_ALLOWED_VALUE = 'multiFile';
/* eslint-enable */ /* eslint-enable */
@@ -4901,7 +4901,7 @@ module.exports = {
mapProcessRelatedFiles(rootFiles, inputData, origin, version, format, toBundle = false) { mapProcessRelatedFiles(rootFiles, inputData, origin, version, format, toBundle = false) {
let bundleFormat = format, let bundleFormat = format,
parsedRootFiles = rootFiles.map((rootFile) => { parsedRootFiles = rootFiles.map((rootFile) => {
let parsedContent = this.parseFileOrThrow(rootFile.content); let parsedContent = parseFileOrThrow(rootFile.content);
return { fileName: rootFile.fileName, content: rootFile.content, parsed: parsedContent }; return { fileName: rootFile.fileName, content: rootFile.content, parsed: parsedContent };
}).filter((rootWithParsedContent) => { }).filter((rootWithParsedContent) => {
// bundleFormat = bundleFormat ? bundleFormat : rootWithParsedContent.parsed.inputFormat; // bundleFormat = bundleFormat ? bundleFormat : rootWithParsedContent.parsed.inputFormat;
@@ -4985,13 +4985,5 @@ module.exports = {
throw new Error('"Path" of the data element should be provided'); throw new Error('"Path" of the data element should be provided');
} }
}, },
parseFileOrThrow(fileContent) {
const result = parse.getOasObject(fileContent);
if (result.result === false) {
throw new ParseError(result.reason);
}
return result;
},
MULTI_FILE_API_TYPE_ALLOWED_VALUE MULTI_FILE_API_TYPE_ALLOWED_VALUE
}; };

View File

@@ -49,19 +49,22 @@
"type": "object", "type": "object",
"properties": { "properties": {
"theUsersPet": { "theUsersPet": {
"type": "object", "$ref": "#/components/schemas/~1schemas~1user.yaml%23~1Pet"
"properties": {
"name": {
"type": "string"
},
"breed": {
"type": "string"
}
}
} }
} }
} }
} }
},
"/schemas/user.yaml#/Pet": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"breed": {
"type": "string"
}
}
} }
} }
} }

View File

@@ -49,43 +49,58 @@
"type": "object", "type": "object",
"properties": { "properties": {
"favoriteFood": { "favoriteFood": {
"type": "object", "$ref": "#/components/schemas/~1schemas~1food.yaml%23Food"
"properties": {
"brand": {
"type": "string"
},
"benefits": {
"type": "array",
"items": {
"$ref": "#/components/schemas/~1schemas~1food.yaml%23~1Benefit"
}
},
"cost": {
"type": "string"
}
}
}, },
"theUsersPet": { "theUsersPet": {
"type": "object", "$ref": "#/components/schemas/~1schemas~1user.yaml%23~1Pet"
"properties": {
"name": {
"type": "string"
},
"breed": {
"type": "string"
},
"color": {
"type": "array",
"items": {
"$ref": "#/components/schemas/~1schemas~1user.yaml%23~1Color"
}
}
}
} }
} }
} }
} }
}, },
"/schemas/food.yaml#Food": {
"type": "object",
"properties": {
"brand": {
"$ref": "#/components/schemas/~1schemas~1food.yaml%23~1Brand"
},
"benefits": {
"type": "array",
"items": {
"$ref": "#/components/schemas/~1schemas~1food.yaml%23~1Benefit"
}
},
"cost": {
"type": "string"
}
}
},
"/schemas/user.yaml#/Pet": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"breed": {
"type": "string"
},
"color": {
"$ref": "#/components/schemas/~1schemas~1user.yaml%23~1Colors"
}
}
},
"/schemas/user.yaml#/Colors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/~1schemas~1user.yaml%23~1Color"
}
},
"/schemas/user.yaml#/Color": {
"type": "string"
},
"/schemas/food.yaml#/Brand": {
"type": "string"
},
"/schemas/food.yaml#/Benefit": { "/schemas/food.yaml#/Benefit": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -96,9 +111,6 @@
"type": "string" "type": "string"
} }
} }
},
"/schemas/user.yaml#/Color": {
"type": "string"
} }
} }
} }

View File

@@ -80,31 +80,13 @@
"type": "object", "type": "object",
"properties": { "properties": {
"userInfo": { "userInfo": {
"type": "object", "$ref": "#/components/schemas/~1schemas~1user.yaml"
"properties": {
"id": {
"type": "integer"
},
"userName": {
"type": "string"
}
}
}, },
"carType": { "carType": {
"type": "object", "$ref": "#/components/schemas/~1schemas~1carType.yaml"
"properties": {
"model": {
"type": "string"
}
}
}, },
"work": { "work": {
"type": "object", "$ref": "#/components/schemas/~1otherSchemas~1work.yaml"
"properties": {
"office": {
"type": "string"
}
}
} }
} }
}, },
@@ -118,6 +100,36 @@
"type": "string" "type": "string"
} }
} }
},
"/schemas/user.yaml": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"userName": {
"type": "string"
}
}
},
"/schemas/carType.yaml": {
"type": "object",
"properties": {
"model": {
"$ref": "#/components/schemas/~1otherSchemas~1model.yaml"
}
}
},
"/otherSchemas/work.yaml": {
"type": "object",
"properties": {
"office": {
"type": "string"
}
}
},
"/otherSchemas/model.yaml": {
"type": "string"
} }
} }
} }

View File

@@ -0,0 +1,126 @@
{
"openapi": "3.0.0",
"info": {
"title": "Sample API",
"description": "Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.",
"version": "0.1.9"
},
"servers": [
{
"url": "http://api.example.com/v1",
"description": "Optional server description, e.g. Main (production) server"
},
{
"url": "http://staging-api.example.com",
"description": "Optional server description, e.g. Internal staging server for testing"
}
],
"paths": {
"/users/{userId}": {
"get": {
"summary": "Get a user by ID",
"responses": {
"200": {
"description": "A single user.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/~1schemas~1user.yaml"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"/schemas/user.yaml": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"userName": {
"type": "string"
},
"complexProp": {
"$ref": "#/components/schemas/~1properties~1prop.yaml"
}
}
},
"/properties/prop.yaml": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"secondName": {
"type": "string"
},
"age": {
"type": "integer"
},
"nestedProp": {
"$ref": "#/components/schemas/~1properties~1nestedProp.yaml"
},
"country": {
"$ref": "#/components/schemas/~1properties~1country.yaml"
},
"warrior": {
"$ref": "#/components/schemas/~1properties~1warrior.yaml"
}
}
},
"/properties/nestedProp.yaml": {
"type": "object",
"rock": {
"type": "boolean"
},
"friendly": {
"type": "string"
},
"lastNested": {
"type": "object",
"properties": {
"this": {
"type": "string"
},
"is": {
"type": "string"
},
"the": {
"type": "string"
},
"last": {
"type": "integer"
}
}
}
},
"/properties/country.yaml": {
"type": "object",
"properties": {
"region": {
"type": "string"
},
"flag": {
"type": "string"
}
}
},
"/properties/warrior.yaml": {
"type": "object",
"properties": {
"power": {
"type": "string"
},
"weapon": {
"type": "string"
}
}
}
}
}
}

View File

@@ -0,0 +1,6 @@
type: object
properties:
region:
type: string
flag:
type: string

View File

@@ -0,0 +1,10 @@
type: object
properties:
this:
type: string
is:
type: string
the:
type: string
last:
type: integer

View File

@@ -0,0 +1,7 @@
type: object
rock:
type: boolean
friendly:
type: string
lastNested:
$ref: "./lastNested.yaml"

View File

@@ -0,0 +1,14 @@
type: object
properties:
firstName:
type: string
secondName:
type: string
age:
type: integer
nestedProp:
$ref: "./nestedProp.yaml"
country:
$ref: "./country.yaml"
warrior:
$ref: "./warrior.yaml"

View File

@@ -0,0 +1,6 @@
type: object
properties:
power:
type: string
weapon:
type: string

View File

@@ -0,0 +1,23 @@
openapi: 3.0.0
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users/{userId}:
get:
summary: Get a user by ID
responses:
200:
description: A single user.
content:
application/json:
schema:
$ref: "./schemas/user.yaml"

View File

@@ -0,0 +1,8 @@
type: object
properties:
id:
type: integer
userName:
type: string
complexProp:
$ref: "../properties/prop.yaml"

View File

@@ -0,0 +1,69 @@
{
"openapi": "3.0.0",
"info": {
"title": "Sample API",
"description": "Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.",
"version": "0.1.9"
},
"servers": [
{
"url": "http://api.example.com/v1",
"description": "Optional server description, e.g. Main (production) server"
},
{
"url": "http://staging-api.example.com",
"description": "Optional server description, e.g. Internal staging server for testing"
}
],
"paths": {
"/users/{userId}": {
"get": {
"summary": "Get a user by ID",
"responses": {
"200": {
"description": "A single user.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/~1schemas~1user.yaml"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"/schemas/user.yaml": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"userName": {
"type": "string"
},
"complexProp": {
"$ref": "#/components/schemas/~1schemas~1prop.yaml"
}
}
},
"/schemas/prop.yaml": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"secondName": {
"type": "string"
},
"age": {
"type": "integer"
}
}
}
}
}
}

View File

@@ -0,0 +1,23 @@
openapi: 3.0.0
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users/{userId}:
get:
summary: Get a user by ID
responses:
200:
description: A single user.
content:
application/json:
schema:
$ref: "./schemas/user.yaml"

View File

@@ -0,0 +1,8 @@
type: object
properties:
firstName:
type: string
secondName:
type: string
age:
type: integer

View File

@@ -0,0 +1,8 @@
type: object
properties:
id:
type: integer
userName:
type: string
complexProp:
$ref: ./prop.yaml

View File

@@ -0,0 +1,5 @@
foo:
summary: sum
value:
code: 1
message: test error message

View File

@@ -0,0 +1,100 @@
{
"openapi": "3.0.2",
"info": {
"version": "1.0.0",
"title": "Swagger Petstore",
"description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "Swagger API Team",
"email": "apiteam@swagger.io",
"url": "http://swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"paths": {
"/pets": {
"get": {
"description": "Returns all pets alesuada ac...",
"operationId": "findPets",
"responses": {
"200": {
"description": "pet response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Pet"
}
},
"example": {
"$ref": "#/components/examples/~1examples.yaml%23~1foo"
}
}
}
},
"default": {
"description": "unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Pet": {
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"tag": {
"type": "string"
}
}
},
"Error": {
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
}
}
}
},
"examples": {
"/examples.yaml#/foo": {
"summary": "sum",
"value": {
"code": 1,
"message": "test error message"
}
}
}
}
}

View File

@@ -0,0 +1,60 @@
openapi: "3.0.2"
info:
version: 1.0.0
title: Swagger Petstore
description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification
termsOfService: http://swagger.io/terms/
contact:
name: Swagger API Team
email: apiteam@swagger.io
url: http://swagger.io
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
paths:
/pets:
get:
description: Returns all pets alesuada ac...
operationId: findPets
responses:
"200":
description: pet response
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Pet"
example:
$ref: "examples.yaml#/foo"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Error:
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string

View File

@@ -63,12 +63,7 @@
"type": "string" "type": "string"
}, },
"special": { "special": {
"type": "object", "$ref": "#/components/schemas/~1schemas~1user~1special.yaml"
"properties": {
"specialUserId": {
"type": "string"
}
}
} }
} }
}, },
@@ -82,23 +77,37 @@
"type": "string" "type": "string"
}, },
"special": { "special": {
"type": "object", "$ref": "#/components/schemas/~1schemas~1client~1special.yaml"
"properties": { }
"specialClientId": { }
"type": "string" },
}, "/schemas/client/special.yaml": {
"magic": { "type": "object",
"type": "object", "properties": {
"properties": { "specialClientId": {
"magicNumber": { "type": "string"
"type": "integer" },
}, "magic": {
"magicString": { "$ref": "#/components/schemas/~1schemas~1client~1magic.yaml"
"type": "string" }
} }
} },
} "/schemas/client/magic.yaml": {
} "type": "object",
"properties": {
"magicNumber": {
"type": "integer"
},
"magicString": {
"type": "string"
}
}
},
"/schemas/user/special.yaml": {
"type": "object",
"properties": {
"specialUserId": {
"type": "string"
} }
} }
} }

View File

@@ -0,0 +1,94 @@
{
"openapi": "3.0.0",
"info": {
"title": "Sample API",
"description": "Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.",
"version": "0.1.9"
},
"servers": [
{
"url": "http://api.example.com/v1",
"description": "Optional server description, e.g. Main (production) server"
},
{
"url": "http://staging-api.example.com",
"description": "Optional server description, e.g. Internal staging server for testing"
}
],
"paths": {
"/users": {
"get": {
"summary": "Get a user by ID",
"responses": {
"200": {
"description": "A single user.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/~1schemas~1user~1user.yaml"
}
}
}
}
}
}
},
"/clients": {
"get": {
"summary": "Get a user by ID",
"responses": {
"200": {
"description": "A single user.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/~1schemas~1client~1client.yaml"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"/schemas/user/user.yaml": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"userName": {
"type": "string"
},
"special": {
"$ref": "#/components/schemas/~1schemas~1user~1special.yaml"
}
}
},
"/schemas/client/client.yaml": {
"type": "object",
"properties": {
"idClient": {
"type": "integer"
},
"clientName": {
"type": "string"
},
"special": {
"$ref": "#/components/schemas/~1schemas~1user~1special.yaml"
}
}
},
"/schemas/user/special.yaml": {
"type": "object",
"properties": {
"specialUserId": {
"type": "string"
}
}
}
}
}
}

View File

@@ -0,0 +1,33 @@
openapi: 3.0.0
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users:
get:
summary: Get a user by ID
responses:
200:
description: A single user.
content:
application/json:
schema:
$ref: "./schemas/user/user.yaml"
/clients:
get:
summary: Get a user by ID
responses:
200:
description: A single user.
content:
application/json:
schema:
$ref: "./schemas/client/client.yaml"

View File

@@ -0,0 +1,8 @@
type: object
properties:
idClient:
type: integer
clientName:
type: string
special:
$ref: ../user/special.yaml

View File

@@ -0,0 +1,4 @@
type: object
properties:
specialUserId:
type: string

View File

@@ -0,0 +1,8 @@
type: object
properties:
id:
type: integer
userName:
type: string
special:
$ref: ./special.yaml

View File

@@ -22,7 +22,11 @@ let expect = require('chai').expect,
refTags = path.join(__dirname, BUNDLES_FOLDER + '/referenced_tags'), refTags = path.join(__dirname, BUNDLES_FOLDER + '/referenced_tags'),
refInfo = path.join(__dirname, BUNDLES_FOLDER + '/referenced_info'), refInfo = path.join(__dirname, BUNDLES_FOLDER + '/referenced_info'),
refPaths = path.join(__dirname, BUNDLES_FOLDER + '/referenced_paths'), refPaths = path.join(__dirname, BUNDLES_FOLDER + '/referenced_paths'),
refPathsRefToLocalSchema = path.join(__dirname, BUNDLES_FOLDER + '/referenced_paths_local_schema'); refPathsRefToLocalSchema = path.join(__dirname, BUNDLES_FOLDER + '/referenced_paths_local_schema'),
refExample = path.join(__dirname, BUNDLES_FOLDER + '/referenced_examples'),
properties = path.join(__dirname, BUNDLES_FOLDER + '/properties'),
sameSourceDifferentPlace = path.join(__dirname, BUNDLES_FOLDER + '/same_source_different_place'),
nestedProperties = path.join(__dirname, BUNDLES_FOLDER + '/nestedProperties');
describe('bundle files method - 3.0', function () { describe('bundle files method - 3.0', function () {
@@ -52,6 +56,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(res.output.specification.version).to.equal('3.0'); expect(res.output.specification.version).to.equal('3.0');
@@ -84,6 +89,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'yaml' bundleFormat: 'yaml'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(res.output.data[0].bundledContent).to.be.equal(expected); expect(res.output.data[0].bundledContent).to.be.equal(expected);
@@ -114,6 +120,7 @@ describe('bundle files method - 3.0', function () {
options: {} options: {}
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(res.output.data[0].bundledContent).to.be.equal(expected); expect(res.output.data[0].bundledContent).to.be.equal(expected);
@@ -170,6 +177,7 @@ describe('bundle files method - 3.0', function () {
] ]
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -217,6 +225,7 @@ describe('bundle files method - 3.0', function () {
] ]
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -323,6 +332,7 @@ describe('bundle files method - 3.0', function () {
] ]
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(res.output.data[0].bundledContent).to.be.equal(expected); expect(res.output.data[0].bundledContent).to.be.equal(expected);
@@ -359,6 +369,7 @@ describe('bundle files method - 3.0', function () {
] ]
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -395,6 +406,7 @@ describe('bundle files method - 3.0', function () {
] ]
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -429,6 +441,7 @@ describe('bundle files method - 3.0', function () {
} }
] ]
}; };
try { try {
await Converter.bundle(input); await Converter.bundle(input);
} }
@@ -485,6 +498,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -556,6 +570,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'json' bundleFormat: 'json'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -587,6 +602,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -623,6 +639,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -665,6 +682,7 @@ describe('bundle files method - 3.0', function () {
] ]
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -696,6 +714,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -727,6 +746,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -763,6 +783,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -819,6 +840,7 @@ describe('bundle files method - 3.0', function () {
options: {}, options: {},
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
try { try {
await Converter.bundle(input); await Converter.bundle(input);
} }
@@ -842,6 +864,7 @@ describe('bundle files method - 3.0', function () {
options: {}, options: {},
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
try { try {
await Converter.bundle(input); await Converter.bundle(input);
} }
@@ -905,6 +928,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -930,6 +954,7 @@ describe('bundle files method - 3.0', function () {
options: {}, options: {},
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
try { try {
await Converter.bundle(input); await Converter.bundle(input);
} }
@@ -937,6 +962,7 @@ describe('bundle files method - 3.0', function () {
expect(error.message).to.equal('Root file content not found in data array'); expect(error.message).to.equal('Root file content not found in data array');
} }
}); });
it('Should return bundled 1 file with 2 root but 1 is missing', async function () { it('Should return bundled 1 file with 2 root but 1 is missing', async function () {
let contentRootFile = fs.readFileSync(schemaFromResponse + '/root.yaml', 'utf8'), let contentRootFile = fs.readFileSync(schemaFromResponse + '/root.yaml', 'utf8'),
user = fs.readFileSync(schemaFromResponse + '/schemas/user.yaml', 'utf8'), user = fs.readFileSync(schemaFromResponse + '/schemas/user.yaml', 'utf8'),
@@ -986,6 +1012,7 @@ describe('bundle files method - 3.0', function () {
bundleFormat: 'JSON' bundleFormat: 'JSON'
}; };
const res = await Converter.bundle(input); const res = await Converter.bundle(input);
expect(res).to.not.be.empty; expect(res).to.not.be.empty;
expect(res.result).to.be.true; expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
@@ -1117,12 +1144,251 @@ describe('bundle files method - 3.0', function () {
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
}); });
it('Should return bundled file with referenced example', async function () {
let contentRootFile = fs.readFileSync(refExample + '/root.yaml', 'utf8'),
example = fs.readFileSync(refExample + '/examples.yaml', 'utf8'),
expected = fs.readFileSync(refExample + '/expected.json', 'utf8'),
input = {
type: 'multiFile',
specificationVersion: '3.0',
rootFiles: [
{
path: '/root.yaml'
}
],
data: [
{
path: '/root.yaml',
content: contentRootFile
},
{
path: '/examples.yaml',
content: example
}
],
options: {},
bundleFormat: 'JSON'
};
const res = await Converter.bundle(input);
expect(res).to.not.be.empty;
expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
expect(res.output.data.length).to.equal(1);
});
it('should return error when "type" parameter is not sent', async function () {
let contentRootFile = fs.readFileSync(refExample + '/root.yaml', 'utf8'),
example = fs.readFileSync(refExample + '/examples.yaml', 'utf8'),
input = {
rootFiles: [
{
path: '/root.yaml'
}
],
data: [
{
path: '/root.yaml',
content: contentRootFile
},
{
path: '/examples.yaml',
content: example
}
],
options: {},
bundleFormat: 'JSON'
};
try {
await Converter.bundle(input);
}
catch (error) {
expect(error).to.not.be.undefined;
expect(error.message).to.equal('"Type" parameter should be provided');
}
});
it('should return error when input is an empty object', async function () {
try {
await Converter.bundle({});
}
catch (error) {
expect(error).to.not.be.undefined;
expect(error.message).to.equal('Input object must have "type" and "data" information');
}
});
it('should return error when input has no root files', async function () {
let contentRootFile = fs.readFileSync(refExample + '/root.yaml', 'utf8'),
input = {
type: 'multiFile',
specificationVersion: '3.0',
rootFiles: [],
data: [
{
path: '/root.yaml',
content: contentRootFile
}
],
options: {},
bundleFormat: 'JSON'
};
try {
await Converter.bundle(input);
}
catch (error) {
expect(error).to.not.be.undefined;
expect(error.message).to.equal('Input should have at least one root file');
}
});
it('Should return bundled file as json - sameSourceDifferentPlace', async function () {
let contentRootFile = fs.readFileSync(sameSourceDifferentPlace + '/root.yaml', 'utf8'),
user = fs.readFileSync(sameSourceDifferentPlace + '/schemas/user/user.yaml', 'utf8'),
special = fs.readFileSync(sameSourceDifferentPlace + '/schemas/user/special.yaml', 'utf8'),
client = fs.readFileSync(sameSourceDifferentPlace + '/schemas/client/client.yaml', 'utf8'),
expected = fs.readFileSync(sameSourceDifferentPlace + '/expected.json', 'utf8'),
input = {
type: 'multiFile',
specificationVersion: '3.0',
rootFiles: [
{
path: '/root.yaml'
}
],
data: [
{
path: '/root.yaml',
content: contentRootFile
},
{
path: '/schemas/user/user.yaml',
content: user
},
{
path: '/schemas/user/special.yaml',
content: special
},
{
path: '/schemas/client/client.yaml',
content: client
}
],
options: {},
bundleFormat: 'JSON'
};
const res = await Converter.bundle(input);
expect(res).to.not.be.empty;
expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
expect(res.output.data.length).to.equal(1);
});
it('Should return bundled file as json - nestedProperties', async function () {
let contentRootFile = fs.readFileSync(nestedProperties + '/root.yaml', 'utf8'),
user = fs.readFileSync(nestedProperties + '/schemas/user.yaml', 'utf8'),
prop = fs.readFileSync(nestedProperties + '/properties/prop.yaml', 'utf8'),
nestedProp = fs.readFileSync(nestedProperties + '/properties/nestedProp.yaml', 'utf8'),
lastNested = fs.readFileSync(nestedProperties + '/properties/lastNested.yaml', 'utf8'),
warrior = fs.readFileSync(nestedProperties + '/properties/warrior.yaml', 'utf8'),
country = fs.readFileSync(nestedProperties + '/properties/country.yaml', 'utf8'),
expected = fs.readFileSync(nestedProperties + '/expected.json', 'utf8'),
input = {
type: 'multiFile',
specificationVersion: '3.0',
rootFiles: [
{
path: '/root.yaml'
}
],
data: [
{
path: '/root.yaml',
content: contentRootFile
},
{
path: '/schemas/user.yaml',
content: user
},
{
path: '/properties/prop.yaml',
content: prop
},
{
path: '/properties/nestedProp.yaml',
content: nestedProp
},
{
path: '/properties/country.yaml',
content: country
},
{
path: '/properties/lastNested.yaml',
content: lastNested
},
{
path: '/properties/warrior.yaml',
content: warrior
}
],
options: {},
bundleFormat: 'JSON'
};
const res = await Converter.bundle(input);
expect(res).to.not.be.empty;
expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
expect(res.output.data.length).to.equal(1);
});
it('Should return bundled file as json - properties', async function () {
let contentRootFile = fs.readFileSync(properties + '/root.yaml', 'utf8'),
user = fs.readFileSync(properties + '/schemas/user.yaml', 'utf8'),
prop = fs.readFileSync(properties + '/schemas/prop.yaml', 'utf8'),
expected = fs.readFileSync(properties + '/expected.json', 'utf8'),
input = {
type: 'multiFile',
specificationVersion: '3.0',
rootFiles: [
{
path: '/root.yaml'
}
],
data: [
{
path: '/root.yaml',
content: contentRootFile
},
{
path: '/schemas/user.yaml',
content: user
},
{
path: '/schemas/prop.yaml',
content: prop
}
],
options: {},
bundleFormat: 'JSON'
};
const res = await Converter.bundle(input);
expect(res).to.not.be.empty;
expect(res.result).to.be.true;
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expected);
expect(res.output.data.length).to.equal(1);
});
it('Should bundle according to the input root format when bundleFormat is not present', async function () { it('Should bundle according to the input root format when bundleFormat is not present', async function () {
let contentRootFile = fs.readFileSync(schemaFromResponse + '/root.yaml', 'utf8'), let contentRootFileYAML = fs.readFileSync(schemaFromResponse + '/root.yaml', 'utf8'),
contentRootJSON = fs.readFileSync(schemaFromResponse + '/root.json', 'utf8'), contentRootJSON = fs.readFileSync(schemaFromResponse + '/root.json', 'utf8'),
user = fs.readFileSync(schemaFromResponse + '/schemas/user.yaml', 'utf8'), user = fs.readFileSync(schemaFromResponse + '/schemas/user.yaml', 'utf8'),
expectedJSON = fs.readFileSync(schemaFromResponse + '/expected.json', 'utf8'), expectedJSON = fs.readFileSync(schemaFromResponse + '/expected.json', 'utf8'),
expected = fs.readFileSync(schemaFromResponse + '/expected.yaml', 'utf8'), expectedYAML = fs.readFileSync(schemaFromResponse + '/expected.yaml', 'utf8'),
input = { input = {
type: 'multiFile', type: 'multiFile',
specificationVersion: '3.0', specificationVersion: '3.0',
@@ -1137,7 +1403,7 @@ describe('bundle files method - 3.0', function () {
data: [ data: [
{ {
path: '/root.yaml', path: '/root.yaml',
content: contentRootFile content: contentRootFileYAML
}, },
{ {
path: '/root.json', path: '/root.json',
@@ -1157,7 +1423,7 @@ describe('bundle files method - 3.0', function () {
expect(res.output.specification.version).to.equal('3.0'); expect(res.output.specification.version).to.equal('3.0');
expect(res.output.data.length).to.equal(2); expect(res.output.data.length).to.equal(2);
expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expectedJSON); expect(JSON.stringify(res.output.data[0].bundledContent, null, 2)).to.be.equal(expectedJSON);
expect(res.output.data[1].bundledContent).to.be.equal(expected); expect(res.output.data[1].bundledContent).to.be.equal(expectedYAML);
}); });
}); });

View File

@@ -6,27 +6,21 @@ const expect = require('chai').expect,
getKeyInComponents } = require('./../../lib/jsonPointer'); getKeyInComponents } = require('./../../lib/jsonPointer');
describe('getKeyInComponents function', function () { describe('getKeyInComponents function', function () {
it('should return [[], true] when is pointing to an element in components', function () { it('should return [] when is pointing to an element in components', function () {
const result = getKeyInComponents(['components', 'schemas'], 'pet.yaml'); const result = getKeyInComponents(['components', 'schemas'], 'pet.yaml');
expect(result).to.be.an('array').with.length(2); expect(result).to.be.an('array').with.length(0);
expect(result[0].length).to.equal(0);
expect(result[1]).to.equal(true);
}); });
it('should return [[], true] when is pointing to a local ref in components', it('should return [] when is pointing to a local ref in components',
function () { function () {
const result = getKeyInComponents(['components', 'schemas'], 'pet.yaml', '/definitions/world'); const result = getKeyInComponents(['components', 'schemas'], 'pet.yaml', '/definitions/world');
expect(result).to.be.an('array').with.length(2); expect(result).to.be.an('array').with.length(0);
expect(result[0].length).to.equal(0);
expect(result[1]).to.equal(true);
}); });
it('should return [["schemas", "folder/pet.yaml"], false] when there is an scaped slash', function () { it('should return ["schemas", "folder/pet.yaml"] when there is an scaped slash', function () {
const result = getKeyInComponents(['path', 'schemas'], 'folder~1pet.yaml'); const result = getKeyInComponents(['path', 'schemas'], 'folder~1pet.yaml');
expect(result).to.be.an('array').with.length(2); expect(result).to.be.an('array').with.length(2);
expect(result[0].length).to.equal(2); expect(result[0]).to.equal('schemas');
expect(result[0][0]).to.equal('schemas');
expect(result[1]).to.equal(false);
}); });
}); });
@@ -62,7 +56,8 @@ describe('concatJsonPointer function ', function () {
it('should return "#/components/schemas/Pets.yaml" no local path and schema', function () { it('should return "#/components/schemas/Pets.yaml" no local path and schema', function () {
let res = concatJsonPointer( let res = concatJsonPointer(
jsonPointerEncodeAndReplace, jsonPointerEncodeAndReplace,
['schemas', 'Pets.yaml'] ['schemas', 'Pets.yaml'],
'/components'
); );
expect(res).to.equal('#/components/schemas/Pets.yaml'); expect(res).to.equal('#/components/schemas/Pets.yaml');
}); });
@@ -70,21 +65,24 @@ describe('concatJsonPointer function ', function () {
it('should return "#/components/schemas/other~1Pets.yaml" no local path and schema folder in filename', function () { it('should return "#/components/schemas/other~1Pets.yaml" no local path and schema folder in filename', function () {
let res = concatJsonPointer( let res = concatJsonPointer(
jsonPointerEncodeAndReplace, jsonPointerEncodeAndReplace,
['schemas', 'other/Pets.yaml'] ['schemas', 'other/Pets.yaml'],
'/components'
); );
expect(res).to.equal('#/components/schemas/other~1Pets.yaml'); expect(res).to.equal('#/components/schemas/other~1Pets.yaml');
}); });
it('should return "#/components/schemas/some~1Pet" no local path and schema folder in filename', function () { it('should return "#/components/schemas/some~1Pet" no local path and schema folder in filename', function () {
let res = concatJsonPointer( let res = concatJsonPointer(
jsonPointerEncodeAndReplace, jsonPointerEncodeAndReplace,
['schemas', 'some/Pet.yaml'] ['schemas', 'some/Pet.yaml'],
'/components'
); );
expect(res).to.equal('#/components/schemas/some~1Pet.yaml'); expect(res).to.equal('#/components/schemas/some~1Pet.yaml');
}); });
it('should return "#/components/schemas/hello.yaml" no local path and schema', function () { it('should return "#/components/schemas/hello.yaml" no local path and schema', function () {
let res = concatJsonPointer( let res = concatJsonPointer(
jsonPointerEncodeAndReplace, jsonPointerEncodeAndReplace,
['schemas', 'hello.yaml'] ['schemas', 'hello.yaml'],
'/components'
); );
expect(res).to.equal('#/components/schemas/hello.yaml'); expect(res).to.equal('#/components/schemas/hello.yaml');
}); });
@@ -92,7 +90,8 @@ describe('concatJsonPointer function ', function () {
it('should return "#/components/schemas/~1Pets.yaml" no local path and schema', function () { it('should return "#/components/schemas/~1Pets.yaml" no local path and schema', function () {
let res = concatJsonPointer( let res = concatJsonPointer(
jsonPointerEncodeAndReplace, jsonPointerEncodeAndReplace,
['schemas', '/Pets.yaml'] ['schemas', '/Pets.yaml'],
'/components'
); );
expect(res).to.equal('#/components/schemas/~1Pets.yaml'); expect(res).to.equal('#/components/schemas/~1Pets.yaml');
}); });