honey 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +14 -0
- data/.rspec +1 -0
- data/.travis.yml +19 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +55 -0
- data/Rakefile +26 -0
- data/bin/apiary +12 -0
- data/bin/honey +12 -0
- data/doc/Apiary.html +131 -0
- data/doc/Apiary/CLI.html +480 -0
- data/doc/Apiary/Command.html +117 -0
- data/doc/Apiary/Command/Help.html +331 -0
- data/doc/Apiary/Command/Preview.html +1102 -0
- data/doc/Apiary/Command/Runner.html +201 -0
- data/doc/Apiary/Command/Version.html +201 -0
- data/doc/_index.html +192 -0
- data/doc/class_list.html +53 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +328 -0
- data/doc/file.README.html +119 -0
- data/doc/file_list.html +55 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +119 -0
- data/doc/js/app.js +214 -0
- data/doc/js/full_list.js +173 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +252 -0
- data/doc/top-level-namespace.html +112 -0
- data/honey.gemspec +27 -0
- data/lib/honey.rb +7 -0
- data/lib/honey/cli.rb +70 -0
- data/lib/honey/command/help.rb +36 -0
- data/lib/honey/command/preview.rb +103 -0
- data/lib/honey/command/publish.rb +74 -0
- data/lib/honey/command/runner.rb +13 -0
- data/lib/honey/command/version.rb +13 -0
- data/lib/honey/version.rb +3 -0
- data/lib/okapi.rb +13 -0
- data/lib/okapi/apiary_connector.rb +98 -0
- data/lib/okapi/cli.rb +122 -0
- data/lib/okapi/config.rb +13 -0
- data/lib/okapi/examples/apiary.apib +59 -0
- data/lib/okapi/examples/apiary.yaml +5 -0
- data/lib/okapi/examples/tests.spec +6 -0
- data/lib/okapi/examples/tests2.spec +3 -0
- data/lib/okapi/exceptions.rb +0 -0
- data/lib/okapi/help.rb +36 -0
- data/lib/okapi/okapi +43 -0
- data/lib/okapi/output.rb +14 -0
- data/lib/okapi/outputs/base.rb +91 -0
- data/lib/okapi/outputs/tap.rb +44 -0
- data/lib/okapi/resources.rb +53 -0
- data/lib/okapi/spec_parser.rb +82 -0
- data/lib/okapi/test.rb +141 -0
- data/spec/cli_spec.rb +9 -0
- data/spec/spec_helper.rb +2 -0
- metadata +205 -0
data/lib/okapi/config.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Honey
|
3
|
+
module Okapi
|
4
|
+
CONFIG_PATH = "apiary.yaml"
|
5
|
+
APIARY_URL = "https://api.apiary.io"
|
6
|
+
GET_REQUESTS_PATH = "/tests/get-requests"
|
7
|
+
GET_RESULTS_PATH = "/tests/get-test-results"
|
8
|
+
BLUEPRINT_PATH = "apiary.apib"
|
9
|
+
TEST_SPEC_PATHS = "tests.spec"
|
10
|
+
TEST_URL = "http://127.0.0.1"
|
11
|
+
OUTPUT = 'tap'
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
HOST: http://www.google.com/
|
2
|
+
|
3
|
+
--- test API ---
|
4
|
+
|
5
|
+
---
|
6
|
+
Welcome to the our sample API documentation. All comments can be written in (support [Markdown](http://daringfireball.net/projects/markdown/syntax) syntax)
|
7
|
+
---
|
8
|
+
|
9
|
+
--
|
10
|
+
Shopping Cart Resources
|
11
|
+
The following is a section of resources related to the shopping cart
|
12
|
+
--
|
13
|
+
|
14
|
+
List products added into your shopping-cart. (comment block again in Markdown)
|
15
|
+
GET /shopping-cart/{id}
|
16
|
+
< 200
|
17
|
+
< Content-Type: application/json
|
18
|
+
{ "items": [
|
19
|
+
{ "url": "/shopping-cart/1", "product":"2ZY48XPZ", "quantity": 1, "name": "New socks", "price": 1.25 }
|
20
|
+
] }
|
21
|
+
|
22
|
+
Save new products in your shopping cart
|
23
|
+
POST /shopping-cart/{id2}
|
24
|
+
> Content-Type: application/json
|
25
|
+
> CCC: aaa
|
26
|
+
{ "product":"1AB23ORM", "quantity": 2 }
|
27
|
+
< 201
|
28
|
+
< Content-Type: application/json
|
29
|
+
< CCC: aaa
|
30
|
+
{ "status": "created", "url": "/shopping-cart/2" }
|
31
|
+
|
32
|
+
-- Payment Resources --
|
33
|
+
|
34
|
+
This resource allows you to submit payment information to process your *shopping cart* items
|
35
|
+
POST /payment
|
36
|
+
{ "cc": "12345678900", "cvc": "123", "expiry": "0112" }
|
37
|
+
< 200
|
38
|
+
{ "receipt": "/payment/receipt/1" }
|
39
|
+
|
40
|
+
-- JSON Schema Validations --
|
41
|
+
|
42
|
+
POST /shopping-cart/{id2}
|
43
|
+
{"request":
|
44
|
+
{ "type": "object",
|
45
|
+
"properties": {
|
46
|
+
"product": { "type": "string","format": "alphanumeric" },
|
47
|
+
"quantity": { "type": "integer" }
|
48
|
+
}
|
49
|
+
}
|
50
|
+
,
|
51
|
+
"response":
|
52
|
+
{ "type": "object",
|
53
|
+
"properties": {
|
54
|
+
"product": { "type": "string","format": "alphanumeric" },
|
55
|
+
"status": { "type": "integer" }
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
File without changes
|
data/lib/okapi/help.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Honey
|
3
|
+
module Okapi
|
4
|
+
class Help
|
5
|
+
|
6
|
+
def self.show
|
7
|
+
banner
|
8
|
+
options
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.banner
|
12
|
+
puts "\nUsage: okapi [options]"
|
13
|
+
puts "Try 'okapi help' for more information."
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.options
|
17
|
+
puts "\nCurrently available okapi options are:\n\n"
|
18
|
+
|
19
|
+
puts "\t-b, --blueprint path to the blueprint (default: " + BLUEPRINT_PATH + " )"
|
20
|
+
puts "\t-t, --test_spec path to the test specification (default: " + TEST_SPEC_PATHS + " )"
|
21
|
+
#puts "\t-o, --output output format (default: " + OUTPUT + ")"
|
22
|
+
puts "\t-u, --test_url url to test (default: " + TEST_URL + ")"
|
23
|
+
puts "\t-a, --apiary apiary url (default: " + APIARY_URL + ")"
|
24
|
+
puts "\t-s, --config config file (default: " + CONFIG_PATH + ")"
|
25
|
+
puts "\t-p, --params prints used parameters"
|
26
|
+
puts "\n"
|
27
|
+
puts "\thelp Show this help"
|
28
|
+
puts "\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.okapi
|
32
|
+
puts File.read(File.dirname(__FILE__) + '/okapi')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/okapi/okapi
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
,#.@:
|
3
|
+
@;#@@#
|
4
|
+
#+#@#@;
|
5
|
+
:+#;#'+@#@#`
|
6
|
+
@@##@+@;; ``` ,` ;,;@@@+',`
|
7
|
+
;@###@@. ,+#@@@@@@@@#@@@@@@@@@@#``
|
8
|
+
#@@: `,@@#@#@#@@##@@@@@@@'#`+:+:`
|
9
|
+
.#@` #+ ` ::` :`,.+;#`,``'`@.##:#`+`##;` `
|
10
|
+
'@# ` , #+@#@+':@###@+;+.#@,@#`+`+#@@@#:.
|
11
|
+
+@@` + `;#;++`'@@###@@+ @@,@@`#;@@#@#@@@#;+'
|
12
|
+
:@@@@. `; ';#+@,##@####@;,@+,@#`:#':#+'@##@@#'@+`
|
13
|
+
`@@@@###; ` ' @;+#@@#@#.@@'@@@``.'` +#:@'@@#@#@#;
|
14
|
+
`,`#+`,#` `:;#;@#@;.#+;@@#:'`++ ` #.@@@:@,@@@#
|
15
|
+
`:;##@##@:##@.'+:@#,#`.@#@:@@;@##+`
|
16
|
+
#,#@+@@@##@##@#+:`#@@#@`+#;##++
|
17
|
+
@@@@@@@@@@;'@+@#`#.'@@@@``,.,:#,
|
18
|
+
####@@@##'`#@'@@`#'#,@@@# `@#
|
19
|
+
;#@@+@@#'+@'@+@#`#@+@@@@@## #,#
|
20
|
+
#@@##@#+##:@#@@,'@.@@@` :: ;#;
|
21
|
+
'#,#`#@#.'.#@@#+,####` ` `'#
|
22
|
+
+ +:;+@@#@#.##@@#.@. `+`,
|
23
|
+
' `#+###@@@@@#@@@+`.:` .'#
|
24
|
+
@` ##@#####@:@@##`` #,@
|
25
|
+
@#'` #@@##@#,'### ` @'#
|
26
|
+
###' @ :##`#;;#, @.,
|
27
|
+
,+,+ .. ` +#+': . ``++,
|
28
|
+
:':'@; +; `,,, `;
|
29
|
+
#; `: @;#'`; :+``
|
30
|
+
|
31
|
+
+` ` '+;' : .#`
|
32
|
+
@@,@+ .+. ; +##;
|
33
|
+
;#,#@ ',+. `@##
|
34
|
+
:#:#
|
35
|
+
`+ .
|
36
|
+
##.#` + #
|
37
|
+
#+,@. @ +
|
38
|
+
#+ .` # `
|
39
|
+
:; '`` `
|
40
|
+
+## ###
|
41
|
+
`@@: .##`
|
42
|
+
'## ##:
|
43
|
+
`# `
|
data/lib/okapi/output.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
Dir["#{File.dirname(__FILE__)}/outputs/*.rb"].each { |f| require(f) }
|
3
|
+
|
4
|
+
module Honey
|
5
|
+
module Okapi
|
6
|
+
class Output
|
7
|
+
def self.get(output,resources, error)
|
8
|
+
output = Honey::Okapi::Outputs.const_get(output.to_s.capitalize).send(:new, resources, error)
|
9
|
+
output.get()
|
10
|
+
output.status
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Apiary
|
2
|
+
module Okapi
|
3
|
+
module Outputs
|
4
|
+
class BaseOutput
|
5
|
+
attr_reader :status
|
6
|
+
|
7
|
+
def initialize(resources, error)
|
8
|
+
@resources = resources
|
9
|
+
@error = error
|
10
|
+
@results = {
|
11
|
+
:count => 0,
|
12
|
+
:give_up => false,
|
13
|
+
}
|
14
|
+
@status = true
|
15
|
+
get_results
|
16
|
+
end
|
17
|
+
|
18
|
+
def get
|
19
|
+
p @results[:count].to_s + ' tests'
|
20
|
+
p @results[:give_up][:error].to_s if @results[:give_up]
|
21
|
+
@results[:tests].each { |test|
|
22
|
+
p '-------------------------------------------------'
|
23
|
+
p test[:test_no]
|
24
|
+
p test[:description]
|
25
|
+
if test[:pass]
|
26
|
+
p 'OK'
|
27
|
+
else
|
28
|
+
p "FAILED"
|
29
|
+
p test[:exp]
|
30
|
+
end
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_results
|
35
|
+
@results[:count] = @resources.count
|
36
|
+
@results[:tests] = []
|
37
|
+
|
38
|
+
if @error
|
39
|
+
@results[:give_up] = {:error => @error}
|
40
|
+
@status = false
|
41
|
+
else
|
42
|
+
counter = 0
|
43
|
+
@resources.each { |res|
|
44
|
+
counter += 1
|
45
|
+
test_res = {
|
46
|
+
:test_no=> counter,
|
47
|
+
:pass => (res.validation_result.status and res.response.validation_result.status),
|
48
|
+
:description => (res.method + ' ' + res.uri) + ((res.expanded_uri and res.uri != res.expanded_uri['url']) ? " (#{res.expanded_uri['url']}) " : '')
|
49
|
+
}
|
50
|
+
if not test_res[:pass]
|
51
|
+
test_res[:exp] = {:request => {:pass => false}, :response => {:pass => false}}
|
52
|
+
if res.validation_result.status
|
53
|
+
test_res[:exp][:request][:pass] = true
|
54
|
+
else
|
55
|
+
test_res[:exp][:request][:reasons] = get_fail_result(res.validation_result)
|
56
|
+
@status = false
|
57
|
+
end
|
58
|
+
|
59
|
+
if res.response.validation_result.status
|
60
|
+
test_res[:exp][:response][:pass] = true
|
61
|
+
else
|
62
|
+
test_res[:exp][:response][:reasons] = get_fail_result(res.response.validation_result)
|
63
|
+
@status = false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
@results[:tests] << test_res
|
67
|
+
}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_fail_result(result)
|
72
|
+
res = []
|
73
|
+
|
74
|
+
if result.schema
|
75
|
+
result.schema_res["errors"]["length"].times {|i|
|
76
|
+
res << result.schema_res["errors"][i.to_s]["message"]
|
77
|
+
}
|
78
|
+
else
|
79
|
+
if not result.body_pass
|
80
|
+
res << 'Body does not match'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
if not result.header_pass
|
84
|
+
res << 'Headers does not match'
|
85
|
+
end
|
86
|
+
res
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/base.rb"
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Apiary
|
5
|
+
module Okapi
|
6
|
+
module Outputs
|
7
|
+
class Tap < Apiary::Okapi::Outputs::BaseOutput
|
8
|
+
|
9
|
+
def get
|
10
|
+
get_int
|
11
|
+
puts "\n\n"
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_int
|
15
|
+
puts "TAP version 13"
|
16
|
+
puts "1..#{@results[:count].to_s}"
|
17
|
+
if @results[:give_up]
|
18
|
+
puts "Bail out! #{@results[:give_up][:error].to_s.tr("\n"," ")}"
|
19
|
+
return
|
20
|
+
end
|
21
|
+
@results[:tests].each { |test|
|
22
|
+
if test[:pass]
|
23
|
+
o = 'ok '
|
24
|
+
else
|
25
|
+
o = 'not ok '
|
26
|
+
end
|
27
|
+
puts o + test[:test_no].to_s + ' ' + test[:description]
|
28
|
+
if not test[:pass]
|
29
|
+
error_block(test)
|
30
|
+
end
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def error_block(test)
|
35
|
+
test[:exp].to_yaml.split(/\n/).each { |line|
|
36
|
+
puts " #{line}"
|
37
|
+
}
|
38
|
+
puts " ..."
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Apiary
|
3
|
+
module Okapi
|
4
|
+
class Resource
|
5
|
+
attr_accessor :uri, :method, :params, :expanded_uri, :headers, :body, :response, :validation_result
|
6
|
+
|
7
|
+
def initialize(uri, method, params, expanded_uri = nil, headers = nil, body = nil, response = nil, validation_result = nil)
|
8
|
+
#p uri, method, params
|
9
|
+
@uri = uri
|
10
|
+
@method = method
|
11
|
+
@params = params
|
12
|
+
@expanded_uri = expanded_uri
|
13
|
+
@headers = headers
|
14
|
+
@body = body
|
15
|
+
@response = response
|
16
|
+
@validation_result = validation_result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Response
|
21
|
+
attr_accessor :status, :headers, :body, :error, :validation_result
|
22
|
+
|
23
|
+
def initialize(status = nil, headers = nil, body = nil, error = nil, validation_result = nil)
|
24
|
+
@headers = headers
|
25
|
+
@body = body
|
26
|
+
@status = status
|
27
|
+
@error = error
|
28
|
+
@validation_result = validation_result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ValidationResult
|
33
|
+
attr_accessor :status, :error, :schema_res , :body_pass, :body_diff, :header_pass, :header_diff
|
34
|
+
|
35
|
+
def status
|
36
|
+
@status ||= get_status
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_status
|
40
|
+
return true if not @error and @header_pass and ((schema and schema_pass) or (not schema and @body_pass))
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
def schema
|
45
|
+
!(@schema_res == false)
|
46
|
+
end
|
47
|
+
|
48
|
+
def schema_pass
|
49
|
+
not schema or schema and @schema_res and not @schema_res['errors']
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Honey
|
5
|
+
module Okapi
|
6
|
+
class Parser
|
7
|
+
attr_reader :data, :resources, :proces_all_bp_resources, :global_vars
|
8
|
+
|
9
|
+
def initialize(spec_path)
|
10
|
+
if not File.exist? spec_path
|
11
|
+
raise Exception, "Test spec. file '#{spec_path}' not found"
|
12
|
+
end
|
13
|
+
@data = read_file(spec_path)
|
14
|
+
@proces_all_bp_resources = false
|
15
|
+
end
|
16
|
+
|
17
|
+
def resources
|
18
|
+
@resources ||= parse_data
|
19
|
+
end
|
20
|
+
|
21
|
+
def read_file(path)
|
22
|
+
@data = []
|
23
|
+
File.open(path).each do |line|
|
24
|
+
@data << line if line.strip != ""
|
25
|
+
end
|
26
|
+
@data
|
27
|
+
end
|
28
|
+
|
29
|
+
def substituite_vars(local, global)
|
30
|
+
tmp = {}
|
31
|
+
global.each {|k,v|
|
32
|
+
tmp[k] = v
|
33
|
+
}
|
34
|
+
local.each {|k,v|
|
35
|
+
tmp[k] = v
|
36
|
+
}
|
37
|
+
tmp
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse_data
|
41
|
+
global_vars = {}
|
42
|
+
resources = []
|
43
|
+
@data.each { |res|
|
44
|
+
if res.index('CONTINUE') == 0
|
45
|
+
@proces_all_bp_resources = true
|
46
|
+
next
|
47
|
+
end
|
48
|
+
|
49
|
+
if res.index('VARS') == 0
|
50
|
+
splited = res.split(' ',2)
|
51
|
+
begin
|
52
|
+
global_vars = JSON.parse splited[1] if splited[1] and splited[1] != ''
|
53
|
+
rescue Exception => e
|
54
|
+
raise Exception, "can not parse global parameters (#{e})"
|
55
|
+
end
|
56
|
+
next
|
57
|
+
end
|
58
|
+
|
59
|
+
splited = res.split(' ',3)
|
60
|
+
|
61
|
+
begin
|
62
|
+
splited[2] = JSON.parse splited[2] if splited[2] and splited[2] != ''
|
63
|
+
rescue Exception => e
|
64
|
+
raise Exception, 'can not parse parameters for resource:' + res + "(#{e})"
|
65
|
+
end
|
66
|
+
|
67
|
+
if splited[1] and splited[1] != '' and splited[0] and splited[0] != ''
|
68
|
+
out = {
|
69
|
+
'resource' => splited[1],
|
70
|
+
'method' => splited[0],
|
71
|
+
'params' => substituite_vars(splited[2] || {}, global_vars)
|
72
|
+
}
|
73
|
+
resources << out
|
74
|
+
end
|
75
|
+
}
|
76
|
+
|
77
|
+
@global_vars = global_vars
|
78
|
+
resources
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|