apiaryio 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,8 +2,12 @@
2
2
  .rvmrc
3
3
  .tags
4
4
  .rbenv-version
5
+ *.gem
5
6
  /coverage
6
7
  /pkg
7
8
  /rdoc
8
9
  /vendor
9
10
  !/doc
11
+ /.idea
12
+ /nbproject/
13
+
data/README.md CHANGED
@@ -3,10 +3,18 @@ apiaryio
3
3
 
4
4
  Apiary.io CLI
5
5
 
6
+
7
+ ## Install
8
+
9
+ ``` bash
10
+ gem install apiaryio
11
+ ```
12
+
13
+
6
14
  ## Description
7
15
 
8
- Apiaryio gem provides a way to display your API documentation on your local
9
- machine, either using static files or using a standalone web server
16
+ Apiaryio gem provides a way to test and display your API documentation on your local
17
+ machine, either using static files or using a standalone web server...
10
18
 
11
19
  ## Usage
12
20
 
@@ -23,7 +31,7 @@ machine, either using static files or using a standalone web server
23
31
  preview --api_host [HOST] Specify apiary host
24
32
  preview --server Start standalone web server on port 8080
25
33
  preview --server --port [PORT] Start standalone web server on specified port
26
-
34
+ okapi help Show okapi testing tool help
27
35
  help Show help
28
36
 
29
37
  version Show version
@@ -38,6 +46,7 @@ Copyright 2012 (c) Apiary Ltd.
38
46
  - James Charles Russell
39
47
  - Lukáš Linhart
40
48
  - Emili Parreño
49
+ - Peter Grilli [Tu1ly]
41
50
 
42
51
  ## License
43
52
 
@@ -18,9 +18,9 @@ Gem::Specification.new do |gem|
18
18
 
19
19
  gem.add_dependency "rest-client", "~> 1.6.7"
20
20
  gem.add_dependency "rack", "~> 1.4.1"
21
+ gem.add_dependency "json"
21
22
 
22
23
  gem.add_development_dependency "rspec", "~> 2.11.0"
23
24
  gem.add_development_dependency "yard", "~> 0.8.2.1"
24
25
 
25
- gem.post_install_message = "This gem is a client for http://apiary.io. Apiary is in closed beta version now, you need an invitation. If you don't have one, visit http://apiary.us2.list-manage.com/subscribe?u=b89934a238dcec9533f4a834a&id=08f2bdde55 to get on the waiting list!"
26
26
  end
data/bin/apiary CHANGED
@@ -1,6 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
  $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..','lib')))
3
3
  require 'apiary'
4
+ require 'okapi'
4
5
 
5
6
  trap(:INT) { abort "" }
6
- Apiary::CLI.new(ARGV)
7
+ if ARGV[0] == 'okapi' || ARGV[0] == 'test'
8
+ ARGV.delete_at(0)
9
+ Apiary::Okapi::CLI.new(ARGV)
10
+ else
11
+ Apiary::CLI.new(ARGV)
12
+ end
@@ -11,7 +11,7 @@ module Apiary
11
11
  end
12
12
 
13
13
  def run(args, options)
14
- command = args.first
14
+ command = args.first || :help
15
15
  command = @command if @command
16
16
  Apiary::Command::Runner.run(command, options)
17
17
  end
@@ -21,7 +21,7 @@ module Apiary
21
21
  options = {}
22
22
  options_parser = OptionParser.new do |opts|
23
23
  opts.on("--path [PATH]") do |path|
24
- options[:apib_path] = path
24
+ options[:path] = path
25
25
  end
26
26
 
27
27
  opts.on("--api_host API_HOST") do |api_host|
@@ -22,8 +22,9 @@ module Apiary
22
22
  puts "\tpreview --api_host [HOST] Specify apiary host"
23
23
  puts "\tpreview --server Start standalone web server on port 8080"
24
24
  puts "\tpreview --server --port [PORT] Start standalone web server on specified port"
25
+ puts "\tokapi help Show okapi testing tool help"
25
26
  puts "\n"
26
- puts "\thelp Show help"
27
+ puts "\thelp Show this help"
27
28
  puts "\n"
28
29
  puts "\tversion Show version"
29
30
  puts "\n"
@@ -1,6 +1,8 @@
1
1
  # encoding: utf-8
2
2
  require 'rest_client'
3
3
  require 'rack'
4
+ require 'ostruct'
5
+
4
6
  module Apiary
5
7
  module Command
6
8
  # Display preview of local blueprint file
@@ -14,13 +16,13 @@ module Apiary
14
16
 
15
17
  attr_reader :options
16
18
 
17
- def initialize(args)
18
- @options = {}
19
- @options[:apib_path] = "apiary.apib"
20
- @options[:api_host] = "api.apiary.io"
21
- @options[:headers] = {:accept => "text/html", :content_type => "text/plain"}
22
- @options[:port] = 8080
23
- @options.merge! args
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
24
26
  end
25
27
 
26
28
  def self.execute(args)
@@ -32,7 +34,7 @@ module Apiary
32
34
  end
33
35
 
34
36
  def show
35
- generate_static(apib_path)
37
+ generate_static(path)
36
38
  end
37
39
 
38
40
  def validate_apib_file(apib_file)
@@ -41,20 +43,12 @@ module Apiary
41
43
  end
42
44
  end
43
45
 
44
- def apib_path
45
- @options[:apib_path] || "#{File.basename(Dir.pwd)}.apib"
46
+ def path
47
+ @options.path || "#{File.basename(Dir.pwd)}.apib"
46
48
  end
47
49
 
48
50
  def browser
49
- BROWSERS[@options[:browser]] || nil
50
- end
51
-
52
- def api_host
53
- @options[:api_host]
54
- end
55
-
56
- def port
57
- @options[:port]
51
+ BROWSERS[@options.browser] || nil
58
52
  end
59
53
 
60
54
  def rack_app(&block)
@@ -65,21 +59,21 @@ module Apiary
65
59
 
66
60
  def run_server
67
61
  app = self.rack_app do
68
- self.query_apiary(api_host, apib_path)
62
+ self.query_apiary(@options.api_host, @options.path)
69
63
  end
70
64
 
71
- Rack::Server.start(:Port => port, :app => app)
65
+ Rack::Server.start(:Port => @options.port, :app => app)
72
66
  end
73
67
 
74
- def preview_path(apib_path)
75
- basename = File.basename(apib_path)
68
+ def preview_path(path)
69
+ basename = File.basename(@options.path)
76
70
  "/tmp/#{basename}-preview.html"
77
71
  end
78
72
 
79
- def query_apiary(host, apib_path)
73
+ def query_apiary(host, path)
80
74
  url = "https://#{host}/blueprint/generate"
81
- data = File.read(apib_path)
82
- RestClient.post(url, data, @options[:headers])
75
+ data = File.read(path)
76
+ RestClient.post(url, data, @options.headers)
83
77
  end
84
78
 
85
79
  # TODO: add linux and windows systems
@@ -87,16 +81,16 @@ module Apiary
87
81
  exec "open #{browser_options} #{path}"
88
82
  end
89
83
 
90
- def generate_static(apib_path)
91
- File.open(preview_path(apib_path), "w") do |file|
92
- file.write(query_apiary(api_host, apib_path))
84
+ def generate_static(path)
85
+ File.open(preview_path(path), "w") do |file|
86
+ file.write(query_apiary(@options.api_host, path))
93
87
  open_generated_page(file.path)
94
88
  end
95
89
  end
96
90
 
97
91
  private
98
92
  def browser_options
99
- "-a #{BROWSERS[@options[:browser].to_sym]}" if @options[:browser]
93
+ "-a #{BROWSERS[@options.browser.to_sym]}" if @options.browser
100
94
  end
101
95
  end
102
96
  end
@@ -1,3 +1,3 @@
1
1
  module Apiary
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -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 Apiary
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
@@ -0,0 +1,122 @@
1
+ # encoding: utf-8
2
+ require 'optparse'
3
+ require 'yaml'
4
+
5
+ module Apiary
6
+ module Okapi
7
+ class CLI
8
+
9
+ def initialize(args)
10
+ case args.first
11
+ when 'help'
12
+ Apiary::Okapi::Help.show
13
+ exit 0
14
+ when 'okapi'
15
+ Apiary::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 = Apiary::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
+ Apiary::Okapi::Help.banner
116
+ puts "\n"
117
+ exit 1
118
+ end
119
+
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ module Apiary
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
+
@@ -0,0 +1,5 @@
1
+ tests:
2
+ host: http://aptest.apiary.io
3
+ specs:
4
+ - tests.spec
5
+ - tests2.spec
@@ -0,0 +1,6 @@
1
+ VARS {"id2": "eee", "id": "5"}
2
+ POST /shopping-cart/{id2} {"id2": "eee2"}
3
+ POST
4
+ CONTINUE
5
+
6
+
@@ -0,0 +1,3 @@
1
+ POST /shopping-cart/{id2} {"id2": "eee2"}
2
+ POST /payment
3
+
File without changes
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module Apiary
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
@@ -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
+ `# `
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ Dir["#{File.dirname(__FILE__)}/outputs/*.rb"].each { |f| require(f) }
3
+
4
+ module Apiary
5
+ module Okapi
6
+ class Output
7
+ def self.get(output,resources, error)
8
+ output = Apiary::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 Apiary
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
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+ require 'rest_client'
3
+
4
+ module Apiary
5
+ module Okapi
6
+ class Test
7
+ def initialize(blueprint_path, test_spec_path, test_url, output, apiary_url)
8
+ @blueprint_path = blueprint_path
9
+ @test_spec_path = test_spec_path
10
+ @test_url = test_url
11
+ @output_format = output
12
+ @apiary_url = apiary_url
13
+ @req_path = GET_REQUESTS_PATH
14
+ @res_path = GET_RESULTS_PATH
15
+ @connector = Apiary::Okapi::ApiaryConnector.new(@apiary_url, @req_path, @res_path)
16
+ @proces_all_bp_resources = false
17
+ @output = []
18
+ @resources = []
19
+ @error = nil
20
+ end
21
+
22
+ def run
23
+ begin
24
+ test()
25
+ rescue Exception => e
26
+ @resources = []
27
+ @error = e
28
+ end
29
+ Apiary::Okapi::Output.get(@output_format, @resources, @error)
30
+ end
31
+
32
+ def test
33
+ prepare()
34
+ if not @resources.empty?
35
+ get_responses
36
+ evaluate
37
+ else
38
+ raise Exception, 'No resources provided'
39
+ end
40
+ end
41
+
42
+ def prepare
43
+ @resources = []
44
+ parser = get_test_spec_parser(@test_spec_path)
45
+ resources = parser.resources
46
+ counter = 0
47
+
48
+ resources.each { |res|
49
+ counter += 1
50
+ raise Exception, "Rresource not defined for item #{counter.to_d} in #{@test_spec_path}" unless res["resource"]
51
+ raise Exception, "Method not defined for resource #{res["resource"].to_s} in #{@test_spec_path}" unless res["method"]
52
+ }
53
+
54
+ @proces_all_bp_resources = parser.proces_all_bp_resources
55
+ data = get_requests_spec(resources, parser.global_vars)
56
+
57
+ if data[:error] or data[:code] != 200
58
+ raise Exception, 'Can not get request data from Apiary: ' + data[:error] ? data[:error] : ''
59
+ end
60
+
61
+ data[:data].each do |res|
62
+ raise Exception, 'Resource error "' + res['error'] + '" for resource "' + res["method"] + ' ' + res["uri"] + '"' if res['error']
63
+ @resources << Apiary::Okapi::Resource.new(res["uri"], res["method"], res["params"], res["expandedUri"], res["headers"], res["body"])
64
+ end
65
+
66
+ @resources
67
+ end
68
+
69
+ def blueprint
70
+ @blueprint ||= parse_blueprint(@blueprint_path)
71
+ end
72
+
73
+ def get_responses
74
+ @resources.each { |resource|
75
+ params = {:method => resource.method, :url => @test_url + resource.expanded_uri['url'], :headers => resource.headers || {}}
76
+ begin
77
+ response = RestClient::Request.execute(params)
78
+
79
+ raw_headers = response.raw_headers.inject({}) do |out, (key, value)|
80
+ out[key] = %w{ set-cookie }.include?(key.downcase) ? value : value.first
81
+ out
82
+ end
83
+
84
+ resource.response = Apiary::Okapi::Response.new(response.code, raw_headers, response.body)
85
+ rescue Exception => e
86
+ raise Exception, 'Can not get response for: ' + params.to_json + ' (' + e.to_s + ')'
87
+ end
88
+ }
89
+
90
+ end
91
+
92
+ def evaluate
93
+
94
+ data = @connector.get_results(@resources, blueprint)
95
+ if data[:error] or data[:code] != 200
96
+ raise Exception, 'Can not get evaluation data from apiary: ' + data[:error] ? data[:error] : ''
97
+ end
98
+
99
+ data[:data].each { |validation|
100
+ @resources.each { |resource|
101
+ if validation['resource']['uri'] == resource.uri and validation['resource']['method'] == resource.method
102
+ resource.validation_result = Apiary::Okapi::ValidationResult.new()
103
+ resource.validation_result.error = validation['errors']
104
+ resource.validation_result.schema_res = validation["validations"]['reqSchemaValidations']
105
+ resource.validation_result.body_pass = !validation["validations"]['reqData']['body']['isDifferent']
106
+ resource.validation_result.body_diff = validation["validations"]['reqData']['body']['diff']
107
+ resource.validation_result.header_pass = !validation["validations"]['reqData']['headers']['isDifferent']
108
+ resource.validation_result.header_diff = validation["validations"]['reqData']['headers']['diff']
109
+
110
+ resource.response.validation_result = Apiary::Okapi::ValidationResult.new()
111
+ resource.response.validation_result.error = validation['errors']
112
+ resource.response.validation_result.schema_res = validation["validations"]['resSchemaValidations']
113
+ resource.response.validation_result.body_pass = !validation["validations"]['resData']['body']['isDifferent']
114
+ resource.response.validation_result.body_diff = validation["validations"]['resData']['body']['diff']
115
+ resource.response.validation_result.header_pass = !validation["validations"]['resData']['headers']['isDifferent']
116
+ resource.response.validation_result.header_diff = validation["validations"]['resData']['headers']['diff']
117
+ end
118
+
119
+ }
120
+ }
121
+ end
122
+
123
+ def get_test_spec_parser(test_spec)
124
+ Apiary::Okapi::Parser.new(test_spec)
125
+ end
126
+
127
+ def parse_blueprint(blueprint_path)
128
+ if not File.exist? blueprint_path
129
+ raise Exception, "Blueprint file '#{blueprint_path}' not found"
130
+ end
131
+ File.read(blueprint_path)
132
+ end
133
+
134
+ def get_requests_spec(resources, global_vars)
135
+ @connector.get_requests(resources, blueprint, @proces_all_bp_resources, global_vars)
136
+ end
137
+
138
+ end
139
+ end
140
+ end
141
+
metadata CHANGED
@@ -1,88 +1,112 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: apiaryio
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 3
10
+ version: 0.0.3
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Apiary Ltd.
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-08-09 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2013-05-09 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
15
22
  name: rest-client
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: 1.6.7
22
- type: :runtime
23
23
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
- requirements:
26
+ requirements:
27
27
  - - ~>
