fabrique 1.0.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b961bd9747ba8e903c3dfcbc00dcada62acfdd9f
4
- data.tar.gz: 9c101248eb91a7ac3012206b663e7f027624905b
3
+ metadata.gz: 2e300f8bf753f7c3087c94db1a3a94bd41e4964c
4
+ data.tar.gz: 9512f2e6bd7d69d8e76f00fa9eb17a63dfd09d9f
5
5
  SHA512:
6
- metadata.gz: e3a43cad0ac1a58530ee750542d330c7f88515cfb02c0b89e66d580ab98f27ff841b8ae9bd5a44b362df855c2b76c2cf1b449c2af692133add744d07c855f93a
7
- data.tar.gz: 2ce1b6c9abeb2d99cad80249a8e13a846951163d3694bdddf3aa458c9b5dfe223b08dabe57d411907f355cba21ac0a36815c67de3247801fc71c85606d0ebdaa
6
+ metadata.gz: ba6d63d716c3d901a3ef209dce4734707e3084a4213b54457d55712b2bd327375a695eb8b99387b681ab3e2d6d8f3f367a86d8b51be2a839f0711168697354b9
7
+ data.tar.gz: 9a289a742376878ed8337acae369aa2aaf8e2e0597491c31448c17db25c2c9338096bf0425ee3801edf30dfc30761c4b3c0fdcedeac9e9658d4f5ac68bae33ac
data/Gemfile CHANGED
@@ -8,6 +8,6 @@ group :development, :test do
8
8
  end
9
9
 
10
10
  group :devtools do
11
- gem "guard-cucumber", "~> 1.6"
12
- gem "byebug", "~> 6.0"
11
+ gem "guard-cucumber", "~> 2.1"
12
+ gem "byebug", "~> 9.0"
13
13
  end
data/README.md CHANGED
@@ -21,7 +21,104 @@ Or install it yourself as:
21
21
 
22
22
  $ gem install fabrique
23
23
 
24
+ ## Testing
25
+
26
+ ```shell
27
+ git clone git@github.com/starjuice/fabrique.git
28
+ cd fabrique
29
+ bundle
30
+ bundle exec rake
31
+ ```
32
+
33
+ The test coverage is superficial at the moment. When working with features/bean_factory.feature,
34
+ keep in mind that some exceptions are caught and stored as instance variables to be evlauated by
35
+ subsequent steps. This avoids some English contortions, but the down side is that if you introduce
36
+ a regression that raises an exception in a scenario that doesn't expect one, you won't see the
37
+ exception. To log exceptions, even when they are expected:
38
+
39
+ ```shell
40
+ DEBUG=1 bundle exec rake
41
+ ```
42
+
24
43
  ## Usage
25
44
 
26
45
  Under construction; hard hat required!
27
46
 
47
+ The best source of documentation of what's possible in the configuration of Fabrique::BeanFactory is currently
48
+ features/bean\_factory.feature. But reading the step definitions for an example of usage would be awkward, so
49
+ here is a code example.
50
+
51
+ Given this example YAML application context definition,
52
+ in a file called application\_context.yml:
53
+
54
+ ```yaml
55
+ ---
56
+ beans:
57
+ - id: customer_repository
58
+ class: Acme::Repository::CustomerRepository
59
+ constructor_args:
60
+ - !bean/ref store
61
+ - !bean/ref customer_data_mapper
62
+ - id: product_repository
63
+ class: Acme::Repository::ProductRepository
64
+ constructor_args:
65
+ store: !bean/ref store
66
+ data_mapper: !bean/ref product_data_mapper
67
+ - id: store
68
+ class: Acme::Repository::MysqlStore
69
+ constructor_args:
70
+ host: localhost
71
+ port: 3306
72
+ gem:
73
+ name: acme-repository-mysql_store
74
+ version: "~> 1.0"
75
+ require: "acme/repository/mysql_store"
76
+ - id: customer_data_mapper
77
+ class: Acme::Repository::MysqlDataMapper::Customer
78
+ gem:
79
+ name: acme-repository-mysql_data_mapper
80
+ require: acme/repository/mysql_data_mapper/customer
81
+ - id: product_data_mapper
82
+ class: Acme::Repository::MysqlDataMapper::Product
83
+ gem:
84
+ name: acme-repository-mysql_data_mapper
85
+ require: acme/repository/mysql_data_mapper/product
86
+ ```
87
+
88
+ Here is how we could materialize these dependencies:
89
+
90
+ ```ruby
91
+ bean_factory = Fabrique::YamlBeanFactory.new(File.read('application_context.yml'))
92
+ bean_factory.load_gem_dependencies
93
+
94
+ customer_service = CustomerService.new(repository: bean_factory.get_bean('customer_repository'))
95
+ product_service = ProductService.new(repository: bean_factory.get_bean('product_repository'))
96
+ store_service = StoreService.new(customers: customer_service, products: product_service)
97
+ # ...
98
+ ```
99
+
100
+ Of course, the construction of these services could just as well have been handled by the
101
+ bean factory as well. Where to draw the line is an interesting topic. The example above draws it
102
+ "at dependencies that could be expected to vary per deployment".
103
+
104
+ Notice that gems were only specified for the parts of the context that could be expected to
105
+ vary per deployment; the gem providing Acme::Repository::CustomerRepository and
106
+ Acme::Repository::ProductRepository would be bundled with the application.
107
+
108
+ Also notice that the gem loader is activated by an explicit call to load\_gem\_dependencies.
109
+ Runtime installation and activation of gems is controversial, and so it must be requested
110
+ explicitly.
111
+
112
+ For a data-centric approach to IoC, the entire set of beans can be materialized as a dictionary
113
+ and made available to consumer to cherry-pick what they need without any awareness of the use
114
+ of a BeanFactory:
115
+
116
+ ```ruby
117
+ bean_factory = Fabrique::YamlBeanFactory.new('application_context.yml')
118
+ bean_factory.load_gem_dependencies
119
+
120
+ # Symbolize keys for use as keyword arguments:
121
+ context = bean_factory.to_h.map { |k, v| [k.intern, v] }.to_h
122
+
123
+ store_service = StoreService.new(context)
124
+ ```
data/fabrique.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ["lib"]
21
21
 
