Skip to content

Commit

Permalink
Improve mock generation for large JSONs
Browse files Browse the repository at this point in the history
  • Loading branch information
mittsh committed Sep 22, 2017
1 parent cd57b28 commit 48da74f
Showing 1 changed file with 69 additions and 30 deletions.
99 changes: 69 additions & 30 deletions src/MockingjayGenerator.js
@@ -1,44 +1,71 @@
@registerCodeGenerator
class MockingjayGenerator {
static identifier = 'com.luckymarmot.PawExtensions.MockingjayGenerator';
static title = 'Swift Mockingjay Generator';
class StubGenerator {
constructor(request, httpExchange) {
this.request = request
this.httpExchange = httpExchange
this.setupLines = []
}

_generateStub(request) {
const lastExchange = request.getLastExchange()
return `stub(${this._generateMatcher(request)}, ${this._generateBuilder(lastExchange)})\n`
generateStub() {
const commentLine = `// Stub for "${this.request.name}"`
const stubLine = `stub(${this._generateMatcher()}, ${this._generateBuilder()})`
let lines = this.setupLines
lines.unshift(commentLine)
lines.push(stubLine)
return lines.join('\n')
}

_getRequestSlug() {
let slug = this.request.name.split(/[^a-z0-9]/i).map(s => s.substr(0,1).toUpperCase() + s.substr(1).toLowerCase()).join('')
return slug.substr(0,1).toLowerCase() + slug.substr(1)
}

_generateMatcher(request) {
const method = request.method.toUpperCase()
_generateMatcher() {
const method = this.request.method.toUpperCase()
if (method === 'GET') {
return `uri("${request.urlBase}")`
return `uri("${this.request.urlBase}")`
}
else {
return `http(.${method}, "${request.urlBase}")`
return `http(.${method}, "${this.request.urlBase}")`
}
}

_generateBuilder(httpExchange) {
const contentType = httpExchange.responseHeaders['Content-Type']
_generateBuilder() {
const contentType = this.httpExchange.responseHeaders['Content-Type']
if (contentType.match(/^application\/json/)) {
let jsonObject
let swiftJsonString
try {
jsonObject = JSON.parse(httpExchange.responseBody)
if (this.httpExchange.responseBody.length > 8192) {
return this._generateLargeJsonBuilder()
}
catch (e) {
console.error(`Invalid JSON response: ${e.toString()}`)
jsonObject = null
}
if (jsonObject !== null) {
swiftJsonString = this._generateJsonObject(jsonObject)
}
else {
swiftJsonString = '/* JSON response */'
}
return `json(${swiftJsonString}, status: ${httpExchange.responseStatusCode})`
return this._generateJsonBuilder()
}
return `http(${httpExchange.responseStatusCode})`
return `http(${this.httpExchange.responseStatusCode})`
}

_generateLargeJsonBuilder() {
const slug = this._getRequestSlug(this.request)
const dataVarName = `${slug}JsonData`
const objectVarName = `${slug}JsonObject`
this.setupLines.push(`let ${dataVarName} = try! Data(contentsOf: Bundle.main.url(forResource: "${slug}", withExtension: "json")!)`)
this.setupLines.push(`let ${objectVarName} = try! JSONSerialization.jsonObject(with: ${dataVarName}, options: [])`)
return `json(${objectVarName}, status: ${this.httpExchange.responseStatusCode})`
}

_generateJsonBuilder() {
let jsonObject
let swiftJsonString
try {
jsonObject = JSON.parse(this.httpExchange.responseBody)
}
catch (e) {
console.error(`Invalid JSON response: ${e.toString()}`)
jsonObject = null
}
if (jsonObject !== null) {
swiftJsonString = this._generateJsonObject(jsonObject)
}
else {
swiftJsonString = '/* JSON response */'
}
return `json(${swiftJsonString}, status: ${this.httpExchange.responseStatusCode})`
}

_generateJsonObject(jsonObject, indent = 0) {
Expand Down Expand Up @@ -70,10 +97,22 @@ class MockingjayGenerator {
return jsonObject.toString()
}
}
}

@registerCodeGenerator
class MockingjayGenerator {
static identifier = 'com.luckymarmot.PawExtensions.MockingjayGenerator';
static title = 'Swift Mockingjay';

_generateStub(request) {
const lastExchange = request.getLastExchange()
let generator = new StubGenerator(request, lastExchange)
return generator.generateStub()
}

generate(context, requests, options) {
return requests.map(request => {
return this._generateStub(request)
})
}).join('\n\n') + '\n'
}
}

0 comments on commit 48da74f

Please sign in to comment.