28
- - !ruby/object:Gem::Version
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 1
32
+ - 6
33
+ - 7
29
34
  version: 1.6.7
30
- - !ruby/object:Gem::Dependency
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
31
38
  name: rack
32
- requirement: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
33
41
  none: false
34
- requirements:
42
+ requirements:
35
43
  - - ~>
36
- - !ruby/object:Gem::Version
44
+ - !ruby/object:Gem::Version
45
+ hash: 5
46
+ segments:
47
+ - 1
48
+ - 4
49
+ - 1
37
50
  version: 1.4.1
38
51
  type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: json
39
55
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
56
+ requirement: &id003 !ruby/object:Gem::Requirement
41
57
  none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 1.4.1
46
- - !ruby/object:Gem::Dependency
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :runtime
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
47
68
  name: rspec
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ~>
52
- - !ruby/object:Gem::Version
53
- version: 2.11.0
54
- type: :development
55
69
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
70
+ requirement: &id004 !ruby/object:Gem::Requirement
57
71
  none: false
58
- requirements:
72
+ requirements:
59
73
  - - ~>
60
- - !ruby/object:Gem::Version
74
+ - !ruby/object:Gem::Version
75
+ hash: 35
76
+ segments:
77
+ - 2
78
+ - 11
79
+ - 0
61
80
  version: 2.11.0
62
- - !ruby/object:Gem::Dependency
63
- name: yard
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ~>
68
- - !ruby/object:Gem::Version
69
- version: 0.8.2.1
70
81
  type: :development
82
+ version_requirements: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
71
85
  prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
86
+ requirement: &id005 !ruby/object:Gem::Requirement
73
87
  none: false
74
- requirements:
88
+ requirements:
75
89
  - - ~>
76
- - !ruby/object:Gem::Version
90
+ - !ruby/object:Gem::Version
91
+ hash: 5
92
+ segments:
93
+ - 0
94
+ - 8
95
+ - 2
96
+ - 1
77
97
  version: 0.8.2.1
98
+ type: :development
99
+ version_requirements: *id005
78
100
  description: Apiary.io CLI
79
- email:
101
+ email:
80
102
  - team@apiary.io
81
- executables:
103
+ executables:
82
104
  - apiary
83
105
  extensions: []
106
+
84
107
  extra_rdoc_files: []
85
- files:
108
+
109
+ files:
86
110
  - .gitignore
87
111
  - .rspec
88
112
  - Gemfile
@@ -120,36 +144,59 @@ files:
120
144
  - lib/apiary/command/runner.rb
121
145
  - lib/apiary/command/version.rb
122
146
  - lib/apiary/version.rb
147
+ - lib/okapi.rb
148
+ - lib/okapi/apiary_connector.rb
149
+ - lib/okapi/cli.rb
150
+ - lib/okapi/config.rb
151
+ - lib/okapi/examples/apiary.apib
152
+ - lib/okapi/examples/apiary.yaml
153
+ - lib/okapi/examples/tests.spec
154
+ - lib/okapi/examples/tests2.spec
155
+ - lib/okapi/exceptions.rb
156
+ - lib/okapi/help.rb
157
+ - lib/okapi/okapi
158
+ - lib/okapi/output.rb
159
+ - lib/okapi/outputs/base.rb
160
+ - lib/okapi/outputs/tap.rb
161
+ - lib/okapi/resources.rb
162
+ - lib/okapi/spec_parser.rb
163
+ - lib/okapi/test.rb
123
164
  - spec/cli_spec.rb
124
165
  - spec/spec_helper.rb
166
+ has_rdoc: true
125
167
  homepage: http://apiary.io
126
- licenses:
168
+ licenses:
127
169
  - MIT
128
- post_install_message: This gem is a client for http://apiary.io. Apiary is in closed
129
- beta version now, you need an invitation. If you don't have one, visit http://apiary.us2.list-manage.com/subscribe?u=b89934a238dcec9533f4a834a&id=08f2bdde55
130
- to get on the waiting list!
170
+ post_install_message:
131
171
  rdoc_options: []
132
- require_paths:
172
+
173
+ require_paths:
133
174
  - lib
134
- required_ruby_version: !ruby/object:Gem::Requirement
175
+ required_ruby_version: !ruby/object:Gem::Requirement
135
176
  none: false
136
- requirements:
137
- - - ! '>='
138
- - !ruby/object:Gem::Version
139
- version: '0'
140
- required_rubygems_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ hash: 3
181
+ segments:
182
+ - 0
183
+ version: "0"
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
185
  none: false
142
- requirements:
143
- - - ! '>='
144
- - !ruby/object:Gem::Version
145
- version: '0'
186
+ requirements:
187
+ - - ">="
188
+ - !ruby/object:Gem::Version
189
+ hash: 3
190
+ segments:
191
+ - 0
192
+ version: "0"
146
193
  requirements: []
194
+
147
195
  rubyforge_project:
148
- rubygems_version: 1.8.24
196
+ rubygems_version: 1.3.7
149
197
  signing_key:
150
198
  specification_version: 3
151
199
  summary: Apiary.io CLI
152
- test_files:
200
+ test_files:
153
201
  - spec/cli_spec.rb
154
202
  - spec/spec_helper.rb
155
- has_rdoc: