little_boxes 0.4.0 → 0.5.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: 77465da04002cee545af36aa985b38e7d875aed8
4
- data.tar.gz: cf45d61cd79aa7d4680196e00b62694a107123e1
3
+ metadata.gz: 1760a38a874d4cac46e07b4fe51c57f74ac4f0a2
4
+ data.tar.gz: bb94c00e8e67f6895eb2202a2b828647691a6c46
5
5
  SHA512:
6
- metadata.gz: 4c98743e0199a8637bad9bf293328ab8a8beb1a7df8d5a04b1447242aa6a92598ee418e201634df60ce50f38ec755e23c5fe05b403efb1745ee7c34392b37ab2
7
- data.tar.gz: a0cd7179defeec69b51e3cbd7318552d562bbb129d5cfa7693b84ab171a67d52a1079374202dae593a6c276ae70adec2ccb7db38b0bb50246ee219a45126aeae
6
+ metadata.gz: 6d0e22e9cb55af101a0f235e2ff6a93f8cbcae15d9595e38c9f1d0c9f605de43baa808a3a6da324e396ff8592fcb71b2c8a4b9d8cb870b6bcab07cd3289acb43
7
+ data.tar.gz: a54f0f7790d45b98ee9621ddc35c8d137a68a76858a8a54c9f0d67ffc555e057af210d3e5aac2d426a40741811903f2f4fe449cd8a3532a2c5ae362401c0ba40
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.4.0
4
+ - 2.3.3
5
+ - 2.2.4
6
+ - 2.1.10
7
+ cache: bundler
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # LittleBoxes
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/little_boxes.svg)](http://badge.fury.io/rb/little_boxes)
4
+ [![Build Status](https://travis-ci.org/manuelmorales/little-boxes.svg?branch=master)](https://travis-ci.org/manuelmorales/little-boxes)
5
+ [![Code Climate](https://codeclimate.com/github/manuelmorales/little-boxes/badges/gpa.svg)](https://codeclimate.com/github/manuelmorales/little-boxes)
6
+
3
7
  Dependency injection library in Ruby.
4
8
 
5
9
  ## Intro
@@ -1,3 +1,5 @@
1
+ require 'pathname'
2
+
1
3
  module LittleBoxes
2
4
  def self.root_path
3
5
  Pathname.new(__FILE__) + '../..'
@@ -41,6 +41,8 @@ module LittleBoxes
41
41
  Class.new do
42
42
  include ::LittleBoxes::Box
43
43
 
44
+ define_singleton_method(:name) { "Box[#{name}]" }
45
+
44
46
  instance_eval(&block)
45
47
  end.new(parent: box)
46
48
  end
@@ -1,70 +1,8 @@
1
1
  module LittleBoxes
2
2
  module Configurable
3
- attr_accessor :config
4
-
5
- def initialize(options = {})
6
- @config = {}
7
-
8
- options.keys.each do |k|
9
- config[k] = options[k]
10
- end
11
- end
12
-
13
- def configure(&block)
14
- yield @config
15
- self
16
- end
17
-
18
- private
19
-
20
3
  def self.included(klass)
21
- klass.extend ClassMethods
22
-
23
- klass.class_eval do
24
- class << self
25
- attr_accessor :config
26
- instance_variable_set :@config, {}
27
- end
28
- end
29
- end
30
-
31
- module ClassMethods
32
- def dependency name, &default_block
33
- default_block ||= Proc.new do
34
- fail(DependencyNotFound, "Dependency #{name} not found")
35
- end
36
-
37
- private
38
-
39
- define_method name do
40
- @config[name] ||= default_block.call(@config[:box])
41
- end
42
-
43
- define_method "#{name}=" do |value|
44
- @config[name] = value
45
- end
46
- end
47
-
48
- def class_dependency name, &default_block
49
- default_block ||= Proc.new do
50
- fail(DependencyNotFound, "Dependency #{name} not found")
51
- end
52
-
53
- private
54
-
55
- define_singleton_method name do
56
- @config[name] ||= default_block.call(@config[:box])
57
- end
58
-
59
- define_method name do
60
- self.class.config[name] ||= default_block.call(self.class.config[:box])
61
- end
62
- end
63
-
64
- def configure(&block)
65
- yield @config
66
- self
67
- end
4
+ klass.include Dependant
5
+ klass.include Initializable
68
6
  end
69
7
  end
70
8
  end
@@ -0,0 +1,71 @@
1
+ module LittleBoxes
2
+ module Dependant
3
+ attr_accessor :config
4
+
5
+ def initialize(*args)
6
+ @config = {}
7
+ super
8
+ end
9
+
10
+ def configure(&block)
11
+ yield @config
12
+ self
13
+ end
14
+
15
+ private
16
+
17
+ def self.included(klass)
18
+ klass.extend ClassMethods
19
+ end
20
+
21
+ module ClassMethods
22
+ def self.extended(base)
23
+ base.class_eval do
24
+ class << self
25
+ attr_accessor :config
26
+ instance_variable_set :@config, {}
27
+ end
28
+ end
29
+ end
30
+
31
+ def dependency name, &default_block
32
+ default_block ||= Proc.new do
33
+ fail(DependencyNotFound, "Dependency #{name} not found")
34
+ end
35
+
36
+ define_method name do
37
+ @config[name] ||= default_block.call(@config[:box])
38
+ end
39
+
40
+ define_method "#{name}=" do |value|
41
+ @config[name] = value
42
+ end
43
+ end
44
+
45
+ def class_dependency name, &default_block
46
+ default_block ||= Proc.new do
47
+ fail(DependencyNotFound, "Dependency #{name} not found")
48
+ end
49
+
50
+ @config ||= {}
51
+
52
+ define_singleton_method name do
53
+ @config[name] ||= default_block.call(@config[:box])
54
+ end
55
+
56
+ define_singleton_method "#{name}=" do |value|
57
+ @config[name] = value
58
+ end
59
+
60
+ define_method name do
61
+ self.class.config[name] ||= default_block.call(self.class.config[:box])
62
+ end
63
+ end
64
+
65
+ def configure(&block)
66
+ yield @config
67
+ self
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,11 @@
1
+ module LittleBoxes
2
+ module Initializable
3
+ def initialize(options = {})
4
+ @config = {}
5
+
6
+ options.keys.each do |k|
7
+ config[k] = options[k]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -3,65 +3,17 @@ module LittleBoxes
3
3
  module_function
4
4
 
5
5
  def for(block, memo: false, configure: false, then_block: nil)
6
- case [memo, configure, !!then_block]
7
- when [true, true, true]
8
- memo_configure_then(block, then_block)
9
- when [true, true, false]
10
- memo_configure(block)
11
- when [true, false, true]
12
- memo_then(block, then_block)
13
- when [true, false, false]
14
- memo(block)
15
- when [false, true, true]
16
- configure_then(block, then_block)
17
- when [false, true, false]
18
- configure(block)
19
- when [false, false, true]
20
- then_block(block, then_block)
21
- else
22
- default(block)
23
- end
24
- end
25
-
26
- def memo_configure(block)
27
- value = nil
28
- -> (bx) { value ||= do_configure(block.call(bx), bx) }
29
- end
30
-
31
- def memo_then(block, then_block)
32
- value = nil
33
- -> (bx) { value ||= block.call(bx).tap { |v| then_block.call v, bx } }
34
- end
35
-
36
- def memo_configure_then(block, then_block)
37
- value = nil
38
- -> (bx) do
39
- value ||= do_configure(block.call(bx), bx)
40
- .tap{ |v| then_block.call v, bx }
41
- end
42
- end
43
-
44
- def memo(block)
45
- value = nil
46
- -> (bx) { value ||= block.call(bx) }
47
- end
48
-
49
- def configure(block)
50
- -> (bx) { do_configure(block.call(bx), bx) }
51
- end
6
+ code = "block.call(bx)"
7
+ code = "do_configure(#{code}, bx)" if configure
8
+ code = "#{code}.tap { |v| then_block.call v, bx }" if then_block
52
9
 
53
- def then_block(block, then_block)
54
- -> (bx) { block.call(bx).tap { |v| then_block.call v, bx } }
55
- end
56
-
57
- def configure_then(block, then_block)
58
- -> (bx) do
59
- do_configure(block.call(bx), bx).tap{ |v| then_block.call v, bx }
10
+ if memo
11
+ code = "value = nil; ->(bx) { value ||= #{code} }"
12
+ else
13
+ code = "->(bx) { #{code} }"
60
14
  end
61
- end
62
15
 
63
- def default(block)
64
- block
16
+ eval code
65
17
  end
66
18
 
67
19
  def do_configure(subject, box)
@@ -1,3 +1,3 @@
1
1
  module LittleBoxes
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -244,6 +244,12 @@ RSpec.describe 'Box' do
244
244
  expect(box).not_to receive(:logger)
245
245
  box
246
246
  end
247
+
248
+ it 'can be reconfigured' do
249
+ http_client.logger = :new_logger
250
+
251
+ expect(http_client.logger).to be :new_logger
252
+ end
247
253
  end
248
254
 
249
255
  describe 'api_client (configured eager loading)' do
@@ -292,6 +298,10 @@ RSpec.describe 'Box' do
292
298
  box
293
299
  expect(rest_client.logger).to be logger
294
300
  end
301
+
302
+ it 'has a name' do
303
+ expect(box.files.inspect).to match(/files/)
304
+ end
295
305
  end
296
306
  end
297
307
 
@@ -0,0 +1,28 @@
1
+ require_relative '../spec_helper'
2
+
3
+ RSpec.describe 'Configurable' do
4
+ it 'provides the Dependant functionality' do
5
+ define_class :Server do
6
+ include Configurable
7
+ dependency :instance_dependency
8
+ class_dependency :class_dependency
9
+ end
10
+
11
+ Server.class_dependency = :class_dep
12
+ expect(Server.class_dependency).to be :class_dep
13
+
14
+ server = Server.new
15
+ server.instance_dependency = :instance_dep
16
+ expect(server.instance_dependency).to be :instance_dep
17
+ end
18
+
19
+ it 'provides the Initializable functionality' do
20
+ define_class :Server do
21
+ include Configurable
22
+ dependency :instance_dependency
23
+ end
24
+
25
+ server = Server.new instance_dependency: :instance_dep
26
+ expect(server.instance_dependency).to be :instance_dep
27
+ end
28
+ end
@@ -0,0 +1,130 @@
1
+ require_relative '../spec_helper'
2
+
3
+ RSpec.describe 'Dependant' do
4
+ describe 'dependency' do
5
+ it 'provides getter and setter' do
6
+ define_class :Server do
7
+ include Dependant
8
+ dependency :logger
9
+ end
10
+
11
+ server = Server.new
12
+ server.logger = :the_logger
13
+
14
+ expect(server.logger).to be :the_logger
15
+ end
16
+
17
+ it 'allows configuring by #configure' do
18
+ define_class :Server do
19
+ include Dependant
20
+ dependency :logger
21
+ end
22
+
23
+ server = Server.new
24
+
25
+ server.configure do |c|
26
+ c[:logger] = :the_logger
27
+ end
28
+
29
+ expect(server.logger).to be :the_logger
30
+ end
31
+
32
+ it 'accepts default values' do
33
+ define_class :Server do
34
+ include Dependant
35
+ dependency(:logger) { :the_logger }
36
+ end
37
+
38
+ server = Server.new
39
+
40
+ expect(server.logger).to be :the_logger
41
+ end
42
+
43
+ it 'passes the box to the default lambda' do
44
+ define_class :Server do
45
+ include Dependant
46
+ dependency(:logger) { |box| box }
47
+ end
48
+
49
+ server = Server.new
50
+
51
+ server.configure do |c|
52
+ c[:box] = :the_box
53
+ end
54
+
55
+ expect(server.logger).to be :the_box
56
+ end
57
+ end
58
+
59
+ describe 'class_dependency' do
60
+ it 'provides getter and setter' do
61
+ define_class :Server do
62
+ include Dependant
63
+ class_dependency :logger
64
+ end
65
+
66
+ Server.logger = :the_logger
67
+
68
+ expect(Server.logger).to be :the_logger
69
+ end
70
+
71
+ it 'allows configuring by #configure' do
72
+ define_class :Server do
73
+ include Dependant
74
+ class_dependency :logger
75
+ end
76
+
77
+ Server.configure do |c|
78
+ c[:logger] = :the_logger
79
+ end
80
+
81
+ expect(Server.logger).to be :the_logger
82
+ end
83
+
84
+ it 'accepts default values' do
85
+ define_class :Server do
86
+ include Dependant
87
+ class_dependency(:logger) { :the_logger }
88
+ end
89
+
90
+ expect(Server.logger).to be :the_logger
91
+ end
92
+
93
+ it 'passes the box to the default lambda' do
94
+ define_class :Server do
95
+ include Dependant
96
+ class_dependency(:logger) { |box| box }
97
+ end
98
+
99
+ Server.configure do |c|
100
+ c[:box] = :the_box
101
+ end
102
+
103
+ expect(Server.logger).to be :the_box
104
+ end
105
+ end
106
+
107
+ it 'respects original initializer' do
108
+ define_class :ServerBase do
109
+ attr_accessor :given_args
110
+ attr_accessor :changed_on_yield
111
+
112
+ def initialize(*args)
113
+ @given_args = args
114
+
115
+ yield self
116
+ end
117
+ end
118
+
119
+ define_class :Server, ServerBase do
120
+ include Dependant
121
+ end
122
+
123
+ server = Server.new(:some_args) do |s|
124
+ s.changed_on_yield = true
125
+ end
126
+
127
+ expect(server.given_args).to eq [:some_args]
128
+ expect(server.changed_on_yield).to be true
129
+ end
130
+ end
@@ -0,0 +1,21 @@
1
+ require_relative '../spec_helper'
2
+
3
+ RSpec.describe 'Initializable' do
4
+ before :each do
5
+ define_class :User do
6
+ include Initializable
7
+ include Configurable
8
+
9
+ dependency :age
10
+ end
11
+ end
12
+
13
+ it 'allows configuring attributes in initialize' do
14
+ user = User.new age: 24
15
+ expect(user.age).to be 24
16
+ end
17
+
18
+ it 'allows initializing with no args' do
19
+ expect { User.new }.not_to raise_error
20
+ end
21
+ end
@@ -0,0 +1,65 @@
1
+ require_relative '../spec_helper'
2
+ require 'redis'
3
+
4
+ RSpec.describe 'Use cases' do
5
+ it 'does memoization with #let' do
6
+ define_class :MainBox do
7
+ include LittleBoxes::Box
8
+ let(:redis) { require 'redis'; Redis.new }
9
+ end
10
+
11
+ box = MainBox.new
12
+
13
+ expect(box.redis).to be_a Redis
14
+ expect(box.redis).to be box.redis
15
+ end
16
+
17
+ it 'does automatic configuration with letc' do
18
+ define_class :Publisher do
19
+ include LittleBoxes::Configurable
20
+ dependency :redis
21
+ end
22
+
23
+ define_class :MainBox do
24
+ include LittleBoxes::Box
25
+ let(:redis) { require 'redis'; Redis.new }
26
+ letc(:publisher) { Publisher.new }
27
+ end
28
+
29
+ box = MainBox.new
30
+ expect(box.publisher.redis).to be box.redis
31
+ end
32
+
33
+ it 'supports default values' do
34
+ define_class :Repo do
35
+ include LittleBoxes::Configurable
36
+ dependency(:store) { Hash.new }
37
+ end
38
+
39
+ define_class :MainBox do
40
+ include LittleBoxes::Box
41
+ letc(:repo) { Repo.new }
42
+ end
43
+
44
+ box = MainBox.new
45
+ expect(box.repo.store).to be_a Hash
46
+ end
47
+
48
+ it 'supports default values that use the box' do
49
+ define_class :Repo do
50
+ include LittleBoxes::Configurable
51
+ dependency(:log) { |box| box.logger }
52
+ end
53
+
54
+ define_class(:Logger) { }
55
+
56
+ define_class :MainBox do
57
+ include LittleBoxes::Box
58
+ let(:logger) { Logger.new }
59
+ letc(:repo) { Repo.new }
60
+ end
61
+
62
+ box = MainBox.new
63
+ expect(box.repo.log).to be box.logger
64
+ end
65
+ end
@@ -6,6 +6,7 @@ $LOAD_PATH.unshift File.expand_path('lib')
6
6
  require 'little_boxes'
7
7
 
8
8
  $LOAD_PATH.unshift File.expand_path('spec/support')
9
+ require 'class_support'
9
10
 
10
11
  module LittleBoxes
11
12
  module SpecHelper
@@ -16,6 +17,7 @@ module LittleBoxes
16
17
  c.formatter = :documentation # :documentation, :progress, :html, :textmate
17
18
  c.filter_run_excluding benchmark: !benchmark_enabled?, docs: !docs?
18
19
  c.include SpecHelper
20
+ c.include ClassSupport
19
21
  end
20
22
  end
21
23
 
@@ -0,0 +1,11 @@
1
+ module LittleBoxes
2
+ module SpecHelper
3
+ module ClassSupport
4
+ def define_class name, base = Object, &block
5
+ stub_const(name.to_s, Class.new(base)).tap do |c|
6
+ c.class_eval(&block)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module LittleBoxes
2
+ # Fake Redis stub for testing
3
+ class Redis
4
+ end
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: little_boxes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Workshare's dev team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-20 00:00:00.000000000 Z
11
+ date: 2017-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description: Dependency injection library in Ruby.
41
+ description: "[![Gem Version](https://badge.fury.io/rb/little_boxes.svg)](http://badge.fury.io/rb/little_boxes)"
42
42
  email:
43
43
  - _Development@workshare.com
44
44
  executables: []
@@ -46,6 +46,7 @@ extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
48
  - ".gitignore"
49
+ - ".travis.yml"
49
50
  - Gemfile
50
51
  - LICENSE.txt
51
52
  - README.md
@@ -53,8 +54,10 @@ files:
53
54
  - lib/little_boxes.rb
54
55
  - lib/little_boxes/box.rb
55
56
  - lib/little_boxes/configurable.rb
57
+ - lib/little_boxes/dependant.rb
56
58
  - lib/little_boxes/entry.rb
57
59
  - lib/little_boxes/entry_definition.rb
60
+ - lib/little_boxes/initializable.rb
58
61
  - lib/little_boxes/strategy.rb
59
62
  - lib/little_boxes/version.rb
60
63
  - little_boxes.gemspec
@@ -62,9 +65,15 @@ files:
62
65
  - spec/docs/readme_spec.rb
63
66
  - spec/integration/thread_safety_spec.rb
64
67
  - spec/little_boxes/box_spec.rb
68
+ - spec/little_boxes/configurable_spec.rb
69
+ - spec/little_boxes/dependant_spec.rb
70
+ - spec/little_boxes/initializable_spec.rb
71
+ - spec/little_boxes/use_cases_spec.rb
65
72
  - spec/little_boxes_spec.rb
66
73
  - spec/real_benchmarks_spec.rb
67
74
  - spec/spec_helper.rb
75
+ - spec/support/class_support.rb
76
+ - spec/support/redis.rb
68
77
  - tmp/.gitkeep
69
78
  homepage: https://github.com/worshare/little-boxes
70
79
  licenses:
@@ -89,13 +98,19 @@ rubyforge_project:
89
98
  rubygems_version: 2.2.2
90
99
  signing_key:
91
100
  specification_version: 4
92
- summary: Dependency injection library in Ruby.
101
+ summary: "[![Gem Version](https://badge.fury.io/rb/little_boxes.svg)](http://badge.fury.io/rb/little_boxes)"
93
102
  test_files:
94
103
  - spec/benchmarks_spec.rb
95
104
  - spec/docs/readme_spec.rb
96
105
  - spec/integration/thread_safety_spec.rb
97
106
  - spec/little_boxes/box_spec.rb
107
+ - spec/little_boxes/configurable_spec.rb
108
+ - spec/little_boxes/dependant_spec.rb
109
+ - spec/little_boxes/initializable_spec.rb
110
+ - spec/little_boxes/use_cases_spec.rb
98
111
  - spec/little_boxes_spec.rb
99
112
  - spec/real_benchmarks_spec.rb
100
113
  - spec/spec_helper.rb
114
+ - spec/support/class_support.rb
115
+ - spec/support/redis.rb
101
116
  has_rdoc: