mirage 0.1.2

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 (41) hide show
  1. data/.rvmrc +1 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +50 -0
  4. data/README.md +93 -0
  5. data/bin/mirage +54 -0
  6. data/features/checking_for_requests.feature +74 -0
  7. data/features/clearing_requests_and_responses.feature +81 -0
  8. data/features/client/checking_for_requests.feature +20 -0
  9. data/features/client/clearing_responses.feature +75 -0
  10. data/features/client/getting_responses.feature +30 -0
  11. data/features/client/mirage_client.feature +36 -0
  12. data/features/client/peeking.feature +32 -0
  13. data/features/client/setting_responses.feature +91 -0
  14. data/features/client/snapshotting.feature +34 -0
  15. data/features/command_line_iterface.feature +39 -0
  16. data/features/default_responses.feature +91 -0
  17. data/features/file_hosting.feature +8 -0
  18. data/features/logging.feature +7 -0
  19. data/features/peeking_at_response.feature +24 -0
  20. data/features/resources/test.zip +0 -0
  21. data/features/response_templates.feature +45 -0
  22. data/features/root_responses.feature +47 -0
  23. data/features/setting_responses.feature +40 -0
  24. data/features/setting_responses_with_a_delay.feature +10 -0
  25. data/features/setting_responses_with_pattern_matching.feature +72 -0
  26. data/features/snapshotting.feature +25 -0
  27. data/features/step_definitions/my_steps.rb +127 -0
  28. data/features/support/env.rb +89 -0
  29. data/features/web_user_interface.feature +39 -0
  30. data/full_build.sh +100 -0
  31. data/lib/config.ru +5 -0
  32. data/lib/mirage.rb +14 -0
  33. data/lib/mirage/client.rb +140 -0
  34. data/lib/mirage/core.rb +206 -0
  35. data/lib/mirage/util.rb +40 -0
  36. data/lib/mirage/web.rb +65 -0
  37. data/lib/start_mirage.rb +15 -0
  38. data/lib/view/mirage/index.xhtml +23 -0
  39. data/mirage.gemspec +40 -0
  40. data/rakefile +50 -0
  41. metadata +199 -0
