mirage 1.3.6 → 2.0.0.alpha1

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.
Files changed (36) hide show
  1. data/Gemfile +7 -4
  2. data/VERSION +1 -1
  3. data/bin/mirage +2 -0
  4. data/features/client/clear.feature +38 -20
  5. data/features/client/peek.feature +11 -11
  6. data/features/client/save_and_revert.feature +14 -8
  7. data/features/client/set.feature +59 -13
  8. data/features/client/track.feature +5 -3
  9. data/features/server/clear.feature +59 -47
  10. data/features/server/logging.feature +2 -3
  11. data/features/server/peek.feature +12 -10
  12. data/features/server/prime.feature +15 -13
  13. data/features/server/response_templates.feature +9 -16
  14. data/features/server/save_and_revert.feature +11 -14
  15. data/features/server/set.feature +44 -17
  16. data/features/server/set_default_response.feature +19 -25
  17. data/features/server/set_with_a_delay.feature +3 -5
  18. data/features/server/set_with_a_pattern.feature +24 -29
  19. data/features/server/track_requests.feature +71 -0
  20. data/features/server/web_user_interface.feature +7 -8
  21. data/features/step_definitions/my_steps.rb +83 -28
  22. data/features/support/env.rb +0 -14
  23. data/lib/mirage.rb +3 -0
  24. data/lib/mirage/client.rb +48 -43
  25. data/lib/mirage/core.rb +65 -152
  26. data/lib/mirage/mock_response.rb +49 -0
  27. data/lib/mirage/mock_responses_collection.rb +109 -0
  28. data/lib/mirage/object.rb +5 -0
  29. data/lib/mirage/web.rb +37 -28
  30. data/lib/start_mirage.rb +27 -5
  31. data/lib/{view/mirage/index.xhtml → views/index.erb} +5 -5
  32. data/mirage.gemspec +7 -7
  33. metadata +57 -23
  34. data/features/client/get.feature +0 -46
  35. data/features/server/file_responses.feature +0 -8
  36. data/features/server/track.feature +0 -74