22
22
  spec.add_development_dependency "bundler", "~> 1.7"
23
- spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rake", "~> 11.0"
24
24
  spec.add_development_dependency "rspec", "~> 3.2"
25
25
  spec.add_development_dependency "cucumber", "~> 2.0"
26
26
  end
@@ -466,6 +466,38 @@ Feature: Bean Factory
466
466
  And I request the "local_only" bean from the bean factory
467
467
  Then the bean has "version" set to "0.1.0"
468
468
 
469
+ Scenario: Gem loader with duplicate gem
470
+
471
+ Given I have a YAML application context definition:
472
+ """
473
+ ---
474
+ beans:
475
+ - id: sampler
476
+ class: Fabrique::DataBean
477
+ constructor_args:
478
+ - sample1_version: !bean/property_ref sample1.version
479
+ sample2_version: !bean/property_ref sample2.version
480
+ - id: sample1
481
+ class: Sample
482
+ gem:
483
+ name: sample
484
+ version: "= 0.1.1"
485
+ require: sample
486
+ factory_method: itself
487
+ - id: sample2
488
+ class: Sample
489
+ gem:
490
+ name: sample
491
+ require: sample
492
+ factory_method: itself
493
+ """
494
+ And the "sample" gem is not installed
495
+ When I request a bean factory for the application context
496
+ And I request that bean dependency gems be loaded for the bean factory
497
+ And I request the "sampler" bean from the bean factory
498
+ Then the bean has "sample1_version" set to "0.1.1"
499
+ And the bean has "sample2_version" set to "0.1.1"
500
+
469
501
  Scenario: Gem loader version conflict
470
502
 
471
503
  Given I have a YAML application context definition:
@@ -1,6 +1,7 @@
1
1
  require "tsort"
2
2
  require_relative "bean_definition"
3
3
  require_relative "cyclic_bean_dependency_error"
4
+ require_relative "missing_bean_error"
4
5
 
5
6
  module Fabrique
6
7
 
@@ -12,7 +13,7 @@ module Fabrique
12
13
  end
13
14
 
14
15
  def get_definition(bean_name)
15
- @defs.detect { |d| d.id == bean_name }
16
+ @defs.detect { |d| d.id == bean_name } or raise MissingBeanError.new("missing bean #{bean_name.inspect}")
16
17
  end
17
18
 
18
19
  def get_definitions
@@ -0,0 +1,6 @@
1
+ module Fabrique
2
+
3
+ class MissingBeanError < RuntimeError
4
+ end
5
+
6
+ end
@@ -1,3 +1,3 @@
1
1
  module Fabrique
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe Fabrique::BeanFactory do
4
+
5
+ it "raises a missing bean error when asked for a nonexistent bean" do
6
+ bean_factory = Fabrique::BeanFactory.new(Fabrique::BeanDefinitionRegistry.new([]))
7
+ expect {
8
+ bean_factory.get_bean("nonexistent")
9
+ }.to raise_error Fabrique::MissingBeanError, /nonexistent/
10
+ end
11
+
12
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fabrique
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sheldon Hearn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-16 00:00:00.000000000 Z
11
+ date: 2016-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '11.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '11.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,7 @@ files:
122
122
  - lib/fabrique/gem_definition.rb
123
123
  - lib/fabrique/gem_dependency_error.rb
124
124
  - lib/fabrique/gem_loader.rb
125
+ - lib/fabrique/missing_bean_error.rb
125
126
  - lib/fabrique/test.rb
126
127
  - lib/fabrique/test/fixtures/constructors.rb
127
128
  - lib/fabrique/test/fixtures/modules.rb
@@ -129,6 +130,7 @@ files:
129
130
  - lib/fabrique/test/fixtures/repository.rb
130
131
  - lib/fabrique/version.rb
131
132
  - lib/fabrique/yaml_bean_factory.rb
133
+ - spec/fabrique/bean_factory_spec.rb
132
134
  - spec/fabrique/data_bean_spec.rb
133
135
  - spec/fabrique/yaml_bean_factory_spec.rb
134
136
  - spec/fabrique_spec.rb
@@ -162,7 +164,9 @@ test_files:
162
164
  - features/step_definitions/bean_factory_steps.rb
163
165
  - features/support/byebug.rb
164
166
  - features/support/fabrique.rb
167
+ - spec/fabrique/bean_factory_spec.rb
165
168
  - spec/fabrique/data_bean_spec.rb
166
169
  - spec/fabrique/yaml_bean_factory_spec.rb
167
170
  - spec/fabrique_spec.rb
168
171
  - spec/spec_helper.rb
172
+ has_rdoc: