apirunner 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -9,6 +9,7 @@ source "http://rubygems.org"
9
9
  gem 'nokogiri', '~> 1.4.3.1'
10
10
  gem 'json'
11
11
 
12
+
12
13
  group :development do
13
14
  gem "rspec", ">= 2.0.0.beta.19"
14
15
  gem "cucumber", ">= 0"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
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.4.1"
8
+ s.version = "0.4.2"
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-20}
12
+ s.date = %q{2010-10-25}
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,6 +45,7 @@ Gem::Specification.new do |s|
45
45
  "lib/apirunner.rb",
46
46
  "lib/apirunner/railtie.rb",
47
47
  "lib/checker.rb",
48
+ "lib/csv_writer.rb",
48
49
  "lib/expectation_matcher.rb",
49
50
  "lib/http_client.rb",
50
51
  "lib/plugins/plug01_response_json_syntax_checker.rb",
@@ -64,7 +65,8 @@ Gem::Specification.new do |s|
64
65
  "spec/http_client_spec.rb",
65
66
  "spec/response_body_checker_spec.rb",
66
67
  "spec/result_spec.rb",
67
- "spec/spec_helper.rb"
68
+ "spec/spec_helper.rb",
69
+ "spec/testcase_spec.rb"
68
70
  ]
69
71
  s.homepage = %q{http://github.com/moviepilot/apirunner}
70
72
  s.require_paths = ["lib"]
@@ -78,7 +80,8 @@ Gem::Specification.new do |s|
78
80
  "spec/http_client_spec.rb",
79
81
  "spec/response_body_checker_spec.rb",
80
82
  "spec/result_spec.rb",
81
- "spec/spec_helper.rb"
83
+ "spec/spec_helper.rb",
84
+ "spec/testcase_spec.rb"
82
85
  ]
83
86
 
84
87
  if s.respond_to? :specification_version then
@@ -1,6 +1,6 @@
1
1
  class ApiConfiguration
2
2
 
3
- attr_accessor :protocol, :host, :namespace, :port, :verbosity, :priority, :substitution
3
+ attr_accessor :protocol, :host, :namespace, :port, :verbosity, :priority, :substitution, :csv_mode
4
4
 
5
5
  # initializes a configuration object from given YAML file for given environment
6
6
  def initialize(raw_config, env)
@@ -8,6 +8,7 @@ class ApiConfiguration
8
8
  self.verbosity = raw_config['general']['verbosity'].first
9
9
  self.priority = raw_config['general']['priority'] || 0
10
10
  self.substitution = raw_config['general']['substitution']
11
+ self.csv_mode = raw_config['general']['csv_mode'].first rescue "none"
11
12
  self
12
13
  end
13
14
  end
data/lib/api_runner.rb CHANGED
@@ -1,16 +1,17 @@
1
1
  class ApiRunner
2
2
  require 'yaml'
3
+ require 'csv_writer'
3
4
  require 'string_ext' if not String.respond_to?(:underscore)
4
5
  require 'expectation_matcher'
5
6
  require 'http_client'
6
7
  require 'api_configuration'
7
8
  require 'testcase'
8
- require 'string_ext'
9
9
  require 'json'
10
10
 
11
11
  CONFIG_FILE = "config/api_runner.yml"
12
12
  SPEC_PATH = "test/api_runner/"
13
13
  EXCLUDES_FILE = "test/api_runner/excludes.yml"
14
+ CSV_PATH = "tmp"
14
15
 
15
16
  # initializes the object, loads environment, build base_uri
16
17
  def initialize(env, performance=nil)
@@ -23,12 +24,14 @@ class ApiRunner
23
24
  load_url_spec
24
25
  @http_client = HttpClient.new(@configuration.protocol, @configuration.host, @configuration.port, @configuration.namespace)
25
26
  @expectation = ExpectationMatcher.new(@excludes)
27
+ @csv_writer = CsvWriter.new(self.class.csv_path, env)
26
28
  end
27
29
 
28
30
  # checks servers availability and invokes test cases
29
31
  def run
30
32
  if server_is_available?
31
33
  run_tests
34
+ @csv_writer.write(@configuration.csv_mode, @results) unless @results.empty?
32
35
  @results.each_with_index do |result, index|
33
36
  result.honk_in(@configuration.verbosity, index)
34
37
  end unless @results.empty?
