codependent 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9346a0d2621442d6fba3e69e244895fb5a4c22dc
4
- data.tar.gz: ff00bf9084921b52e50dbeba357ff06a8eadcaa7
3
+ metadata.gz: 824b117cef6d2000cb55df3ed8793c75f2119d42
4
+ data.tar.gz: d83e83d6c90f343853e26a8f6d154798bc2e32ef
5
5
  SHA512:
6
- metadata.gz: 4d9d0327496277dad897ce11b73abd6548ed3f97d107d17e1bc844958e35bb42191ecd5321c17a6c3c9ecd2ab04f5d4888de3224bcdb3026910f0f283fa33765
7
- data.tar.gz: 3a8a641f957db178008be0848fde2813c10c15430cd79d3fa970962d95b5426efeaf3dda1feca61031f5c9ebe7c1122def7d9cf4c756816ce6f0e3bdb9d3384d
6
+ metadata.gz: 16364a8df976b2b7a6da996898d16c4210248d25bb3774d0a446001d10d2fdf73395027979d87c6e359efd086b713a33b40dece6127330b356519e2249956da6
7
+ data.tar.gz: 2c27d0c05a78fcf297225a43cfa2cefe69cec7ed20e644841750dfee3acb253b33ce58a1efda727e8ec5ee7fe3f645bc997c2caa11dcb09b4188155e2c198d1f
data/Changelog.md CHANGED
@@ -3,3 +3,23 @@
3
3
  ### Features
4
4
 
5
5
  * Initial Release
6
+
7
+ ## 0.2 - New injection types!
8
+
9
+ ### Features
10
+
11
+ * Constructor injection
12
+ * Value injection
13
+ * Provider functions
14
+ * Dependency type checking
15
+ * New DSL syntax
16
+
17
+ ## 0.3 - Better error handling
18
+
19
+ ### Features
20
+
21
+ * Validation errors are more descriptive and contain the ID of the injectable.
22
+
23
+ ### Bug Fixes
24
+
25
+ * Dependencies that appear in multiple places in the dependency graph are injected properly.
data/Gemfile CHANGED
@@ -1,10 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- group :development do
4
- gem 'rspec'
5
- gem 'pry'
6
- gem 'pry-byebug'
7
- gem 'rubocop', '~> 0.40.0', require: false
8
- gem 'rake'
9
- gem 'simplecov', require: false
10
- end
3
+ # Specify your gem's dependencies in pastafari.gemspec
4
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,3 +1,8 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ codependent (0.3)
5
+
1
6
  GEM
2
7
  remote: https://rubygems.org/
3
8
  specs:
@@ -52,6 +57,7 @@ PLATFORMS
52
57
  ruby
53
58
 
54
59
  DEPENDENCIES
60
+ codependent!
55
61
  pry
56
62
  pry-byebug
57
63
  rake
data/README.md CHANGED
@@ -114,7 +114,7 @@ Codependent::Manager.container :my_container do
114
114
  # This block is passed to a new container instance and uses the same syntax
115
115
  # we've already seen.
116
116
  instance :logger do
117
- with_constructor { Logger.new }
117
+ from_value Logger.new
118
118
  end
119
119
  end
120
120
 
@@ -131,33 +131,6 @@ Codependent::Manager.reset_container!(:my_container)
131
131
  Codependent::Manager.reset!
