mirror of
https://github.com/postmanlabs/openapi-to-postman.git
synced 2022-11-29 22:05:00 +03:00
Add dfs algorithm
Add dfs algorithm
This commit is contained in:
committed by
Erik Mendoza
parent
0b03a26d1c
commit
2fefe62dc1
5
index.js
5
index.js
@@ -37,6 +37,11 @@ module.exports = {
|
||||
return schema.detectRootFiles();
|
||||
},
|
||||
|
||||
detectRelatedFiles: async function(input) {
|
||||
var schema = new SchemaPack(input);
|
||||
return schema.detectRelatedFiles();
|
||||
},
|
||||
|
||||
// new API
|
||||
SchemaPack
|
||||
};
|
||||
|
||||
26
lib/dfs.js
Normal file
26
lib/dfs.js
Normal file
@@ -0,0 +1,26 @@
|
||||
class DFS {
|
||||
traverse(node, getAdjacent) {
|
||||
let traverseOrder = [],
|
||||
stack = [],
|
||||
missing = [],
|
||||
visited = new Set();
|
||||
stack.push(node);
|
||||
while (stack.length > 0) {
|
||||
node = stack.pop();
|
||||
if (!visited.has(node)) {
|
||||
traverseOrder.push(node);
|
||||
visited.add(node);
|
||||
let { graphAdj, missingNodes } = getAdjacent(node);
|
||||
missing.push(...missingNodes);
|
||||
for (let j = 0; j < graphAdj.length; j++) {
|
||||
stack.push(graphAdj[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return { traverseOrder, missing };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
DFS
|
||||
};
|
||||
26
lib/relatedFiles.js
Normal file
26
lib/relatedFiles.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const { DFS } = require('./dfs');
|
||||
|
||||
/**
|
||||
* Maps the output from get root files to detect root files
|
||||
* @param {object} output - output schema
|
||||
* @param {string} version - specified version of the process
|
||||
* @returns {object} - Detect root files result object
|
||||
*/
|
||||
function getReferences () {
|
||||
// obtener los refs => '../common/Error.yaml' //relative to root path
|
||||
// obtener el file de data por path (puede que aqui sea absoluto)
|
||||
// si no existe agregarlo a missing
|
||||
// obtener el objeto
|
||||
// agregarlo a un array (de nodos adjacentes)
|
||||
//
|
||||
return { graphAdj: [], missingNodes: [] };
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
getRelatedFiles: function (specRoot) {
|
||||
let algorithm = new DFS(),
|
||||
orderTraversed = algorithm.traverse(specRoot, getReferences);
|
||||
return orderTraversed;
|
||||
}
|
||||
};
|
||||
@@ -87,7 +87,8 @@ const { formatDataPath, checkIsCorrectType, isKnownType,
|
||||
],
|
||||
|
||||
crypto = require('crypto'),
|
||||
DEFAULT_SCHEMA_UTILS = require('./30XUtils/schemaUtils30X');
|
||||
DEFAULT_SCHEMA_UTILS = require('./30XUtils/schemaUtils30X'),
|
||||
{ getRelatedFiles } = require('./relatedFiles');
|
||||
/* eslint-enable */
|
||||
|
||||
// See https://github.com/json-schema-faker/json-schema-faker/tree/master/docs#available-options
|
||||
@@ -4842,6 +4843,35 @@ module.exports = {
|
||||
data: adaptedData
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
mapRootFiles(rootFiles) {
|
||||
let data = rootFiles.map((root) => {
|
||||
let relatedFiles = getRelatedFiles();
|
||||
return { rootFile: { path: root.path }, relatedFiles: relatedFiles };
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
processRelatedFiles(inputRelatedFiles) {
|
||||
let version = inputRelatedFiles.specificationVersion ? inputRelatedFiles.specificationVersion : '3.0.0',
|
||||
res = {
|
||||
result: true,
|
||||
output: {
|
||||
type: 'relatedFiles',
|
||||
specification: {
|
||||
type: 'OpenAPI',
|
||||
version: version
|
||||
},
|
||||
data: [
|
||||
]
|
||||
}
|
||||
};
|
||||
if (inputRelatedFiles.rootFiles && inputRelatedFiles.rootFiles.length > 0) {
|
||||
res.output.data = this.mapRootFiles(inputRelatedFiles.rootFiles, version);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -652,6 +652,24 @@ class SchemaPack {
|
||||
res = schemaUtils.mapGetRootFilesOutputToDetectRootFilesOutput(rootFiles, input.specificationVersion);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description Takes in a folder and identifies the root files in that folder
|
||||
* if there are different specification's versions will return only the ones that
|
||||
* corresponds to the field specificationVersion
|
||||
*
|
||||
* @returns {object} root files information found in the input
|
||||
*/
|
||||
async detectRelatedFiles() {
|
||||
const input = this.input;
|
||||
if (!input.rootFiles || input.rootFiles.length === 0) {
|
||||
let rootFiles = await this.detectRootFiles(input);
|
||||
input.rootFiles = rootFiles.output.data;
|
||||
return schemaUtils.processRelatedFiles(input);
|
||||
}
|
||||
return schemaUtils.processRelatedFiles(input);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
80
test/unit/DFS.test.js
Normal file
80
test/unit/DFS.test.js
Normal file
@@ -0,0 +1,80 @@
|
||||
let expect = require('chai').expect,
|
||||
{ DFS } = require('./../../lib/dfs');
|
||||
|
||||
describe('DFS Algorithm ', function () {
|
||||
it('should return non repeated nodes', function () {
|
||||
let algorithm = new DFS(),
|
||||
d = {
|
||||
name: 'd',
|
||||
children: []
|
||||
},
|
||||
c = {
|
||||
name: 'c',
|
||||
children: []
|
||||
},
|
||||
b = {
|
||||
name: 'b',
|
||||
children: [c]
|
||||
},
|
||||
root = {
|
||||
name: 'a',
|
||||
children: [d, c, b]
|
||||
},
|
||||
{ traverseOrder, missing } = algorithm.traverse(root, (node) => {
|
||||
return { graphAdj: node.children, missingNodes: [] };
|
||||
});
|
||||
expect(traverseOrder.length).to.equal(4);
|
||||
expect(traverseOrder[0].name).to.equal('a');
|
||||
expect(traverseOrder[1].name).to.equal('b');
|
||||
expect(traverseOrder[2].name).to.equal('c');
|
||||
expect(traverseOrder[3].name).to.equal('d');
|
||||
expect(missing.length).to.equal(0);
|
||||
|
||||
});
|
||||
|
||||
it('should return non repeated nodes and missing nodes', function () {
|
||||
let algorithm = new DFS(),
|
||||
d = {
|
||||
name: 'd',
|
||||
children: []
|
||||
},
|
||||
c = {
|
||||
name: 'c',
|
||||
children: []
|
||||
},
|
||||
b = {
|
||||
name: 'b',
|
||||
children: ['c']
|
||||
},
|
||||
root = {
|
||||
name: 'a',
|
||||
children: ['d', 'c', 'b', 'e']
|
||||
},
|
||||
allData = [root, b, c, d],
|
||||
{ traverseOrder, missing } = algorithm.traverse(root, (node) => {
|
||||
let missing = [],
|
||||
foundArray = [];
|
||||
node.children.forEach((child) => {
|
||||
let found = allData.find((item) => {
|
||||
return child === item.name;
|
||||
});
|
||||
if (found) {
|
||||
foundArray.push(found);
|
||||
}
|
||||
else {
|
||||
missing.push(child);
|
||||
}
|
||||
});
|
||||
return { graphAdj: foundArray, missingNodes: missing };
|
||||
});
|
||||
expect(traverseOrder.length).to.equal(4);
|
||||
expect(traverseOrder[0].name).to.equal('a');
|
||||
expect(traverseOrder[1].name).to.equal('b');
|
||||
expect(traverseOrder[2].name).to.equal('c');
|
||||
expect(traverseOrder[3].name).to.equal('d');
|
||||
expect(missing.length).to.equal(1);
|
||||
expect(missing[0]).to.equal('e');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
59
test/unit/detectRelatedFiles.test.js
Normal file
59
test/unit/detectRelatedFiles.test.js
Normal file
@@ -0,0 +1,59 @@
|
||||
var expect = require('chai').expect,
|
||||
Converter = require('../../index.js'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
VALID_OPENAPI_PATH = '../data/valid_openapi',
|
||||
// VALID_OPENAPI_31_PATH = '../data/valid_openapi31X',
|
||||
PET_STORE_SEPARATED = '../data/petstore separate yaml/spec',
|
||||
// PET_STORE_SEPARATED_JSON = '../data/petstore-separate/spec',
|
||||
validPetstore = path.join(__dirname, VALID_OPENAPI_PATH + '/petstore.yaml'),
|
||||
// noauth = path.join(__dirname, VALID_OPENAPI_PATH + '/noauth.yaml'),
|
||||
// petstoreSeparated = path.join(__dirname, PET_STORE_SEPARATED + '/swagger.yaml'),
|
||||
petstoreSeparatedPet = path.join(__dirname, PET_STORE_SEPARATED + '/Pet.yaml');
|
||||
// petstoreSeparatedJson = path.join(__dirname, PET_STORE_SEPARATED_JSON + '/swagger.json'),
|
||||
// petstoreSeparatedPetJson = path.join(__dirname, PET_STORE_SEPARATED_JSON + '/Pet.json'),
|
||||
// validHopService31x = path.join(__dirname, VALID_OPENAPI_31_PATH + '/yaml/hopService.yaml');
|
||||
|
||||
|
||||
describe('detectRoot method', function() {
|
||||
|
||||
it('should return empty data when there is no root in the entry', async function() {
|
||||
let contentFile = fs.readFileSync(petstoreSeparatedPet, 'utf8'),
|
||||
input = {
|
||||
type: 'folder',
|
||||
specificationVersion: '3.0',
|
||||
rootFiles: [
|
||||
],
|
||||
data: [
|
||||
{
|
||||
path: '/Pet.yaml',
|
||||
content: contentFile
|
||||
}
|
||||
]
|
||||
};
|
||||
const res = await Converter.detectRelatedFiles(input);
|
||||
expect(res).to.not.be.empty;
|
||||
expect(res.result).to.be.true;
|
||||
expect(res.output.data.length).to.equal(0);
|
||||
});
|
||||
|
||||
it('should locate root and return empty data when there is no ref', async function() {
|
||||
let contentFile = fs.readFileSync(validPetstore, 'utf8'),
|
||||
input = {
|
||||
type: 'folder',
|
||||
specificationVersion: '3.0',
|
||||
rootFiles: [
|
||||
],
|
||||
data: [
|
||||
{
|
||||
path: '/petstore.yaml',
|
||||
content: contentFile
|
||||
}
|
||||
]
|
||||
};
|
||||
const res = await Converter.detectRelatedFiles(input);
|
||||
expect(res).to.not.be.empty;
|
||||
expect(res.result).to.be.true;
|
||||
expect(res.output.data[0].rootFile.path).to.equal('/petstore.yaml');
|
||||
});
|
||||
});
|
||||
10
test/unit/relatedFiles.test.js
Normal file
10
test/unit/relatedFiles.test.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// let expect = require('chai').expect,
|
||||
let { getRelatedFiles } = require('./../../lib/relatedFiles');
|
||||
|
||||
describe('Get header family function ', function () {
|
||||
it('should check for custom type JSON header', function () {
|
||||
getRelatedFiles();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user