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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +147 -0
- data/Gemfile.lock +68 -39
- data/lib/brainstem/api_docs.rb +9 -4
- data/lib/brainstem/api_docs/atlas.rb +3 -3
- data/lib/brainstem/api_docs/controller.rb +12 -4
- data/lib/brainstem/api_docs/controller_collection.rb +11 -2
- data/lib/brainstem/api_docs/endpoint.rb +17 -7
- data/lib/brainstem/api_docs/endpoint_collection.rb +9 -1
- data/lib/brainstem/api_docs/formatters/open_api_specification/helper.rb +19 -16
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter.rb +52 -80
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter.rb +64 -84
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_formatter.rb +1 -1
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/endpoint_param_formatter.rb +39 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/presenter_field_formatter.rb +147 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/response_field_formatter.rb +146 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter.rb +53 -55
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter.rb +1 -1
- data/lib/brainstem/api_docs/presenter.rb +16 -8
- data/lib/brainstem/api_docs/presenter_collection.rb +8 -5
- data/lib/brainstem/api_docs/sinks/open_api_specification_sink.rb +3 -1
- data/lib/brainstem/cli/generate_api_docs_command.rb +4 -0
- data/lib/brainstem/concerns/controller_dsl.rb +90 -20
- data/lib/brainstem/concerns/presenter_dsl.rb +16 -8
- data/lib/brainstem/dsl/association.rb +12 -0
- data/lib/brainstem/dsl/fields_block.rb +1 -1
- data/lib/brainstem/version.rb +1 -1
- data/spec/brainstem/api_docs/controller_spec.rb +127 -5
- data/spec/brainstem/api_docs/endpoint_spec.rb +489 -57
- data/spec/brainstem/api_docs/formatters/open_api_specification/helper_spec.rb +15 -4
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter_spec.rb +112 -66
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter_spec.rb +404 -32
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/endpoint_param_formatter_spec.rb +335 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/presenter_field_formatter_spec.rb +237 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/field_definitions/response_field_formatter_spec.rb +413 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter_spec.rb +116 -4
- data/spec/brainstem/api_docs/presenter_spec.rb +406 -24
- data/spec/brainstem/cli/generate_api_docs_command_spec.rb +8 -0
- data/spec/brainstem/concerns/controller_dsl_spec.rb +606 -45
- data/spec/brainstem/concerns/presenter_dsl_spec.rb +34 -2
- data/spec/brainstem/dsl/association_spec.rb +54 -3
- metadata +11 -2
@@ -119,6 +119,14 @@ module Brainstem
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
+
context "when --include-internal" do
|
123
|
+
let(:args) { %w(--include-internal) }
|
124
|
+
|
125
|
+
it "sets the internal option in the args for atlas" do
|
126
|
+
expect(subject.options[:builder][:args_for_atlas][:include_internal]).to eq true
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
122
130
|
context "when --oas-filename-pattern" do
|
123
131
|
let(:args) { %w(--oas-filename-pattern=blah/{{version}}.{{extension}}) }
|
124
132
|
|
@@ -13,7 +13,15 @@ module Brainstem
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe ".nodoc!" do
|
16
|
-
it "sets the config nodoc to
|
16
|
+
it "sets the config nodoc to passed in description" do
|
17
|
+
subject.brainstem_params do
|
18
|
+
nodoc! "Description for why these are nodoc"
|
19
|
+
end
|
20
|
+
|
21
|
+
expect(subject.configuration[:_default][:nodoc]).to eq "Description for why these are nodoc"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "sets the config nodoc to default value (true)" do
|
17
25
|
subject.brainstem_params do
|
18
26
|
nodoc!
|
19
27
|
end
|
@@ -22,6 +30,24 @@ module Brainstem
|
|
22
30
|
end
|
23
31
|
end
|
24
32
|
|
33
|
+
describe ".internal!" do
|
34
|
+
it "sets the config internal to passed in description" do
|
35
|
+
subject.brainstem_params do
|
36
|
+
internal! "Description for why these are internal docs"
|
37
|
+
end
|
38
|
+
|
39
|
+
expect(subject.configuration[:_default][:internal]).to eq "Description for why these are internal docs"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "sets the config internal to default value (true)" do
|
43
|
+
subject.brainstem_params do
|
44
|
+
internal!
|
45
|
+
end
|
46
|
+
|
47
|
+
expect(subject.configuration[:_default][:internal]).to eq true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
25
51
|
describe ".brainstem_params" do
|
26
52
|
it "evaluates the given block in the class context" do
|
27
53
|
mock(subject).configuration
|
@@ -388,43 +414,6 @@ module Brainstem
|
|
388
414
|
expect(template_key.call).to eq('template')
|
389
415
|
expect(valid_params[template_key][:required]).to be_falsey
|
390
416
|
end
|
391
|
-
|
392
|
-
context "when one of the nested fields is required" do
|
393
|
-
it "sets the required attribute for the parent configuration to true" do
|
394
|
-
subject.brainstem_params do
|
395
|
-
valid :template, :hash do |param|
|
396
|
-
param.valid :id, :integer, required: true
|
397
|
-
param.valid :title, :string
|
398
|
-
end
|
399
|
-
|
400
|
-
model_params :sprocket do |param|
|
401
|
-
param.valid :details, :hash do |nested_param|
|
402
|
-
nested_param.valid :data, :hash do |double_nested_param|
|
403
|
-
double_nested_param.valid :raw_text, :string, required: true
|
404
|
-
end
|
405
|
-
end
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
|
-
valid_params = subject.configuration[:_default][:valid_params]
|
410
|
-
|
411
|
-
template_key = valid_params.keys[0]
|
412
|
-
expect(template_key.call).to eq('template')
|
413
|
-
expect(valid_params[template_key][:required]).to be_truthy
|
414
|
-
|
415
|
-
sprocket_details_key = valid_params.keys[3]
|
416
|
-
expect(sprocket_details_key.call).to eq('details')
|
417
|
-
expect(valid_params[sprocket_details_key][:required]).to be_truthy
|
418
|
-
|
419
|
-
sprocket_details_data_key = valid_params.keys[4]
|
420
|
-
expect(sprocket_details_data_key.call).to eq('data')
|
421
|
-
expect(valid_params[sprocket_details_data_key][:required]).to be_truthy
|
422
|
-
|
423
|
-
sprocket_details_data_raw_text_key = valid_params.keys[5]
|
424
|
-
expect(sprocket_details_data_raw_text_key.call).to eq('raw_text')
|
425
|
-
expect(valid_params[sprocket_details_data_raw_text_key][:required]).to be_truthy
|
426
|
-
end
|
427
|
-
end
|
428
417
|
end
|
429
418
|
|
430
419
|
context "when root is nodoc" do
|
@@ -524,6 +513,171 @@ module Brainstem
|
|
524
513
|
end
|
525
514
|
end
|
526
515
|
end
|
516
|
+
|
517
|
+
context "when the param has a dynamic key" do
|
518
|
+
let(:dynamic_keyword) { described_class::DYNAMIC_KEY.to_s }
|
519
|
+
|
520
|
+
it "sets the dynamic key property" do
|
521
|
+
subject.brainstem_params do
|
522
|
+
valid :id, :integer
|
523
|
+
valid :_dynamic_key, :string, required: true
|
524
|
+
valid :user_id, :integer, dynamic_key: true
|
525
|
+
end
|
526
|
+
|
527
|
+
valid_params = subject.configuration[:_default][:valid_params]
|
528
|
+
expect(valid_params.keys.length).to eq(3)
|
529
|
+
|
530
|
+
id_config_key = valid_params.keys[0]
|
531
|
+
expect(id_config_key.call).to eq('id')
|
532
|
+
id_config = valid_params[id_config_key]
|
533
|
+
expect(id_config[:required]).to be_falsey
|
534
|
+
expect(id_config[:type]).to eq("integer")
|
535
|
+
|
536
|
+
dynamic_string_key = valid_params.keys[1]
|
537
|
+
expect(dynamic_string_key.call).to eq(dynamic_keyword)
|
538
|
+
dynamic_string_config = valid_params[dynamic_string_key]
|
539
|
+
expect(dynamic_string_config[:type]).to eq("string")
|
540
|
+
expect(dynamic_string_config[:required]).to be_truthy
|
541
|
+
expect(dynamic_string_config[:dynamic_key]).to be_truthy
|
542
|
+
|
543
|
+
dynamic_user_id_key = valid_params.keys[2]
|
544
|
+
expect(dynamic_user_id_key.call).to eq('user_id')
|
545
|
+
dynamic_user_id_config = valid_params[dynamic_user_id_key]
|
546
|
+
expect(dynamic_user_id_config[:type]).to eq("integer")
|
547
|
+
expect(dynamic_user_id_config[:dynamic_key]).to be_truthy
|
548
|
+
end
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
describe ".valid_dynamic_param" do
|
553
|
+
let(:dynamic_keyword) { described_class::DYNAMIC_KEY.to_s }
|
554
|
+
|
555
|
+
it "sets the correct configuration" do
|
556
|
+
subject.brainstem_params do
|
557
|
+
valid_dynamic_param :integer,
|
558
|
+
info: "User ID is required",
|
559
|
+
required: true
|
560
|
+
end
|
561
|
+
|
562
|
+
valid_params = subject.configuration[:_default][:valid_params]
|
563
|
+
expect(valid_params.keys.length).to eq(1)
|
564
|
+
expect(valid_params.keys[0]).to be_a(Proc)
|
565
|
+
expect(valid_params.keys[0].call).to eq(dynamic_keyword)
|
566
|
+
|
567
|
+
sprocket_ids_config = valid_params[valid_params.keys[0]]
|
568
|
+
expect(sprocket_ids_config[:info]).to eq "User ID is required"
|
569
|
+
expect(sprocket_ids_config[:required]).to be_truthy
|
570
|
+
expect(sprocket_ids_config[:type]).to eq("integer")
|
571
|
+
expect(sprocket_ids_config[:dynamic_key]).to be_truthy
|
572
|
+
end
|
573
|
+
|
574
|
+
context "when type is hash" do
|
575
|
+
it "adds the nested fields to valid params" do
|
576
|
+
subject.brainstem_params do
|
577
|
+
valid :id, :integer
|
578
|
+
|
579
|
+
valid :info, :hash, required: true do |param|
|
580
|
+
param.valid_dynamic_param :string, required: true
|
581
|
+
|
582
|
+
param.valid :data, :hash do |double_nested_param|
|
583
|
+
double_nested_param.valid_dynamic_param :string
|
584
|
+
end
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
valid_params = subject.configuration[:_default][:valid_params]
|
589
|
+
param_keys = valid_params.keys
|
590
|
+
expect(param_keys.length).to eq(5)
|
591
|
+
|
592
|
+
expect(param_keys[0].call).to eq('id')
|
593
|
+
id_config = valid_params[param_keys[0]]
|
594
|
+
expect(id_config[:root]).to be_nil
|
595
|
+
expect(id_config[:ancestors]).to be_nil
|
596
|
+
|
597
|
+
expect(param_keys[1].call).to eq('info')
|
598
|
+
info_key = param_keys[1]
|
599
|
+
info_config = valid_params[info_key]
|
600
|
+
expect(info_config[:root]).to be_nil
|
601
|
+
expect(info_config[:ancestors]).to be_nil
|
602
|
+
|
603
|
+
expect(param_keys[2].call).to eq(dynamic_keyword)
|
604
|
+
dynamic_info_nested_config = valid_params[param_keys[2]]
|
605
|
+
expect(dynamic_info_nested_config[:root]).to be_nil
|
606
|
+
expect(dynamic_info_nested_config[:ancestors]).to eq([info_key])
|
607
|
+
expect(dynamic_info_nested_config[:dynamic_key]).to be_truthy
|
608
|
+
expect(dynamic_info_nested_config[:required]).to be_truthy
|
609
|
+
|
610
|
+
expect(param_keys[3].call).to eq('data')
|
611
|
+
details_data_key = param_keys[3]
|
612
|
+
details_data_config = valid_params[details_data_key]
|
613
|
+
expect(details_data_config[:root]).to be_nil
|
614
|
+
expect(details_data_config[:ancestors]).to eq([info_key])
|
615
|
+
|
616
|
+
expect(param_keys[4].call).to eq(dynamic_keyword)
|
617
|
+
dynamic_data_nested_config = valid_params[param_keys[4]]
|
618
|
+
expect(dynamic_data_nested_config[:root]).to be_nil
|
619
|
+
expect(dynamic_data_nested_config[:ancestors]).to eq([info_key, details_data_key])
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
context "when type is array" do
|
624
|
+
it "sets the type and sub type appropriately" do
|
625
|
+
subject.brainstem_params do
|
626
|
+
valid :sprocket_ids, :array,
|
627
|
+
required: true,
|
628
|
+
item_type: :string
|
629
|
+
end
|
630
|
+
|
631
|
+
valid_params = subject.configuration[:_default][:valid_params]
|
632
|
+
|
633
|
+
sprocket_ids_key = valid_params.keys[0]
|
634
|
+
expect(sprocket_ids_key.call).to eq('sprocket_ids')
|
635
|
+
|
636
|
+
sprocket_ids_config = valid_params[sprocket_ids_key]
|
637
|
+
expect(sprocket_ids_config[:required]).to be_truthy
|
638
|
+
expect(sprocket_ids_config[:type]).to eq('array')
|
639
|
+
expect(sprocket_ids_config[:item_type]).to eq('string')
|
640
|
+
end
|
641
|
+
|
642
|
+
context "when a block is given" do
|
643
|
+
it "sets the type and sub type appropriately" do
|
644
|
+
subject.brainstem_params do
|
645
|
+
valid :sprocket_tasks, :array, required: true, item_type: 'hash' do |param|
|
646
|
+
param.valid :task_id, :integer, required: true
|
647
|
+
param.valid :task_title, :string
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
valid_params = subject.configuration[:_default][:valid_params]
|
652
|
+
|
653
|
+
sprocket_tasks_key = valid_params.keys[0]
|
654
|
+
expect(sprocket_tasks_key.call).to eq('sprocket_tasks')
|
655
|
+
|
656
|
+
sprocket_tasks_config = valid_params[sprocket_tasks_key]
|
657
|
+
expect(sprocket_tasks_config[:required]).to be_truthy
|
658
|
+
expect(sprocket_tasks_config[:type]).to eq('array')
|
659
|
+
expect(sprocket_tasks_config[:item_type]).to eq('hash')
|
660
|
+
|
661
|
+
task_id_key = valid_params.keys[1]
|
662
|
+
expect(task_id_key.call).to eq('task_id')
|
663
|
+
|
664
|
+
task_id_config = valid_params[task_id_key]
|
665
|
+
expect(task_id_config[:required]).to be_truthy
|
666
|
+
expect(task_id_config[:type]).to eq('integer')
|
667
|
+
expect(task_id_config[:root]).to be_nil
|
668
|
+
expect(task_id_config[:ancestors]).to eq([sprocket_tasks_key])
|
669
|
+
|
670
|
+
task_title_key = valid_params.keys[2]
|
671
|
+
expect(task_title_key.call).to eq('task_title')
|
672
|
+
|
673
|
+
task_title_config = valid_params[task_title_key]
|
674
|
+
expect(task_title_config[:required]).to be_falsey
|
675
|
+
expect(task_title_config[:type]).to eq('string')
|
676
|
+
expect(task_title_config[:root]).to be_nil
|
677
|
+
expect(task_title_config[:ancestors]).to eq([sprocket_tasks_key])
|
678
|
+
end
|
679
|
+
end
|
680
|
+
end
|
527
681
|
end
|
528
682
|
|
529
683
|
describe ".transform" do
|
@@ -721,6 +875,114 @@ module Brainstem
|
|
721
875
|
required: false,
|
722
876
|
}.with_indifferent_access)
|
723
877
|
end
|
878
|
+
|
879
|
+
context "when key is dynamic" do
|
880
|
+
it "sets the custom_response configuration" do
|
881
|
+
subject.brainstem_params do
|
882
|
+
actions :show do
|
883
|
+
response :hash do |response_param|
|
884
|
+
response_param.fields :mk, :hash do |dk|
|
885
|
+
dk.dynamic_key_field :string,
|
886
|
+
info: "I am a dynamic key field I"
|
887
|
+
dk.field :mk_blah, :string,
|
888
|
+
required: true
|
889
|
+
end
|
890
|
+
|
891
|
+
response_param.fields :mk2, :hash do |dk|
|
892
|
+
dk.field :_dynamic_key, :string,
|
893
|
+
required: true,
|
894
|
+
info: "dynamic key field II"
|
895
|
+
end
|
896
|
+
|
897
|
+
response_param.dynamic_key_fields :hash do |dk|
|
898
|
+
dk.field :user_id, :string,
|
899
|
+
dynamic_key: true,
|
900
|
+
info: "dynamic key field with dynamic_key attribute"
|
901
|
+
end
|
902
|
+
end
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
configuration = subject.configuration[:show][:custom_response]
|
907
|
+
expect(configuration).to be_present
|
908
|
+
expect(configuration[:_config]).to eq({
|
909
|
+
type: 'hash',
|
910
|
+
nodoc: false,
|
911
|
+
required: false,
|
912
|
+
}.with_indifferent_access)
|
913
|
+
|
914
|
+
param_keys = configuration.keys
|
915
|
+
expect(param_keys.length).to eq(8)
|
916
|
+
|
917
|
+
mk_key = param_keys[1]
|
918
|
+
expect(mk_key.call).to eq('mk')
|
919
|
+
my_key_config = configuration.to_h[mk_key]
|
920
|
+
expect(my_key_config).to eq({
|
921
|
+
nodoc: false,
|
922
|
+
type: 'hash',
|
923
|
+
required: false,
|
924
|
+
}.with_indifferent_access)
|
925
|
+
|
926
|
+
mk_dynamic_key = param_keys[2]
|
927
|
+
mk_dynamic_config = configuration.to_h[mk_dynamic_key]
|
928
|
+
expect(mk_dynamic_config).to eq({
|
929
|
+
nodoc: false,
|
930
|
+
dynamic_key: true,
|
931
|
+
type: 'string',
|
932
|
+
ancestors: [mk_key],
|
933
|
+
required: false,
|
934
|
+
info: "I am a dynamic key field I"
|
935
|
+
}.with_indifferent_access)
|
936
|
+
|
937
|
+
mk_blah_key = param_keys[3]
|
938
|
+
mk_blah_config = configuration.to_h[mk_blah_key]
|
939
|
+
expect(mk_blah_config).to eq({
|
940
|
+
nodoc: false,
|
941
|
+
type: 'string',
|
942
|
+
ancestors: [mk_key],
|
943
|
+
required: true,
|
944
|
+
}.with_indifferent_access)
|
945
|
+
|
946
|
+
mk2_key = param_keys[4]
|
947
|
+
mk2_config = configuration.to_h[mk2_key]
|
948
|
+
expect(mk2_config).to eq({
|
949
|
+
nodoc: false,
|
950
|
+
type: 'hash',
|
951
|
+
required: false,
|
952
|
+
}.with_indifferent_access)
|
953
|
+
|
954
|
+
mk2_dynamic_key = param_keys[5]
|
955
|
+
mk2_dynamic_config = configuration.to_h[mk2_dynamic_key]
|
956
|
+
expect(mk2_dynamic_config).to eq({
|
957
|
+
nodoc: false,
|
958
|
+
dynamic_key: true,
|
959
|
+
type: 'string',
|
960
|
+
ancestors: [mk2_key],
|
961
|
+
required: true,
|
962
|
+
info: "dynamic key field II",
|
963
|
+
}.with_indifferent_access)
|
964
|
+
|
965
|
+
dynamic_key = param_keys[6]
|
966
|
+
dynamic_config = configuration.to_h[dynamic_key]
|
967
|
+
expect(dynamic_config).to eq({
|
968
|
+
nodoc: false,
|
969
|
+
dynamic_key: true,
|
970
|
+
type: 'hash',
|
971
|
+
required: false,
|
972
|
+
}.with_indifferent_access)
|
973
|
+
|
974
|
+
dynamic_child_key = param_keys[7]
|
975
|
+
dynamic_child_config = configuration.to_h[dynamic_child_key]
|
976
|
+
expect(dynamic_child_config).to eq({
|
977
|
+
nodoc: false,
|
978
|
+
dynamic_key: true,
|
979
|
+
ancestors: [dynamic_key],
|
980
|
+
type: 'string',
|
981
|
+
required: false,
|
982
|
+
info: "dynamic key field with dynamic_key attribute",
|
983
|
+
}.with_indifferent_access)
|
984
|
+
end
|
985
|
+
end
|
724
986
|
end
|
725
987
|
|
726
988
|
context "when block not given" do
|
@@ -740,6 +1002,45 @@ module Brainstem
|
|
740
1002
|
required: false,
|
741
1003
|
}.with_indifferent_access)
|
742
1004
|
end
|
1005
|
+
|
1006
|
+
context "when response is a nested array of strings" do
|
1007
|
+
it "sets the custom_response configuration" do
|
1008
|
+
subject.brainstem_params do
|
1009
|
+
actions :show do
|
1010
|
+
response :array, nested_levels: 2, item_type: :string
|
1011
|
+
end
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
configuration = subject.configuration[:show][:custom_response]
|
1015
|
+
expect(configuration).to be_present
|
1016
|
+
expect(configuration[:_config]).to eq({
|
1017
|
+
type: 'array',
|
1018
|
+
item_type: 'string',
|
1019
|
+
nested_levels: 2,
|
1020
|
+
nodoc: false,
|
1021
|
+
required: false,
|
1022
|
+
}.with_indifferent_access)
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
context "when the nested level is less than 2" do
|
1026
|
+
it "does not return a config with a `nested_levels` key" do
|
1027
|
+
subject.brainstem_params do
|
1028
|
+
actions :show do
|
1029
|
+
response :array, nested_levels: 1, item_type: :string
|
1030
|
+
end
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
configuration = subject.configuration[:show][:custom_response]
|
1034
|
+
expect(configuration).to be_present
|
1035
|
+
expect(configuration[:_config]).to eq({
|
1036
|
+
type: 'array',
|
1037
|
+
item_type: 'string',
|
1038
|
+
nodoc: false,
|
1039
|
+
required: false,
|
1040
|
+
}.with_indifferent_access)
|
1041
|
+
end
|
1042
|
+
end
|
1043
|
+
end
|
743
1044
|
end
|
744
1045
|
end
|
745
1046
|
|
@@ -796,8 +1097,13 @@ module Brainstem
|
|
796
1097
|
subject.brainstem_params do
|
797
1098
|
actions :show do
|
798
1099
|
response :hash do
|
799
|
-
fields :contacts, :array do
|
800
|
-
field :full_name, :string
|
1100
|
+
fields :contacts, :array do |contact|
|
1101
|
+
contact.field :full_name, :string
|
1102
|
+
contact.field :friends, :array, nested_levels: 3, item_type: :string
|
1103
|
+
contact.field :enemies, :array, nested_levels: 1, item_type: :string
|
1104
|
+
contact.fields :frenemies, :array, nested_levels: 2 do |frenemy|
|
1105
|
+
frenemy.field :jim, :string
|
1106
|
+
end
|
801
1107
|
end
|
802
1108
|
end
|
803
1109
|
end
|
@@ -806,20 +1112,63 @@ module Brainstem
|
|
806
1112
|
configuration = subject.configuration[:show][:custom_response]
|
807
1113
|
param_keys = configuration.keys
|
808
1114
|
|
809
|
-
|
810
|
-
expect(
|
1115
|
+
contacts_proc = param_keys[1]
|
1116
|
+
expect(contacts_proc.call).to eq('contacts')
|
1117
|
+
expect(configuration[contacts_proc]).to eq({
|
811
1118
|
type: 'array',
|
812
1119
|
item_type: 'hash',
|
813
1120
|
nodoc: false,
|
814
1121
|
required: false,
|
815
1122
|
}.with_indifferent_access)
|
816
1123
|
|
817
|
-
|
818
|
-
expect(
|
1124
|
+
full_name_proc = param_keys[2]
|
1125
|
+
expect(full_name_proc.call).to eq('full_name')
|
1126
|
+
expect(configuration[full_name_proc]).to eq({
|
819
1127
|
type: 'string',
|
820
1128
|
nodoc: false,
|
821
1129
|
required: false,
|
822
|
-
ancestors: [
|
1130
|
+
ancestors: [contacts_proc]
|
1131
|
+
}.with_indifferent_access)
|
1132
|
+
|
1133
|
+
friends_proc = param_keys[3]
|
1134
|
+
expect(friends_proc.call).to eq('friends')
|
1135
|
+
expect(configuration[friends_proc]).to eq({
|
1136
|
+
type: 'array',
|
1137
|
+
item_type: 'string',
|
1138
|
+
nested_levels: 3,
|
1139
|
+
nodoc: false,
|
1140
|
+
required: false,
|
1141
|
+
ancestors: [contacts_proc]
|
1142
|
+
}.with_indifferent_access)
|
1143
|
+
|
1144
|
+
enemies_proc = param_keys[4]
|
1145
|
+
expect(enemies_proc.call).to eq('enemies')
|
1146
|
+
expect(configuration[enemies_proc]).to eq({
|
1147
|
+
type: 'array',
|
1148
|
+
item_type: 'string',
|
1149
|
+
nodoc: false,
|
1150
|
+
required: false,
|
1151
|
+
ancestors: [contacts_proc]
|
1152
|
+
}.with_indifferent_access)
|
1153
|
+
|
1154
|
+
frenemies_proc = param_keys[5]
|
1155
|
+
expect(frenemies_proc.call).to eq('frenemies')
|
1156
|
+
expect(configuration[frenemies_proc]).to eq({
|
1157
|
+
type: 'array',
|
1158
|
+
nested_levels: 2,
|
1159
|
+
item_type: 'hash',
|
1160
|
+
nodoc: false,
|
1161
|
+
required: false,
|
1162
|
+
ancestors: [contacts_proc]
|
1163
|
+
}.with_indifferent_access)
|
1164
|
+
|
1165
|
+
jim_proc = param_keys[6]
|
1166
|
+
expect(jim_proc.call).to eq('jim')
|
1167
|
+
expect(configuration[jim_proc]).to eq({
|
1168
|
+
type: 'string',
|
1169
|
+
nodoc: false,
|
1170
|
+
required: false,
|
1171
|
+
ancestors: [contacts_proc, frenemies_proc]
|
823
1172
|
}.with_indifferent_access)
|
824
1173
|
end
|
825
1174
|
end
|
@@ -868,6 +1217,119 @@ module Brainstem
|
|
868
1217
|
end
|
869
1218
|
end
|
870
1219
|
|
1220
|
+
describe ".dynamic_key_fields" do
|
1221
|
+
context "when used outside of the response block" do
|
1222
|
+
it "raises an error" do
|
1223
|
+
expect {
|
1224
|
+
subject.brainstem_params do
|
1225
|
+
actions :show do
|
1226
|
+
dynamic_key_fields :array do
|
1227
|
+
field :full_name, :string
|
1228
|
+
end
|
1229
|
+
end
|
1230
|
+
end
|
1231
|
+
}.to raise_error(StandardError)
|
1232
|
+
end
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
context "when used within the response block" do
|
1236
|
+
let(:dynamic_keyword) { described_class::DYNAMIC_KEY.to_s }
|
1237
|
+
|
1238
|
+
context "when type is hash" do
|
1239
|
+
it "adds the field block to custom_response configuration" do
|
1240
|
+
subject.brainstem_params do
|
1241
|
+
actions :show do
|
1242
|
+
response :hash do
|
1243
|
+
dynamic_key_fields :hash do
|
1244
|
+
field :full_name, :string
|
1245
|
+
end
|
1246
|
+
end
|
1247
|
+
end
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
configuration = subject.configuration[:show][:custom_response]
|
1251
|
+
param_keys = configuration.keys
|
1252
|
+
|
1253
|
+
expect(param_keys[1].call).to eq(dynamic_keyword)
|
1254
|
+
expect(configuration[param_keys[1]]).to eq({
|
1255
|
+
type: 'hash',
|
1256
|
+
nodoc: false,
|
1257
|
+
required: false,
|
1258
|
+
dynamic_key: true,
|
1259
|
+
}.with_indifferent_access)
|
1260
|
+
|
1261
|
+
expect(param_keys[2].call).to eq('full_name')
|
1262
|
+
expect(configuration[param_keys[2]]).to eq({
|
1263
|
+
type: 'string',
|
1264
|
+
nodoc: false,
|
1265
|
+
ancestors: [param_keys[1]],
|
1266
|
+
required: false,
|
1267
|
+
}.with_indifferent_access)
|
1268
|
+
end
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
context "when type is array" do
|
1272
|
+
it "adds the field block to custom_response configuration" do
|
1273
|
+
subject.brainstem_params do
|
1274
|
+
actions :show do
|
1275
|
+
response :hash do
|
1276
|
+
dynamic_key_fields :array do |contact|
|
1277
|
+
contact.field :full_name, :string
|
1278
|
+
contact.dynamic_key_fields :array, nested_levels: 2 do |frenemy|
|
1279
|
+
frenemy.field :jim, :string
|
1280
|
+
end
|
1281
|
+
end
|
1282
|
+
end
|
1283
|
+
end
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
configuration = subject.configuration[:show][:custom_response]
|
1287
|
+
param_keys = configuration.keys
|
1288
|
+
|
1289
|
+
dynamic_parent_proc = param_keys[1]
|
1290
|
+
expect(dynamic_parent_proc.call).to eq(dynamic_keyword)
|
1291
|
+
expect(configuration[dynamic_parent_proc]).to eq({
|
1292
|
+
type: 'array',
|
1293
|
+
item_type: 'hash',
|
1294
|
+
nodoc: false,
|
1295
|
+
required: false,
|
1296
|
+
dynamic_key: true,
|
1297
|
+
}.with_indifferent_access)
|
1298
|
+
|
1299
|
+
full_name_proc = param_keys[2]
|
1300
|
+
expect(full_name_proc.call).to eq('full_name')
|
1301
|
+
expect(configuration[full_name_proc]).to eq({
|
1302
|
+
type: 'string',
|
1303
|
+
nodoc: false,
|
1304
|
+
required: false,
|
1305
|
+
ancestors: [dynamic_parent_proc]
|
1306
|
+
}.with_indifferent_access)
|
1307
|
+
|
1308
|
+
dynamic_nested_proc = param_keys[3]
|
1309
|
+
expect(dynamic_nested_proc.call).to eq(dynamic_keyword)
|
1310
|
+
expect(configuration[dynamic_nested_proc]).to eq({
|
1311
|
+
type: 'array',
|
1312
|
+
nested_levels: 2,
|
1313
|
+
item_type: 'hash',
|
1314
|
+
nodoc: false,
|
1315
|
+
required: false,
|
1316
|
+
ancestors: [dynamic_parent_proc],
|
1317
|
+
dynamic_key: true,
|
1318
|
+
}.with_indifferent_access)
|
1319
|
+
|
1320
|
+
jim_proc = param_keys[4]
|
1321
|
+
expect(jim_proc.call).to eq('jim')
|
1322
|
+
expect(configuration[jim_proc]).to eq({
|
1323
|
+
type: 'string',
|
1324
|
+
nodoc: false,
|
1325
|
+
required: false,
|
1326
|
+
ancestors: [dynamic_parent_proc, dynamic_nested_proc]
|
1327
|
+
}.with_indifferent_access)
|
1328
|
+
end
|
1329
|
+
end
|
1330
|
+
end
|
1331
|
+
end
|
1332
|
+
|
871
1333
|
describe ".field" do
|
872
1334
|
context "when used outside of the response block" do
|
873
1335
|
it "raises an error" do
|
@@ -961,6 +1423,105 @@ module Brainstem
|
|
961
1423
|
end
|
962
1424
|
end
|
963
1425
|
|
1426
|
+
describe ".dynamic_key_field" do
|
1427
|
+
let(:dynamic_keyword) { described_class::DYNAMIC_KEY.to_s }
|
1428
|
+
|
1429
|
+
context "when used outside of the response block" do
|
1430
|
+
it "raises an error" do
|
1431
|
+
expect {
|
1432
|
+
subject.brainstem_params do
|
1433
|
+
actions :show do
|
1434
|
+
dynamic_key_field :string
|
1435
|
+
end
|
1436
|
+
end
|
1437
|
+
}.to raise_error(StandardError)
|
1438
|
+
end
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
context "when used within the response block" do
|
1442
|
+
context "when type is array" do
|
1443
|
+
it "adds the field block to custom_response configuration" do
|
1444
|
+
subject.brainstem_params do
|
1445
|
+
actions :show do
|
1446
|
+
response :hash do
|
1447
|
+
dynamic_key_field :array
|
1448
|
+
end
|
1449
|
+
end
|
1450
|
+
end
|
1451
|
+
|
1452
|
+
configuration = subject.configuration[:show][:custom_response]
|
1453
|
+
param_keys = configuration.keys
|
1454
|
+
|
1455
|
+
expect(param_keys[1].call).to eq(dynamic_keyword)
|
1456
|
+
expect(configuration[param_keys[1]]).to eq({
|
1457
|
+
type: 'array',
|
1458
|
+
item_type: 'string',
|
1459
|
+
nodoc: false,
|
1460
|
+
required: false,
|
1461
|
+
dynamic_key: true
|
1462
|
+
}.with_indifferent_access)
|
1463
|
+
end
|
1464
|
+
end
|
1465
|
+
|
1466
|
+
context "when type is not array" do
|
1467
|
+
it "adds the field block to custom_response configuration" do
|
1468
|
+
subject.brainstem_params do
|
1469
|
+
actions :show do
|
1470
|
+
response :hash do
|
1471
|
+
dynamic_key_field :string
|
1472
|
+
end
|
1473
|
+
end
|
1474
|
+
end
|
1475
|
+
|
1476
|
+
configuration = subject.configuration[:show][:custom_response]
|
1477
|
+
param_keys = configuration.keys
|
1478
|
+
|
1479
|
+
expect(param_keys[1].call).to eq(dynamic_keyword)
|
1480
|
+
expect(configuration[param_keys[1]]).to eq({
|
1481
|
+
type: 'string',
|
1482
|
+
nodoc: false,
|
1483
|
+
required: false,
|
1484
|
+
dynamic_key: true,
|
1485
|
+
}.with_indifferent_access)
|
1486
|
+
end
|
1487
|
+
end
|
1488
|
+
|
1489
|
+
context "when nested under parent field" do
|
1490
|
+
it "inherits the nodoc attribute" do
|
1491
|
+
subject.brainstem_params do
|
1492
|
+
actions :show do
|
1493
|
+
response :hash do
|
1494
|
+
dynamic_key_fields :hash, nodoc: true do
|
1495
|
+
dynamic_key_field :string
|
1496
|
+
end
|
1497
|
+
end
|
1498
|
+
end
|
1499
|
+
end
|
1500
|
+
|
1501
|
+
configuration = subject.configuration[:show][:custom_response]
|
1502
|
+
param_keys = configuration.keys
|
1503
|
+
|
1504
|
+
expect(param_keys[1].call).to eq(dynamic_keyword)
|
1505
|
+
expect(configuration[param_keys[1]]).to eq({
|
1506
|
+
type: 'hash',
|
1507
|
+
nodoc: true,
|
1508
|
+
required: false,
|
1509
|
+
dynamic_key: true,
|
1510
|
+
}.with_indifferent_access)
|
1511
|
+
|
1512
|
+
expect(param_keys[2].call).to eq(dynamic_keyword)
|
1513
|
+
expect(configuration[param_keys[2]]).to eq({
|
1514
|
+
type: 'string',
|
1515
|
+
nodoc: true,
|
1516
|
+
required: false,
|
1517
|
+
dynamic_key: true,
|
1518
|
+
ancestors: [param_keys[1]]
|
1519
|
+
}.with_indifferent_access)
|
1520
|
+
end
|
1521
|
+
end
|
1522
|
+
end
|
1523
|
+
end
|
1524
|
+
|
964
1525
|
describe ".operation_id" do
|
965
1526
|
it "sets the operation_id for the context" do
|
966
1527
|
subject.brainstem_params do
|