Skip to content
This repository has been archived by the owner on Nov 8, 2024. It is now read-only.

Commit

Permalink
Merge pull request #61 from apiaryio/honzajavorek/fix-apib-regression…
Browse files Browse the repository at this point in the history
…-transaction-examples

Use just the 1st req-res pair within APIB transaction examples
  • Loading branch information
Adam Kliment authored Aug 24, 2016
2 parents 20eb425 + 0af7c01 commit ccc545c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 10 deletions.
34 changes: 30 additions & 4 deletions src/compile.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ compile = (mediaType, parseResult, filename) ->
location: content(child(annotation.attributes?.sourceMap, {element: 'sourceMap'}))
})

if mediaType is 'text/vnd.apiblueprint'
children(parseResult, {element: 'transition'}).map(detectTransactionExamples)

for httpTransaction in children(parseResult, {element: 'httpTransaction'})
for httpTransaction in findRelevantTransactions(parseResult, mediaType)
resource = parent(httpTransaction, parseResult, {element: 'resource'})
httpRequest = child(httpTransaction, {element: 'httpRequest'})
httpResponse = child(httpTransaction, {element: 'httpResponse'})
Expand All @@ -51,6 +48,35 @@ compile = (mediaType, parseResult, filename) ->
{transactions, errors, warnings}


findRelevantTransactions = (parseResult, mediaType) ->
relevantTransactions = []

if mediaType is 'text/vnd.apiblueprint'
# API Blueprint has a concept of transaction examples and
# the API Blueprint AST used to expose it. The concept isn't present
# in API Elements anymore, so we have to detect and backport them.
children(parseResult, {element: 'transition'}).map(detectTransactionExamples)

# Dredd supports only testing of the first request-response pair within
# each transaction example. So if we're dealing with API Blueprint, we
# iterate over available transactions and skip those, which are not first
# within a particular example.
#
# That's achieved by tracking example number within each transition
# and skipping transactions with example number we've already seen.
for transition in children(parseResult, {element: 'transition'})
example = 0

for httpTransaction in children(transition, {element: 'httpTransaction'})
if mediaType is 'text/vnd.apiblueprint'
relevantTransactions.push(httpTransaction) unless httpTransaction.attributes.example is example
else
relevantTransactions.push(httpTransaction)
example = httpTransaction.attributes.example

return relevantTransactions


compileRequest = (parseResult, httpRequest) ->
messageBody = child(httpRequest, {element: 'asset', 'meta.classes': 'messageBody'})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ FORMAT: 1A

## Honey [/honey]

### Retrieve [GET]

+ Request (application/json)
+ Response 200
+ Response 500

### Remove [DELETE]

+ Request (application/json)
+ Response 200
+ Response 500

+ Request (text/plain)
+ Request (application/xml)
+ Response 415
30 changes: 24 additions & 6 deletions test/integration/compile-api-blueprint-test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ describe('compile() · API Blueprint', ->
describe('with multiple transaction examples', ->
detectTransactionExamples = sinon.spy(require('../../src/detect-transaction-examples'))
transactions = undefined
exampleNumbersPerTransaction = [1, 1, 2]
expected = [
{exampleName: '', requestContentType: 'application/json', responseStatusCode: 200}
{exampleName: 'Example 1', requestContentType: 'application/json', responseStatusCode: 200}
{exampleName: 'Example 2', requestContentType: 'text/plain', responseStatusCode: 415}
]

beforeEach((done) ->
stubs = {'./detect-transaction-examples': detectTransactionExamples}
Expand All @@ -107,15 +111,29 @@ describe('compile() · API Blueprint', ->
assert.isTrue(detectTransactionExamples.called)
)
it('is compiled into expected number of transactions', ->
assert.equal(transactions.length, exampleNumbersPerTransaction.length)
assert.equal(transactions.length, expected.length)
)
for exampleNumber, i in exampleNumbersPerTransaction
do (exampleNumber, i) ->
for expectations, i in expected
do (expectations, i) ->
context("transaction ##{i + 1}", ->
it("is identified as part of Example #{exampleNumber}", ->
{exampleName, requestContentType, responseStatusCode} = expectations

it("is identified as part of #{JSON.stringify(exampleName)}", ->
assert.equal(
transactions[i].origin.exampleName,
"Example #{exampleNumber}"
exampleName
)
)
it("has request with Content-Type: #{requestContentType}", ->
assert.equal(
transactions[i].request.headers['Content-Type'].value,
requestContentType
)
)
it("has response with status code #{responseStatusCode}", ->
assert.equal(
transactions[i].response.status,
responseStatusCode
)
)
)
Expand Down

0 comments on commit ccc545c

Please sign in to comment.