trailblazer-operation 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +223 -0
- data/.travis.yml +6 -7
- data/CHANGES.md +2 -14
- data/Gemfile +4 -2
- data/README.md +13 -2
- data/Rakefile +2 -2
- data/lib/trailblazer/operation.rb +53 -67
- data/lib/trailblazer/operation/class_dependencies.rb +1 -1
- data/lib/trailblazer/operation/container.rb +14 -0
- data/lib/trailblazer/operation/deprecated_macro.rb +2 -2
- data/lib/trailblazer/operation/inspect.rb +17 -27
- data/lib/trailblazer/operation/public_call.rb +16 -18
- data/lib/trailblazer/operation/railway.rb +2 -3
- data/lib/trailblazer/operation/railway/macaroni.rb +2 -2
- data/lib/trailblazer/operation/result.rb +14 -1
- data/lib/trailblazer/operation/trace.rb +5 -8
- data/lib/trailblazer/operation/version.rb +4 -2
- data/test/benchmark/skill_resolver_benchmark.rb +8 -9
- data/test/call_test.rb +56 -30
- data/test/callable_test.rb +147 -147
- data/test/class_dependencies_test.rb +6 -7
- data/test/docs/doormat_test.rb +13 -12
- data/test/docs/macaroni_test.rb +7 -9
- data/test/docs/operation_test.rb +69 -4
- data/test/docs/wiring_test.rb +98 -53
- data/test/dry_container_test.rb +4 -3
- data/test/fast_track_test.rb +24 -44
- data/test/inheritance_test.rb +13 -12
- data/test/inspect_test.rb +6 -7
- data/test/introspect_test.rb +6 -6
- data/test/operation_test.rb +17 -25
- data/test/result_test.rb +4 -4
- data/test/ruby-2.0.0/operation_test.rb +9 -9
- data/test/ruby-2.0.0/step_test.rb +17 -16
- data/test/step_test.rb +47 -42
- data/test/test_helper.rb +6 -13
- data/test/trace_test.rb +26 -26
- data/test/wiring/defaults_test.rb +29 -33
- data/trailblazer-operation.gemspec +7 -6
- metadata +26 -18
- data/lib/trailblazer/operation/heritage.rb +0 -30
- data/lib/trailblazer/operation/inject.rb +0 -36
- data/lib/trailblazer/operation/railway/fast_track.rb +0 -13
- data/lib/trailblazer/operation/railway/normalizer.rb +0 -58
- data/lib/trailblazer/operation/railway/task_builder.rb +0 -37
- data/test/macro_test.rb +0 -60
- data/test/task_wrap_test.rb +0 -97
@@ -16,7 +16,7 @@ class Trailblazer::Operation
|
|
16
16
|
# The use of this module is not encouraged and it is only here for backward-compatibility.
|
17
17
|
# Instead, please pass dependencies via containers, locals, or macros into the respective steps.
|
18
18
|
module ClassDependencies
|
19
|
-
def call_with_circuit_interface(
|
19
|
+
def call_with_circuit_interface((ctx, flow_options), **circuit_options)
|
20
20
|
@skills.each { |name, value| ctx[name] ||= value } # this resembles the behavior in 2.0. we didn't say we liked it.
|
21
21
|
|
22
22
|
super
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
module Operation::Container
|
3
|
+
def options_for_public_call(options={}, *containers)
|
4
|
+
# generate the skill hash that embraces runtime options plus potential containers, the so called Runtime options.
|
5
|
+
# This wrapping is supposed to happen once in the entire system.
|
6
|
+
|
7
|
+
hash_transformer = ->(containers) { containers[0].to_hash } # FIXME: don't transform any containers into kw args.
|
8
|
+
|
9
|
+
immutable_options = Trailblazer::Context::ContainerChain.new([options, *containers], to_hash: hash_transformer)
|
10
|
+
|
11
|
+
Trailblazer::Context(immutable_options)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -5,7 +5,7 @@ module Trailblazer
|
|
5
5
|
def self.call(proc, options)
|
6
6
|
warn %{[Trailblazer] Macros with API (input, options) are deprecated. Please use the "Task API" signature (options, flow_options) or use a simpler Callable. (#{proc})}
|
7
7
|
|
8
|
-
wrapped_proc = ->(
|
8
|
+
wrapped_proc = ->((options, flow_options), **circuit_options) do
|
9
9
|
result = proc.(circuit_options[:exec_context], options) # run the macro, with the deprecated signature.
|
10
10
|
|
11
11
|
direction = Activity::TaskBuilder.binary_signal_for(result, Activity::Right, Activity::Left)
|
@@ -13,7 +13,7 @@ module Trailblazer
|
|
13
13
|
return direction, [options, flow_options]
|
14
14
|
end
|
15
15
|
|
16
|
-
options.merge(
|
16
|
+
options.merge(task: wrapped_proc)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -14,31 +14,21 @@ module Trailblazer
|
|
14
14
|
module Operation::Inspect
|
15
15
|
module_function
|
16
16
|
|
17
|
-
def call(operation, options={
|
18
|
-
|
17
|
+
def call(operation, options = {style: :line})
|
18
|
+
graph = Activity::Introspect::Graph(operation)
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
rows = graph.collect do |node, i|
|
21
|
+
next if node[:data][:stop_event] # DISCUSS: show this?
|
22
22
|
|
23
|
-
|
24
|
-
railway = alterations.instance_variable_get(:@groups).instance_variable_get(:@groups)[:main]
|
23
|
+
created_by = node[:data][:dsl_track] || :pass
|
25
24
|
|
26
|
-
|
27
|
-
|
25
|
+
[i, [created_by, node.id]]
|
26
|
+
end.compact
|
28
27
|
|
29
|
-
|
30
|
-
if magnetic_to == [:failure]
|
31
|
-
:fail
|
32
|
-
elsif plus_poles.size > 1
|
33
|
-
plus_poles[0].color == plus_poles[1].color ? :pass : :step
|
34
|
-
else
|
35
|
-
:pass # this is wrong for Nested, sometimes
|
36
|
-
end
|
37
|
-
|
38
|
-
[ i, [ created_by, element.id ] ]
|
39
|
-
end
|
28
|
+
rows = rows[1..-1] # remove start
|
40
29
|
|
41
30
|
return inspect_line(rows) if options[:style] == :line
|
31
|
+
|
42
32
|
return inspect_rows(rows)
|
43
33
|
end
|
44
34
|
|
@@ -46,7 +36,7 @@ module Trailblazer
|
|
46
36
|
@inspect[step]
|
47
37
|
end
|
48
38
|
|
49
|
-
Operator = {
|
39
|
+
Operator = {fail: "<<", pass: ">>", step: ">"}
|
50
40
|
|
51
41
|
def inspect_line(names)
|
52
42
|
string = names.collect { |i, (end_of_edge, name)| "#{Operator[end_of_edge]}#{name}" }.join(",")
|
@@ -61,13 +51,13 @@ module Trailblazer
|
|
61
51
|
padding = 38
|
62
52
|
|
63
53
|
proc = if operator == "<<"
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
54
|
+
sprintf("%- #{padding}s", op)
|
55
|
+
elsif [">", ">>", "&"].include?(operator.to_s)
|
56
|
+
sprintf("% #{padding}s", op)
|
57
|
+
else
|
58
|
+
pad = " " * ((padding - op.length) / 2)
|
59
|
+
"#{pad}#{op}#{pad}"
|
60
|
+
end
|
71
61
|
|
72
62
|
proc = proc.gsub(" ", "=")
|
73
63
|
|
@@ -15,41 +15,39 @@ module Trailblazer
|
|
15
15
|
# @return Operation::Railway::Result binary result object
|
16
16
|
def call(*args)
|
17
17
|
return call_with_circuit_interface(*args) if args.any? && args[0].is_a?(Array) # This is kind of a hack that could be well hidden if Ruby had method overloading. Goal is to simplify the call/__call__ thing as we're fading out Operation::call anyway.
|
18
|
+
|
18
19
|
call_with_public_interface(*args)
|
19
20
|
end
|
20
21
|
|
21
22
|
def call_with_public_interface(*args)
|
22
|
-
ctx =
|
23
|
+
ctx = options_for_public_call(*args)
|
23
24
|
|
24
25
|
# call the activity.
|
25
26
|
# This will result in invoking {::call_with_circuit_interface}.
|
26
|
-
last_signal, (options, flow_options) = Activity::TaskWrap.invoke(self, [ctx, {}], {})
|
27
|
+
# last_signal, (options, flow_options) = Activity::TaskWrap.invoke(self, [ctx, {}], {})
|
28
|
+
signal, (ctx, flow_options) = Activity::TaskWrap.invoke(
|
29
|
+
@activity,
|
30
|
+
[ctx, {}],
|
31
|
+
exec_context: new
|
32
|
+
)
|
27
33
|
|
28
34
|
# Result is successful if the activity ended with an End event derived from Railway::End::Success.
|
29
|
-
Operation::Railway::Result(
|
35
|
+
Operation::Railway::Result(signal, ctx, flow_options)
|
30
36
|
end
|
31
37
|
|
32
38
|
# This interface is used for all nested OPs (and the outer-most, too).
|
33
39
|
def call_with_circuit_interface(args, circuit_options)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
)
|
40
|
+
strategy_call(args, circuit_options) # FastTrack#call
|
41
|
+
end
|
42
|
+
|
43
|
+
def options_for_public_call(*args)
|
44
|
+
Operation::PublicCall.options_for_public_call(*args)
|
40
45
|
end
|
41
46
|
|
42
47
|
# Compile a Context object to be passed into the Activity::call.
|
43
48
|
# @private
|
44
|
-
def self.options_for_public_call(options={}
|
45
|
-
|
46
|
-
# This wrapping is supposed to happen once in the entire system.
|
47
|
-
|
48
|
-
hash_transformer = ->(containers) { containers[0].to_hash } # FIXME: don't transform any containers into kw args.
|
49
|
-
|
50
|
-
immutable_options = Trailblazer::Context::ContainerChain.new( [options, *containers], to_hash: hash_transformer ) # Runtime options, immutable.
|
51
|
-
|
52
|
-
ctx = Trailblazer::Context(immutable_options)
|
49
|
+
def self.options_for_public_call(options={})
|
50
|
+
Trailblazer::Context(options)
|
53
51
|
end
|
54
52
|
end
|
55
53
|
end
|
@@ -7,13 +7,13 @@ module Trailblazer
|
|
7
7
|
# def my_step( params:, options:, ** )
|
8
8
|
module Macaroni
|
9
9
|
def self.call(user_proc)
|
10
|
-
Activity::TaskBuilder::Task.new(
|
10
|
+
Activity::TaskBuilder::Task.new(Trailblazer::Option.build(Macaroni::Option, user_proc), user_proc)
|
11
11
|
end
|
12
12
|
|
13
13
|
class Option < Trailblazer::Option
|
14
14
|
# The Option#call! method prepares the arguments.
|
15
15
|
def self.call!(proc, options, *)
|
16
|
-
proc.(
|
16
|
+
proc.(**options.to_hash.merge(options: options))
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -11,7 +11,15 @@ class Trailblazer::Operation
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def failure?
|
14
|
-
!
|
14
|
+
!success?
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
data.to_hash
|
19
|
+
end
|
20
|
+
|
21
|
+
def keys
|
22
|
+
data.to_hash.keys
|
15
23
|
end
|
16
24
|
|
17
25
|
extend Forwardable
|
@@ -20,11 +28,16 @@ class Trailblazer::Operation
|
|
20
28
|
# DISCUSS: the two methods below are more for testing.
|
21
29
|
def inspect(*slices)
|
22
30
|
return "<Result:#{success?} #{slice(*slices).inspect} >" if slices.any?
|
31
|
+
|
23
32
|
"<Result:#{success?} #{@data.inspect} >"
|
24
33
|
end
|
25
34
|
|
26
35
|
def slice(*keys)
|
27
36
|
keys.collect { |k| self[k] }
|
28
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_reader :data
|
29
42
|
end
|
30
43
|
end
|
@@ -3,16 +3,13 @@ module Trailblazer
|
|
3
3
|
module Trace
|
4
4
|
# @note The problem in this method is, we have redundancy with Operation::PublicCall
|
5
5
|
def self.call(operation, *args)
|
6
|
-
ctx = PublicCall.options_for_public_call(*args)
|
6
|
+
ctx = PublicCall.options_for_public_call(*args) # redundant with PublicCall::call.
|
7
7
|
|
8
|
-
|
9
|
-
operation, *args = Trailblazer::Activity::Trace.arguments_for_call( operation, [ctx, {}], {} )
|
8
|
+
stack, signal, (ctx, _flow_options) = Activity::Trace.(operation, [ctx, {}])
|
10
9
|
|
11
|
-
|
10
|
+
result = Railway::Result(signal, ctx) # redundant with PublicCall::call.
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
Result.new(result, flow_options[:stack].to_a)
|
12
|
+
Result.new(result, stack.to_a)
|
16
13
|
end
|
17
14
|
|
18
15
|
# `Operation::trace` is included for simple tracing of the flow.
|
@@ -20,7 +17,7 @@ module Trailblazer
|
|
20
17
|
#
|
21
18
|
# @public
|
22
19
|
#
|
23
|
-
# Operation.trace(params,
|
20
|
+
# Operation.trace(params, current_user: current_user).wtf
|
24
21
|
def trace(*args)
|
25
22
|
Trace.(self, *args)
|
26
23
|
end
|
@@ -11,28 +11,27 @@ normal_container = {}
|
|
11
11
|
normal_container["xbla_#{i}"] = i
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
14
|
Benchmark.ips do |x|
|
16
|
-
x.report(:merge)
|
15
|
+
x.report(:merge) do
|
17
16
|
attrs = normal_container.merge(initialize_hash)
|
18
|
-
10.times do |
|
17
|
+
10.times do |_i|
|
19
18
|
attrs["bla_8"]
|
20
19
|
end
|
21
|
-
10.times do |
|
20
|
+
10.times do |_i|
|
22
21
|
attrs["xbla_1"]
|
23
22
|
end
|
24
|
-
|
23
|
+
end
|
25
24
|
|
26
|
-
x.report(:resolver)
|
25
|
+
x.report(:resolver) do
|
27
26
|
attrs = Trailblazer::Skill::Resolver.new(initialize_hash, normal_container)
|
28
27
|
|
29
|
-
10.times do |
|
28
|
+
10.times do |_i|
|
30
29
|
attrs["bla_8"]
|
31
30
|
end
|
32
|
-
10.times do |
|
31
|
+
10.times do |_i|
|
33
32
|
attrs["xbla_1"]
|
34
33
|
end
|
35
|
-
|
34
|
+
end
|
36
35
|
end
|
37
36
|
|
38
37
|
# Warming up --------------------------------------
|
data/test/call_test.rb
CHANGED
@@ -1,47 +1,73 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
3
|
class CallTest < Minitest::Spec
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
"#{@skills.inspect}"
|
9
|
-
end
|
4
|
+
class Create < Trailblazer::Operation
|
5
|
+
step ->(*) { true }
|
6
|
+
def inspect
|
7
|
+
@skills.inspect.to_s
|
10
8
|
end
|
9
|
+
end
|
11
10
|
|
12
|
-
|
11
|
+
it { Create.().must_be_instance_of Trailblazer::Operation::Railway::Result }
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
# it { Create.({}).inspect.must_equal %{<Result:true <Skill {} {\"params\"=>{}} {\"pipetree\"=>[>operation.new]}> >} }
|
14
|
+
# it { Create.(name: "Jacob").inspect.must_equal %{<Result:true <Skill {} {\"params\"=>{:name=>\"Jacob\"}} {\"pipetree\"=>[>operation.new]}> >} }
|
15
|
+
# it { Create.({ name: "Jacob" }, { policy: Object }).inspect.must_equal %{<Result:true <Skill {} {:policy=>Object, \"params\"=>{:name=>\"Jacob\"}} {\"pipetree\"=>[>operation.new]}> >} }
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
#---
|
18
|
+
# success?
|
19
|
+
class Update < Trailblazer::Operation
|
20
|
+
step ->(ctx, **) { ctx[:result] }
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
# operation success
|
24
|
+
it do
|
25
|
+
result = Update.(result: true)
|
27
26
|
|
28
|
-
|
27
|
+
result.success?.must_equal true
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Success
|
30
|
+
result.event.must_equal Update.to_h[:outputs][0].signal
|
31
|
+
end
|
32
|
+
|
33
|
+
# operation failure
|
34
|
+
it do
|
35
|
+
result = Update.(result: false)
|
33
36
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
result.success?.must_equal false
|
38
|
+
result.failure?.must_equal true
|
39
|
+
|
40
|
+
result.event.must_be_instance_of Trailblazer::Operation::Railway::End::Failure
|
41
|
+
result.event.must_equal Update.to_h[:outputs].find { |output| output.semantic == :failure }.signal
|
42
|
+
end
|
37
43
|
|
38
|
-
|
39
|
-
|
44
|
+
it "invokes with the taskWrap" do
|
45
|
+
operation = Class.new(Trailblazer::Operation) do
|
46
|
+
include Trailblazer::Activity::Testing.def_steps(:a)
|
40
47
|
|
41
|
-
|
42
|
-
|
48
|
+
def self.add_1(wrap_ctx, original_args)
|
49
|
+
ctx, = original_args[0]
|
50
|
+
ctx[:seq] << 1
|
51
|
+
return wrap_ctx, original_args # yay to mutable state. not.
|
52
|
+
end
|
53
|
+
|
54
|
+
merge = [
|
55
|
+
[Trailblazer::Activity::TaskWrap::Pipeline.method(:insert_before), "task_wrap.call_task", ["user.add_1", method(:add_1)]]
|
56
|
+
]
|
57
|
+
|
58
|
+
step :a, extensions: [Trailblazer::Activity::TaskWrap::Extension(merge: merge)]
|
43
59
|
end
|
44
60
|
|
61
|
+
# normal operation invocation
|
62
|
+
result = operation.(seq: [])
|
63
|
+
|
64
|
+
result.inspect(:seq).must_equal %{<Result:true [[1, :a]] >}
|
65
|
+
|
66
|
+
# with tracing
|
67
|
+
result = operation.trace(seq: [])
|
68
|
+
|
69
|
+
result.inspect(:seq).must_equal %{<Result:true [[1, :a]] >}
|
70
|
+
|
71
|
+
result.wtf?
|
45
72
|
end
|
46
73
|
end
|
47
|
-
|
data/test/callable_test.rb
CHANGED
@@ -1,147 +1,147 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class CallableHelper < Minitest::Spec
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
1
|
+
# require "test_helper"
|
2
|
+
|
3
|
+
# class CallableHelper < Minitest::Spec
|
4
|
+
# Operation = Trailblazer::Operation
|
5
|
+
# Activity = Trailblazer::Activity
|
6
|
+
|
7
|
+
# module Blog
|
8
|
+
# Read = ->((options, *args), *) { options["Read"] = 1; [ Activity::Right, [options, *args] ] }
|
9
|
+
# Next = ->((options, *args), *) { options["NextPage"] = []; [ options["return"], [options, *args] ] }
|
10
|
+
# Comment = ->((options, *args), *) { options["Comment"] = 2; [ Activity::Right, [options, *args] ] }
|
11
|
+
# end
|
12
|
+
|
13
|
+
# module User
|
14
|
+
# Relax = ->((options, *args), *) { options["Relax"]=true; [ Activity::Right, [options, *args] ] }
|
15
|
+
# end
|
16
|
+
|
17
|
+
# ### Callable( )
|
18
|
+
# ###
|
19
|
+
# describe "circuit with 1 level of nesting" do # TODO: test this kind of configuration in dsl_tests somewhere.
|
20
|
+
# let(:blog) do
|
21
|
+
# Module.new do
|
22
|
+
# extend Activity::Path()
|
23
|
+
|
24
|
+
# task task: Blog::Read
|
25
|
+
# task task: Blog::Next, Output(Activity::Right, :done) => "End.success", Output(Activity::Left, :success) => Track(:success)
|
26
|
+
# task task: Blog::Comment
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
# let(:user) do
|
31
|
+
# _blog = blog
|
32
|
+
|
33
|
+
# Module.new do
|
34
|
+
# extend Activity::Path()
|
35
|
+
|
36
|
+
# task task: _blog, _blog.outputs[:success] => Track(:success)
|
37
|
+
# task task: User::Relax
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
|
41
|
+
# it "ends before comment, on next_page" do
|
42
|
+
# user.( [options = { "return" => Activity::Right }] ).must_equal(
|
43
|
+
# [user.outputs[:success].signal, [{"return"=>Trailblazer::Activity::Right, "Read"=>1, "NextPage"=>[], "Relax"=>true}]]
|
44
|
+
# )
|
45
|
+
|
46
|
+
# options.must_equal({"return"=>Trailblazer::Activity::Right, "Read"=>1, "NextPage"=>[], "Relax"=>true})
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
|
50
|
+
# ### Callable( End1, End2 )
|
51
|
+
# ###
|
52
|
+
# describe "circuit with 2 end events in the nested process" do
|
53
|
+
# let(:blog) do
|
54
|
+
# Module.new do
|
55
|
+
# extend Activity::Path()
|
56
|
+
|
57
|
+
# task task: Blog::Read
|
58
|
+
# task task: Blog::Next, Output(Activity::Right, :success___) => :__success, Output(Activity::Left, :retry___) => _retry=End(:retry)
|
59
|
+
# end
|
60
|
+
# end
|
61
|
+
|
62
|
+
# let(:user) do
|
63
|
+
# _blog = blog
|
64
|
+
|
65
|
+
# Module.new do
|
66
|
+
# extend Activity::Path()
|
67
|
+
|
68
|
+
# task task: _blog, _blog.outputs[:success] => Track(:success), _blog.outputs[:retry] => "End.success"
|
69
|
+
# task task: User::Relax
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
|
73
|
+
# it "runs from Callable->default to Relax" do
|
74
|
+
# user.( [ options = { "return" => Activity::Right } ] ).must_equal [
|
75
|
+
# user.outputs[:success].signal,
|
76
|
+
# [ {"return"=>Activity::Right, "Read"=>1, "NextPage"=>[], "Relax"=>true} ]
|
77
|
+
# ]
|
78
|
+
|
79
|
+
# options.must_equal({"return"=>Activity::Right, "Read"=>1, "NextPage"=>[], "Relax"=>true})
|
80
|
+
# end
|
81
|
+
|
82
|
+
# it "runs from other Callable end" do
|
83
|
+
# user.( [ options = { "return" => Activity::Left } ] ).must_equal [
|
84
|
+
# user.outputs[:success].signal,
|
85
|
+
# [ {"return"=>Activity::Left, "Read"=>1, "NextPage"=>[]} ]
|
86
|
+
# ]
|
87
|
+
|
88
|
+
# options.must_equal({"return"=>Activity::Left, "Read"=>1, "NextPage"=>[]})
|
89
|
+
# end
|
90
|
+
|
91
|
+
# #---
|
92
|
+
# #- Callable( activity, start_at )
|
93
|
+
# let(:with_nested_and_start_at) do
|
94
|
+
# _blog = blog
|
95
|
+
|
96
|
+
# Module.new do
|
97
|
+
# extend Activity::Path()
|
98
|
+
|
99
|
+
# task task: Operation::Callable( _blog, start_task: Blog::Next ), _blog.outputs[:success] => Track(:success)
|
100
|
+
# task task: User::Relax
|
101
|
+
# end
|
102
|
+
# end
|
103
|
+
|
104
|
+
# it "runs Callable from alternative start" do
|
105
|
+
# with_nested_and_start_at.( [options = { "return" => Activity::Right }] ).
|
106
|
+
# must_equal [
|
107
|
+
# with_nested_and_start_at.outputs[:success].signal,
|
108
|
+
# [ {"return"=>Activity::Right, "NextPage"=>[], "Relax"=>true} ]
|
109
|
+
# ]
|
110
|
+
|
111
|
+
# options.must_equal({"return"=>Activity::Right, "NextPage"=>[], "Relax"=>true})
|
112
|
+
# end
|
113
|
+
|
114
|
+
# #---
|
115
|
+
# #- Callable( activity, call: :__call__ ) { ... }
|
116
|
+
# describe "Callable with :call option" do
|
117
|
+
# let(:process) do
|
118
|
+
# class Workout
|
119
|
+
# def self.__call__((options, *args), *)
|
120
|
+
# options[:workout] = 9
|
121
|
+
|
122
|
+
# return Activity::Right, [options, *args]
|
123
|
+
# end
|
124
|
+
# end
|
125
|
+
|
126
|
+
# subprocess = Operation::Callable( Workout, call: :__call__ )
|
127
|
+
|
128
|
+
# Module.new do
|
129
|
+
# extend Activity::Path()
|
130
|
+
|
131
|
+
# task task: subprocess
|
132
|
+
# task task: User::Relax
|
133
|
+
# end
|
134
|
+
# end
|
135
|
+
|
136
|
+
# it "runs Callable process with __call__" do
|
137
|
+
# process.( [options = { "return" => Activity::Right }] ).
|
138
|
+
# must_equal [
|
139
|
+
# process.outputs[:success].signal,
|
140
|
+
# [{"return"=>Activity::Right, :workout=>9, "Relax"=>true}]
|
141
|
+
# ]
|
142
|
+
|
143
|
+
# options.must_equal({"return"=>Activity::Right, :workout=>9, "Relax"=>true})
|
144
|
+
# end
|
145
|
+
# end
|
146
|
+
# end
|
147
|
+
# end
|