plumbum 0.1.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 +7 -0
- data/CHANGELOG.md +18 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE +22 -0
- data/README.md +163 -0
- data/lib/plumbum/consumer.rb +148 -0
- data/lib/plumbum/consumers/class_methods.rb +319 -0
- data/lib/plumbum/consumers/instance_methods.rb +105 -0
- data/lib/plumbum/consumers/scoped_consumer.rb +25 -0
- data/lib/plumbum/consumers.rb +12 -0
- data/lib/plumbum/errors/immutable_error.rb +8 -0
- data/lib/plumbum/errors/invalid_dependency_error.rb +8 -0
- data/lib/plumbum/errors/invalid_key_error.rb +8 -0
- data/lib/plumbum/errors/missing_dependency_error.rb +8 -0
- data/lib/plumbum/errors.rb +13 -0
- data/lib/plumbum/many_provider.rb +86 -0
- data/lib/plumbum/one_provider.rb +56 -0
- data/lib/plumbum/parameters.rb +39 -0
- data/lib/plumbum/provider.rb +148 -0
- data/lib/plumbum/providers/lazy.rb +26 -0
- data/lib/plumbum/providers/plural.rb +31 -0
- data/lib/plumbum/providers/singular.rb +26 -0
- data/lib/plumbum/providers.rb +12 -0
- data/lib/plumbum/rspec/deferred/consumer_examples.rb +2122 -0
- data/lib/plumbum/rspec/deferred/provider_examples.rb +848 -0
- data/lib/plumbum/rspec/deferred.rb +8 -0
- data/lib/plumbum/rspec/stub_provider.rb +75 -0
- data/lib/plumbum/rspec.rb +8 -0
- data/lib/plumbum/version.rb +57 -0
- data/lib/plumbum.rb +25 -0
- metadata +91 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'sleeping_king_studios/tools'
|
|
4
|
+
|
|
5
|
+
require 'plumbum'
|
|
6
|
+
require 'plumbum/errors/immutable_error'
|
|
7
|
+
require 'plumbum/errors/invalid_key_error'
|
|
8
|
+
|
|
9
|
+
module Plumbum
|
|
10
|
+
# Abstract module defining the Provider interface.
|
|
11
|
+
#
|
|
12
|
+
# A Plumbum::Provider is responsible for making one or more values available
|
|
13
|
+
# to a consumer object. How those values are stored or generated is up to the
|
|
14
|
+
# provider implementation.
|
|
15
|
+
#
|
|
16
|
+
# Each provider implementation is responsible for defining the #get_value(key)
|
|
17
|
+
# and #has_value(key) methods:
|
|
18
|
+
#
|
|
19
|
+
# - #get_value(key) must accept a single non-empty String argument and return
|
|
20
|
+
# the provided value matching the key, or nil if there is no matching value.
|
|
21
|
+
# - #has_value?(key) must accept a single non-empty String argument and return
|
|
22
|
+
# true if the provider has a value matching the key, or false if there is
|
|
23
|
+
# no matching value.
|
|
24
|
+
#
|
|
25
|
+
# @see Plumbum::Consumer
|
|
26
|
+
# @see Plumbum::Providers::Plural
|
|
27
|
+
# @see Plumbum::Providers::Singular
|
|
28
|
+
module Provider
|
|
29
|
+
# Retrieves the provided value for the given key.
|
|
30
|
+
#
|
|
31
|
+
# @param key [String, Symbol] the key for the requested value.
|
|
32
|
+
#
|
|
33
|
+
# @return [Object, nil] the requested object, or nil if the provider does
|
|
34
|
+
# not have a value for the requested key.
|
|
35
|
+
def get(key)
|
|
36
|
+
key
|
|
37
|
+
.then { |obj| normalize_key(obj) }
|
|
38
|
+
.then { |str| get_value(str) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Checks if the provider has a value for the given key.
|
|
42
|
+
#
|
|
43
|
+
# @param key [String, Symbol] the key for the requested value.
|
|
44
|
+
# @param allow_undefined [true, false] if true, returns true even if the key
|
|
45
|
+
# exists but the value is undefined.
|
|
46
|
+
#
|
|
47
|
+
# @return [true, false] true if the provider has a value for the requested
|
|
48
|
+
# key, otherwise false.
|
|
49
|
+
def has?(key, allow_undefined: false)
|
|
50
|
+
key
|
|
51
|
+
.then { |obj| normalize_key(obj) }
|
|
52
|
+
.then { |str| has_value?(str, allow_undefined:) }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Sets the value for the given key.
|
|
56
|
+
#
|
|
57
|
+
# @param key [String, Symbol] the key for the assigned value.
|
|
58
|
+
# @param value [Object] the value to assign.
|
|
59
|
+
#
|
|
60
|
+
# @return [Object] the assigned value.
|
|
61
|
+
#
|
|
62
|
+
# @raise [Plumbum::Errors::ImmutableError] when attempting to assign a value
|
|
63
|
+
# to an immutable provider.
|
|
64
|
+
def set(key, value)
|
|
65
|
+
if frozen?
|
|
66
|
+
raise FrozenError, "can't modify frozen #{self.class}: #{inspect}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
key
|
|
70
|
+
.then { |obj| normalize_key(obj) }
|
|
71
|
+
.tap { |key| validate_key(key) }
|
|
72
|
+
.tap { |key| require_mutable(key) }
|
|
73
|
+
.then { |key| set_value(key, value) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# @return [Hash{Symbol => Object}] the options used to configure the
|
|
77
|
+
# provider.
|
|
78
|
+
def options
|
|
79
|
+
@options ||= {}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @return [true, false] if true, indicates the provider is read only, and an
|
|
83
|
+
# exception will be raised when attempting to set or change its value(s).
|
|
84
|
+
def read_only?
|
|
85
|
+
options.fetch(:read_only, true)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @return [true, false] if true, indicates the provider permits overwriting
|
|
89
|
+
# undefined values, and an exception will be raised when attemption to
|
|
90
|
+
# set or change any other values.
|
|
91
|
+
def write_once?
|
|
92
|
+
options.fetch(:write_once, false)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def get_value(key) = raw_value(key)
|
|
98
|
+
|
|
99
|
+
def has_value?(_key, **) = false # rubocop:disable Naming/PredicatePrefix
|
|
100
|
+
|
|
101
|
+
def mutable?(key)
|
|
102
|
+
return true if write_once? && raw_value(key) == Plumbum::UNDEFINED
|
|
103
|
+
|
|
104
|
+
!read_only?
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def normalize_key(key)
|
|
108
|
+
tools.assertions.validate_name(key, as: :key)
|
|
109
|
+
|
|
110
|
+
key.to_s
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def provider_name = respond_to?(:name) ? name : self.class.name
|
|
114
|
+
|
|
115
|
+
def raw_value(_key) = nil
|
|
116
|
+
|
|
117
|
+
def require_mutable(key)
|
|
118
|
+
return if mutable?(key)
|
|
119
|
+
|
|
120
|
+
raise Plumbum::Errors::ImmutableError,
|
|
121
|
+
"unable to change immutable value for #{provider_name} with key " \
|
|
122
|
+
"#{key.inspect}"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def set_value(_key, _value) = nil
|
|
126
|
+
|
|
127
|
+
def tools = SleepingKingStudios::Tools::Toolbelt.instance
|
|
128
|
+
|
|
129
|
+
def valid_key?(key) = has_value?(key) # rubocop:disable Style/PreferredHashMethods
|
|
130
|
+
|
|
131
|
+
def validate_key(key)
|
|
132
|
+
return if valid_key?(key)
|
|
133
|
+
|
|
134
|
+
return if raw_value(key) == Plumbum::UNDEFINED
|
|
135
|
+
|
|
136
|
+
raise Plumbum::Errors::InvalidKeyError,
|
|
137
|
+
"invalid key #{key.inspect} for #{provider_name}"
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def validate_options(options)
|
|
141
|
+
if options.key?(:read_only) && options.key?(:write_once)
|
|
142
|
+
raise ArgumentError, 'incompatible options :read_only and :write_once'
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
options
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'plumbum/providers'
|
|
4
|
+
|
|
5
|
+
module Plumbum::Providers
|
|
6
|
+
# Provider that calls proc values and returns the result.
|
|
7
|
+
#
|
|
8
|
+
# Add Plumbum::Providers::Lazy for values that have a consistent definition
|
|
9
|
+
# but changing value, such as class definitions under code reloading.
|
|
10
|
+
module Lazy
|
|
11
|
+
# Retrieves the provided value for the given key.
|
|
12
|
+
#
|
|
13
|
+
# If the value is a Proc, the Proc is called and the value returned by the
|
|
14
|
+
# Proc is returned by #get. Otherwise, #get returns the value directly.
|
|
15
|
+
#
|
|
16
|
+
# @param key [String, Symbol] the key for the requested value.
|
|
17
|
+
#
|
|
18
|
+
# @return [Object, nil] the requested object, or nil if the provider does
|
|
19
|
+
# not have a value for the requested key.
|
|
20
|
+
def get(key)
|
|
21
|
+
value = super
|
|
22
|
+
|
|
23
|
+
value.is_a?(Proc) ? value.call : value
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'plumbum/providers'
|
|
4
|
+
|
|
5
|
+
module Plumbum::Providers
|
|
6
|
+
# Provider implementation that wraps a multiple key-value pairs.
|
|
7
|
+
module Plural
|
|
8
|
+
include Plumbum::Provider
|
|
9
|
+
|
|
10
|
+
# @return [Hash] the key-value pairs returned by the provider.
|
|
11
|
+
attr_reader :values
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def get_value(key) = values[key]
|
|
16
|
+
|
|
17
|
+
def has_value?(key, **) = values.key?(key) # rubocop:disable Naming/PredicatePrefix
|
|
18
|
+
|
|
19
|
+
def mutable?(key)
|
|
20
|
+
return true if write_once? && @values == Plumbum::UNDEFINED
|
|
21
|
+
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def raw_value(key) = values[key]
|
|
26
|
+
|
|
27
|
+
def set_value(key, value)
|
|
28
|
+
@values[key.to_s] = value
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'plumbum/providers'
|
|
4
|
+
|
|
5
|
+
module Plumbum::Providers
|
|
6
|
+
# Provider implementation that wraps a single key-value pair.
|
|
7
|
+
module Singular
|
|
8
|
+
include Plumbum::Provider
|
|
9
|
+
|
|
10
|
+
# @return [String] the key matched by the provider.
|
|
11
|
+
attr_reader :key
|
|
12
|
+
|
|
13
|
+
# @return [Object] the value returned by the provider.
|
|
14
|
+
attr_reader :value
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def has_value?(key, **) = key == self.key # rubocop:disable Naming/PredicatePrefix
|
|
19
|
+
|
|
20
|
+
def raw_value(key) = key == self.key ? @value : nil
|
|
21
|
+
|
|
22
|
+
def set_value(key, value) = key == self.key ? @value = value : nil
|
|
23
|
+
|
|
24
|
+
def valid_key?(key) = key == self.key
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'plumbum'
|
|
4
|
+
|
|
5
|
+
module Plumbum
|
|
6
|
+
# Namespace for Provider implementations.
|
|
7
|
+
module Providers
|
|
8
|
+
autoload :Lazy, 'plumbum/providers/lazy'
|
|
9
|
+
autoload :Plural, 'plumbum/providers/plural'
|
|
10
|
+
autoload :Singular, 'plumbum/providers/singular'
|
|
11
|
+
end
|
|
12
|
+
end
|