honey 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|