hexx 5.0.0 → 5.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7290018a93943ca2db70630dac37ed9d1b2eabfe
4
- data.tar.gz: 04b3a2c21598e88beda09d3f2a8bcee7622ba105
3
+ metadata.gz: 7a0f508972f47609f09b6b7b303ee55c0268256e
4
+ data.tar.gz: a3c0760ee8824891234b4b6b0c48d29c47c4eecd
5
5
  SHA512:
6
- metadata.gz: e93648cc19a96e0dca81731ce200b443a4d10e394356e329f0995061cf5ea9656758f42a382b65d465125baa6bc38013f94f5d39b2d00ffe3c04922c6317c5db
7
- data.tar.gz: 4169b5355f71c1a1bb1c431edacb47e68d81990c6b74c6164a71aebc5d0b85c098be054f9f6789239c4c371b26144224e4379e78bc3f36b1b5764af7a909a1fd
6
+ metadata.gz: fc2de5bffc7cfc7fd0cdfc75b6a3fad2b2f657cfa80e28e1b90980af0d746d244a546a86ef125164001518fd89f30adb1f3023b3dc7cff09a2d0761ab484bf00
7
+ data.tar.gz: 81442ee8209ef2b7e4c3ac9e5b37f5ff8f94e3a63dbe6dd193dea1d0b9623b2e6f7c90e812a696630cea08f634989a9d154f2c7f822c705cb57be6d572422c08
data/README.rdoc CHANGED
@@ -139,6 +139,32 @@ preparation:
139
139
  user = User.name " Ivan "
140
140
  user.name # => "Ivan"
141
141
 
142
+ == Dependencies
143
+
144
+ The module provides methods +depends_on+ and +config+ to create
145
+ dependency injection framework.
146
+
147
+ Declare gem dependencies (external classes and modules).
148
+
149
+ # lib/my_gem.rb
150
+ module MyGem
151
+ extend Hexx::Dependencies
152
+ depends_on :get_item, :add_item
153
+ end
154
+
155
+ Inject gem dependencies:
156
+
157
+ # config/my_gem.rb
158
+ MyGem.configure do |config|
159
+ config.get_item = AnotherGem::Services::Get # as a constant
160
+ config.add_item = "AnotherGem::Services::Add" # as a name of a constant
161
+ end
162
+
163
+ Use them somewhere in a code:
164
+
165
+ MyGem.get_item # => AnotherGem::Services::Get
166
+ MyGem.add_item # => AnotherGem::Services::Add # the name is constantized
167
+
142
168
  == Relevant Links
143
169
 
144
170
  * Matt Wynne's talk {Hexagonal Rails}[http://www.confreaks.com/videos/977-goruco2012-hexagonal-rails]