@@ -37,7 +40,7 @@ class ApiRunner
37
40
  end
38
41
  error_count = @results.select{ |r| !r.succeeded }.count
39
42
  puts "\n\nResults: I greatfully ran #{ @spec.size } test(s), \033[32m#{ @spec.size - error_count }\033[0m succeeded, \033[31m#{ error_count }\033[0m failed."
40
- exit(error_count)
43
+ return (error_count)
41
44
  end
42
45
 
43
46
  protected
@@ -87,63 +90,7 @@ class ApiRunner
87
90
  Dir.new(path).entries.sort.each do |dir_entry|
88
91
  specs.push *YAML.load_file(path+dir_entry) if not (File.directory? dir_entry or dir_entry.match(/^\./) or dir_entry.match(/excludes/))
89
92
  end
90
- @spec = objectize(priorize(partition(explode_iterations(specs))))
91
- end
92
-
93
- # explodes specs that include iterations and interpolates the iteration variable into all occuring @@ placeholders
94
- def explode_iterations(specs)
95
- return specs unless specs.detect{ |s| s['iterations']}
96
- exploded_specs = []
97
- specs.each do |spec|
98
- if spec['iterations'].nil?
99
- exploded_specs << spec
100
- else
101
- 1.upto(spec['iterations'].to_i) do |i|
102
- exploded_specs << JSON.parse(spec.to_json.gsub(/@@/, "%07d" % i.to_s))
103
- end
104
- end
105
- end
106
- return exploded_specs
107
- end
108
-
109
- # converts the given array of raw testcases to an array of testcase objects
110
- def objectize(raw_specs)
111
- specs = []
112
- raw_specs.each do |spec|
113
- specs << Testcase.new(spec, @configuration.substitution)
114
- end
115
- specs
116
- end
117
-
118
- # returns only spec whose priority level is less or equals configures priority level
119
- # if no priority level is configured for the api runner, 0 is assumed
120
- # if no priority level ist configured for a story, 0 is assumed
121
- def priorize(specs)
122
- relevant_specs = []
123
- specs.each do |spec|
124
- relevant_specs << spec if spec['priority'].nil? or spec['priority'].to_i <= @configuration.priority.to_i
125
- end
126
- relevant_specs
127
- end
128
-
129
- # partitions the spec if keywords like 'focus', 'until' or 'from exist'
130
- # and returns the relevant subset of specs that have to be tested then
131
- def partition(specs)
132
- relevant_specs = []
133
- specs.each do |spec|
134
- if spec['focus']
135
- relevant_specs << spec
136
- break
137
- elsif spec['until']
138
- relevant_specs = specs[0..specs.index(spec)]
139
- break
140
- elsif spec['from']
141
- relevant_specs = specs[specs.index(spec)..specs.size+1]
142
- break
143
- end
144
- end
145
- relevant_specs = specs if relevant_specs.empty?
146
- relevant_specs
93
+ @spec = Testcase.expand_specs(specs, @configuration)
147
94
  end
148
95
 
149
96
  # loads and parses items that need to be excluded from the checks in certain environments
@@ -166,4 +113,9 @@ class ApiRunner
166
113
  def self.excludes_file
167
114
  EXCLUDES_FILE
168
115
  end
116
+
117
+ # returns csv file path that can be stubbed
118
+ def self.csv_path
119
+ CSV_PATH
120
+ end
169
121
  end
data/lib/csv_writer.rb ADDED
@@ -0,0 +1,80 @@
1
+ class CsvWriter
2
+ require 'csv'
3
+
4
+ def initialize(path, env)
5
+ @file = qualified_csv_path(path, env)
6
+ end
7
+
8
+ # dispatches the configured CSV create style to the matching method
9
+ def write(method, data)
10
+ self.send(method.to_sym, convert_to_hash_array(data))
11
+ end
12
+
13
+ protected
14
+
15
+ def qualified_csv_path(path, env)
16
+ return path + "/" + "api_performance_report_#{env}.csv"
17
+ end
18
+
19
+ # appends given data to an existing CSV file
20
+ # if new testcases come in, their data is appended to the right of the csv
21
+ # if one or more testcases are missing but were known before, the structure of the csv stays clean
22
+ # and empty entries are made for these cases
23
+ # to be refactored!
24
+ def append(data)
25
+ STDERR.puts("appending #{data} to file #{@file}")
26
+ begin
27
+ # convert old data to array
28
+ old_data_array = CSV.read(@file, headers: true, header_converters: :symbol).to_a
29
+
30
+ # extend the headers by the ones for new testcases
31
+ data.each do |result|
32
+ old_data_array[0] << result[:identifier] if not old_data_array[0].include?(result[:identifier].to_sym)
33
+ end unless data.empty?
34
+
35
+ # create the new line column by column in the right order
36
+ line = []
37
+ old_data_array[0].each do |header|
38
+ line << (data.detect{ |field| field[:identifier] == header.to_s }[:runtime] rescue nil)
39
+ end unless old_data_array[0].empty?
40
+
41
+ # append the new line of data to existing data
42
+ old_data_array << line
43
+
44
+ # write the CSV
45
+ file = File.open(@file, "w")
46
+ CSV(file, col_sep: ",") do |csv|
47
+ old_data_array.each do |line|
48
+ csv << line
49
+ end
50
+ end
51
+ file.close
52
+ rescue
53
+ create(data)
54
+ end
55
+ end
56
+
57
+ # recreates the CSV file and writes the data to it
58
+ def create(data)
59
+ file = File.open(@file, "w")
60
+ CSV(file, col_sep: ",") do |csv|
61
+ csv << data.map{ |test| test[:identifier] }
62
+ csv << data.map{ |test| test[:runtime] }
63
+ end
64
+ file.close
65
+ end
66
+
67
+ # does not write any data ... for convenience only
68
+ def none(data)
69
+ end
70
+
71
+ # converts array of testcases into array of hashes containing only identifier and runtime of the testcases
72
+ def convert_to_hash_array(data)
73
+ hash_array = []
74
+ data.each do |result|
75
+ hash_array << { :identifier => result.testcase.unique_identifier, :runtime => result.response.runtime.round(3) }
76
+ end
77
+ return hash_array
78
+ end
79
+
80
+ end
data/lib/result.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  class Result
2
2
 
3
- attr_accessor :succeeded
4
- attr_accessor :error_message
3
+ attr_accessor :succeeded, :error_message, :testcase, :response
5
4
 
6
5
  def initialize(testcase, response)
7
6
  @succeeded = true
@@ -47,7 +46,7 @@ class Result
47
46
 
48
47
  # yields the verbose error messages
49
48
  def be_verbose(index)
50
- puts "\n#{result_case} (#{index+1})- \"#{@testcase.name}\""
49
+ puts "\n#{result_case} (#{index+1})- #{@testcase.unique_identifier} - \"#{@testcase.name}\""
51
50
  puts @error_message
52
51
  puts("Request runtime: #{@response.runtime}")
53
52
  puts(" More more more verbosity\n")
data/lib/testcase.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  class Testcase
2
+ require 'digest/md5'
2
3
 
3
4
  attr_reader :raw, :name, :request, :response_expectation, :wait_before_request
5
+ @@configuration ||= nil
4
6
 
5
7
  def initialize(raw, substitution)
6
8
  @raw = raw
@@ -11,7 +13,75 @@ class Testcase
11
13
  create_resource_substitutes(substitution)
12
14
  end
13
15
 
16
+ # creates an array of spec hashes by calling priorize, partition and explode_iterations
17
+ # to prepare the specs, automagically create the ierting ones and partition them
18
+ def self.expand_specs(specs, configuration)
19
+ @@configuration = configuration
20
+ objectize(partition(explode_iterations(priorize(specs))))
21
+ end
22
+
23
+ # returns an identifier of that testcase that should be unique
24
+ def unique_identifier
25
+ Digest::MD5.hexdigest(@name.to_s)[0..9]
26
+ end
27
+
14
28
  private
