Skip to content
This repository has been archived by the owner on Feb 28, 2020. It is now read-only.

Commit

Permalink
feat: decouple path reformatting from swaggerize
Browse files Browse the repository at this point in the history
decouple the path reformatting from swaggerize
nhardman authored Aug 24, 2017
1 parent 6a6b0be commit 349cec4
Showing 12 changed files with 123 additions and 21 deletions.
7 changes: 7 additions & 0 deletions lib/helpers.js
Original file line number Diff line number Diff line change
@@ -599,3 +599,10 @@ exports.loadAsync = function (path, memfs) {
return (isHttp ? loadHttpAsync(path) : loadFileAsync(path, memfs))
.then(data => isYaml ? JSON.stringify(YAML.load(data)) : data)
}

exports.reformatPathToSwift = function (thepath) {
// take a swagger path and convert the parameters to swift format.
// i.e. convert "/path/to/{param1}/{param2}" to "/path/to/:param1/:param2"
var newPath = thepath.replace(/{/g, ':')
return newPath.replace(/}/g, '')
}
8 changes: 7 additions & 1 deletion lib/sdkGenHelper.js
Original file line number Diff line number Diff line change
@@ -60,7 +60,13 @@ exports.performSDKGenerationAsync = function (sdkName, sdkType, fileContent) {
url: startGenURL,
body: fileContent
})
.then(response => JSON.parse(response.body).job.id)
.then(function (response) {
var body = JSON.parse(response.body)
if (body.job && body.job.id) {
return body.job.id
}
throw new Error(chalk.red('SDK generation error:', response.statusCode, response.statusMessage, body.message))
})
.tap(generatedID => debug(`SDK generation job for ${sdkName} started with id ${generatedID}`))
.then(generatedID => checkUntilFinished(generatedID))

8 changes: 0 additions & 8 deletions refresh/fromswagger/generatorUtils.js
Original file line number Diff line number Diff line change
@@ -21,13 +21,6 @@ function baseName (thepath) {
return path.basename(thepath).split('.')[0]
}

function convertToSwiftParameterFormat (thepath) {
// take a swagger path and convert the parameters to swift format.
// i.e. convert "/path/to/{param1}/{param2}" to "/path/to/:param1/:param2"
var newPath = thepath.replace(/{/g, ':')
return newPath.replace(/}/g, '')
}

function resourceNameFromPath (thepath) {
// grab the first valid element of a path (or partial path) and return it capitalized.
var resource = thepath.match(/^\/*([^/]+)/)[1]
@@ -39,6 +32,5 @@ function getRefName (ref) {
}

module.exports = {baseName,
convertToSwiftParameterFormat,
resourceNameFromPath,
getRefName}
11 changes: 6 additions & 5 deletions refresh/fromswagger/swaggerize.js
Original file line number Diff line number Diff line change
@@ -29,17 +29,18 @@ function ensureValidAsync (loadedSwagger) {
})
}

function parseSwagger (api) {
function parseSwagger (api, pathFormatter) {
debug('in parseSwagger')
// walk the api, extract the schemas from the definitions, the parameters and the responses.
var resources = {}
var refs = []
var basePath = api.basePath || undefined
pathFormatter = pathFormatter || function (path) { return path }

Object.keys(api.paths).forEach(function (path) {
var resource = genUtils.resourceNameFromPath(path)

debug('path:', path, 'becomes resource:', resource)
debug('path:', path, 'becomes resource: "' + resource + '" with route: "' + pathFormatter(path) + '"')
// for each path, walk the method verbs
builderUtils.verbs.forEach(function (verb) {
if (api.paths[path][verb]) {
@@ -49,7 +50,7 @@ function parseSwagger (api) {

debug('parsing verb:', verb)
// save the method and the path in the resources list.
resources[resource].push({method: verb, route: genUtils.convertToSwiftParameterFormat(path)})
resources[resource].push({method: verb, route: pathFormatter(path)})
// process the parameters
if (api.paths[path][verb].parameters) {
var parameters = api.paths[path][verb].parameters
@@ -135,14 +136,14 @@ function parseSwagger (api) {
return parsed
}

exports.parse = function (swaggerStr) {
exports.parse = function (swaggerStr, pathFormatter) {
debug('in parse')
var loaded = JSON.parse(swaggerStr)
return ensureValidAsync(loaded)
.then(function () {
debug('successfully validated against schema')
// restore the original swagger as the call to ensureValidAsync modifies the original loaded object.
loaded = JSON.parse(swaggerStr)
return { loaded: loaded, parsed: parseSwagger(loaded) }
return { loaded: loaded, parsed: parseSwagger(loaded, pathFormatter) }
})
}
4 changes: 2 additions & 2 deletions refresh/index.js
Original file line number Diff line number Diff line change
@@ -668,7 +668,7 @@ module.exports = Generator.extend({
if (!this.fromSwagger) return

return helpers.loadAsync(this.fromSwagger, this.fs)
.then(loaded => swaggerize.parse(loaded))
.then(loaded => swaggerize.parse(loaded, helpers.reformatPathToSwift))
.then(response => {
this.loadedApi = response.loaded
this.parsedSwagger = response.parsed
@@ -705,7 +705,7 @@ module.exports = Generator.extend({
return Promise.map(this.serverSwaggerFiles, file => {
return helpers.loadAsync(file, this.fs)
.then(loaded => {
return swaggerize.parse(loaded)
return swaggerize.parse(loaded, helpers.reformatPathToSwift)
.then(response => {
if (response.loaded.info.title === undefined) {
this.env.error(chalk.red('Could not extract title from Swagger API.'))
15 changes: 15 additions & 0 deletions test/integration/app/prompted_build.js
Original file line number Diff line number Diff line change
@@ -27,6 +27,11 @@ var appGeneratorPath = path.join(__dirname, '../../../app')
var testResourcesPath = path.join(__dirname, '../../../test/resources')
var buildTimeout = 300000

// Require config to alter sdkgen delay between
// status checks to speed up unit tests
var config = require('../../../config')
var sdkGenCheckDelaySaved

describe('Prompt and build integration tests for app generator', function () {
describe('Basic application', function () {
// Swift build is slow so we need to set a longer timeout for the test
@@ -100,6 +105,10 @@ describe('Prompt and build integration tests for app generator', function () {
var runContext
var appName = 'notes'
before(function () {
// alter delay between status checks to speed up unit tests
sdkGenCheckDelaySaved = config.sdkGenCheckDelay
config.sdkGenCheckDelay = 10000

// Swift build is slow so we need to set a longer timeout for the test
this.timeout(buildTimeout)
runContext = helpers.run(appGeneratorPath)
@@ -120,6 +129,12 @@ describe('Prompt and build integration tests for app generator', function () {
return runContext.toPromise() // Get a Promise back when the generator finishes
})

after('restore sdkgen status check delay', function () {
// restore delay between status checks so integration tests
// remain resilient
config.sdkGenCheckDelay = sdkGenCheckDelaySaved
})

it('compiles the application', function () {
assert.file(process.cwd() + '/.build/debug/' + appName)
})
35 changes: 35 additions & 0 deletions test/integration/app/prompted_nobuild.js
Original file line number Diff line number Diff line change
@@ -27,6 +27,11 @@ var appGeneratorPath = path.join(__dirname, '../../../app')
var testResourcesPath = path.join(__dirname, '../../../test/resources')
var extendedTimeout = 300000

// Require config to alter sdkgen delay between
// status checks to speed up unit tests
var config = require('../../../config')
var sdkGenCheckDelaySaved

describe('Prompt and no build integration tests for app generator', function () {
describe('Basic application', function () {
this.timeout(10000) // Allow first test to be slow
@@ -222,6 +227,10 @@ describe('Prompt and no build integration tests for app generator', function ()
var appName = 'notes'

before(function () {
// alter delay between status checks to speed up unit tests
sdkGenCheckDelaySaved = config.sdkGenCheckDelay
config.sdkGenCheckDelay = 10000

runContext = helpers.run(appGeneratorPath)
.withOptions({ 'skip-build': true })
.withPrompts({
@@ -235,6 +244,12 @@ describe('Prompt and no build integration tests for app generator', function ()
return runContext.toPromise()
})

after('restore sdkgen status check delay', function () {
// restore delay between status checks so integration tests
// remain resilient
config.sdkGenCheckDelay = sdkGenCheckDelaySaved
})

describe('Static web file serving', function () {
it('created public web directory', function () {
assert.file('public')
@@ -321,6 +336,10 @@ describe('Prompt and no build integration tests for app generator', function ()
var runContext

before(function () {
// alter delay between status checks to speed up unit tests
sdkGenCheckDelaySaved = config.sdkGenCheckDelay
config.sdkGenCheckDelay = 10000

runContext = helpers.run(appGeneratorPath)
.withOptions({ 'skip-build': true })
.withPrompts({
@@ -336,6 +355,12 @@ describe('Prompt and no build integration tests for app generator', function ()
return runContext.toPromise()
})

after('restore sdkgen status check delay', function () {
// restore delay between status checks so integration tests
// remain resilient
config.sdkGenCheckDelay = sdkGenCheckDelaySaved
})

describe('Example endpoints', function () {
it('created example endpoints', function () {
assert.file(`Sources/Application/Routes/PersonsRoutes.swift`)
@@ -350,6 +375,10 @@ describe('Prompt and no build integration tests for app generator', function ()
var appName = 'notes'

before(function () {
// alter delay between status checks to speed up unit tests
sdkGenCheckDelaySaved = config.sdkGenCheckDelay
config.sdkGenCheckDelay = 10000

runContext = helpers.run(appGeneratorPath)
.withOptions({ 'skip-build': true })
.withPrompts({
@@ -370,6 +399,12 @@ describe('Prompt and no build integration tests for app generator', function ()
return runContext.toPromise()
})

after('restore sdkgen status check delay', function () {
// restore delay between status checks so integration tests
// remain resilient
config.sdkGenCheckDelay = sdkGenCheckDelaySaved
})

it('created a iOS SDK zip file', function () {
assert.file(appName + '_iOS_SDK.zip')
})
25 changes: 25 additions & 0 deletions test/integration/app/spec_build.js
Original file line number Diff line number Diff line change
@@ -26,6 +26,11 @@ var helpers = require('yeoman-test')
var appGeneratorPath = path.join(__dirname, '../../../app')
var buildGeneratorPath = path.join(__dirname, '../../../build')

// Require config to alter sdkgen delay between
// status checks to speed up unit tests
var config = require('../../../config')
var sdkGenCheckDelaySaved

describe('Spec option and build integration tests for app generator', function () {
describe('A CRUD application with a cloudant service is able to build', function () {
// Swift build is slow so we need to set a longer timeout for the test
@@ -66,6 +71,10 @@ describe('Spec option and build integration tests for app generator', function (
}

before(function () {
// alter delay between status checks to speed up unit tests
sdkGenCheckDelaySaved = config.sdkGenCheckDelay
config.sdkGenCheckDelay = 10000

runContext = helpers.run(appGeneratorPath)
.withOptions({
spec: JSON.stringify(spec)
@@ -79,6 +88,12 @@ describe('Spec option and build integration tests for app generator', function (
})
})

after('restore sdkgen status check delay', function () {
// restore delay between status checks so integration tests
// remain resilient
config.sdkGenCheckDelay = sdkGenCheckDelaySaved
})

it('compiles the application', function () {
assert.file('.build/debug/todo')
})
@@ -122,6 +137,10 @@ describe('Spec option and build integration tests for app generator', function (
}

before(function () {
// alter delay between status checks to speed up unit tests
sdkGenCheckDelaySaved = config.sdkGenCheckDelay
config.sdkGenCheckDelay = 10000

runContext = helpers.run(appGeneratorPath)
.withOptions({
spec: JSON.stringify(spec)
@@ -135,6 +154,12 @@ describe('Spec option and build integration tests for app generator', function (
})
})

after('restore sdkgen status check delay', function () {
// restore delay between status checks so integration tests
// remain resilient
config.sdkGenCheckDelay = sdkGenCheckDelaySaved
})

it('compiles the application', function () {
assert.file('.build/debug/todo')
})
2 changes: 1 addition & 1 deletion test/mocha.opts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--timeout 10000
--timeout 40000
6 changes: 6 additions & 0 deletions test/unit/helpers.js
Original file line number Diff line number Diff line change
@@ -609,4 +609,10 @@ describe('helpers', function () {
})
})
})

describe('swagger path formatter', function () {
it('convert swagger path parameters to swift format', function () {
assert(helpers.reformatPathToSwift('/helper/ff/test/{p1}/{p2}') === '/helper/ff/test/:p1/:p2')
})
})
})
19 changes: 19 additions & 0 deletions test/unit/refresh.js
Original file line number Diff line number Diff line change
@@ -510,9 +510,23 @@ describe('swiftserver:refresh', function () {
})

describe('Generate scaffolded app from valid swagger but no basepath', function () {
var sdkScope
var runContext

before(function () {
sdkScope = nock('https://mobilesdkgen.ng.bluemix.net')
.filteringRequestBody(/.*/, '*')
.post(`/sdkgen/api/generator/${appName}_iOS_SDK/ios_swift`, '*')
.reply(200, { job: { id: 'myid' } })
.get('/sdkgen/api/generator/myid/status')
.reply(200, { status: 'FINISHED' })
.get('/sdkgen/api/generator/myid')
.replyWithFile(
200,
path.join(__dirname, '../resources/dummy_iOS_SDK.zip'),
{ 'Content-Type': 'application/zip' }
)

// Mock the options, set up an output folder and run the generator
var spec = {
appType: 'scaffold',
@@ -542,7 +556,12 @@ describe('swiftserver:refresh', function () {
assert.fileContent(`Sources/${applicationModule}/Routes/ProductsRoutes.swift`, 'router.get("/products/:id"')
})

it('requested iOS SDK over http', function () {
assert(sdkScope.isDone())
})

after(function () {
nock.cleanAll()
runContext.cleanTestDirectory()
})
})
4 changes: 0 additions & 4 deletions test/unit/swaggerize.js
Original file line number Diff line number Diff line change
@@ -24,10 +24,6 @@ describe('swagger generator', function () {
assert(utils.baseName('/hh/ff/test.txt') === 'test')
})

it('can convert Swagger parameters to swift format', function () {
assert(utils.convertToSwiftParameterFormat('/helper/ff/test{p1} {p2}') === '/helper/ff/test:p1 :p2')
})

it('can extract the resource name from a path', function () {
assert(utils.resourceNameFromPath('/helper/ff/test{p1} {p2}') === 'Helper')
})

0 comments on commit 349cec4

Please sign in to comment.