raml_ruby 0.1.1

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 (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