29
+ # explodes specs that include iterations and interpolates the iteration variable into all occuring @@ placeholders
30
+ def self.explode_iterations(specs)
31
+ return specs unless specs.detect{ |s| s['iterations']}
32
+ exploded_specs = []
33
+ specs.each do |spec|
34
+ if spec['iterations'].nil?
35
+ exploded_specs << spec
36
+ else
37
+ 1.upto(spec['iterations'].to_i) do |i|
38
+ exploded_specs << JSON.parse(spec.to_json.gsub(/@@/, "%07d" % i.to_s))
39
+ end
40
+ end
41
+ end
42
+ return exploded_specs
43
+ end
44
+
45
+ # converts the given array of raw testcases to an array of testcase objects
46
+ def self.objectize(raw_specs)
47
+ specs = []
48
+ raw_specs.each do |spec|
49
+ specs << self.new(spec, @@configuration.substitution)
50
+ end
51
+ specs
52
+ end
53
+
54
+ # returns only spec whose priority level is less or equals configures priority level
55
+ # if no priority level is configured for the api runner, 0 is assumed
56
+ # if no priority level ist configured for a story, 0 is assumed
57
+ def self.priorize(specs)
58
+ relevant_specs = []
59
+ specs.each do |spec|
60
+ relevant_specs << spec if spec['priority'].nil? or spec['priority'].to_i <= @@configuration.priority.to_i
61
+ end
62
+ relevant_specs
63
+ end
64
+
65
+ # partitions the spec if keywords like 'focus', 'until' or 'from exist'
66
+ # and returns the relevant subset of specs that have to be tested then
67
+ def self.partition(specs)
68
+ relevant_specs = []
69
+ specs.each do |spec|
70
+ if spec['focus']
71
+ relevant_specs << spec
72
+ break
73
+ elsif spec['until']
74
+ relevant_specs = specs[0..specs.index(spec)]
75
+ break
76
+ elsif spec['from']
77
+ relevant_specs = specs[specs.index(spec)..specs.size+1]
78
+ break
79
+ end
80
+ end
81
+ relevant_specs = specs if relevant_specs.empty?
82
+ relevant_specs
83
+ end
84
+
15
85
  # substitutes rersource names cause of race conditions in multiple system scenarios
16
86
  def create_resource_substitutes(substitution)
17
87
  substitution['substitutes'].each do |substitute|
@@ -74,17 +74,4 @@ describe 'apirunner' do
74
74
  it 'should return true if the requested server is available'
75
75
  it 'should return false if the given server is not available'
76
76
  end
77
-
78
- describe 'explode_iterations' do
79
- it 'should explode iterations if iterations is set to a proper value' do
80
- yaml_fixture = [{"name"=>"Create new User", "iterations" => "10", "request"=>{"headers"=>{"Content-Type"=>"application/json"}, "path"=>"/users/duffyduck@@", "method"=>"PUT", "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "expires_at"=>"2011-09-10 00:41:50 +0200"}}, "response_expectation"=>{"status_code"=>201, "headers"=>{"Last-Modified"=>"/.*/"}, "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "fsk"=>"18"}}}]
81
- @a.send(:explode_iterations,yaml_fixture).size.should == 10
82
- @a.send(:explode_iterations,yaml_fixture).map{ |x| x['request']['path']}.sort.should == ["/users/duffyduck0000001","/users/duffyduck0000002","/users/duffyduck0000003","/users/duffyduck0000004","/users/duffyduck0000005","/users/duffyduck0000006","/users/duffyduck0000007","/users/duffyduck0000008","/users/duffyduck0000009","/users/duffyduck0000010",]
83
- end
84
- it 'should not explode iterations if iterations is not set' do
85
- yaml_fixture = [{"name"=>"Create new User", "request"=>{"headers"=>{"Content-Type"=>"application/json"}, "path"=>"/users/duffyduck@@", "method"=>"PUT", "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "expires_at"=>"2011-09-10 00:41:50 +0200"}}, "response_expectation"=>{"status_code"=>201, "headers"=>{"Last-Modified"=>"/.*/"}, "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "fsk"=>"18"}}}]
86
- @a.send(:explode_iterations, yaml_fixture).size.should == 1
87
- @a.send(:explode_iterations, yaml_fixture).should eql yaml_fixture
88
- end
89
- end
90
77
  end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'testcase' do
4
+ describe 'explode_iterations' do
5
+ it 'should explode iterations if iterations is set to a proper value' do
6
+ yaml_fixture = [{"name"=>"Create new User", "iterations" => "10", "request"=>{"headers"=>{"Content-Type"=>"application/json"}, "path"=>"/users/duffyduck@@", "method"=>"PUT", "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "expires_at"=>"2011-09-10 00:41:50 +0200"}}, "response_expectation"=>{"status_code"=>201, "headers"=>{"Last-Modified"=>"/.*/"}, "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "fsk"=>"18"}}}]
7
+ Testcase.send(:explode_iterations,yaml_fixture).size.should == 10
8
+ Testcase.send(:explode_iterations,yaml_fixture).map{ |x| x['request']['path']}.sort.should == ["/users/duffyduck0000001","/users/duffyduck0000002","/users/duffyduck0000003","/users/duffyduck0000004","/users/duffyduck0000005","/users/duffyduck0000006","/users/duffyduck0000007","/users/duffyduck0000008","/users/duffyduck0000009","/users/duffyduck0000010",]
9
+ end
10
+ it 'should not explode iterations if iterations is not set' do
11
+ yaml_fixture = [{"name"=>"Create new User", "request"=>{"headers"=>{"Content-Type"=>"application/json"}, "path"=>"/users/duffyduck@@", "method"=>"PUT", "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "expires_at"=>"2011-09-10 00:41:50 +0200"}}, "response_expectation"=>{"status_code"=>201, "headers"=>{"Last-Modified"=>"/.*/"}, "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "fsk"=>"18"}}}]
12
+ Testcase.send(:explode_iterations, yaml_fixture).size.should == 1
13
+ Testcase.send(:explode_iterations, yaml_fixture).should eql yaml_fixture
14
+ end
15
+ end
16
+ describe 'unique_identifier' do
17
+ before(:each) do
18
+ @testcase_hash = {"name"=>"Create new User", "request"=>{"headers"=>{"Content-Type"=>"application/json"}, "path"=>"/users/duffyduck@@", "method"=>"PUT", "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "expires_at"=>"2011-09-10 00:41:50 +0200"}}, "response_expectation"=>{"status_code"=>201, "headers"=>{"Last-Modified"=>"/.*/"}, "body"=>{"username"=>"duffyduck", "watchlist"=>["m1035", "m2087"], "blacklist"=>["m1554", "m2981"], "skiplist"=>["m1590", "m1056"], "ratings"=>{"m12493"=>4.0, "m1875"=>2.5, "m7258"=>3.0, "m7339"=>4.0, "m3642"=>5.0}, "fsk"=>"18"}}}
19
+ end
20
+ it 'should create a certian md5 hash for a certain testcase' do
21
+ t = Testcase.new(@testcase_hash, nil)
22
+ t.unique_identifier.should == "eb46f75b6a"
23
+ end
24
+ it 'should create a different md5 hash for a the same testcase with minimum changes' do
25
+ testcase_hash2 = @testcase_hash.merge({"name" => "Create new User with different hash this time"})
26
+ t = Testcase.new(testcase_hash2, nil)
27
+ t.unique_identifier.should_not == "eb46f75b6a"
28
+ end
29
+ it 'should return a string with length 10' do
30
+ t = Testcase.new(@testcase_hash, nil)
31
+ t.unique_identifier.should be_a(String)
32
+ t.unique_identifier.length.should == 10
33
+ end
34
+ end
35
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 4
8
- - 1
9
- version: 0.4.1
8
+ - 2
9
+ version: 0.4.2
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-20 00:00:00 +02:00
17
+ date: 2010-10-25 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -247,6 +247,7 @@ files:
247
247
  - lib/apirunner.rb
248
248
  - lib/apirunner/railtie.rb
249
249
  - lib/checker.rb
250
+ - lib/csv_writer.rb
250
251
  - lib/expectation_matcher.rb
251
252
  - lib/http_client.rb
252
253
  - lib/plugins/plug01_response_json_syntax_checker.rb
@@ -267,6 +268,7 @@ files:
267
268
  - spec/response_body_checker_spec.rb
268
269
  - spec/result_spec.rb
269
270
  - spec/spec_helper.rb
271
+ - spec/testcase_spec.rb
270
272
  has_rdoc: true
271
273
  homepage: http://github.com/moviepilot/apirunner
272
274
  licenses: []
@@ -281,7 +283,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
281
283
  requirements:
282
284
  - - ">="
283
285
  - !ruby/object:Gem::Version
284
- hash: 2852718756556817364
286
+ hash: -952737511013591802
285
287
  segments:
286
288
  - 0
287
289
  version: "0"
@@ -309,3 +311,4 @@ test_files:
309
311
  - spec/response_body_checker_spec.rb
310
312
  - spec/result_spec.rb
311
313
  - spec/spec_helper.rb
314
+ - spec/testcase_spec.rb