api-bdd-test
Version:
use the bdd(cucumber) to test the RESTfull API
167 lines (151 loc) • 5.84 kB
text/coffeescript
isObject = require 'util-ex/lib/is/type/object'
isArray = require 'util-ex/lib/is/type/array'
path = require 'path'
cs = require 'coffeescript'
toQuery = require '../to-query'
module.exports = (aDictionary)->
# `this` is the library.
this.define new RegExp('(GET|HEAD|DEL(?:ETE)?)\\s+$string'), (method, resource)->
testScope = this.ctx
method = method.toLowerCase()
request = this.api.request method, resource
.then (res)=>
testScope.result = res
.catch (err)=>
testScope.result = err
return err
this.define new RegExp('(GET|HEAD|DEL(?:ETE)?|POST|PATCH|PUT)\\s+$string[:]$object'), (method, resource, data={})->
testScope = this.ctx
resource ?= this.resource
method = method.toLowerCase()
request = this.api.request method, resource
data.head = data.heads || data.head
data.accept = data.accepts || data.accept
data.query = data.queries || data.query
data.field = data.fields || data.field
data.attach = data.attachs || data.attachments || data.attachment || data.attach
toQuery data.query if data.query
request = request.send data.data if data.data
# accepting the canonicalized MIME type name complete with type/subtype, or simply the extension name such as "xml", "json", "png", etc
# defaults to json
request = request.set data.head if data.head
request = request.type data.type if data.type
request = request.accept data.accept if data.accept
request = request.query data.query if data.query
request = request.field data.field if data.field
if isArray data.attach
for attach in data.attach
if isArray(attach) and attach.length >= 2
attach[1] = path.resolve this.dir, attach[1]
request = request.attach.apply request, attach
request
.then (res)=>
testScope.result = res
.catch (err)=>
testScope.result = err
return err
this.define new RegExp('(?:last|prev(?:ious)?)\\s+results?\\s+(?:should\\s+)?(be|is|are|includes?)\\s*[:]?\\s*$object'), (isInclude, data={})->
testScope = this.ctx
isInclude = isInclude[2] is 'n'
if isInclude
expect(testScope.result.body).to.be.containSubset data
else
expect(testScope.result.body).to.be.deep.equal data
this.define /(?:last|prev(?:ious)?)\s+status\s*(?:code)?\s*(?:should\s+)?((?:be|is)(?:n't|\s+not)?)\s*[:]?\s*$integer/, (isNot, status)->
testScope = this.ctx
isNot = isNot.length > 2
if isNot
expect(testScope.result.status).to.be.not.equal status
else
expect(testScope.result.status).to.be.equal status
return
# Yadda can not support ignore case: /xxx/i
this.define /login\s+user:\s*$string\s*,\s*passw(?:or)?d:\s*$string/, (username, password)->
testScope = this.ctx
this.api.login
username: username
password: password
.then (res)=>
testScope.result = res
return
.catch (err)=>
testScope.result = err
return err
this.define /logout\s+user|(?:exit|quit)\s+system/, ->
testScope = this.ctx
this.api.logout()
.then (res)=>
testScope.result = res
return
.catch (err)=>
testScope.result = err
return err
# keep the `result.body.id` to 'myvar'
this.define /(?:keep|store|save)\s+(?:the\s+)?$string\s+(?:in)?to\s+$string/, (aKey, aToVar)->
this.ctx[aToVar] = aKey
return
# keep the result of 'body.id' to 'myvar'
this.define /(?:keep|store|save)\s+(?:the\s+)?result\s+of\s+$string\s+(?:in)?to\s+$string/, (aKey, aToVar)->
vResult = this.ctx.result
if aKey? and aKey.length and vResult?
aKey = aKey.split '.'
for k in aKey
vResult = vResult[k] if vResult?
this.ctx[aToVar] = vResult
return
# keep the result to 'myvar'
this.define /(?:keep|store|save)\s+(?:the\s+)?result\s+(?:in)?to\s+$string/, (aToVar)->
this.ctx[aToVar] = this.ctx.result
return
# expect the stored "mvar" equal xxx
this.define /expect\s+(?:the\s+)(?:stored|kept|saved)\s+$string(?:\s+is|be|are|to)?\s+(not\s+)?(above|below|most|least|equa?l?|(?:include|contain)(?:\s+key)?|[><!]=|[<=>])\s*(.+)$/, (aKey, aNot, aOp, aValue)->
aValue = cs.eval aValue
myExpect = expect(aKey).to.be
myExpect = myExpect.not if aNot?
switch aOp
when 'least', '>='
myExpect.least aValue
when 'most', '<='
myExpect.most aValue
when 'above', '>'
myExpect.above aValue
when 'below', '<'
myExpect.below aValue
when 'equal', 'equ', '='
myExpect.equal aValue
when '!='
myExpect.not.equal aValue
else
if aOp.slice(aOp.length-3) is 'key'
myExpect.include.keys aValue
else
myExpect.containSubset aValue
return
this.define /expect\s+(?:the\s+)(?:stored|kept|saved)\s+$string(?:\s+is|be|are|to)?\s+(not\s+)?(above|below|most|least|equa?l?|(?:include|contain)(?:\s+key)?|[><!]=|[<=>])[:]$object/, (aKey, aNot, aOp, aValue)->
myExpect = expect(aKey).to.be
myExpect = myExpect.not if aNot?
switch aOp
when 'least', '>='
myExpect.least aValue
when 'most', '<='
myExpect.most aValue
when 'above', '>'
myExpect.above aValue
when 'below', '<'
myExpect.below aValue
when 'equal', 'equ', '='
myExpect.equal aValue
when '!='
myExpect.not.equal aValue
else
myExpect = myExpect.not if aOp[0] is 'n'
if aOp.slice(aOp.length-3) is 'key'
myExpect.include.keys aValue
else
myExpect.containSubset aValue
return
this.define /expect\s+((?:not\s+)?exist)(?:the\s+)?(?:stored|kept|saved)\s+$string/, (aExists, aKey)->
if aExists[0] isnt 'n'
expect(this.ctx[aKey]).to.be.exist
else
expect(this.ctx[aKey]).not.to.be.exist