132
132
  ```
133
133
 
134
- ### Class Definition Syntax
135
-
136
- ```ruby
137
- # Not everyone wants to configure the container up front. You can define your
138
- # dependencies in your class definitions with the Codependent Helper.
139
- class UserRepository
140
- extend Codependent::Helper
141
-
142
- # Tell Codependent what to call this injectable and how it should be resolved:
143
- singleton :user_repository do
144
- # The syntax here is the same as before.
145
- with_constructor { self.new }
146
- depends_on :logger
147
- end
148
- end
149
-
150
- class Logger
151
- extend Codependent::Helper
152
-
153
- # You can also specify the managed container into which this type should be
154
- # defined:
155
- instance :logger, in_container: :my_container do
156
- with_constructor { self.new }
157
- end
158
- end
159
- ```
160
-
161
134
  ## Developing Codependent
162
135
 
163
136
  ### Building from source
@@ -166,5 +139,5 @@ end
166
139
  2. Install dependencies: `bundle install`
167
140
  3. Run the tests: `bundle exec rake ci`
168
141
  4. Build a local copy of the gem: `gem build codependent.gemspec`
169
- 5. Install the gem locally: `gem install ./Codependent-0.1.gem`
142
+ 5. Install the gem locally: `gem install ./codependent-0.2.gem`
170
143
  6. Don't forget to version-bump the gemspec before publishing!
data/codependent.gemspec CHANGED
@@ -1,11 +1,18 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'codependent'
3
- s.version = '0.2'
4
- s.date = '2017-02-23'
3
+ s.version = '0.3'
4
+ s.date = '2017-02-24'
5
5
  s.summary = "A simple dependency injection library for Ruby."
6
6
  s.authors = ["Joshua Tompkins"]
7
7
  s.email = 'josh@joshtompkins.com'
8
8
  s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
9
9
  s.homepage = 'https://github.com/jtompkins/codependent'
10
10
  s.license = 'MIT'
11
+
12
+ s.add_development_dependency 'rspec'
13
+ s.add_development_dependency 'pry'
14
+ s.add_development_dependency 'pry-byebug'
15
+ s.add_development_dependency 'rake'
16
+ s.add_development_dependency 'rubocop', '~> 0.40.0'
17
+ s.add_development_dependency 'simplecov'
11
18
  end
@@ -50,7 +50,7 @@ module Codependent
50
50
  end
51
51
 
52
52
  def add_injectable!(id, type, config_block)
53
- builder = Codependent::InjectableBuilder.new(type)
53
+ builder = Codependent::InjectableBuilder.new(id, type)
54
54
 
55
55
  builder.instance_eval(&config_block)
56
56
 
@@ -0,0 +1,53 @@
1
+ module Codependent
2
+ module Errors
3
+ class CodependentError < StandardError; end
4
+
5
+ class MissingTypeError < CodependentError
6
+ def message
7
+ 'Type injection requires a type.'
8
+ end
9
+ end
10
+
11
+ class MissingKeywordArgError < CodependentError
12
+ def message
13
+ 'All dependencies must appear as keyword arguments.'
14
+ end
15
+ end
16
+
17
+ class MissingAccessorError < CodependentError
18
+ def message
19
+ 'All dependencies must have accessors.'
20
+ end
21
+ end
22
+
23
+ class NoConstructorArgsError < CodependentError
24
+ def message
25
+ 'No constructor arguments.'
26
+ end
27
+ end
28
+
29
+ class MissingProviderBlockError < CodependentError
30
+ def message
31
+ 'Providers must have a block.'
32
+ end
33
+ end
34
+
35
+ class ValueDependencyError < CodependentError
36
+ def message
37
+ 'Value injectables may not have dependencies.'
38
+ end
39
+ end
40
+
41
+ class NoValueError < CodependentError
42
+ def message
43
+ 'Value injectables must have a value.'
44
+ end
45
+ end
46
+
47
+ class ValueOnInstanceError < CodependentError
48
+ def message
49
+ 'Value injectables cannot be singletons.'
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,4 +1,5 @@
1
1
  require 'codependent/injectable'
2
+ require 'codependent/errors'
2
3
 
3
4
  require 'codependent/validators/value_validator'
4
5
  require 'codependent/validators/provider_validator'
@@ -12,14 +13,15 @@ require 'codependent/resolvers/value_resolver'
12
13
 
13
14
  module Codependent
14
15
  class InjectableBuilder
15
- def initialize(type)
16
+ def initialize(id, type)
17
+ @id = id
16
18
  @type = type
17
19
  @dependencies = []
18
20
  @state = {}
19
21
  @skip_checks = false
20
22
  end
21
23
 
22
- attr_reader :type, :dependencies, :state, :validator, :resolver
24
+ attr_reader :id, :type, :dependencies, :state, :validator, :resolver
23
25
 
24
26
  def from_value(value)
25
27
  @state = { value: value }
@@ -59,9 +61,17 @@ module Codependent
59
61
  def build
60
62
  return unless @validator
61
63
 
62
- @validator.new.(@type, @state, @dependencies) unless @skip_checks
64
+ validate unless @skip_checks
63
65
 
64
66
  Injectable.new(@type, @dependencies, @state, @resolver)
65
67
  end
68
+
69
+ private
70
+
71
+ def validate
72
+ @validator.new.(@type, @state, @dependencies)
73
+ rescue Codependent::Errors::CodependentError => e
74
+ raise "#{e.message} Check the configuration for #{id}."
75
+ end
66
76
  end
67
77
  end
@@ -26,7 +26,8 @@ module Codependent
26
26
 
27
27
  def resolve_eager_dependencies(injectable_ids)
28
28
  injectable_ids.reduce({}) do |acc, id|
29
- acc.merge(id => resolve_value(id, acc))
29
+ next acc if acc.key?(id)
30
+ acc.tap { |hash| hash[id] = resolve_value(id, acc) }
30
31
  end
31
32
  end
32
33
 
@@ -71,9 +72,8 @@ module Codependent
71
72
  current = injectables[stack.pop]
72
73
 
73
74
  current.dependencies.each do |dep_id|
74
- next if dependencies.include?(dep_id)
75
+ stack.push(dep_id) unless dependencies.include?(dep_id)
75
76
  dependencies.unshift(dep_id)
76
- stack.push(dep_id)
77
77
  end
78
78
  end
79
79
 
@@ -1,12 +1,10 @@
1
+ require 'codependent/errors'
2
+
1
3
  module Codependent
2
4
  module Validators
3
5
  class ConstructorInjectionValidator
4
- MISSING_TYPE_ERROR = 'Constructor injection requires a type to be specified.'.freeze
5
- MISSING_DEPENDENCY_KEYWORDS_ERROR = 'All dependencies must appear as keyword arguments to the constructor.'.freeze
6
- NO_ARGS_WITH_DEPENDENCIES_ERROR = 'Constructor injection requires the constructor to receive arguments.'.freeze
7
-
8
6
  def call(_, state, dependencies)
9
- raise MISSING_TYPE_ERROR unless state[:type]
7
+ raise Codependent::Errors::MissingTypeError unless state[:type]
10
8
 
11
9
  return unless dependencies.count > 0
12
10
 
@@ -30,7 +28,7 @@ module Codependent
30
28
  def validate_constructor_params(klass, dependencies)
31
29
  params = klass.instance_method(:initialize).parameters
32
30
 
33
- raise NO_ARGS_WITH_DEPENDENCIES_ERROR if params.count == 0
31
+ raise Codependent::Errors::NoConstructorArgsError if params.count == 0
34
32
 
35
33
  return unless all_keywords?(params)
36
34
 
@@ -38,7 +36,7 @@ module Codependent
38
36
 
39
37
  return if params_for_all_dependencies?(dependencies, parameter_names)
40
38
 
41
- raise MISSING_DEPENDENCY_KEYWORDS_ERROR
39
+ raise Codependent::Errors::MissingKeywordArgError
42
40
  end
43
41
  end
44
42
  end
@@ -1,10 +1,10 @@
1
+ require 'codependent/errors'
2
+
1
3
  module Codependent
2
4
  module Validators
3
5
  class ProviderValidator
4
- NO_BLOCK_ERROR = 'Provider injectables must have a block.'.freeze
5
-
6
6
  def call(_, state, _)
7
- raise NO_BLOCK_ERROR unless state[:provider]
7
+ raise Codependent::Errors::MissingProviderBlockError unless state[:provider]
8
8
  end
9
9
  end
10
10
  end
@@ -1,11 +1,12 @@
1
+ require 'codependent/errors'
2
+
1
3
  module Codependent
2
4
  module Validators
3
5
  class SetterInjectionValidator
4
- MISSING_TYPE_ERROR = 'Setter injection requires a type to be specified.'.freeze
5
6
  MISSING_ACCESSOR_KEYWORDS_ERROR = 'All dependencies must appear as accessors on the class.'.freeze
6
7
 
7
8
  def call(_, state, dependencies)
8
- raise MISSING_TYPE_ERROR unless state[:type]
9
+ raise Codependent::Errors::MissingTypeError unless state[:type]
9
10
 
10
11
  return unless dependencies.count > 0
11
12
 
@@ -17,7 +18,7 @@ module Codependent
17
18
  def validate_setters(klass, dependencies)
18
19
  dependencies.each do |dep_id|
19
20
  unless klass.method_defined? "#{dep_id}=".to_sym
20
- raise MISSING_ACCESSOR_KEYWORDS_ERROR
21
+ raise Codependent::Errors::MissingAccessorError
21
22
  end
22
23
  end
23
24
  end
@@ -1,17 +1,15 @@
1
+ require 'codependent/errors'
2
+
1
3
  module Codependent
2
4
  module Validators
3
5
  class ValueValidator
4
- SINGLETON_ERROR = 'Value injectables are only allowed on singletons.'.freeze
5
- NIL_VALUE_ERROR = 'Value injectables must not be nil.'.freeze
6
- NO_DEPENDENCIES_ERROR = 'Value injectables may not have dependencies'.freeze
7
-
8
6
  def call(type, state, dependencies)
9
- raise SINGLETON_ERROR unless type == :singleton
10
- raise NIL_VALUE_ERROR unless state[:value]
7
+ raise Codependent::Errors::ValueOnInstanceError unless type == :singleton
8
+ raise Codependent::Errors::NoValueError unless state[:value]
11
9
 
12
10
  no_dependencies = !dependencies || dependencies.count != 0
13
11
 
14
- raise NO_DEPENDENCIES_ERROR if no_dependencies
12
+ raise Codependent::Errors::ValueDependencyError if no_dependencies
15
13
  end
16
14
  end
17
15
  end
data/lib/codependent.rb CHANGED
@@ -2,6 +2,7 @@ require 'codependent/manager'
2
2
  require 'codependent/container'
3
3
  require 'codependent/injectable'
4
4
  require 'codependent/injectable_builder'
5
+ require 'codependent/errors'
5
6
 
6
7
  require 'codependent/resolvers/root_resolver'
7
8
  require 'codependent/resolvers/eager_type_resolver'
metadata CHANGED
@@ -1,15 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codependent
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: '0.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Tompkins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-23 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2017-02-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.40.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.40.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
13
97
  description:
14
98
  email: josh@joshtompkins.com
15
99
  executables: []
@@ -29,6 +113,7 @@ files:
29
113
  - codependent.gemspec
30
114
  - lib/codependent.rb
31
115
  - lib/codependent/container.rb
116
+ - lib/codependent/errors.rb
32
117
  - lib/codependent/injectable.rb
33
118
  - lib/codependent/injectable_builder.rb
34
119
  - lib/codependent/manager.rb