little_boxes 0.1.0 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,164 @@
1
+ require_relative 'spec_helper'
2
+ require 'benchmark'
3
+ require 'logger'
4
+
5
+ RSpec.describe 'Benchmark the speed', benchmark: true do
6
+ def define_class name, &block
7
+ stub_const(name.to_s, Class.new).tap do |c|
8
+ c.class_eval(&block)
9
+ end
10
+ end
11
+
12
+ def iterations
13
+ 500000
14
+ end
15
+
16
+ def test_name
17
+ @__inspect_output.
18
+ gsub(/^"/,'').
19
+ gsub(/" \([^\(]+\)/,'')
20
+ end
21
+
22
+ def measure
23
+ b = Benchmark.measure{ iterations.times { yield } }
24
+ @results << {name: test_name, time: b.real}
25
+ end
26
+
27
+ before :all do
28
+ @results = []
29
+ end
30
+
31
+ after :all do
32
+ File.open 'tmp/real_benchmarks.log', 'w' do |r|
33
+ @results.sort_by{|res| res[:time] }.each do |res|
34
+ r.puts "#{'%0.4f' % res[:time]}s #{res[:name]}"
35
+ end
36
+ end
37
+
38
+ puts File.read 'tmp/real_benchmarks.log' if ENV['BENCH_OUT']
39
+ end
40
+
41
+ context 'shallow' do
42
+ before do
43
+ define_class :Server do
44
+ include Configurable
45
+
46
+ dependency :logger
47
+ dependency :new_logger
48
+ public :new_logger
49
+ public :logger
50
+ def logger= value
51
+ config[:logger] = value
52
+ end
53
+ end
54
+
55
+ configurable_server = Server.new
56
+
57
+ define_class :MainBox do
58
+ include Box
59
+
60
+ get(:new_logger) { :logger }
61
+ let(:logger) { :logger }
62
+ letc(:server) { Server.new }
63
+ getc(:explicit_server) { Server.new }.then do |s, b|
64
+ s.logger = b.another_logger
65
+ end
66
+ getc(:new_server) { configurable_server }
67
+ let(:another_logger) { :another_logger }
68
+ end
69
+
70
+ define_class :Logger do
71
+ end
72
+ end
73
+
74
+ let(:box) { MainBox.new }
75
+ define_method(:logger) { box.logger }
76
+ define_method(:server) { box.server }
77
+
78
+ it 'measures getting a memoized dependency within the dependant' do
79
+ server = server()
80
+ measure { server.logger }
81
+ end
82
+
83
+ it 'measures getting a dependency within the dependant' do
84
+ server = server()
85
+ measure { server.new_logger }
86
+ end
87
+
88
+ it 'measures config time' do
89
+ box = box()
90
+ measure { box.new_server }
91
+ end
92
+
93
+ it 'measures first dependency injection time' do
94
+ box = box()
95
+ measure { box.new_server.logger }
96
+ end
97
+
98
+ it 'lookup logger in then block' do
99
+ box = box()
100
+ measure { box.explicit_server }
101
+ end
102
+ end
103
+
104
+ context 'deep' do
105
+ before do
106
+ define_class :Server do
107
+ include Configurable
108
+
109
+ def logger= value
110
+ @config[:logger] = value
111
+ end
112
+
113
+ dependency :logger
114
+ dependency :new_logger
115
+ public :new_logger
116
+ public :logger
117
+ end
118
+
119
+ configurable_server = Server.new
120
+
121
+ define_class :MainBox do
122
+ include Box
123
+
124
+ get(:new_logger) { :logger }
125
+ let(:logger) { :logger }
126
+ let(:another_logger) { :another_logger }
127
+
128
+ box(:level) do
129
+ box(:level) do
130
+ box(:level) do
131
+ letc(:server) { Server.new }
132
+ getc(:new_server) { configurable_server }
133
+ getc(:explicit_server) { Server.new }.then do |s, b|
134
+ s.logger = b.another_logger
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ define_class :Logger do
142
+ end
143
+ end
144
+
145
+ let(:box) { MainBox.new }
146
+ define_method(:logger) { box.logger }
147
+ define_method(:server) { box.level.level.level.server }
148
+
149
+ it 'measures config time (deep)' do
150
+ box = box().level.level.level
151
+ measure { box.new_server }
152
+ end
153
+
154
+ it 'measures first dependency injection time (deep)' do
155
+ box = box().level.level.level
156
+ measure { box.new_server.logger }
157
+ end
158
+
159
+ it 'lookup logger in then block (deep)' do
160
+ box = box().level.level.level
161
+ measure { box.explicit_server }
162
+ end
163
+ end
164
+ end
@@ -2,14 +2,32 @@ require 'rubygems'
2
2
  require 'rspec'
3
3
  require 'pry'
4
4
 
5
- RSpec.configure do |config|
6
- config.color = true
7
- config.tty = true
8
- config.formatter = :documentation # :documentation, :progress, :html, :textmate
9
- end
10
-
11
5
  $LOAD_PATH.unshift File.expand_path('lib')
12
6
  require 'little_boxes'
13
7
 
14
8
  $LOAD_PATH.unshift File.expand_path('spec/support')
15
9
 
10
+ module LittleBoxes
11
+ module SpecHelper
12
+ def self.configure_rspec
13
+ RSpec.configure do |c|
14
+ c.color = true
15
+ c.tty = true
16
+ c.formatter = :documentation # :documentation, :progress, :html, :textmate
17
+ c.filter_run_excluding benchmark: !benchmark_enabled?, docs: !docs?
18
+ c.include SpecHelper
19
+ end
20
+ end
21
+
22
+ def self.benchmark_enabled?
23
+ ENV['BENCH'] == "true"
24
+ end
25
+
26
+ def self.docs?
27
+ ENV['DOCS'] == "true"
28
+ end
29
+ end
30
+ end
31
+
32
+ LittleBoxes::SpecHelper.configure_rspec
33
+ include LittleBoxes
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.1.0
4
+ version: 0.3.7
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: 2015-09-07 00:00:00.000000000 Z
11
+ date: 2017-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,35 +38,7 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: forwarding_dsl
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
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: mini_object
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- description: Dependancy injection framework in Ruby.
41
+ description: Dependency injection library in Ruby.
70
42
  email:
71
43
  - _Development@workshare.com
72
44
  executables: []
@@ -80,19 +52,20 @@ files:
80
52
  - Rakefile
81
53
  - lib/little_boxes.rb
82
54
  - lib/little_boxes/box.rb
83
- - lib/little_boxes/defined_dependant.rb
84
- - lib/little_boxes/dependant.rb
85
- - lib/little_boxes/dependant_registry.rb
86
- - lib/little_boxes/memoized_dependant.rb
87
- - lib/little_boxes/null_logger.rb
88
- - lib/little_boxes/obtained.rb
89
- - lib/little_boxes/registry.rb
55
+ - lib/little_boxes/configurable.rb
56
+ - lib/little_boxes/entry.rb
57
+ - lib/little_boxes/entry_definition.rb
58
+ - lib/little_boxes/strategy.rb
90
59
  - lib/little_boxes/version.rb
91
60
  - little_boxes.gemspec
61
+ - spec/benchmarks_spec.rb
62
+ - spec/docs/readme_spec.rb
63
+ - spec/integration/thread_safety_spec.rb
92
64
  - spec/little_boxes/box_spec.rb
93
- - spec/little_boxes/dependant_spec.rb
94
65
  - spec/little_boxes_spec.rb
66
+ - spec/real_benchmarks_spec.rb
95
67
  - spec/spec_helper.rb
68
+ - tmp/.gitkeep
96
69
  homepage: https://github.com/worshare/little-boxes
97
70
  licenses:
98
71
  - Copyright
@@ -116,10 +89,13 @@ rubyforge_project:
116
89
  rubygems_version: 2.2.2
117
90
  signing_key:
118
91
  specification_version: 4
119
- summary: Dependancy injection framework in Ruby.
92
+ summary: Dependency injection library in Ruby.
120
93
  test_files:
94
+ - spec/benchmarks_spec.rb
95
+ - spec/docs/readme_spec.rb
96
+ - spec/integration/thread_safety_spec.rb
121
97
  - spec/little_boxes/box_spec.rb
122
- - spec/little_boxes/dependant_spec.rb
123
98
  - spec/little_boxes_spec.rb
99
+ - spec/real_benchmarks_spec.rb
124
100
  - spec/spec_helper.rb
125
101
  has_rdoc:
@@ -1,9 +0,0 @@
1
- module LittleBoxes
2
- class DefinedDependant
3
- include DependantRegistry
4
-
5
- def get
6
- run
7
- end
8
- end
9
- end
@@ -1,44 +0,0 @@
1
- require 'mini_object'
2
-
3
- module LittleBoxes
4
- module Dependant
5
- module ClassMethods
6
- def dependency name, opts = {}
7
- instance_dependencies[name] = opts
8
- attr_injectable name
9
- end
10
-
11
- def class_dependency name, opts = {}
12
- class_dependencies[name] = opts
13
- cattr_injectable name
14
- end
15
-
16
- def instance_dependencies
17
- @instance_dependencies ||= {}
18
- end
19
-
20
- def class_dependencies
21
- @class_dependencies ||= {}
22
- end
23
-
24
- def dependencies
25
- class_dependencies
26
- end
27
-
28
- def inherited klass
29
- klass.class_dependencies.merge! class_dependencies
30
- klass.instance_dependencies.merge! instance_dependencies
31
- super
32
- end
33
- end
34
-
35
- def self.included klass
36
- klass.extend ClassMethods
37
- klass.include MiniObject::Injectable
38
- end
39
-
40
- def dependencies
41
- self.class.instance_dependencies
42
- end
43
- end
44
- end
@@ -1,44 +0,0 @@
1
- module LittleBoxes
2
- module DependantRegistry
3
- def self.included base
4
- base.class_eval do
5
- include Registry
6
- attr_accessor :build_block
7
-
8
- def initialize name: nil, parent: parent, &block
9
- @build_block = block
10
- @name = name
11
- @parent = parent
12
- end
13
- end
14
- end
15
-
16
- def get
17
- raise NotImplementedError
18
- end
19
-
20
- def build &block
21
- @build_block = block
22
- end
23
-
24
- def get_dependency name, options = nil
25
- options ||= {}
26
-
27
- if d = self[name]; d.get
28
- elsif s = options[:default]; s.call parent
29
- else raise(MissingDependency.new "Could not find #{name}")
30
- end
31
- end
32
-
33
- private
34
- def run
35
- ForwardingDsl.run(self, &build_block).tap do |subject|
36
- if subject.respond_to? :dependencies
37
- subject.dependencies.each do |name, options|
38
- subject.send("#{name}"){ get_dependency(name, options) }
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,9 +0,0 @@
1
- module LittleBoxes
2
- class MemoizedDependant
3
- include DependantRegistry
4
-
5
- def get
6
- @value ||= run
7
- end
8
- end
9
- end
@@ -1,8 +0,0 @@
1
- require 'logger'
2
-
3
- module LittleBoxes
4
- class NullLogger < Logger
5
- def initialize; end
6
- def add(*args); end
7
- end
8
- end
@@ -1,13 +0,0 @@
1
- module LittleBoxes
2
- class Obtained
3
- include DependantRegistry
4
-
5
- def get
6
- run
7
- end
8
-
9
- def get
10
- ForwardingDsl.run(self, &build_block)
11
- end
12
- end
13
- end
@@ -1,84 +0,0 @@
1
- require 'forwarding_dsl'
2
-
3
- module LittleBoxes
4
- module Registry
5
- attr_accessor :parent
6
- attr_accessor :name
7
-
8
- def initialize parent: nil, name: self.class, &block
9
- @parent = parent
10
- @name = name
11
- ForwardingDsl.run self, &block
12
- end
13
-
14
- def registry
15
- @registry ||= {}
16
- end
17
-
18
- def method_missing name, *args, &block
19
- if self[name]
20
- self[name].get
21
- else
22
- super
23
- end
24
- end
25
-
26
- def respond_to_missing? name, *args
27
- !!self[name] || super
28
- end
29
-
30
- def [] name
31
- registry[name] || (parent && parent[name])
32
- end
33
-
34
- def []= name, value
35
- registry[name]= value
36
- end
37
-
38
- def clear
39
- @registry = {}
40
- end
41
-
42
- def let name, &block
43
- self[name] = MemoizedDependant.new name: name, parent: self, &block
44
- end
45
-
46
- def define name, &block
47
- self[name] = DefinedDependant.new name: name, parent: self, &block
48
- end
49
-
50
- def obtain name, &block
51
- self[name] = Obtained.new name: name, parent: self, &block
52
- end
53
-
54
- def inspect
55
- "<#{name} box: #{registry.keys.join(" ")}>"
56
- end
57
-
58
- alias to_s inspect
59
-
60
- def name
61
- @name || self.class.name
62
- end
63
-
64
- def path
65
- if parent
66
- parent.path + [self]
67
- else
68
- [self]
69
- end
70
- end
71
-
72
- def root
73
- path.first
74
- end
75
-
76
- def reset
77
- @value = nil
78
-
79
- registry.each do |name, register|
80
- register.reset
81
- end
82
- end
83
- end
84
- end