mirage 0.1.2

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