alki 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +4 -0
  6. data/Rakefile +29 -0
  7. data/alki.gemspec +24 -0
  8. data/lib/alki/class_builder.rb +41 -0
  9. data/lib/alki/dsl_builder.rb +43 -0
  10. data/lib/alki/group_builder.rb +25 -0
  11. data/lib/alki/group_dsl.rb +98 -0
  12. data/lib/alki/loader.rb +32 -0
  13. data/lib/alki/overlay_delegator.rb +33 -0
  14. data/lib/alki/package.rb +33 -0
  15. data/lib/alki/package_builder.rb +2 -0
  16. data/lib/alki/package_executor.rb +120 -0
  17. data/lib/alki/package_processor.rb +167 -0
  18. data/lib/alki/service_delegator.rb +14 -0
  19. data/lib/alki/standard_package.rb +19 -0
  20. data/lib/alki/test.rb +28 -0
  21. data/lib/alki/util.rb +35 -0
  22. data/lib/alki/version.rb +3 -0
  23. data/lib/alki.rb +27 -0
  24. data/test/feature/create_package_test.rb +17 -0
  25. data/test/fixtures/config.rb +6 -0
  26. data/test/fixtures/example/config/handlers.rb +29 -0
  27. data/test/fixtures/example/config/package.rb +35 -0
  28. data/test/fixtures/example/config/settings.rb +11 -0
  29. data/test/fixtures/example/lib/array_output.rb +11 -0
  30. data/test/fixtures/example/lib/echo_handler.rb +9 -0
  31. data/test/fixtures/example/lib/example.rb +3 -0
  32. data/test/fixtures/example/lib/num_handler.rb +11 -0
  33. data/test/fixtures/example/lib/range_handler.rb +11 -0
  34. data/test/fixtures/example/lib/switch_handler.rb +9 -0
  35. data/test/integration/class_builder_test.rb +130 -0
  36. data/test/integration/loader_test.rb +36 -0
  37. data/test/test_helper.rb +1 -0
  38. data/test/unit/application_settings_test.rb +56 -0
  39. data/test/unit/application_test.rb +159 -0
  40. data/test/unit/package_processor_test.rb +319 -0
  41. metadata +129 -0
