raml_ruby 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +71 -0
  7. data/Rakefile +1 -0
  8. data/fixtures/include_1.raml +7 -0
  9. data/fixtures/schemas/canonicalSchemas.raml +3 -0
  10. data/fixtures/schemas/filesystem/file.json +1 -0
  11. data/fixtures/schemas/filesystem/files.json +1 -0
  12. data/fixtures/schemas/filesystem/fileupdate.json +1 -0
  13. data/fixtures/schemas/filesystem/relative/test.json +1 -0
  14. data/lib/raml.rb +104 -0
  15. data/lib/raml/exceptions.rb +27 -0
  16. data/lib/raml/mixin/bodies.rb +32 -0
  17. data/lib/raml/mixin/documentable.rb +32 -0
  18. data/lib/raml/mixin/global.rb +20 -0
  19. data/lib/raml/mixin/headers.rb +22 -0
  20. data/lib/raml/mixin/merge.rb +24 -0
  21. data/lib/raml/mixin/parent.rb +54 -0
  22. data/lib/raml/mixin/validation.rb +49 -0
  23. data/lib/raml/node.rb +219 -0
  24. data/lib/raml/node/abstract_method.rb +61 -0
  25. data/lib/raml/node/abstract_resource.rb +165 -0
  26. data/lib/raml/node/abstract_resource_circular.rb +5 -0
  27. data/lib/raml/node/body.rb +94 -0
  28. data/lib/raml/node/documentation.rb +28 -0
  29. data/lib/raml/node/header.rb +4 -0
  30. data/lib/raml/node/method.rb +106 -0
  31. data/lib/raml/node/parameter/abstract_parameter.rb +251 -0
  32. data/lib/raml/node/parameter/base_uri_parameter.rb +6 -0
  33. data/lib/raml/node/parameter/form_parameter.rb +6 -0
  34. data/lib/raml/node/parameter/query_parameter.rb +6 -0
  35. data/lib/raml/node/parameter/uri_parameter.rb +7 -0
  36. data/lib/raml/node/parametized_reference.rb +15 -0
  37. data/lib/raml/node/reference.rb +4 -0
  38. data/lib/raml/node/resource.rb +26 -0
  39. data/lib/raml/node/resource_type.rb +20 -0
  40. data/lib/raml/node/resource_type_reference.rb +5 -0
  41. data/lib/raml/node/response.rb +32 -0
  42. data/lib/raml/node/root.rb +246 -0
  43. data/lib/raml/node/schema.rb +41 -0
  44. data/lib/raml/node/schema_reference.rb +5 -0
  45. data/lib/raml/node/template.rb +55 -0
  46. data/lib/raml/node/trait.rb +18 -0
  47. data/lib/raml/node/trait_reference.rb +5 -0
  48. data/lib/raml/parser.rb +57 -0
  49. data/lib/raml/parser/include.rb +25 -0
  50. data/lib/raml/patch/hash.rb +6 -0
  51. data/lib/raml/patch/module.rb +12 -0
  52. data/lib/raml/version.rb +3 -0
  53. data/raml_ruby.gemspec +35 -0
  54. data/raml_spec_reqs.md +276 -0
  55. data/templates/abstract_parameter.slim +68 -0
  56. data/templates/body.slim +15 -0
  57. data/templates/collapse.slim +10 -0
  58. data/templates/documentation.slim +2 -0
  59. data/templates/method.slim +38 -0
  60. data/templates/resource.slim +33 -0
  61. data/templates/response.slim +13 -0
  62. data/templates/root.slim +39 -0
  63. data/templates/style.sass +119 -0
  64. data/test/apis/box-api.raml +4224 -0
  65. data/test/apis/instagram-api.raml +3378 -0
  66. data/test/apis/stripe-api.raml +12227 -0
  67. data/test/apis/twilio-rest-api.raml +6618 -0
  68. data/test/apis/twitter-rest-api.raml +34284 -0
  69. data/test/raml/body_spec.rb +268 -0
  70. data/test/raml/documentation_spec.rb +49 -0
  71. data/test/raml/header_spec.rb +17 -0
  72. data/test/raml/include_spec.rb +40 -0
  73. data/test/raml/method_spec.rb +701 -0
  74. data/test/raml/parameter/abstract_parameter_spec.rb +564 -0
  75. data/test/raml/parameter/form_parameter_spec.rb +17 -0
  76. data/test/raml/parameter/query_parameter_spec.rb +33 -0
  77. data/test/raml/parameter/uri_parameter_spec.rb +44 -0
  78. data/test/raml/parser_spec.rb +53 -0
  79. data/test/raml/raml_spec.rb +32 -0
  80. data/test/raml/resource_spec.rb +440 -0
  81. data/test/raml/resource_type_spec.rb +51 -0
  82. data/test/raml/response_spec.rb +251 -0
  83. data/test/raml/root_spec.rb +655 -0
  84. data/test/raml/schema_spec.rb +110 -0
  85. data/test/raml/spec_helper.rb +11 -0
  86. data/test/raml/template_spec.rb +98 -0
  87. data/test/raml/trait_spec.rb +31 -0
  88. metadata +337 -0
@@ -0,0 +1,564 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Raml::Parameter::AbstractParameter do
4
+ let(:abstract_param_class) { Raml::Parameter::AbstractParameter }
5
+ let(:root_data) { {'title' => 'x', 'baseUri' => 'http://foo.com'} }
6
+ let(:root) { Raml::Root.new root_data }
7
+ subject { abstract_param_class.new(name, parameter_data, root) }
8
+
9
+ describe '#new' do
10
+ let(:name) { 'page_number' }
11
+ let(:parameter_data) {
12
+ {
13
+ type: 'integer',
14
+ required: true,
15
+ example: 253995,
16
+ minimum: 33
17
+ }
18
+ }
19
+
20
+ it 'should initialize ' do
21
+ subject.name.should == name
22
+ end
23
+
24
+ context 'when a paratemer type is not supplied' do
25
+ let(:parameter_data) { { required: true } }
26
+ it 'should default parameter type to string' do
27
+ subject.type.should == 'string'
28
+ end
29
+ end
30
+
31
+ context 'when the parameter type is valid' do
32
+ %w(string number integer date boolean file).each do |type|
33
+ context "when the parameter type is #{type}" do
34
+ let(:parameter_data) { { type: type } }
35
+ it { expect { subject }.to_not raise_error }
36
+ it "allows the type" do
37
+ subject.type.should == type
38
+ end
39
+ end
40
+ end
41
+ end
42
+ context 'when the parameter type is invalid' do
43
+ let(:parameter_data) { { type: 'invalid' } }
44
+ it { expect { subject }.to raise_error Raml::InvalidParameterType }
45
+ end
46
+
47
+ context 'when the parameter type is string' do
48
+ context 'and a minLength attribute is given' do
49
+ context 'and the value is an integer' do
50
+ let(:parameter_data) { { type: 'string', min_length: 2 } }
51
+ it { expect { subject }.to_not raise_error }
52
+ it "stores the attribute" do
53
+ subject.min_length.should == 2
54
+ end
55
+ end
56
+ context 'and the value is not an integer' do
57
+ let(:parameter_data) { { type: 'string', min_length: 2.0 } }
58
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
59
+ end
60
+ end
61
+ context 'and a maxLength attribute is given' do
62
+ context 'and the value is an integer' do
63
+ let(:parameter_data) { { type: 'string', max_length: 2 } }
64
+ it { expect { subject }.to_not raise_error }
65
+ it "stores the attribute" do
66
+ subject.max_length.should == 2
67
+ end
68
+ end
69
+ context 'and the value is not an integer' do
70
+ let(:parameter_data) { { type: 'string', max_length: 2.0 } }
71
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
72
+ end
73
+ end
74
+ context 'and an enum attribute is given' do
75
+ context 'and the value is an array of strings' do
76
+ let(:enum) { ['foo', 'bar'] }
77
+ let(:parameter_data) { { type: 'string', enum: enum } }
78
+ it { expect { subject }.to_not raise_error }
79
+ it "stores the attribute" do
80
+ subject.enum.should == enum
81
+ end
82
+ end
83
+ context 'and the value is not an array' do
84
+ let(:enum) { 'foo' }
85
+ let(:parameter_data) { { type: 'string', enum: enum } }
86
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
87
+ end
88
+ context 'and the value is an array but not all elements are string' do
89
+ let(:enum) { ['foo', 'bar', 2] }
90
+ let(:parameter_data) { { type: 'string', enum: enum } }
91
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
92
+ end
93
+ end
94
+ context 'and an pattern attribute is given' do
95
+ let(:parameter_data) { { type: 'string', pattern: pattern } }
96
+ context 'and the value is string representing a valid regexp' do
97
+ let(:pattern) { '[a-z]*' }
98
+ it { expect { subject }.to_not raise_error }
99
+ it 'it converts the attribute into a Regexp object' do
100
+ subject.pattern.should == /[a-z]*/
101
+ end
102
+ context 'when the regexp has JS ^ anchors' do
103
+ let(:pattern) { "^[a-z]*\\\\^" }
104
+ it 'replaces them with the Ruby \\A anchor' do
105
+ subject.pattern.should == /\A[a-z]*\\\A/
106
+ end
107
+ end
108
+ context 'when the regexp has JS $ anchors' do
109
+ let(:pattern) { '$[a-z]*\\\\$' }
110
+ it 'replaces them with the Ruby \\z anchor' do
111
+ subject.pattern.should == /\z[a-z]*\\\z/
112
+ end
113
+ end
114
+ context 'when the regexp has escaped an escaped ^' do
115
+ let(:pattern) { "\\^[a-z]*\\\\\\^" }
116
+ it 'doesnt replace them' do
117
+ subject.pattern.should == /\^[a-z]*\\\^/
118
+ end
119
+ end
120
+ context 'when the regexp has escaped an escaped $' do
121
+ let(:pattern) { "\\$[a-z]*\\\\\\$" }
122
+ it 'doesnt replace them' do
123
+ subject.pattern.should == /\$[a-z]*\\\$/
124
+ end
125
+ end
126
+ end
127
+ context 'and the pattern is not a string' do
128
+ let(:pattern) { 1 }
129
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
130
+ end
131
+ context 'and the pattern an invalid regexp pattern' do
132
+ let(:pattern) { '[' }
133
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
134
+ end
135
+ end
136
+ end
137
+ context 'when the parameter type is not string' do
138
+ context 'and a minLength attribute is given' do
139
+ let(:parameter_data) { { type: 'integer', min_length: 2 } }
140
+ it { expect { subject }.to raise_error Raml::InapplicableParameterAttribute }
141
+ end
142
+ context 'and a maxLength attribute is given' do
143
+ let(:parameter_data) { { type: 'integer', max_length: 2 } }
144
+ it { expect { subject }.to raise_error Raml::InapplicableParameterAttribute }
145
+ end
146
+ context 'and an enum attribute is given' do
147
+ let(:enum) { ['foo', 'bar'] }
148
+ let(:parameter_data) { { type: 'integer', enum: enum } }
149
+ it { expect { subject }.to raise_error Raml::InapplicableParameterAttribute }
150
+ end
151
+ context 'and a pattern attribute is given' do
152
+ let(:parameter_data) { { type: 'integer', pattern: '[a-Z]*' } }
153
+ it { expect { subject }.to raise_error Raml::InapplicableParameterAttribute }
154
+ end
155
+ end
156
+
157
+ %w(integer number).each do |type|
158
+ context "when the parameter type is #{type}" do
159
+ %w(minimum maximum).each do |attribute|
160
+ context "and a #{attribute} attribute is given" do
161
+ context 'and the attribute\'s value is an integer' do
162
+ let(:parameter_data) { { type: type, attribute => 2 } }
163
+ it { expect { subject }.to_not raise_error }
164
+ it "stores the attribute" do
165
+ subject.send(attribute.to_sym).should == 2
166
+ end
167
+ end
168
+ context 'and the attribute\'s value is an float' do
169
+ let(:parameter_data) { { type: type, attribute => 2.1 } }
170
+ it { expect { subject }.to_not raise_error }
171
+ it "stores the attribute" do
172
+ subject.send(attribute.to_sym).should == 2.1
173
+ end
174
+ end
175
+ context 'and the attribute\'s value is not an integer or a float' do
176
+ let(:parameter_data) { { type: type, attribute => '2' } }
177
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ context 'when the parameter type is not integer or number' do
184
+ context 'and a minimum attribute is given' do
185
+ let(:parameter_data) { { type: 'string', minimum: 2 } }
186
+ it { expect { subject }.to raise_error Raml::InapplicableParameterAttribute }
187
+ end
188
+ context 'and a maximum attribute is given' do
189
+ let(:parameter_data) { { type: 'string', maximum: 2 } }
190
+ it { expect { subject }.to raise_error Raml::InapplicableParameterAttribute }
191
+ end
192
+ end
193
+
194
+ [
195
+ [ 'string' , 'string' , '123', 123 ],
196
+ [ 'number' , 'number' , 12.3, '123' ],
197
+ [ 'integer', 'integer', 123 , 12.3 ],
198
+ [ 'date' , 'string' , '123', 123 ],
199
+ [ 'boolean', 'boolean', true, 123 ]
200
+ ].each do |test|
201
+ param_type, attr_type, good_value, bad_value = test
202
+ context "when the paramater type is a #{param_type}" do
203
+ [ :example, :default ].each do |attr|
204
+ context "when the #{attr} attribute is a #{attr_type}" do
205
+ let(:parameter_data) { { type: param_type, attr => good_value } }
206
+ it { expect { subject }.to_not raise_error }
207
+ it "stores the attribute" do
208
+ subject.send(attr).should == good_value
209
+ end
210
+ end
211
+ context "when the #{attr} attribute is not a #{attr_type}" do
212
+ let(:parameter_data) { { type: param_type, attr => bad_value } }
213
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ %w{repeat required}.each do |attribute|
220
+ context "when the #{attribute} attribute is not true or false" do
221
+ let(:parameter_data) { { attribute => 111 } }
222
+ it { expect { subject }.to raise_error Raml::InvalidParameterAttribute }
223
+ end
224
+ context "when the #{attribute} attribute is not given" do
225
+ let(:parameter_data) { { } }
226
+ it 'defaults to false' do
227
+ subject.send(attribute.to_sym).should == false
228
+ end
229
+ end
230
+ [ true, false ].each do |val|
231
+ context "when the #{attribute} attribute is #{val}" do
232
+ let(:parameter_data) { { attribute => val} }
233
+ it { expect { subject }.to_not raise_error }
234
+ it "stores the attribute" do
235
+ subject.send(attribute.to_sym).should == val
236
+ end
237
+ end
238
+ end
239
+ end
240
+
241
+ context 'when example property is given' do
242
+ context 'when the example property is a string' do
243
+ let(:parameter_data) { { 'example' => 'My Attribute' } }
244
+ it { expect { subject }.to_not raise_error }
245
+ it 'should store the value' do
246
+ subject.example.should eq parameter_data['example']
247
+ end
248
+ it 'uses the description in the documentation' do
249
+ subject.document.should include parameter_data['example']
250
+ end
251
+ end
252
+ end
253
+
254
+ context 'when the parameter has multiple types' do
255
+ let(:parameter_data) {
256
+ YAML.load %q(
257
+ - type: string
258
+ description: Text content. The text content must be the last field in the form.
259
+ - type: file
260
+ description: File to upload. The file must be the last field in the form.
261
+ )
262
+ }
263
+ let(:name) { 'file' }
264
+
265
+ it "creates children for multiple types" do
266
+ subject.children.should_not be_empty
267
+ subject.children.should all( be_a Raml::Parameter::AbstractParameter )
268
+ subject.children.map(&:type).should contain_exactly 'string', 'file'
269
+ end
270
+
271
+ it "prints out documentation" do
272
+ subject.document
273
+ end
274
+ end
275
+ end
276
+
277
+ describe '#has_multiple_types?' do
278
+ let(:name) { 'file' }
279
+ context 'when the parameter has a single type' do
280
+ let(:parameter_data) { { type: 'string' } }
281
+ it { subject.has_multiple_types?.should be false }
282
+ end
283
+ context 'when the parameter has multiple types' do
284
+ let(:parameter_data) {
285
+ YAML.load %q(
286
+ - type: string
287
+ description: Text content. The text content must be the last field in the form.
288
+ - type: file
289
+ description: File to upload. The file must be the last field in the form.
290
+ )
291
+ }
292
+
293
+ it { subject.has_multiple_types?.should be true }
294
+ end
295
+ end
296
+
297
+ describe '#merge' do
298
+ let(:other ) { Raml::Parameter::AbstractParameter.new 'name', other_data , root }
299
+ let(:param) { Raml::Parameter::AbstractParameter.new 'name', param_data, root }
300
+ subject(:merged_param) { param.merge other }
301
+
302
+ context 'when trying to merge parameters of different names' do
303
+ let(:other ) { Raml::Parameter::AbstractParameter.new 'name1', {}, root }
304
+ let(:param) { Raml::Parameter::AbstractParameter.new 'name2', {}, root }
305
+ it { expect { merged_param }.to raise_error Raml::MergeError }
306
+ end
307
+ context 'when a single type parameter is merged' do
308
+ context 'with a single type parameter' do
309
+ context 'when the parameter being merged into already has that property set' do
310
+ context 'displayName property' do
311
+ let(:other_data) { {displayName: 'other displayName' } }
312
+ let(:param_data) { {displayName: 'param displayName'} }
313
+ it 'overrides it' do
314
+ merged_param.display_name.should eq 'other displayName'
315
+ end
316
+ end
317
+ context 'description property' do
318
+ let(:other_data) { {description: 'other description' } }
319
+ let(:param_data) { {description: 'param description'} }
320
+ it 'overrides it' do
321
+ merged_param.description.should eq 'other description'
322
+ end
323
+ end
324
+ context 'type property' do
325
+ let(:other_data) { {type: 'string' } }
326
+ let(:param_data) { {type: 'number' } }
327
+ it 'overrides it' do
328
+ merged_param.type.should eq 'string'
329
+ end
330
+ end
331
+ context 'enum property' do
332
+ let(:other_data) { {enum: [ 'other' ] } }
333
+ let(:param_data) { {enum: [ 'param' ] } }
334
+ it 'overrides it' do
335
+ merged_param.enum.should eq [ 'other' ]
336
+ end
337
+ end
338
+ context 'pattern property' do
339
+ let(:other_data) { {pattern: 'other' } }
340
+ let(:param_data) { {pattern: 'param' } }
341
+ it 'overrides it' do
342
+ merged_param.pattern.should eq /other/
343
+ end
344
+ end
345
+ context 'min_length property' do
346
+ let(:other_data) { {min_length: 1 } }
347
+ let(:param_data) { {min_length: 2 } }
348
+ it 'overrides it' do
349
+ merged_param.min_length.should eq 1
350
+ end
351
+ end
352
+ context 'max_length property' do
353
+ let(:other_data) { {max_length: 1 } }
354
+ let(:param_data) { {max_length: 2 } }
355
+ it 'overrides it' do
356
+ merged_param.max_length.should eq 1
357
+ end
358
+ end
359
+ context 'minimum property' do
360
+ let(:other_data) { {type: 'number', minimum: 1 } }
361
+ let(:param_data) { {type: 'number', minimum: 2 } }
362
+ it 'overrides it' do
363
+ merged_param.minimum.should eq 1
364
+ end
365
+ end
366
+ context 'maximum property' do
367
+ let(:other_data) { {type: 'number', maximum: 1 } }
368
+ let(:param_data) { {type: 'number', maximum: 2 } }
369
+ it 'overrides it' do
370
+ merged_param.maximum.should eq 1
371
+ end
372
+ end
373
+ context 'example property' do
374
+ let(:other_data) { {example: 'other example' } }
375
+ let(:param_data) { {example: 'param example'} }
376
+ it 'overrides it' do
377
+ merged_param.example.should eq 'other example'
378
+ end
379
+ end
380
+ context 'repeat property' do
381
+ let(:other_data) { {repeat: true } }
382
+ let(:param_data) { {repeat: false } }
383
+ it 'overrides it' do
384
+ merged_param.repeat.should eq true
385
+ end
386
+ end
387
+ context 'required property' do
388
+ let(:other_data) { {required: true } }
389
+ let(:param_data) { {required: false } }
390
+ it 'overrides it' do
391
+ merged_param.required.should eq true
392
+ end
393
+ end
394
+ context 'default property' do
395
+ let(:other_data) { {default: 'other default' } }
396
+ let(:param_data) { {default: 'param default' } }
397
+ it 'overrides it' do
398
+ merged_param.default.should eq 'other default'
399
+ end
400
+ end
401
+ end
402
+ context 'when the parameter being merged into does not have that property set' do
403
+ let(:param_data) { {} }
404
+ context 'displayName property' do
405
+ let(:other_data) { {displayName: 'other displayName'} }
406
+ it 'can override it' do
407
+ merged_param.display_name.should eq other.display_name
408
+ end
409
+ end
410
+ context 'description property' do
411
+ let(:other_data) { {description: 'other description'} }
412
+ it 'can override it' do
413
+ merged_param.description.should eq other.description
414
+ end
415
+ end
416
+ context 'type property' do
417
+ let(:other_data) { {type: 'string'} }
418
+ it 'can override it' do
419
+ merged_param.type.should eq other.type
420
+ end
421
+ end
422
+ context 'enum property' do
423
+ let(:other_data) { {enum: [ 'other' ]} }
424
+ it 'can override it' do
425
+ merged_param.enum.should eq other.enum
426
+ end
427
+ end
428
+ context 'pattern property' do
429
+ let(:other_data) { {pattern: 'other'} }
430
+ it 'can override it' do
431
+ merged_param.pattern.should eq other.pattern
432
+ end
433
+ end
434
+ context 'min_length property' do
435
+ let(:other_data) { {min_length: 1} }
436
+ it 'can override it' do
437
+ merged_param.min_length.should eq other.min_length
438
+ end
439
+ end
440
+ context 'max_length property' do
441
+ let(:other_data) { {max_length: 1} }
442
+ it 'can override it' do
443
+ merged_param.max_length.should eq other.max_length
444
+ end
445
+ end
446
+ context 'minimum property' do
447
+ let(:other_data) { {type: 'number', minimum: 1} }
448
+ it 'can override it' do
449
+ merged_param.minimum.should eq other.minimum
450
+ end
451
+ end
452
+ context 'maximum property' do
453
+ let(:other_data) { {type: 'number', maximum: 1} }
454
+ it 'can override it' do
455
+ merged_param.maximum.should eq other.maximum
456
+ end
457
+ end
458
+ context 'example property' do
459
+ let(:other_data) { {example: 'other example'} }
460
+ it 'can override it' do
461
+ merged_param.example.should eq other.example
462
+ end
463
+ end
464
+ context 'repeat property' do
465
+ let(:other_data) { {repeat: true} }
466
+ it 'can override it' do
467
+ merged_param.repeat.should eq other.repeat
468
+ end
469
+ end
470
+ context 'required property' do
471
+ let(:other_data) { {required: true} }
472
+ it 'can override it' do
473
+ merged_param.required.should eq other.required
474
+ end
475
+ end
476
+ context 'default property' do
477
+ let(:other_data) { {default: 'other default'} }
478
+ it 'can override it' do
479
+ merged_param.default.should eq other.default
480
+ end
481
+ end
482
+ end
483
+ end
484
+ context 'with a multiple type parameter' do
485
+ let(:param_data) { [
486
+ { type: 'number' , description: 'param1' },
487
+ { type: 'boolean', description: 'param2' },
488
+ ] }
489
+ context 'when none of the parameter types match the type of the merged parameter' do
490
+ let(:other_data) { {type: 'string', description: 'other'} }
491
+ it 'adds the new type as an option' do
492
+ merged_param.types.keys.should contain_exactly('string', 'number', 'boolean')
493
+ end
494
+ end
495
+ context 'when one of the parameter types matches the type of the merged parameter' do
496
+ let(:other_data) { {type: 'number', description: 'other', minimum: 5} }
497
+ it 'merges the matching types' do
498
+ merged_param.types.keys.should contain_exactly('number', 'boolean')
499
+ merged_param.types['number'].description.should eq other.description
500
+ merged_param.types['number'].minimum.should eq other.minimum
501
+ end
502
+ end
503
+ end
504
+ end
505
+ context 'when a multiple type parameter is merged' do
506
+ let(:other_data) { [
507
+ { type: 'number' , description: 'other1', minimum: 5 },
508
+ { type: 'boolean', description: 'other2' },
509
+ ] }
510
+ context 'with a single type parameter' do
511
+ context 'when the parameter type does not match any type of the merged parameter' do
512
+ let(:param_data) { {type: 'string', description: 'param'} }
513
+ it 'converts the parameter to multiple types' do
514
+ merged_param.should be_has_multiple_types
515
+ end
516
+ it 'adds the other types as an alternative' do
517
+ merged_param.types.keys.should contain_exactly('string', 'number', 'boolean')
518
+ end
519
+ end
520
+ context 'when the parameter type matches one of the types of the merged parameter' do
521
+ let(:param_data) { {type: 'number', description: 'param'} }
522
+ it 'converts the parameter to multiple types' do
523
+ merged_param.should be_has_multiple_types
524
+ end
525
+ it 'merges the overriding type with the matching other type' do
526
+ merged_param.types.keys.should contain_exactly('number', 'boolean')
527
+ merged_param.types['number'].description.should eq 'other1'
528
+ merged_param.types['number'].minimum.should eq 5
529
+ end
530
+ end
531
+ end
532
+ context 'with a multiple type parameter' do
533
+ let(:param_data) { [
534
+ { type: 'number' , description: 'param1' },
535
+ { type: 'string' , description: 'param2' },
536
+ ] }
537
+ it 'merges types that match and adds those that dont' do
538
+ merged_param.types.keys.should contain_exactly('string', 'number', 'boolean')
539
+ merged_param.types['number'].description.should eq 'other1'
540
+ merged_param.types['number'].minimum.should eq 5
541
+ end
542
+ end
543
+ end
544
+ end
545
+
546
+ describe '#document' do
547
+ let(:name) { 'page_number' }
548
+ let(:parameter_data) {
549
+ {
550
+ type: 'integer',
551
+ required: true,
552
+ example: 253995,
553
+ minimum: 33
554
+ }
555
+ }
556
+ it 'returns a String' do
557
+ subject.document.should be_a String
558
+ end
559
+ it 'should render the template' do
560
+ mock(Slim::Template).new(/templates\/abstract_parameter.slim\z/, is_a(Hash)).mock!.render(is_a(Raml::Node)) { '' }
561
+ subject.document
562
+ end
563
+ end
564
+ end