brainstem 1.0.0.pre.1 → 1.0.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 +12 -0
- data/Gemfile.lock +1 -1
- data/README.md +383 -32
- data/bin/brainstem +6 -0
- data/brainstem.gemspec +2 -0
- data/docs/api_doc_generator.markdown +175 -0
- data/docs/brainstem_executable.markdown +32 -0
- data/docs/docgen.png +0 -0
- data/docs/docgen_ascii.txt +63 -0
- data/docs/executable.png +0 -0
- data/docs/executable_ascii.txt +10 -0
- data/lib/brainstem/api_docs.rb +146 -0
- data/lib/brainstem/api_docs/abstract_collection.rb +116 -0
- data/lib/brainstem/api_docs/atlas.rb +158 -0
- data/lib/brainstem/api_docs/builder.rb +167 -0
- data/lib/brainstem/api_docs/controller.rb +122 -0
- data/lib/brainstem/api_docs/controller_collection.rb +40 -0
- data/lib/brainstem/api_docs/endpoint.rb +234 -0
- data/lib/brainstem/api_docs/endpoint_collection.rb +58 -0
- data/lib/brainstem/api_docs/exceptions.rb +8 -0
- data/lib/brainstem/api_docs/formatters/abstract_formatter.rb +64 -0
- data/lib/brainstem/api_docs/formatters/markdown/controller_formatter.rb +76 -0
- data/lib/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter.rb +73 -0
- data/lib/brainstem/api_docs/formatters/markdown/endpoint_formatter.rb +169 -0
- data/lib/brainstem/api_docs/formatters/markdown/helper.rb +76 -0
- data/lib/brainstem/api_docs/formatters/markdown/presenter_formatter.rb +200 -0
- data/lib/brainstem/api_docs/introspectors/abstract_introspector.rb +100 -0
- data/lib/brainstem/api_docs/introspectors/rails_introspector.rb +232 -0
- data/lib/brainstem/api_docs/presenter.rb +225 -0
- data/lib/brainstem/api_docs/presenter_collection.rb +97 -0
- data/lib/brainstem/api_docs/resolver.rb +73 -0
- data/lib/brainstem/api_docs/sinks/abstract_sink.rb +37 -0
- data/lib/brainstem/api_docs/sinks/controller_presenter_multifile_sink.rb +93 -0
- data/lib/brainstem/api_docs/sinks/stdout_sink.rb +44 -0
- data/lib/brainstem/cli.rb +146 -0
- data/lib/brainstem/cli/abstract_command.rb +97 -0
- data/lib/brainstem/cli/generate_api_docs_command.rb +169 -0
- data/lib/brainstem/concerns/controller_dsl.rb +300 -0
- data/lib/brainstem/concerns/controller_param_management.rb +30 -9
- data/lib/brainstem/concerns/formattable.rb +38 -0
- data/lib/brainstem/concerns/inheritable_configuration.rb +3 -2
- data/lib/brainstem/concerns/optional.rb +43 -0
- data/lib/brainstem/concerns/presenter_dsl.rb +76 -15
- data/lib/brainstem/controller_methods.rb +6 -3
- data/lib/brainstem/dsl/association.rb +6 -3
- data/lib/brainstem/dsl/associations_block.rb +6 -3
- data/lib/brainstem/dsl/base_block.rb +2 -4
- data/lib/brainstem/dsl/conditional.rb +7 -3
- data/lib/brainstem/dsl/conditionals_block.rb +4 -4
- data/lib/brainstem/dsl/configuration.rb +184 -8
- data/lib/brainstem/dsl/field.rb +6 -3
- data/lib/brainstem/dsl/fields_block.rb +2 -3
- data/lib/brainstem/help_text.txt +8 -0
- data/lib/brainstem/presenter.rb +27 -6
- data/lib/brainstem/presenter_validator.rb +5 -2
- data/lib/brainstem/time_classes.rb +1 -1
- data/lib/brainstem/version.rb +1 -1
- data/spec/brainstem/api_docs/abstract_collection_spec.rb +156 -0
- data/spec/brainstem/api_docs/atlas_spec.rb +353 -0
- data/spec/brainstem/api_docs/builder_spec.rb +100 -0
- data/spec/brainstem/api_docs/controller_collection_spec.rb +92 -0
- data/spec/brainstem/api_docs/controller_spec.rb +225 -0
- data/spec/brainstem/api_docs/endpoint_collection_spec.rb +144 -0
- data/spec/brainstem/api_docs/endpoint_spec.rb +346 -0
- data/spec/brainstem/api_docs/formatters/abstract_formatter_spec.rb +30 -0
- data/spec/brainstem/api_docs/formatters/markdown/controller_formatter_spec.rb +126 -0
- data/spec/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter_spec.rb +85 -0
- data/spec/brainstem/api_docs/formatters/markdown/endpoint_formatter_spec.rb +261 -0
- data/spec/brainstem/api_docs/formatters/markdown/helper_spec.rb +100 -0
- data/spec/brainstem/api_docs/formatters/markdown/presenter_formatter_spec.rb +485 -0
- data/spec/brainstem/api_docs/introspectors/abstract_introspector_spec.rb +192 -0
- data/spec/brainstem/api_docs/introspectors/rails_introspector_spec.rb +170 -0
- data/spec/brainstem/api_docs/presenter_collection_spec.rb +84 -0
- data/spec/brainstem/api_docs/presenter_spec.rb +519 -0
- data/spec/brainstem/api_docs/resolver_spec.rb +72 -0
- data/spec/brainstem/api_docs/sinks/abstract_sink_spec.rb +16 -0
- data/spec/brainstem/api_docs/sinks/controller_presenter_multifile_sink_spec.rb +56 -0
- data/spec/brainstem/api_docs/sinks/stdout_sink_spec.rb +22 -0
- data/spec/brainstem/api_docs_spec.rb +58 -0
- data/spec/brainstem/cli/abstract_command_spec.rb +91 -0
- data/spec/brainstem/cli/generate_api_docs_command_spec.rb +125 -0
- data/spec/brainstem/cli_spec.rb +67 -0
- data/spec/brainstem/concerns/controller_dsl_spec.rb +471 -0
- data/spec/brainstem/concerns/controller_param_management_spec.rb +36 -16
- data/spec/brainstem/concerns/formattable_spec.rb +30 -0
- data/spec/brainstem/concerns/inheritable_configuration_spec.rb +104 -4
- data/spec/brainstem/concerns/optional_spec.rb +48 -0
- data/spec/brainstem/concerns/presenter_dsl_spec.rb +202 -31
- data/spec/brainstem/dsl/association_spec.rb +18 -2
- data/spec/brainstem/dsl/conditional_spec.rb +25 -2
- data/spec/brainstem/dsl/configuration_spec.rb +1 -1
- data/spec/brainstem/dsl/field_spec.rb +18 -2
- data/spec/brainstem/presenter_collection_spec.rb +10 -2
- data/spec/brainstem/presenter_spec.rb +32 -0
- data/spec/brainstem/presenter_validator_spec.rb +12 -7
- data/spec/dummy/rails.rb +49 -0
- data/spec/shared/atlas_taker.rb +18 -0
- data/spec/shared/formattable.rb +14 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/spec_helpers/db.rb +1 -1
- data/spec/spec_helpers/presenters.rb +20 -14
- metadata +106 -6
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'brainstem/api_docs/builder'
|
3
|
+
|
4
|
+
module Brainstem
|
5
|
+
module ApiDocs
|
6
|
+
describe Builder do
|
7
|
+
let(:dummy_environment_file) do
|
8
|
+
File.expand_path('../../../../spec/dummy/rails.rb', __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:default_options) do
|
12
|
+
{ args_for_introspector: { rails_environment_file: dummy_environment_file } }
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:options) { {} }
|
16
|
+
|
17
|
+
subject { Builder.new(default_options.merge(options)) }
|
18
|
+
|
19
|
+
|
20
|
+
describe "#initialize" do
|
21
|
+
let(:introspector_method) { Object.new }
|
22
|
+
let(:options) { { introspector_method: introspector_method } }
|
23
|
+
|
24
|
+
before do
|
25
|
+
any_instance_of(Builder) do |instance|
|
26
|
+
stub(instance) do |k|
|
27
|
+
k.build_introspector!
|
28
|
+
k.build_atlas!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sets all valid values given to it as options" do
|
34
|
+
expect(subject.introspector_method).to eq introspector_method
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
describe "introspection" do
|
40
|
+
let(:introspector_method) { Object.new }
|
41
|
+
let(:args_for_introspector) { { blah: true } }
|
42
|
+
let(:introspector) { Object.new }
|
43
|
+
let(:options) do
|
44
|
+
{
|
45
|
+
args_for_introspector: args_for_introspector,
|
46
|
+
introspector_method: introspector_method
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
before do
|
51
|
+
any_instance_of(Builder) do |instance|
|
52
|
+
stub(instance) do |k|
|
53
|
+
k.build_atlas!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
it "passes the introspector method the introspector options" do
|
60
|
+
mock(introspector_method).call(args_for_introspector)
|
61
|
+
subject
|
62
|
+
end
|
63
|
+
|
64
|
+
it "creates an introspector" do
|
65
|
+
stub(introspector_method).call(args_for_introspector) { introspector }
|
66
|
+
expect(subject.introspector).to eq introspector
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
describe "modeling" do
|
72
|
+
let(:introspector) { Object.new }
|
73
|
+
let(:atlas_method) { Object.new }
|
74
|
+
let(:args_for_atlas) { { blah: true } }
|
75
|
+
let(:atlas) { Object.new }
|
76
|
+
let(:options) { { atlas_method: atlas_method, args_for_atlas: args_for_atlas } }
|
77
|
+
|
78
|
+
before do
|
79
|
+
any_instance_of(Builder) do |instance|
|
80
|
+
stub(instance) do |inst|
|
81
|
+
inst.introspector { introspector }
|
82
|
+
inst.build_introspector!
|
83
|
+
inst.build_formatter!
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it "passes the atlas method the introspector and the atlas options" do
|
89
|
+
mock(atlas_method).call(introspector, args_for_atlas)
|
90
|
+
subject
|
91
|
+
end
|
92
|
+
|
93
|
+
it "creates an atlas" do
|
94
|
+
mock(atlas_method).call(introspector, args_for_atlas) { atlas }
|
95
|
+
expect(subject.atlas).to eq atlas
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'brainstem/api_docs/controller_collection'
|
3
|
+
|
4
|
+
module Brainstem
|
5
|
+
module ApiDocs
|
6
|
+
describe ControllerCollection do
|
7
|
+
let(:controller) { Object.new }
|
8
|
+
let(:atlas) { Object.new }
|
9
|
+
let(:options) { {} }
|
10
|
+
|
11
|
+
subject { described_class.new(atlas, options) }
|
12
|
+
|
13
|
+
describe "#find_by_route" do
|
14
|
+
before do
|
15
|
+
stub(controller) do |c|
|
16
|
+
c.path { "/posts" }
|
17
|
+
c.const { Object }
|
18
|
+
c.action { "index" }
|
19
|
+
end
|
20
|
+
|
21
|
+
subject << controller
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when matches route" do
|
25
|
+
it "returns the matching controller" do
|
26
|
+
route = { controller: Object }
|
27
|
+
expect(subject.find_by_route(route)).to eq controller
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when does not match route" do
|
32
|
+
it "returns nil" do
|
33
|
+
route = { controller: TrueClass }
|
34
|
+
expect(subject.find_by_route(route)).to eq nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
describe "#create_from_route" do
|
41
|
+
it "creates a new controller, adding it to the members" do
|
42
|
+
controller = subject.create_from_route(
|
43
|
+
path: "/posts",
|
44
|
+
controller: Object,
|
45
|
+
action: "index",
|
46
|
+
controller_name: "object"
|
47
|
+
)
|
48
|
+
|
49
|
+
expect(subject.first).to eq controller
|
50
|
+
expect(controller.const).to eq Object
|
51
|
+
expect(controller.name).to eq "object"
|
52
|
+
expect(controller.endpoints).to \
|
53
|
+
be_a Brainstem::ApiDocs::EndpointCollection
|
54
|
+
expect(controller.endpoints.count).to eq 0
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
describe "#find_or_create_from_route" do
|
60
|
+
let!(:existing_controller) { subject.create_from_route(
|
61
|
+
path: "/posts",
|
62
|
+
controller: Object,
|
63
|
+
action: "index",
|
64
|
+
controller_name: "object"
|
65
|
+
) }
|
66
|
+
|
67
|
+
context "when has matching controller" do
|
68
|
+
let(:route) { { controller: Object, controller_name: "object" } }
|
69
|
+
|
70
|
+
it "returns that controller" do
|
71
|
+
subject.find_or_create_from_route(route)
|
72
|
+
expect(subject.count).to eq 1
|
73
|
+
expect(subject.last).to eq existing_controller
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when no matching controller" do
|
78
|
+
let(:route) { { controller: TrueClass, controller_name: "true_class" } }
|
79
|
+
|
80
|
+
it "returns a new controller" do
|
81
|
+
new_controller = subject.find_or_create_from_route(route)
|
82
|
+
expect(subject.count).to eq 2
|
83
|
+
expect(subject.last).to eq new_controller
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it_behaves_like "formattable"
|
89
|
+
it_behaves_like "atlas taker"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'brainstem/api_docs/controller'
|
3
|
+
|
4
|
+
module Brainstem
|
5
|
+
module ApiDocs
|
6
|
+
describe Controller do
|
7
|
+
subject { described_class.new(atlas, options) }
|
8
|
+
let(:atlas) { Object.new }
|
9
|
+
let(:options) { {} }
|
10
|
+
|
11
|
+
describe "#initialize" do
|
12
|
+
it "yields self if given a block" do
|
13
|
+
block = Proc.new { |s| s.name = "bork bork" }
|
14
|
+
expect(described_class.new(atlas, &block).name).to eq "bork bork"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
describe "#add_endpoint" do
|
20
|
+
let(:endpoint) { Object.new }
|
21
|
+
|
22
|
+
it "adds the endpoint to its list" do
|
23
|
+
expect(subject.endpoints.count).to eq 0
|
24
|
+
subject.add_endpoint(endpoint)
|
25
|
+
expect(subject.endpoints.count).to eq 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe "derived fields" do
|
31
|
+
let(:lorem) { "lorem ipsum dolor sit amet" }
|
32
|
+
let(:const) { Object.new }
|
33
|
+
let(:default_config) { {} }
|
34
|
+
let(:show_config) { {} }
|
35
|
+
let(:nodoc) { false }
|
36
|
+
let(:options) { { const: const } }
|
37
|
+
|
38
|
+
before do
|
39
|
+
stub(const) do |constant|
|
40
|
+
constant.configuration { {
|
41
|
+
:_default => default_config,
|
42
|
+
:show => show_config
|
43
|
+
} }
|
44
|
+
|
45
|
+
constant.to_s { "Api::V1::ClassName" }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
describe "configuration helpers" do
|
51
|
+
describe "#contextual_documentation" do
|
52
|
+
let(:default_config) { { title: { info: info, nodoc: nodoc } } }
|
53
|
+
let(:info) { lorem }
|
54
|
+
|
55
|
+
context "when has the key" do
|
56
|
+
let(:key) { :title }
|
57
|
+
|
58
|
+
context "when not nodoc" do
|
59
|
+
context "when has info" do
|
60
|
+
it "is truthy" do
|
61
|
+
expect(subject.contextual_documentation(key)).to be_truthy
|
62
|
+
end
|
63
|
+
|
64
|
+
it "is the info" do
|
65
|
+
expect(subject.contextual_documentation(key)).to eq lorem
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when has no info" do
|
70
|
+
let(:info) { nil }
|
71
|
+
|
72
|
+
it "is falsey" do
|
73
|
+
expect(subject.contextual_documentation(key)).to be_falsey
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when nodoc" do
|
79
|
+
let(:nodoc) { true }
|
80
|
+
|
81
|
+
it "is falsey" do
|
82
|
+
expect(subject.contextual_documentation(key)).to be_falsey
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "when doesn't have the key" do
|
88
|
+
let(:key) { :herp }
|
89
|
+
|
90
|
+
it "is falsey" do
|
91
|
+
expect(subject.contextual_documentation(key)).to be_falsey
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
describe "#default_configuration" do
|
98
|
+
let(:default_config) { { title: nil } }
|
99
|
+
|
100
|
+
it "returns the default key of the configuration" do
|
101
|
+
expect(subject.default_configuration).to eq default_config
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
describe "#nodoc?" do
|
108
|
+
let(:default_config) { { nodoc: nodoc } }
|
109
|
+
|
110
|
+
context "when nodoc in default" do
|
111
|
+
let(:nodoc) { true }
|
112
|
+
|
113
|
+
it "is true" do
|
114
|
+
expect(subject.nodoc?).to eq true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when not nodoc in default" do
|
119
|
+
it "is false" do
|
120
|
+
expect(subject.nodoc?).to eq false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
describe "#title" do
|
127
|
+
context "when present" do
|
128
|
+
let(:default_config) { { title: { info: lorem, nodoc: nodoc } } }
|
129
|
+
|
130
|
+
context "when nodoc" do
|
131
|
+
let(:nodoc) { true }
|
132
|
+
|
133
|
+
it "falls back to the controller class" do
|
134
|
+
expect(subject.title).to eq "ClassName"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context "when documentable" do
|
139
|
+
it "shows the title" do
|
140
|
+
expect(subject.title).to eq lorem
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "when absent" do
|
146
|
+
it "falls back to the controller class" do
|
147
|
+
expect(subject.title).to eq "ClassName"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
describe "#description" do
|
154
|
+
context "when present" do
|
155
|
+
let(:default_config) { { description: { info: lorem, nodoc: nodoc } } }
|
156
|
+
|
157
|
+
context "when nodoc" do
|
158
|
+
let(:nodoc) { true }
|
159
|
+
|
160
|
+
it "shows nothing" do
|
161
|
+
expect(subject.description).to eq ""
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "when documentable" do
|
166
|
+
it "shows the description" do
|
167
|
+
expect(subject.description).to eq lorem
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "when absent" do
|
173
|
+
it "shows nothing" do
|
174
|
+
expect(subject.description).to eq ""
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
describe "#suggested_filename" do
|
182
|
+
let(:const) { Object.new }
|
183
|
+
|
184
|
+
before do
|
185
|
+
stub(const) do |constant|
|
186
|
+
constant.to_s { "Api::V1::ClassName" }
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
it "gsubs namespace, filename and extension" do
|
192
|
+
instance = described_class.new(atlas,
|
193
|
+
filename_pattern: "controllers/{{namespace}}/{{name}}_controller.{{extension}}",
|
194
|
+
name: 'api/v1/abc',
|
195
|
+
const: const,
|
196
|
+
)
|
197
|
+
|
198
|
+
stub(instance).extension { "xyz" }
|
199
|
+
|
200
|
+
expect(instance.suggested_filename(:xyz)).to \
|
201
|
+
eq "controllers/api/v1/abc_controller.xyz"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
describe "#suggested_filename_link" do
|
207
|
+
it "gsubs filename and extension" do
|
208
|
+
|
209
|
+
instance = described_class.new(atlas,
|
210
|
+
filename_link_pattern: "controllers/{{name}}_controller.{{extension}}.foo",
|
211
|
+
name: 'abc'
|
212
|
+
)
|
213
|
+
|
214
|
+
stub(instance).extension { "xyz" }
|
215
|
+
|
216
|
+
expect(instance.suggested_filename_link(:xyz)).to eq "controllers/abc_controller.xyz.foo"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
it_behaves_like "formattable"
|
222
|
+
it_behaves_like "atlas taker"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'brainstem/api_docs/endpoint_collection'
|
3
|
+
|
4
|
+
module Brainstem
|
5
|
+
module ApiDocs
|
6
|
+
describe EndpointCollection do
|
7
|
+
let(:atlas) { Object.new }
|
8
|
+
let(:options) { {} }
|
9
|
+
let(:endpoint) { Object.new }
|
10
|
+
|
11
|
+
subject { described_class.new(atlas, options) }
|
12
|
+
|
13
|
+
|
14
|
+
describe "#find_from_route" do
|
15
|
+
let(:controller) { stub!.const { Object }.subject }
|
16
|
+
|
17
|
+
before do
|
18
|
+
stub(endpoint) do |c|
|
19
|
+
c.path { "/posts" }
|
20
|
+
c.http_methods { ["GET", "POST"] }
|
21
|
+
c.controller { controller }
|
22
|
+
c.controller_name { "object" }
|
23
|
+
c.action { "index" }
|
24
|
+
end
|
25
|
+
|
26
|
+
subject << endpoint
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when matches route" do
|
30
|
+
it "returns the matching controller" do
|
31
|
+
route = { controller: Object, path: "/posts", action: "index" }
|
32
|
+
expect(subject.find_by_route(route)).to eq endpoint
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when does not match route" do
|
37
|
+
it "returns nil" do
|
38
|
+
routes = [
|
39
|
+
{ controller: TrueClass, path: "/posts", action: "index" },
|
40
|
+
{ controller: Object, path: "/wrong", action: "index" },
|
41
|
+
{ controller: Object, path: "/posts", action: "wrong" },
|
42
|
+
]
|
43
|
+
|
44
|
+
routes.each do |route|
|
45
|
+
expect(subject.find_by_route(route)).to eq nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
describe "#create_from_route" do
|
53
|
+
it "creates a new endpoint, adding it to the members" do
|
54
|
+
controller = Object.new
|
55
|
+
|
56
|
+
endpoint = subject.create_from_route({
|
57
|
+
path: "/posts",
|
58
|
+
http_methods: ["GET"],
|
59
|
+
controller_name: "object",
|
60
|
+
action: "index",
|
61
|
+
}, controller)
|
62
|
+
|
63
|
+
expect(subject.first).to eq endpoint
|
64
|
+
expect(endpoint.controller).to eq controller
|
65
|
+
expect(endpoint.controller_name).to eq "object"
|
66
|
+
expect(endpoint.action).to eq "index"
|
67
|
+
expect(endpoint.path).to eq "/posts"
|
68
|
+
expect(endpoint.http_methods).to eq ["GET"]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
describe "#only_documentable" do
|
74
|
+
let(:endpoint_2) { Object.new }
|
75
|
+
|
76
|
+
before do
|
77
|
+
stub(endpoint).nodoc? { false }
|
78
|
+
stub(endpoint_2).nodoc? { true }
|
79
|
+
|
80
|
+
subject << endpoint
|
81
|
+
subject << endpoint_2
|
82
|
+
end
|
83
|
+
|
84
|
+
it "returns a new collection with members that are not nodoc" do
|
85
|
+
new_clxn = subject.only_documentable
|
86
|
+
|
87
|
+
expect(new_clxn).to be_a described_class
|
88
|
+
expect(new_clxn).to include endpoint
|
89
|
+
expect(new_clxn).not_to include endpoint_2
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
describe "#with_declared_presented_class" do
|
95
|
+
let(:endpoint_2) { Object.new }
|
96
|
+
|
97
|
+
before do
|
98
|
+
stub(endpoint).declared_presented_class { Class.new }
|
99
|
+
stub(endpoint_2).declared_presented_class { nil }
|
100
|
+
subject << endpoint
|
101
|
+
subject << endpoint_2
|
102
|
+
end
|
103
|
+
|
104
|
+
it "returns a new collection with members that have declared presents" do
|
105
|
+
new_clxn = subject.with_declared_presented_class
|
106
|
+
|
107
|
+
expect(new_clxn).to be_a described_class
|
108
|
+
expect(new_clxn).to include endpoint
|
109
|
+
expect(new_clxn).not_to include endpoint_2
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
describe "#with_actions_in_controller" do
|
115
|
+
let(:endpoint_2) { Object.new }
|
116
|
+
let(:const) do
|
117
|
+
Class.new do
|
118
|
+
def show
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
before do
|
124
|
+
stub(endpoint).action { :show }
|
125
|
+
stub(endpoint_2).action { :index }
|
126
|
+
subject << endpoint
|
127
|
+
subject << endpoint_2
|
128
|
+
end
|
129
|
+
|
130
|
+
it "returns a new collection with members that the const responds to" do
|
131
|
+
new_clxn = subject.with_actions_in_controller(const)
|
132
|
+
|
133
|
+
expect(new_clxn).to be_a described_class
|
134
|
+
expect(new_clxn).to include endpoint
|
135
|
+
expect(new_clxn).not_to include endpoint_2
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
it_behaves_like "formattable"
|
141
|
+
it_behaves_like "atlas taker"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|