brainstem 1.4.1 → 2.0.0

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -0
  3. data/README.md +119 -0
  4. data/docs/api_doc_generator.markdown +45 -4
  5. data/docs/brainstem_executable.markdown +1 -1
  6. data/docs/oas_2_docgen.png +0 -0
  7. data/docs/oas_2_docgen_ascii.txt +78 -0
  8. data/lib/brainstem/api_docs.rb +23 -9
  9. data/lib/brainstem/api_docs/abstract_collection.rb +0 -13
  10. data/lib/brainstem/api_docs/atlas.rb +0 -14
  11. data/lib/brainstem/api_docs/builder.rb +0 -14
  12. data/lib/brainstem/api_docs/controller.rb +7 -16
  13. data/lib/brainstem/api_docs/controller_collection.rb +0 -3
  14. data/lib/brainstem/api_docs/endpoint.rb +73 -19
  15. data/lib/brainstem/api_docs/endpoint_collection.rb +0 -7
  16. data/lib/brainstem/api_docs/formatters/abstract_formatter.rb +0 -2
  17. data/lib/brainstem/api_docs/formatters/markdown/controller_formatter.rb +1 -9
  18. data/lib/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter.rb +1 -9
  19. data/lib/brainstem/api_docs/formatters/markdown/endpoint_formatter.rb +39 -24
  20. data/lib/brainstem/api_docs/formatters/markdown/helper.rb +0 -13
  21. data/lib/brainstem/api_docs/formatters/markdown/presenter_formatter.rb +22 -35
  22. data/lib/brainstem/api_docs/formatters/open_api_specification/helper.rb +66 -0
  23. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/controller_formatter.rb +57 -0
  24. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter.rb +311 -0
  25. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter.rb +197 -0
  26. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_collection_formatter.rb +60 -0
  27. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_formatter.rb +162 -0
  28. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/info_formatter.rb +126 -0
  29. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter.rb +132 -0
  30. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/security_definitions_formatter.rb +99 -0
  31. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter.rb +123 -0
  32. data/lib/brainstem/api_docs/introspectors/abstract_introspector.rb +0 -7
  33. data/lib/brainstem/api_docs/introspectors/rails_introspector.rb +1 -20
  34. data/lib/brainstem/api_docs/presenter.rb +21 -27
  35. data/lib/brainstem/api_docs/presenter_collection.rb +1 -11
  36. data/lib/brainstem/api_docs/resolver.rb +1 -8
  37. data/lib/brainstem/api_docs/sinks/abstract_sink.rb +0 -4
  38. data/lib/brainstem/api_docs/sinks/controller_presenter_multifile_sink.rb +0 -9
  39. data/lib/brainstem/api_docs/sinks/open_api_specification_sink.rb +234 -0
  40. data/lib/brainstem/api_docs/sinks/stdout_sink.rb +0 -5
  41. data/lib/brainstem/cli.rb +0 -13
  42. data/lib/brainstem/cli/abstract_command.rb +0 -7
  43. data/lib/brainstem/cli/generate_api_docs_command.rb +48 -24
  44. data/lib/brainstem/concerns/controller_dsl.rb +288 -145
  45. data/lib/brainstem/concerns/formattable.rb +0 -5
  46. data/lib/brainstem/concerns/optional.rb +0 -1
  47. data/lib/brainstem/concerns/presenter_dsl.rb +2 -21
  48. data/lib/brainstem/dsl/configuration.rb +0 -11
  49. data/lib/brainstem/presenter.rb +0 -4
  50. data/lib/brainstem/version.rb +1 -1
  51. data/spec/brainstem/api_docs/abstract_collection_spec.rb +0 -11
  52. data/spec/brainstem/api_docs/atlas_spec.rb +0 -6
  53. data/spec/brainstem/api_docs/builder_spec.rb +0 -4
  54. data/spec/brainstem/api_docs/controller_collection_spec.rb +0 -2
  55. data/spec/brainstem/api_docs/controller_spec.rb +29 -18
  56. data/spec/brainstem/api_docs/endpoint_collection_spec.rb +0 -6
  57. data/spec/brainstem/api_docs/endpoint_spec.rb +343 -13
  58. data/spec/brainstem/api_docs/formatters/abstract_formatter_spec.rb +0 -2
  59. data/spec/brainstem/api_docs/formatters/markdown/controller_formatter_spec.rb +0 -1
  60. data/spec/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter_spec.rb +0 -5
  61. data/spec/brainstem/api_docs/formatters/markdown/endpoint_formatter_spec.rb +94 -8
  62. data/spec/brainstem/api_docs/formatters/markdown/helper_spec.rb +0 -8
  63. data/spec/brainstem/api_docs/formatters/markdown/presenter_formatter_spec.rb +0 -7
  64. data/spec/brainstem/api_docs/formatters/open_api_specification/helper_spec.rb +210 -0
  65. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/controller_formatter_spec.rb +81 -0
  66. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter_spec.rb +672 -0
  67. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter_spec.rb +335 -0
  68. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_collection_formatter_spec.rb +59 -0
  69. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_formatter_spec.rb +308 -0
  70. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/info_formatter_spec.rb +89 -0
  71. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter_spec.rb +430 -0
  72. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/security_definitions_formatter_spec.rb +190 -0
  73. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter_spec.rb +217 -0
  74. data/spec/brainstem/api_docs/introspectors/abstract_introspector_spec.rb +0 -2
  75. data/spec/brainstem/api_docs/introspectors/rails_introspector_spec.rb +0 -2
  76. data/spec/brainstem/api_docs/presenter_collection_spec.rb +0 -2
  77. data/spec/brainstem/api_docs/presenter_spec.rb +58 -18
  78. data/spec/brainstem/api_docs/resolver_spec.rb +0 -1
  79. data/spec/brainstem/api_docs/sinks/controller_presenter_multifile_sink_spec.rb +0 -2
  80. data/spec/brainstem/api_docs/sinks/open_api_specification_sink_spec.rb +371 -0
  81. data/spec/brainstem/api_docs_spec.rb +2 -0
  82. data/spec/brainstem/cli/abstract_command_spec.rb +0 -4
  83. data/spec/brainstem/cli/generate_api_docs_command_spec.rb +53 -2
  84. data/spec/brainstem/concerns/controller_dsl_spec.rb +430 -64
  85. data/spec/brainstem/concerns/presenter_dsl_spec.rb +0 -20
  86. data/spec/brainstem/preloader_spec.rb +0 -7
  87. data/spec/brainstem/presenter_spec.rb +0 -1
  88. data/spec/dummy/rails.rb +0 -1
  89. data/spec/spec_helpers/db.rb +0 -1
  90. metadata +37 -2
@@ -21,7 +21,6 @@ module Brainstem
21
21
  end
22
22
  end
23
23
 
24
-
25
24
  describe "configured fields" do
26
25
  let(:lorem) { "lorem ipsum dolor sit amet" }
27
26
  let(:const) { Object.new }
@@ -38,7 +37,6 @@ module Brainstem
38
37
  end
39
38
  end
40
39
 
41
-
42
40
  describe "#nodoc?" do
43
41
  let(:config) { { nodoc: nodoc } }
44
42
 
@@ -57,7 +55,6 @@ module Brainstem
57
55
  end
58
56
  end
59
57
 
60
-
61
58
  describe "#title" do
62
59
  let(:config) { { title: { info: lorem, nodoc: nodoc } } }
63
60
 
@@ -76,14 +73,12 @@ module Brainstem
76
73
  end
77
74
  end
78
75
 
79
-
80
76
  describe "#brainstem_keys" do
81
77
  it "retrieves from the constant, array-izes, and sorts" do
82
78
  expect(subject.brainstem_keys).to eq [ "ipsum", "lorem" ]
83
79
  end
84
80
  end
85
81
 
86
-
87
82
  describe "#description" do
88
83
  context "with description" do
89
84
  let(:config) { { description: { info: lorem, nodoc: nodoc } } }