@@ -0,0 +1,47 @@
1
+ Feature: Mirage can respond with a 'root' response when a when the response requested at a sub url is not found.
2
+ I.e.
3
+ if a response is held for 'level1' and request comes in for 'level1/level2' the response for 'level1'
4
+ can be returned if nothing is held for 'level1/level2'
5
+
6
+ If a request is made and there is more than one response that could be appropriate then the closet is chosen.
7
+
8
+ E.g.
9
+ responses exist for: 'level1' and 'level1/level2'. If a response for 'level1/level2/level3 is made, then the response for
10
+ 'level1/level2' will be returned as it is the most specific match out of the two.
11
+
12
+ Root responses can cause unexpected behaviour and so in order to qualify as a root reponse a client must knowingly mark it as one.
13
+
14
+ Scenario: A root response is returned
15
+ Given I hit 'http://localhost:7001/mirage/set/level0/level1' with parameters:
16
+ | response | another level |
17
+ And I hit 'http://localhost:7001/mirage/set/level1' with parameters:
18
+ | response | level 1 |
19
+ | root_response | true |
20
+
21
+ When I hit 'http://localhost:7001/mirage/get/level1/level2'
22
+ Then 'level 1' should be returned
23
+
24
+
25
+ Scenario: More than one potential root response exists
26
+ Given I hit 'http://localhost:7001/mirage/set/level1' with parameters:
27
+ | response | level 1 |
28
+ | root_response | true |
29
+ And I hit 'http://localhost:7001/mirage/set/level1/level2' with parameters:
30
+ | response | level 2 |
31
+ | root_response | true |
32
+ And I hit 'http://localhost:7001/mirage/set/level1/level2/level3' with parameters:
33
+ | response | level 3 |
34
+ | root_response | false |
35
+ And I hit 'http://localhost:7001/mirage/set/level1/level2/level3/level4/level5' with parameters:
36
+ | response | level 5 |
37
+ | root_response | true |
38
+
39
+ When I hit 'http://localhost:7001/mirage/get/level1/level2/level3/level4'
40
+ Then 'level 2' should be returned
41
+
42
+
43
+ Scenario: There isnt a root response
44
+ Given I hit 'http://localhost:7001/mirage/set/level1' with parameters:
45
+ | response | level 1 |
46
+ When I hit 'http://localhost:7001/mirage/get/level1/level2'
47
+ Then a 404 should be returned
@@ -0,0 +1,40 @@
1
+ Feature: Mirage can be configured with endpoints that when request returned defined responses.
2
+ On setting a response, a unique id is retuned. This is a key that can be used to manage the response. E.g. clearing or peek at it.
3
+
4
+ Usage:
5
+ ${mirage_url}/set/your/end/point?response=your_response
6
+
7
+
8
+ Scenario: Setting a response without any selection criteria
9
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
10
+ | response | Hello, how are you? |
11
+
12
+ When I hit 'http://localhost:7001/mirage/get/greeting'
13
+ Then 'Hello, how are you?' should be returned
14
+
15
+ Scenario: A response hosted on a longer url
16
+ Given I hit 'http://localhost:7001/mirage/set/say/hello/to/me' with parameters:
17
+ | response | Hello to me |
18
+
19
+ When I hit 'http://localhost:7001/mirage/get/say/hello/to/me'
20
+ Then 'Hello to me' should be returned
21
+
22
+
23
+ Scenario: The same endpoint is set more than once
24
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
25
+ | response | Hello |
26
+ Then '1' should be returned
27
+
28
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
29
+ | response | Hi |
30
+ Then '1' should be returned
31
+
32
+
33
+ Scenario: A response is not supplied
34
+ Given I hit 'http://localhost:7001/mirage/set/greeting'
35
+ Then a 500 should be returned
36
+
37
+
38
+ Scenario: Getting a response that does not exist
39
+ When I hit 'http://localhost:7001/mirage/get/response_that_does_not_exist'
40
+ Then a 404 should be returned
@@ -0,0 +1,10 @@
1
+ Feature: Its possible introduce a delay before responding to a client with a particular response. This lets you simulate real world
2
+ conditions by making your application wait before receiving a response.
3
+
4
+ Scenario: Response with a delay
5
+ Given I hit 'http://localhost:7001/mirage/set/an_appology' with parameters:
6
+ | response | Sorry it took me so long! |
7
+ | delay | 4 |
8
+
9
+ When I hit 'http://localhost:7001/mirage/get/an_appology'
10
+ Then it should take at least '4' seconds
@@ -0,0 +1,72 @@
1
+ Feature: Mirage can be configured to return particular responses conditionally based on if a prescribed pattern is found in
2
+ querystring or the body of a request.
3
+
4
+ Patterns can be either plain text or a regular expression
5
+
6
+ Background: There is already a default response for 'greeting'
7
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
8
+ | response | Hello Stranger. |
9
+
10
+
11
+ Scenario: A plain text pattern found in the request body
12
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
13
+ | response | Hello Leon, how are you? |
14
+ | pattern | <name>leon</name> |
15
+ When I hit 'http://localhost:7001/mirage/get/greeting' with request body:
16
+ """
17
+ <greetingRequest>
18
+ <name>leon</name>
19
+ </greetingRequest>
20
+ """
21
+ Then 'Hello Leon, how are you?' should be returned
22
+
23
+
24
+ Scenario: A regex based pattern found in the request body
25
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
26
+ | response | Hello Leon, how are you? |
27
+ | pattern | .*?leon<\/name> |
28
+
29
+ When I hit 'http://localhost:7001/mirage/get/greeting' with request body:
30
+ """
31
+ <greetingRequest>
32
+ <name>leon</name>
33
+ </greetingRequest>
34
+ """
35
+ Then 'Hello Leon, how are you?' should be returned
36
+
37
+
38
+ Scenario: A plain text pattern found in the query string
39
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
40
+ | response | Hello Leon, how are you? |
41
+ | pattern | leon |
42
+
43
+ When I hit 'http://localhost:7001/mirage/get/greeting' with parameters:
44
+ | name | leon |
45
+
46
+ Then 'Hello Leon, how are you?' should be returned
47
+
48
+
49
+ Scenario: A regex based pattern found in the query string
50
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
51
+ | response | Hello Leon, how are you? |
52
+ | pattern | name=[L\|l]eon |
53
+
54
+ When I hit 'http://localhost:7001/mirage/get/greeting' with parameters:
55
+ | name | leon |
56
+
57
+ Then 'Hello Leon, how are you?' should be returned
58
+
59
+
60
+ Scenario: The pattern is not matched
61
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
62
+ | response | Hello Leon, how are you? |
63
+ | pattern | .*?leon<\/name> |
64
+
65
+ When I hit 'http://localhost:7001/mirage/get/greeting' with request body:
66
+ """
67
+ <greetingRequest>
68
+ <name>jim</name>
69
+ </greetingRequest>
70
+ """
71
+
72
+ Then 'Hello Stranger.' should be returned
@@ -0,0 +1,25 @@
1
+ Feature: Having set up the Mirage with a number of defaults, your tests may continue to change its state.
2
+ Clearing and resetting all of your responses, potentially hundreds of times, can be time expensive.
3
+
4
+ Mirage provides the ability to take a snapshot of its current state and to roll it back to that state.
5
+
6
+ Background: The MockServer has been setup with some default responses
7
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
8
+ | response | The default greeting |
9
+
10
+
11
+ Scenario: Taking a snapshot and rolling it back
12
+ Given I hit 'http://localhost:7001/mirage/snapshot'
13
+ And I hit 'http://localhost:7001/mirage/set/leaving' with parameters:
14
+ | response | Goodye |
15
+
16
+ And I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
17
+ | response | Changed |
18
+
19
+ And I hit 'http://localhost:7001/mirage/rollback'
20
+
21
+ When I hit 'http://localhost:7001/mirage/get/leaving'
22
+ Then a 404 should be returned
23
+
24
+ When I hit 'http://localhost:7001/mirage/get/greeting'
25
+ Then 'The default greeting' should be returned
@@ -0,0 +1,127 @@
1
+ Before('@command_line') do
2
+ stop_mirage
3
+ end
4
+
5
+ After('@command_line') do
6
+ stop_mirage
7
+ end
8
+
9
+ Then /^'(.*?)' should be returned$/ do |expected_response|
10
+ response_text = @response.body
11
+ if ["1.8.6", "1.8.7"].include?(RUBY_VERSION) && response_text != expected_response
12
+ expected_response.length.should == response_text.length
13
+ expected_response.split('&').each { |param_value_pair| response_text.should =~ /#{param_value_pair}/ }
14
+ else
15
+ response_text.should == expected_response
16
+ end
17
+ end
18
+
19
+ Then /^a (404|500) should be returned$/ do |error_code|
20
+ @response.code.should == error_code.to_i
21
+ end
22
+
23
+ Then /^it should take at least '(.*)' seconds$/ do |time|
24
+ (@response_time).should >= time.to_f
25
+ end
26
+
27
+
28
+ Then /^the response should be a file the same as '([^']*)'$/ do |file_path|
29
+ download_path = "#{SCRATCH}/temp.download"
30
+ @response.save_as(download_path)
31
+ FileUtils.cmp(download_path, file_path).should == true
32
+ end
33
+
34
+ Then /^mirage should be running on '(.*)'$/ do |url|
35
+ get(url).code.to_i.should == 200
36
+ end
37
+
38
+ Given /^I run '(.*)'$/ do |command|
39
+ path = ENV['mode'] == 'regression' ? '' : "../bin/"
40
+ @commandline_output = normalise(IO.popen("export RUBYOPT='' && cd #{SCRATCH} && #{path}#{command}").read)
41
+ end
42
+
43
+ Given /^Mirage (is|is not) running$/ do |running|
44
+ if running == 'is'
45
+ start_mirage unless $mirage.running?
46
+ else
47
+ stop_mirage if $mirage.running?
48
+ end
49
+ end
50
+
51
+ Then /^Connection should be refused to '(.*)'$/ do |url|
52
+
53
+ begin
54
+ get(url)
55
+ fail "Mirage is still running"
56
+ rescue Errno::ECONNREFUSED
57
+ end
58
+
59
+ end
60
+
61
+ Given /^the file '(.*)' contains:$/ do |file_path, content|
62
+ file_path = "#{SCRATCH}/#{file_path}" unless file_path =~ /^\//
63
+
64
+ FileUtils.rm_rf(file_path) if File.exists?(file_path)
65
+ directory = File.dirname(file_path)
66
+ FileUtils.mkdir_p(directory)
67
+ file = File.new("#{directory}/#{File.basename(file_path)}", 'w')
68
+ file.write(content)
69
+ file.close
70
+ end
71
+
72
+ Then /^the usage information should be displayed$/ do
73
+ @usage.each { |line| @commandline_output.should =~ /#{line}/ }
74
+ end
75
+ Given /^usage information:$/ do |table|
76
+ @usage = table.raw.flatten.collect { |line| normalise(line) }
77
+ end
78
+
79
+ Then /^I run$/ do |text|
80
+ text.gsub!("\"", "\\\\\"")
81
+ raise "run failed" unless system "#{RUBY_CMD} -e \"#{@code_snippet}\n#{text}\""
82
+ end
83
+
84
+ Given /^the following gems are required to run the Mirage client test code:$/ do |text|
85
+ @code_snippet = text.gsub("\"", "\\\\\"")
86
+ end
87
+
88
+ When /^I hit '(http:\/\/localhost:7001\/mirage\/(.*?))'$/ do |url, response_id|
89
+ @response = hit_mirage(url)
90
+ end
91
+
92
+ When /^I (hit|get|post to) '(http:\/\/localhost:7001\/mirage\/(.*?))' with parameters:$/ do |http_method, url, endpoint, table|
93
+
94
+ parameters = {}
95
+ table.raw.each do |row|
96
+ parameter, value = row[0].to_sym, row[1]
97
+ value = (parameter == :file ? File.open(value) : value)
98
+ parameters[parameter.to_sym]=value
99
+ end
100
+
101
+ @response = hit_mirage(url, parameters)
102
+ end
103
+
104
+ When /^I hit '(http:\/\/localhost:7001\/mirage\/(.*?))' with request body:$/ do |url, endpoint, request_body|
105
+ @response = hit_mirage(url, {:body => request_body})
106
+ end
107
+
108
+ Then /^I should see '(.*?)' on the command line$/ do |content|
109
+ @commandline_output.should =~/#{content}/
110
+ end
111
+
112
+ Then /^'(.*)' should exist$/ do |path|
113
+ File.exists?("#{SCRATCH}/#{path}").should == true
114
+ end
115
+
116
+ Then /^'(.*)' should contain '(.*)'$/ do |file, content|
117
+ fail("#{content} not found in: #{File.read(file)}") unless File.read("#{SCRATCH}/#{file}").index(content)
118
+ end
119
+ Given /^I goto '(.*)'$/ do |url|
120
+ @page = Mechanize.new.get url
121
+ end
122
+ Then /^I should see '(.*)'$/ do |text|
123
+ @page.body.index(text).should_not == nil
124
+ end
125
+ When /^I click '(.*)'$/ do |thing|
126
+ @page = @page.links.find{|link| link.attributes['id'] == thing}.click
127
+ end
@@ -0,0 +1,89 @@
1
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib")
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ Bundler.setup(:test)
5
+ require 'mirage'
6
+ require 'cucumber'
7
+ require 'rspec'
8
+ require 'mechanize'
9
+
10
+ SCRATCH = './scratch'
11
+ RUBY_CMD = RUBY_PLATFORM == 'JAVA' ? 'jruby' : 'ruby'
12
+
13
+
14
+ module Web
15
+ include Mirage::Web
16
+
17
+ def get(url)
18
+ browser = Mechanize.new
19
+ browser.keep_alive= false
20
+ browser.get(url)
21
+ end
22
+
23
+ def hit_mirage(url, parameters={})
24
+ start_time = Time.now
25
+ response = (parameters.include?(:file) ? http_post(url, parameters) : http_get(url, parameters))
26
+ @response_time = Time.now - start_time
27
+ response
28
+ end
29
+
30
+ def normalise text
31
+ text.gsub(/[\n]/, ' ').gsub(/\s+/, ' ')
32
+ end
33
+ end
34
+
35
+
36
+ module Regression
37
+ def stop_mirage
38
+ `export RUBYOPT='' && cd #{SCRATCH} && mirage stop`
39
+ end
40
+
41
+ def start_mirage
42
+ `truncate mirage.log --size 0`
43
+ `export RUBYOPT='' && cd #{SCRATCH} && mirage start`
44
+ end
45
+ end
46
+
47
+ module IntelliJ
48
+ include Mirage::Util
49
+
50
+ def stop_mirage
51
+ system "cd #{SCRATCH} && ../bin/mirage stop"
52
+ wait_until do
53
+ !$mirage.running?
54
+ end
55
+ end
56
+
57
+ def start_mirage
58
+ puts "starting mirage"
59
+ `truncate mirage.log --size 0`
60
+ system "cd #{SCRATCH} && ../bin/mirage start"
61
+
62
+ wait_until do
63
+ $mirage.running?
64
+ end
65
+ end
66
+ end
67
+
68
+ 'regression' == ENV['mode'] ? World(Regression) : World(IntelliJ)
69
+ 'regression' == ENV['mode'] ? include(Regression) : include(IntelliJ)
70
+
71
+ World(Web)
72
+
73
+ Before do
74
+ FileUtils.mkdir_p(SCRATCH)
75
+ $mirage = Mirage::Client.new
76
+
77
+ if $mirage.running?
78
+ $mirage.clear
79
+ else
80
+ start_mirage
81
+ end
82
+
83
+ `ls #{SCRATCH}/ | grep -v mirage.log | rm -rf`
84
+ `truncate -s 0 #{SCRATCH}/mirage.log`
85
+ end
86
+
87
+ at_exit do
88
+ stop_mirage
89
+ end
@@ -0,0 +1,39 @@
1
+ Feature: Mirage's home page allows you to see what response are currently being hosted.
2
+ From this page you can:
3
+ - Peek at a responses content
4
+ - Check the response to see if a request has been made to it
5
+
6
+ Background: There are already a couple of responses hosted on he Mirage server
7
+ Given I hit 'http://localhost:7001/mirage/set/greeting' with parameters:
8
+ | response | hello |
9
+ | root_response | true |
10
+ And I hit 'http://localhost:7001/mirage/set/leaving' with parameters:
11
+ | response | goodbye |
12
+
13
+ Scenario: Using the home page to see what response are being hosted
14
+ Given I goto 'http://localhost:7001/mirage'
15
+ Then I should see 'greeting/*'
16
+ Then I should see 'leaving'
17
+
18
+ Scenario: Using the home page to peek at a response
19
+ Given I goto 'http://localhost:7001/mirage'
20
+ When I click 'peek_response_1'
21
+ Then I should see 'hello'
22
+
23
+ Scenario: Using the home page to check if a request has been made
24
+ Given I hit 'http://localhost:7001/mirage/get/greeting' with request body:
25
+ """
26
+ Yo!
27
+ """
28
+ Given I goto 'http://localhost:7001/mirage'
29
+ When I click 'check_response_1'
30
+ Then I should see 'Yo!'
31
+
32
+ Scenario: Using the home page to check if a request has been made
33
+ Given I hit 'http://localhost:7001/mirage/get/greeting' with request body:
34
+ """
35
+ Yo!
36
+ """
37
+ Given I goto 'http://localhost:7001/mirage'
38
+ When I click 'check_response_1'
39
+ Then I should see 'Yo!'