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
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Honey
|
3
|
+
module Command
|
4
|
+
# Display help
|
5
|
+
class Help
|
6
|
+
|
7
|
+
def self.execute(options)
|
8
|
+
banner
|
9
|
+
commands
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.banner
|
13
|
+
puts "\nUsage: apiary command [options]"
|
14
|
+
puts "Try 'apiary help' for more information."
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.commands
|
18
|
+
puts "\nCurrently available apiary commands are:\n\n"
|
19
|
+
puts "\tpreview Show API documentation in default browser"
|
20
|
+
puts "\tpreview --browser [chrome|safari|firefox] Show API documentation in specified browser"
|
21
|
+
puts "\tpreview --path [PATH] Specify path to blueprint file"
|
22
|
+
puts "\tpreview --api_host [HOST] Specify apiary host"
|
23
|
+
puts "\tpreview --server Start standalone web server on port 8080"
|
24
|
+
puts "\tpreview --server --port [PORT] Start standalone web server on specified port"
|
25
|
+
puts "\tpublish --api-name [API_NAME] Publish apiary.apib on docs.API_NAME.apiary.io"
|
26
|
+
puts "\tokapi help Show okapi testing tool help"
|
27
|
+
puts "\n"
|
28
|
+
puts "\thelp Show this help"
|
29
|
+
puts "\n"
|
30
|
+
puts "\tversion Show version"
|
31
|
+
puts "\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rest_client'
|
3
|
+
require 'rack'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
module Honey
|
7
|
+
module Command
|
8
|
+
# Display preview of local blueprint file
|
9
|
+
class Preview
|
10
|
+
|
11
|
+
BROWSERS = {
|
12
|
+
:safari => "Safari",
|
13
|
+
:chrome => "Google Chrome",
|
14
|
+
:firefox => "Firefox"
|
15
|
+
}
|
16
|
+
|
17
|
+
attr_reader :options
|
18
|
+
|
19
|
+
# TODO: use OpenStruct to store @options
|
20
|
+
def initialize(opts)
|
21
|
+
@options = OpenStruct.new(opts)
|
22
|
+
@options.path ||= "apiary.apib"
|
23
|
+
@options.api_host ||= "api.apiary.io"
|
24
|
+
@options.headers ||= {:accept => "text/html", :content_type => "text/plain"}
|
25
|
+
@options.port ||= 8080
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.execute(args)
|
29
|
+
args[:server] ? new(args).server : new(args).show
|
30
|
+
end
|
31
|
+
|
32
|
+
def server
|
33
|
+
run_server
|
34
|
+
end
|
35
|
+
|
36
|
+
def show
|
37
|
+
generate_static(path)
|
38
|
+
end
|
39
|
+
|
40
|
+
def validate_apib_file(apib_file)
|
41
|
+
unless File.exist?(apib_file)
|
42
|
+
abort "Apiary definition file hasn't been found: #{apib_file.inspect}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def path
|
47
|
+
@options.path || "#{File.basename(Dir.pwd)}.apib"
|
48
|
+
end
|
49
|
+
|
50
|
+
def browser
|
51
|
+
BROWSERS[@options.browser] || nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def rack_app(&block)
|
55
|
+
Rack::Builder.new do
|
56
|
+
run lambda { |env| [200, Hash.new, [block.call]] }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def run_server
|
61
|
+
app = self.rack_app do
|
62
|
+
self.query_apiary(@options.api_host, @options.path)
|
63
|
+
end
|
64
|
+
|
65
|
+
Rack::Server.start(:Port => @options.port, :app => app)
|
66
|
+
end
|
67
|
+
|
68
|
+
def preview_path(path)
|
69
|
+
basename = File.basename(@options.path)
|
70
|
+
"/tmp/#{basename}-preview.html"
|
71
|
+
end
|
72
|
+
|
73
|
+
def query_apiary(host, path)
|
74
|
+
url = "https://#{host}/blueprint/generate"
|
75
|
+
data = File.read(path)
|
76
|
+
RestClient.post(url, data, @options.headers)
|
77
|
+
end
|
78
|
+
|
79
|
+
# TODO: add linux and windows systems
|
80
|
+
def open_generated_page(path)
|
81
|
+
exec "open #{browser_options} #{path}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def write_generated_path(path, outfile)
|
85
|
+
File.open(outfile, 'w') do |file|
|
86
|
+
file.write(File.open(path, 'r').read)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def generate_static(path)
|
91
|
+
File.open(preview_path(path), "w") do |file|
|
92
|
+
file.write(query_apiary(@options.api_host, path))
|
93
|
+
@options.output ? write_generated_path(file.path, @options.output) : open_generated_page(file.path)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def browser_options
|
99
|
+
"-a #{BROWSERS[@options.browser.to_sym]}" if @options.browser
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rest_client'
|
3
|
+
require 'rack'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
module Honey
|
7
|
+
module Command
|
8
|
+
# Display preview of local blueprint file
|
9
|
+
class Publish
|
10
|
+
|
11
|
+
attr_reader :options
|
12
|
+
|
13
|
+
# TODO: use OpenStruct to store @options
|
14
|
+
def initialize(opts)
|
15
|
+
@options = OpenStruct.new(opts)
|
16
|
+
@options.path ||= "apiary.apib"
|
17
|
+
@options.api_host ||= "api.apiary.io"
|
18
|
+
@options.port ||= 8080
|
19
|
+
@options.api_name ||= false
|
20
|
+
@options.api_key ||= ENV['APIARY_API_KEY']
|
21
|
+
@options.headers ||= {
|
22
|
+
:accept => "text/html",
|
23
|
+
:content_type => "text/plain",
|
24
|
+
:authentication => "Token #{@options.api_key}"
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.execute(args)
|
29
|
+
new(args).publish_on_apiary
|
30
|
+
end
|
31
|
+
|
32
|
+
def publish_on_apiary
|
33
|
+
unless @options.api_name
|
34
|
+
abort "Please provide an api-name option (subdomain part from your http://docs.<api-name>.apiary.io/)"
|
35
|
+
end
|
36
|
+
|
37
|
+
unless @options.api_key
|
38
|
+
abort "API key must be provided through environment variable APIARY_API_KEY. Please go to https://login.apiary.io/tokens to obtain it."
|
39
|
+
end
|
40
|
+
|
41
|
+
self.query_apiary(@options.api_host, @options.path)
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def validate_apib_file(apib_file)
|
46
|
+
unless File.exist?(apib_file)
|
47
|
+
abort "Apiary definition file hasn't been found: #{apib_file.inspect}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def path
|
52
|
+
@options.path || "#{File.basename(Dir.pwd)}.apib"
|
53
|
+
end
|
54
|
+
|
55
|
+
def query_apiary(host, path)
|
56
|
+
url = "https://#{host}/blueprint/publish/#{@options.api_name}"
|
57
|
+
data = {
|
58
|
+
:code => File.read(path)
|
59
|
+
}
|
60
|
+
response = RestClient.post url, data, @options.headers
|
61
|
+
|
62
|
+
unless response.code == 201
|
63
|
+
abort "Request failed with code #{response.code}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def api_name
|
69
|
+
"-a"
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/okapi.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
require "okapi/config"
|
4
|
+
require "okapi/output"
|
5
|
+
require "okapi/apiary_connector"
|
6
|
+
require "okapi/resources"
|
7
|
+
require "okapi/spec_parser"
|
8
|
+
require "okapi/test"
|
9
|
+
require "okapi/cli"
|
10
|
+
require "okapi/help"
|
11
|
+
|
12
|
+
module Okapi
|
13
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rest_client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Honey
|
6
|
+
module Okapi
|
7
|
+
class ApiaryConnector
|
8
|
+
attr_reader :apiary_url, :blueprint
|
9
|
+
|
10
|
+
def initialize(apiary_url, req_path, res_path)
|
11
|
+
@apiary_url = apiary_url
|
12
|
+
@req_path = req_path
|
13
|
+
@res_path = res_path
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_response(raw_resp, json_data, error, code)
|
17
|
+
{ :resp => raw_resp,
|
18
|
+
:data => json_data ? json_data['requests'] : nil,
|
19
|
+
:status => json_data ? json_data['status'] : nil ,
|
20
|
+
:error => json_data ? json_data['error'] || error : error,
|
21
|
+
:code => code
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_requests(resources, blueprint, all_resources = false, global_vars = {})
|
26
|
+
resources_list = []
|
27
|
+
|
28
|
+
resources.each() do |res|
|
29
|
+
resources_list << {
|
30
|
+
:resource => res['resource'],
|
31
|
+
:method => res['method'],
|
32
|
+
:params => res['params']
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
data = {
|
37
|
+
:resources => resources_list,
|
38
|
+
:blueprint => blueprint,
|
39
|
+
:all_resources => all_resources,
|
40
|
+
:global_vars => global_vars
|
41
|
+
}.to_json()
|
42
|
+
|
43
|
+
begin
|
44
|
+
response = RestClient.post @apiary_url + @req_path, data, :content_type => :json, :accept => :json
|
45
|
+
get_response(response, JSON.parse(response.to_str), nil, response.code.to_i)
|
46
|
+
rescue RestClient::BadRequest, RestClient::InternalServerError => e
|
47
|
+
begin
|
48
|
+
data = JSON.parse(e.http_body)
|
49
|
+
get_response(nil, JSON.parse(e.http_body), data['error'], e.http_code.to_i)
|
50
|
+
rescue
|
51
|
+
get_response(nil, nil, e.to_s, e.http_code.to_i)
|
52
|
+
end
|
53
|
+
rescue Exception => e
|
54
|
+
get_response(nil, nil, e.to_s, nil)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_results(resources, blueprint)
|
60
|
+
resources_list = []
|
61
|
+
resources.each() do |res|
|
62
|
+
resources_list << {
|
63
|
+
:request => {
|
64
|
+
:uri => res.uri,
|
65
|
+
:expandedUri => res.expanded_uri,
|
66
|
+
:method => res.method,
|
67
|
+
:headers => res.headers,
|
68
|
+
:body => res.body,
|
69
|
+
},
|
70
|
+
:response => {
|
71
|
+
:status => res.response.status,
|
72
|
+
:headers => res.response.headers ,
|
73
|
+
:body => res.response.body
|
74
|
+
}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
data = {
|
79
|
+
:resources => resources_list,
|
80
|
+
:blueprint => blueprint
|
81
|
+
}.to_json()
|
82
|
+
|
83
|
+
begin
|
84
|
+
response = RestClient.post @apiary_url + @res_path, data, :content_type => :json, :accept => :json
|
85
|
+
get_response(response, JSON.parse(response.to_str), nil, response.code.to_i)
|
86
|
+
rescue RestClient::BadRequest, RestClient::InternalServerError => e
|
87
|
+
begin
|
88
|
+
get_response(nil, JSON.parse(e.http_body), data['error'], e.http_code.to_i)
|
89
|
+
rescue
|
90
|
+
get_response(nil, nil, e.to_s, e.http_code.to_i)
|
91
|
+
end
|
92
|
+
rescue Exception => e
|
93
|
+
get_response(nil, nil, e.to_s, nil)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/okapi/cli.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'optparse'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Honey
|
6
|
+
module Okapi
|
7
|
+
class CLI
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
case args.first
|
11
|
+
when 'help'
|
12
|
+
Honey::Okapi::Help.show
|
13
|
+
exit 0
|
14
|
+
when 'okapi'
|
15
|
+
Honey::Okapi::Help.okapi
|
16
|
+
exit 0
|
17
|
+
else
|
18
|
+
parse_options!(args)
|
19
|
+
parse_config
|
20
|
+
@options[:blueprint] ||= BLUEPRINT_PATH
|
21
|
+
@options[:test_spec] ||= TEST_SPEC_PATHS
|
22
|
+
@options[:output] ||= OUTPUT
|
23
|
+
@options[:test_url] ||= TEST_URL
|
24
|
+
@options[:apiary_url] ||= APIARY_URL
|
25
|
+
|
26
|
+
@options[:test_spec] ||= TEST_SPEC_PATHS.gsub(' ','').split(',')
|
27
|
+
|
28
|
+
if @options[:params]
|
29
|
+
puts "running with :"
|
30
|
+
p @options
|
31
|
+
puts "\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
exit run
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def run
|
39
|
+
pass = true
|
40
|
+
@options[:test_spec].each { |spec|
|
41
|
+
pass = Honey::Okapi::Test.new(@options[:blueprint], spec, @options[:test_url], @options[:output], @options[:apiary_url]).run()
|
42
|
+
}
|
43
|
+
if pass
|
44
|
+
0
|
45
|
+
else
|
46
|
+
1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_config
|
51
|
+
begin
|
52
|
+
if tests = YAML.load_file(@options[:config_path])['tests']
|
53
|
+
@options[:test_url] ||= tests['host'] if tests['host']
|
54
|
+
@options[:test_spec] ||= tests['specs'] if tests['specs']
|
55
|
+
end
|
56
|
+
rescue Errno::ENOENT => e
|
57
|
+
puts "Config file (#{@options[:config_path]}) not accessible ... skiping"
|
58
|
+
puts "\n"
|
59
|
+
rescue Exception => e
|
60
|
+
puts "Config file (#{@options[:config_path]}) loading problem :#{e}"
|
61
|
+
puts "\n"
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_options!(args)
|
67
|
+
@options = {}
|
68
|
+
options_parser = OptionParser.new do |opts|
|
69
|
+
opts.on("-c", "--config CONFIG",
|
70
|
+
"path config file (default: " + CONFIG_PATH + " )") do |config|
|
71
|
+
@options[:config_path] = config
|
72
|
+
end
|
73
|
+
|
74
|
+
opts.on("-b", "--blueprint BLUEPRINT",
|
75
|
+
"path to the blueprint (default: " + BLUEPRINT_PATH + " )") do |blueprint|
|
76
|
+
@options[:blueprint] = blueprint
|
77
|
+
end
|
78
|
+
|
79
|
+
opts.on("-t","--test_spec TEST_SPEC",
|
80
|
+
"comma separated paths to the test specifications (default: " + TEST_SPEC_PATHS + " )") do |test_spec|
|
81
|
+
@options[:test_spec] = test_spec
|
82
|
+
end
|
83
|
+
|
84
|
+
opts.on("-o","--output OUTPUT",
|
85
|
+
"output format (default" + OUTPUT + ")") do |output|
|
86
|
+
@options[:output] = output
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.on("-u","--test_url TEST_URL",
|
90
|
+
"url to test (default" + TEST_URL + ")") do |test_url|
|
91
|
+
@options[:test_url] = test_url
|
92
|
+
end
|
93
|
+
|
94
|
+
opts.on("-a","--apiary APIARY",
|
95
|
+
"apiary url (default" + APIARY_URL + ")") do |apiary|
|
96
|
+
@options[:apiary_url] = apiary
|
97
|
+
end
|
98
|
+
|
99
|
+
opts.on("-p","--params [PARAMS]",
|
100
|
+
"show parameters" ) do |params|
|
101
|
+
@options[:params] = true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
options_parser.parse!
|
106
|
+
|
107
|
+
@options[:config_path] ||= CONFIG_PATH
|
108
|
+
@options[:test_spec] = @options[:test_spec].gsub(' ','').split(',') if @options[:test_spec]
|
109
|
+
|
110
|
+
@options
|
111
|
+
|
112
|
+
rescue OptionParser::InvalidOption => e
|
113
|
+
puts "\n"
|
114
|
+
puts e
|
115
|
+
Honey::Okapi::Help.banner
|
116
|
+
puts "\n"
|
117
|
+
exit 1
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|