hexx 5.4.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,182 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Hexx
4
-
5
- # Contains methods to declare and inject module dependencies.
6
- #
7
- # Allows to provide DJ framework for the gem.
8
- #
9
- # @example
10
- # # Declare the dependencies for the gem root module
11
- #
12
- # # lib/my_gem.rb
13
- # module MyGem
14
- # extend Hexx::Dependencies
15
- # self.depends_on :get_item, :add_item, :delete_item
16
- # end
17
- #
18
- # # Inject dependencies (as a constant or its name)
19
- #
20
- # # config/my_gem.rb
21
- # MyGem.configure do |config|
22
- # config.get_item = AnotherGem::Services::Get
23
- # config.add_item = "AnotherGem::Services::Add"
24
- # end
25
- #
26
- # # Use dependency in the module code (models, services, etc.)
27
- # # When the dependency hasn't been set, fails with +NotImplementedError+
28
- #
29
- # MyGem.get_item # => AnotherGem::Services::Get
30
- # MyGem.add_item # => AnotherGem::Services::Add
31
- # MyGem.delete_item # raises #<NotImplementedError ... >
32
- module Dependencies
33
-
34
- # Yields a block and gives it self
35
- #
36
- # @example
37
- # module MyGem
38
- # extend Hexx::Dependencies
39
- # end
40
- #
41
- # MyGem.configure do |config|
42
- # c # => MyGem
43
- # end
44
- #
45
- # @yield The block.
46
- # @yieldparam [Dependencies] +self+.
47
- def configure
48
- yield(self)
49
- end
50
-
51
- # Declares dependency getter and setter.
52
- #
53
- # The getter constants, strings and symbols. The setter constantize the
54
- # assigned value.
55
- #
56
- # This allows setting dependency before definition of a corresponding
57
- # constant.
58
- #
59
- # @example
60
- # module MyGem
61
- # extend Hexx::Dependencies
62
- # self.depends_on :some_class
63
- # end
64
- #
65
- # MyGem.some_class = String
66
- # # => "String"
67
- # MyGem.some_class # => String
68
- #
69
- # MyGem.some_class = "String"
70
- # # => "String"
71
- # MyGem.some_class # => String
72
- #
73
- # MyGem.some_class = :String
74
- # # => "String"
75
- # MyGem.some_class # => String
76
- #
77
- # @example Dependencies can be set as a plain list of names
78
- # module MyGem
79
- # extend Hexx::Dependencies
80
- # self.depends_on :some_class, "another_class"
81
- # end
82
- #
83
- # @example Dependencies can be set as an array of names
84
- # module MyGem
85
- # extend Hexx::Dependencies
86
- # self.depends_on %w(some_class another_class)
87
- # end
88
- #
89
- # @param [Array<String, Symbol>] names The list of names for dependencies.
90
- def depends_on(*names, default: nil)
91
- names.flatten.each do |name|
92
- DependencyName.new(name).validate
93
- add_dependency_setter name
94
- add_dependency_getter name, default
95
- end
96
- end
97
-
98
- private
99
-
100
- # @api hide
101
- # Checks the name of the dependency.
102
- class DependencyName < Struct.new(:name)
103
-
104
- # @api hide
105
- # Runs validations and fails in case of any error.
106
- # @raise [TypeError] if the name has a wrong type.
107
- # @raise [ArgumentError] if the name is blank.
108
- def validate
109
- check_type
110
- check_value
111
- end
112
-
113
- private
114
-
115
- def check_type
116
- return if [String, Symbol].include? name.class
117
- fail TypeError.new "#{ name.inspect } is neither a string nor symbol."
118
- end
119
-
120
- def check_value
121
- return unless name.to_s == ""
122
- fail ArgumentError.new "The dependency name should not be blank."
123
- end
124
- end
125
-
126
- # @api hide
127
- # Checks the value of the dependency.
128
- class Dependency < Struct.new(:name, :value)
129
-
130
- # @api hide
131
- # Runs validations and fails in case of any error.
132
- # @raise [TypeError] if the value has a wrong type.
133
- # @raise [ArgumentError] if the value name is blank.
134
- def validate
135
- check_type
136
- check_value
137
- end
138
-
139
- private
140
-
141
- def check_type
142
- return if value.is_a? String
143
- return if value.is_a? Symbol
144
- return if value.is_a? Module
145
- fail TypeError.new "#{ inspect } is not a string, symbol or module."
146
- end
147
-
148
- def check_value
149
- return unless value.to_s == ""
150
- fail ArgumentError.new "The dependency #{ name } should not be blank."
151
- end
152
-
153
- def inspect
154
- value.inspect
155
- end
156
- end
157
-
158
- def add_dependency_setter(name)
159
- instance_eval "
160
- def #{ name }=(value);
161
- Dependency.new(:#{ name }, value).validate;
162
- @#{ name }= value.to_s;
163
- end"
164
- end
165
-
166
- def add_dependency_getter(name, default)
167
- instance_eval "
168
- def #{ name };
169
- value = @#{ default_name name, default };
170
- constantize(value);
171
- end"
172
- end
173
-
174
- def constantize(value)
175
- value.is_a?(Module) ? value : Kernel.const_get(value.to_s)
176
- end
177
-
178
- def default_name(name, default)
179
- [name, default].compact.map(&:to_s).join " || "
180
- end
181
- end
182
- end
@@ -1,44 +0,0 @@
1
- module Hexx
2
- module Models
3
-
4
- # @api hide
5
- # Coerces class attribute getter and setter with given type.
6
- class BaseCoercer < Struct.new(:klass, :name, :type)
7
-
8
- # Coerces class attribute's getter and setter.
9
- #
10
- # @example
11
- # BaseCoercer.new SomeModel, :name, StrippedString
12
- # BaseCoercer.coerce
13
- #
14
- # model = SomeModel.new name: "string"
15
- # model.name.class # => StrippedString
16
- def coerce
17
- coerce_setter
18
- coerce_getter
19
- end
20
-
21
- private
22
-
23
- def coerce_setter
24
- klass.class_eval(
25
- "def #{ name };
26
- #{ type_name }.new(@#{ name });
27
- end"
28
- )
29
- end
30
-
31
- def coerce_getter
32
- klass.class_eval(
33
- "def #{ name }=(value);
34
- @#{ name } = #{ type_name }.new(value);
35
- end"
36
- )
37
- end
38
-
39
- def type_name
40
- @type_name ||= type.name
41
- end
42
- end
43
- end
44
- end
@@ -1,81 +0,0 @@
1
- module Hexx
2
- class Service
3
-
4
- # @api hide
5
- # Contains methods to declare parameters and set their values.
6
- module Parameters
7
- extend ActiveSupport::Concern
8
-
9
- # Methods to declare and allow services params.
10
- module ClassMethods
11
-
12
- # @!attribute [r] params
13
- # The list of allowed instance parameters. The parameters are added
14
- # to the list by the {.allow_params} method.
15
- #
16
- # @example
17
- # class Service
18
- # include Parameters
19
- # allow_params :name
20
- # end
21
- #
22
- # Service.params # => "name"
23
- #
24
- # @return [Array<String>] The list of allowed instance parameters.
25
- def params
26
- @params ||= []
27
- end
28
-
29
- private
30
-
31
- # Sets a list of allowed parameters for the class constructor and
32
- # defines the corresponding instance attributes.
33
- #
34
- # @example (see Hexx::Service::Parameters.params)
35
- # @param [Array<Symbol, String>] keys The list of allowed parameters.
36
- def allow_params(*keys)
37
- @params = keys.map(&:to_s)
38
- define_individual_params
39
- end
40
-
41
- def define_individual_params
42
- params.each do |name|
43
- add_getter(name)
44
- add_setter(name)
45
- end
46
- end
47
-
48
- def add_getter(name)
49
- define_method(name) { params[name] }
50
- end
51
-
52
- def add_setter(name)
53
- define_method("#{name}=") { |value| params[name] = value }
54
- end
55
- end
56
-
57
- # @!method new(params)
58
- # Constructs a service object with a hash of parameters.
59
- #
60
- # @example
61
- # Service.new name: "name"
62
- #
63
- # @param [Hash] params ({}) The parameters of the service object.
64
- def initialize(params = {})
65
- extract_params_from params
66
- end
67
-
68
- # @!attribute [r] params
69
- # The parameters of the service objects. The parameters are set on
70
- # the object initialization, then are stringified and whitelisted.
71
- # @return [Hash] the service object parameters.
72
- attr_reader :params
73
-
74
- private
75
-
76
- def extract_params_from(hash)
77
- @params = hash.stringify_keys.slice(*(self.class.params))
78
- end
79
- end
80
- end
81
- end
@@ -1,40 +0,0 @@
1
- require "spec_helper"
2
-
3
- module Hexx
4
- describe Models do
5
-
6
- # ==========================================================================
7
- # Prepare environment
8
- # ==========================================================================
9
-
10
- around do |example|
11
- class TestModel; extend Models; end
12
- class TestAttribute; end
13
- example.run
14
- Hexx.send :remove_const, :TestAttribute
15
- Hexx.send :remove_const, :TestModel
16
- end
17
-
18
- let!(:coerced_attribute) { double "coerced attribute" }
19
- before do
20
- allow(TestAttribute).to receive(:new) { |val| coerced_attribute if val }
21
- end
22
-
23
- # ==========================================================================
24
- # Run tests
25
- # ==========================================================================
26
-
27
- describe ".attr_coerced" do
28
-
29
- subject { TestModel }
30
- before { subject.send :attr_coerced, :name, type: TestAttribute }
31
- let(:object) { TestModel.new }
32
-
33
- it "coerces an attribute with given type" do
34
- expect { object.name = "some name" }
35
- .to change { object.name }
36
- .from(nil).to coerced_attribute
37
- end
38
- end
39
- end
40
- end