poisol 0.1.8 → 0.1.10
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.
- checksums.yaml +4 -4
- data/README.md +242 -34
- data/lib/poisol/domain.rb +1 -1
- data/lib/poisol/server.rb +2 -2
- data/lib/poisol/stub/response/response_body_builder.rb +1 -1
- data/lib/poisol/stub/stub_builder_instance.rb +13 -9
- data/lib/poisol/stub_config/stub_config.rb +1 -1
- data/lib/poisol/stub_config/stub_config_builder.rb +8 -0
- data/lib/poisol/stub_mapper/request_matcher.rb +1 -0
- data/lib/poisol/stub_mapper/response_mapper.rb +4 -5
- data/lib/poisol/stub_mapper/stubs.rb +1 -2
- data/spec/data/main/query/book.yml +2 -2
- data/spec/data/main/query/book_explicit.yml +2 -0
- data/spec/data/main/query/book_optional.yml +18 -0
- data/spec/functional/query/query_explicit_spec.rb +10 -4
- data/spec/functional/query/query_implicit_spec.rb +5 -5
- data/spec/functional/query/query_optional_spec.rb +15 -0
- data/spec/unit/stubs_spec.rb +12 -0
- metadata +29 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34bc0f6127f9644eba49c984a2ef64d71e1020ed
|
4
|
+
data.tar.gz: 899e509e87aa934d351895a465cb2206242decdc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d310b68c98b9ce80f4f3869b6d4fd140b46e6eedf3d1202661a3f88d53175fa41a287a7fa0921a08885ffd4aecb2883792981e9d907a10ed0c047e5f45662fdd
|
7
|
+
data.tar.gz: e4e2669aa1bd819a962aebc537b2a1518dbd1c2ad0d9d4725d90a4b2d15705fb36a08d7c72f1ffcffad4da9668344f0ea2d2a6b96acfa2ee4048b869eced1fc6
|
data/README.md
CHANGED
@@ -2,10 +2,12 @@
|
|
2
2
|
[](https://travis-ci.org/paramadeep/poisol) [](https://gemnasium.com/paramadeep/poisol) [](https://codeclimate.com/github/paramadeep/poisol)
|
3
3
|
|
4
4
|
#Poisol
|
5
|
+
Poisol provides builder DSL to stub http endpoints. Similar to models and fixtures (factorygirl) used to set test data in database.
|
5
6
|
|
6
|
-
|
7
|
+
##Why yet another stub
|
8
|
+
Using other stub frameworks, had to do clumsy manipulation of the url's and json's to setup different scenarios for tests.
|
7
9
|
|
8
|
-
|
10
|
+
Poisol is a logical evolution in an attempt to define base stub data, and a most flexible/precise DSL to specify the required variation.
|
9
11
|
|
10
12
|
###Example
|
11
13
|
|
@@ -13,20 +15,20 @@ Stubbing a http service that provides user identification, gets as simple as
|
|
13
15
|
|
14
16
|
```ruby
|
15
17
|
User.new.for_name('Joe').has_role('buyer').build
|
16
|
-
# => stub that
|
18
|
+
# => stub http://localhost:3030/user?name=Joe that returns {"role":"buyer"}
|
17
19
|
|
18
20
|
User.new.for_name('Mani').has_role('Manager').build
|
19
|
-
# => stub that
|
21
|
+
# => stub http://localhost:3030/user?name=Mani that returns {"role":"Manager"}
|
20
22
|
|
21
23
|
User.new.build
|
22
|
-
# => stub that
|
24
|
+
# => stub http://localhost:3030/user?name=Raji that returns {"role":"Singer"}
|
23
25
|
```
|
24
26
|
given a minimal configuration
|
25
27
|
|
26
28
|
```yaml
|
27
29
|
#user.yml
|
28
30
|
request:
|
29
|
-
url:
|
31
|
+
url: user
|
30
32
|
query:
|
31
33
|
name: "Raji"
|
32
34
|
response:
|
@@ -41,7 +43,6 @@ It handles complex request and responses, like array, nested array, array having
|
|
41
43
|
The following can be dynamically configured, through the builders available
|
42
44
|
- Request
|
43
45
|
- url
|
44
|
-
- method*
|
45
46
|
- query params
|
46
47
|
- request body
|
47
48
|
- Response
|
@@ -49,17 +50,6 @@ The following can be dynamically configured, through the builders available
|
|
49
50
|
- header*
|
50
51
|
- response body
|
51
52
|
|
52
|
-
## Prepositions
|
53
|
-
|
54
|
-
| Preposition | for defining |
|
55
|
-
| ----: | :---- |
|
56
|
-
| of | url |
|
57
|
-
| for | query params |
|
58
|
-
| by | request body filed/array item |
|
59
|
-
| having | request body array item field |
|
60
|
-
| has | response body field/array item |
|
61
|
-
| with | response body array item field |
|
62
|
-
|
63
53
|
##Usage
|
64
54
|
|
65
55
|
In your project Gemfile add
|
@@ -79,12 +69,13 @@ require 'poisol'
|
|
79
69
|
Before do
|
80
70
|
if $poisol_loaded.blank?
|
81
71
|
Poisol.start #starts the stub server
|
82
|
-
Poisol.load "
|
83
|
-
#Poisol.load "
|
84
|
-
#
|
72
|
+
Poisol.load "stubs/cost"
|
73
|
+
#Poisol.load "<--location of the stub configs folder-->"
|
74
|
+
#loads the configs as stub builders
|
85
75
|
$poisol_loaded = true
|
86
76
|
end
|
87
|
-
Poisol.reset_data
|
77
|
+
Poisol.reset_data
|
78
|
+
#clears the stubs configured prior, hence every test is independent
|
88
79
|
end
|
89
80
|
|
90
81
|
at_exit do
|
@@ -100,14 +91,15 @@ require 'poisol'
|
|
100
91
|
RSpec.configure do |config|
|
101
92
|
|
102
93
|
config.before(:each) do
|
103
|
-
Poisol.reset_data
|
94
|
+
Poisol.reset_data
|
95
|
+
#clears the stubs configured prior, hence every test is independent
|
104
96
|
end
|
105
97
|
|
106
98
|
config.before(:suite) do
|
107
99
|
Poisol.start #starts the stub server
|
108
|
-
Poisol.load "
|
109
|
-
#Poisol.load "
|
110
|
-
#
|
100
|
+
Poisol.load "stubs/cost"
|
101
|
+
#Poisol.load "<--location of the stub configs folder-->"
|
102
|
+
#loads the configs as stub builders
|
111
103
|
end
|
112
104
|
|
113
105
|
config.after(:suite) do
|
@@ -117,22 +109,238 @@ RSpec.configure do |config|
|
|
117
109
|
end
|
118
110
|
```
|
119
111
|
### Port
|
120
|
-
By default, on Poisol.start will start the stub server in port
|
112
|
+
By default, on Poisol.start will start the stub server in port 3030, we can change the default port.
|
113
|
+
```ruby
|
114
|
+
Poisol.start(:port=>3333)
|
115
|
+
#=> Stub server runs with address http://localhost:3333
|
116
|
+
```
|
117
|
+
|
118
|
+
####Stubs Config
|
119
|
+
For each service that is stubbed, configuration of all endpoints are kept inside corresponding service's folder.
|
120
|
+
```ruby
|
121
|
+
Poisol.load "<--location of the stub configs folder-->"
|
122
|
+
#loads the configs as stub builders
|
123
|
+
#Poisol.load "stubs/cost"
|
124
|
+
#Poisol.load "stubs/exchange"
|
125
|
+
#Poisol.load "stubs/sms"
|
126
|
+
```
|
127
|
+
The below stubs folder will yield
|
121
128
|
|
122
|
-
|
123
|
-
|
129
|
+
1. Cost service servers two enpoints. Gross Cost and Net Cost.
|
130
|
+
2. Excahange service serves two endpoints. Rupee and Yen.
|
131
|
+
3. SMS service service serves one endpoint. Send SMS.
|
132
|
+
```
|
133
|
+
.
|
134
|
+
── stubs
|
135
|
+
├── cost
|
136
|
+
│ ├── domain.yml
|
137
|
+
│ └── gross_cost.yml
|
138
|
+
│ └── net_cost.yml
|
139
|
+
├── exchange
|
140
|
+
│ ├── domain.yml
|
141
|
+
│ └── rupee.yml
|
142
|
+
│ └── yen.yml
|
143
|
+
└── sms
|
144
|
+
├── domain.yml
|
145
|
+
└── send_sms.yml
|
146
|
+
|
147
|
+
```
|
148
|
+
#### Domain
|
149
|
+
In the above example each service folder contains a file called "domain.yml" which contain domain information of a specific service.
|
150
|
+
|
151
|
+
```yml
|
152
|
+
#stubs/cost/domain.yml
|
153
|
+
sub_domain: "cost"
|
154
|
+
```
|
155
|
+
hence cost service will be served at url, "http://localhost:3030/cost"
|
156
|
+
|
157
|
+
```yml
|
158
|
+
#stubs/exchange/domain.yml
|
159
|
+
sub_domain: "exchange/currency"
|
160
|
+
```
|
161
|
+
hence exchange service will be served at url, "http://localhost:3030/exchange/currency"
|
124
162
|
|
125
163
|
## Builders
|
126
|
-
|
164
|
+
For every stub configuration file as they are loaded by Poisol, a builder class gets created dynamically. Which on building creates a stub for the endpoint.
|
165
|
+
```ruby
|
166
|
+
#cost\gross_cost.yml => GrossCost
|
167
|
+
GrossCost.new.build
|
168
|
+
#sms\send_sms.yml => SendSms
|
169
|
+
SendSms.new.build
|
170
|
+
```
|
171
|
+
By default, without any modifiers mentioned, builder builds stub for the endpoint with the default values as mentioned in the configuration file.
|
172
|
+
|
173
|
+
###URL
|
127
174
|
```yml
|
128
|
-
#
|
175
|
+
#cost/gross_cost.yml
|
129
176
|
request:
|
130
|
-
url:
|
131
|
-
|
177
|
+
url: gross/{article|"soap"}/{area|"chennai"}
|
178
|
+
method: get
|
179
|
+
response:
|
180
|
+
body: '{"hi"}'
|
181
|
+
```
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
GrossCost.new.build
|
185
|
+
#=> builds localhost:3030/cost/gross/soap/chennai
|
132
186
|
```
|
187
|
+
Using "of_[place_holder]" method corresponding value can be modified.
|
188
|
+
```ruby
|
189
|
+
GrossCost.new.of_article("tooth_paste").of_area("mumbai").build
|
190
|
+
#=> builds localhost:3030/cost/gross/tooth_paste/mumbai
|
191
|
+
```
|
192
|
+
###Query Params
|
193
|
+
```yml
|
194
|
+
#cost/gross_cost.yml
|
195
|
+
request:
|
196
|
+
url: gross
|
197
|
+
query:
|
198
|
+
article: "soap"
|
199
|
+
area: "chennai"
|
200
|
+
response:
|
201
|
+
body: '{"hi"}'
|
202
|
+
```
|
203
|
+
```ruby
|
204
|
+
GrossCost.new.build
|
205
|
+
#=> builds localhost:3030/cost/gross?article=soap&area=chennai
|
206
|
+
```
|
207
|
+
Using "for_[param_name]" method corresponding query param value can be modified.
|
208
|
+
```ruby
|
209
|
+
GrossCost.new.for_article("tooth_paste").build
|
210
|
+
#=> builds localhost:3030/cost/gross?article=tooth_paste&area=chennai
|
211
|
+
GrossCost.new.for_area("mumbai").build
|
212
|
+
#=> builds localhost:3030/cost/gross?article=soap&area=mumbai
|
213
|
+
```
|
214
|
+
Using "for" method which takes a hash-map as parameter, all or partial list of query params can be modified.
|
215
|
+
```ruby
|
216
|
+
GrossCost.new.for({article=>"tooth_paste",:area=>"mumbai"}).build
|
217
|
+
#=> builds localhost:3030/cost/gross?article=tooth_paste&area=mumbai
|
218
|
+
GrossCost.new.for({:area=>"mumbai"}).build
|
219
|
+
#=> builds localhost:3030/cost/gross?article=soap&area=mumbai
|
220
|
+
```
|
221
|
+
If some of your query params are optional, you can require them to be explicitly declared using the `query_explicit` directive.
|
222
|
+
```yml
|
223
|
+
request:
|
224
|
+
url: book_explicit
|
225
|
+
method: get
|
226
|
+
query_explicit: true
|
227
|
+
query:
|
228
|
+
author: "bharathi"
|
229
|
+
name: "doni"
|
230
|
+
response:
|
231
|
+
body: '{
|
232
|
+
"title": "independance",
|
233
|
+
"category": {
|
234
|
+
"age_group": "10",
|
235
|
+
"genre": "action",
|
236
|
+
"publisher": {
|
237
|
+
"name": "summa",
|
238
|
+
"place":"erode"
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}'
|
242
|
+
```
|
243
|
+
```ruby
|
244
|
+
BookExplicit.new.for_author('bha').build()
|
245
|
+
#=> builds http://localhost:3030/book_explicit?author=bha
|
246
|
+
```
|
247
|
+
Note that the `name` query parameter is not explicitly declared and is therefore ignored.
|
248
|
+
### Status
|
249
|
+
```yml
|
250
|
+
#cost/gross_cost.yml
|
251
|
+
request:
|
252
|
+
url: gross
|
253
|
+
response:
|
254
|
+
body: '{"hi"}'
|
255
|
+
```
|
256
|
+
When no status is mentioned, the default status is 200
|
257
|
+
```ruby
|
258
|
+
GrossCost.new.build
|
259
|
+
#=> builds localhost:3030/cost/gross which returns status 200
|
260
|
+
```
|
261
|
+
Using "status" method, status value is modified
|
262
|
+
```ruby
|
263
|
+
GrossCost.new.status(404).build
|
264
|
+
#=> builds localhost:3030/cost/gross which returns status 404
|
265
|
+
```
|
266
|
+
###Response Body
|
267
|
+
```yml
|
268
|
+
#cost/gross_cost.yml
|
269
|
+
request:
|
270
|
+
url: gross
|
271
|
+
response:
|
272
|
+
body: '{
|
273
|
+
"cost":2,
|
274
|
+
"currency":"rupee"
|
275
|
+
}'
|
276
|
+
```
|
277
|
+
```ruby
|
278
|
+
GrossCost.new.build
|
279
|
+
#=> builds localhost:3030/cost/gross which returns {"cost":2,"currency"=>"rupee"}
|
280
|
+
```
|
281
|
+
Using "has_[field_name]" method value of the field can be modified.
|
282
|
+
```ruby
|
283
|
+
GrossCost.new.has_cost(10).has_currency("dollar").build
|
284
|
+
#=> builds localhost:3030/cost/gross which returns {"cost":10,"currency":"dollar"}
|
285
|
+
GrossCost.new.has_currency("pound").build
|
286
|
+
#=> builds localhost:3030/cost/gross which returns {"cost":2,"currency":"pound"}
|
287
|
+
```
|
288
|
+
Using "has" method which takes a hash-map as parameter, all or partial list of fields can be modified.
|
289
|
+
```ruby
|
290
|
+
GrossCost.new.has(:cost=>10,:currency=>"dollar").build
|
291
|
+
#=> builds localhost:3030/cost/gross which returns {"cost":10,"currency":"dollar"}
|
292
|
+
GrossCost.new.has(:currency=>"pound").build
|
293
|
+
#=> builds localhost:3030/cost/gross which returns {"cost":2,"currency":"pound"}
|
294
|
+
```
|
295
|
+
######[Handling array in response body](https://github.com/paramadeep/poisol/wiki/Response-Body)
|
296
|
+
###Request Body
|
297
|
+
```yml
|
298
|
+
#cost/gross_cost.yml
|
299
|
+
request:
|
300
|
+
url: gross
|
301
|
+
method: post
|
302
|
+
body: '{
|
303
|
+
"article":"soap",
|
304
|
+
"cost":1
|
305
|
+
}'
|
306
|
+
```
|
307
|
+
```ruby
|
308
|
+
GrossCost.new.build
|
309
|
+
#=> builds post localhost:3030/cost/gross which takes {"aticle":"soap","cost"=>1}
|
310
|
+
```
|
311
|
+
Using "by_[field_name]" method value of the field can be modified.
|
312
|
+
```ruby
|
313
|
+
GrossCost.new.by_cost(10).by_article("tooth_paste").build
|
314
|
+
#=> builds post localhost:3030/cost/gross which takes {"aticle":"tooth_paste","cost"=>10}
|
315
|
+
GrossCost.new.by_cost(2).build
|
316
|
+
#=> builds post localhost:3030/cost/gross which takes {"aticle":"soap","cost"=>2}
|
317
|
+
```
|
318
|
+
Using "by" method which takes a hash-map as parameter, all or partial list of fields can be modified.
|
319
|
+
```ruby
|
320
|
+
GrossCost.new.by(:cost=>10,:article=>"tooth_paste").build
|
321
|
+
#=> builds post localhost:3030/cost/gross which takes {"aticle":"tooth_paste","cost"=>10}
|
322
|
+
GrossCost.new.by(:cost=>2).build
|
323
|
+
#=> builds post localhost:3030/cost/gross which takes {"aticle":"soap","cost"=>2}
|
324
|
+
```
|
325
|
+
######[Handling array in request body](https://github.com/paramadeep/poisol/wiki/Request-Body)
|
326
|
+
|
327
|
+
## Prepositions
|
328
|
+
|
329
|
+
| Preposition | for defining |
|
330
|
+
| ----: | :---- |
|
331
|
+
| of | url |
|
332
|
+
| for | query params |
|
333
|
+
| by | request body filed/array item |
|
334
|
+
| having | request body array item field |
|
335
|
+
| has | response body field/array item |
|
336
|
+
| with | response body array item field |
|
133
337
|
|
134
338
|
|
135
339
|
|
136
340
|
##ToDo
|
341
|
+
* Allow regex defenition and matching of request
|
342
|
+
* Use part of request as part of response, dynamically.
|
343
|
+
* Setting response for multiple hits.
|
344
|
+
* Configuring time delay for responses
|
137
345
|
* Make header configurable
|
138
|
-
* Ensure contract mentioned
|
346
|
+
* Ensure contract mentioned cannot be changed
|
data/lib/poisol/domain.rb
CHANGED
data/lib/poisol/server.rb
CHANGED
@@ -8,7 +8,7 @@ module Poisol
|
|
8
8
|
stub_response = Poisol::ResponseMapper.map(req)
|
9
9
|
res.status = stub_response.status
|
10
10
|
res.body = stub_response.body.to_json
|
11
|
-
res.
|
11
|
+
res.header.merge! stub_response.header
|
12
12
|
end
|
13
13
|
alias do_DELETE do_GET
|
14
14
|
alias do_POST do_GET
|
@@ -49,7 +49,7 @@ module Poisol
|
|
49
49
|
def access_log
|
50
50
|
log_file = File.open 'log/poisol_webrick.log', 'a+'
|
51
51
|
[
|
52
|
-
[log_file, WEBrick::AccessLog::COMBINED_LOG_FORMAT],
|
52
|
+
[log_file, "#{WEBrick::AccessLog::COMBINED_LOG_FORMAT} %T"],
|
53
53
|
]
|
54
54
|
end
|
55
55
|
|
@@ -3,7 +3,7 @@ module Poisol
|
|
3
3
|
|
4
4
|
def prepare_response_body
|
5
5
|
return if @stub_config.response.body.blank?
|
6
|
-
if @stub_config.response.is_column_array or @stub_config.response.is_row_array
|
6
|
+
if @stub_config.response.is_column_array or @stub_config.response.is_row_array
|
7
7
|
make_methods_to_alter_response_array
|
8
8
|
else
|
9
9
|
make_methods_to_alter_response_object
|
@@ -16,13 +16,17 @@ module Poisol
|
|
16
16
|
|
17
17
|
def init_response
|
18
18
|
@response = Response.new
|
19
|
-
if
|
20
|
-
@response.body = [stub_config.response.body.deep_dup]
|
19
|
+
if stub_config.response.is_column_array or stub_config.response.is_row_array
|
20
|
+
@response.body = [stub_config.response.body.deep_dup]
|
21
21
|
else
|
22
22
|
@response.body = stub_config.response.body.deep_dup
|
23
23
|
end
|
24
24
|
@response.status = 200
|
25
|
+
|
25
26
|
@response.header = {'Content-Type' => 'application/json'}
|
27
|
+
if (stub_config.response.header)
|
28
|
+
@response.header.merge! stub_config.response.header
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
def set_dumb_response response_file
|
@@ -31,10 +35,10 @@ module Poisol
|
|
31
35
|
self
|
32
36
|
end
|
33
37
|
|
34
|
-
def get_assignment_value actual_field_value,input_value
|
35
|
-
if
|
38
|
+
def get_assignment_value actual_field_value, input_value
|
39
|
+
if actual_field_value.class.to_s == "Hash"
|
36
40
|
input_value = {} if input_value.blank?
|
37
|
-
actual_field_value.deep_merge(input_value.stringify_keys)
|
41
|
+
actual_field_value.deep_merge(input_value.stringify_keys)
|
38
42
|
else
|
39
43
|
input_value
|
40
44
|
end
|
@@ -56,18 +60,18 @@ module Poisol
|
|
56
60
|
self
|
57
61
|
end
|
58
62
|
|
59
|
-
def
|
60
|
-
@request.query.deep_merge! input_hash.
|
63
|
+
def for input_hash
|
64
|
+
@request.query.deep_merge! input_hash.stringify_keys
|
61
65
|
self
|
62
66
|
end
|
63
67
|
|
64
|
-
def
|
68
|
+
def status input
|
65
69
|
@response.status = input
|
66
70
|
self
|
67
71
|
end
|
68
72
|
|
69
73
|
def remove_array_field_calls
|
70
|
-
method_of_array_fileds_of_array = self.methods.select{|method_name|method_name.to_s.start_with?"with_"}
|
74
|
+
method_of_array_fileds_of_array = self.methods.select { |method_name| method_name.to_s.start_with? "with_" }
|
71
75
|
@called_methods = @called_methods - method_of_array_fileds_of_array
|
72
76
|
end
|
73
77
|
end
|
@@ -77,6 +77,14 @@ module Poisol
|
|
77
77
|
def build_response
|
78
78
|
@stub_config.is_inline ? load_inline_response_body : load_exploaded_response_body
|
79
79
|
load_resonse_array_type
|
80
|
+
load_header
|
81
|
+
end
|
82
|
+
|
83
|
+
def load_header
|
84
|
+
return if @raw_config_hash["response"].blank?
|
85
|
+
header = @raw_config_hash["response"]["header"]
|
86
|
+
return if header.blank?
|
87
|
+
@stub_config.response.header = header
|
80
88
|
end
|
81
89
|
|
82
90
|
def load_resonse_array_type
|
@@ -19,6 +19,7 @@ module Poisol
|
|
19
19
|
|
20
20
|
def query_matches? actual_req,stub_req
|
21
21
|
return true if actual_req.query==stub_req.query
|
22
|
+
return false if (actual_req.query.blank? || stub_req.query.blank?)
|
22
23
|
actual_query = CGI::parse(actual_req.query)
|
23
24
|
stub_query = CGI::parse(stub_req.query)
|
24
25
|
return matching_hashes? actual_query,stub_query
|
@@ -5,15 +5,14 @@ module Poisol
|
|
5
5
|
def map webrick_request
|
6
6
|
stub_request = get_stub_request webrick_request
|
7
7
|
PoisolLog.info stub_request.to_s
|
8
|
-
|
8
|
+
get_stub_response stub_request
|
9
9
|
end
|
10
10
|
|
11
11
|
def get_stub_request webrick_request
|
12
12
|
stub_request = Request.new
|
13
13
|
stub_request.type = webrick_request.request_method.downcase
|
14
|
-
|
15
|
-
stub_request.
|
16
|
-
stub_request.query = webrick_request.query_string
|
14
|
+
stub_request.url = webrick_request.request_uri.path
|
15
|
+
stub_request.query = webrick_request.query_string
|
17
16
|
stub_request.body = webrick_request.body
|
18
17
|
stub_request
|
19
18
|
end
|
@@ -26,7 +25,7 @@ module Poisol
|
|
26
25
|
raise "No match found for request: #{stub_request.to_s} "
|
27
26
|
end
|
28
27
|
PoisolLog.info JSON.pretty_generate(stub.response.body)
|
29
|
-
|
28
|
+
stub.response if stub.present?
|
30
29
|
end
|
31
30
|
|
32
31
|
def log_error request
|
@@ -20,7 +20,7 @@ module Poisol
|
|
20
20
|
return nil if @stubs.blank?
|
21
21
|
matches = @stubs.select{|stub| Poisol::RequestMatcher.matches? actual_request,stub.request}
|
22
22
|
return nil unless matches.present?
|
23
|
-
match = matches
|
23
|
+
match = matches.last
|
24
24
|
match.called_count = match.called_count + 1
|
25
25
|
return match
|
26
26
|
end
|
@@ -29,6 +29,5 @@ module Poisol
|
|
29
29
|
@stubs.select{|stub| stub.called_count ==0}
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
32
|
end
|
34
33
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
request:
|
2
|
+
url: book_optional
|
3
|
+
method: get
|
4
|
+
query_explicit: true
|
5
|
+
query:
|
6
|
+
author: "bharathi"
|
7
|
+
response:
|
8
|
+
body: '{
|
9
|
+
"title": "independance",
|
10
|
+
"category": {
|
11
|
+
"age_group": "10",
|
12
|
+
"genre": "action",
|
13
|
+
"publisher": {
|
14
|
+
"name": "summa",
|
15
|
+
"place":"erode"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}'
|
@@ -7,15 +7,21 @@ describe Poisol::Stub, "#query_explicit" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "full dymamic" do
|
10
|
-
Book.new.
|
11
|
-
response = RestClient.get "http://localhost:3030/book",{:params => {:
|
10
|
+
Book.new.for_author_id('1').for_author_name('don').build()
|
11
|
+
response = RestClient.get "http://localhost:3030/book",{:params => {:author_id=>'1',:author_name=>'don'}}
|
12
12
|
expect(response.body).to eq({"title"=>"independance", "category"=>{"age_group"=>"10", "genre"=>"action", "publisher"=>{"name"=>"summa", "place"=>"erode"}}}.to_json)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "full dymamic hash params" do
|
16
|
-
Book.new.for(:
|
17
|
-
response = RestClient.get "http://localhost:3030/book",{:params => {:
|
16
|
+
Book.new.for(:author_id => '1',:author_name =>'don').build
|
17
|
+
response = RestClient.get "http://localhost:3030/book",{:params => {:author_id=>'1',:author_name=>'don'}}
|
18
18
|
expect(response.body).to eq({"title"=>"independance", "category"=>{"age_group"=>"10", "genre"=>"action", "publisher"=>{"name"=>"summa", "place"=>"erode"}}}.to_json)
|
19
19
|
end
|
20
20
|
|
21
|
+
it "should be able to configure headers" do
|
22
|
+
BookExplicit.new.for_author('bha').build()
|
23
|
+
response = RestClient.get "http://localhost:3030/book_explicit",{:params => {:author=>'bha'}}
|
24
|
+
expect(response.headers[:content_language]).to eq("en")
|
25
|
+
end
|
26
|
+
|
21
27
|
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
describe Poisol::Stub, "#implicit query params" do
|
2
2
|
|
3
3
|
it "dynamic response" do
|
4
|
-
Book.new.
|
5
|
-
response = RestClient.get "http://localhost:3030/book",{:params => {:
|
4
|
+
Book.new.for_author_id("1").has_category({"age_group"=>"11", "publisher"=>{"name"=>"oxford"}}).build()
|
5
|
+
response = RestClient.get "http://localhost:3030/book",{:params => {:author_id=>'1',:author_name=>"doni"}}
|
6
6
|
expect(response.body).to eq({"title"=>"independance", "category"=>{"age_group"=>"11", "genre"=>"action", "publisher"=>{"name"=>"oxford", "place"=>"erode"}}}.to_json)
|
7
7
|
end
|
8
8
|
|
9
9
|
it "default request and response" do
|
10
10
|
Book.new.build()
|
11
|
-
response = RestClient.get "http://localhost:3030/book",{:params => {:
|
11
|
+
response = RestClient.get "http://localhost:3030/book",{:params => {:author_id=>'bharathi',:author_name=>"doni"}}
|
12
12
|
expect(response.body).to eq({"title"=>"independance", "category"=>{"age_group"=>"10", "genre"=>"action", "publisher"=>{"name"=>"summa", "place"=>"erode"}}}.to_json)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "hash params for query" do
|
16
|
-
Book.new.for(:
|
17
|
-
response = RestClient.get "http://localhost:3030/book",{:params => {:
|
16
|
+
Book.new.for(:author_id=>"1").build()
|
17
|
+
response = RestClient.get "http://localhost:3030/book",{:params => {:author_id=>'1',:author_name=>"doni"}}
|
18
18
|
expect(response.body).to eq({"title"=>"independance", "category"=>{"age_group"=>"10", "genre"=>"action", "publisher"=>{"name"=>"summa", "place"=>"erode"}}}.to_json)
|
19
19
|
end
|
20
20
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
describe Poisol::Stub, "#query_optional" do
|
2
|
+
|
3
|
+
it "with & without optional param" do
|
4
|
+
BookOptional.new.build
|
5
|
+
BookOptional.new.for_author('bha').build
|
6
|
+
|
7
|
+
response = RestClient.get "http://localhost:3030/book_optional",{:params => {:author=>'bha'}}
|
8
|
+
expect(response.body).to eq({"title"=>"independance", "category"=>{"age_group"=>"10", "genre"=>"action", "publisher"=>{"name"=>"summa", "place"=>"erode"}}}.to_json)
|
9
|
+
|
10
|
+
response = RestClient.get "http://localhost:3030/book_optional"
|
11
|
+
expect(response.body).to eq({"title"=>"independance", "category"=>{"age_group"=>"10", "genre"=>"action", "publisher"=>{"name"=>"summa", "place"=>"erode"}}}.to_json)
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
describe "adding and retiral of stubs" do
|
2
|
+
it "returns the last matching request" do
|
3
|
+
stub = Poisol::Stub.new
|
4
|
+
stub.request.url = "url"
|
5
|
+
stub.response.status = 200
|
6
|
+
Poisol::Stubs.add stub
|
7
|
+
stub.response.status = 300
|
8
|
+
Poisol::Stubs.add stub
|
9
|
+
matched_stub = Poisol::Stubs.get_match stub.request
|
10
|
+
expect(matched_stub.response.status).to eq 300
|
11
|
+
end
|
12
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poisol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Deepak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 4.2.0
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: 4.2.0
|
125
125
|
description: HTTP stub as DSL
|
126
126
|
email:
|
127
127
|
executables: []
|
@@ -164,6 +164,7 @@ files:
|
|
164
164
|
- spec/data/main/key_value/key_value.yml
|
165
165
|
- spec/data/main/query/book.yml
|
166
166
|
- spec/data/main/query/book_explicit.yml
|
167
|
+
- spec/data/main/query/book_optional.yml
|
167
168
|
- spec/data/main/response/array/columns.yml
|
168
169
|
- spec/data/main/response/array/rows.yml
|
169
170
|
- spec/data/main/response/nested_array.yml
|
@@ -179,6 +180,7 @@ files:
|
|
179
180
|
- spec/functional/post_request_spec.rb
|
180
181
|
- spec/functional/query/query_explicit_spec.rb
|
181
182
|
- spec/functional/query/query_implicit_spec.rb
|
183
|
+
- spec/functional/query/query_optional_spec.rb
|
182
184
|
- spec/functional/response/array_spec.rb
|
183
185
|
- spec/functional/response/dumb_response_spec.rb
|
184
186
|
- spec/functional/response/hash_params_spec.rb
|
@@ -190,6 +192,7 @@ files:
|
|
190
192
|
- spec/unit/extension/hash_spec.rb
|
191
193
|
- spec/unit/request_matcher_spec.rb
|
192
194
|
- spec/unit/stub_spec.rb
|
195
|
+
- spec/unit/stubs_spec.rb
|
193
196
|
homepage: https://github.com/paramadeep/poisol
|
194
197
|
licenses:
|
195
198
|
- MIT
|
@@ -210,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
213
|
version: '0'
|
211
214
|
requirements: []
|
212
215
|
rubyforge_project:
|
213
|
-
rubygems_version: 2.
|
216
|
+
rubygems_version: 2.4.5
|
214
217
|
signing_key:
|
215
218
|
specification_version: 4
|
216
219
|
summary: HTTP stub as DSL
|
@@ -219,35 +222,38 @@ test_files:
|
|
219
222
|
- spec/data/domain/first/first.yml
|
220
223
|
- spec/data/domain/second/domain.yml
|
221
224
|
- spec/data/domain/second/second.yml
|
222
|
-
- spec/data/main/
|
223
|
-
- spec/data/main/user/request.json
|
224
|
-
- spec/data/main/user/response.json
|
225
|
+
- spec/data/main/delete.yml
|
225
226
|
- spec/data/main/domain.yml
|
226
|
-
- spec/data/main/url.yml
|
227
227
|
- spec/data/main/key_value/explicit.yml
|
228
228
|
- spec/data/main/key_value/key_value.yml
|
229
|
-
- spec/data/main/
|
229
|
+
- spec/data/main/query/book.yml
|
230
|
+
- spec/data/main/query/book_explicit.yml
|
231
|
+
- spec/data/main/query/book_optional.yml
|
230
232
|
- spec/data/main/response/array/columns.yml
|
231
233
|
- spec/data/main/response/array/rows.yml
|
232
234
|
- spec/data/main/response/nested_array.yml
|
233
|
-
- spec/data/main/
|
234
|
-
- spec/data/main/
|
235
|
-
- spec/data/main/
|
236
|
-
- spec/
|
237
|
-
- spec/
|
238
|
-
- spec/unit/exception_spec.rb
|
239
|
-
- spec/unit/stub_spec.rb
|
240
|
-
- spec/spec_helper.rb
|
241
|
-
- spec/functional/wasted_spec.rb
|
242
|
-
- spec/functional/multi_domain_spec.rb
|
235
|
+
- spec/data/main/response/simple_response.yml
|
236
|
+
- spec/data/main/url.yml
|
237
|
+
- spec/data/main/user/config.yml
|
238
|
+
- spec/data/main/user/request.json
|
239
|
+
- spec/data/main/user/response.json
|
243
240
|
- spec/functional/delete_spec.rb
|
244
241
|
- spec/functional/key_value/explicit_inclusion_spec.rb
|
245
242
|
- spec/functional/key_value/implicit_inclusion_spec.rb
|
243
|
+
- spec/functional/multi_domain_spec.rb
|
246
244
|
- spec/functional/post_request_spec.rb
|
247
|
-
- spec/functional/
|
245
|
+
- spec/functional/query/query_explicit_spec.rb
|
246
|
+
- spec/functional/query/query_implicit_spec.rb
|
247
|
+
- spec/functional/query/query_optional_spec.rb
|
248
248
|
- spec/functional/response/array_spec.rb
|
249
249
|
- spec/functional/response/dumb_response_spec.rb
|
250
|
+
- spec/functional/response/hash_params_spec.rb
|
250
251
|
- spec/functional/response/nested_array_spec.rb
|
251
252
|
- spec/functional/url_spec.rb
|
252
|
-
- spec/functional/
|
253
|
-
- spec/
|
253
|
+
- spec/functional/wasted_spec.rb
|
254
|
+
- spec/spec_helper.rb
|
255
|
+
- spec/unit/exception_spec.rb
|
256
|
+
- spec/unit/extension/hash_spec.rb
|
257
|
+
- spec/unit/request_matcher_spec.rb
|
258
|
+
- spec/unit/stub_spec.rb
|
259
|
+
- spec/unit/stubs_spec.rb
|