trailblazer-operation 0.0.3 → 0.0.4
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 +4 -0
- data/README.md +6 -0
- data/lib/trailblazer/operation.rb +2 -1
- data/lib/trailblazer/operation/generic.rb +1 -1
- data/lib/trailblazer/operation/{stepable.rb → macro.rb} +2 -2
- data/lib/trailblazer/operation/pipetree.rb +6 -3
- data/lib/trailblazer/operation/result.rb +2 -2
- data/lib/trailblazer/operation/skill.rb +14 -2
- data/lib/trailblazer/operation/version.rb +1 -1
- data/lib/trailblazer/skill.rb +21 -5
- data/test/gemfiles/Gemfile.ruby-1.9 +1 -0
- data/test/gemfiles/Gemfile.ruby-1.9.lock +2 -1
- data/test/pipetree_test.rb +1 -1
- data/test/skill_test.rb +1 -5
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06580a6dc8f0356b1c6b8216728703e5c994e0e1
|
4
|
+
data.tar.gz: c8f45a4f5066f203a59c04620fe90a2f464ded39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31fe5767c979b2224b6b06c18ffb76e3a60e99543788f219cc744cad361d69d1c710c18295835091c1e299a8966a5e81f2ca9eb02b295e5d273ae3ef8590e67d
|
7
|
+
data.tar.gz: c844b16ab00e425c533e9bc867520c4b88fb437ef63ddf949a41260a5a851af0b4577acb02d05fc7392235aa1d05ac9481a7516b3b1f3a2e906cd6e5c155058d
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
1
|
## Goal
|
2
2
|
|
3
3
|
* Make `Operation` an imutable object without having to expose @instance variables. This is now done via the Result object.
|
4
|
+
|
5
|
+
## Copyright
|
6
|
+
|
7
|
+
Copyright (c) 2016 Nick Sutterer <apotonick@gmail.com>
|
8
|
+
|
9
|
+
`trailblazer-operation` is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
@@ -2,7 +2,7 @@ require "declarative" # FIXME: here?
|
|
2
2
|
require "trailblazer/operation/skill"
|
3
3
|
require "trailblazer/operation/pipetree"
|
4
4
|
require "trailblazer/operation/generic"
|
5
|
-
require "trailblazer/operation/
|
5
|
+
require "trailblazer/operation/macro"
|
6
6
|
|
7
7
|
module Trailblazer
|
8
8
|
# The Trailblazer-style operation.
|
@@ -16,6 +16,7 @@ module Trailblazer
|
|
16
16
|
include Pipetree # ::call, ::|
|
17
17
|
# we want the skill dependency-mechanism.
|
18
18
|
extend Skill::Call # ::call
|
19
|
+
extend Skill::Call::Positional # ::call(params, options)
|
19
20
|
|
20
21
|
# we want the initializer and the ::call method.
|
21
22
|
include Generic # #initialize, #call, #process.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Trailblazer::Operation
|
2
|
-
module
|
2
|
+
module Macro
|
3
3
|
Configuration = Struct.new(:mod, :args, :block) do
|
4
|
-
include
|
4
|
+
include Macro # mark it, so that ::| thinks this is a step module.
|
5
5
|
|
6
6
|
def import!(operation, import)
|
7
7
|
mod.import!(operation, import, *args)
|
@@ -23,9 +23,12 @@ class Trailblazer::Operation
|
|
23
23
|
def call(options)
|
24
24
|
pipe = self["pipetree"] # TODO: injectable? WTF? how cool is that?
|
25
25
|
|
26
|
-
last, operation = pipe.(self, options)
|
26
|
+
last, operation = pipe.(self, options)
|
27
27
|
|
28
|
-
Result
|
28
|
+
# The reason the Result wraps the Skill object (`options`), not the operation
|
29
|
+
# itself is because the op should be irrelevant, plus when stopping the pipe
|
30
|
+
# before op instantiation, this would be confusing (and wrong!).
|
31
|
+
Result.new(last == ::Pipetree::Flow::Right, options)
|
29
32
|
end
|
30
33
|
|
31
34
|
# This method would be redundant if Ruby had a Class::finalize! method the way
|
@@ -56,7 +59,7 @@ class Trailblazer::Operation
|
|
56
59
|
end
|
57
60
|
|
58
61
|
def |(cfg, user_options={}) # sorry for the magic here, but still playing with the DSL.
|
59
|
-
if cfg.is_a?(
|
62
|
+
if cfg.is_a?(Macro) # e.g. Contract::Validate
|
60
63
|
import = Import.new(self, user_options)
|
61
64
|
|
62
65
|
return cfg.import!(self, import) &&
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class Trailblazer::Operation
|
2
2
|
class Result
|
3
3
|
def initialize(success, data)
|
4
|
-
@success, @data = success, data
|
4
|
+
@success, @data = success, data # @data is a Skill instance.
|
5
5
|
end
|
6
6
|
|
7
7
|
extend Uber::Delegates
|
8
|
-
delegates :@data, :[]
|
8
|
+
delegates :@data, :[] # DISCUSS: make it a real delegator? see Nested.
|
9
9
|
|
10
10
|
def success?
|
11
11
|
@success
|
@@ -23,9 +23,21 @@ class Trailblazer::Operation
|
|
23
23
|
|
24
24
|
# Overrides Operation::call, creates the Skill hash and passes it to :call.
|
25
25
|
module Call
|
26
|
-
def call(
|
27
|
-
super Trailblazer::Skill.new(
|
26
|
+
def call(options={}, *dependencies)
|
27
|
+
super Trailblazer::Skill.new(options, *dependencies, self.skills)
|
28
|
+
# DISCUSS: should this be: Trailblazer::Skill.new(runtime_options: [options, *dependencies], compiletime_options: [self.skills])
|
29
|
+
end
|
30
|
+
alias :_call :call
|
31
|
+
|
32
|
+
# It really sucks that Ruby doesn't have method overloading where we could simply have
|
33
|
+
# two different implementations of ::call.
|
34
|
+
# FIXME: that shouldn't be here in this namespace.
|
35
|
+
module Positional
|
36
|
+
def call(params={}, options={}, *dependencies)
|
37
|
+
super(options.merge("params" => params), *dependencies)
|
38
|
+
end
|
28
39
|
end
|
29
40
|
end
|
41
|
+
|
30
42
|
end
|
31
43
|
end
|
data/lib/trailblazer/skill.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
# TODO: mark/make all but mutable_options as frozen.
|
2
|
+
# The idea of Skill is to have a generic, ordered read/write interface that
|
3
|
+
# collects mutable runtime-computed data while providing access to compile-time
|
4
|
+
# information.
|
5
|
+
# The runtime-data takes precedence over the class data.
|
2
6
|
module Trailblazer
|
3
7
|
class Skill
|
4
|
-
def initialize(
|
5
|
-
@
|
6
|
-
@resolver
|
8
|
+
def initialize(*containers)
|
9
|
+
@mutable_options = {}
|
10
|
+
@resolver = Resolver.new(@mutable_options, *containers)
|
7
11
|
end
|
8
12
|
|
9
13
|
def [](name)
|
@@ -11,13 +15,25 @@ module Trailblazer
|
|
11
15
|
end
|
12
16
|
|
13
17
|
def []=(name, value)
|
14
|
-
@
|
18
|
+
@mutable_options[name] = value
|
19
|
+
end
|
20
|
+
|
21
|
+
# THIS METHOD IS CONSIDERED PRIVATE AND MIGHT BE REMOVED.
|
22
|
+
# Options from ::call (e.g. "user.current"), containers, etc.
|
23
|
+
# NO mutual data from the caller operation. no class state.
|
24
|
+
def to_runtime_data
|
25
|
+
@resolver.instance_variable_get(:@containers).slice(1..-2)
|
26
|
+
end
|
27
|
+
|
28
|
+
# THIS METHOD IS CONSIDERED PRIVATE AND MIGHT BE REMOVED.
|
29
|
+
def to_mutable_data
|
30
|
+
@mutable_options
|
15
31
|
end
|
16
32
|
|
17
33
|
# Look through a list of containers until you find the skill.
|
18
34
|
class Resolver
|
19
35
|
# alternative implementation:
|
20
|
-
# containers.reverse.each do |container| @
|
36
|
+
# containers.reverse.each do |container| @mutable_options.merge!(container) end
|
21
37
|
#
|
22
38
|
# benchmark, merging in #initialize vs. this resolver.
|
23
39
|
# merge 39.678k (± 9.1%) i/s - 198.700k in 5.056653s
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../../
|
3
3
|
specs:
|
4
|
-
trailblazer-operation (0.0.
|
4
|
+
trailblazer-operation (0.0.3)
|
5
5
|
declarative
|
6
6
|
pipetree (>= 0.0.4, < 0.1.0)
|
7
7
|
uber (>= 0.1.0, < 0.2.0)
|
@@ -23,6 +23,7 @@ DEPENDENCIES
|
|
23
23
|
bundler
|
24
24
|
declarative
|
25
25
|
minitest
|
26
|
+
pipetree
|
26
27
|
rake
|
27
28
|
trailblazer-operation!
|
28
29
|
|
data/test/pipetree_test.rb
CHANGED
@@ -2,7 +2,7 @@ require "test_helper"
|
|
2
2
|
|
3
3
|
class PipetreeTest < Minitest::Spec
|
4
4
|
module Validate
|
5
|
-
extend Trailblazer::Operation::
|
5
|
+
extend Trailblazer::Operation::Macro
|
6
6
|
|
7
7
|
def self.import!(operation, pipe)
|
8
8
|
pipe.(:>, ->{ snippet }, name: "validate", before: "operation.new")
|
data/test/skill_test.rb
CHANGED
@@ -14,9 +14,7 @@ class SkillTest < Minitest::Spec
|
|
14
14
|
"model.class" => Integer
|
15
15
|
}
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
skill = Trailblazer::Skill.new(mutable_options, runtime_skills, class_level_container)
|
17
|
+
skill = Trailblazer::Skill.new(runtime_skills, class_level_container)
|
20
18
|
|
21
19
|
# non-existent key.
|
22
20
|
skill[:nope].must_equal nil
|
@@ -34,8 +32,6 @@ class SkillTest < Minitest::Spec
|
|
34
32
|
# add new tuple.
|
35
33
|
skill["user.current"] = "Todd"
|
36
34
|
|
37
|
-
# options we add get added to the hash.
|
38
|
-
mutable_options.inspect.must_equal %{{"model.class"=>Fixnum, "user.current"=>"Todd"}}
|
39
35
|
# original container don't get changed
|
40
36
|
class_level_container.inspect.must_equal %{{"contract.class"=>Object, "model.class"=>String}}
|
41
37
|
runtime_skills.inspect.must_equal %{{"contract"=>SkillTest::MyContract, "model.class"=>Integer}}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-operation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: uber
|
@@ -121,10 +121,10 @@ files:
|
|
121
121
|
- Rakefile
|
122
122
|
- lib/trailblazer/operation.rb
|
123
123
|
- lib/trailblazer/operation/generic.rb
|
124
|
+
- lib/trailblazer/operation/macro.rb
|
124
125
|
- lib/trailblazer/operation/pipetree.rb
|
125
126
|
- lib/trailblazer/operation/result.rb
|
126
127
|
- lib/trailblazer/operation/skill.rb
|
127
|
-
- lib/trailblazer/operation/stepable.rb
|
128
128
|
- lib/trailblazer/operation/version.rb
|
129
129
|
- lib/trailblazer/skill.rb
|
130
130
|
- test/benchmark/skill_resolver_benchmark.rb
|