mirage-on-thin 3.0.8

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 (102) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.simplecov +6 -0
  5. data/.travis.yml +3 -0
  6. data/Gemfile +29 -0
  7. data/Gemfile.lock +151 -0
  8. data/HISTORY +22 -0
  9. data/README.md +156 -0
  10. data/Rakefile +10 -0
  11. data/VERSION +1 -0
  12. data/bin/mirage +14 -0
  13. data/features/.nav +29 -0
  14. data/features/client/clear.feature +78 -0
  15. data/features/client/configure.feature +72 -0
  16. data/features/client/model.feature +95 -0
  17. data/features/client/preview_responses.feature +33 -0
  18. data/features/client/prime.feature +32 -0
  19. data/features/client/put.feature +111 -0
  20. data/features/client/readme.md +3 -0
  21. data/features/client/requests.feature +20 -0
  22. data/features/client/running.feature +51 -0
  23. data/features/client/save_and_revert.feature +39 -0
  24. data/features/client/start.feature +46 -0
  25. data/features/client/stop.feature +53 -0
  26. data/features/commandline_interface/help.feature +17 -0
  27. data/features/commandline_interface/readme.md +1 -0
  28. data/features/commandline_interface/start.feature +18 -0
  29. data/features/commandline_interface/stop.feature +42 -0
  30. data/features/logging.feature +6 -0
  31. data/features/prime.feature +35 -0
  32. data/features/readme.md +7 -0
  33. data/features/requests/delete.feature +48 -0
  34. data/features/requests/get.feature +36 -0
  35. data/features/save_and_revert.feature +35 -0
  36. data/features/step_definitions/my_steps.rb +98 -0
  37. data/features/step_definitions/observation_steps.rb +103 -0
  38. data/features/support/command_line.rb +33 -0
  39. data/features/support/env.rb +22 -0
  40. data/features/support/hooks.rb +26 -0
  41. data/features/support/mirage.rb +12 -0
  42. data/features/support/web.rb +20 -0
  43. data/features/templates/delete.feature +45 -0
  44. data/features/templates/get.feature +54 -0
  45. data/features/templates/path_wildcards.feature +10 -0
  46. data/features/templates/preview.feature +18 -0
  47. data/features/templates/put.feature +77 -0
  48. data/features/templates/put_with_substitutions.feature +22 -0
  49. data/features/templates/readme.md +4 -0
  50. data/features/templates/required_content.feature +113 -0
  51. data/features/web_user_interface.feature +44 -0
  52. data/full_build.sh +100 -0
  53. data/lib/mirage/client.rb +10 -0
  54. data/lib/mirage/client/cli_bridge.rb +30 -0
  55. data/lib/mirage/client/client.rb +73 -0
  56. data/lib/mirage/client/error.rb +22 -0
  57. data/lib/mirage/client/helpers/method_builder.rb +19 -0
  58. data/lib/mirage/client/request.rb +26 -0
  59. data/lib/mirage/client/requests.rb +13 -0
  60. data/lib/mirage/client/runner.rb +103 -0
  61. data/lib/mirage/client/template.rb +56 -0
  62. data/lib/mirage/client/template/configuration.rb +44 -0
  63. data/lib/mirage/client/template/model.rb +48 -0
  64. data/lib/mirage/client/template/model/common_methods.rb +24 -0
  65. data/lib/mirage/client/template/model/instance_methods.rb +95 -0
  66. data/lib/mirage/client/templates.rb +50 -0
  67. data/mirage-on-thin.gemspec +175 -0
  68. data/mirage_server.rb +35 -0
  69. data/server/app.rb +4 -0
  70. data/server/binary_data_checker.rb +15 -0
  71. data/server/extensions/hash.rb +10 -0
  72. data/server/extensions/object.rb +5 -0
  73. data/server/helpers.rb +3 -0
  74. data/server/helpers/http_headers.rb +31 -0
  75. data/server/helpers/template_requirements.rb +33 -0
  76. data/server/mock_response.rb +242 -0
  77. data/server/server.rb +184 -0
  78. data/spec/client/cli_bridge_spec.rb +63 -0
  79. data/spec/client/client_spec.rb +179 -0
  80. data/spec/client/helpers/method_builder_spec.rb +40 -0
  81. data/spec/client/request_spec.rb +39 -0
  82. data/spec/client/requests_spec.rb +9 -0
  83. data/spec/client/runner_spec.rb +138 -0
  84. data/spec/client/template/configuration_spec.rb +32 -0
  85. data/spec/client/template/model/common_methods_spec.rb +25 -0
  86. data/spec/client/template/model/instance_methods_spec.rb +169 -0
  87. data/spec/client/template/model_spec.rb +119 -0
  88. data/spec/client/template_spec.rb +146 -0
  89. data/spec/client/templates_spec.rb +197 -0
  90. data/spec/resources/binary.file +0 -0
  91. data/spec/server/binary_data_checker_spec.rb +21 -0
  92. data/spec/server/helpers/http_headers_spec.rb +20 -0
  93. data/spec/server/helpers/template_requirements_spec.rb +34 -0
  94. data/spec/server/mock_response_spec.rb +577 -0
  95. data/spec/server/server_spec.rb +156 -0
  96. data/spec/spec_helper.rb +85 -0
  97. data/tasks/application.rake +7 -0
  98. data/tasks/packaging.rake +28 -0
  99. data/tasks/tests.rake +25 -0
  100. data/views/index.haml +16 -0
  101. data/views/response.haml +46 -0
  102. metadata +337 -0
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Request do
4
+ let(:id) { "url_for_request_entity" }
5
+ let(:request_url) { "requested_url" }
6
+ let(:trigger_url) { "trigger url" }
7
+
8
+ let(:body) { "body" }
9
+ let(:parameters) { {"name" => "joe"} }
10
+ let(:headers) { {"header" => "value"} }
11
+
12
+ let(:request_json) do
13
+ {body: body,
14
+ headers: headers,
15
+ parameters: parameters,
16
+ request_url: trigger_url,
17
+ id: id}
18
+ end
19
+
20
+ it 'delete a request' do
21
+ id = "url"
22
+ Request.should_receive(:delete).with(id)
23
+ request = Request.new
24
+ request.id = id
25
+ request.delete
26
+ end
27
+
28
+ it 'should load request data' do
29
+ Request.should_receive(:backedup_get).with(request_url, format: :json).and_return(request_json)
30
+
31
+ request = Request.get(request_url)
32
+ request.headers.should == headers
33
+ request.body.should == body
34
+ request.request_url.should == trigger_url
35
+ request.parameters.should == parameters
36
+ request.id.should == id
37
+ end
38
+
39
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Requests do
4
+ it 'should delete all request data' do
5
+ base_url = "base_url"
6
+ Requests.should_receive(:delete).with("#{base_url}/requests")
7
+ Requests.new(base_url).delete_all
8
+ end
9
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+ require 'mirage/client'
3
+
4
+
5
+ describe Mirage do
6
+
7
+ describe 'starting' do
8
+ before(:each) do
9
+ @runner = double
10
+ Runner.should_receive(:new).and_return(@runner)
11
+ end
12
+
13
+ it 'should start Mirage on port 7001 by default' do
14
+ @runner.should_receive(:invoke).with(:start, [], {:port => 7001})
15
+ client = Mirage.start
16
+ client.should == Mirage::Client.new
17
+ end
18
+
19
+ it 'should start mirage on the given port' do
20
+ options = {:port => 9001}
21
+ @runner.should_receive(:invoke).with(:start, [], options)
22
+ Mirage.start options
23
+ end
24
+ end
25
+
26
+ describe 'stopping' do
27
+ before(:each) do
28
+ @runner = double
29
+ Runner.stub(:new).and_return(@runner)
30
+ end
31
+
32
+ it 'should supply single port argument in an array to the runner' do
33
+ port = 7001
34
+ @runner.should_receive(:invoke).with(:stop, [], :port => [port])
35
+ @runner.should_receive(:invoke).with(:stop, [], :port => [:all])
36
+ Mirage.stop(:port => port)
37
+ Mirage.stop(:all)
38
+ end
39
+
40
+ it 'should stop multiple instances of Mirage' do
41
+ ports = 7001, 7002
42
+ @runner.should_receive(:invoke).with(:stop, [], :port => ports)
43
+ Mirage.stop(:port => ports)
44
+ end
45
+
46
+ end
47
+
48
+ describe Mirage::Runner do
49
+ it 'should stop the running instance of Mirage' do
50
+ options = {:port => []}
51
+ runner = Mirage::Runner.new
52
+ runner.options = options
53
+
54
+ runner.stub(:mirage_process_ids).with([]).and_return({"7001" => "18901"})
55
+
56
+
57
+ runner.should_receive(:kill).with("18901") do
58
+ RSpec.reset
59
+ runner.stub(:mirage_process_ids).with([]).and_return({})
60
+ end
61
+
62
+ Mirage::Runner.should_receive(:new).and_return(runner)
63
+ runner.invoke(:stop, [], options)
64
+ end
65
+
66
+ it 'should not stop any instances when more than one is running' do
67
+ options = {:port => []}
68
+ runner = Mirage::Runner.new
69
+ runner.options = options
70
+
71
+ runner.stub(:mirage_process_ids).with([]).and_return({"7001" => "18901", "7002" => "18902", "7003" => "18903"})
72
+ runner.should_not_receive(:kill)
73
+ Mirage::Runner.should_receive(:new).and_return(runner)
74
+
75
+ expect{ runner.invoke(:stop, [], options) }.to raise_error(Mirage::ClientError)
76
+ end
77
+
78
+
79
+ it 'should stop the instance running on the given port' do
80
+ options = {:port => [7001]}
81
+ runner = Mirage::Runner.new
82
+ runner.options = options
83
+
84
+ runner.should_receive(:mirage_process_ids).with([7001]).and_return({"7001" => "18901"})
85
+ runner.should_receive(:kill).with("18901") do
86
+ RSpec.reset
87
+ runner.stub(:mirage_process_ids).with([7001]).and_return({})
88
+ end
89
+
90
+ Mirage::Runner.should_receive(:new).and_return(runner)
91
+ runner.invoke(:stop, [], options)
92
+ end
93
+
94
+ it 'should stop the instance running on the given ports' do
95
+ options = {:port => [7001, 7002]}
96
+ runner = Mirage::Runner.new
97
+ runner.options = options
98
+
99
+ runner.should_receive(:mirage_process_ids).with([7001, 7002]).and_return({"7001" => "18901", "7002" => "18902"})
100
+ runner.should_receive(:kill).with("18901")
101
+ runner.should_receive(:kill).with("18902") do
102
+ RSpec.reset
103
+ runner.stub(:mirage_process_ids).with([7001, 7002]).and_return({})
104
+ end
105
+
106
+ Mirage::Runner.should_receive(:new).and_return(runner)
107
+ runner.invoke(:stop, [], options)
108
+ end
109
+
110
+ it 'should stop all running instances' do
111
+ options = {:port => [:all]}
112
+ runner = Mirage::Runner.new
113
+ runner.options = options
114
+
115
+ runner.should_receive(:mirage_process_ids).with([:all]).and_return({"7001" => "18901", "7002" => "18902"})
116
+ runner.should_receive(:kill).with("18901")
117
+ runner.should_receive(:kill).with("18902") do
118
+ RSpec.reset
119
+ runner.stub(:mirage_process_ids).with([:all]).and_return({})
120
+ end
121
+
122
+ Mirage::Runner.should_receive(:new).and_return(runner)
123
+ runner.invoke(:stop, [], options)
124
+
125
+ end
126
+
127
+ it 'should not error when asked to stop Mirage on a port that it is not running on' do
128
+ options = {:port => [7001]}
129
+ runner = Mirage::Runner.new
130
+ runner.options = options
131
+ runner.stub(:mirage_process_ids).with([7001]).and_return({})
132
+
133
+ Mirage::Runner.should_receive(:new).and_return(runner)
134
+ expect { runner.invoke(:stop, [], options) }.not_to raise_error
135
+ end
136
+
137
+ end
138
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'mirage/client'
3
+
4
+
5
+
6
+ describe Template::Configuration do
7
+
8
+ it 'should have defaults' do
9
+ configuration = Template::Configuration.new
10
+ assert_defaults configuration
11
+ end
12
+
13
+ it 'should be reset' do
14
+ configuration = Template::Configuration.new
15
+ configuration.http_method :post
16
+ configuration.status 202
17
+ configuration.delay 3
18
+ configuration.default true
19
+ configuration.content_type "text/xml"
20
+
21
+ configuration.reset
22
+ assert_defaults configuration
23
+ end
24
+
25
+ def assert_defaults configuration
26
+ configuration.http_method.should == :get
27
+ configuration.status.should == 200
28
+ configuration.delay.should == 0
29
+ configuration.default.should == false
30
+ configuration.content_type.should == "text/plain"
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ describe 'CommonMethods' do
3
+ let!(:model) do
4
+ Class.new do
5
+ include Template::Model::CommonMethods
6
+ end
7
+ end
8
+
9
+ let!(:instance) do
10
+ model.new
11
+ end
12
+ it 'should provide methods for customising the model' do
13
+ instance.methods.should include(:content_type,
14
+ :http_method,
15
+ :default,
16
+ :status,
17
+ :delay,
18
+ :required_parameters,
19
+ :required_body_content,
20
+ :required_headers,
21
+ :endpoint,
22
+ :headers,
23
+ :body)
24
+ end
25
+ end
@@ -0,0 +1,169 @@
1
+ require 'spec_helper'
2
+
3
+ describe Template::Model::InstanceMethods do
4
+
5
+
6
+ let!(:model) do
7
+ Class.new do
8
+ include Template::Model::InstanceMethods
9
+ end
10
+ end
11
+
12
+ let!(:instance) do
13
+ model.new '', ''
14
+ end
15
+
16
+
17
+ context 'initialize' do
18
+
19
+ it 'requires an endpoint' do
20
+ endpoint = 'value'
21
+ instance = model.new endpoint
22
+ instance.endpoint.should == endpoint
23
+ end
24
+
25
+ it 'requires an endpoint and value to be provided' do
26
+ endpoint, value = 'endpoint', 'value'
27
+ instance = model.new endpoint, value
28
+ instance.endpoint.should == endpoint
29
+ instance.body.should == value
30
+ end
31
+
32
+ it 'can use configuration for all http related config' do
33
+ config = Mirage::Template::Configuration.new
34
+ config.content_type 'content_type'
35
+ config.http_method 'method'
36
+ config.status 'status'
37
+ config.default true
38
+
39
+ instance = model.new 'endpoint', 'value', config
40
+ instance.content_type.should == config.content_type
41
+ instance.http_method.should == config.http_method
42
+ instance.status.should == config.status
43
+ instance.default.should == config.default
44
+
45
+ instance = model.new 'endpoint', config
46
+ instance.content_type.should == config.content_type
47
+ instance.http_method.should == config.http_method
48
+ instance.status.should == config.status
49
+ instance.default.should == config.default
50
+ end
51
+ end
52
+
53
+ context 'to_json' do
54
+ describe 'response body' do
55
+ it 'should base64 encode response values' do
56
+ value = "value"
57
+ response = model.new "endpoint", value
58
+ JSON.parse(response.to_json)["response"]["body"].should == Base64.encode64(value)
59
+ end
60
+ end
61
+
62
+ describe 'required request parameters' do
63
+
64
+ it 'should contain expected request parameters' do
65
+ required_parameters = {:key => "value"}
66
+ instance.required_parameters required_parameters
67
+ JSON.parse(instance.to_json)["request"]["parameters"].should == convert_keys_to_strings(required_parameters)
68
+ end
69
+
70
+ it 'should encode parameter requirements that are regexs' do
71
+ instance.required_parameters({:key => /regex/})
72
+ JSON.parse(instance.to_json)["request"]["parameters"].should == convert_keys_to_strings({:key => "%r{regex}"})
73
+ end
74
+ end
75
+
76
+ describe 'required body content' do
77
+ it 'should contain expected body content' do
78
+ required_body_content = ["body content"]
79
+ instance.required_body_content required_body_content
80
+ JSON.parse(instance.to_json)["request"]["body_content"].should == required_body_content
81
+ end
82
+
83
+ it 'should encode body content requirements that are regexs' do
84
+ instance.required_body_content [/regex/]
85
+ JSON.parse(instance.to_json)["request"]["body_content"].should == %w(%r{regex})
86
+ end
87
+ end
88
+
89
+ describe 'required headers' do
90
+ it 'should contain expected headers' do
91
+ required_headers = {:header => "value"}
92
+ instance.required_headers required_headers
93
+ JSON.parse(instance.to_json)["request"]["headers"].should == convert_keys_to_strings(required_headers)
94
+ end
95
+
96
+ it 'should encode header requirements that are regexs' do
97
+ instance.required_headers({:header => /regex/})
98
+ JSON.parse(instance.to_json)["request"]["headers"].should == convert_keys_to_strings(:header => "%r{regex}")
99
+ end
100
+ end
101
+
102
+ describe 'delay' do
103
+ it 'should default to 0' do
104
+ JSON.parse(instance.to_json)["response"]["delay"].should == 0
105
+ end
106
+
107
+ it 'should set the delay' do
108
+ delay = 5
109
+ instance.delay delay
110
+ JSON.parse(instance.to_json)["response"]["delay"].should == delay
111
+ end
112
+ end
113
+
114
+ describe 'status code' do
115
+ it 'should default to 200' do
116
+ JSON.parse(instance.to_json)["response"]["status"].should == 200
117
+ end
118
+
119
+ it 'should set the status' do
120
+ status = 404
121
+ instance.status status
122
+ JSON.parse(instance.to_json)["response"]["status"].should == status
123
+ end
124
+ end
125
+
126
+ describe 'http method' do
127
+ it 'should default to get' do
128
+ JSON.parse(instance.to_json)["request"]["http_method"].should == "get"
129
+ end
130
+
131
+ it 'should set the http method' do
132
+ method = :post
133
+ instance.http_method(method)
134
+ JSON.parse(instance.to_json)["request"]["http_method"].should == "post"
135
+ end
136
+ end
137
+
138
+ describe 'response as default' do
139
+ it 'should be false by default' do
140
+ JSON.parse(instance.to_json, symbolize_names: true)[:response][:default].should == false
141
+ end
142
+
143
+ it 'should set the default value' do
144
+ default = true
145
+ instance.default(default)
146
+ JSON.parse(instance.to_json)["response"]["default"].should == default
147
+ end
148
+ end
149
+
150
+ describe 'content type' do
151
+ it 'should be text/plain by default' do
152
+ JSON.parse(instance.to_json)["response"]["content_type"].should == "text/plain"
153
+ end
154
+
155
+ it 'should set the default value' do
156
+ content_type = "application/json"
157
+ instance.content_type content_type
158
+ JSON.parse(instance.to_json)["response"]["content_type"].should == content_type
159
+ end
160
+ end
161
+
162
+ it 'should set headers' do
163
+ header, value = 'header', 'value'
164
+ instance.headers[header] = value
165
+ JSON.parse(instance.to_json)["response"]["headers"].should == {header => value}
166
+ end
167
+ end
168
+
169
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ describe Template::Model do
4
+ let(:endpoint) { 'endpoint' }
5
+ let!(:test_class) do
6
+ Class.new do
7
+ extend Template::Model
8
+
9
+ endpoint 'endpoint'
10
+
11
+ def initialize
12
+ super
13
+ end
14
+ end
15
+ end
16
+ context 'class' do
17
+ it 'should extend MethodBuilder and CommonMethods' do
18
+ test_class.is_a?(Helpers::MethodBuilder).should == true
19
+ test_class.is_a?(Template::Model::CommonMethods).should == true
20
+ end
21
+
22
+ it 'should include Instance methods' do
23
+ test_class.is_a?(Template::Model::CommonMethods).should == true
24
+ end
25
+
26
+ context 'inherited constructor' do
27
+ it 'should set the endpoint of the class' do
28
+ test_class.new.endpoint.should == 'endpoint'
29
+ end
30
+
31
+ it 'calls to super should not fail if a constructor has been defined that takes args' do
32
+ test_class.class_eval do
33
+ def initialize arg
34
+ super
35
+ end
36
+ end
37
+ test_class.new('arg').endpoint.should == endpoint
38
+
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ context 'instances' do
45
+ it 'should have instance methods included' do
46
+ test_class.ancestors.should include(Template::Model::InstanceMethods)
47
+ end
48
+
49
+
50
+ it 'should include httparty' do
51
+ test_class.ancestors.should include(HTTParty)
52
+ end
53
+
54
+ describe 'defaults' do
55
+
56
+ it 'should be default the endpoint' do
57
+ endpoint = 'endpoint'
58
+ test_class.endpoint endpoint
59
+ test_class.new.endpoint.should == endpoint
60
+ end
61
+
62
+ it 'should be default the status' do
63
+ status = 404
64
+ test_class.status status
65
+ test_class.new.status.should == status
66
+ end
67
+
68
+ it 'should be default the content-type' do
69
+ content_type = 'application/json'
70
+ test_class.content_type content_type
71
+ test_class.new.content_type.should == content_type
72
+ end
73
+
74
+ it 'should be default the http_method' do
75
+ method = :post
76
+ test_class.http_method method
77
+ test_class.new.http_method.should == method
78
+ end
79
+
80
+ it 'should be default the default status' do
81
+ default = true
82
+ test_class.default default
83
+ test_class.new.default.should == default
84
+ end
85
+
86
+ it 'should be default the required parameters' do
87
+ required_parameters = {name: 'joe'}
88
+ test_class.required_parameters required_parameters
89
+ test_class.new.required_parameters.should == required_parameters
90
+ end
91
+
92
+ it 'should be default the required headers' do
93
+ headers = {name: 'joe'}
94
+ test_class.required_headers headers
95
+ test_class.new.required_headers.should == headers
96
+ end
97
+
98
+ it 'should be default the required body content' do
99
+ content = ['content']
100
+ test_class.required_body_content content
101
+ test_class.new.required_body_content.should == content
102
+ end
103
+
104
+ it 'should be default the headers' do
105
+ headers = {name: 'joe'}
106
+ test_class.headers headers
107
+ test_class.new.headers.should == headers
108
+ end
109
+
110
+ it 'should be default the delay' do
111
+ delay = 4
112
+ test_class.delay delay
113
+ test_class.new.delay.should == delay
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ end