brainstem 2.0.0 → 2.1.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +147 -0
  3. data/Gemfile.lock +68 -39
  4. data/lib/brainstem/api_docs.rb +9 -4
  5. data/lib/brainstem/api_docs/atlas.rb +3 -3
  6. data/lib/brainstem/api_docs/controller.rb +12 -4
  7. data/lib/brainstem/api_docs/controller_collection.rb +11 -2
  8. data/lib/brainstem/api_docs/endpoint.rb +17 -7
  9. data/lib/brainstem/api_docs/endpoint_collection.rb +9 -1
  10. data/lib/brainstem/api_docs/formatters/open_api_specification/helper.rb +19 -16
  11. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter.rb +52 -80
  12. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter.rb +64 -84
  13. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_formatter.rb +1 -1
  14. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/endpoint_param_formatter.rb +39 -0
  15. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/presenter_field_formatter.rb +147 -0
  16. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/response_field_formatter.rb +146 -0
  17. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter.rb +53 -55
  18. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter.rb +1 -1
  19. data/lib/brainstem/api_docs/presenter.rb +16 -8
  20. data/lib/brainstem/api_docs/presenter_collection.rb +8 -5
  21. data/lib/brainstem/api_docs/sinks/open_api_specification_sink.rb +3 -1
  22. data/lib/brainstem/cli/generate_api_docs_command.rb +4 -0
  23. data/lib/brainstem/concerns/controller_dsl.rb +90 -20
  24. data/lib/brainstem/concerns/presenter_dsl.rb +16 -8
  25. data/lib/brainstem/dsl/association.rb +12 -0
  26. data/lib/brainstem/dsl/fields_block.rb +1 -1
  27. data/lib/brainstem/version.rb +1 -1
  28. data/spec/brainstem/api_docs/controller_spec.rb +127 -5
  29. data/spec/brainstem/api_docs/endpoint_spec.rb +489 -57
  30. data/spec/brainstem/api_docs/formatters/open_api_specification/helper_spec.rb +15 -4
  31. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter_spec.rb +112 -66
  32. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter_spec.rb +404 -32
  33. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/endpoint_param_formatter_spec.rb +335 -0
  34. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/presenter_field_formatter_spec.rb +237 -0
  35. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/response_field_formatter_spec.rb +413 -0
  36. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter_spec.rb +116 -4
  37. data/spec/brainstem/api_docs/presenter_spec.rb +406 -24
  38. data/spec/brainstem/cli/generate_api_docs_command_spec.rb +8 -0
  39. data/spec/brainstem/concerns/controller_dsl_spec.rb +606 -45
  40. data/spec/brainstem/concerns/presenter_dsl_spec.rb +34 -2
  41. data/spec/brainstem/dsl/association_spec.rb +54 -3
  42. metadata +11 -2
@@ -15,7 +15,7 @@ module Brainstem
15
15
 
16
16
  private
17
17
 
18
- NON_INHERITABLE_FIELD_OPTIONS = [:dynamic, :via, :lookup, :lookup_fetch, :info, :type, :item_type]
18
+ NON_INHERITABLE_FIELD_OPTIONS = [:dynamic, :via, :lookup, :lookup_fetch, :info, :type, :item_type, :nested_levels, :dynamic_key]
19
19
  private_constant :NON_INHERITABLE_FIELD_OPTIONS
20
20
 
21
21
  def merge_parent_options(block_options, parent_options)
@@ -1,3 +1,3 @@
1
1
  module Brainstem
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -6,7 +6,8 @@ module Brainstem
6
6
  describe Controller do
7
7
  subject { described_class.new(atlas, options) }
8
8
  let(:atlas) { Object.new }
9
- let(:options) { {} }
9
+ let(:options) { {include_internal: internal_flag} }
10
+ let(:internal_flag) { false }
10
11
 
11
12
  describe "#initialize" do
12
13
  it "yields self if given a block" do
@@ -31,9 +32,10 @@ module Brainstem
31
32
  let(:default_config) { {} }
32
33
  let(:show_config) { {} }
33
34
  let(:nodoc) { false }
34
- let(:options) { { const: const } }
35
+ let(:internal) { false }
35
36
 
36
37
  before do
38
+ options[:const] = const
37
39
  stub(const) do |constant|
38
40
  constant.configuration { {
39
41
  :_default => default_config,
@@ -46,12 +48,52 @@ module Brainstem
46
48
 
47
49
  describe "configuration helpers" do
48
50
  describe "#contextual_documentation" do
49
- let(:default_config) { { title: { info: info, nodoc: nodoc } } }
51
+ let(:default_config) { { title: { info: info, nodoc: nodoc, internal: internal } } }
50
52
  let(:info) { lorem }
51
53
 
52
54
  context "when has the key" do
53
55
  let(:key) { :title }
54
56
 
57
+ context "when internal flag is true" do
58
+ let(:internal_flag) { true }
59
+
60
+ context "when contextual key is internal" do
61
+ let(:internal) { true }
62
+
63
+ it "is truthy" do
64
+ expect(subject.contextual_documentation(key)).to be_truthy
65
+ end
66
+ end
67
+
68
+ context "when contextual key is not internal" do
69
+ let(:internal) { false }
70
+
71
+ it "is truthy" do
72
+ expect(subject.contextual_documentation(key)).to be_truthy
73
+ end
74
+ end
75
+ end
76
+
77
+ context "when internal flag is false" do
78
+ let(:internal_flag) { false }
79
+
80
+ context "when contextual key is internal" do
81
+ let(:internal) { true }
82
+
83
+ it "is falsey" do
84
+ expect(subject.contextual_documentation(key)).to be_falsey
85
+ end
86
+ end
87
+
88
+ context "when contextual key is not internal" do
89
+ let(:internal) { false }
90
+
91
+ it "is truthy" do
92
+ expect(subject.contextual_documentation(key)).to be_truthy
93
+ end
94
+ end
95
+ end
96
+
55
97
  context "when not nodoc" do
56
98
  context "when has info" do
57
99
  it "is truthy" do
@@ -141,7 +183,7 @@ module Brainstem
141
183
 
142
184
  describe "#title" do
143
185
  context "when present" do
144
- let(:default_config) { { title: { info: lorem, nodoc: nodoc } } }
186
+ let(:default_config) { { title: { info: lorem, nodoc: nodoc, internal: internal } } }
145
187
 
146
188
  context "when nodoc" do
147
189
  let(:nodoc) { true }
@@ -156,6 +198,46 @@ module Brainstem
156
198
  expect(subject.title).to eq lorem
157
199
  end
158
200
  end
201
+
202
+ context "when internal flag is true" do
203
+ let(:internal_flag) { true }
204
+
205
+ context "when title is internal" do
206
+ let(:internal) { true }
207
+
208
+ it "shows the title" do
209
+ expect(subject.title).to eq lorem
210
+ end
211
+ end
212
+
213
+ context "when title is not internal" do
214
+ let(:internal) { false }
215
+
216
+ it "shows the title" do
217
+ expect(subject.title).to eq lorem
218
+ end
219
+ end
220
+ end
221
+
222
+ context "when internal flag is false" do
223
+ let(:internal_flag) { false }
224
+
225
+ context "when title is internal" do
226
+ let(:internal) { true }
227
+
228
+ it "falls back to the controller class" do
229
+ expect(subject.title).to eq "ClassName"
230
+ end
231
+ end
232
+
233
+ context "when title is not internal" do
234
+ let(:internal) { false }
235
+
236
+ it "shows the title" do
237
+ expect(subject.title).to eq lorem
238
+ end
239
+ end
240
+ end
159
241
  end
160
242
 
161
243
  context "when absent" do
@@ -167,7 +249,7 @@ module Brainstem
167
249
 
168
250
  describe "#description" do
169
251
  context "when present" do
170
- let(:default_config) { { description: { info: lorem, nodoc: nodoc } } }
252
+ let(:default_config) { { description: { info: lorem, nodoc: nodoc, internal: internal } } }
171
253
 
172
254
  context "when nodoc" do
173
255
  let(:nodoc) { true }
@@ -182,6 +264,46 @@ module Brainstem
182
264
  expect(subject.description).to eq lorem
183
265
  end
184
266
  end
267
+
268
+ context "when internal flag is true" do
269
+ let(:internal_flag) { true }
270
+
271
+ context "when description is internal" do
272
+ let(:internal) { true }
273
+
274
+ it "shows the description" do
275
+ expect(subject.description).to eq lorem
276
+ end
277
+ end
278
+
279
+ context "when description is not internal" do
280
+ let(:internal) { false }
281
+
282
+ it "shows the description" do
283
+ expect(subject.description).to eq lorem
284
+ end
285
+ end
286
+ end
287
+
288
+ context "when internal flag is false" do
289
+ let(:internal_flag) { false }
290
+
291
+ context "when description is internal" do
292
+ let(:internal) { true }
293
+
294
+ it "shows nothing" do
295
+ expect(subject.description).to eq ""
296
+ end
297
+ end
298
+
299
+ context "when description is not internal" do
300
+ let(:internal) { false }
301
+
302
+ it "shows the description" do
303
+ expect(subject.description).to eq lorem
304
+ end
305
+ end
306
+ end
185
307
  end
186
308
 
187
309
  context "when absent" do
@@ -4,10 +4,11 @@ require 'brainstem/api_docs/endpoint'
4
4
  module Brainstem
5
5
  module ApiDocs
6
6
  describe Endpoint do
7
- let(:lorem) { "lorem ipsum dolor sit amet" }
8
- let(:atlas) { Object.new }
9
- let(:options) { {} }
10
- subject { described_class.new(atlas, options) }
7
+ let(:lorem) { "lorem ipsum dolor sit amet" }
8
+ let(:atlas) { Object.new }
9
+ let(:options) { { include_internal: internal_flag } }
10
+ let(:internal_flag) { false }
11
+ subject { described_class.new(atlas, options) }
11
12
 
12
13
  describe "#initialize" do
13
14
  it "yields self if given a block" do
@@ -17,7 +18,9 @@ module Brainstem
17
18
  end
18
19
 
19
20
  describe "#merge_http_methods!" do
20
- let(:options) { { http_methods: %w(GET) } }
21
+ before do
22
+ options[:http_methods] = %w(GET)
23
+ end
21
24
 
22
25
  it "adds http methods that are not already present" do
23
26
 
@@ -36,30 +39,31 @@ module Brainstem
36
39
  end
37
40
  end
38
41
 
39
- let(:controller) { Object.new }
40
- let(:action) { :show }
42
+ let(:controller) { Object.new }
43
+ let(:action) { :show }
41
44
 
42
- let(:lorem) { "lorem ipsum dolor sit amet" }
45
+ let(:lorem) { "lorem ipsum dolor sit amet" }
43
46
  let(:default_config) { {} }
44
- let(:show_config) { {} }
45
- let(:nodoc) { false }
47
+ let(:show_config) { {} }
48
+ let(:nodoc) { false }
49
+ let(:internal) { false }
46
50
 
47
- let(:configuration) {
51
+ let(:configuration) {
48
52
  {
49
53
  :_default => default_config,
50
- :show => show_config,
54
+ :show => show_config,
51
55
  }
52
56
  }
53
57
 
54
- let(:options) { { controller: controller, action: action } }
55
-
56
58
  before do
57
59
  stub(controller).configuration { configuration }
58
60
  stub(controller).const { const }
61
+ options[:controller] = controller
62
+ options[:action] = action
59
63
  end
60
64
 
61
65
  describe "#nodoc?" do
62
- let(:show_config) { { nodoc: nodoc } }
66
+ let(:show_config) { { nodoc: nodoc, internal: internal } }
63
67
 
64
68
  context "when nodoc" do
65
69
  let(:nodoc) { true }
@@ -69,6 +73,46 @@ module Brainstem
69
73
  end
70
74
  end
71
75
 
76
+ context "when internal flag is true" do
77
+ let(:internal_flag) { true }
78
+
79
+ context "when action config is internal" do
80
+ let(:internal) { true }
81
+
82
+ it "is false" do
83
+ expect(subject.nodoc?).to eq false
84
+ end
85
+ end
86
+
87
+ context "when action config is not internal" do
88
+ let(:internal) { false }
89
+
90
+ it "is false" do
91
+ expect(subject.nodoc?).to eq false
92
+ end
93
+ end
94
+ end
95
+
96
+ context "when internal flag is false" do
97
+ let(:internal_flag) { false }
98
+
99
+ context "when action config is internal" do
100
+ let(:internal) { true }
101
+
102
+ it "is true" do
103
+ expect(subject.nodoc?).to eq true
104
+ end
105
+ end
106
+
107
+ context "when action config is not internal" do
108
+ let(:internal) { false }
109
+
110
+ it "is false" do
111
+ expect(subject.nodoc?).to eq false
112
+ end
113
+ end
114
+ end
115
+
72
116
  context "when documentable" do
73
117
  it "is false" do
74
118
  expect(subject.nodoc?).to eq false
@@ -78,7 +122,7 @@ module Brainstem
78
122
 
79
123
  describe "#title" do
80
124
  context "when present" do
81
- let(:show_config) { { title: { info: lorem, nodoc: nodoc } } }
125
+ let(:show_config) { { title: { info: lorem, nodoc: nodoc, internal: internal } } }
82
126
 
83
127
  context "when nodoc" do
84
128
  let(:nodoc) { true }
@@ -93,6 +137,46 @@ module Brainstem
93
137
  expect(subject.title).to eq lorem
94
138
  end
95
139
  end
140
+
141
+ context "when internal flag is true" do
142
+ let(:internal_flag) { true }
143
+
144
+ context "when title is internal" do
145
+ let(:internal) { true }
146
+
147
+ it "formats the title as an h4" do
148
+ expect(subject.title).to eq lorem
149
+ end
150
+ end
151
+
152
+ context "when title is not internal" do
153
+ let(:internal) { false }
154
+
155
+ it "formats the title as an h4" do
156
+ expect(subject.title).to eq lorem
157
+ end
158
+ end
159
+ end
160
+
161
+ context "when internal flag is false" do
162
+ let(:internal_flag) { false }
163
+
164
+ context "when title is internal" do
165
+ let(:internal) { true }
166
+
167
+ it "uses the action name" do
168
+ expect(subject.title).to eq "Show"
169
+ end
170
+ end
171
+
172
+ context "when title is not internal" do
173
+ let(:internal) { false }
174
+
175
+ it "formats the title as an h4" do
176
+ expect(subject.title).to eq lorem
177
+ end
178
+ end
179
+ end
96
180
  end
97
181
 
98
182
  context "when absent" do
@@ -104,7 +188,7 @@ module Brainstem
104
188
 
105
189
  describe "#description" do
106
190
  context "when present" do
107
- let(:show_config) { { description: { info: lorem, nodoc: nodoc } } }
191
+ let(:show_config) { { description: { info: lorem, nodoc: nodoc, internal: internal } } }
108
192
 
109
193
  context "when nodoc" do
110
194
  let(:nodoc) { true }
@@ -119,6 +203,46 @@ module Brainstem
119
203
  expect(subject.description).to eq lorem
120
204
  end
121
205
  end
206
+
207
+ context "when internal flag is true" do
208
+ let(:internal_flag) { true }
209
+
210
+ context "when description is internal" do
211
+ let(:internal) { true }
212
+
213
+ it "shows the description" do
214
+ expect(subject.description).to eq lorem
215
+ end
216
+ end
217
+
218
+ context "when description is not internal" do
219
+ let(:internal) { false }
220
+
221
+ it "shows the description" do
222
+ expect(subject.description).to eq lorem
223
+ end
224
+ end
225
+ end
226
+
227
+ context "when internal flag is false" do
228
+ let(:internal_flag) { false }
229
+
230
+ context "when description is internal" do
231
+ let(:internal) { true }
232
+
233
+ it "shows nothing" do
234
+ expect(subject.description).to be_empty
235
+ end
236
+ end
237
+
238
+ context "when description is not internal" do
239
+ let(:internal) { false }
240
+
241
+ it "shows the description" do
242
+ expect(subject.description).to eq lorem
243
+ end
244
+ end
245
+ end
122
246
  end
123
247
 
124
248
  context "when not present" do
@@ -199,7 +323,7 @@ module Brainstem
199
323
  let(:default_config) { { valid_params: which_param } }
200
324
 
201
325
  context "non-nested params" do
202
- let(:root_param) { { Proc.new { 'title' } => { nodoc: nodoc, type: 'string' } } }
326
+ let(:root_param) { { Proc.new { 'title' } => { nodoc: nodoc, type: 'string', internal: internal } } }
203
327
  let(:which_param) { root_param }
204
328
 
205
329
  context "when nodoc" do
@@ -217,7 +341,7 @@ module Brainstem
217
341
  expect(subject.params_configuration_tree).to eq(
218
342
  {
219
343
  title: {
220
- _config: { nodoc: nodoc, type: 'string' }
344
+ _config: { type: 'string' }
221
345
  }
222
346
  }.with_indifferent_access
223
347
  )
@@ -230,7 +354,65 @@ module Brainstem
230
354
  expect(subject.params_configuration_tree).to eq(
231
355
  {
232
356
  only: {
233
- _config: { nodoc: nodoc, type: 'array', item: 'integer' }
357
+ _config: { type: 'array', item: 'integer' }
358
+ }
359
+ }.with_indifferent_access
360
+ )
361
+ end
362
+ end
363
+ end
364
+
365
+ context "when internal flag is true" do
366
+ let(:internal_flag) { true }
367
+
368
+ context "when params_configuration_tree is internal" do
369
+ let(:internal) { true }
370
+
371
+ it "lists it as a root param" do
372
+ expect(subject.params_configuration_tree).to eq(
373
+ {
374
+ title: {
375
+ _config: { type: 'string' }
376
+ }
377
+ }.with_indifferent_access
378
+ )
379
+ end
380
+ end
381
+
382
+ context "when params_configuration_tree is not internal" do
383
+ let(:internal) { false }
384
+
385
+ it "lists it as a root param" do
386
+ expect(subject.params_configuration_tree).to eq(
387
+ {
388
+ title: {
389
+ _config: { type: 'string' }
390
+ }
391
+ }.with_indifferent_access
392
+ )
393
+ end
394
+ end
395
+ end
396
+
397
+ context "when internal flag is false" do
398
+ let(:internal_flag) { false }
399
+
400
+ context "when description is internal" do
401
+ let(:internal) { true }
402
+
403
+ it "rejects the key" do
404
+ expect(subject.params_configuration_tree).to be_empty
405
+ end
406
+ end
407
+
408
+ context "when description is not internal" do
409
+ let(:internal) { false }
410
+
411
+ it "lists it as a root param" do
412
+ expect(subject.params_configuration_tree).to eq(
413
+ {
414
+ title: {
415
+ _config: { type: 'string' }
234
416
  }
235
417
  }.with_indifferent_access
236
418
  )
@@ -242,7 +424,13 @@ module Brainstem
242
424
  context "nested params" do
243
425
  let(:root_proc) { Proc.new { 'sprocket' } }
244
426
  let(:nested_param) {
245
- { Proc.new { 'title' } => { nodoc: nodoc, type: 'string', root: root_proc, ancestors: [root_proc] } }
427
+ { Proc.new { 'title' } => {
428
+ nodoc: nodoc,
429
+ type: 'string',
430
+ root: root_proc,
431
+ ancestors: [root_proc],
432
+ internal: internal
433
+ } }
246
434
  }
247
435
  let(:which_param) { nested_param }
248
436
 
@@ -254,6 +442,85 @@ module Brainstem
254
442
  end
255
443
  end
256
444
 
445
+ context "when internal flag is true" do
446
+ let(:internal_flag) { true }
447
+
448
+ context "when params_configuration_tree is internal" do
449
+ let(:internal) { true }
450
+
451
+ it "lists it as a nested param" do
452
+ expect(subject.params_configuration_tree).to eq(
453
+ {
454
+ sprocket: {
455
+ _config: {
456
+ type: 'hash',
457
+ },
458
+ title: {
459
+ _config: {
460
+ type: 'string'
461
+ }
462
+ }
463
+ }
464
+ }.with_indifferent_access
465
+ )
466
+ end
467
+ end
468
+
469
+ context "when params_configuration_tree is not internal" do
470
+ let(:internal) { false }
471
+
472
+ it "lists it as a nested param" do
473
+ expect(subject.params_configuration_tree).to eq(
474
+ {
475
+ sprocket: {
476
+ _config: {
477
+ type: 'hash',
478
+ },
479
+ title: {
480
+ _config: {
481
+ type: 'string'
482
+ }
483
+ }
484
+ }
485
+ }.with_indifferent_access
486
+ )
487
+ end
488
+ end
489
+ end
490
+
491
+ context "when internal flag is false" do
492
+ let(:internal_flag) { false }
493
+
494
+ context "when description is internal" do
495
+ let(:internal) { true }
496
+
497
+ it "rejects the key" do
498
+ expect(subject.params_configuration_tree).to be_empty
499
+ end
500
+ end
501
+
502
+ context "when description is not internal" do
503
+ let(:internal) { false }
504
+
505
+ it "lists it as a nested param" do
506
+ expect(subject.params_configuration_tree).to eq(
507
+ {
508
+ sprocket: {
509
+ _config: {
510
+ type: 'hash',
511
+ },
512
+ title: {
513
+ _config: {
514
+ type: 'string'
515
+ }
516
+ }
517
+ }
518
+ }.with_indifferent_access
519
+ )
520
+ end
521
+ end
522
+ end
523
+
257
524
  context "when not nodoc" do
258
525
  it "lists it as a nested param" do
259
526
  expect(subject.params_configuration_tree).to eq(
@@ -264,7 +531,6 @@ module Brainstem
264
531
  },
265
532
  title: {
266
533
  _config: {
267
- nodoc: nodoc,
268
534
  type: 'string'
269
535
  }
270
536
  }
@@ -289,7 +555,6 @@ module Brainstem
289
555
  },
290
556
  ids: {
291
557
  _config: {
292
- nodoc: nodoc,
293
558
  type: 'array',
294
559
  item: 'integer'
295
560
  }
@@ -303,11 +568,11 @@ module Brainstem
303
568
  end
304
569
 
305
570
  context "proc nested params" do
306
- let!(:root_proc) { Proc.new { |klass| klass.brainstem_model_name } }
571
+ let!(:root_proc) { Proc.new { |klass| klass.brainstem_model_name } }
307
572
  let(:proc_nested_param) {
308
573
  { Proc.new { 'title' } => { nodoc: nodoc, type: 'string', root: root_proc, ancestors: [root_proc] } }
309
574
  }
310
- let(:which_param) { proc_nested_param }
575
+ let(:which_param) { proc_nested_param }
311
576
 
312
577
  context "when nodoc" do
313
578
  let(:nodoc) { true }
@@ -328,20 +593,19 @@ module Brainstem
328
593
  expect(children_of_the_root.keys).to eq(%w(title))
329
594
 
330
595
  title_param = children_of_the_root[:title][:_config]
331
- expect(title_param.keys).to eq(%w(nodoc type))
332
- expect(title_param[:nodoc]).to eq(nodoc)
596
+ expect(title_param.keys).to eq(%w(type))
333
597
  expect(title_param[:type]).to eq('string')
334
598
  end
335
599
  end
336
600
  end
337
601
 
338
602
  context "multi nested params" do
339
- let(:project_proc) { Proc.new { 'project' } }
340
- let(:id_proc) { Proc.new { 'id' } }
341
- let(:task_proc) { Proc.new { 'task' } }
342
- let(:title_proc) { Proc.new { 'title' } }
603
+ let(:project_proc) { Proc.new { 'project' } }
604
+ let(:id_proc) { Proc.new { 'id' } }
605
+ let(:task_proc) { Proc.new { 'task' } }
606
+ let(:title_proc) { Proc.new { 'title' } }
343
607
  let(:checklist_proc) { Proc.new { 'checklist' } }
344
- let(:name_proc) { Proc.new { 'name' } }
608
+ let(:name_proc) { Proc.new { 'name' } }
345
609
 
346
610
  context "has a root & ancestors" do
347
611
  let(:which_param) {
@@ -600,12 +864,52 @@ module Brainstem
600
864
  end
601
865
 
602
866
  describe "#contextual_documentation" do
603
- let(:show_config) { { title: { info: info, nodoc: nodoc } } }
604
- let(:info) { lorem }
867
+ let(:show_config) { { title: { info: info, nodoc: nodoc, internal: internal } } }
868
+ let(:info) { lorem }
605
869
 
606
870
  context "when has the key" do
607
871
  let(:key) { :title }
608
872
 
873
+ context "when internal flag is true" do
874
+ let(:internal_flag) { true }
875
+
876
+ context "when contextual key is internal" do
877
+ let(:internal) { true }
878
+
879
+ it "is the info" do
880
+ expect(subject.contextual_documentation(key)).to eq lorem
881
+ end
882
+ end
883
+
884
+ context "when contextual key is not internal" do
885
+ let(:internal) { false }
886
+
887
+ it "is the info" do
888
+ expect(subject.contextual_documentation(key)).to eq lorem
889
+ end
890
+ end
891
+ end
892
+
893
+ context "when internal flag is false" do
894
+ let(:internal_flag) { false }
895
+
896
+ context "when contextual key is internal" do
897
+ let(:internal) { true }
898
+
899
+ it "is falsey" do
900
+ expect(subject.contextual_documentation(key)).to be_falsey
901
+ end
902
+ end
903
+
904
+ context "when contextual key is not internal" do
905
+ let(:internal) { false }
906
+
907
+ it "is the info" do
908
+ expect(subject.contextual_documentation(key)).to eq lorem
909
+ end
910
+ end
911
+ end
912
+
609
913
  context "when not nodoc" do
610
914
  context "when has info" do
611
915
  it "is truthy" do
@@ -648,7 +952,7 @@ module Brainstem
648
952
  let(:default_config) { { info: "default" } }
649
953
 
650
954
  context "when it has the key in the action config" do
651
- let(:show_config) { { info: "show" } }
955
+ let(:show_config) { { info: "show" } }
652
956
 
653
957
  it "returns that" do
654
958
  expect(subject.key_with_default_fallback(:info)).to eq "show"
@@ -670,7 +974,7 @@ module Brainstem
670
974
  let(axn.to_sym) { described_class.new(atlas, action: axn.to_sym) }
671
975
  end
672
976
 
673
- let(:axns) { actions.map {|axn| send(axn.to_sym) } }
977
+ let(:axns) { actions.map { |axn| send(axn.to_sym) } }
674
978
 
675
979
  it "orders appropriately" do
676
980
  sorted = axns.reverse.sort
@@ -687,7 +991,7 @@ module Brainstem
687
991
 
688
992
  describe "#presenter_title" do
689
993
  let(:presenter) { mock!.title.returns(lorem).subject }
690
- let(:options) { { presenter: presenter } }
994
+ let(:options) { { presenter: presenter } }
691
995
 
692
996
  it "returns the presenter's title" do
693
997
  expect(subject.presenter_title).to eq lorem
@@ -726,15 +1030,15 @@ module Brainstem
726
1030
  end
727
1031
  end
728
1032
 
729
- let(:controller) { Object.new }
730
- let(:action) { :show }
731
- let(:show_config) { {} }
732
- let(:nodoc) { false }
733
- let(:configuration) { { :show => show_config } }
734
-
735
- let(:options) { { controller: controller, action: action } }
1033
+ let(:controller) { Object.new }
1034
+ let(:action) { :show }
1035
+ let(:show_config) { {} }
1036
+ let(:nodoc) { false }
1037
+ let(:configuration) { { :show => show_config } }
736
1038
 
737
1039
  before do
1040
+ options[:controller] = controller
1041
+ options[:action] = action
738
1042
  stub(controller).configuration { configuration }
739
1043
  stub(controller).const { const }
740
1044
  end
@@ -782,7 +1086,7 @@ module Brainstem
782
1086
  {
783
1087
  _config: default_response_config,
784
1088
  title: {
785
- _config: { nodoc: nodoc, type: 'string' }
1089
+ _config: { type: 'string' }
786
1090
  }
787
1091
  }.with_indifferent_access
788
1092
  )
@@ -798,7 +1102,7 @@ module Brainstem
798
1102
  {
799
1103
  _config: default_response_config,
800
1104
  only: {
801
- _config: { nodoc: nodoc, type: 'array', item: 'integer' }
1105
+ _config: { type: 'array', item: 'integer' }
802
1106
  }
803
1107
  }.with_indifferent_access
804
1108
  )
@@ -808,11 +1112,30 @@ module Brainstem
808
1112
  end
809
1113
 
810
1114
  context "nested params" do
1115
+ let(:internal) { false }
811
1116
  let(:parent_proc) { Proc.new { 'sprocket' } }
812
1117
  let(:other_response_fields) do
813
1118
  {
814
- parent_proc => { nodoc: nodoc, type: 'array', item_type: 'hash' },
815
- Proc.new { 'title' } => { nodoc: nodoc, type: 'string', ancestors: [parent_proc] }
1119
+ parent_proc => {
1120
+ nodoc: nodoc,
1121
+ type: 'array',
1122
+ item_type: 'hash',
1123
+ internal: internal
1124
+ },
1125
+ Proc.new { 'title' } => {
1126
+ nodoc: nodoc,
1127
+ type: 'string',
1128
+ ancestors: [parent_proc],
1129
+ internal: internal
1130
+ },
1131
+ Proc.new { 'nested_array' } => {
1132
+ nodoc: nodoc,
1133
+ type: 'array',
1134
+ item_type: 'string',
1135
+ nested_levels: 2,
1136
+ ancestors: [parent_proc],
1137
+ internal: internal
1138
+ },
816
1139
  }
817
1140
  end
818
1141
 
@@ -828,6 +1151,112 @@ module Brainstem
828
1151
  end
829
1152
  end
830
1153
 
1154
+ context "when internal flag is true" do
1155
+ let(:internal_flag) { true }
1156
+
1157
+ context "when tree is internal" do
1158
+ let(:internal) { true }
1159
+
1160
+ it "lists it as a nested param" do
1161
+ expect(subject.custom_response_configuration_tree).to eq(
1162
+ {
1163
+ _config: default_response_config,
1164
+ sprocket: {
1165
+ _config: {
1166
+ type: 'array',
1167
+ item_type: 'hash'
1168
+ },
1169
+ title: {
1170
+ _config: {
1171
+ type: 'string'
1172
+ }
1173
+ },
1174
+ nested_array: {
1175
+ _config: {
1176
+ type: 'array',
1177
+ nested_levels: 2,
1178
+ item_type: 'string'
1179
+ }
1180
+ }
1181
+ }
1182
+ }.with_indifferent_access
1183
+ )
1184
+ end
1185
+ end
1186
+
1187
+ context "when params_configuration_tree is not internal" do
1188
+ let(:internal) { false }
1189
+
1190
+ it "lists it as a nested param" do
1191
+ expect(subject.custom_response_configuration_tree).to eq(
1192
+ {
1193
+ _config: default_response_config,
1194
+ sprocket: {
1195
+ _config: {
1196
+ type: 'array',
1197
+ item_type: 'hash'
1198
+ },
1199
+ title: {
1200
+ _config: {
1201
+ type: 'string'
1202
+ }
1203
+ },
1204
+ nested_array: {
1205
+ _config: {
1206
+ type: 'array',
1207
+ nested_levels: 2,
1208
+ item_type: 'string'
1209
+ }
1210
+ }
1211
+ }
1212
+ }.with_indifferent_access
1213
+ )
1214
+ end
1215
+ end
1216
+ end
1217
+
1218
+ context "when internal flag is false" do
1219
+ let(:internal_flag) { false }
1220
+
1221
+ context "when description is internal" do
1222
+ let(:internal) { true }
1223
+
1224
+ it "rejects the key" do
1225
+ expect(subject.params_configuration_tree).to be_empty
1226
+ end
1227
+ end
1228
+
1229
+ context "when description is not internal" do
1230
+ let(:internal) { false }
1231
+
1232
+ it "lists it as a nested param" do
1233
+ expect(subject.custom_response_configuration_tree).to eq(
1234
+ {
1235
+ _config: default_response_config,
1236
+ sprocket: {
1237
+ _config: {
1238
+ type: 'array',
1239
+ item_type: 'hash'
1240
+ },
1241
+ title: {
1242
+ _config: {
1243
+ type: 'string'
1244
+ }
1245
+ },
1246
+ nested_array: {
1247
+ _config: {
1248
+ type: 'array',
1249
+ nested_levels: 2,
1250
+ item_type: 'string'
1251
+ }
1252
+ }
1253
+ }
1254
+ }.with_indifferent_access
1255
+ )
1256
+ end
1257
+ end
1258
+ end
1259
+
831
1260
  context "when not nodoc" do
832
1261
  it "lists it as a nested param" do
833
1262
  expect(subject.custom_response_configuration_tree).to eq(
@@ -835,15 +1264,20 @@ module Brainstem
835
1264
  _config: default_response_config,
836
1265
  sprocket: {
837
1266
  _config: {
838
- nodoc: nodoc,
839
1267
  type: 'array',
840
1268
  item_type: 'hash'
841
1269
  },
842
1270
  title: {
843
1271
  _config: {
844
- nodoc: nodoc,
845
1272
  type: 'string'
846
1273
  }
1274
+ },
1275
+ nested_array: {
1276
+ _config: {
1277
+ type: 'array',
1278
+ nested_levels: 2,
1279
+ item_type: 'string'
1280
+ }
847
1281
  }
848
1282
  }
849
1283
  }.with_indifferent_access
@@ -864,13 +1298,11 @@ module Brainstem
864
1298
  _config: default_response_config,
865
1299
  sprocket: {
866
1300
  _config: {
867
- nodoc: nodoc,
868
1301
  type: 'array',
869
1302
  item_type: 'hash'
870
1303
  },
871
1304
  ids: {
872
1305
  _config: {
873
- nodoc: nodoc,
874
1306
  type: 'array',
875
1307
  item: 'integer'
876
1308
  }
@@ -884,12 +1316,12 @@ module Brainstem
884
1316
  end
885
1317
 
886
1318
  context "multi nested params" do
887
- let(:project_proc) { Proc.new { 'project' } }
888
- let(:id_proc) { Proc.new { 'id' } }
889
- let(:task_proc) { Proc.new { 'task' } }
890
- let(:title_proc) { Proc.new { 'title' } }
1319
+ let(:project_proc) { Proc.new { 'project' } }
1320
+ let(:id_proc) { Proc.new { 'id' } }
1321
+ let(:task_proc) { Proc.new { 'task' } }
1322
+ let(:title_proc) { Proc.new { 'title' } }
891
1323
  let(:checklist_proc) { Proc.new { 'checklist' } }
892
- let(:name_proc) { Proc.new { 'name' } }
1324
+ let(:name_proc) { Proc.new { 'name' } }
893
1325
  let(:other_response_fields) do
894
1326
  {
895
1327
  task_proc => {