mirage 1.3.6 → 2.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
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: