azeroth 1.0.0 → 2.0.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/.circleci/config.yml +3 -3
- data/.rubocop.yml +15 -1
- data/Dockerfile +2 -2
- data/Gemfile +30 -0
- data/Makefile +6 -0
- data/README.md +13 -1
- data/azeroth.gemspec +6 -36
- data/config/check_specs.yml +1 -0
- data/lib/azeroth/controller_interface.rb +3 -2
- data/lib/azeroth/decorator/class_methods.rb +249 -0
- data/lib/azeroth/decorator/hash_builder.rb +1 -0
- data/lib/azeroth/decorator/method_builder.rb +23 -7
- data/lib/azeroth/decorator/options.rb +3 -1
- data/lib/azeroth/decorator.rb +35 -192
- data/lib/azeroth/model.rb +1 -0
- data/lib/azeroth/request_handler/index.rb +7 -33
- data/lib/azeroth/request_handler/pagination.rb +53 -0
- data/lib/azeroth/request_handler.rb +11 -9
- data/lib/azeroth/resourceable/builder.rb +3 -2
- data/lib/azeroth/version.rb +1 -1
- data/spec/dummy/app/models/website/decorator.rb +11 -0
- data/spec/dummy/app/models/website/with_location.rb +21 -0
- data/spec/dummy/app/models/website.rb +4 -0
- data/spec/dummy/config/environments/production.rb +2 -2
- data/spec/dummy/config/puma.rb +3 -3
- data/spec/dummy/db/schema.rb +6 -0
- data/spec/integration/readme/controllers/games_controller_spec.rb +1 -1
- data/spec/integration/yard/azeroth/decorator_spec.rb +15 -0
- data/spec/integration/yard/controllers/games_controller_spec.rb +1 -1
- data/spec/integration/yard/controllers/paginated_documents_controller_spec.rb +1 -1
- data/spec/lib/azeroth/controller_interface_spec.rb +1 -1
- data/spec/lib/azeroth/decorator/method_builder_spec.rb +61 -2
- data/spec/lib/azeroth/decorator_spec.rb +96 -5
- data/spec/lib/azeroth/request_handler/pagination_spec.rb +133 -0
- data/spec/lib/azeroth/request_handler/update_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/app/controllers/controller.rb +1 -0
- data/spec/support/matchers/add_method.rb +6 -4
- data/spec/support/shared_examples/request_handler.rb +1 -5
- metadata +17 -569
@@ -3,21 +3,80 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Azeroth::Decorator::MethodBuilder do
|
6
|
+
subject(:build_reader) do
|
7
|
+
described_class.build_reader(decorator_class, :age, options)
|
8
|
+
end
|
9
|
+
|
6
10
|
let(:decorator_class) { Class.new(Azeroth::Decorator) }
|
7
11
|
let(:decorator) { decorator_class.new(object) }
|
8
12
|
let(:model) { build(:dummy_model) }
|
9
13
|
let(:object) { model }
|
14
|
+
let(:options) { Azeroth::Decorator::Options.new(options_hash) }
|
15
|
+
let(:options_hash) { {} }
|
10
16
|
|
11
17
|
describe '.build_reader' do
|
12
18
|
it do
|
13
|
-
expect {
|
19
|
+
expect { build_reader }
|
14
20
|
.to add_method(:age).to(decorator)
|
15
21
|
end
|
16
22
|
|
17
23
|
it do
|
18
|
-
|
24
|
+
build_reader
|
19
25
|
|
20
26
|
expect(decorator.age).to eq(model.age)
|
21
27
|
end
|
28
|
+
|
29
|
+
context 'when passing reader option' do
|
30
|
+
context 'when passing true' do
|
31
|
+
let(:options_hash) { { reader: true } }
|
32
|
+
|
33
|
+
it do
|
34
|
+
expect { build_reader }
|
35
|
+
.to add_method(:age).to(decorator)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when passing false' do
|
40
|
+
let(:options_hash) { { reader: false } }
|
41
|
+
|
42
|
+
it do
|
43
|
+
expect { build_reader }
|
44
|
+
.not_to add_method(:age).to(decorator)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when passing override option as true' do
|
50
|
+
let(:options_hash) { { override: false } }
|
51
|
+
|
52
|
+
it do
|
53
|
+
expect { build_reader }
|
54
|
+
.to add_method(:age).to(decorator)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when method already existed' do
|
59
|
+
before do
|
60
|
+
decorator_class.define_method(:age) { 1 }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when passing override option as true' do
|
64
|
+
let(:options_hash) { { override: true } }
|
65
|
+
|
66
|
+
it do
|
67
|
+
expect { build_reader }
|
68
|
+
.to change_method(:age).on(decorator)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when passing override option as false' do
|
73
|
+
let(:options_hash) { { override: false } }
|
74
|
+
|
75
|
+
it do
|
76
|
+
expect { build_reader }
|
77
|
+
.not_to change_method(:age).on(decorator)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
22
81
|
end
|
23
82
|
end
|
@@ -5,14 +5,16 @@ require 'spec_helper'
|
|
5
5
|
describe Azeroth::Decorator do
|
6
6
|
subject(:decorator) { DummyModel::Decorator.new(object) }
|
7
7
|
|
8
|
-
let(:model)
|
9
|
-
let(:object)
|
8
|
+
let(:model) { build(:dummy_model) }
|
9
|
+
let(:object) { model }
|
10
|
+
let(:instance) { decorator.new(object) }
|
10
11
|
|
11
12
|
describe '.expose' do
|
12
13
|
subject(:decorator) { Class.new(described_class) }
|
13
14
|
|
15
|
+
let(:options_hash) { {} }
|
14
16
|
let(:expected_options) do
|
15
|
-
Azeroth::Decorator::Options.new
|
17
|
+
Azeroth::Decorator::Options.new(options_hash)
|
16
18
|
end
|
17
19
|
|
18
20
|
it do
|
@@ -59,6 +61,97 @@ describe Azeroth::Decorator do
|
|
59
61
|
.and raise_error(Sinclair::Exception::InvalidOptions)
|
60
62
|
end
|
61
63
|
end
|
64
|
+
|
65
|
+
context 'when decorator already has the method' do
|
66
|
+
before do
|
67
|
+
decorator.define_method(:name) do
|
68
|
+
'some name'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when not passing override' do
|
73
|
+
it do
|
74
|
+
expect { decorator.send(:expose, :name) }
|
75
|
+
.to change(decorator, :attributes_map)
|
76
|
+
.from({})
|
77
|
+
.to({ name: expected_options })
|
78
|
+
end
|
79
|
+
|
80
|
+
it do
|
81
|
+
expect { decorator.send(:expose, :name) }
|
82
|
+
.to change_method(:name)
|
83
|
+
.on(instance)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when passing override as true' do
|
88
|
+
let(:options_hash) { { override: true } }
|
89
|
+
|
90
|
+
it do
|
91
|
+
expect { decorator.send(:expose, :name, **options_hash) }
|
92
|
+
.to change(decorator, :attributes_map)
|
93
|
+
.from({})
|
94
|
+
.to({ name: expected_options })
|
95
|
+
end
|
96
|
+
|
97
|
+
it do
|
98
|
+
expect { decorator.send(:expose, :name, **options_hash) }
|
99
|
+
.to change_method(:name)
|
100
|
+
.on(instance)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when passing override as false' do
|
105
|
+
let(:options_hash) { { override: false } }
|
106
|
+
|
107
|
+
it do
|
108
|
+
expect { decorator.send(:expose, :name, **options_hash) }
|
109
|
+
.to change(decorator, :attributes_map)
|
110
|
+
.from({})
|
111
|
+
.to({ name: expected_options })
|
112
|
+
end
|
113
|
+
|
114
|
+
it do
|
115
|
+
expect { decorator.send(:expose, :name, **options_hash) }
|
116
|
+
.not_to change_method(:name)
|
117
|
+
.on(instance)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when passing reader option' do
|
123
|
+
context 'when option is true' do
|
124
|
+
let(:options_hash) { { reader: true } }
|
125
|
+
|
126
|
+
it do
|
127
|
+
expect { decorator.send(:expose, :name, **options_hash) }
|
128
|
+
.to change(decorator, :attributes_map)
|
129
|
+
.from({})
|
130
|
+
.to({ name: expected_options })
|
131
|
+
end
|
132
|
+
|
133
|
+
it do
|
134
|
+
expect { decorator.send(:expose, :name, **options_hash) }
|
135
|
+
.to add_method(:name).to(decorator)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when option is false' do
|
140
|
+
let(:options_hash) { { reader: false } }
|
141
|
+
|
142
|
+
it do
|
143
|
+
expect { decorator.send(:expose, :name, **options_hash) }
|
144
|
+
.to change(decorator, :attributes_map)
|
145
|
+
.from({})
|
146
|
+
.to({ name: expected_options })
|
147
|
+
end
|
148
|
+
|
149
|
+
it do
|
150
|
+
expect { decorator.send(:expose, :name, **options_hash) }
|
151
|
+
.not_to add_method(:name).to(decorator)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
62
155
|
end
|
63
156
|
|
64
157
|
describe '#as_json' do
|
@@ -323,12 +416,10 @@ describe Azeroth::Decorator do
|
|
323
416
|
end
|
324
417
|
|
325
418
|
context 'when method is private and passing include_private' do
|
326
|
-
# rubocop:disable RSpec/PredicateMatcher
|
327
419
|
it do
|
328
420
|
expect(decorator.respond_to?(:private_name, true))
|
329
421
|
.to be_truthy
|
330
422
|
end
|
331
|
-
# rubocop:enable RSpec/PredicateMatcher
|
332
423
|
end
|
333
424
|
|
334
425
|
context 'when object does not respond to it' do
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Azeroth::RequestHandler::Pagination do
|
6
|
+
subject(:pagination) { described_class.new(params, options) }
|
7
|
+
|
8
|
+
let(:options) { Azeroth::Options.new(options_hash) }
|
9
|
+
let(:options_hash) { {} }
|
10
|
+
let(:params) { ActionController::Parameters.new(parameters) }
|
11
|
+
let(:parameters) { {} }
|
12
|
+
|
13
|
+
describe '#offset' do
|
14
|
+
context 'when nothing was defined' do
|
15
|
+
it do
|
16
|
+
expect(pagination.offset).to be_zero
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when parameters has page value' do
|
21
|
+
let(:parameters) { { page: page } }
|
22
|
+
let(:page) { Random.rand(1..10) }
|
23
|
+
let(:expected_offset) { (page - 1) * expected_per_page }
|
24
|
+
let(:expected_per_page) { 20 }
|
25
|
+
|
26
|
+
it 'returns value from request using default per_page' do
|
27
|
+
expect(pagination.offset).to eq(expected_offset)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when parameters has per_page value' do
|
32
|
+
let(:parameters) { { per_page: per_page } }
|
33
|
+
let(:per_page) { Random.rand(1..10) }
|
34
|
+
|
35
|
+
it do
|
36
|
+
expect(pagination.offset).to be_zero
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when parameters has page and per page values' do
|
41
|
+
let(:parameters) { { page: page, per_page: per_page } }
|
42
|
+
let(:page) { Random.rand(1..10) }
|
43
|
+
let(:per_page) { Random.rand(1..10) }
|
44
|
+
let(:expected_offset) { (page - 1) * expected_per_page }
|
45
|
+
let(:expected_per_page) { per_page }
|
46
|
+
|
47
|
+
it 'returns value from request' do
|
48
|
+
expect(pagination.offset).to eq(expected_offset)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when parameters has page and options per page values' do
|
53
|
+
let(:parameters) { { page: page } }
|
54
|
+
let(:options_hash) { { per_page: per_page } }
|
55
|
+
let(:page) { Random.rand(1..10) }
|
56
|
+
let(:per_page) { Random.rand(1..10) }
|
57
|
+
let(:expected_offset) { (page - 1) * expected_per_page }
|
58
|
+
let(:expected_per_page) { per_page }
|
59
|
+
|
60
|
+
it 'returns value from request and options' do
|
61
|
+
expect(pagination.offset).to eq(expected_offset)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when params has page and per_page and options per page values' do
|
66
|
+
let(:parameters) { { page: page, per_page: per_page } }
|
67
|
+
let(:options_hash) { { per_page: options_per_page } }
|
68
|
+
let(:page) { Random.rand(1..10) }
|
69
|
+
let(:options_per_page) { Random.rand(1..10) }
|
70
|
+
let(:per_page) { Random.rand(1..10) }
|
71
|
+
let(:expected_offset) { (page - 1) * expected_per_page }
|
72
|
+
let(:expected_per_page) { per_page }
|
73
|
+
|
74
|
+
it 'returns value from request' do
|
75
|
+
expect(pagination.offset).to eq(expected_offset)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#limit' do
|
81
|
+
context 'when nothing was defined' do
|
82
|
+
it 'returns default value' do
|
83
|
+
expect(pagination.limit).to eq(20)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when parameters has per_page' do
|
88
|
+
let(:parameters) { { per_page: per_page } }
|
89
|
+
let(:per_page) { Random.rand(1..10) }
|
90
|
+
|
91
|
+
it 'returns value from request' do
|
92
|
+
expect(pagination.limit).to eq(per_page)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when options has per_page' do
|
97
|
+
let(:options_hash) { { per_page: per_page } }
|
98
|
+
let(:per_page) { Random.rand(1..10) }
|
99
|
+
|
100
|
+
it 'returns value from options' do
|
101
|
+
expect(pagination.limit).to eq(per_page)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when params and options have per_page' do
|
106
|
+
let(:parameters) { { per_page: per_page } }
|
107
|
+
let(:per_page) { Random.rand(1..10) }
|
108
|
+
let(:options_hash) { { per_page: options_per_page } }
|
109
|
+
let(:options_per_page) { Random.rand(1..10) }
|
110
|
+
|
111
|
+
it 'returns value from request' do
|
112
|
+
expect(pagination.limit).to eq(per_page)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#current_page' do
|
118
|
+
context 'when nothing was defined' do
|
119
|
+
it 'returns first page' do
|
120
|
+
expect(pagination.current_page).to eq(1)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'when parameters has page' do
|
125
|
+
let(:parameters) { { page: page } }
|
126
|
+
let(:page) { Random.rand(1..10) }
|
127
|
+
|
128
|
+
it 'returns value from request' do
|
129
|
+
expect(pagination.current_page).to eq(page)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -22,7 +22,7 @@ require 'shoulda-matchers'
|
|
22
22
|
require 'rspec/collection_matchers'
|
23
23
|
|
24
24
|
support_files = File.expand_path('spec/support/**/*.rb')
|
25
|
-
Dir[support_files].
|
25
|
+
Dir[support_files].each { |file| require file }
|
26
26
|
|
27
27
|
RSpec::Matchers.define_negated_matcher :not_change, :change
|
28
28
|
RSpec::Matchers.define_negated_matcher :not_add_method, :add_method
|
@@ -6,11 +6,12 @@ module RSpec
|
|
6
6
|
attr_reader :method
|
7
7
|
|
8
8
|
def initialize(method = nil)
|
9
|
+
super
|
9
10
|
@method = method
|
10
11
|
end
|
11
12
|
|
12
|
-
def to(instance = nil, &
|
13
|
-
AddMethodTo.new(instance, method, &
|
13
|
+
def to(instance = nil, &)
|
14
|
+
AddMethodTo.new(instance, method, &)
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
@@ -18,6 +19,7 @@ module RSpec
|
|
18
19
|
attr_reader :method, :instance, :block
|
19
20
|
|
20
21
|
def initialize(instance, method, &block)
|
22
|
+
super
|
21
23
|
@instance = instance
|
22
24
|
@method = method
|
23
25
|
@block = block
|
@@ -68,8 +70,8 @@ module RSpec
|
|
68
70
|
|
69
71
|
def raise_block_syntax_error
|
70
72
|
raise SyntaxError, 'Block not received by the' \
|
71
|
-
|
72
|
-
|
73
|
+
'`add_method_to` matcher. ' \
|
74
|
+
'Perhaps you want to use `{ ... }` instead of do/end?'
|
73
75
|
end
|
74
76
|
end
|
75
77
|
end
|
@@ -29,15 +29,11 @@ shared_examples 'a request handler' do |status: :ok|
|
|
29
29
|
before do
|
30
30
|
create_list(:document, documents_count)
|
31
31
|
|
32
|
-
allow(controller).to receive(:params)
|
33
|
-
.and_return(params)
|
34
|
-
|
35
32
|
allow(controller).to receive(:render)
|
36
33
|
.with(json: expected_json, status: status)
|
37
34
|
.and_return(expected_json)
|
38
35
|
|
39
|
-
allow(controller).to
|
40
|
-
.and_return(controller_headers)
|
36
|
+
allow(controller).to receive_messages(params: params, headers: controller_headers)
|
41
37
|
end
|
42
38
|
|
43
39
|
it 'returns all documents json' do
|