@@ -0,0 +1,49 @@
1
+ module Mirage
2
+ class MockResponse
3
+ @@id_count = 0
4
+ attr_reader :response_id, :delay, :name, :pattern, :http_method, :content_type
5
+ attr_accessor :response_id
6
+
7
+ def initialize name, value, content_type, http_method, pattern=nil, delay=0, default=false, file=false
8
+ @name, @value,@content_type, @http_method, @pattern, @response_id, @delay, @default, @file = name, value, content_type, http_method, pattern, @@id_count+=1, delay, default, file
9
+ end
10
+
11
+ def self.reset_count
12
+ @@id_count = 0
13
+ end
14
+
15
+ def default?
16
+ 'true' == @default
17
+ end
18
+
19
+ def file?
20
+ @file == 'true'
21
+ end
22
+
23
+
24
+ def value(body='', request_parameters={}, query_string='')
25
+ return @value if file?
26
+
27
+ value = @value
28
+ value.scan(/\$\{([^\}]*)\}/).flatten.each do |pattern|
29
+
30
+ if (parameter_match = request_parameters[pattern])
31
+ value = value.gsub("${#{pattern}}", parameter_match)
32
+ end
33
+
34
+ [body, query_string].each do |string|
35
+ if (string_match = find_match(string, pattern))
36
+ value = value.gsub("${#{pattern}}", string_match)
37
+ end
38
+ end
39
+
40
+ end
41
+ value
42
+ end
43
+
44
+ private
45
+ def find_match(string, regex)
46
+ string.scan(/#{regex}/).flatten.first
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,109 @@
1
+ module Mirage
2
+ class MockResponsesCollection
3
+ def initialize
4
+ @snapshot, @responses = {}, {}
5
+ end
6
+
7
+ def << response
8
+
9
+
10
+ stored_responses = @responses[response.name]||={}
11
+
12
+ stored_responses[response.pattern] ||= {}
13
+ old_response = stored_responses[response.pattern].delete(response.http_method)
14
+ stored_responses[response.pattern][response.http_method] = response
15
+
16
+
17
+ # Right not an the main id count goes up by one even if the id is not used because the old id is reused from another response
18
+ response.response_id = old_response.response_id if old_response
19
+ response.response_id.to_s
20
+
21
+ end
22
+
23
+ def get_response name, http_method, body, query_string
24
+ stored_responses = @responses[name]
25
+ record = nil
26
+
27
+ record = find_response(body, query_string, stored_responses, http_method) if stored_responses
28
+
29
+
30
+ unless record
31
+ default_responses, record = find_default_responses(name), nil
32
+
33
+ until record || default_responses.empty?
34
+ record = find_response(body, query_string, default_responses.delete_at(0), http_method)
35
+ if record
36
+ record = record.default? ? record : nil
37
+ end
38
+
39
+ end
40
+ end
41
+
42
+ record
43
+ end
44
+
45
+ def find id
46
+ @responses.values.each do |response_sets|
47
+ response_sets.values.each do |response_set|
48
+ response_set.values.each do |response|
49
+ return response if response.response_id == id
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ def delete(response_id)
56
+ @responses.values.each do |response_sets|
57
+ response_sets.values.each do |response_set|
58
+ response_set.each do |method, response|
59
+ response_set.delete(method) if response.response_id == response_id
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def clear
66
+ @responses.clear
67
+ end
68
+
69
+ def backup
70
+ @snapshot.clear and @snapshot.replace(@responses.deep_clone)
71
+ end
72
+
73
+ def revert
74
+ @responses.clear and @responses.replace(@snapshot.deep_clone)
75
+ end
76
+
77
+ def all
78
+ responses = []
79
+ @responses.values.each do |response_sets|
80
+ response_sets.each do |pattern, response_set|
81
+ response_set.values.each do |response|
82
+ responses << response
83
+ end
84
+ end
85
+ end
86
+ responses
87
+ end
88
+
89
+ private
90
+ def find_response(body, query_string, stored_responses, http_method)
91
+ pattern_match = stored_responses.keys.find_all { |pattern| pattern != :basic }.find { |pattern| (body =~ pattern || query_string =~ pattern) }
92
+
93
+ if pattern_match
94
+ record = stored_responses[pattern_match][http_method]
95
+ else
96
+ record = stored_responses[:basic]
97
+ record = record[http_method] if record
98
+ end
99
+ record
100
+ end
101
+
102
+ def find_default_responses(name)
103
+ matches = @responses.keys.find_all { |key| name.index(key) == 0 }.sort { |a, b| b.length <=> a.length }
104
+ matches.collect { |key| @responses[key] }
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,5 @@
1
+ class Object
2
+ def deep_clone
3
+ Marshal.load(Marshal.dump(self))
4
+ end
5
+ end
@@ -1,6 +1,9 @@
1
+ require 'net/http'
2
+ require 'uri'
1
3
  module Mirage
2
4
  module Web
3
5
  class FileResponse
6
+ attr_reader :response
4
7
  def initialize response
5
8
  @response = response
6
9
  end
@@ -10,40 +13,46 @@ module Mirage
10
13
  end
11
14
  end
12
15
 
13
- def http_get url, params={}
14
- using_mechanize do |browser|
15
- params[:body] ? browser.put(url, params[:body]) : browser.get(url, params)
16
- end
17
- end
16
+ def put url, entity, headers={}
17
+ uri = URI.parse(url)
18
+ request = Net::HTTP::Put.new(uri.request_uri)
18
19
 
19
- def http_post url, params={}
20
- using_mechanize do |browser|
21
- browser.post(url, params)
20
+ if entity.is_a? File
21
+ request.body_stream=entity
22
+ request.content_length=entity.lstat.size
23
+ else
24
+ request.body=entity
22
25
  end
26
+ headers.each { |field, value| request.add_field(field, value) }
27
+
28
+ Net::HTTP.new(uri.host, uri.port).request(request)
23
29
  end
24
30
 
25
- private
26
- def using_mechanize
27
- begin
28
- browser = Mechanize.new
29
- browser.keep_alive = false
30
- response = yield browser
31
-
32
- def response.code
33
- @code.to_i
34
- end
35
- rescue Exception => e
36
- response = e
31
+ def get url, params={}, headers={}
32
+ uri = URI.parse(url)
33
+ request = Net::HTTP::Get.new(uri.request_uri)
34
+ request.set_form_data params
35
+ headers.each { |field, value| request.add_field(field, value) }
36
+ Net::HTTP.new(uri.host, uri.port).request(request)
37
+ end
37
38
 
38
- def response.code
39
- self.response_code.to_i
40
- end
39
+ def post url, params={}, headers={}
40
+ uri = URI.parse(url)
41
+ request = Net::HTTP::Post.new(uri.request_uri)
42
+
43
+ params.is_a?(Hash) ? request.set_form_data(params) : request.body = params
44
+
45
+ headers.each { |field, value| request.add_field(field, value) }
46
+ Net::HTTP.new(uri.host, uri.port).request(request)
47
+ end
41
48
 
42
- def response.body
43
- ""
44
- end
45
- end
46
- response
49
+ def delete url, params={}, headers={}
50
+ uri = URI.parse(url)
51
+ request = Net::HTTP::Delete.new(uri.request_uri)
52
+ params.is_a?(Hash) ? request.set_form_data(params) : request.body = params
53
+ headers.each { |field, value| request.add_field(field, value) }
54
+ Net::HTTP.new(uri.host, uri.port).request(request)
47
55
  end
56
+
48
57
  end
49
58
  end
@@ -1,16 +1,38 @@
1
1
  require 'rubygems'
2
+
2
3
  $0='Mirage Server'
3
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+
6
+ require 'sinatra'
7
+ require 'sinatra/base'
8
+ require 'sinatra/reloader'
9
+
10
+
11
+ module Mirage
12
+ class MirageServer < Sinatra::Base
13
+ configure do
14
+ require 'logger'
15
+ enable :logging
16
+ log_file = File.open('mirage.log', 'a')
17
+ log_file.sync=true
18
+ use Rack::CommonLogger, log_file
19
+ register Sinatra::Reloader
20
+ also_reload "**/*.rb"
21
+ set :views, File.dirname(__FILE__) + '/views'
22
+ end
23
+ end
24
+ end
4
25
  require 'mirage'
5
26
  include Mirage::Util
6
-
7
- #puts "ARGV is " + ARGV
27
+ #
8
28
  options = parse_options(ARGV)
9
29
 
30
+
10
31
  DEFAULT_RESPONSES_DIR = "#{options[:defaults_directory]}"
11
32
  Mirage.client = Mirage::Client.new
12
- Ramaze::Log.loggers = [Logger.new('mirage.log')]
13
- Ramaze::Log.level= Logger::WARN
14
- Ramaze.start :port => options[:port]
33
+ set(:show_exception, false)
34
+ set(:raise_errors, true)
35
+
36
+ Mirage::MirageServer.run! :port => options[:port], :show_exceptions => false, :logging => true, :server => 'webrick'
15
37
 
16
38
 
@@ -17,12 +17,12 @@
17
17
  <br/>
18
18
  <strong>Note:</strong> if requests or responses contain xml, you will need to view page source to see it properly.</p>
19
19
 
20
- <?r unless @responses.empty? ?>
20
+ <% unless @responses.empty? %>
21
21
  <table border="1" width='100%'>
22
- <?r @responses.each do |key, response| ?>
23
- <tr><td><a id='peek_response_#{response.response_id}' href="/mirage/peek/#{response.response_id}">#{key}</a></td><td><a id='track_response_#{response.response_id}' href="/mirage/track/#{response.response_id}">track</a></td></tr>
24
- <?r end ?>
22
+ <% @responses.each do |key, response| %>
23
+ <tr><td><a id='peek_response_<%=response.response_id%>' href="/mirage/templates/<%=response.response_id%>"><%=key%></a></td><td><a id='track_response_<%=response.response_id%>' href="/mirage/requests/<%=response.response_id%>">track</a></td></tr>
24
+ <% end %>
25
25
  </table>
26
- <?r end ?>
26
+ <% end %>
27
27
  </body>
28
28
  </html>
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Leon Davis"]
12
- s.date = %q{2011-04-06}
12
+ s.date = %q{2011-04-25}
13
13
  s.default_executable = %q{mirage}
14
14
  s.description = %q{Mirage aids testing of your applications by hosting mock responses so that your applications do not have to talk to real endpoints. Its accessible via HTTP and has a RESTful interface.}
15
15
  s.executables = ["mirage"]
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  "features/client/peek.feature",
29
29
  "features/client/save_and_revert.feature",
30
30
  "features/client/set.feature",
31
- "features/client/track.feature",
31
+ "features/client/track_requests.feature",
32
32
  "features/server/clear.feature",
33
33
  "features/server/command_line_iterface.feature",
34
34
  "features/server/file_responses.feature",
@@ -41,7 +41,7 @@ Gem::Specification.new do |s|
41
41
  "features/server/set_default_response.feature",
42
42
  "features/server/set_with_a_delay.feature",
43
43
  "features/server/set_with_a_pattern.feature",
44
- "features/server/track.feature",
44
+ "features/server/track_requests.feature",
45
45
  "features/server/web_user_interface.feature",
46
46
  "features/step_definitions/my_steps.rb",
47
47
  "features/support/env.rb",
@@ -53,7 +53,7 @@ Gem::Specification.new do |s|
53
53
  "lib/mirage/util.rb",
54
54
  "lib/mirage/web.rb",
55
55
  "lib/start_mirage.rb",
56
- "lib/view/mirage/index.xhtml",
56
+ "lib/views/index.erb",
57
57
  "mirage.gemspec",
58
58
  "rakefile"
59
59
  ]
@@ -79,7 +79,7 @@ For more information go to: https://github.com/lashd/mirage/wiki
79
79
 
80
80
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
81
81
  s.add_runtime_dependency(%q<rack>, ["~> 1.1.0"])
82
- s.add_runtime_dependency(%q<ramaze>, [">= 2011.01.30"])
82
+ s.add_runtime_dependency(%q<sinatra>, [">= 0"])
83
83
  s.add_runtime_dependency(%q<mechanize>, [">= 1.0.0"])
84
84
  s.add_runtime_dependency(%q<childprocess>, ["~> 0.1"])
85
85
  s.add_development_dependency(%q<rake>, [">= 0"])
@@ -89,7 +89,7 @@ For more information go to: https://github.com/lashd/mirage/wiki
89
89
  s.add_development_dependency(%q<bundler>, [">= 0"])
90
90
  else
91
91
  s.add_dependency(%q<rack>, ["~> 1.1.0"])
92
- s.add_dependency(%q<ramaze>, [">= 2011.01.30"])
92
+ s.add_dependency(%q<sinatra>, [">= 0"])
93
93
  s.add_dependency(%q<mechanize>, [">= 1.0.0"])
94
94
  s.add_dependency(%q<childprocess>, ["~> 0.1"])
95
95
  s.add_dependency(%q<rake>, [">= 0"])
