Skip to content

Commit

Permalink
Merge 1909705 into 91b62f1
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Kliment committed Apr 14, 2015
2 parents 91b62f1 + 1909705 commit 7694cee
Show file tree
Hide file tree
Showing 21 changed files with 885 additions and 94 deletions.
4 changes: 2 additions & 2 deletions bin/dredd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env node
var DreddCommand = require('../lib/command');
var DreddCommand = require('../lib/dredd-command');

var dreddCli = new DreddCommand({
custom: {
Expand All @@ -9,4 +9,4 @@ var dreddCli = new DreddCommand({
exit: process.exit
});

dreddCli.warmUp().takeoff();
dreddCli.run();
11 changes: 11 additions & 0 deletions docs/canonical-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Cannonical path convention for transaction names

- when processing multiple blueprint, `API Name` is a part of the transaction name
- when there is no API Name in the blueprint, it will use `filename` instead
- when group is not present, transaction starts with a space (bug #168)
- when resource name and action name is empty, URI and method is used instead
- when multiple request response pairs are present, it uses generic sequential example names

## Fundamental indeterminism
- When there are compiled duplicate paths, it does not throw any error

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"glob": "^5.0.3",
"html": "~0.0.7",
"htmlencode": "~0.0.4",
"inquirer": "^0.8.2",
"js-yaml": "^3.2.7",
"markdown-it": "^4.0.1",
"node-uuid": "~1.4.2",
"optimist": "~0.6.1",
Expand Down
4 changes: 2 additions & 2 deletions scripts/cov
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ $COV --exclude node_modules,.git,test --path relative . ./src-cov 1>&2
cp -r ./test ./src-cov/test
cp ./package.json ./src-cov

# Excluding test breaking coveralls report :( Reporting to coveralls.io for further investigation
find ./src-cov/test/ | grep "\-test" | xargs $MOCHA --reporter $REPORTER --compilers 'coffee:coffee-script/register' -i -g 'Using workaround for hooks in ruby'
# Excluding test breaking coveralls report :( Reporting to coveralls.io for further investigation
$MOCHA --reporter $REPORTER --recursive --timeout 120000 --compilers 'coffee:coffee-script/register' -i -g 'Using workaround for hooks in ruby' -i -g 'when using --server' -i -g 'Command line interface' './src-cov/test/**/*-test.coffee'

rm -rf ./src-cov
2 changes: 1 addition & 1 deletion scripts/mocha
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh
cd $(dirname $0)/..
find ./test/ -name '*-test.coffee' | xargs ./node_modules/.bin/mocha --timeout 20000 --reporter spec --compilers 'coffee:coffee-script/register'
./node_modules/.bin/mocha --timeout 120000 --reporter spec --compilers 'coffee:coffee-script/register' --recursive './test/**/*-test.coffee'
47 changes: 47 additions & 0 deletions src/config-utils.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
fs = require 'fs'
yaml = require 'js-yaml'
clone = require 'clone'

configUtils = {}

configUtils.save = (argsOrigin, path) ->
path ?= './dredd.yml'

args = clone argsOrigin

args['blueprint'] = args['_'][0]
args['endpoint'] = args['_'][1]

for key, value of args
delete args[key] if key.length == 1

delete args['$0']
delete args['_']

yamlArgs = yaml.dump args
fs.writeFileSync path, yamlArgs


configUtils.load = (path) ->
path ?= './dredd.yml'

yamlData = fs.readFileSync path
data = yaml.safeLoad yamlData

data['_'] = [data['blueprint'], data['endpoint']]

delete data['blueprint']
delete data['endpoint']

data

configUtils.parseCustom = (customArray) ->
output = {}
if Array.isArray customArray
for string in customArray
splitted = string.split(/:(.+)?/)
output[splitted[0]] = splitted[1]

output

module.exports = configUtils
155 changes: 128 additions & 27 deletions src/command.coffee → src/dredd-command.coffee
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
path = require 'path'
optimist = require 'optimist'
console = require 'console'
fs = require 'fs'
{exec} = require('child_process')

parsePackageJson = require './parse-package-json'
Dredd = require './dredd'
interactiveConfig = require './interactive-config'
configUtils = require './config-utils'

version = parsePackageJson path.join(__dirname, '../package.json')

Expand All @@ -26,72 +30,173 @@ class DreddCommand

@finished = false

warmUp: ->
@finished = false

setOptimistArgv: ->
@optimist = optimist(@custom['argv'], @custom['cwd'])

@optimist.usage(
"""
Usage:
dredd <path or URL to blueprint> <api_endpoint> [OPTIONS]
$ dredd init
Or:
$ dredd <path or URL to blueprint> <api_endpoint> [OPTIONS]
Example:
dredd ./apiary.md http://localhost:3000 --dry-run
$ dredd ./apiary.md http://localhost:3000 --dry-run
"""
)
.options(Dredd.options)
.wrap(80)

@argv = @optimist.argv

argError = false

setExitOrCallback: ->
if not @cb
@exit and (@exit is process.exit) and @sigIntEventAdd = true
@_processExit = @exit or process.exit
if @exit and (@exit is process.exit)
@sigIntEventAdd = true

if @exit
@_processExit = ((code) ->
@finished = true
@serverProcess.kill('SIGKILL') if @serverProcess?
@exit(code)
).bind @
else
@_processExit = ((code) ->
@serverProcess.kill('SIGKILL') if @serverProcess?
process.exit code
).bind @

else
@_processExit = ((code) ->
if @finished then return

@finished = true
if @sigIntEventAdded
process.removeEventListener 'SIGINT', @commandSigInt
@cb code
return @
).bind @

if @argv.help is true
@optimist.showHelp(console.error)
return @_processExit(0)
moveBlueprintArgToPath: () ->
# transform path and p argument to array if it's not
if !Array.isArray(@argv['path'])
@argv['path'] = @argv['p'] = [@argv['path']]

if @argv.version is true
console.log version
return @_processExit(0)
checkRequiredArgs: () ->
argError = false

# if blueprint is missing
if not @argv._[0]?
console.error("\nError: Must specify path to blueprint file.")
argError = true

# if endpoint is missing
if not @argv._[1]?
console.error("\nError: Must specify api endpoint.")
argError = true

# show help if argument is missing
if argError
console.error("\n")
@optimist.showHelp(console.error)
return @_processExit(1)

# transform path and p argument to array if it's not
if !Array.isArray(@argv['path'])
@argv['path'] = @argv['p'] = [@argv['path']]

runExitingActions: () ->
# run interactive config
if @argv["_"][0] == "init" or @argv.init == true
@finished = true
interactiveConfig.run @argv, (config) =>
configUtils.save(config)

console.log ""
console.log "Configuration saved to dredd.yml"
console.log ""
console.log "Run test now, with:"
console.log ""
console.log " $ dredd"
console.log ""

return @_processExit(0)

# show help
else if @argv.help is true
@optimist.showHelp(console.error)
return @_processExit(0)

# show version
else if @argv.version is true
console.log version
return @_processExit(0)

loadDreddFile: () ->
if fs.existsSync './dredd.yml'
console.log 'Configuration dredd.yml found, ignoring other arguments.'
@argv = configUtils.load()

parseCustomConfig: () ->
@argv.custom = configUtils.parseCustom @argv.custom

runServerAndThenDredd: (callback) ->
if not @argv['server']?
@runDredd @dreddInstance
else
@serverProcess = exec @argv['server']
console.log "Starting server with command: #{@argv['server']}"

@serverProcess.stdout.setEncoding 'utf8'

@serverProcess.stdout.on 'data', (data) ->
process.stdout.write data.toString()

@serverProcess.stderr.setEncoding 'utf8'

@serverProcess.stderr.on 'data', (data) ->
process.stdout.write data.toString()

@serverProcess.on 'error', (error) =>
console.log error
console.log "Server command failed, exitting..."
@_processExit(2)

waitSecs = parseInt(@argv['server-wait'], 10)
waitMilis = waitSecs * 1000
console.log "Waiting #{waitSecs} seconds for server command to start..."

@wait = setTimeout =>
@runDredd @dreddInstance
, waitMilis

run: ->
for task in [
@setOptimistArgv
@setExitOrCallback
@parseCustomConfig
@runExitingActions
@loadDreddFile
@checkRequiredArgs
@moveBlueprintArgToPath
]
task.call @
return if @finished

configurationForDredd = @initConfig()
@dreddInstance = @initDredd configurationForDredd
return @

try
@runServerAndThenDredd()
catch e
console.log e.message
console.log e.stack
@_processExit(2)

return


lastArgvIsApiEndpoint: ->
# some shells are automatically expanding globs and concating result as arguments
# so I'm taking last argument as API endpoint server URL and removing it forom optimist's args
# when blueprint path is a glob, some shells are automatically expanding globs and concating
# result as arguments so I'm taking last argument as API endpoint server URL and removing it
# forom optimist's args
@server = @argv._[@argv._.length - 1]
@argv._.splice(@argv._.length - 1, 1)
return @
Expand Down Expand Up @@ -126,11 +231,6 @@ class DreddCommand
console.log "\nShutting down from SIGINT (Ctrl-C)"
@dreddInstance.transactionsComplete => @_processExit(0)

takeoff: ->
if @finished then return

@runDredd @dreddInstance

runDredd: (dreddInstance) ->
if @sigIntEventAdd
# handle SIGINT from user
Expand All @@ -144,6 +244,7 @@ class DreddCommand
if error.stack
console.error error.stack
return @_processExit(1)

if (stats.failures + stats.errors) > 0
@_processExit(1)
else
Expand Down
10 changes: 5 additions & 5 deletions src/expand-uri-template-with-parameters.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ expandUriTemplateWithParameters = (uriTemplate, parameters) ->
for param in expression['params']
uriParameters.push param['name']

# check if all parameters have an expression in URI
# check if all parameters from blueprint have an expression in URI
for parameter in Object.keys(parameters)
if uriParameters.indexOf(parameter) == -1
text = "\nURI template: #{uriTemplate}\nDoesn\'t contain expression for parameter" + \
Expand All @@ -34,8 +34,8 @@ expandUriTemplateWithParameters = (uriTemplate, parameters) ->
for uriParameter in uriParameters
if Object.keys(parameters).indexOf(uriParameter) == -1
ambigous = true
text = "\nAmbigous URI template: #{uriTemplate} " + \
"\nParameter not defined:" + \
text = "\nAmbigous URI parameter in template: #{uriTemplate} " + \
"\nParameter not defined in blueprint:" + \
"'" + uriParameter + "'"
result['warnings'].push text

Expand All @@ -46,8 +46,8 @@ expandUriTemplateWithParameters = (uriTemplate, parameters) ->
if param['required'] == true
if param['example'] == undefined or param['example'] == ""
ambigous = true
text = "\nAmbigous URI template: #{uriTemplate} " + \
"\nNo example value for required parameter:" + \
text = "\nAmbigous URI parameter in template: #{uriTemplate} " + \
"\nNo example value for required parameter in blueprint:" + \
"'" + uriParameter + "'"
result['warnings'].push text
else
Expand Down
Loading

0 comments on commit 7694cee

Please sign in to comment.