@@ -110,7 +105,6 @@ module Brainstem
110
105
  end
111
106
  end
112
107
 
113
-
114
108
  describe "#valid_fields" do
115
109
  let(:presenter_class) do
116
110
  Class.new(Brainstem::Presenter) do
@@ -240,6 +234,64 @@ module Brainstem
240
234
  end
241
235
  end
242
236
 
237
+ describe "#optional_field_names" do
238
+ let(:presenter_class) do
239
+ Class.new(Brainstem::Presenter) do
240
+ presents Workspace
241
+
242
+ fields do
243
+ field :mandatory_field, :string, dynamic: lambda { "new_field value" }
244
+ field :optional_top_field, :string, dynamic: lambda { "new_field value" }, optional: true
245
+ field :nodoc_optional_top_field, :string, dynamic: lambda { "new_field value" }, optional: true, nodoc: true
246
+
247
+ fields :optional_block_field, :hash, optional: true do
248
+ field :leaf_field_1, :string
249
+ end
250
+
251
+ fields :nodoc_optional_block_field, :hash, optional: true, nodoc: true do
252
+ field :leaf_field_2, :string
253
+ end
254
+
255
+ fields :nodoc_block_field, :hash, nodoc: true do
256
+ field :optional_field_nodoc_block_field, :string, optional: true
257
+ end
258
+
259
+ fields :block_field_with_optional_fields, :hash do
260
+ fields :optional_double_nested_field, :hash, optional: true do
261
+ field :leaf_field_3, :string
262
+ end
263
+
264
+ fields :double_nested_field, :hash do
265
+ field :leaf_field_4, :string
266
+ field :optional_leaf_field, :string, optional: true
267
+ field :nodoc_optional_leaf_field, :string, optional: true, nodoc: true
268
+ end
269
+ end
270
+ end
271
+ end
272
+ end
273
+
274
+ subject { described_class.new(atlas, target_class: 'Workspace', const: presenter_class).optional_field_names }
275
+
276
+ before do
277
+ stub(atlas).find_by_class(anything) { nil }
278
+ end
279
+
280
+ it 'includes optional top level fields if nodoc is false' do
281
+ expect(subject).to include('optional_top_field')
282
+ expect(subject).to_not include('nodoc_optional_top_field')
283
+ end
284
+
285
+ it 'includes optional block fields if nodoc is false' do
286
+ expect(subject).to include('optional_block_field', 'optional_double_nested_field')
287
+ expect(subject).to_not include('nodoc_optional_block_field')
288
+ end
289
+
290
+ it 'includes optional leaf fields of block fields if nodoc is false' do
291
+ expect(subject).to include('optional_leaf_field')
292
+ expect(subject).to_not include('nodoc_optional_leaf_field', 'optional_field_nodoc_block_field')
293
+ end
294
+ end
243
295
 
244
296
  describe "#valid_filters" do
245
297
  let(:info) { lorem }
@@ -267,7 +319,6 @@ module Brainstem
267
319
  end
268
320
  end
269
321
 
270
-
271
322
  describe "#documentable_filter?" do
272
323
  let(:info) { lorem }
273
324
  let(:filter) { { nodoc: nodoc, info: info } }
@@ -309,7 +360,6 @@ module Brainstem
309
360
  end
310
361
  end
311
362
 
312
-
313
363
  describe "#valid_sort_orders" do
314
364
  let(:config) { { sort_orders: { title: { nodoc: true }, date: {} } } }
315
365
 
@@ -319,7 +369,6 @@ module Brainstem
319
369
  end
320
370
  end
321
371
 
322
-
323
372
  describe "#valid_associations" do
324
373
  let(:info) { lorem }
325
374
  let(:association) { Object.new }
@@ -346,7 +395,6 @@ module Brainstem
346
395
  end
347
396
  end
348
397
 
349
-
350
398
  describe "#documentable_association?" do
351
399
  let(:desc) { lorem }
352
400
  let(:association) { OpenStruct.new(options: { nodoc: nodoc }, description: desc ) }
@@ -388,7 +436,6 @@ module Brainstem
388
436
  end
389
437
  end
390
438
 
391
-
392
439
  describe "#conditionals" do
393
440
  let(:config) { { conditionals: { thing: :other_thing } } }
394
441
 
@@ -405,7 +452,6 @@ module Brainstem
405
452
  end
406
453
  end
407
454
 
408
-
409
455
  describe "#default_sort_field" do
410
456
  context "when has default sort order" do
411
457
  let(:config) { { default_sort_order: "alphabetical:asc" } }
@@ -422,7 +468,6 @@ module Brainstem
422
468
  end
423
469
  end
424
470
 
425
-
426
471
  describe "#default_sort_direction" do
427
472
  context "when has default sort order" do
428
473
  let(:config) { { default_sort_order: "alphabetical:asc" } }
@@ -485,7 +530,6 @@ module Brainstem
485
530
  end
486
531
  end
487
532
 
488
-
489
533
  describe "#suggested_filename" do
490
534
  before do
491
535
  stub(target_class).to_s { "Abc" }
@@ -504,7 +548,6 @@ module Brainstem
504
548
  end
505
549
  end
506
550
 
507
-
508
551
  describe "#suggested_filename_link" do
509
552
  before do
510
553
  stub(target_class).to_s { "Abc" }
@@ -523,7 +566,6 @@ module Brainstem
523
566
  end
524
567
  end
525
568
 
526
-
527
569
  describe "#relative_path_to_presenter" do
528
570
  let(:presenter) {
529
571
  mock!
@@ -538,7 +580,6 @@ module Brainstem
538
580
  end
539
581
  end
540
582
 
541
-
542
583
  describe "#link_for_association" do
543
584
  let(:presenter) { Object.new }
544
585
  let(:target_class) { Class.new }
@@ -578,7 +619,6 @@ module Brainstem
578
619
  end
579
620
  end
580
621
 
581
-
582
622
  it_behaves_like "formattable"
583
623
  it_behaves_like "atlas taker"
584
624
  end
@@ -49,7 +49,6 @@ module Brainstem
49
49
  end
50
50
  end
51
51
 
52
-
53
52
  describe "#find_presenter_from_target_class" do
54
53
  let(:klass) { Class.new }
55
54
  let(:presenter_const) { Class.new }
@@ -33,13 +33,11 @@ module Brainstem
33
33
  end
34
34
  end
35
35
 
36
-
37
36
  context "presenters" do
38
37
  before do
39
38
  stub(subject).write_controller_files
40
39
  end
41
40
 
42
-
43
41
  it "writes each presenter to its own file" do
44
42
  stub(atlas).presenters
45
43
  .stub!
@@ -0,0 +1,371 @@
1
+ require 'spec_helper'
2
+ require 'brainstem/api_docs/sinks/open_api_specification_sink'
3
+ require 'brainstem/api_docs/formatters/open_api_specification/version_2/info_formatter'
4
+ require 'brainstem/api_docs/formatters/open_api_specification/version_2/security_definitions_formatter'
5
+ require 'brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter'
6
+
7
+ module Brainstem
8
+ module ApiDocs
9
+ module Sinks
10
+ describe OpenApiSpecificationSink do
11
+ let(:write_method) { Object.new }
12
+ let(:atlas) { Object.new }
13
+ let(:options) { default_options }
14
+ let(:default_options) {
15
+ {
16
+ api_version: '2.0.0',
17
+ format: :oas_v2,
18
+ write_method: write_method,
19
+ write_path: './',
20
+ }
21
+ }
22
+
23
+ subject { described_class.new(options) }
24
+
25
+ context "writing the specification" do
26
+ before do
27
+ mock(subject).write_info_object!
28
+ mock(subject).write_presenter_definitions!
29
+ mock(subject).write_error_definitions!
30
+ mock(subject).write_endpoint_definitions!
31
+ mock(subject).write_tag_definitions!
32
+ mock(subject).write_security_definitions!
33
+
34
+ mock.proxy(subject).write_spec_to_file!
35
+ end
36
+
37
+ it "calls the write method" do
38
+ mock(write_method).call('./specification.yml', anything)
39
+
40
+ subject << atlas
41
+ end
42
+
43
+ context "when a filename pattern is specified" do
44
+ let(:options) {
45
+ default_options.merge(
46
+ api_version: "1.1.0",
47
+ oas_filename_pattern: "specification_{{version}}.{{extension}}",
48
+ output_extension: "json"
49
+ )
50
+ }
51
+
52
+ it "calls the write method with customized filename" do
53
+ mock(write_method).call('./specification_1.1.0.json', anything)
54
+
55
+ subject << atlas
56
+ end
57
+ end
58
+
59
+ context "when a output extension is specified" do
60
+ let(:options) { default_options.merge(output_extension: output_extension) }
61
+
62
+ context "when valid extension is specified" do
63
+ let(:output_extension) { 'JSON' }
64
+
65
+ it "calls the write method with the correct file extension" do
66
+ mock(write_method).call('./specification.json', anything)
67
+
68
+ subject << atlas
69
+ end
70
+ end
71
+
72
+ context "when unsupported extension is specified" do
73
+ let(:output_extension) { 'JSON' }
74
+
75
+ it "raises an error" do
76
+ expect { subject << atlas }.to raise_error(StandardError)
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "specification" do
83
+ let(:generated_data) { { 'sprockets' => { 'type' => 'object' } } }
84
+
85
+ before do
86
+ mock.proxy(subject).write_spec_to_file!
87
+ end
88
+
89
+ it "writes the data returned from the info formatter" do
90
+ mock(subject).write_presenter_definitions!
91
+ mock(subject).write_error_definitions!
92
+ mock(subject).write_endpoint_definitions!
93
+ mock(subject).write_tag_definitions!
94
+ mock(subject).write_security_definitions!
95
+
96
+ mock.proxy(subject).write_info_object!
97
+ mock.proxy
98
+ .any_instance_of(Brainstem::ApiDocs::Formatters::OpenApiSpecification::Version2::InfoFormatter)
99
+ .call { generated_data }
100
+ mock(write_method).call('./specification.yml', generated_data.to_yaml)
101
+
102
+ subject << atlas
103
+ end
104
+
105
+ context "when generating schema definitions" do
106
+ let(:generated_data) {
107
+ [
108
+ { 'widgets' => { 'type' => 'object' } },
109
+ { 'sprockets' => { 'type' => 'object' } }
110
+ ]
111
+ }
112
+ let(:expected_yaml) {
113
+ {
114
+ 'definitions' => {
115
+ 'sprockets' => { 'type' => 'object' },
116
+ 'widgets' => { 'type' => 'object' }
117
+ }
118
+ }.to_yaml
119
+ }
120
+
121
+ it "writes presenter definitions" do
122
+ mock(subject).write_info_object!
123
+ mock(subject).write_error_definitions!
124
+ mock(subject).write_endpoint_definitions!
125
+ mock(subject).write_tag_definitions!
126
+ mock(subject).write_security_definitions!
127
+
128
+ mock.proxy(subject).write_presenter_definitions!
129
+ stub(atlas).presenters.stub!.formatted(:oas_v2) { generated_data }
130
+ mock(write_method).call('./specification.yml', expected_yaml)
131
+
132
+ subject << atlas
133
+ end
134
+ end
135
+
136
+ context "when generating error definitions" do
137
+ let(:generated_data) {
138
+ [
139
+ { 'widgets' => { 'type' => 'object' } },
140
+ { 'sprockets' => { 'type' => 'object' } }
141
+ ]
142
+ }
143
+ let(:expected_yaml) {
144
+ {
145
+ 'definitions' => {
146
+ 'sprockets' => { 'type' => 'object' },
147
+ 'widgets' => { 'type' => 'object' },
148
+ 'Error' => {
149
+ 'type' => 'object',
150
+ 'properties' => {
151
+ 'type' => { 'type' => 'string' },
152
+ 'message' => { 'type' => 'string' },
153
+ }
154
+ },
155
+ 'Errors' => {
156
+ 'type' => 'object',
157
+ 'properties' => {
158
+ 'errors' => {
159
+ 'type' => 'array',
160
+ 'items' => {
161
+ '$ref' => '#/definitions/Error'
162
+ }
163
+ }
164
+ }
165
+ },
166
+ }
167
+ }.to_yaml
168
+ }
169
+
170
+ it "writes error definitions" do
171
+ mock(subject).write_info_object!
172
+ mock(subject).write_endpoint_definitions!
173
+ mock(subject).write_tag_definitions!
174
+ mock(subject).write_security_definitions!
175
+
176
+ mock.proxy(subject).write_presenter_definitions!
177
+ mock.proxy(subject).write_error_definitions!
178
+
179
+ stub(atlas).presenters.stub!.formatted(:oas_v2) { generated_data }
180
+ mock(write_method).call('./specification.yml', expected_yaml)
181
+
182
+ subject << atlas
183
+ end
184
+ end
185
+
186
+ context "when generating endpoint definitions" do
187
+ let(:generated_data) {
188
+ [
189
+ { '/widgets' => { 'get' => { 'type' => 'object' } } },
190
+ { '/sprockets' => { 'post' => { 'type' => 'object' } } }
191
+ ]
192
+ }
193
+ let(:expected_yaml) {
194
+ {
195
+ 'paths' => {
196
+ '/sprockets' => { 'post' => { 'type' => 'object' } },
197
+ '/widgets' => { 'get' => { 'type' => 'object' } }
198
+ }
199
+ }.to_yaml
200
+ }
201
+
202
+ it "writes endpoint definitions" do
203
+ mock(subject).write_info_object!
204
+ mock(subject).write_error_definitions!
205
+ mock(subject).write_presenter_definitions!
206
+ mock(subject).write_tag_definitions!
207
+ mock(subject).write_security_definitions!
208
+ mock.proxy(subject).write_endpoint_definitions!
209
+
210
+ stub(atlas).controllers.stub!.formatted(:oas_v2) { generated_data }
211
+ mock(write_method).call('./specification.yml', expected_yaml)
212
+
213
+ subject << atlas
214
+ end
215
+ end
216
+
217
+ context "when generating tag definitions" do
218
+ let(:documentable_controller_Z) {
219
+ OpenStruct.new(
220
+ name: 'controller_Z',
221
+ description: 'controller_Z desc',
222
+ endpoints: OpenStruct.new(only_documentable: [1, 2]),
223
+ tag: 'Tag Z',
224
+ tag_groups: ['Group Z'],
225
+ )
226
+ }
227
+ let(:documentable_controller_A) {
228
+ OpenStruct.new(
229
+ name: 'controller_A',
230
+ description: 'controller_A desc',
231
+ endpoints: OpenStruct.new(only_documentable: [1, 2]),
232
+ tag: 'Tag A',
233
+ tag_groups: ['Group Z', 'Group A'],
234
+ )
235
+ }
236
+ let(:controllers) {
237
+ [
238
+ documentable_controller_Z,
239
+ documentable_controller_A,
240
+ ]
241
+ }
242
+ let(:expected_yaml) {
243
+ {
244
+ 'tags' => [
245
+ { 'name' => 'Tag A', 'description' => 'Controller_A desc.' },
246
+ { 'name' => 'Tag Z', 'description' => 'Controller_Z desc.' }
247
+ ],
248
+ 'x-tagGroups' => [
249
+ { 'name' => 'Group A', 'tags' => ['Tag A'] },
250
+ { 'name' => 'Group Z', 'tags' => ['Tag A', 'Tag Z'] }
251
+ ],
252
+ }.to_yaml
253
+ }
254
+ let(:ignore_tagging) { false }
255
+ let(:options) { default_options.merge(ignore_tagging: ignore_tagging) }
256
+
257
+ it "writes endpoint definitions" do
258
+ mock(subject).write_info_object!
259
+ mock(subject).write_error_definitions!
260
+ mock(subject).write_presenter_definitions!
261
+ mock(subject).write_endpoint_definitions!
262
+ mock(subject).write_security_definitions!
263
+
264
+ mock.proxy(subject).write_tag_definitions!
265
+ stub(atlas).controllers { controllers }
266
+ mock(write_method).call('./specification.yml', expected_yaml)
267
+
268
+ subject << atlas
269
+ end
270
+ end
271
+
272
+ context "when generating security definitions" do
273
+ let(:expected_yaml) {
274
+ {
275
+ 'securityDefinitions' => {
276
+ 'api_key' => {
277
+ 'type' => 'apiKey',
278
+ 'name' => 'api_key',
279
+ 'in' => 'header'
280
+ },
281
+ 'petstore_auth' => {
282
+ 'type' => 'oauth2',
283
+ 'authorizationUrl' => 'http://petstore.swagger.io/oauth/dialog',
284
+ 'flow' => 'implicit',
285
+ 'scopes' => {
286
+ 'write:pets' => 'modify pets in your account',
287
+ 'read:pets' => 'read your pets'
288
+ }
289
+ }
290
+ }
291
+ }.to_yaml
292
+ }
293
+
294
+ it "writes endpoint definitions" do
295
+ mock(subject).write_info_object!
296
+ mock(subject).write_error_definitions!
297
+ mock(subject).write_presenter_definitions!
298
+ mock(subject).write_tag_definitions!
299
+ mock(subject).write_endpoint_definitions!
300
+
301
+ mock.proxy(subject).write_security_definitions!
302
+ stub(atlas).controllers.stub!.formatted(:oas_v2) { generated_data }
303
+ mock(write_method).call('./specification.yml', expected_yaml)
304
+
305
+ subject << atlas
306
+ end
307
+ end
308
+ end
309
+
310
+ describe "versioning" do
311
+ let(:options) {
312
+ {
313
+ api_version: api_version,
314
+ write_method: write_method,
315
+ write_path: './'
316
+ }
317
+ }
318
+
319
+ before do
320
+ stub(subject).write_spec_to_file!
321
+ end
322
+
323
+ context "when version is specified" do
324
+ let(:api_version) { '2.1.1' }
325
+
326
+ it "returns the specified version" do
327
+ expect(subject.send(:formatted_version)).to eq(api_version)
328
+ end
329
+ end
330
+
331
+ context "when version is not specified" do
332
+ let(:api_version) { nil }
333
+
334
+ it "returns the default version" do
335
+ expect(subject.send(:formatted_version)).to eq('1.0.0')
336
+ end
337
+ end
338
+ end
339
+
340
+ describe "suggested_filename" do
341
+ let(:options) {
342
+ default_options.merge(
343
+ api_version: '1.1.1',
344
+ oas_filename_pattern: oas_filename_pattern
345
+ )
346
+ }
347
+
348
+ before do
349
+ stub(subject).write_spec_to_file!
350
+ end
351
+
352
+ context "when version is specified" do
353
+ let(:oas_filename_pattern) { "{{version}}.{{extension}}" }
354
+
355
+ it "returns the customized filename" do
356
+ expect(subject.send(:suggested_filename)).to eq("1.1.1.yml")
357
+ end
358
+ end
359
+
360
+ context "when version is not specified" do
361
+ let(:oas_filename_pattern) { nil }
362
+
363
+ it "returns the default filename" do
364
+ expect(subject.send(:suggested_filename)).to eq('specification.yml')
365
+ end
366
+ end
367
+ end
368
+ end
369
+ end
370
+ end
371
+ end