trailblazer-context 0.1.4 → 0.2.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 +4 -4
- data/CHANGES.md +10 -0
- data/lib/trailblazer/context.rb +17 -5
- data/lib/trailblazer/context/aliasing.rb +36 -0
- data/lib/trailblazer/context/indifferent_access.rb +23 -6
- data/lib/trailblazer/context/version.rb +1 -1
- data/lib/trailblazer/option.rb +2 -2
- data/test/context_test.rb +90 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fec7a9c801fedda32fee29585bf8108b6a730980fe826df22d00cd7f0b6c8d1b
|
4
|
+
data.tar.gz: 6a39db80e891a99c802c1262b26434389869fc2b367c34cfffb5923acdd574b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdfce2ccb6119793c8971e70d0161f8b330b5941f07c7b06467713f3a3ebe42ce2563bcc9c0259bc412fbb12c2264586dde4414456d24f7d3eb2b2c4eec65fc7
|
7
|
+
data.tar.gz: 8f34a42f0b7a245586e86a45482e5d797d40edf9c6164cb149fd11de4bdbfe750b067d69a19eebdd747631df85bd40ce0789b2ce65c050c9309f87bed398795d
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
# 0.2.0
|
2
|
+
|
3
|
+
* Added `Context::IndifferentAccess`.
|
4
|
+
* Added `Context::Aliasing`.
|
5
|
+
* `Context.for_circuit` is not the authorative builder for creating a context.
|
6
|
+
|
7
|
+
# 0.1.5
|
8
|
+
|
9
|
+
* `Context.build` allows quickly building a Context without requiring the circuit interface.
|
10
|
+
|
1
11
|
# 0.1.4
|
2
12
|
|
3
13
|
* Fix the `IndifferentAccess` name lookup. Since we can't convert all keys to symbols internally (not every options structure has `collect`) we need to have a lookup chain.
|
data/lib/trailblazer/context.rb
CHANGED
@@ -14,10 +14,22 @@ module Trailblazer
|
|
14
14
|
# only public creator: Build
|
15
15
|
# :data object:
|
16
16
|
class Context
|
17
|
-
# NOTE:
|
18
|
-
#
|
19
|
-
|
20
|
-
|
17
|
+
# NOTE: In the future, we might look up the Context to use in the ctx.
|
18
|
+
# The demanding signature is for forward-compat.
|
19
|
+
# @private
|
20
|
+
def self.for(wrapped_options, (ctx, flow_options), circuit_options) # TODO: remove
|
21
|
+
implementation.build(wrapped_options, {}, [ctx, flow_options], circuit_options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.for_circuit(wrapped_options, mutable_options, (ctx, flow_options), circuit_options)
|
25
|
+
context_class = flow_options[:context_class] || implementation # Context::IndifferentAccess
|
26
|
+
|
27
|
+
context_class.build(wrapped_options, mutable_options, [ctx, flow_options], circuit_options)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @public
|
31
|
+
def self.build(wrapped_options, *)
|
32
|
+
new(wrapped_options)
|
21
33
|
end
|
22
34
|
|
23
35
|
# I hate globals, but currently this is the only easy way for setting the implementation.
|
@@ -25,7 +37,7 @@ module Trailblazer
|
|
25
37
|
IndifferentAccess
|
26
38
|
end
|
27
39
|
|
28
|
-
def initialize(wrapped_options, mutable_options)
|
40
|
+
def initialize(wrapped_options, mutable_options, *)
|
29
41
|
@wrapped_options = wrapped_options
|
30
42
|
@mutable_options = mutable_options
|
31
43
|
# TODO: wrapped_options should be optimized for lookups here since
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
class Context
|
3
|
+
module Aliasing
|
4
|
+
def initialize(wrapped_options, mutable_options, context_alias: {}, **)
|
5
|
+
super(wrapped_options, mutable_options)
|
6
|
+
|
7
|
+
@aliases = context_alias.invert
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](key)
|
11
|
+
return super unless aka = @aliases[key] # yepp, nil/false won't work
|
12
|
+
super(aka)
|
13
|
+
end
|
14
|
+
|
15
|
+
def key?(key)
|
16
|
+
return super unless aka = @aliases[key] # yepp, nil/false won't work
|
17
|
+
super(aka)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @private ?
|
21
|
+
def merge(hash)
|
22
|
+
original, mutable_options = decompose
|
23
|
+
|
24
|
+
self.class.new(
|
25
|
+
original,
|
26
|
+
mutable_options.merge(hash),
|
27
|
+
context_alias: @aliases.invert # DISCUSS: maybe we can speed up by remembering the original options?
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_hash
|
32
|
+
super.merge(Hash[@aliases.collect { |aka, k| key?(k) ? [aka, self[k]] : nil }.compact]) # FIXME: performance!
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,18 +1,35 @@
|
|
1
|
+
require "trailblazer/context/aliasing"
|
2
|
+
|
1
3
|
module Trailblazer
|
2
4
|
class Context
|
3
5
|
class IndifferentAccess < Context
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
module InstanceMethods
|
7
|
+
def [](name)
|
8
|
+
# TODO: well...
|
9
|
+
@mutable_options.key?(name.to_sym) and return @mutable_options[name.to_sym]
|
10
|
+
@mutable_options.key?(name.to_s) and return @mutable_options[name.to_s]
|
11
|
+
@wrapped_options.key?(name.to_sym) and return @wrapped_options[name.to_sym]
|
12
|
+
@wrapped_options[name.to_s]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.build(wrapped_options, mutable_options, (ctx, flow_options), circuit_options)
|
16
|
+
new(wrapped_options, mutable_options, flow_options)
|
17
|
+
end
|
10
18
|
end
|
19
|
+
include InstanceMethods
|
11
20
|
|
12
21
|
def key?(name)
|
13
22
|
super(name.to_sym) || super(name.to_s)
|
14
23
|
end
|
15
24
|
|
25
|
+
include Aliasing # FIXME
|
26
|
+
|
27
|
+
# This also builds IndifferentAccess::Aliasing.
|
28
|
+
# The {#build} method is designed to take all args from {for_circuit} and then
|
29
|
+
# translate that to the constructor.
|
30
|
+
def self.build(wrapped_options, mutable_options, (ctx, flow_options), circuit_options)
|
31
|
+
new(wrapped_options, mutable_options, **flow_options)
|
32
|
+
end
|
16
33
|
end
|
17
34
|
end
|
18
35
|
end
|
data/lib/trailblazer/option.rb
CHANGED
@@ -27,13 +27,13 @@ module Trailblazer
|
|
27
27
|
# Note that both #evaluate_callable and #evaluate_method drop most of the args.
|
28
28
|
# If you need those, override this class.
|
29
29
|
# @private
|
30
|
-
def self.evaluate_callable(proc, *args, **
|
30
|
+
def self.evaluate_callable(proc, *args, **circuit_options, &block)
|
31
31
|
call!(proc, *args, &block)
|
32
32
|
end
|
33
33
|
|
34
34
|
# Make the context's instance method a "lambda" and reuse #call!.
|
35
35
|
# @private
|
36
|
-
def self.evaluate_method(proc, *args, exec_context: raise("No :exec_context given."), **
|
36
|
+
def self.evaluate_method(proc, *args, exec_context: raise("No :exec_context given."), **circuit_options, &block)
|
37
37
|
call!(exec_context.method(proc), *args, &block)
|
38
38
|
end
|
39
39
|
|
data/test/context_test.rb
CHANGED
@@ -75,7 +75,7 @@ class ContextWithIndifferentAccessTest < Minitest::Spec
|
|
75
75
|
|
76
76
|
immutable = {model: Object, "policy" => Hash}
|
77
77
|
|
78
|
-
ctx = Trailblazer::Context.
|
78
|
+
ctx = Trailblazer::Context.for_circuit(immutable, {}, [immutable, flow_options], circuit_options)
|
79
79
|
|
80
80
|
ctx[:model].must_equal Object
|
81
81
|
ctx["model"].must_equal Object
|
@@ -92,7 +92,7 @@ class ContextWithIndifferentAccessTest < Minitest::Spec
|
|
92
92
|
ctx.key?(:"contract.default").must_equal true
|
93
93
|
|
94
94
|
# context in context
|
95
|
-
ctx2 = Trailblazer::Context.
|
95
|
+
ctx2 = Trailblazer::Context.for_circuit(ctx, {}, [ctx, flow_options], circuit_options)
|
96
96
|
|
97
97
|
ctx2[:model].must_equal Object
|
98
98
|
ctx2["model"].must_equal Object
|
@@ -120,6 +120,94 @@ class ContextWithIndifferentAccessTest < Minitest::Spec
|
|
120
120
|
ctx3.key?("result").must_equal true
|
121
121
|
ctx3.key?(:result).must_equal true
|
122
122
|
end
|
123
|
+
|
124
|
+
it "Aliasable" do
|
125
|
+
flow_options = {context_alias: {"contract.default" => :contract, "result.default"=>:result, "trace.stack" => :stack}}
|
126
|
+
circuit_options = {}
|
127
|
+
|
128
|
+
immutable = {model: Object, "policy" => Hash}
|
129
|
+
|
130
|
+
ctx = Trailblazer::Context.for_circuit(immutable, {}, [immutable, flow_options], circuit_options)
|
131
|
+
|
132
|
+
ctx[:model].must_equal Object
|
133
|
+
ctx["model"].must_equal Object
|
134
|
+
ctx[:policy].must_equal Hash
|
135
|
+
ctx["policy"].must_equal Hash
|
136
|
+
|
137
|
+
ctx["contract.default"] = Module
|
138
|
+
ctx["contract.default"].must_equal Module
|
139
|
+
ctx[:"contract.default"].must_equal Module
|
140
|
+
|
141
|
+
# alias
|
142
|
+
ctx[:result].must_equal nil
|
143
|
+
ctx["result"].must_equal nil
|
144
|
+
|
145
|
+
ctx[:contract].must_equal Module
|
146
|
+
|
147
|
+
ctx[:stack].must_equal nil
|
148
|
+
|
149
|
+
# Set an aliased property via setter
|
150
|
+
ctx["trace.stack"] = Object
|
151
|
+
ctx[:stack].must_equal Object
|
152
|
+
ctx["trace.stack"].must_equal Object
|
153
|
+
|
154
|
+
# key?
|
155
|
+
ctx.key?("____contract.default").must_equal false
|
156
|
+
ctx.key?("contract.default").must_equal true
|
157
|
+
ctx.key?(:"contract.default").must_equal true
|
158
|
+
ctx.key?(:contract).must_equal true
|
159
|
+
ctx.key?(:result).must_equal false
|
160
|
+
ctx.key?(:stack).must_equal true
|
161
|
+
ctx.key?("trace.stack").must_equal true
|
162
|
+
ctx.key?(:"trace.stack").must_equal true
|
163
|
+
|
164
|
+
# to_hash
|
165
|
+
ctx.to_hash.must_equal(:model=>Object, :policy=>Hash, :"contract.default"=>Module, :"trace.stack"=>Object, :contract=>Module, :stack=>Object)
|
166
|
+
|
167
|
+
# context in context
|
168
|
+
ctx2 = Trailblazer::Context.for_circuit(ctx, {}, [ctx, flow_options], circuit_options)
|
169
|
+
|
170
|
+
ctx2.key?("____contract.default").must_equal false
|
171
|
+
ctx2.key?("contract.default").must_equal true
|
172
|
+
ctx2.key?(:"contract.default").must_equal true
|
173
|
+
ctx2.key?(:contract).must_equal true
|
174
|
+
ctx2.key?(:result).must_equal false
|
175
|
+
ctx2.key?("result.default").must_equal false
|
176
|
+
ctx2.key?(:stack).must_equal true
|
177
|
+
ctx2.key?("trace.stack").must_equal true
|
178
|
+
ctx2.key?(:"trace.stack").must_equal true
|
179
|
+
|
180
|
+
# Set aliased in new context via setter
|
181
|
+
ctx2["result.default"] = Class
|
182
|
+
|
183
|
+
ctx2[:result].must_equal Class
|
184
|
+
ctx2[:"result.default"].must_equal Class
|
185
|
+
|
186
|
+
ctx2.key?("result.default").must_equal true
|
187
|
+
ctx2.key?(:"result.default").must_equal true
|
188
|
+
ctx2.key?(:result).must_equal true
|
189
|
+
|
190
|
+
# todo: TEST flow_options={context_class: SomethingElse}
|
191
|
+
end
|
192
|
+
|
193
|
+
it ".build provides default args" do
|
194
|
+
immutable = {model: Object, "policy.default" => Hash}
|
195
|
+
|
196
|
+
# {Aliasing#initialize}
|
197
|
+
ctx = Trailblazer::Context::IndifferentAccess.new(immutable, {}, context_alias: {"policy.default" => :policy})
|
198
|
+
|
199
|
+
ctx[:model].must_equal Object
|
200
|
+
ctx["model"].must_equal Object
|
201
|
+
ctx[:policy].must_equal Hash
|
202
|
+
|
203
|
+
ctx2 = ctx.merge(result: :success)
|
204
|
+
|
205
|
+
|
206
|
+
ctx2[:model].must_equal Object
|
207
|
+
ctx2["model"].must_equal Object
|
208
|
+
ctx2[:policy].must_equal Hash
|
209
|
+
ctx2[:result].must_equal :success
|
210
|
+
end
|
123
211
|
end
|
124
212
|
|
125
213
|
# TODO: test overriding Context.implementation.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-context
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- lib/trailblazer-context.rb
|
87
87
|
- lib/trailblazer/container_chain.rb
|
88
88
|
- lib/trailblazer/context.rb
|
89
|
+
- lib/trailblazer/context/aliasing.rb
|
89
90
|
- lib/trailblazer/context/indifferent_access.rb
|
90
91
|
- lib/trailblazer/context/version.rb
|
91
92
|
- lib/trailblazer/option.rb
|