brainstem 1.4.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -17,13 +17,11 @@ module Brainstem
17
17
  end
18
18
  end
19
19
 
20
-
21
20
  describe "#call" do
22
21
  it "is not implemented" do
23
22
  expect { subject.call }.to raise_error NotImplementedError
24
23
  end
25
24
  end
26
-
27
25
  end
28
26
  end
29
27
  end
@@ -56,7 +56,6 @@ module Brainstem
56
56
  let(:default_config) { {} }
57
57
  let(:configuration) { { _default: default_config } }
58
58
 
59
-
60
59
  describe "#format_title!" do
61
60
  it "outputs it as an h2" do
62
61
  stub(controller).title { lorem }
@@ -40,7 +40,6 @@ module Brainstem
40
40
  end
41
41
  end
42
42
 
43
-
44
43
  describe "formatting" do
45
44
  describe "#format_endpoints!" do
46
45
  it "joins each documentable endpoint" do
@@ -50,7 +49,6 @@ module Brainstem
50
49
  end
51
50
  end
52
51
 
53
-
54
52
  describe "#format_zero_text!" do
55
53
  it "appends the zero text" do
56
54
  subject.send(:format_zero_text!)
@@ -59,7 +57,6 @@ module Brainstem
59
57
  end
60
58
  end
61
59
 
62
-
63
60
  describe "#all_formatted_endpoints" do
64
61
  it "retrieves all formatted endpoints" do
65
62
  documentable_collection = Object.new
@@ -77,8 +74,6 @@ module Brainstem
77
74
  end
78
75
  end
79
76
  end
80
-
81
-
82
77
  end
83
78
  end
84
79
  end
@@ -18,6 +18,7 @@ module Brainstem
18
18
  describe "#call" do
19
19
  before do
20
20
  stub(endpoint).nodoc? { nodoc }
21
+ stub(endpoint).custom_response { {} }
21
22
  end
22
23
 
23
24
  context "when it is nodoc" do
@@ -78,7 +79,6 @@ module Brainstem
78
79
  end
79
80
  end
80
81
 
81
-
82
82
  describe "#format_description!" do
83
83
  context "when present" do
84
84
  before do
@@ -106,7 +106,6 @@ module Brainstem
106
106
  end
107
107
  end
108
108
 
109
-
110
109
  describe "#format_endpoint!" do
111
110
  let(:endpoint_args) { { http_methods: %w(get post), path: "/widgets(.:format)" } }
112
111
 
@@ -127,7 +126,6 @@ module Brainstem
127
126
  end
128
127
  end
129
128
 
130
-
131
129
  describe "#format_params!" do
132
130
  let(:const) do
133
131
  Class.new do
@@ -316,15 +314,103 @@ module Brainstem
316
314
  end
317
315
 
318
316
  describe "#format_presents!" do
319
- let(:presenter) { Object.new }
317
+ context "when has a custom response" do
318
+ before do
319
+ stub(endpoint).custom_response { true }
320
+ stub(endpoint).custom_response_configuration_tree { custom_response_configuration }
321
+ end
320
322
 
321
- before do
322
- stub(endpoint).presenter_title { "Sprocket Widget" }
323
- stub(endpoint).relative_presenter_path_from_controller(:markdown) { "../../sprocket_widget.markdown" }
323
+ context "when the response type is a hash" do
324
+ let(:custom_response_configuration) do
325
+ {
326
+ '_config' => {
327
+ 'type' => 'hash',
328
+ },
329
+ 'widget_name' => {
330
+ '_config' => {
331
+ 'type' => 'string',
332
+ 'info' => 'the name of the widget',
333
+ 'nodoc' => false
334
+ },
335
+ },
336
+ 'widget_permission' => {
337
+ '_config' => {
338
+ 'type' => 'hash',
339
+ 'nodoc' => false
340
+ },
341
+ 'can_edit' => {
342
+ '_config' => {
343
+ 'type' => 'boolean',
344
+ 'info' => 'can edit the widget',
345
+ 'nodoc' => false
346
+ },
347
+ }
348
+ },
349
+ }.with_indifferent_access
350
+ end
351
+
352
+ it "formats the custom response" do
353
+ subject.send(:format_presents!)
354
+
355
+ output = subject.output
356
+ expect(output).to include("The resulting JSON is a hash with the following properties\n\n")
357
+ expect(output).to include("- `widget_name` (`String`) - the name of the widget\n")
358
+ expect(output).to include("- `widget_permission` (`Hash`)\n")
359
+ expect(output).to include(" - `can_edit` (`Boolean`) - can edit the widget\n")
360
+ end
361
+ end
362
+
363
+ context "when the response is an array" do
364
+ let(:custom_response_configuration) do
365
+ {
366
+ '_config' => {
367
+ 'type' => 'array',
368
+ 'item_type' => 'hash',
369
+ },
370
+ 'widget_name' => {
371
+ '_config' => {
372
+ 'type' => 'string',
373
+ 'info' => 'the name of the widget',
374
+ 'nodoc' => false
375
+ },
376
+ },
377
+ 'widget_permissions' => {
378
+ '_config' => {
379
+ 'type' => 'array',
380
+ 'item_type' => 'hash',
381
+ 'info' => 'the permissions of the widget',
382
+ 'nodoc' => false
383
+ },
384
+ 'can_edit' => {
385
+ '_config' => {
386
+ 'type' => 'boolean',
387
+ 'info' => 'can edit the widget',
388
+ 'nodoc' => false
389
+ },
390
+ }
391
+ },
392
+ }.with_indifferent_access
393
+ end
394
+
395
+ it "formats the custom response" do
396
+ subject.send(:format_presents!)
397
+
398
+ output = subject.output
399
+ expect(output).to include "The resulting JSON is an array of objects with the following properties\n\n"
400
+ expect(output).to include("- `widget_name` (`String`) - the name of the widget\n")
401
+ expect(output).to include("- `widget_permissions` (`Array<Hash>`) - the permissions of the widget\n")
402
+ expect(output).to include(" - `can_edit` (`Boolean`) - can edit the widget\n")
403
+ end
404
+ end
324
405
  end
325
406
 
326
- context "when present" do
407
+ context "when custom response is absent and presenter is present" do
408
+ let(:presenter) { Object.new }
409
+
327
410
  before do
411
+ stub(endpoint).custom_response { false }
412
+ stub(endpoint).presenter_title { "Sprocket Widget" }
413
+ stub(endpoint).relative_presenter_path_from_controller(:markdown) { "../../sprocket_widget.markdown" }
328
414
  stub(endpoint).presenter { presenter }
329
415
  end
330
416
 
@@ -32,21 +32,18 @@ module Brainstem
32
32
  end
33
33
  end
34
34
 
35
-
36
35
  describe "#md_p" do
37
36
  it "appends two newlines" do
38
37
  expect(subject.md_p(lipsum)).to eq(lipsum + "\n\n")
39
38
  end
40
39
  end
41
40
 
42
-
43
41
  describe "#md_strong" do
44
42
  it "wraps the text in asterisk pairs" do
45
43
  expect(subject.md_strong("Popeye")).to eq "**Popeye**"
46
44
  end
47
45
  end
48
46
 
49
-
50
47
  describe "#md_code" do
51
48
  it "renders the code between backtick blocks" do
52
49
  expect(subject.md_code('var my_var = 1;')).to eq "```\nvar my_var = 1;\n```\n\n"
@@ -57,14 +54,12 @@ module Brainstem
57
54
  end
58
55
  end
59
56
 
60
-
61
57
  describe "#md_inline_code" do
62
58
  it "renders the code between single backticks" do
63
59
  expect(subject.md_inline_code('my_var')).to eq "`my_var`"
64
60
  end
65
61
  end
66
62
 
67
-
68
63
  describe "#md_ul" do
69
64
  it "evaluates the block given to it in the instance's context" do
70
65
  mock(subject).md_h1('hello') { }
@@ -76,7 +71,6 @@ module Brainstem
76
71
  end
77
72
  end
78
73
 
79
-
80
74
  describe "#md_li" do
81
75
  it "renders the text after a dash-space with a newline" do
82
76
  expect(subject.md_li("text")).to eq "- text\n"
@@ -87,14 +81,12 @@ module Brainstem
87
81
  end
88
82
  end
89
83
 
90
-
91
84
  describe "#md_a" do
92
85
  it "renders the text in a bracket and includes a link in parens" do
93
86
  expect(subject.md_a("text", "link.md")).to eq "[text](link.md)"
94
87
  end
95
88
  end
96
89
 
97
-
98
90
  describe "#md_inline_type" do
99
91
  it "renders the code between single backticks" do
100
92
  expect(subject.md_inline_type("string")).to eq " (`String`)"
@@ -68,7 +68,6 @@ module Brainstem
68
68
  end
69
69
  end
70
70
 
71
-
72
71
  describe "#format_brainstem_keys!" do
73
72
  before do
74
73
  stub(presenter).brainstem_keys { [ "sprockets", "widgets" ] }
@@ -80,7 +79,6 @@ module Brainstem
80
79
  end
81
80
  end
82
81
 
83
-
84
82
  describe "#format_description!" do
85
83
  context "when present" do
86
84
  before do
@@ -107,7 +105,6 @@ module Brainstem
107
105
  end
108
106
  end
109
107
 
110
-
111
108
  describe "#format_fields!" do
112
109
  let(:presenter_class) do
113
110
  Class.new(Brainstem::Presenter) do
@@ -315,7 +312,6 @@ module Brainstem
315
312
  end
316
313
  end
317
314
 
318
-
319
315
  context "if it is conditional" do
320
316
  before do
321
317
  presenter_class.fields do
@@ -383,7 +379,6 @@ module Brainstem
383
379
  end
384
380
  end
385
381
 
386
-
387
382
  describe "#format_filters!" do
388
383
  let(:valid_filters) { {} }
389
384
 
@@ -440,7 +435,6 @@ module Brainstem
440
435
  end
441
436
  end
442
437
 
443
-
444
438
  describe "format_sort_orders!" do
445
439
  before do
446
440
  stub(presenter).valid_sort_orders { sort_orders }
@@ -492,7 +486,6 @@ module Brainstem
492
486
  end
493
487
  end
494
488
 
495
-
496
489
  describe "format_associations!" do
497
490
  let(:associations) { {} }
498
491
  let(:link) { nil }
@@ -0,0 +1,210 @@
1
+ require 'spec_helper'
2
+ require 'brainstem/api_docs/formatters/open_api_specification/helper'
3
+
4
+ module Brainstem
5
+ module ApiDocs
6
+ module Formatters
7
+ module OpenApiSpecification
8
+ describe Helper do
9
+ let(:klass) { Class.new { include Helper } }
10
+
11
+ subject { klass.new }
12
+
13
+ describe "presenter_title" do
14
+ let(:presenter) { Presenter }
15
+ let(:target_class) { "cool_stuff" }
16
+
17
+ before do
18
+ mock(presenter).contextual_documentation(:title) { title }
19
+ stub(presenter).target_class { target_class }
20
+ end
21
+
22
+ context "when presenter has a title" do
23
+ let(:title) { "Awesome Sauce!" }
24
+
25
+ it "returns the title" do
26
+ expect(subject.presenter_title(presenter)).to eq(title)
27
+ end
28
+ end
29
+
30
+ context "when presenter does not have a title" do
31
+ let(:title) { nil }
32
+
33
+ it "returns the formatted target class of the presenter" do
34
+ expect(subject.presenter_title(presenter)).to eq("Cool Stuff")
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "format_tag_name" do
40
+ context "when name is given" do
41
+ let(:title) { "awesome_sauce" }
42
+
43
+ it "returns the formatted name" do
44
+ expect(subject.format_tag_name(title)).to eq("Awesome Sauce")
45
+ end
46
+ end
47
+
48
+ context "when name is nil" do
49
+ let(:title) { nil }
50
+
51
+ it "returns nil" do
52
+ expect(subject.format_tag_name(title)).to be_nil
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "format_description" do
58
+ context "when description is given" do
59
+ let(:description) { " lorem ipsum dolor sit amet " }
60
+
61
+ it "returns the formatted description" do
62
+ expect(subject.format_description(description)).to eq("Lorem ipsum dolor sit amet.")
63
+ end
64
+ end
65
+
66
+ context "when description is nil" do
67
+ let(:description) { "" }
68
+
69
+ it "returns nil" do
70
+ expect(subject.format_description(description)).to eq('')
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "uncapitalize" do
76
+ context "when description is given" do
77
+ let(:description) { " Lorem ipsum dolor sit amet " }
78
+
79
+ it "returns the formatted description" do
80
+ expect(subject.uncapitalize(description)).to eq("lorem ipsum dolor sit amet")
81
+ end
82
+ end
83
+
84
+ context "when description is nil" do
85
+ let(:description) { "" }
86
+
87
+ it "returns nil" do
88
+ expect(subject.uncapitalize(description)).to eq("")
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "format_http_method" do
94
+ let(:endpoint) { OpenStruct.new(http_methods: %w(PATCH PUT)) }
95
+
96
+ it "returns the first downcased http method" do
97
+ expect(subject.format_http_method(endpoint)).to eq("patch")
98
+ end
99
+ end
100
+
101
+ describe "type_and_format" do
102
+ context "when type is 'string'" do
103
+ it "returns the correct type and format" do
104
+ expect(subject.type_and_format('string')).to eq({ 'type' => 'string' })
105
+ end
106
+ end
107
+
108
+ context "when type is 'boolean'" do
109
+ it "returns the correct type and format" do
110
+ expect(subject.send(:type_and_format, 'boolean')).to eq({ 'type' => 'boolean' })
111
+ end
112
+ end
113
+
114
+ context "when type is 'integer'" do
115
+ it "returns the correct type and format" do
116
+ expect(subject.send(:type_and_format, 'integer')).to eq({ 'type' => 'integer', 'format' => 'int32' })
117
+ end
118
+ end
119
+
120
+ context "when type is 'long'" do
121
+ it "returns the correct type and format" do
122
+ expect(subject.send(:type_and_format, 'long')).to eq({ 'type' => 'integer', 'format' => 'int64' })
123
+ end
124
+ end
125
+
126
+ context "when type is 'float'" do
127
+ it "returns the correct type and format" do
128
+ expect(subject.send(:type_and_format, 'float')).to eq({ 'type' => 'number', 'format' => 'float' })
129
+ end
130
+ end
131
+
132
+ context "when type is 'double'" do
133
+ it "returns the correct type and format" do
134
+ expect(subject.send(:type_and_format, 'double')).to eq({ 'type' => 'number', 'format' => 'double' })
135
+ end
136
+ end
137
+
138
+ context "when type is 'byte'" do
139
+ it "returns the correct type and format" do
140
+ expect(subject.send(:type_and_format, 'byte')).to eq({ 'type' => 'string', 'format' => 'byte' })
141
+ end
142
+ end
143
+
144
+ context "when type is 'binary'" do
145
+ it "returns the correct type and format" do
146
+ expect(subject.send(:type_and_format, 'binary')).to eq({ 'type' => 'string', 'format' => 'binary' })
147
+ end
148
+ end
149
+
150
+ context "when type is 'date'" do
151
+ it "returns the correct type and format" do
152
+ expect(subject.send(:type_and_format, 'date')).to eq({ 'type' => 'string', 'format' => 'date' })
153
+ end
154
+ end
155
+
156
+ context "when type is 'datetime'" do
157
+ it "returns the correct type and format" do
158
+ expect(subject.send(:type_and_format, 'datetime')).to eq({ 'type' => 'string', 'format' => 'date-time' })
159
+ end
160
+ end
161
+
162
+ context "when type is 'password'" do
163
+ it "returns the correct type and format" do
164
+ expect(subject.send(:type_and_format, 'password')).to eq({ 'type' => 'string', 'format' => 'password' })
165
+ end
166
+ end
167
+
168
+ context "when type is 'id'" do
169
+ it "returns the correct type and format" do
170
+ expect(subject.send(:type_and_format, 'id')).to eq({ 'type' => 'integer', 'format' => 'int32' })
171
+ end
172
+ end
173
+
174
+ context "when type is 'decimal'" do
175
+ it "returns the correct type and format" do
176
+ expect(subject.send(:type_and_format, 'decimal')).to eq({ 'type' => 'number', 'format' => 'float' })
177
+ end
178
+ end
179
+
180
+ context "when type is array" do
181
+ context "when item type is not specified" do
182
+ it "returns type as `array` and item type as `string`" do
183
+ expect(subject.send(:type_and_format, 'array')).to eq({
184
+ 'type' => 'array',
185
+ 'items' => { 'type' => 'string' }
186
+ })
187
+ end
188
+ end
189
+
190
+ context "when item type is specified" do
191
+ it "returns type as `array` and given item type" do
192
+ expect(subject.send(:type_and_format, 'array', 'integer')).to eq({
193
+ 'type' => 'array',
194
+ 'items' => { 'type' => 'integer' }
195
+ })
196
+ end
197
+ end
198
+ end
199
+
200
+ context "when type is unknown" do
201
+ it "returns nil" do
202
+ expect(subject.send(:type_and_format, 'invalid')).to be_nil
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end