@@ -100,7 +100,7 @@ For more information go to: https://github.com/lashd/mirage/wiki
100
100
  end
101
101
  else
102
102
  s.add_dependency(%q<rack>, ["~> 1.1.0"])
103
- s.add_dependency(%q<ramaze>, [">= 2011.01.30"])
103
+ s.add_dependency(%q<sinatra>, [">= 0"])
104
104
  s.add_dependency(%q<mechanize>, [">= 1.0.0"])
105
105
  s.add_dependency(%q<childprocess>, ["~> 0.1"])
106
106
  s.add_dependency(%q<rake>, [">= 0"])
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mirage
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 1.3.6
4
+ prerelease: 6
5
+ version: 2.0.0.alpha1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Leon Davis
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-06 00:00:00 +01:00
13
+ date: 2011-06-07 00:00:00 +01:00
14
14
  default_executable: mirage
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -25,40 +25,40 @@ dependencies:
25
25
  prerelease: false
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: ramaze
28
+ name: sinatra
29
29
  requirement: &id002 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 2011.01.30
34
+ version: "0"
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
39
- name: mechanize
39
+ name: childprocess
40
40
  requirement: &id003 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ">="
43
+ - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: 1.0.0
45
+ version: "0.1"
46
46
  type: :runtime
47
47
  prerelease: false
48
48
  version_requirements: *id003
49
49
  - !ruby/object:Gem::Dependency
50
- name: childprocess
50
+ name: rake
51
51
  requirement: &id004 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
- - - ~>
54
+ - - "="
55
55
  - !ruby/object:Gem::Version
56
- version: "0.1"
57
- type: :runtime
56
+ version: 0.9.0
57
+ type: :development
58
58
  prerelease: false
59
59
  version_requirements: *id004
60
60
  - !ruby/object:Gem::Dependency
61
- name: rake
61
+ name: cucumber
62
62
  requirement: &id005 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
@@ -69,13 +69,13 @@ dependencies:
69
69
  prerelease: false
70
70
  version_requirements: *id005
71
71
  - !ruby/object:Gem::Dependency
72
- name: cucumber
72
+ name: gherkin
73
73
  requirement: &id006 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
- - - ">="
76
+ - - "="
77
77
  - !ruby/object:Gem::Version
78
- version: "0"
78
+ version: 2.3.9
79
79
  type: :development
80
80
  prerelease: false
81
81
  version_requirements: *id006
@@ -112,6 +112,39 @@ dependencies:
112
112
  type: :development
113
113
  prerelease: false
114
114
  version_requirements: *id009
115
+ - !ruby/object:Gem::Dependency
116
+ name: sinatra-reloader
117
+ requirement: &id010 !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: "0"
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: *id010
126
+ - !ruby/object:Gem::Dependency
127
+ name: mechanize
128
+ requirement: &id011 !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: 1.0.0
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: *id011
137
+ - !ruby/object:Gem::Dependency
138
+ name: gemcutter
139
+ requirement: &id012 !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: "0"
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: *id012
115
148
  description: Mirage aids testing of your applications by hosting mock responses so that your applications do not have to talk to real endpoints. Its accessible via HTTP and has a RESTful interface.
116
149
  email:
117
150
  executables:
@@ -127,7 +160,6 @@ files:
127
160
  - VERSION
128
161
  - bin/mirage
129
162
  - features/client/clear.feature
130
- - features/client/get.feature
131
163
  - features/client/mirage_client.feature
132
164
  - features/client/peek.feature
133
165
  - features/client/save_and_revert.feature
@@ -135,7 +167,6 @@ files:
135
167
  - features/client/track.feature
136
168
  - features/server/clear.feature
137
169
  - features/server/command_line_iterface.feature
138
- - features/server/file_responses.feature
139
170
  - features/server/logging.feature
140
171
  - features/server/peek.feature
141
172
  - features/server/prime.feature
@@ -145,7 +176,7 @@ files:
145
176
  - features/server/set_default_response.feature
146
177
  - features/server/set_with_a_delay.feature
147
178
  - features/server/set_with_a_pattern.feature
148
- - features/server/track.feature
179
+ - features/server/track_requests.feature
149
180
  - features/server/web_user_interface.feature
150
181
  - features/step_definitions/my_steps.rb
151
182
  - features/support/env.rb
@@ -154,10 +185,13 @@ files:
154
185
  - lib/mirage.rb
155
186
  - lib/mirage/client.rb
156
187
  - lib/mirage/core.rb
188
+ - lib/mirage/mock_response.rb
189
+ - lib/mirage/mock_responses_collection.rb
190
+ - lib/mirage/object.rb
157
191
  - lib/mirage/util.rb
158
192
  - lib/mirage/web.rb
159
193
  - lib/start_mirage.rb
160
- - lib/view/mirage/index.xhtml
194
+ - lib/views/index.erb
161
195
  - mirage.gemspec
162
196
  - rakefile
163
197
  has_rdoc: true
@@ -180,16 +214,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
180
214
  requirements:
181
215
  - - ">="
182
216
  - !ruby/object:Gem::Version
183
- hash: -2067065448166583273
217
+ hash: 122609927051635249
184
218
  segments:
185
219
  - 0
186
220
  version: "0"
187
221
  required_rubygems_version: !ruby/object:Gem::Requirement
188
222
  none: false
189
223
  requirements:
190
- - - ">="
224
+ - - ">"
191
225
  - !ruby/object:Gem::Version
192
- version: "0"
226
+ version: 1.3.1
193
227
  requirements: []
194
228
 
195
229
  rubyforge_project: