trailblazer-context 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f888d046e1096b02494a7a5fede3827027321d7553d6a01fb5f7ac2dc9fb43cc
4
- data.tar.gz: 67f3bd4537ea2671a94ac3a74c55ed2f49ed9e9b58169af8eb2e1767fbc0416b
3
+ metadata.gz: fec7a9c801fedda32fee29585bf8108b6a730980fe826df22d00cd7f0b6c8d1b
4
+ data.tar.gz: 6a39db80e891a99c802c1262b26434389869fc2b367c34cfffb5923acdd574b4
5
5
  SHA512:
6
- metadata.gz: 950342604fd800574b188606453e5dbe2b685fe8bb49c8b4c042d27c4beb91be298c2a4a0e07cc509164b6c5ebc0987785e631f487179dbecffacfb180a11ca3
7
- data.tar.gz: f8fafddb80a3441a623c0db104776919313ff99f4eea0d2c0aa8826c00ba0fb89319294e0c3f892db11061825d41f67e9d2d68637768ce67be984533c1d92230
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.
@@ -14,10 +14,22 @@ module Trailblazer
14
14
  # only public creator: Build
15
15
  # :data object:
16
16
  class Context
17
- # NOTE: in the future, we might look up the Context to use in the ctx.
18
- # The options we pass in here to be forward-compatible.
19
- def self.for(wrapped_options, (ctx, flow_options), circuit_options)
20
- implementation.new(wrapped_options, {})
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
- def [](name)
5
- # TODO: well...
6
- @mutable_options.key?(name.to_sym) and return @mutable_options[name.to_sym]
7
- @mutable_options.key?(name.to_s) and return @mutable_options[name.to_s]
8
- @wrapped_options.key?(name.to_sym) and return @wrapped_options[name.to_sym]
9
- @wrapped_options[name.to_s]
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
@@ -1,5 +1,5 @@
1
1
  module Trailblazer
2
2
  class Context
3
- VERSION = "0.1.4"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -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, **flow_options, &block)
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."), **flow_options, &block)
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.for(immutable, [immutable, flow_options], circuit_options)
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.for(ctx, [ctx, flow_options], circuit_options)
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.1.4
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-07-18 00:00:00.000000000 Z
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