@@ -0,0 +1,159 @@
1
+ require_relative '../test_helper'
2
+
3
+ require 'alki/application'
4
+
5
+ describe Alki::Application do
6
+ before do
7
+ @settings = {test: 1}
8
+ @app = Alki::Application.new @settings
9
+ end
10
+
11
+ describe :settings do
12
+ it 'should return settings passed into new' do
13
+ @app.settings.must_be_same_as @settings
14
+ end
15
+ end
16
+
17
+ describe :configure do
18
+ it 'should allow calling methods as a DSL' do
19
+ @app.configure do
20
+ service :test_m do
21
+ :test
22
+ end
23
+ end
24
+ @app.test_m.must_equal :test
25
+ end
26
+ end
27
+
28
+ describe :root do
29
+ it 'should allow extracting the root group from the application' do
30
+ @app.service(:test_m) { :test }
31
+ @app.root.test_m.must_equal :test
32
+ end
33
+ end
34
+
35
+ describe :service do
36
+ it 'should create method that gets result of block' do
37
+ @app.service(:test_m) { :test }
38
+ @app.respond_to?(:test_m).must_equal true
39
+ @app.test_m.must_equal :test
40
+ end
41
+
42
+ it 'generated method should run on demand' do
43
+ count = 0
44
+ @app.service(:test_m){ count += 1; :test }
45
+ count.must_equal 0
46
+ @app.test_m
47
+ count.must_equal 1
48
+ end
49
+
50
+ it 'generated method should run only once' do
51
+ count = 0
52
+ @app.service(:test_m){ count += 1; :test }
53
+ @app.test_m
54
+ @app.test_m
55
+ count.must_equal 1
56
+ end
57
+ end
58
+
59
+ describe :group do
60
+ it 'should create group with block' do
61
+ @app.configure do
62
+ group :g1 do
63
+ end
64
+ end
65
+ @app.g1.wont_be_nil
66
+ end
67
+
68
+ it 'should add services to group' do
69
+ @app.configure do
70
+ group :g1 do
71
+ service(:testm1) { :test1 }
72
+ end
73
+ group :g1 do
74
+ service(:testm2) { :test2 }
75
+ end
76
+ end
77
+ @app.g1.testm1.must_equal :test1
78
+ @app.g1.testm2.must_equal :test2
79
+ end
80
+
81
+ it 'should allow creation of subgroups' do
82
+ @app.configure do
83
+ group :g1 do
84
+ group :g2 do
85
+ service(:test_m) { :test }
86
+ end
87
+ end
88
+ end
89
+ @app.g1.g2.test_m.must_equal :test
90
+ end
91
+
92
+ it 'should allow calling services of parent groups' do
93
+ @app.configure do
94
+ service(:test1) { :test1 }
95
+ group :g1 do
96
+ service(:test2) { :test2 }
97
+ group :g2 do
98
+ service(:test3) { [test1,test2] }
99
+ end
100
+ end
101
+ end
102
+ @app.g1.g2.test3.must_equal [:test1,:test2]
103
+ end
104
+
105
+ it 'should allow aliasing groups' do
106
+ @app.configure do
107
+ group :g1 do
108
+ service(:test_m) { :test }
109
+ end
110
+ end
111
+ @app.group(:g2,@app.g1)
112
+ @app[:g2].test_m.must_equal :test
113
+ end
114
+
115
+ it 'should allow moving groups to other applications' do
116
+ app2 = Alki::Application.new
117
+ app2.service(:test_m) { :test }
118
+ @app.group(:other,app2.root)
119
+ @app.other.test_m.must_equal :test
120
+ end
121
+
122
+ it 'should raise ArgumentError if non-group is provided' do
123
+ assert_raises ArgumentError do
124
+ @app.group(:test, {})
125
+ end
126
+ end
127
+ end
128
+
129
+ describe :lookup do
130
+ it 'should allow lookups of services by string' do
131
+ @app.service(:test_m) { :test }
132
+ @app.lookup('test_m').must_equal :test
133
+ end
134
+
135
+ it 'should allow looking up services in groups using dot separators' do
136
+ @app.configure do
137
+ group :g1 do
138
+ service(:test_m) { :test1 }
139
+ group :g2 do
140
+ service(:test_m) { :test2 }
141
+ end
142
+ end
143
+ end
144
+ @app.lookup('g1.test_m').must_equal :test1
145
+ @app.lookup('g1.g2.test_m').must_equal :test2
146
+ end
147
+ end
148
+
149
+ describe :delegate do
150
+ it 'should allow service reference cycles' do
151
+ @app.configure do
152
+ service(:all) { {print_all: delegate(:print_all)} }
153
+ service(:print_all) { list = all.keys; ->{ p list } }
154
+ end
155
+
156
+ @app.print_all.call.must_equal [:print_all]
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,319 @@
1
+ require_relative '../test_helper'
2
+ require 'alki/package_processor'
3
+
4
+ describe Alki::PackageProcessor do
5
+ def pkg(pkg,overrides ={})
6
+ {
7
+ type: :package,
8
+ children: pkg,
9
+ overrides: overrides
10
+ }
11
+ end
12
+ def group(children={})
13
+ {
14
+ type: :group,
15
+ children: children
16
+ }
17
+ end
18
+ def svc(sym)
19
+ {
20
+ type: :service,
21
+ block: -> { sym }
22
+ }
23
+ end
24
+ def factory(sym)
25
+ {
26
+ type: :factory,
27
+ block: -> { sym }
28
+ }
29
+ end
30
+ before do
31
+ @pe = Alki::PackageProcessor.new
32
+ @pkg1 = {
33
+ a: svc(:orig1_a),
34
+ b: svc(:orig1_b),
35
+ c: group
36
+ }
37
+ @desc = {
38
+ a: group(
39
+ test: svc(:a_test)
40
+ ),
41
+ b: svc(:b),
42
+ test: svc(:test),
43
+ pkg1: pkg(
44
+ @pkg1,
45
+ b: svc(:orig1_b_or)
46
+ )
47
+ }
48
+ end
49
+
50
+ describe :lookup do
51
+ it 'should identify services and return their block and a scope' do
52
+ pkg = {
53
+ a: svc(:a)
54
+ }
55
+ result = @pe.lookup(pkg,[:a])
56
+ result[:type].must_equal :service
57
+ result[:block].call.must_equal :a
58
+ result[:scope].must_be_instance_of Hash
59
+ end
60
+
61
+ it 'should identify factory and return their block and a scope' do
62
+ pkg = {
63
+ a: factory(:a)
64
+ }
65
+ result = @pe.lookup(pkg,[:a])
66
+ result[:type].must_equal :factory
67
+ result[:block].call.must_equal :a
68
+ result[:scope].must_be_instance_of Hash
69
+ end
70
+
71
+ it 'should identify groups and return their children' do
72
+ pkg2 = {
73
+ e: svc(:e)
74
+ }
75
+ pkg = {
76
+ a: svc(:a),
77
+ b: group(
78
+ c: svc(:c),
79
+ d: pkg(
80
+ pkg2,
81
+ f: svc(:f)
82
+ )
83
+ ),
84
+ }
85
+ @pe.lookup(pkg,[]).must_equal(
86
+ type: :group, children: {a: [:a], b: [:b]})
87
+ @pe.lookup(pkg,[:b]).must_equal(
88
+ type: :group, children: {c: [:b,:c],d: [:b,:d]})
89
+ @pe.lookup(pkg,[:b,:d]).must_equal(
90
+ type: :group, children: {e: [:b,:d,:e],f: [:b,:d,:f]})
91
+ @pe.lookup(pkg,[:b,:d,:orig]).must_equal(
92
+ type: :group, children: {e: [:b,:d,:orig,:e]})
93
+ end
94
+ end
95
+
96
+ describe :lookup_scope do
97
+ def scope(pkg,path)
98
+ @pe.lookup(pkg,path)[:scope]
99
+ end
100
+
101
+ it 'should contain a root item for the tree root' do
102
+ pkg = {
103
+ a: svc(:a)
104
+ }
105
+ scope(pkg,[:a]).must_equal(root: [],a: [:a])
106
+ end
107
+
108
+ it 'should return all visible items for the given context' do
109
+ pkg = {
110
+ a: svc(:a),
111
+ b: group(
112
+ c: svc(:c),
113
+ d: svc(:d),
114
+ )
115
+ }
116
+ scope(pkg,[:b,:c]).must_equal(root: [], a: [:a], b: [:b], c: [:b,:c], d: [:b,:d])
117
+ end
118
+
119
+ it 'should respect shadowing of symbols' do
120
+ pkg = {
121
+ a: svc(:a),
122
+ b: group(
123
+ a: svc(:a),
124
+ c: svc(:c),
125
+ )
126
+ }
127
+ scope(pkg,[:b,:c]).must_equal(root: [], a: [:b,:a], b: [:b], c: [:b,:c])
128
+ end
129
+
130
+ it 'should hide parent scope of context is in a package' do
131
+ pkg = {
132
+ a: svc(:a),
133
+ b: pkg(
134
+ c: svc(:c),
135
+ d: svc(:d),
136
+ )
137
+ }
138
+ scope(pkg,[:b,:c]).must_equal(root: [:b], c: [:b,:c], d: [:b,:d])
139
+ end
140
+
141
+ it 'should respect package overrides' do
142
+ pkg2 = {
143
+ c: svc(:c),
144
+ }
145
+ pkg = {
146
+ a: svc(:a),
147
+ b: pkg(
148
+ pkg2,
149
+ d: svc(:d),
150
+ )
151
+ }
152
+ scope(pkg,[:b,:c]).must_equal(root: [:b], c: [:b,:c], d: [:b,:d])
153
+ end
154
+
155
+ it 'should not change root and should add :orig symbol to override contexts' do
156
+ pkg2 = {
157
+ d: svc(:d),
158
+ }
159
+ pkg = {
160
+ a: svc(:a),
161
+ b: pkg(
162
+ pkg2,
163
+ c: svc(:c),
164
+ )
165
+ }
166
+ scope(pkg,[:b,:c]).must_equal(root: [],pkg: [:b,:orig], c: [:b,:c], a: [:a], b: [:b])
167
+ end
168
+
169
+ it 'should respect :orig symbol in path to access non-overriden services' do
170
+ pkg2 = {
171
+ c: svc(:c),
172
+ d: svc(:d),
173
+ }
174
+ pkg = {
175
+ a: svc(:a),
176
+ b: pkg(
177
+ pkg2,
178
+ c: svc(:c),
179
+ )
180
+ }
181
+ scope(pkg,[:b,:orig,:c]).must_equal(root: [:b], c: [:b,:c], d: [:b,:d])
182
+ end
183
+
184
+ it 'should handle nested packages' do
185
+ pkg2 = {
186
+ e: svc(:e),
187
+ }
188
+ pkg = {
189
+ a: svc(:a),
190
+ b: pkg(
191
+ c: svc(:c),
192
+ d: pkg(
193
+ pkg2,
194
+ f: svc(:f),
195
+ )
196
+ )
197
+ }
198
+ scope(pkg,[:b,:d,:e]).must_equal(root: [:b,:d], e: [:b,:d,:e], f: [:b,:d,:f])
199
+ scope(pkg,[:b,:d,:f]).must_equal(root: [:b], pkg: [:b,:d,:orig], d: [:b,:d], c: [:b,:c], f: [:b,:d,:f])
200
+ end
201
+
202
+ it 'should handle nested packages in overrides' do
203
+ pkg2 = {
204
+ c: svc(:c),
205
+ }
206
+ pkg3 = {
207
+ e: svc(:e),
208
+ }
209
+ pkg = {
210
+ a: svc(:a),
211
+ b: pkg(
212
+ pkg2,
213
+ d: pkg(
214
+ pkg3,
215
+ f: svc(:f)
216
+ )
217
+ )
218
+ }
219
+ scope(pkg,[:b,:d,:e]).must_equal(root: [:b,:d], e: [:b,:d,:e], f: [:b,:d,:f])
220
+ end
221
+ end
222
+
223
+ describe :lookup_overlays do
224
+ def overlays(pkg,path)
225
+ @pe.lookup(pkg,path)[:overlays].map{|o| o[:block]}
226
+ end
227
+
228
+ it 'should contain a root item for the tree root' do
229
+ pkg = {
230
+ a: svc(:a)
231
+ }
232
+ overlays(pkg,[:a]).must_equal([])
233
+ end
234
+
235
+ it 'should contain a root item for the tree root2' do
236
+ pkg = {
237
+ 'overlays' => [:o1,:o2],
238
+ a: svc(:a)
239
+ }
240
+ overlays(pkg,[:a]).must_equal([:o1,:o2])
241
+ end
242
+
243
+ it 'should contain a root item for the tree root3' do
244
+ pkg = {
245
+ 'overlays' => [:o1,:o2],
246
+ a: svc(:a),
247
+ b: group(
248
+ 'overlays' => [:o3,:o4],
249
+ c: svc(:c)
250
+ )
251
+ }
252
+ overlays(pkg,[:b,:c]).must_equal([:o1,:o2,:o3,:o4])
253
+ end
254
+
255
+ it 'should contain a root item for the tree root4' do
256
+ pkg = {
257
+ 'overlays' => [:o1],
258
+ a: svc(:a),
259
+ b: pkg(
260
+ 'overlays' => [:o3,:o4],
261
+ c: svc(:c)
262
+ )
263
+ }
264
+ overlays(pkg,[:b,:c]).must_equal([:o1,:o3,:o4])
265
+ end
266
+
267
+ it 'should contain a root item for the tree root5' do
268
+ pkg2 = {
269
+ 'overlays' => [:o3],
270
+ d: svc(:d),
271
+ }
272
+ pkg = {
273
+ 'overlays' => [:o1],
274
+ a: svc(:a),
275
+ b: pkg(pkg2,
276
+ 'overlays' => [:o2],
277
+ c: svc(:c)
278
+ )
279
+ }
280
+ overlays(pkg,[:b,:c]).must_equal([:o1,:o2,:o3])
281
+ overlays(pkg,[:b,:d]).must_equal([:o1,:o2,:o3])
282
+ end
283
+
284
+ it 'should contain a root item for the tree root6' do
285
+ pkg2 = {
286
+ 'overlays' => [:o3],
287
+ d: svc(:d),
288
+ }
289
+ pkg = {
290
+ 'overlays' => [:o1],
291
+ a: svc(:a),
292
+ b: pkg(pkg2,
293
+ 'overlays' => [:clear,:o2],
294
+ c: svc(:c)
295
+ )
296
+ }
297
+ overlays(pkg,[:b,:c]).must_equal([:o2,:o3])
298
+ overlays(pkg,[:b,:d]).must_equal([:o2,:o3])
299
+ end
300
+
301
+ it 'should contain a root item for the tree root7' do
302
+ pkg2 = {
303
+ 'overlays' => [:clear,:o3],
304
+ d: svc(:d),
305
+ }
306
+ pkg = {
307
+ 'overlays' => [:o1],
308
+ a: svc(:a),
309
+ b: pkg(pkg2,
310
+ 'overlays' => [:o2],
311
+ c: svc(:c)
312
+ )
313
+ }
314
+ overlays(pkg,[:b,:c]).must_equal([:o3])
315
+ overlays(pkg,[:b,:d]).must_equal([:o3])
316
+ end
317
+
318
+ end
319
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alki
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Edlefsen
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-10-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Base library for building applications. Provides tools for organizing
42
+ and connection application units.
43
+ email:
44
+ - matt@xforty.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - alki.gemspec
55
+ - lib/alki.rb
56
+ - lib/alki/class_builder.rb
57
+ - lib/alki/dsl_builder.rb
58
+ - lib/alki/group_builder.rb
59
+ - lib/alki/group_dsl.rb
60
+ - lib/alki/loader.rb
61
+ - lib/alki/overlay_delegator.rb
62
+ - lib/alki/package.rb
63
+ - lib/alki/package_builder.rb
64
+ - lib/alki/package_executor.rb
65
+ - lib/alki/package_processor.rb
66
+ - lib/alki/service_delegator.rb
67
+ - lib/alki/standard_package.rb
68
+ - lib/alki/test.rb
69
+ - lib/alki/util.rb
70
+ - lib/alki/version.rb
71
+ - test/feature/create_package_test.rb
72
+ - test/fixtures/config.rb
73
+ - test/fixtures/example/config/handlers.rb
74
+ - test/fixtures/example/config/package.rb
75
+ - test/fixtures/example/config/settings.rb
76
+ - test/fixtures/example/lib/array_output.rb
77
+ - test/fixtures/example/lib/echo_handler.rb
78
+ - test/fixtures/example/lib/example.rb
79
+ - test/fixtures/example/lib/num_handler.rb
80
+ - test/fixtures/example/lib/range_handler.rb
81
+ - test/fixtures/example/lib/switch_handler.rb
82
+ - test/integration/class_builder_test.rb
83
+ - test/integration/loader_test.rb
84
+ - test/test_helper.rb
85
+ - test/unit/application_settings_test.rb
86
+ - test/unit/application_test.rb
87
+ - test/unit/package_processor_test.rb
88
+ homepage: https://gitlab.xforty.com/matt/base-alki
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.5.1
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Base library for building applications.
112
+ test_files:
113
+ - test/feature/create_package_test.rb
114
+ - test/fixtures/config.rb
115
+ - test/fixtures/example/config/handlers.rb
116
+ - test/fixtures/example/config/package.rb
117
+ - test/fixtures/example/config/settings.rb
118
+ - test/fixtures/example/lib/array_output.rb
119
+ - test/fixtures/example/lib/echo_handler.rb
120
+ - test/fixtures/example/lib/example.rb
121
+ - test/fixtures/example/lib/num_handler.rb
122
+ - test/fixtures/example/lib/range_handler.rb
123
+ - test/fixtures/example/lib/switch_handler.rb
124
+ - test/integration/class_builder_test.rb
125
+ - test/integration/loader_test.rb
126
+ - test/test_helper.rb
127
+ - test/unit/application_settings_test.rb
128
+ - test/unit/application_test.rb
129
+ - test/unit/package_processor_test.rb