apirunner 0.3.5 → 0.3.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/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
|