apirunner 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/apirunner.gemspec +9 -3
- data/lib/api_runner.rb +6 -4
- data/lib/apirunner.rb +1 -0
- data/lib/checker.rb +1 -22
- data/lib/http_client.rb +14 -9
- data/lib/plugins/plug01_response_json_syntax_checker.rb +1 -1
- data/lib/plugins/plug02_response_code_checker.rb +5 -4
- data/lib/plugins/plug03_response_header_checker.rb +5 -4
- data/lib/plugins/plug04_response_body_checker.rb +22 -0
- data/lib/result.rb +10 -3
- data/lib/string_ext.rb +23 -0
- data/lib/tasks/api.rake +12 -1
- data/spec/api_configuration_spec.rb +40 -0
- data/spec/api_runner_spec.rb +35 -21
- data/spec/checker_spec.rb +86 -0
- data/spec/expectation_matcher_spec.rb +29 -226
- data/spec/http_client_spec.rb +50 -23
- data/spec/result_spec.rb +45 -0
- metadata +11 -5
- data/lib/core_extensions.rb +0 -17
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.6
|
data/apirunner.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{apirunner}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["jan@moviepilot.com"]
|
12
|
-
s.date = %q{2010-10-
|
12
|
+
s.date = %q{2010-10-12}
|
13
13
|
s.description = %q{apirunner is a testsuite to query your RESTful JSON API and match response with your defined expectations}
|
14
14
|
s.email = %q{developers@moviepilot.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -45,7 +45,6 @@ Gem::Specification.new do |s|
|
|
45
45
|
"lib/apirunner.rb",
|
46
46
|
"lib/apirunner/railtie.rb",
|
47
47
|
"lib/checker.rb",
|
48
|
-
"lib/core_extensions.rb",
|
49
48
|
"lib/expectation_matcher.rb",
|
50
49
|
"lib/http_client.rb",
|
51
50
|
"lib/plugins/plug01_response_json_syntax_checker.rb",
|
@@ -53,12 +52,16 @@ Gem::Specification.new do |s|
|
|
53
52
|
"lib/plugins/plug03_response_header_checker.rb",
|
54
53
|
"lib/plugins/plug04_response_body_checker.rb",
|
55
54
|
"lib/result.rb",
|
55
|
+
"lib/string_ext.rb",
|
56
56
|
"lib/tasks/api.rake",
|
57
57
|
"lib/testcase.rb",
|
58
58
|
"spec/.rspec",
|
59
|
+
"spec/api_configuration_spec.rb",
|
59
60
|
"spec/api_runner_spec.rb",
|
61
|
+
"spec/checker_spec.rb",
|
60
62
|
"spec/expectation_matcher_spec.rb",
|
61
63
|
"spec/http_client_spec.rb",
|
64
|
+
"spec/result_spec.rb",
|
62
65
|
"spec/spec_helper.rb"
|
63
66
|
]
|
64
67
|
s.homepage = %q{http://github.com/moviepilot/apirunner}
|
@@ -66,9 +69,12 @@ Gem::Specification.new do |s|
|
|
66
69
|
s.rubygems_version = %q{1.3.7}
|
67
70
|
s.summary = %q{one-line summary of your gem}
|
68
71
|
s.test_files = [
|
72
|
+
"spec/api_configuration_spec.rb",
|
69
73
|
"spec/api_runner_spec.rb",
|
74
|
+
"spec/checker_spec.rb",
|
70
75
|
"spec/expectation_matcher_spec.rb",
|
71
76
|
"spec/http_client_spec.rb",
|
77
|
+
"spec/result_spec.rb",
|
72
78
|
"spec/spec_helper.rb"
|
73
79
|
]
|
74
80
|
|
data/lib/api_runner.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
1
|
class ApiRunner
|
2
2
|
require 'yaml'
|
3
|
+
require 'string_ext' if not String.respond_to?(:underscore)
|
3
4
|
require 'expectation_matcher'
|
4
5
|
require 'http_client'
|
5
6
|
require 'api_configuration'
|
6
7
|
require 'testcase'
|
7
|
-
require '
|
8
|
-
|
8
|
+
require 'string_ext'
|
9
|
+
|
10
|
+
require 'JSON'
|
9
11
|
|
10
12
|
CONFIG_FILE = "config/api_runner.yml"
|
11
13
|
SPEC_PATH = "test/api_runner/"
|
12
14
|
EXCLUDES_FILE = "test/api_runner/excludes.yml"
|
13
15
|
|
14
16
|
# initializes the object, loads environment, build base_uri
|
15
|
-
def initialize(env)
|
17
|
+
def initialize(env, performance=nil)
|
16
18
|
@spec = []
|
17
19
|
@results = []
|
18
20
|
@excludes = []
|
19
21
|
@configuration = ApiConfiguration.new(YAML.load_file(self.class.config_file), env)
|
22
|
+
@configuration.verbosity = "performance" if performance
|
20
23
|
load_excludes(env)
|
21
24
|
load_url_spec
|
22
25
|
@http_client = HttpClient.new(@configuration.protocol, @configuration.host, @configuration.port, @configuration.namespace)
|
@@ -148,4 +151,3 @@ class ApiRunner
|
|
148
151
|
EXCLUDES_FILE
|
149
152
|
end
|
150
153
|
end
|
151
|
-
|
data/lib/apirunner.rb
CHANGED
data/lib/checker.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class Checker
|
2
|
-
|
3
2
|
@@children = []
|
4
3
|
|
5
4
|
def initialize(testcase, response, excludes=nil)
|
@@ -27,26 +26,6 @@ class Checker
|
|
27
26
|
@@children << child
|
28
27
|
end
|
29
28
|
|
30
|
-
# recursively parses the tree and returns a set of relative pathes
|
31
|
-
# that can be used to match the both trees leafs
|
32
|
-
def matcher_pathes_from(node, pathes = nil)
|
33
|
-
pathes ||= []
|
34
|
-
if not node.children.blank?
|
35
|
-
node.children.each do |sub_node|
|
36
|
-
matcher_pathes_from(sub_node, pathes)
|
37
|
-
end
|
38
|
-
else
|
39
|
-
pathes << relative_path(node.parent.path)
|
40
|
-
end
|
41
|
-
pathes
|
42
|
-
end
|
43
|
-
|
44
|
-
# returns relative path for matching the target tree of the response body
|
45
|
-
# explicit array adressing is replaced by *
|
46
|
-
def relative_path(path)
|
47
|
-
path.gsub(/\/([^\/]+)\[\d+\]\//i,"/*/")
|
48
|
-
end
|
49
|
-
|
50
29
|
# returns true if given attributes is an excluded item that does not have to be evaluated in this environment
|
51
30
|
def excluded?(item)
|
52
31
|
@excludes.include?(item)
|
@@ -71,7 +50,7 @@ class Checker
|
|
71
50
|
# parses output into JSON object
|
72
51
|
def valid_json?(response_body)
|
73
52
|
# responses may be nil, return true then
|
74
|
-
return true if response_body.
|
53
|
+
return true if response_body.nil? or response_body == {} or response_body == "" or response_body == " "
|
75
54
|
# returns true if given response is valid json, else false
|
76
55
|
JSON.parse(response_body.to_s) rescue false
|
77
56
|
end
|
data/lib/http_client.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class HttpClient
|
2
2
|
require 'net/http'
|
3
|
+
require "cgi"
|
4
|
+
require "benchmark"
|
3
5
|
|
4
6
|
def initialize(protocol, host, port, namespace)
|
5
7
|
@http = Net::HTTP.new(host, port)
|
@@ -10,53 +12,56 @@ class HttpClient
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def send_request(method, resource, headers=nil, data=nil, params=nil)
|
13
|
-
|
15
|
+
runtime, response = self.send(method.to_s.downcase, headers, resource, data, params)
|
16
|
+
build_response(response, runtime, method, resource, params)
|
14
17
|
end
|
15
18
|
|
16
19
|
protected
|
17
20
|
|
18
21
|
# returns struct containing response.code, headers, body and message
|
19
22
|
# this is only for easily interfaceing another http client
|
20
|
-
def build_response(raw_response)
|
21
|
-
|
23
|
+
def build_response(raw_response, runtime, method, resource, params)
|
24
|
+
end_time = Time.now.usec
|
25
|
+
response_struct = Struct.new(:code, :message, :headers, :body, :runtime, :fully_qualified_path)
|
22
26
|
response = response_struct.new
|
23
27
|
response.code = raw_response.code
|
24
28
|
response.message = raw_response.message
|
25
29
|
response.body = raw_response.body
|
26
|
-
response.headers = JSON.parse(raw_response.
|
30
|
+
response.headers = JSON.parse(raw_response.headers.to_json) rescue ""
|
31
|
+
response.runtime = runtime
|
32
|
+
response.fully_qualified_path = (method == "GET" ? build_uri(resource, params).request_uri : resource_path(resource))
|
27
33
|
response
|
28
34
|
end
|
29
35
|
|
30
36
|
# sends GET request and returns response
|
31
37
|
def get(headers, resource, data, params)
|
32
38
|
request = Net::HTTP::Get.new(build_uri(resource, params).request_uri, initheader = headers)
|
33
|
-
@http.request(request)
|
39
|
+
return Benchmark.realtime{ @response = @http.request(request) }, @response
|
34
40
|
end
|
35
41
|
|
36
42
|
# sends PUT request and returns response
|
37
43
|
def put(headers, resource, data, params)
|
38
44
|
request = Net::HTTP::Put.new(resource_path(resource), initheader = headers)
|
39
45
|
request.body = data.to_json
|
40
|
-
@http.request(request)
|
46
|
+
return Benchmark.realtime { @response = @http.request(request) }, @response
|
41
47
|
end
|
42
48
|
|
43
49
|
# sends POST request and returns response
|
44
50
|
def post(headers, resource, data, params)
|
45
51
|
request = Net::HTTP::Post.new(resource_path(resource), initheader = headers)
|
46
52
|
request.body = data.to_json
|
47
|
-
@http.request(request)
|
53
|
+
return Benchmark.realtime{ @response = @http.request(request) }, @response
|
48
54
|
end
|
49
55
|
|
50
56
|
# sends DELETE request and returns response
|
51
57
|
def delete(headers, resource, data, params)
|
52
58
|
request = Net::HTTP::Delete.new(resource_path(resource), initheader = headers)
|
53
|
-
@http.request(request)
|
59
|
+
return Benchmark.realtime{ @response = @http.request(request) }, @response
|
54
60
|
end
|
55
61
|
|
56
62
|
# redefines the resource path including the namespace
|
57
63
|
def resource_path(resource)
|
58
64
|
@namespace.nil? ? resource : "/" + @namespace + resource
|
59
|
-
"/" + @namespace + resource
|
60
65
|
end
|
61
66
|
|
62
67
|
# rebuild a uri in details, so that another protocol, host, port and GET params can be specified, after Net::HTTP was created
|
@@ -5,7 +5,7 @@ class ResponseJsonSyntaxChecker < Checker
|
|
5
5
|
result = Result.new(@testcase, @response)
|
6
6
|
if not valid_json?(@response.body)
|
7
7
|
result.succeeded = false
|
8
|
-
result.error_message = "expected valid JSON in body\n got --#{@response.body[1..400]}--"
|
8
|
+
result.error_message = "expected valid JSON in body\n got --#{@response.body[1..400]}-- #{@response.body.class}"
|
9
9
|
end
|
10
10
|
result
|
11
11
|
end
|
@@ -8,10 +8,11 @@ class ResponseCodeChecker < Checker
|
|
8
8
|
result.succeeded = false
|
9
9
|
result.error_message = " expected response code --#{@testcase.response_expectation['status_code']}--\n got response code --#{@response.code}--"
|
10
10
|
end
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
rescue Exception => e
|
12
|
+
result.succeeded = false
|
13
|
+
result.error_message = " unexpected error while parsing testcase/response. Check your testcase format!"
|
14
|
+
result.error_message = "\n\n Exception occured: #{e}"
|
15
|
+
end
|
15
16
|
result
|
16
17
|
end
|
17
18
|
|
@@ -17,10 +17,11 @@ class ResponseHeaderChecker < Checker
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end unless (@testcase.response_expectation['headers'].nil? or @testcase.response_expectation['headers'].empty?)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
rescue Exception => e
|
21
|
+
result.succeeded = false
|
22
|
+
result.error_message = " unexpected error while parsing testcase/response. Check your testcase format!"
|
23
|
+
result.error_message = "\n\nException occured: #{e}"
|
24
|
+
end
|
24
25
|
result
|
25
26
|
end
|
26
27
|
|
@@ -66,4 +66,26 @@ class ResponseBodyChecker < Checker
|
|
66
66
|
end
|
67
67
|
result
|
68
68
|
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# recursively parses the tree and returns a set of relative pathes
|
73
|
+
# that can be used to match the both trees leafs
|
74
|
+
def matcher_pathes_from(node, pathes = nil)
|
75
|
+
pathes ||= []
|
76
|
+
if not node.children.blank?
|
77
|
+
node.children.each do |sub_node|
|
78
|
+
matcher_pathes_from(sub_node, pathes)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
pathes << relative_path(node.parent.path)
|
82
|
+
end
|
83
|
+
pathes
|
84
|
+
end
|
85
|
+
|
86
|
+
# returns relative path for matching the target tree of the response body
|
87
|
+
# explicit array adressing is replaced by *
|
88
|
+
def relative_path(path)
|
89
|
+
path.gsub(/\/([^\/]+)\[\d+\]\//i,"/*/")
|
90
|
+
end
|
69
91
|
end
|
data/lib/result.rb
CHANGED
@@ -42,13 +42,14 @@ class Result
|
|
42
42
|
# yields a more verbose message in any case and includes a curl command to manually simulate the testcase
|
43
43
|
def verbose_with_curl(index)
|
44
44
|
be_verbose(index)
|
45
|
-
puts
|
45
|
+
puts("\n simulate this call with: \"curl TODO\"")
|
46
46
|
end
|
47
47
|
|
48
48
|
# yields the verbose error messages
|
49
49
|
def be_verbose(index)
|
50
50
|
puts "\n#{result_case} (#{index+1})- \"#{@testcase.name}\""
|
51
51
|
puts @error_message
|
52
|
+
puts("Request runtime: #{@response.runtime}")
|
52
53
|
puts(" More more more verbosity\n")
|
53
54
|
puts(" request method: #{@testcase.request['method']}")
|
54
55
|
puts(" resource path: #{@testcase.request['path']}")
|
@@ -64,6 +65,12 @@ class Result
|
|
64
65
|
puts(" response body: #{JSON.parse(@response.body) rescue nil}")
|
65
66
|
end
|
66
67
|
|
68
|
+
# yields out only performance information
|
69
|
+
def performance(index)
|
70
|
+
puts "\n#{@testcase.name}\n"
|
71
|
+
puts " %-10s %-20s %-8s %s " % ["#{@response.runtime.to_s[0..6]}s", "[#{result_case}]", @testcase.request['method'], @response.fully_qualified_path]
|
72
|
+
end
|
73
|
+
|
67
74
|
# returns the result case for interpolation in the output message header
|
68
75
|
def result_case
|
69
76
|
if @succeeded
|
@@ -85,8 +92,8 @@ class Result
|
|
85
92
|
|
86
93
|
def ansi_colors(color)
|
87
94
|
case color
|
88
|
-
when
|
89
|
-
when
|
95
|
+
when :green then ["\033[32m", "\033[0m"]
|
96
|
+
when :red then ["\033[31m", "\033[0m"]
|
90
97
|
else ['','']
|
91
98
|
end
|
92
99
|
end
|
data/lib/string_ext.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class String
|
2
|
+
# generates filenames from classnames the rails way
|
3
|
+
def underscore
|
4
|
+
self.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
|
5
|
+
end
|
6
|
+
|
7
|
+
# opposites underscore defined above
|
8
|
+
def camelize(first_letter_in_uppercase = true)
|
9
|
+
if first_letter_in_uppercase
|
10
|
+
self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
11
|
+
else
|
12
|
+
self.first + camelize(lower_case_and_underscored_word)[1..-1]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
# # opposites underscore defined above
|
16
|
+
# def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
17
|
+
# if first_letter_in_uppercase
|
18
|
+
# lower_case_and_underscored_word.to_s.gsub(/\\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
19
|
+
# else
|
20
|
+
# lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
end
|
data/lib/tasks/api.rake
CHANGED
@@ -4,7 +4,7 @@ rescue
|
|
4
4
|
end
|
5
5
|
namespace :api do
|
6
6
|
namespace :run do
|
7
|
-
config.each_key do |env|
|
7
|
+
config.delete_if{ |key| key == "general" }.each_key do |env|
|
8
8
|
desc "runs a series of nessecary api calls and parses their response in environment #{env}"
|
9
9
|
task env.to_sym => :environment do
|
10
10
|
puts "Running API tests in environment #{env}"
|
@@ -14,6 +14,17 @@ namespace :api do
|
|
14
14
|
end
|
15
15
|
end unless config.nil?
|
16
16
|
end
|
17
|
+
namespace:performance do
|
18
|
+
config.delete_if{ |key| key == "general" }.each_key do |env|
|
19
|
+
desc "runs a series of nessecary api calls for performance measuring and parses their response in environment #{env}"
|
20
|
+
task env.to_sym => :environment do
|
21
|
+
puts "Running API performance tests in environment #{env}"
|
22
|
+
api_runner = ApiRunner.new(env, performance=true)
|
23
|
+
api_runner.run
|
24
|
+
puts "\nPerformance testrun finished\n\n"
|
25
|
+
end
|
26
|
+
end unless config.nil?
|
27
|
+
end
|
17
28
|
desc "generates configuration and a skeleton for apirunner tests as well as excludes"
|
18
29
|
task :scaffold do
|
19
30
|
TEST_EXAMPLES_PATH="test/api_runner"
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'initialize' do
|
4
|
+
before(:each) do
|
5
|
+
@config_hash = {
|
6
|
+
"test" => {
|
7
|
+
:a => 1,
|
8
|
+
:b => 2,
|
9
|
+
:protocol => "http",
|
10
|
+
:host => "localhost",
|
11
|
+
:port => 3000,
|
12
|
+
:namespace => "namespace"
|
13
|
+
},
|
14
|
+
"general" => {
|
15
|
+
"verbosity" => ["verbose", "unused"],
|
16
|
+
"priority" => 10
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should set instance variables for each config key value pair' do
|
22
|
+
@a = ApiConfiguration.new(@config_hash, "test")
|
23
|
+
@a.instance_variable_get(:@a).should == 1
|
24
|
+
@a.instance_variable_get(:@b).should == 2
|
25
|
+
@a.instance_variable_get(:@protocol).should == "http"
|
26
|
+
@a.instance_variable_get(:@host).should == "localhost"
|
27
|
+
@a.instance_variable_get(:@port).should == 3000
|
28
|
+
@a.instance_variable_get(:@namespace).should == "namespace"
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should set verbosity correctly' do
|
32
|
+
@a = ApiConfiguration.new(@config_hash, "test")
|
33
|
+
@a.instance_variable_get(:@verbosity).should == "verbose"
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should set priority correctly' do
|
37
|
+
@a = ApiConfiguration.new(@config_hash, "test")
|
38
|
+
@a.instance_variable_get(:@priority).should == 10
|
39
|
+
end
|
40
|
+
end
|
data/spec/api_runner_spec.rb
CHANGED
@@ -8,11 +8,20 @@ describe 'apirunner' do
|
|
8
8
|
@a = ApiRunner.new(:local)
|
9
9
|
end
|
10
10
|
describe 'initialize' do
|
11
|
-
it 'should fill all instance variables' do
|
12
|
-
@a.instance_variable_get(:@
|
13
|
-
@a.instance_variable_get(:@
|
14
|
-
@a.instance_variable_get(:@
|
15
|
-
@a.instance_variable_get(:@
|
11
|
+
it 'should fill all instance variables properly' do
|
12
|
+
@a.instance_variable_get(:@spec).should be_a(Array)
|
13
|
+
@a.instance_variable_get(:@spec).size.should == 58
|
14
|
+
@a.instance_variable_get(:@results).should be_a(Array)
|
15
|
+
@a.instance_variable_get(:@results).size.should == 0
|
16
|
+
@a.instance_variable_get(:@configuration).should be_a(ApiConfiguration)
|
17
|
+
@a.instance_variable_get(:@configuration).host.should == "localhost"
|
18
|
+
@a.instance_variable_get(:@configuration).port.should == 3000
|
19
|
+
@a.instance_variable_get(:@configuration).protocol.should == "http"
|
20
|
+
@a.instance_variable_get(:@configuration).namespace.should == "api1v0"
|
21
|
+
@a.instance_variable_get(:@configuration).verbosity.should == "verbose_on_error"
|
22
|
+
@a.instance_variable_get(:@configuration).priority.should == 0
|
23
|
+
@a.instance_variable_get(:@http_client).should be_a(HttpClient)
|
24
|
+
@a.instance_variable_get(:@expectation).should be_a(ExpectationMatcher)
|
16
25
|
end
|
17
26
|
it 'should fill @excludes' do
|
18
27
|
@a.instance_variable_get(:@excludes).should_not be_nil
|
@@ -24,36 +33,41 @@ describe 'apirunner' do
|
|
24
33
|
@a.instance_variable_get(:@spec).should be_a(Array)
|
25
34
|
@a.instance_variable_get(:@spec).size.should >= 1
|
26
35
|
end
|
27
|
-
it 'should instantiate an http client into @http_client' do
|
28
|
-
@a.instance_variable_get(:@http_client).should be_a(HttpClient)
|
29
|
-
end
|
30
|
-
it 'should instantiate an expectation_matcher into @expectation' do
|
31
|
-
@a.instance_variable_get(:@expectation).should be_a(ExpectationMatcher)
|
32
|
-
end
|
33
36
|
end
|
34
37
|
|
35
38
|
describe 'run_tests' do
|
36
39
|
it 'should send a request for every given testcase' do
|
37
|
-
|
38
|
-
response =
|
39
|
-
response.code = 404
|
40
|
-
response.message = "Ok"
|
41
|
-
response.body = {}
|
42
|
-
response.headers = {}
|
40
|
+
pending "TODO"
|
41
|
+
response = Result.new({},{})
|
43
42
|
@a.should_receive(:server_is_available?).and_return true
|
44
43
|
@a.should_receive(:send_request).exactly(@a.instance_variable_get(:@spec).size).times.and_return(response)
|
45
44
|
@a.run
|
46
45
|
end
|
47
|
-
it 'should
|
48
|
-
|
46
|
+
it 'should save an error message in @errors if an error occured' do
|
47
|
+
pending "TODO"
|
48
|
+
response = Result.new({},{})
|
49
|
+
@a.should_receive(:server_is_available?).and_return true
|
50
|
+
@a.should_receive(:send_request).exactly(@a.instance_variable_get(:@spec).size).times.and_return(response)
|
51
|
+
@a.run
|
52
|
+
@a.instance_variable_get(:@results).should_not be_nil
|
53
|
+
@a.instance_variable_get(:@results).size.should_not == 0
|
54
|
+
end
|
49
55
|
end
|
50
56
|
|
51
57
|
describe 'send_request' do
|
52
|
-
it
|
58
|
+
it "should invoke send_request at the @http_client with appropiate method, path, headers, body and get-parameters" do
|
59
|
+
pending "TODO"
|
60
|
+
@a.instance_variable_get(:@http_client).should_receive(:send_request).and_return(Result.new({},{}))
|
61
|
+
@a.send(:send_request_for,Testcase.new({}))
|
62
|
+
end
|
53
63
|
end
|
54
64
|
|
55
65
|
describe 'target_uri' do
|
56
|
-
it 'should create a correct target uri from existing instance variables'
|
66
|
+
it 'should create a correct target uri from existing instance variables' do
|
67
|
+
@a.send(:target_uri).match(@a.instance_variable_get(:@configuration).protocol).should be_true
|
68
|
+
@a.send(:target_uri).match(@a.instance_variable_get(:@configuration).host).should be_true
|
69
|
+
@a.send(:target_uri).match("://").should be_true
|
70
|
+
end
|
57
71
|
end
|
58
72
|
|
59
73
|
describe 'server_is_available?' do
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'json'
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
describe "Checker" do
|
6
|
+
describe "self.available_plugins" do
|
7
|
+
it "should return an array of available plugins inheriting from self" do
|
8
|
+
Checker.available_plugins.should be_a(Array)
|
9
|
+
Checker.available_plugins.size.should_not == 0
|
10
|
+
end
|
11
|
+
end
|
12
|
+
describe "relative_path" do
|
13
|
+
it 'should substitute an absolute addressing in a given path' do
|
14
|
+
pending "Move me"
|
15
|
+
path = "/bla/foo/values[6]/duffy/duck"
|
16
|
+
Checker.new({},{}).send(:relative_path, path).should eql "/bla/foo/*/duffy/duck"
|
17
|
+
end
|
18
|
+
it 'should substitute more than one absolute adressing in a given path' do
|
19
|
+
pending "Move me"
|
20
|
+
path = "/bla/foo/values[6]/duffy/friends[1]/duck"
|
21
|
+
Checker.new({},{}).send(:relative_path, path).should eql "/bla/foo/*/duffy/*/duck"
|
22
|
+
end
|
23
|
+
it 'should return a string' do
|
24
|
+
pending "Move me"
|
25
|
+
path = "/bla/foo/values[6]/duffy/friends[1]/duck"
|
26
|
+
Checker.new({},{}).send(:relative_path, path).should be_a(String)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
describe "excluded?" do
|
30
|
+
it "should return true if a given item is not part of the instances exludes"
|
31
|
+
it "should return false if a given item is part of the instances excludes"
|
32
|
+
end
|
33
|
+
describe "is_regex?" do
|
34
|
+
it 'should return true if the given string seems to be a regular expression' do
|
35
|
+
string = "/^\d{3}$/"
|
36
|
+
Checker.new({},{}).send(:is_regex?, string).should be_true
|
37
|
+
end
|
38
|
+
it 'should return false if the given string does not seem to be a regular expression' do
|
39
|
+
string = "fooz"
|
40
|
+
Checker.new({},{}).send(:is_regex?, string).should be_false
|
41
|
+
string = "/fooz"
|
42
|
+
Checker.new({},{}).send(:is_regex?, string).should be_false
|
43
|
+
string = "fooz/"
|
44
|
+
Checker.new({},{}).send(:is_regex?, string).should be_false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
describe "regex_matches?" do
|
48
|
+
it 'should return true if the given regular expression matches the given value' do
|
49
|
+
regex = "^\\d{2}$"
|
50
|
+
value = "12"
|
51
|
+
Checker.new({},{}).send(:regex_matches?, regex, value).should be_true
|
52
|
+
end
|
53
|
+
it 'should return false if the giveb reular expression does not match the given value' do
|
54
|
+
regex = "^\\d{2}$"
|
55
|
+
value = "123"
|
56
|
+
Checker.new({},{}).send(:regex_matches?, regex, value).should be_false
|
57
|
+
value = "foo"
|
58
|
+
Checker.new({},{}).send(:regex_matches?, regex, value).should be_false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
describe "string_matches?" do
|
62
|
+
it 'should return true if the given string matches the given value' do
|
63
|
+
string = "bar"
|
64
|
+
value = "bar"
|
65
|
+
Checker.new({},{}).send(:string_matches?, string, value).should be_true
|
66
|
+
end
|
67
|
+
it 'should return false if the given string does not match the given value' do
|
68
|
+
string = "bar"
|
69
|
+
value = "foo"
|
70
|
+
Checker.new({},{}).send(:string_matches?, string, value).should be_false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
describe "valid_json?" do
|
74
|
+
it 'should return true if the given response body consists of valid JSON' do
|
75
|
+
validateable = { :foo => "bar" }.to_json
|
76
|
+
Checker.new({},{}).send(:valid_json?, validateable).should be_true
|
77
|
+
end
|
78
|
+
it 'should return true if the given response body is nil' do
|
79
|
+
Checker.new({},{}).send(:valid_json?, nil).should be_true
|
80
|
+
end
|
81
|
+
it 'should return false if the given response body consists of anything else but valid JSON' do
|
82
|
+
Checker.new({},{}).send(:valid_json?, "foobar").should be_false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
@@ -1,232 +1,35 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
require 'json'
|
3
|
-
require 'nokogiri'
|
4
2
|
|
5
3
|
describe 'ExpectationMatcher' do
|
6
|
-
|
7
|
-
@
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
it
|
14
|
-
ExpectationMatcher.new
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
describe 'check' do
|
37
|
-
it 'should invoke http client with the given method, response and testcase' do
|
38
|
-
@em = ExpectationMatcher.new
|
39
|
-
@em.should_receive(:put)
|
40
|
-
@em.check(:put, {}, [])
|
41
|
-
@em.should_receive(:post)
|
42
|
-
@em.check(:post, {}, [])
|
43
|
-
@em.should_receive(:get)
|
44
|
-
@em.check(:get, {}, [])
|
45
|
-
@em.should_receive(:delete)
|
46
|
-
@em.check(:delete, {}, [])
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe 'response_code' do
|
51
|
-
it 'should return a struct representing success if the given response code matches the expected one' do
|
52
|
-
response_struct = Struct.new(:code, :message, :headers, :body)
|
53
|
-
response = response_struct.new
|
54
|
-
response.code = 404
|
55
|
-
testcase = { 'response_expectation' => { 'status_code' => 404 } }
|
56
|
-
@em.send(:response_code, response, testcase).should be_a(Struct)
|
57
|
-
@em.send(:response_code, response, testcase).succeeded.should be_true
|
58
|
-
@em.send(:response_code, response, testcase).error.should be_nil
|
59
|
-
end
|
60
|
-
it 'should return a struct representing failure if the given repsonse code does not match the expected one' do
|
61
|
-
response_struct = Struct.new(:code, :message, :headers, :body)
|
62
|
-
response = response_struct.new
|
63
|
-
response.code = 400
|
64
|
-
testcase = { 'response_expectation' => { 'status_code' => 404 } }
|
65
|
-
@em.send(:response_code, response, testcase).should be_a(Struct)
|
66
|
-
@em.send(:response_code, response, testcase).succeeded.should be_false
|
67
|
-
@em.send(:response_code, response, testcase).error.should_not be_nil
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe 'response_body_format' do
|
72
|
-
before(:each) do
|
73
|
-
response_struct = Struct.new(:code, :message, :headers, :body)
|
74
|
-
@response = response_struct.new
|
75
|
-
end
|
76
|
-
it 'should return a struct representing success if the given response body is nil, cause this is allowed' do
|
77
|
-
@response.body = nil
|
78
|
-
@em.send(:response_body_format, @response, {}).should be_a(Struct)
|
79
|
-
@em.send(:response_body_format, @response, {}).succeeded.should be_true
|
80
|
-
@em.send(:response_body_format, @response, {}).error.should be_nil
|
81
|
-
end
|
82
|
-
it 'should return the given response body in JSON format, if a valid JSON string is given to check' do
|
83
|
-
@response.body = {:fooz => "baaz"}.to_json
|
84
|
-
@em.send(:response_body_format, @response, {}).should be_a(Struct)
|
85
|
-
@em.send(:response_body_format, @response, {}).succeeded.should be_true
|
86
|
-
@em.send(:response_body_format, @response, {}).error.should be_nil
|
87
|
-
end
|
88
|
-
it 'should not fatal but return false, if the given response body is no valid JSON' do
|
89
|
-
@response.body = "foozbaz"
|
90
|
-
@em.send(:response_body_format, @response, {}).should be_a(Struct)
|
91
|
-
@em.send(:response_body_format, @response, {}).succeeded.should be_false
|
92
|
-
@em.send(:response_body_format, @response, {}).error.should_not be_nil
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
describe 'response_headers' do
|
97
|
-
before(:each) do
|
98
|
-
response_struct = Struct.new(:code, :message, :headers, :body)
|
99
|
-
@response = response_struct.new
|
100
|
-
end
|
101
|
-
it 'should return a struct representing success, if one certain expected header value matches the response header' do
|
102
|
-
@response.headers = {"content-type"=>["text/html; charset=utf-8"], "cache-control"=>["no-cache"], "x-runtime"=>["0.340116"], "server"=>["WEBrick/1.3.1 (Ruby/1.9.2/2010-08-18)"], "date"=>["Tue, 21 Sep 2010 11:33:05 GMT"], "content-length"=>["149"], "connection"=>["close"], "Last-Modified" => "2010-10-01 23:23:23"}
|
103
|
-
testcase = { 'response_expectation' => { 'headers' => {"Last-Modified"=>"/.*/"} } }
|
104
|
-
@em.send(:response_headers, @response, testcase).should be_a(Struct)
|
105
|
-
@em.send(:response_headers, @response, testcase).succeeded.should be_true
|
106
|
-
@em.send(:response_headers, @response, testcase).error.should be_nil
|
107
|
-
end
|
108
|
-
it 'should return a struct representing success, if more than one expected header values match the ones in the repsonse header' do
|
109
|
-
pending "TODO: pair this one"
|
110
|
-
end
|
111
|
-
it 'should even return a struct representing success if the response header contains more values than the excpected' do
|
112
|
-
pending "TODO: pair this one"
|
113
|
-
end
|
114
|
-
it 'should return a struct representing an error, if one single expected header value does not match the one in response' do
|
115
|
-
pending "TODO: pair this one"
|
116
|
-
end
|
117
|
-
it 'should return a struct representing an error, if one of more expected header values does not match the corresponding one in the response' do
|
118
|
-
pending "TODO: pair this one"
|
119
|
-
end
|
120
|
-
it 'should return a struct representing success, if the expected header is nil - no expectation exists' do
|
121
|
-
pending "TODO: pair this one"
|
122
|
-
testcase = { 'response_expectation' => { 'headers' => nil } }
|
123
|
-
@em.send(:response_headers, @response, testcase).should be_a(Struct)
|
124
|
-
@em.send(:response_headers, @response, testcase).succeeded.should be_true
|
125
|
-
@em.send(:response_headers, @response, testcase).error.should be_nil
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
describe 'response_body' do
|
130
|
-
it 'should check something'
|
131
|
-
it 'should return a result struct'
|
132
|
-
end
|
133
|
-
|
134
|
-
describe 'matcher_pathes_from' do
|
135
|
-
it 'should return pathes to all leaves of a given tree including relative pathes in case of arrays in the JSON' do
|
136
|
-
xml_tree = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><hash><bla>laber</bla><foo><values type=\"array\"><value><a>1</a></value><value><b type=\"integer\">2</b></value><value><c>/.*/</c></value></values></foo><bar>baz</bar></hash>"
|
137
|
-
tree = Nokogiri::XML(xml_tree)
|
138
|
-
@em.send(:matcher_pathes_from, tree).should be_a(Array)
|
139
|
-
@em.send(:matcher_pathes_from, tree).include?("/hash/bla").should be_true
|
140
|
-
@em.send(:matcher_pathes_from, tree).include?("/hash/foo/values/*/a").should be_true
|
141
|
-
@em.send(:matcher_pathes_from, tree).include?("/hash/foo/values/*/b").should be_true
|
142
|
-
@em.send(:matcher_pathes_from, tree).include?("/hash/foo/values/*/c").should be_true
|
143
|
-
@em.send(:matcher_pathes_from, tree).include?("/hash/bar").should be_true
|
144
|
-
@em.send(:matcher_pathes_from, tree).each do |path|
|
145
|
-
path.should be_a(String)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
describe 'relative_path' do
|
151
|
-
it 'should substitute an absolute addressing in a given path' do
|
152
|
-
path = "/bla/foo/values[6]/duffy/duck"
|
153
|
-
@em.send(:relative_path, path).should eql "/bla/foo/*/duffy/duck"
|
154
|
-
end
|
155
|
-
it 'should substitute more than one absolute adressing in a given path' do
|
156
|
-
path = "/bla/foo/values[6]/duffy/friends[1]/duck"
|
157
|
-
@em.send(:relative_path, path).should eql "/bla/foo/*/duffy/*/duck"
|
158
|
-
end
|
159
|
-
it 'should return a string' do
|
160
|
-
path = "/bla/foo/values[6]/duffy/friends[1]/duck"
|
161
|
-
@em.send(:relative_path, path).should be_a(String)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
describe 'excluded?' do
|
166
|
-
before(:each) do
|
167
|
-
@em = ExpectationMatcher.new(['foo', 'bar'])
|
168
|
-
end
|
169
|
-
it 'should return true if the given string is present in the @excludes instance variable of the class' do
|
170
|
-
@em.send(:excluded?, 'foo').should be_true
|
171
|
-
end
|
172
|
-
it 'should return false if the given string is not present in the @excludes instance variable of the class' do
|
173
|
-
@em.send(:excluded?, 'fooz').should be_false
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe 'is_regex?' do
|
178
|
-
it 'should return true if the given string seems to be a regular expression' do
|
179
|
-
string = "/^\d{3}$/"
|
180
|
-
@em.send(:is_regex?, string).should be_true
|
181
|
-
end
|
182
|
-
it 'should return false if the given string does not seem to be a regular expression' do
|
183
|
-
string = "fooz"
|
184
|
-
@em.send(:is_regex?, string).should be_false
|
185
|
-
string = "/fooz"
|
186
|
-
@em.send(:is_regex?, string).should be_false
|
187
|
-
string = "fooz/"
|
188
|
-
@em.send(:is_regex?, string).should be_false
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe 'regex_matches?' do
|
193
|
-
it 'should return true if the given regular expression matches the given value' do
|
194
|
-
regex = "^\\d{2}$"
|
195
|
-
value = "12"
|
196
|
-
@em.send(:regex_matches?, regex, value).should be_true
|
197
|
-
end
|
198
|
-
it 'should return false if the giveb reular expression does not match the given value' do
|
199
|
-
regex = "^\\d{2}$"
|
200
|
-
value = "123"
|
201
|
-
@em.send(:regex_matches?, regex, value).should be_false
|
202
|
-
value = "foo"
|
203
|
-
@em.send(:regex_matches?, regex, value).should be_false
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
describe 'string_matches?' do
|
208
|
-
it 'should return true if the given string matches the given value' do
|
209
|
-
string = "bar"
|
210
|
-
value = "bar"
|
211
|
-
@em.send(:string_matches?, string, value).should be_true
|
212
|
-
end
|
213
|
-
it 'should return false if the given string does not match the given value' do
|
214
|
-
string = "bar"
|
215
|
-
value = "foo"
|
216
|
-
@em.send(:string_matches?, string, value).should be_false
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
describe 'valid_json?' do
|
221
|
-
it 'should return true if the given response body consists of valid JSON' do
|
222
|
-
validateable = { :foo => "bar" }.to_json
|
223
|
-
@em.send(:valid_json?, validateable).should be_true
|
224
|
-
end
|
225
|
-
it 'should return true if the given response body is nil' do
|
226
|
-
@em.send(:valid_json?, nil).should be_true
|
227
|
-
end
|
228
|
-
it 'should return false if the given response body consists of anything else but valid JSON' do
|
229
|
-
@em.send(:valid_json?, "foobar").should be_false
|
4
|
+
describe "initialize" do
|
5
|
+
it "should have a properly filled instance variable @excludes after instanciation" do
|
6
|
+
@e = ExpectationMatcher.new(["exclude1","exclude2","exclude3"])
|
7
|
+
@e.instance_variable_get(:@excludes).should be_a(Array)
|
8
|
+
@e.instance_variable_get(:@excludes).size.should == 3
|
9
|
+
@e.instance_variable_get(:@excludes)[0].should eql "exclude1"
|
10
|
+
end
|
11
|
+
it "should habe an empty array in @excludes if no excludes were given" do
|
12
|
+
@e = ExpectationMatcher.new()
|
13
|
+
@e.instance_variable_get(:@excludes).should be_a(Array)
|
14
|
+
@e.instance_variable_get(:@excludes).size.should == 0
|
15
|
+
end
|
16
|
+
end
|
17
|
+
describe "check" do
|
18
|
+
it "should invoke check at the given plugin" do
|
19
|
+
@e = ExpectationMatcher.new
|
20
|
+
@e.should_receive(:test_plugin).once.with({ :response => "1" }, { :testcase => "2" })
|
21
|
+
@e.check("TestPlugin", { :response => "1"}, { :testcase => "2" })
|
22
|
+
end
|
23
|
+
end
|
24
|
+
describe "self.initialize_plugins" do
|
25
|
+
it "should create private invocation methods for every plugin" do
|
26
|
+
pending "TODO"
|
27
|
+
ExpectationMatcher.should_receive(:available_plugins).and_return(["PluginNoOne", "PluginNoTwo", "PluginNoThree"])
|
28
|
+
@e = ExpectationMatcher.new
|
29
|
+
# FIXME private methods
|
30
|
+
@e.should respond_to(:plugin_no_one)
|
31
|
+
@e.should respond_to(:plugin_no_two)
|
32
|
+
@e.should respond_to(:plugin_no_three)
|
230
33
|
end
|
231
34
|
end
|
232
35
|
end
|
data/spec/http_client_spec.rb
CHANGED
@@ -2,46 +2,73 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe 'http_client' do
|
4
4
|
before(:each) do
|
5
|
-
@http_client = HttpClient.new
|
5
|
+
@http_client = HttpClient.new("http", "localhost", 3000, "namespace")
|
6
6
|
any_response = Struct.new(:code, :message, :headers, :body)
|
7
7
|
@response = any_response.new(:code => 200, :message => "Ok", :headers => {:foo => ["baz" => "bar"], :body => {:a => "b"}})
|
8
8
|
end
|
9
9
|
describe 'send_request' do
|
10
|
-
it 'should invoke a
|
11
|
-
@http_client.
|
12
|
-
@http_client.should_receive(:
|
13
|
-
@http_client.send_request(:put, "
|
14
|
-
|
15
|
-
|
16
|
-
@http_client.
|
17
|
-
@http_client.
|
10
|
+
it 'should invoke a PUT request in the underlying http class with the given method, uri and data' do
|
11
|
+
@http_client.stub(:build_response).and_return(@response)
|
12
|
+
@http_client.should_receive(:put).and_return(@response)
|
13
|
+
@http_client.send_request(:put, "/path/to/resource", nil, { :data => "2" }, { :params => "3" })
|
14
|
+
end
|
15
|
+
it 'should invoke a GET request in the underlying http class with the given method, uri and data' do
|
16
|
+
@http_client.stub(:build_response).and_return(@response)
|
17
|
+
@http_client.should_receive(:get).and_return(@response)
|
18
|
+
@http_client.send_request(:get, "/path/to/resource", nil, { :data => "2" }, { :params => "3" })
|
18
19
|
end
|
19
|
-
it 'should invoke
|
20
|
-
@http_client.
|
21
|
-
@http_client.
|
20
|
+
it 'should invoke a POST request in the underlying http class with the given method, uri and data' do
|
21
|
+
@http_client.stub(:build_response).and_return(@response)
|
22
|
+
@http_client.should_receive(:post).and_return(@response)
|
23
|
+
@http_client.send_request(:post, "/path/to/resource", nil, { :data => "2" }, { :params => "3" })
|
22
24
|
end
|
23
|
-
it 'should
|
24
|
-
|
25
|
-
@http_client.should_receive(:
|
26
|
-
@http_client.send_request(:
|
25
|
+
it 'should invoke a DELETE request in the underlying http class with the given method, uri and data' do
|
26
|
+
@http_client.stub(:build_response).and_return(@response)
|
27
|
+
@http_client.should_receive(:delete).and_return(@response)
|
28
|
+
@http_client.send_request(:delete, "/path/to/resource", nil, { :data => "2" }, { :params => "3" })
|
27
29
|
end
|
28
30
|
end
|
29
|
-
|
30
31
|
describe 'build_response' do
|
31
32
|
it 'should return a struct consisting of 4 symbols: :code, :message, :headers and :body with right types' do
|
32
33
|
raw_response_struct = Struct.new(:code, :message, :headers, :body)
|
33
34
|
response = raw_response_struct.new
|
34
|
-
|
35
35
|
response.code = 404
|
36
36
|
response.message = "Hi Duffy Duck"
|
37
|
-
response.headers = { :
|
37
|
+
response.headers = { :daisy => "duck" }
|
38
38
|
response.body = { :duffy => "duck" }
|
39
|
-
|
40
|
-
@http_client.send(:build_response, response).to_s.should eql response.to_s
|
41
39
|
@http_client.send(:build_response, response).code.should_not be_nil
|
42
40
|
@http_client.send(:build_response, response).message.should_not be_nil
|
43
|
-
@http_client.send(:build_response, response).body.
|
44
|
-
@http_client.send(:build_response, response).headers.
|
41
|
+
@http_client.send(:build_response, response).body.should == {:duffy => "duck"}
|
42
|
+
@http_client.send(:build_response, response).headers.should == {"daisy" => "duck"}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
describe "resource_path" do
|
46
|
+
it "should return a resource path extended by the namespace if one is set" do
|
47
|
+
@http_client.send(:resource_path, "/users/duffyduck").match(@http_client.instance_variable_get(:@namespace)).should_not be_nil
|
48
|
+
end
|
49
|
+
it "should return a correct resource path even if no namespace is set" do
|
50
|
+
@http_client.instance_variable_set(:@namespace, nil)
|
51
|
+
@http_client.send(:resource_path, "/users/duffyduck").match(/\/users\/duffyduck/).should_not be_nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
describe "build_uri" do
|
55
|
+
it "should return a correct uri from the given parameters" do
|
56
|
+
@http_client.send(:build_uri,"/users/duffyduck").should_not be_nil
|
57
|
+
@http_client.send(:build_uri,"/users/duffyduck").to_s.match(@http_client.instance_variable_get(:@protocol)).should_not be_nil
|
58
|
+
@http_client.send(:build_uri,"/users/duffyduck").to_s.match(@http_client.instance_variable_get(:@host)).should_not be_nil
|
59
|
+
@http_client.send(:build_uri,"/users/duffyduck").to_s.match(@http_client.instance_variable_get(:@port).to_s).should_not be_nil
|
60
|
+
@http_client.send(:build_uri,"/users/duffyduck").to_s.match(@http_client.instance_variable_get(:@namespace)).should_not be_nil
|
61
|
+
end
|
62
|
+
it "should only include a port in uri if a port was specified or port was set to 80" do
|
63
|
+
@http_client.instance_variable_set(:@port, nil)
|
64
|
+
@http_client.send(:build_uri,"/users/duffyduck").to_s.match("80").should be_nil
|
65
|
+
@http_client.instance_variable_set(:@port, 80)
|
66
|
+
@http_client.send(:build_uri,"/users/duffyduck").to_s.match("80").should be_nil
|
67
|
+
end
|
68
|
+
it "should add given GET parameters in correct notation" do
|
69
|
+
@http_client.send(:build_uri,"/users/duffyduck", {:param1 => "1", :param2 => "a"}).to_s.match(/\?param/).should_not be_nil
|
70
|
+
@http_client.send(:build_uri,"/users/duffyduck", {:param1 => "1", :param2 => "a"}).to_s.match(/param1=1/).should_not be_nil
|
71
|
+
@http_client.send(:build_uri,"/users/duffyduck", {:param1 => "1", :param2 => "a"}).to_s.match(/param2=a/).should_not be_nil
|
45
72
|
end
|
46
73
|
end
|
47
74
|
end
|
data/spec/result_spec.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "result" do
|
4
|
+
before(:all) do
|
5
|
+
@r = Result.new({ :name => "testcase_name" }, {})
|
6
|
+
end
|
7
|
+
describe "verbose_on_error" do
|
8
|
+
it "should invoke be_verbose if an error occured" do
|
9
|
+
@r.instance_variable_set(:@succeeded, false)
|
10
|
+
@r.should_receive(:be_verbose).once
|
11
|
+
@r.send(:verbose_on_error, 1)
|
12
|
+
end
|
13
|
+
it "should not invoke be_verbose if no error occured" do
|
14
|
+
@r.instance_variable_set(:@succeeded, true)
|
15
|
+
@r.should_receive(:be_verbose).exactly(0).times
|
16
|
+
@r.send(:verbose_on_error, 1)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
describe "verbose_on_success" do
|
20
|
+
it "should invoke be_verbose in case of an error" do
|
21
|
+
@r.instance_variable_set(:@succeeded, false)
|
22
|
+
@r.should_receive(:be_verbose).once
|
23
|
+
@r.send(:verbose_on_success, 1)
|
24
|
+
end
|
25
|
+
it "should invoke be_verbose in case of no error too" do
|
26
|
+
@r.instance_variable_set(:@succeeded, true)
|
27
|
+
@r.should_receive(:be_verbose).once
|
28
|
+
@r.send(:verbose_on_success, 1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
describe "verbose_with_curl" do
|
32
|
+
it "should invoke be_verbose in case of an error" do
|
33
|
+
@r.instance_variable_set(:@succeeded, false)
|
34
|
+
@r.should_receive(:be_verbose).once
|
35
|
+
@r.send(:verbose_with_curl, 1)
|
36
|
+
end
|
37
|
+
it "should invoke be_verbose in case of no error too" do
|
38
|
+
@r.instance_variable_set(:@succeeded, true)
|
39
|
+
@r.should_receive(:be_verbose).once
|
40
|
+
@r.send(:verbose_with_curl, 1)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 6
|
9
|
+
version: 0.3.6
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- jan@moviepilot.com
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-12 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -234,7 +234,6 @@ files:
|
|
234
234
|
- lib/apirunner.rb
|
235
235
|
- lib/apirunner/railtie.rb
|
236
236
|
- lib/checker.rb
|
237
|
-
- lib/core_extensions.rb
|
238
237
|
- lib/expectation_matcher.rb
|
239
238
|
- lib/http_client.rb
|
240
239
|
- lib/plugins/plug01_response_json_syntax_checker.rb
|
@@ -242,12 +241,16 @@ files:
|
|
242
241
|
- lib/plugins/plug03_response_header_checker.rb
|
243
242
|
- lib/plugins/plug04_response_body_checker.rb
|
244
243
|
- lib/result.rb
|
244
|
+
- lib/string_ext.rb
|
245
245
|
- lib/tasks/api.rake
|
246
246
|
- lib/testcase.rb
|
247
247
|
- spec/.rspec
|
248
|
+
- spec/api_configuration_spec.rb
|
248
249
|
- spec/api_runner_spec.rb
|
250
|
+
- spec/checker_spec.rb
|
249
251
|
- spec/expectation_matcher_spec.rb
|
250
252
|
- spec/http_client_spec.rb
|
253
|
+
- spec/result_spec.rb
|
251
254
|
- spec/spec_helper.rb
|
252
255
|
has_rdoc: true
|
253
256
|
homepage: http://github.com/moviepilot/apirunner
|
@@ -263,7 +266,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
263
266
|
requirements:
|
264
267
|
- - ">="
|
265
268
|
- !ruby/object:Gem::Version
|
266
|
-
hash:
|
269
|
+
hash: 2715016286846955498
|
267
270
|
segments:
|
268
271
|
- 0
|
269
272
|
version: "0"
|
@@ -283,7 +286,10 @@ signing_key:
|
|
283
286
|
specification_version: 3
|
284
287
|
summary: one-line summary of your gem
|
285
288
|
test_files:
|
289
|
+
- spec/api_configuration_spec.rb
|
286
290
|
- spec/api_runner_spec.rb
|
291
|
+
- spec/checker_spec.rb
|
287
292
|
- spec/expectation_matcher_spec.rb
|
288
293
|
- spec/http_client_spec.rb
|
294
|
+
- spec/result_spec.rb
|
289
295
|
- spec/spec_helper.rb
|
data/lib/core_extensions.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module CoreExtensions
|
2
|
-
class String
|
3
|
-
# generates filenames from classnames the rails way
|
4
|
-
def underscore(string)
|
5
|
-
string.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
|
6
|
-
end
|
7
|
-
|
8
|
-
# opposites underscore defined above
|
9
|
-
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
10
|
-
if first_letter_in_uppercase
|
11
|
-
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
12
|
-
else
|
13
|
-
lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|