skn_utils 5.0.2 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/lib/skn_container.rb +54 -63
- data/lib/skn_failure.rb +10 -9
- data/lib/skn_registry.rb +117 -0
- data/lib/skn_success.rb +10 -9
- data/lib/skn_utils/configuration.rb +1 -1
- data/lib/skn_utils/version.rb +2 -2
- data/lib/skn_utils.rb +1 -0
- data/spec/lib/skn_utils/container_spec.rb +10 -9
- data/spec/lib/skn_utils/registry_spec.rb +130 -0
- data/spec/lib/skn_utils/success_failure_value_container_spec.rb +86 -0
- metadata +7 -6
- data/spec/lib/skn_utils/failure_spec.rb +0 -67
- data/spec/lib/skn_utils/success_spec.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4532c0129c738d77525a2c540cf7d6bdba464b29
|
4
|
+
data.tar.gz: f6fd9d50967810320042a7ceea023164082beeec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e784b05da136b62ccb2920d8449bb1258c1415c7d550ca2e5094c26697f01407b891b769e2d0ce094b72b36ae8171b1d3195a589f7a11f942ec15db4073bf67
|
7
|
+
data.tar.gz: a8ecfb811398cdde7a2aa029478f50358d99585ddcfbfe00ee9a9de5d9686607d4a0436a03c62d4e917c6c2694d4ffb97800e8ec8343094760633d7f9be2ab65
|
data/README.md
CHANGED
@@ -49,6 +49,7 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
|
|
49
49
|
* SknUtils::Configurable
|
50
50
|
* SknUtils::EnvStringHandler
|
51
51
|
* SknContainer
|
52
|
+
* SknRegistry
|
52
53
|
* SknHash
|
53
54
|
* SknUtils::NestedResult
|
54
55
|
* SknUtils::ResultBean
|
@@ -57,6 +58,11 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
|
|
57
58
|
* SknUtils::CoreObjectExtensions
|
58
59
|
|
59
60
|
## History
|
61
|
+
10/13/2018 V5.1.0
|
62
|
+
Added SknRegistry to handle service and handler registrations.
|
63
|
+
- Command.class => CommandHandler.class/instance container
|
64
|
+
- Replaces SknContainer
|
65
|
+
|
60
66
|
10/12/2018 V5.0.1
|
61
67
|
Added SknSuccess/SknFailure as value object to carry return codes vs exceptions
|
62
68
|
Modified Configurable to mimic Rails.env, Rails.root, and Rails.logger
|
data/lib/skn_container.rb
CHANGED
@@ -1,78 +1,69 @@
|
|
1
1
|
# ##
|
2
|
+
# ##
|
3
|
+
# SknContainer
|
4
|
+
# - Key/Value Container where keys and/or values can be any valid Ruby Class, Proc, Instance, or object.
|
2
5
|
#
|
3
6
|
# Credits: Inspired by: andyholland1991@aol.com, http://cv.droppages.com
|
4
7
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# { name: 'Jack' }
|
8
|
-
# end
|
9
|
-
# end
|
8
|
+
# Syntax:
|
9
|
+
# SknContainer is a pre-initialized global singleton
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# end
|
15
|
-
# end
|
11
|
+
# - Methods:
|
12
|
+
# self_chain = SknContainer.register(key, content, options={}, &block)
|
13
|
+
# content = SknContainer.resolve(key, render_proc=true)
|
16
14
|
#
|
17
|
-
|
15
|
+
# - Method Params:
|
16
|
+
# key - anyThing can be used as the key
|
17
|
+
# content - anyThing can be used as value; Class, Proc, instance, value
|
18
|
+
# options - hash of dependencies to pass into procs when rendering
|
19
|
+
# &block - block used for #content; with/without a parameter. ex: {|parm| ...} | { ... }
|
20
|
+
# render_proc - bool: when #content is_a Proc, should it be #call()'ed before being returned
|
18
21
|
#
|
19
|
-
# SknContainer.register(:user_repository, UserRepository)
|
20
|
-
# -- or --
|
21
|
-
# SknContainer.register(:user_repository, UserRepository, call: false )
|
22
22
|
#
|
23
|
-
#
|
23
|
+
# ## Examples
|
24
24
|
#
|
25
|
-
|
25
|
+
# class Person
|
26
|
+
# attr_reader :first, :last
|
27
|
+
# def initialize(names={})
|
28
|
+
# self.first = names[:first]
|
29
|
+
# self.last = names[:last]
|
30
|
+
# end
|
31
|
+
# def name
|
32
|
+
# "#{first}.#{last}"
|
33
|
+
# end
|
34
|
+
# end
|
26
35
|
#
|
27
|
-
#
|
36
|
+
# ##
|
37
|
+
## Using Classes: default no #call before return
|
38
|
+
# ##
|
39
|
+
# SknContainer.register(:user, Person)
|
28
40
|
# -- or --
|
29
|
-
# SknContainer.register(:
|
41
|
+
# SknContainer.register(:user, Person, call: false )
|
42
|
+
# -- then --
|
43
|
+
# SknContainer.resolve(:user).new({first: 'Monty', last: 'Python'}).name # => 'Monty.Python'
|
44
|
+
# SknContainer.resolve(:user).new({first: 'Monty', last: 'Python'}).name # => 'Monty.Python'
|
45
|
+
#
|
46
|
+
# ##
|
47
|
+
## Using Procs: default #call before return
|
48
|
+
# ##
|
30
49
|
#
|
31
|
-
# SknContainer.
|
50
|
+
# SknContainer.register(:user, -> { Person.new })
|
51
|
+
# -- or --
|
52
|
+
# SknContainer.register(:user, -> { Person.new }, call: false )
|
53
|
+
# -- or --
|
54
|
+
# SknContainer.register(:user, ->(hsh) { Person.new(hsh) }, call: false )
|
55
|
+
# -- or --
|
56
|
+
# SknContainer.register(:block_a, ->(hsh) { Person.new(hsh) }, {call: true, first: 'Monty', last: 'Python'} )
|
57
|
+
# -- or --
|
58
|
+
# SknContainer.register(:block_b, {call: true, greet: 'Hello', str: 'Python'}) {|hsh| "#{hsh[:greet]} #{hsh[:str].upcase}" }
|
59
|
+
# -- then --
|
60
|
+
# SknContainer.resolve(:person_repository).name # => '.'
|
61
|
+
# SknContainer.resolve(:person_repository).call().name # => '.'
|
62
|
+
# SknContainer.resolve(:person_repository).call({first: 'Monty', last: 'Python'}).name # => 'Monty.Python'
|
63
|
+
# SknContainer.resolve(:block_a).name # => 'Monty.Python'
|
64
|
+
# SknContainer.resolve(:block_b) # => 'Hello PYTHON'
|
32
65
|
#
|
33
|
-
## Outside Example
|
34
|
-
# SknContainer.register(:some_block, {call: false}) {|str| str.upcase }
|
35
|
-
# #
|
36
|
-
# SknContainer.resolve(:some_block).call("hello")
|
37
|
-
# # ==> "HELLO"
|
38
66
|
##
|
39
67
|
|
40
|
-
# This creates a global constant (and singleton) wrapping a Hash
|
41
|
-
class << (SknContainer =
|
42
|
-
|
43
|
-
class Content
|
44
|
-
attr_reader :item, :options
|
45
|
-
|
46
|
-
def initialize(item, options = {})
|
47
|
-
@item, @options = item, {
|
48
|
-
call: item.is_a?(::Proc)
|
49
|
-
}.merge(options)
|
50
|
-
end
|
51
|
-
|
52
|
-
def call
|
53
|
-
if options[:call] == true
|
54
|
-
item.call
|
55
|
-
else
|
56
|
-
item
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def register(key, contents = nil, options = {}, &block)
|
62
|
-
if block_given?
|
63
|
-
item = block
|
64
|
-
options = contents if contents.is_a?(::Hash)
|
65
|
-
else
|
66
|
-
item = contents
|
67
|
-
end
|
68
|
-
|
69
|
-
self[key] = Content.new(item, options)
|
70
|
-
|
71
|
-
self # enable chaining
|
72
|
-
end
|
73
|
-
|
74
|
-
def resolve(key)
|
75
|
-
self.fetch(key) {|k| nil }&.call
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
68
|
+
# This creates a global constant (and singleton) wrapping SknRegistry which wraps a Concurrent::Hash
|
69
|
+
class << (SknContainer = SknRegistry.new); end
|
data/lib/skn_failure.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# ##
|
2
2
|
# Bad Result
|
3
|
+
#
|
4
|
+
# Syntax: SknFailure.call(payload, message=nil, bool_code=false)
|
5
|
+
#
|
3
6
|
|
4
7
|
class SknFailure
|
5
8
|
attr_reader :value, :success, :message
|
@@ -9,17 +12,15 @@ class SknFailure
|
|
9
12
|
end
|
10
13
|
|
11
14
|
def initialize(*args)
|
12
|
-
val,
|
13
|
-
# puts "#{self.class.name} => val:#{val}, rc:#{rc}, msg:#{msg}, args:#{args}"
|
14
|
-
|
15
|
-
if args.size.eql?(2) and not ['TrueClass','FalseClass'].include?(rc.class.name)
|
16
|
-
msg = rc
|
17
|
-
rc = false
|
18
|
-
end
|
19
|
-
|
15
|
+
val, msg, rc = args
|
20
16
|
@value = val || "Failure"
|
21
|
-
@success = !!rc
|
22
17
|
@message = msg || ''
|
18
|
+
@success = rc.nil? ? false : rc
|
19
|
+
# puts "#{self.class.name} => val:#{val}, rc:#{rc}, msg:#{msg}, args:#{args}"
|
20
|
+
# puts "#{self.class.name} => @val:#{@value}, @rc:#{@success}, @msg:#{@message}"
|
23
21
|
end
|
24
22
|
|
23
|
+
def payload
|
24
|
+
@value
|
25
|
+
end
|
25
26
|
end
|
data/lib/skn_registry.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# ##
|
2
|
+
# SknRegistry
|
3
|
+
# - Key/Value Container where keys and/or values can be any valid Ruby Class, Proc, Instance, or object.
|
4
|
+
#
|
5
|
+
# Credits: Inspired by: andyholland1991@aol.com, http://cv.droppages.com
|
6
|
+
#
|
7
|
+
# Syntax:
|
8
|
+
# reg = SknRegistry.new(®_blk)
|
9
|
+
# - where: ®_blk is {|reg| reg.register(...); ... }
|
10
|
+
#
|
11
|
+
# self_chain = reg.register(key, content, options={}, &block)
|
12
|
+
# content = reg.resolve(key, render_proc=true)
|
13
|
+
#
|
14
|
+
# Params:
|
15
|
+
# key - anyThing can be used as the key
|
16
|
+
# content - anyThing can be used as value; Class, Proc, instance, value
|
17
|
+
# options - hash of dependencies to pass into procs when rendering
|
18
|
+
# &block - block used for #content; with/without a parameter. ex: {|parm| ...} | { ... }
|
19
|
+
# render_proc - bool: when #content is_a Proc, should it be #call()'ed before being returned
|
20
|
+
#
|
21
|
+
#
|
22
|
+
# ## Examples
|
23
|
+
#
|
24
|
+
# class Person
|
25
|
+
# attr_reader :first, :last
|
26
|
+
# def initialize(names={})
|
27
|
+
# self.first = names[:first]
|
28
|
+
# self.last = names[:last]
|
29
|
+
# end
|
30
|
+
# def name
|
31
|
+
# "#{first}.#{last}"
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# ##
|
36
|
+
## Using Classes: default no #call before return
|
37
|
+
# ##
|
38
|
+
# reg.register(:user, Person)
|
39
|
+
# -- or --
|
40
|
+
# reg.register(:user, Person, call: false )
|
41
|
+
# -- then --
|
42
|
+
# reg.resolve(:user).new({first: 'Monty', last: 'Python'}).name # => 'Monty.Python'
|
43
|
+
# reg.resolve(:user).new({first: 'Monty', last: 'Python'}).name # => 'Monty.Python'
|
44
|
+
#
|
45
|
+
# ##
|
46
|
+
## Using Procs: default #call before return
|
47
|
+
# ##
|
48
|
+
#
|
49
|
+
# reg.register(:user, -> { Person.new })
|
50
|
+
# -- or --
|
51
|
+
# reg.register(:user, -> { Person.new }, call: false )
|
52
|
+
# -- or --
|
53
|
+
# reg.register(:user, ->(hsh) { Person.new(hsh) }, call: false )
|
54
|
+
# -- or --
|
55
|
+
# reg.register(:block_a, ->(hsh) { Person.new(hsh) }, {call: true, first: 'Monty', last: 'Python'} )
|
56
|
+
# -- or --
|
57
|
+
# reg.register(:block_b, {call: true, greet: 'Hello', str: 'Python'}) {|hsh| "#{hsh[:greet]} #{hsh[:str].upcase}" }
|
58
|
+
# -- then --
|
59
|
+
# reg.resolve(:person_repository).name # => '.'
|
60
|
+
# reg.resolve(:person_repository).call().name # => '.'
|
61
|
+
# reg.resolve(:person_repository).call({first: 'Monty', last: 'Python'}).name # => 'Monty.Python'
|
62
|
+
# reg.resolve(:block_a).name # => 'Monty.Python'
|
63
|
+
# reg.resolve(:block_b) # => 'Hello PYTHON'
|
64
|
+
#
|
65
|
+
##
|
66
|
+
|
67
|
+
class SknRegistry < Concurrent::Hash
|
68
|
+
|
69
|
+
# Child to contain contents
|
70
|
+
class Content
|
71
|
+
attr_reader :item, :options
|
72
|
+
|
73
|
+
def initialize(item, options = {})
|
74
|
+
@item, @options = item, {
|
75
|
+
call: item.is_a?(::Proc)
|
76
|
+
}.merge(options)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Determine if call is required, without changing original values
|
80
|
+
# - yes, determine if depends are available
|
81
|
+
# -- yes, call with depends: #item.call(depends)
|
82
|
+
# -- no, just #item.call()
|
83
|
+
# - no, return #item
|
84
|
+
def call(render_proc=true)
|
85
|
+
_opts = options.reject {|k,v| k === :call }
|
86
|
+
_do_call = render_proc && options[:call]
|
87
|
+
|
88
|
+
_do_call ? (_opts.empty? ? item.call : item.call( _opts )) : item
|
89
|
+
end
|
90
|
+
end # end content
|
91
|
+
|
92
|
+
# SknRegistry initializer
|
93
|
+
#
|
94
|
+
def initialize(&block)
|
95
|
+
super
|
96
|
+
block.call(self) if block_given?
|
97
|
+
end
|
98
|
+
|
99
|
+
# public instance methods
|
100
|
+
def register(key, contents = nil, options = {}, &block)
|
101
|
+
if block_given?
|
102
|
+
item = block
|
103
|
+
options = contents if contents.is_a?(::Hash)
|
104
|
+
else
|
105
|
+
item = contents
|
106
|
+
end
|
107
|
+
|
108
|
+
self[key] = Content.new(item, options)
|
109
|
+
|
110
|
+
self # enable chaining
|
111
|
+
end
|
112
|
+
|
113
|
+
def resolve(key, render_proc=true) # false to prevent downstream #call
|
114
|
+
self[key]&.call(render_proc)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
data/lib/skn_success.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# ##
|
2
2
|
# Good Result
|
3
|
+
#
|
4
|
+
# Syntax: SknSuccess.call(payload, message=nil, bool_code=true)
|
5
|
+
#
|
3
6
|
|
4
7
|
class SknSuccess
|
5
8
|
attr_reader :value, :success, :message
|
@@ -9,17 +12,15 @@ class SknSuccess
|
|
9
12
|
end
|
10
13
|
|
11
14
|
def initialize(*args)
|
12
|
-
val,
|
13
|
-
# puts "#{self.class.name} => val:#{val}, rc:#{rc}, msg:#{msg}, args:#{args}"
|
14
|
-
|
15
|
-
if args.size.eql?(2) and not ['TrueClass','FalseClass', 'NilClass'].include?(rc.class.name)
|
16
|
-
msg = rc
|
17
|
-
rc = true
|
18
|
-
end
|
19
|
-
|
15
|
+
val, msg, rc = args
|
20
16
|
@value = val || "Success"
|
21
|
-
@success = !!rc || true
|
22
17
|
@message = msg || ''
|
18
|
+
@success = rc.nil? ? true : rc
|
19
|
+
# puts "#{self.class.name} => val:#{val}, rc:#{rc}, msg:#{msg}, args:#{args}"
|
20
|
+
# puts "#{self.class.name} => @val:#{@value}, @rc:#{@success}, @msg:#{@message}"
|
23
21
|
end
|
24
22
|
|
23
|
+
def payload
|
24
|
+
@value
|
25
|
+
end
|
25
26
|
end
|
@@ -13,7 +13,7 @@ module SknUtils
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def load_config_basename!(conf)
|
16
|
-
reset_from_empty!(load_config(conf), false) # enable dot notation via defined methods vs method_missing
|
16
|
+
reset_from_empty!(load_config(conf), false) # enable dot notation via defined methods(true) vs method_missing(false)
|
17
17
|
self
|
18
18
|
end
|
19
19
|
|
data/lib/skn_utils/version.rb
CHANGED
data/lib/skn_utils.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
##
|
2
2
|
# spec/lib/skn_utils/container_spec.rb
|
3
3
|
#
|
4
|
+
# @See SknRegistry also
|
4
5
|
|
5
|
-
class
|
6
|
+
class MyKlassService
|
6
7
|
def value
|
7
8
|
true
|
8
9
|
end
|
@@ -10,39 +11,39 @@ end
|
|
10
11
|
|
11
12
|
|
12
13
|
|
13
|
-
describe SknContainer, "IoC Lite Container
|
14
|
+
describe SknContainer, "IoC Lite Container Singleton." do
|
14
15
|
|
15
16
|
context "Operational Features. " do
|
16
17
|
|
17
18
|
it "#register accepts a proc object to produce unique instances. " do
|
18
|
-
val = subject.register(:service, -> {
|
19
|
+
val = subject.register(:service, -> {MyKlassService.new} )
|
19
20
|
expect( val ).to eq subject
|
20
21
|
end
|
21
22
|
|
22
23
|
it "#resolve returns new instances. " do
|
23
|
-
subject.register(:service, -> {
|
24
|
+
subject.register(:service, -> {MyKlassService.new} )
|
24
25
|
val_a = subject.resolve(:service)
|
25
26
|
val_b = subject.resolve(:service)
|
26
27
|
|
27
|
-
expect( val_a ).to be_instance_of
|
28
|
+
expect( val_a ).to be_instance_of MyKlassService
|
28
29
|
expect( val_a ).to_not be_equal val_b
|
29
30
|
end
|
30
31
|
|
31
32
|
it "#register accepts a class object and return self to enable chaining. " do
|
32
|
-
val = subject.register(:service_k,
|
33
|
+
val = subject.register(:service_k, MyKlassService).register(:more, "More")
|
33
34
|
expect( val ).to eq subject
|
34
35
|
end
|
35
36
|
|
36
37
|
it "#resolve returns class value. " do
|
37
|
-
subject.register(:service_k,
|
38
|
+
subject.register(:service_k, MyKlassService)
|
38
39
|
val = subject.resolve(:service_k)
|
39
40
|
|
40
|
-
expect( val ).to be_equal
|
41
|
+
expect( val ).to be_equal MyKlassService
|
41
42
|
expect( val.new.value ).to be true
|
42
43
|
end
|
43
44
|
|
44
45
|
it "#resolve returns the same object value. " do
|
45
|
-
thingy =
|
46
|
+
thingy = MyKlassService.new
|
46
47
|
subject.register(:service_k, thingy)
|
47
48
|
val_a = subject.resolve(:service_k)
|
48
49
|
val_b = subject.resolve(:service_k)
|
@@ -0,0 +1,130 @@
|
|
1
|
+
##
|
2
|
+
# spec/lib/skn_utils/registry_spec.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
class MyService
|
6
|
+
def value
|
7
|
+
true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
describe SknRegistry, "IoC Lite Container class." do
|
14
|
+
|
15
|
+
let(:registry) { described_class.new }
|
16
|
+
|
17
|
+
let(:services) {
|
18
|
+
described_class.new do|cfg|
|
19
|
+
cfg.register(:service_a, -> {MyService.new} )
|
20
|
+
cfg.register(:service_b, MyService)
|
21
|
+
cfg.register(:service_c, "AnyValue")
|
22
|
+
cfg.register(:some_block, ->(str){ str.upcase }, {call: false})
|
23
|
+
cfg.register(:some_depends, {call: true, greet: 'My warmest', str: 'Hello'}) {|pkg| "#{pkg[:greet]} #{pkg[:str].upcase}" }
|
24
|
+
end
|
25
|
+
}
|
26
|
+
|
27
|
+
context "Basic Operation Features. " do
|
28
|
+
|
29
|
+
it "#register accepts a proc object to produce unique instances. " do
|
30
|
+
val = registry.register(:service, -> {MyService.new} )
|
31
|
+
expect( val ).to eq registry
|
32
|
+
end
|
33
|
+
|
34
|
+
it "#resolve returns new instances. " do
|
35
|
+
registry.register(:service, -> {MyService.new} )
|
36
|
+
val_a = registry.resolve(:service)
|
37
|
+
val_b = registry.resolve(:service)
|
38
|
+
|
39
|
+
expect( val_a ).to be_instance_of MyService
|
40
|
+
expect( val_a ).to_not be_equal val_b
|
41
|
+
end
|
42
|
+
|
43
|
+
it "#register accepts a class object and return self to enable chaining. " do
|
44
|
+
chain = registry.register(:service_k, MyService).register(:more, "More")
|
45
|
+
expect( chain ).to be_equal registry
|
46
|
+
expect( registry.resolve(:service_k) ).to be_equal MyService
|
47
|
+
expect( registry.resolve(:more) ).to eq('More')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "#resolve returns class value. " do
|
51
|
+
registry.register(:service_k, MyService)
|
52
|
+
val = registry.resolve(:service_k)
|
53
|
+
|
54
|
+
expect( val ).to be_equal MyService
|
55
|
+
expect( val.new.value ).to be true
|
56
|
+
end
|
57
|
+
|
58
|
+
it "#resolve returns the same object value. " do
|
59
|
+
thingy = MyService.new
|
60
|
+
registry.register(:service_k, thingy)
|
61
|
+
val_a = registry.resolve(:service_k)
|
62
|
+
val_b = registry.resolve(:service_k)
|
63
|
+
|
64
|
+
expect( val_a ).to be_equal thingy
|
65
|
+
expect( val_b ).to be_equal thingy
|
66
|
+
expect( val_a ).to be_equal val_b
|
67
|
+
end
|
68
|
+
|
69
|
+
it "#resolve returns nil when key is not found. " do
|
70
|
+
registry.register(:service_a, "AnyValue")
|
71
|
+
expect(registry.resolve(:no_find)).to be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it "#resolve returns block without calling it first. " do
|
75
|
+
registry.register(:service_b, {call: false}) do |str|
|
76
|
+
str.upcase
|
77
|
+
end
|
78
|
+
|
79
|
+
expect( registry.resolve(:service_b).call("Hello") ).to eq "HELLO"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
context "Extended Initialization Feature. " do
|
85
|
+
|
86
|
+
it "Register a hash of objects on initialization via block. " do
|
87
|
+
expect(services.keys.size).to eq 5
|
88
|
+
end
|
89
|
+
|
90
|
+
it "#resolve returns new instances. " do
|
91
|
+
val_a = services.resolve(:service_a)
|
92
|
+
val_b = services.resolve(:service_a)
|
93
|
+
|
94
|
+
expect( val_a ).to be_instance_of MyService
|
95
|
+
expect( val_b ).to be_instance_of MyService
|
96
|
+
expect( val_a ).to_not be_equal val_b
|
97
|
+
end
|
98
|
+
|
99
|
+
it "#resolve returns class value. " do
|
100
|
+
val = services.resolve(:service_b)
|
101
|
+
|
102
|
+
expect( val ).to be_equal MyService
|
103
|
+
expect( val.new.value ).to be true
|
104
|
+
end
|
105
|
+
|
106
|
+
it "#resolve returns String value. " do
|
107
|
+
val = services.resolve(:service_c)
|
108
|
+
|
109
|
+
expect( val ).to be_a String
|
110
|
+
expect( val ).to eq("AnyValue")
|
111
|
+
end
|
112
|
+
|
113
|
+
it "#resovle returns a proc without calling it. " do
|
114
|
+
expect(services.resolve(:some_block).call("hello")).to eq("HELLO")
|
115
|
+
end
|
116
|
+
|
117
|
+
it "#resovle invokes the proc passing in dependencies. " do
|
118
|
+
expect(services.resolve(:some_depends)).to eq("My warmest HELLO")
|
119
|
+
end
|
120
|
+
|
121
|
+
it "#resovle accepts override and does not render proc before returning it. " do
|
122
|
+
expect(services.resolve(:some_depends, false)).to be_a Proc
|
123
|
+
expect(
|
124
|
+
services.resolve(:some_depends, false)
|
125
|
+
.call({greet: 'My warmest', str: 'Hello'})
|
126
|
+
).to eq("My warmest HELLO")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# ##
|
2
|
+
# Test both classes in this file
|
3
|
+
|
4
|
+
|
5
|
+
shared_examples "a response value" do
|
6
|
+
|
7
|
+
let(:default_instance) { described_class.call }
|
8
|
+
let(:success_returned) { default_instance.instance_of?(SknSuccess) ? true : false }
|
9
|
+
let(:default_value) { described_class.name.to_s[3..-1] }
|
10
|
+
|
11
|
+
context "Created without Params" do
|
12
|
+
|
13
|
+
it "Exists. " do
|
14
|
+
expect(default_instance).to be
|
15
|
+
end
|
16
|
+
|
17
|
+
it "Has default value. " do
|
18
|
+
expect(default_instance.value ).to eq default_value
|
19
|
+
end
|
20
|
+
|
21
|
+
it "Has default status. " do
|
22
|
+
expect(default_instance.success ).to be success_returned
|
23
|
+
end
|
24
|
+
|
25
|
+
it "Has no default message. " do
|
26
|
+
expect(default_instance.message ).to be_empty
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "Created with Params" do
|
31
|
+
it "#success defaults to false. " do
|
32
|
+
expect(described_class.call("Testing").success ).to be success_returned
|
33
|
+
end
|
34
|
+
|
35
|
+
it "#success accepts input. " do
|
36
|
+
expect(described_class.call("Testing", nil, !success_returned).success ).to be !success_returned
|
37
|
+
end
|
38
|
+
|
39
|
+
it "#value defaults to properly. " do
|
40
|
+
expect(described_class.call(nil, nil, false ).value ).to eq default_value
|
41
|
+
end
|
42
|
+
|
43
|
+
it "#value accepts input. " do
|
44
|
+
expect(described_class.call("Don't know why!").value ).to eq "Don't know why!"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "#message accepts input. " do
|
48
|
+
expect(described_class.call("Don't know why!", 'Something Happened!', false ).message ).to eq "Something Happened!"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "#payload returns value as expected. " do
|
52
|
+
expect(described_class.call("Don't know why!", 'Something Happened!').payload ).to eq "Don't know why!"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "Supports #(), #call, #new, initialization and Forgives. " do
|
57
|
+
|
58
|
+
it "#(...) is supported. " do
|
59
|
+
expect(described_class.('payload', "Testing", false ).message ).to eq('Testing')
|
60
|
+
end
|
61
|
+
|
62
|
+
it "#call(...) is supported. " do
|
63
|
+
expect(described_class.call('payload', "Testing", false ).value ).to eq('payload')
|
64
|
+
end
|
65
|
+
|
66
|
+
it "#new(...) is supported. " do
|
67
|
+
expect(described_class.new('payload', "Testing", false ).success ).to be false
|
68
|
+
end
|
69
|
+
|
70
|
+
it "Forgives absence of return code input with message. " do
|
71
|
+
expect(described_class.('Trying Hard ... !', 'Forgiveness is Wonderful!').message ).to eq('Forgiveness is Wonderful!')
|
72
|
+
expect(described_class.('Trying Hard ... !', 'Forgiveness is Wonderful!').success ).to be success_returned
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
describe SknFailure, "Failure Result Value Container" do
|
80
|
+
it_behaves_like "a response value"
|
81
|
+
end
|
82
|
+
|
83
|
+
describe SknSuccess, "Success Result Value Container" do
|
84
|
+
it_behaves_like "a response value"
|
85
|
+
end
|
86
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skn_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0
|
4
|
+
version: 5.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Scott Jr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deep_merge
|
@@ -167,6 +167,7 @@ files:
|
|
167
167
|
- lib/skn_container.rb
|
168
168
|
- lib/skn_failure.rb
|
169
169
|
- lib/skn_hash.rb
|
170
|
+
- lib/skn_registry.rb
|
170
171
|
- lib/skn_settings.rb
|
171
172
|
- lib/skn_success.rb
|
172
173
|
- lib/skn_utils.rb
|
@@ -188,11 +189,11 @@ files:
|
|
188
189
|
- spec/lib/skn_settings_spec.rb
|
189
190
|
- spec/lib/skn_utils/configurable_spec.rb
|
190
191
|
- spec/lib/skn_utils/container_spec.rb
|
191
|
-
- spec/lib/skn_utils/failure_spec.rb
|
192
192
|
- spec/lib/skn_utils/nested_result_spec.rb
|
193
193
|
- spec/lib/skn_utils/notifier_base_spec.rb
|
194
194
|
- spec/lib/skn_utils/null_object_spec.rb
|
195
|
-
- spec/lib/skn_utils/
|
195
|
+
- spec/lib/skn_utils/registry_spec.rb
|
196
|
+
- spec/lib/skn_utils/success_failure_value_container_spec.rb
|
196
197
|
- spec/spec_helper.rb
|
197
198
|
homepage: https://github.com/skoona/skn_utils
|
198
199
|
licenses:
|
@@ -229,9 +230,9 @@ test_files:
|
|
229
230
|
- spec/lib/skn_settings_spec.rb
|
230
231
|
- spec/lib/skn_utils/configurable_spec.rb
|
231
232
|
- spec/lib/skn_utils/container_spec.rb
|
232
|
-
- spec/lib/skn_utils/failure_spec.rb
|
233
233
|
- spec/lib/skn_utils/nested_result_spec.rb
|
234
234
|
- spec/lib/skn_utils/notifier_base_spec.rb
|
235
235
|
- spec/lib/skn_utils/null_object_spec.rb
|
236
|
-
- spec/lib/skn_utils/
|
236
|
+
- spec/lib/skn_utils/registry_spec.rb
|
237
|
+
- spec/lib/skn_utils/success_failure_value_container_spec.rb
|
237
238
|
- spec/spec_helper.rb
|
@@ -1,67 +0,0 @@
|
|
1
|
-
|
2
|
-
describe SknFailure, "Result/Response Value Container" do
|
3
|
-
|
4
|
-
let(:default_instance) { described_class.call }
|
5
|
-
|
6
|
-
context "Created without Params" do
|
7
|
-
|
8
|
-
it "Exists. " do
|
9
|
-
expect(default_instance).to be
|
10
|
-
end
|
11
|
-
|
12
|
-
it "Has default value. " do
|
13
|
-
expect(default_instance.value ).to eq "Failure"
|
14
|
-
end
|
15
|
-
|
16
|
-
it "Has default status. " do
|
17
|
-
expect(default_instance.success ).to be false
|
18
|
-
end
|
19
|
-
|
20
|
-
it "Has no default message. " do
|
21
|
-
expect(default_instance.message ).to be_empty
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context "Created with Params" do
|
26
|
-
it "#success defaults to false. " do
|
27
|
-
expect(described_class.call("Testing").success ).to be false
|
28
|
-
end
|
29
|
-
|
30
|
-
it "#success accepts input. " do
|
31
|
-
expect(described_class.call("Testing", false).success ).to be false
|
32
|
-
end
|
33
|
-
|
34
|
-
it "#value defaults to Failure. " do
|
35
|
-
expect(described_class.call(nil, false ).value ).to eq "Failure"
|
36
|
-
end
|
37
|
-
|
38
|
-
it "#value accepts input. " do
|
39
|
-
expect(described_class.call("Don't know why!").value ).to eq "Don't know why!"
|
40
|
-
end
|
41
|
-
|
42
|
-
it "#message accepts input. " do
|
43
|
-
expect(described_class.call("Don't know why!", false, 'Something Bad Happened!').message ).to eq "Something Bad Happened!"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context "Supports #(), #call, #new, initialization and Forgives. " do
|
48
|
-
|
49
|
-
it "#(...) is supported. " do
|
50
|
-
expect(described_class.('payload', false, "Testing").message ).to eq('Testing')
|
51
|
-
end
|
52
|
-
|
53
|
-
it "#call(...) is supported. " do
|
54
|
-
expect(described_class.call('payload', false, "Testing").value ).to eq('payload')
|
55
|
-
end
|
56
|
-
|
57
|
-
it "#new(...) is supported. " do
|
58
|
-
expect(described_class.new('payload', false, "Testing").success ).to be false
|
59
|
-
end
|
60
|
-
|
61
|
-
it "Forgives absence of return code input with message. " do
|
62
|
-
expect(described_class.('Failure is ... !', 'Forgiveness is Wonderful!').message ).to eq('Forgiveness is Wonderful!')
|
63
|
-
expect(described_class.('Failure is ... !', 'Forgiveness is Wonderful!').success ).to be false
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
@@ -1,68 +0,0 @@
|
|
1
|
-
|
2
|
-
describe SknSuccess, "Result/Response Value Container" do
|
3
|
-
|
4
|
-
let(:default_instance) { described_class.call }
|
5
|
-
|
6
|
-
context "Created without Params" do
|
7
|
-
|
8
|
-
it "Exists. " do
|
9
|
-
expect(default_instance).to be
|
10
|
-
end
|
11
|
-
|
12
|
-
it "Has default value " do
|
13
|
-
expect(default_instance.value ).to eq "Success"
|
14
|
-
end
|
15
|
-
|
16
|
-
it "Has default status " do
|
17
|
-
expect(default_instance.success ).to be true
|
18
|
-
end
|
19
|
-
|
20
|
-
it "Has no default message. " do
|
21
|
-
expect(default_instance.message ).to be_empty
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context "Created with Params" do
|
26
|
-
it "#success defaults to true. " do
|
27
|
-
expect(described_class.call("Testing").success ).to be true
|
28
|
-
end
|
29
|
-
|
30
|
-
it "#success accepts input. " do
|
31
|
-
expect(described_class.call("Testing", true).success ).to be true
|
32
|
-
end
|
33
|
-
|
34
|
-
it "#value defaults to Success. " do
|
35
|
-
expect(described_class.call(nil, true).value ).to eq "Success"
|
36
|
-
end
|
37
|
-
|
38
|
-
it "#value accepts input. " do
|
39
|
-
expect(described_class.call({some: :hash}).value ).to be_a Hash
|
40
|
-
expect(described_class.call("Success is Wonderful!").value ).to eq "Success is Wonderful!"
|
41
|
-
end
|
42
|
-
|
43
|
-
it "#message accepts input. " do
|
44
|
-
expect(described_class.call("Success is Wonderful!", true, 'Something Good Happened!').message ).to eq "Something Good Happened!"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context "Supports #(), #call, #new, initialization and Forgives. " do
|
49
|
-
|
50
|
-
it "#(...) is supported. " do
|
51
|
-
expect(described_class.('payload', false, "Testing").message ).to eq('Testing')
|
52
|
-
end
|
53
|
-
|
54
|
-
it "#call(...) is supported. " do
|
55
|
-
expect(described_class.call('payload', false, "Testing").value ).to eq('payload')
|
56
|
-
end
|
57
|
-
|
58
|
-
it "#new(...) is supported. " do
|
59
|
-
expect(described_class.new('payload', false, "Testing").success ).to be true
|
60
|
-
end
|
61
|
-
|
62
|
-
it "Forgives absence of return code input with message. " do
|
63
|
-
expect(described_class.('Success is ... !', 'Forgiveness is Wonderful!').message ).to eq('Forgiveness is Wonderful!')
|
64
|
-
expect(described_class.('Success is ... !', 'Forgiveness is Wonderful!').success ).to be true
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|