brainstem 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|