azeroth 0.7.2 → 0.8.1
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 +2 -2
- data/Dockerfile +1 -1
- data/README.md +4 -1
- data/azeroth.gemspec +28 -26
- data/config/yardstick.yml +1 -0
- data/lib/azeroth.rb +9 -8
- data/lib/azeroth/controller_interface.rb +87 -0
- data/lib/azeroth/decorator.rb +2 -3
- data/lib/azeroth/decorator/method_builder.rb +26 -0
- data/lib/azeroth/options.rb +38 -2
- data/lib/azeroth/request_handler.rb +16 -7
- data/lib/azeroth/request_handler/create.rb +1 -1
- data/lib/azeroth/request_handler/index.rb +78 -0
- data/lib/azeroth/version.rb +1 -1
- data/spec/controllers/documents_controller_spec.rb +1 -1
- data/spec/controllers/documents_with_error_controller_spec.rb +1 -1
- data/spec/controllers/index_documents_controller_spec.rb +12 -1
- data/spec/controllers/paginated_documents_controller_spec.rb +146 -0
- data/spec/dummy/app/controllers/paginated_documents_controller.rb +7 -0
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/lib/azeroth/controller_interface_spec.rb +82 -0
- data/spec/lib/azeroth/decorator/method_builder_spec.rb +23 -0
- data/spec/lib/azeroth/request_handler/create_spec.rb +106 -0
- data/spec/lib/azeroth/request_handler/index_spec.rb +118 -0
- data/spec/lib/azeroth/request_handler_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/support/app/controllers/request_handler_controller.rb +5 -0
- data/spec/support/app/workers/worker.rb +5 -0
- data/spec/support/shared_examples/request_handler.rb +6 -1
- metadata +74 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60f05e09418f7fc0e6155ee3c4e7349e3a80638295eb01032dc0c284a5ccbaa5
|
4
|
+
data.tar.gz: 97e333436d04d1cfb255c2dc26751e43aa9da6fad9a383f4c26de33c1df70ffe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d01f8321b172c0f3d6aedde71ae3e34de04ba261bcacaa4f9157bf8223a75390378167dee429e704a67c38d9d8bb21e695d00faaf612b32dd09d2f53aff9927
|
7
|
+
data.tar.gz: b73a0aee9cc39faff3f6e7a3281987028a27bee1034ecc22e0176e36bd8113fa784800d0460966e16fe973384e081112a74472c7e5878595a4156375b09d0ce2
|
data/.circleci/config.yml
CHANGED
@@ -18,7 +18,7 @@ workflows:
|
|
18
18
|
jobs:
|
19
19
|
test:
|
20
20
|
docker:
|
21
|
-
- image: darthjee/circleci_rails_gems:0.
|
21
|
+
- image: darthjee/circleci_rails_gems:0.6.3
|
22
22
|
environment:
|
23
23
|
PROJECT: azeroth
|
24
24
|
steps:
|
@@ -52,7 +52,7 @@ jobs:
|
|
52
52
|
command: check_specs
|
53
53
|
build-and-release:
|
54
54
|
docker:
|
55
|
-
- image: darthjee/circleci_rails_gems:0.
|
55
|
+
- image: darthjee/circleci_rails_gems:0.6.3
|
56
56
|
environment:
|
57
57
|
PROJECT: azeroth
|
58
58
|
steps:
|
data/Dockerfile
CHANGED
data/README.md
CHANGED
@@ -11,7 +11,7 @@ Azeroth
|
|
11
11
|
|
12
12
|
Yard Documentation
|
13
13
|
-------------------
|
14
|
-
[https://www.rubydoc.info/gems/azeroth/0.
|
14
|
+
[https://www.rubydoc.info/gems/azeroth/0.8.1](https://www.rubydoc.info/gems/azeroth/0.8.1)
|
15
15
|
|
16
16
|
Azeroth has been designed making the coding of controllers easier
|
17
17
|
as routes in controllers are usually copy, paste and replace of same
|
@@ -59,7 +59,10 @@ It accepts options
|
|
59
59
|
- except: List of actions to not to be built
|
60
60
|
- decorator: Decorator class or flag allowing/disallowing decorators
|
61
61
|
- before_save: Method/Proc to be ran before saving the resource on create or update
|
62
|
+
- after_save: Method/Proc to be ran after saving the resource on create or update
|
62
63
|
- build_with: Method/Block to be ran when building the reource on create
|
64
|
+
- paginated: Flag when pagination should be applied
|
65
|
+
- per_page: Number of items returned when pagination is active
|
63
66
|
|
64
67
|
```ruby
|
65
68
|
# publishers_controller.rb
|
data/azeroth.gemspec
CHANGED
@@ -18,33 +18,35 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ['lib']
|
20
20
|
|
21
|
-
gem.add_runtime_dependency 'activesupport', '~> 5.2.
|
21
|
+
gem.add_runtime_dependency 'activesupport', '~> 5.2.x'
|
22
22
|
gem.add_runtime_dependency 'darthjee-active_ext', '>= 1.3.2'
|
23
23
|
gem.add_runtime_dependency 'jace', '>= 0.0.3'
|
24
|
-
gem.add_runtime_dependency 'sinclair', '>= 1.6.
|
24
|
+
gem.add_runtime_dependency 'sinclair', '>= 1.6.7'
|
25
25
|
|
26
|
-
gem.add_development_dependency 'actionpack',
|
27
|
-
gem.add_development_dependency 'activerecord',
|
28
|
-
gem.add_development_dependency 'bundler',
|
29
|
-
gem.add_development_dependency 'factory_bot',
|
30
|
-
gem.add_development_dependency 'nokogiri',
|
31
|
-
gem.add_development_dependency 'pry',
|
32
|
-
gem.add_development_dependency 'pry-nav',
|
33
|
-
gem.add_development_dependency 'rails',
|
34
|
-
gem.add_development_dependency 'rails-controller-testing',
|
35
|
-
gem.add_development_dependency 'rake',
|
36
|
-
gem.add_development_dependency 'reek',
|
37
|
-
gem.add_development_dependency 'rspec',
|
38
|
-
gem.add_development_dependency 'rspec-
|
39
|
-
gem.add_development_dependency 'rspec-
|
40
|
-
gem.add_development_dependency 'rspec-
|
41
|
-
gem.add_development_dependency 'rspec-
|
42
|
-
gem.add_development_dependency 'rspec-
|
43
|
-
gem.add_development_dependency '
|
44
|
-
gem.add_development_dependency 'rubocop
|
45
|
-
gem.add_development_dependency '
|
46
|
-
gem.add_development_dependency '
|
47
|
-
gem.add_development_dependency '
|
48
|
-
gem.add_development_dependency '
|
49
|
-
gem.add_development_dependency '
|
26
|
+
gem.add_development_dependency 'actionpack', '~> 5.2.x'
|
27
|
+
gem.add_development_dependency 'activerecord', '~> 5.2.x'
|
28
|
+
gem.add_development_dependency 'bundler', '1.16.1'
|
29
|
+
gem.add_development_dependency 'factory_bot', '5.2.0'
|
30
|
+
gem.add_development_dependency 'nokogiri', '1.11.4'
|
31
|
+
gem.add_development_dependency 'pry', '0.12.2'
|
32
|
+
gem.add_development_dependency 'pry-nav', '0.3.0'
|
33
|
+
gem.add_development_dependency 'rails', '~> 5.2.x'
|
34
|
+
gem.add_development_dependency 'rails-controller-testing', '1.0.4'
|
35
|
+
gem.add_development_dependency 'rake', '13.0.3'
|
36
|
+
gem.add_development_dependency 'reek', '6.0.3'
|
37
|
+
gem.add_development_dependency 'rspec', '3.9.0'
|
38
|
+
gem.add_development_dependency 'rspec-collection_matchers', '1.2.0'
|
39
|
+
gem.add_development_dependency 'rspec-core', '3.9.3'
|
40
|
+
gem.add_development_dependency 'rspec-expectations', '3.9.4'
|
41
|
+
gem.add_development_dependency 'rspec-mocks', '3.9.1'
|
42
|
+
gem.add_development_dependency 'rspec-rails', '3.9.0'
|
43
|
+
gem.add_development_dependency 'rspec-support', '3.9.4'
|
44
|
+
gem.add_development_dependency 'rubocop', '0.80.1'
|
45
|
+
gem.add_development_dependency 'rubocop-rspec', '1.38.1'
|
46
|
+
gem.add_development_dependency 'rubycritic', '4.6.1'
|
47
|
+
gem.add_development_dependency 'shoulda-matchers', '4.3.0'
|
48
|
+
gem.add_development_dependency 'simplecov', '0.17.1'
|
49
|
+
gem.add_development_dependency 'sqlite3', '1.4.2'
|
50
|
+
gem.add_development_dependency 'yard', '0.9.26'
|
51
|
+
gem.add_development_dependency 'yardstick', '0.9.9'
|
50
52
|
end
|
data/config/yardstick.yml
CHANGED
data/lib/azeroth.rb
CHANGED
@@ -11,12 +11,13 @@ require 'jace'
|
|
11
11
|
#
|
12
12
|
# @see Resourceable
|
13
13
|
module Azeroth
|
14
|
-
autoload :
|
15
|
-
autoload :
|
16
|
-
autoload :
|
17
|
-
autoload :
|
18
|
-
autoload :
|
19
|
-
autoload :
|
20
|
-
autoload :
|
21
|
-
autoload :
|
14
|
+
autoload :ControllerInterface, 'azeroth/controller_interface'
|
15
|
+
autoload :Decorator, 'azeroth/decorator'
|
16
|
+
autoload :DummyDecorator, 'azeroth/dummy_decorator'
|
17
|
+
autoload :Model, 'azeroth/model'
|
18
|
+
autoload :RequestHandler, 'azeroth/request_handler'
|
19
|
+
autoload :Resourceable, 'azeroth/resourceable'
|
20
|
+
autoload :ResourceBuilder, 'azeroth/resource_builder'
|
21
|
+
autoload :RoutesBuilder, 'azeroth/routes_builder'
|
22
|
+
autoload :Options, 'azeroth/options'
|
22
23
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Azeroth
|
4
|
+
# @api private
|
5
|
+
#
|
6
|
+
# Interface for using the controller
|
7
|
+
class ControllerInterface
|
8
|
+
# @param controller [ApplicationController]
|
9
|
+
def initialize(controller)
|
10
|
+
@controller = controller
|
11
|
+
end
|
12
|
+
|
13
|
+
# Set response headers
|
14
|
+
#
|
15
|
+
# @param headers_hash [Hash] headers to be set
|
16
|
+
#
|
17
|
+
# @return [Hash]
|
18
|
+
def add_headers(headers_hash)
|
19
|
+
controller.instance_eval do
|
20
|
+
headers_hash.each do |key, value|
|
21
|
+
headers[key.to_s] = value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Renders response json
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
def render_json(json, status)
|
30
|
+
controller.instance_eval do
|
31
|
+
render(json: json, status: status)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set a variable in the controller
|
36
|
+
#
|
37
|
+
# @param variable [String,Symbol] variable name
|
38
|
+
# @param value [Object] value to be set
|
39
|
+
#
|
40
|
+
# @return [Object]
|
41
|
+
def set(variable, value)
|
42
|
+
controller.instance_variable_set("@#{variable}", value)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :controller
|
48
|
+
# @method controller
|
49
|
+
# @private
|
50
|
+
# @api private
|
51
|
+
#
|
52
|
+
# Controller where methods will be called
|
53
|
+
#
|
54
|
+
# @return [ApplicationController]
|
55
|
+
|
56
|
+
# @private
|
57
|
+
#
|
58
|
+
# Dispatcher to delegate all methods call to controller
|
59
|
+
#
|
60
|
+
# @param method_name [Symbol] name of the method
|
61
|
+
# called
|
62
|
+
# @param args [Array<Object>] arguments of the
|
63
|
+
# method called
|
64
|
+
#
|
65
|
+
# @return [Object]
|
66
|
+
def method_missing(method_name, *args)
|
67
|
+
if controller.respond_to?(method_name, true)
|
68
|
+
controller.send(method_name, *args)
|
69
|
+
else
|
70
|
+
super
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# @private
|
75
|
+
#
|
76
|
+
# Checks if a controller responds to a method
|
77
|
+
#
|
78
|
+
# @param method_name [Symbol] name of the method checked
|
79
|
+
# @param include_private [TrueClass,FalseClass] flag
|
80
|
+
# indicating if private methods should be included
|
81
|
+
#
|
82
|
+
# @return [TrueClass,FalseClass]
|
83
|
+
def respond_to_missing?(method_name, include_private)
|
84
|
+
controller.respond_to?(method_name, include_private)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/azeroth/decorator.rb
CHANGED
@@ -42,6 +42,7 @@ module Azeroth
|
|
42
42
|
class Decorator
|
43
43
|
autoload :HashBuilder, 'azeroth/decorator/hash_builder'
|
44
44
|
autoload :KeyValueExtractor, 'azeroth/decorator/key_value_extractor'
|
45
|
+
autoload :MethodBuilder, 'azeroth/decorator/method_builder'
|
45
46
|
autoload :Options, 'azeroth/decorator/options'
|
46
47
|
|
47
48
|
class << self
|
@@ -228,9 +229,7 @@ module Azeroth
|
|
228
229
|
def expose(attribute, **options_hash)
|
229
230
|
options = Decorator::Options.new(options_hash)
|
230
231
|
|
231
|
-
|
232
|
-
builder.add_method(attribute, "@object.#{attribute}")
|
233
|
-
builder.build
|
232
|
+
MethodBuilder.build_reader(self, attribute)
|
234
233
|
|
235
234
|
attributes_map[attribute] = options
|
236
235
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sinclair'
|
4
|
+
|
5
|
+
module Azeroth
|
6
|
+
class Decorator
|
7
|
+
# Responsible for building readers for attributes
|
8
|
+
# @api private
|
9
|
+
class MethodBuilder < Sinclair
|
10
|
+
# Builds reader
|
11
|
+
#
|
12
|
+
# reaader delegate method calls to @object
|
13
|
+
#
|
14
|
+
# @return [Array<Sinclair::MethodDefinition>]
|
15
|
+
def self.build_reader(klass, attribute)
|
16
|
+
new(klass).build_reader(attribute)
|
17
|
+
end
|
18
|
+
|
19
|
+
# (see MethodBuilder.build_reader)
|
20
|
+
def build_reader(attribute)
|
21
|
+
add_method(attribute, "@object.#{attribute}")
|
22
|
+
build
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/azeroth/options.rb
CHANGED
@@ -19,7 +19,10 @@ module Azeroth
|
|
19
19
|
except: [],
|
20
20
|
decorator: true,
|
21
21
|
before_save: nil,
|
22
|
-
|
22
|
+
after_save: nil,
|
23
|
+
build_with: nil,
|
24
|
+
paginated: false,
|
25
|
+
per_page: 20
|
23
26
|
}.freeze
|
24
27
|
|
25
28
|
with_options DEFAULT_OPTIONS
|
@@ -40,10 +43,18 @@ module Azeroth
|
|
40
43
|
# @return [Jace::Dispatcher]
|
41
44
|
def event_dispatcher(event)
|
42
45
|
Jace::Dispatcher.new(
|
43
|
-
before: try("before_#{event}")
|
46
|
+
before: try("before_#{event}"),
|
47
|
+
after: try("after_#{event}")
|
44
48
|
)
|
45
49
|
end
|
46
50
|
|
51
|
+
alias paginated? paginated
|
52
|
+
# @method paginated?
|
53
|
+
# @api private
|
54
|
+
#
|
55
|
+
# @see paginated
|
56
|
+
# @return [TrueClass,FalseClass]
|
57
|
+
|
47
58
|
# @method only
|
48
59
|
# @api private
|
49
60
|
#
|
@@ -81,11 +92,36 @@ module Azeroth
|
|
81
92
|
#
|
82
93
|
# @return [Symbol,Proc]
|
83
94
|
|
95
|
+
# @method after_save
|
96
|
+
# @api private
|
97
|
+
#
|
98
|
+
# Block or method name to be run after save
|
99
|
+
#
|
100
|
+
# The given method or block will be ran
|
101
|
+
# after committing changes in models
|
102
|
+
# to database
|
103
|
+
#
|
104
|
+
# @return [Symbol,Proc]
|
105
|
+
|
84
106
|
# @method build_with
|
85
107
|
# @api private
|
86
108
|
#
|
87
109
|
# Block or method name to be ran when building the resource
|
88
110
|
#
|
89
111
|
# @return [Symbol,Proc]
|
112
|
+
|
113
|
+
# @method paginated
|
114
|
+
# @api private
|
115
|
+
#
|
116
|
+
# Boolean indicating if pagination should or not be used
|
117
|
+
#
|
118
|
+
# @return [TrueClass,FalseClass]
|
119
|
+
|
120
|
+
# @method per_page
|
121
|
+
# @api private
|
122
|
+
#
|
123
|
+
# Number of elements when pagination is active
|
124
|
+
#
|
125
|
+
# @return [Integer]
|
90
126
|
end
|
91
127
|
end
|
@@ -19,7 +19,7 @@ module Azeroth
|
|
19
19
|
# @param controller [ApplicationController]
|
20
20
|
# @param model [Azeroth::Model]
|
21
21
|
def initialize(controller, model, options)
|
22
|
-
@controller = controller
|
22
|
+
@controller = ControllerInterface.new(controller)
|
23
23
|
@model = model
|
24
24
|
@options = options
|
25
25
|
end
|
@@ -35,12 +35,11 @@ module Azeroth
|
|
35
35
|
def process
|
36
36
|
return unless json?
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
38
|
+
controller.add_headers(headers)
|
39
|
+
controller.render_json(
|
40
|
+
model.decorate(resource),
|
41
|
+
status
|
42
|
+
)
|
44
43
|
end
|
45
44
|
|
46
45
|
private
|
@@ -141,5 +140,15 @@ module Azeroth
|
|
141
140
|
def collection
|
142
141
|
@collection = controller.send(model.plural)
|
143
142
|
end
|
143
|
+
|
144
|
+
# @private
|
145
|
+
# @abstract
|
146
|
+
#
|
147
|
+
# Headers to be added
|
148
|
+
#
|
149
|
+
# @return [Hash]
|
150
|
+
def headers
|
151
|
+
{}
|
152
|
+
end
|
144
153
|
end
|
145
154
|
end
|
@@ -8,14 +8,92 @@ module Azeroth
|
|
8
8
|
class Index < RequestHandler
|
9
9
|
private
|
10
10
|
|
11
|
+
delegate :paginated?, :per_page, to: :options
|
12
|
+
|
11
13
|
# @private
|
12
14
|
#
|
13
15
|
# return a collection of the model
|
14
16
|
#
|
15
17
|
# @return [Enumerable<Object>]
|
16
18
|
def resource
|
19
|
+
return scoped_entries unless paginated?
|
20
|
+
|
21
|
+
paginated_entries
|
22
|
+
end
|
23
|
+
|
24
|
+
# @private
|
25
|
+
#
|
26
|
+
# returns pagination headers
|
27
|
+
#
|
28
|
+
# @return [Hash] heders
|
29
|
+
def headers
|
30
|
+
return {} unless paginated?
|
31
|
+
|
32
|
+
{
|
33
|
+
pages: pages,
|
34
|
+
page: current_page,
|
35
|
+
per_page: limit
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
# @private
|
40
|
+
#
|
41
|
+
# paginated collection of the model
|
42
|
+
#
|
43
|
+
# @return [Enumerable<Object>]
|
44
|
+
def paginated_entries
|
45
|
+
scoped_entries.offset(offset).limit(limit)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @private
|
49
|
+
#
|
50
|
+
# offest used in pagination
|
51
|
+
#
|
52
|
+
# offset is retrieved from +params[:per_page]+
|
53
|
+
# or +options.per_page+
|
54
|
+
#
|
55
|
+
# @return [Integer]
|
56
|
+
def offset
|
57
|
+
(current_page - 1) * limit
|
58
|
+
end
|
59
|
+
|
60
|
+
# @private
|
61
|
+
#
|
62
|
+
# limit used in pagination
|
63
|
+
#
|
64
|
+
# limit is retrieved from +params[:page]+
|
65
|
+
#
|
66
|
+
# @return [Integer]
|
67
|
+
def limit
|
68
|
+
(params[:per_page] || per_page).to_i
|
69
|
+
end
|
70
|
+
|
71
|
+
# @private
|
72
|
+
#
|
73
|
+
# default scope of elements
|
74
|
+
#
|
75
|
+
# @return [Enumerable<Object>]
|
76
|
+
def scoped_entries
|
17
77
|
controller.send(model.plural)
|
18
78
|
end
|
79
|
+
|
80
|
+
# @private
|
81
|
+
#
|
82
|
+
# calculates current page
|
83
|
+
#
|
84
|
+
# @return [Integer]
|
85
|
+
def current_page
|
86
|
+
(params[:page] || 1).to_i
|
87
|
+
end
|
88
|
+
|
89
|
+
# @private
|
90
|
+
#
|
91
|
+
# calculates how many pages are there
|
92
|
+
#
|
93
|
+
# @return [Integer]
|
94
|
+
def pages
|
95
|
+
(scoped_entries.count.to_f / limit).ceil
|
96
|
+
end
|
19
97
|
end
|
20
98
|
end
|
21
99
|
end
|