@@ -0,0 +1,159 @@
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
+ # @param [String, Symbol] name The name for dependency.
78
+ def depends_on(*names)
79
+ names.each do |name|
80
+ DependencyName.new(name).validate
81
+ add_dependency_setter name
82
+ add_dependency_getter name
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ # @api hide
89
+ # Checks the name of the dependency.
90
+ class DependencyName < Struct.new(:name)
91
+
92
+ # @api hide
93
+ # Runs validations and fails in case of any error.
94
+ def validate
95
+ check_type
96
+ check_value
97
+ end
98
+
99
+ private
100
+
101
+ def check_type
102
+ return if [String, Symbol].include? name.class
103
+ fail TypeError.new "#{ name.inspect } is neither a string nor symbol."
104
+ end
105
+
106
+ def check_value
107
+ return unless name.to_s == ""
108
+ fail ArgumentError.new "The dependency name should not be blank."
109
+ end
110
+ end
111
+
112
+ # @api hide
113
+ # Checks the value of the dependency.
114
+ class Dependency < Struct.new(:name, :value)
115
+
116
+ # @api hide
117
+ # Runs validations and fails in case of any error.
118
+ def validate
119
+ check_type
120
+ check_value
121
+ end
122
+
123
+ private
124
+
125
+ def check_type
126
+ return if value.is_a? String
127
+ return if value.is_a? Symbol
128
+ return if value.is_a? Module
129
+ fail TypeError.new "#{ inspect } is not a string, symbol or module."
130
+ end
131
+
132
+ def check_value
133
+ return unless value.to_s == ""
134
+ fail ArgumentError.new "The dependency #{ name } should not be blank."
135
+ end
136
+
137
+ def inspect
138
+ value.inspect
139
+ end
140
+ end
141
+
142
+ def add_dependency_setter(name)
143
+ instance_eval "
144
+ def #{ name }=(value);
145
+ Dependency.new(:#{ name }, value).validate;
146
+ @#{ name }= value.to_s;
147
+ end"
148
+ end
149
+
150
+ def add_dependency_getter(name)
151
+ instance_eval "
152
+ def #{ name };
153
+ value = @#{ name };
154
+ fail NotImplementedError unless value;
155
+ value.constantize;
156
+ end"
157
+ end
158
+ end
159
+ end
data/lib/hexx/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  module Hexx
3
3
 
4
4
  # Current release.
5
- VERSION = "5.0.0"
5
+ VERSION = "5.1.0"
6
6
  end
@@ -0,0 +1,87 @@
1
+ require "spec_helper"
2
+
3
+ module Hexx
4
+ describe Dependencies do
5
+
6
+ # Mocks gem core module to test dependencies from
7
+ before { module Test; extend Dependencies; end }
8
+ after { Hexx.send :remove_const, :Test }
9
+ let(:described_module) { Test }
10
+
11
+ describe ".configure" do
12
+
13
+ it "is defined" do
14
+ expect(described_module).to respond_to :configure
15
+ end
16
+
17
+ it "yields block with self" do
18
+ described_module.configure do |config|
19
+ expect(config).to eq described_module
20
+ end
21
+ end
22
+ end
23
+
24
+ describe ".depends_on" do
25
+
26
+ it "is defined" do
27
+ expect(described_module).to respond_to :depends_on
28
+ end
29
+
30
+ it "allows symbolic attributes" do
31
+ expect { described_module.depends_on :item }.not_to raise_error
32
+ end
33
+
34
+ it "allows string attributes" do
35
+ expect { described_module.depends_on "item" }.not_to raise_error
36
+ end
37
+
38
+ it "fails when wrong object given" do
39
+ expect { described_module.depends_on 1 }.to raise_error TypeError
40
+ end
41
+
42
+ it "fails when blank object given" do
43
+ expect { described_module.depends_on "" }.to raise_error ArgumentError
44
+ end
45
+
46
+ it "adds dependencies getters" do
47
+ described_module.depends_on :item, "user"
48
+ expect(described_module).to respond_to :item
49
+ expect(described_module).to respond_to :user
50
+ end
51
+
52
+ it "adds dependencies setters" do
53
+ described_module.depends_on :item, "user"
54
+ expect(described_module).to respond_to :item=
55
+ expect(described_module).to respond_to :user=
56
+ end
57
+
58
+ context ":item" do
59
+
60
+ before { described_module.depends_on :item }
61
+
62
+ it "allows setting string and constantizes it" do
63
+ described_module.item = "String"
64
+ expect(described_module.item).to eq String
65
+ end
66
+
67
+ it "allows setting symbol and constantizes it" do
68
+ described_module.item = :String
69
+ expect(described_module.item).to eq String
70
+ end
71
+
72
+ it "allows setting constant" do
73
+ described_module.item = String
74
+ expect(described_module.item).to eq String
75
+ end
76
+
77
+ it "fails if wrong value type given" do
78
+ expect { described_module.item = 1 }.to raise_error TypeError
79
+ end
80
+
81
+ it "fails if blank string given" do
82
+ expect { described_module.item = "" }.to raise_error ArgumentError
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexx
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kozin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-20 00:00:00.000000000 Z
11
+ date: 2014-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -149,6 +149,7 @@ files:
149
149
  - README.rdoc
150
150
  - Rakefile
151
151
  - lib/hexx.rb
152
+ - lib/hexx/dependencies.rb
152
153
  - lib/hexx/models.rb
153
154
  - lib/hexx/models/base_coercer.rb
154
155
  - lib/hexx/null.rb
@@ -158,6 +159,7 @@ files:
158
159
  - lib/hexx/service/parameters.rb
159
160
  - lib/hexx/service/with_callbacks.rb
160
161
  - lib/hexx/version.rb
162
+ - spec/hexx/dependencies_spec.rb
161
163
  - spec/hexx/models_spec.rb
162
164
  - spec/hexx/null_spec.rb
163
165
  - spec/hexx/service/invalid_spec.rb
@@ -196,6 +198,7 @@ summary: Service objects for Rails.
196
198
  test_files:
197
199
  - spec/spec_helper.rb
198
200
  - spec/hexx/service_spec.rb
201
+ - spec/hexx/dependencies_spec.rb
199
202
  - spec/hexx/null_spec.rb
200
203
  - spec/hexx/service/message_spec.rb
201
204
  - spec/hexx/service/invalid_spec.rb