trailblazer-activity 0.9.1 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 943560a813f46719e16777daa7f1b58f93a5871838a6e1593a913ecc5a7475a5
4
- data.tar.gz: 0a4e4286edcb7319f0002d82388dbfa9c7005ed76d214884af91e8290ff86fe3
3
+ metadata.gz: 0b971b7f8960520b05bcc99a2fe0561056d9ec244cf9faeb072e131604e0bc12
4
+ data.tar.gz: ec6e1d2c4b2de4d1edfce435c08029a061df61b1b770ad174c005733238269cb
5
5
  SHA512:
6
- metadata.gz: f754c43ff0f0a815e52b3bb5f80f4962f3c3566262b6f731aed3a1b1237bc73a16824ad68dd795ca5f7f01349030907bba302fb56863de5a2f5d57e0d7b6924f
7
- data.tar.gz: 103a79e48cf54ca69767ae4370cec9810d6d5ca5a2352db28896f6ffd232ca98f426ff87d3b6d748173af97589c211f14347ae59779d0f9e834e0ccc7f6d7852
6
+ metadata.gz: 5de05a662519033f02c6e58595d502e80970b08abe7bd87caa7ff23c6acae6490498453bcf8584b8ea6dcba14ef6f00298b1aeca75c5405f8e281e4d206e44e9
7
+ data.tar.gz: 35c9f6d275c0da422e0597529424f005af4e44a344c63c0ca8595d87a44ad8c474be21c5e9c985d1f1a01b2d1ff0b2020da06edcc29e9871af9c174c1766d7cb
data/CHANGES.md CHANGED
@@ -1,3 +1,15 @@
1
+ # 0.9.4
2
+
3
+ Move some test helpers to `Activity::Testing` to export them to other gems
4
+
5
+ # 0.9.3
6
+
7
+ Remove introspection modules, it'll also be part of the `Dev` tools now.
8
+
9
+ # 0.9.2
10
+
11
+ Remove tracing modules, it'll be part of the `Dev` tools now.
12
+
1
13
  # 0.9.1
2
14
 
3
15
  Use `context-0.9.1`.
@@ -49,10 +49,6 @@ require "trailblazer/activity/task_wrap/runner"
49
49
  require "trailblazer/activity/task_wrap/variable_mapping"
50
50
  require "trailblazer/activity/task_wrap/inject"
51
51
 
52
- require "trailblazer/activity/trace"
53
- require "trailblazer/activity/present"
54
-
55
- require "trailblazer/activity/introspect"
56
52
  require "trailblazer/option"
57
53
  require "trailblazer/context"
58
54
  require "trailblazer/activity/task_builder"
@@ -47,10 +47,85 @@ module Trailblazer
47
47
  end
48
48
 
49
49
  module Assertions
50
+ Activity = Trailblazer::Activity
51
+ Inter = Trailblazer::Activity::Schema::Intermediate
52
+ Schema = Trailblazer::Activity::Schema
53
+ TaskWrap = Trailblazer::Activity::TaskWrap
54
+
55
+ module Implementing
56
+ extend Activity::Testing.def_tasks(:a, :b, :c, :d, :f, :g)
57
+
58
+ Start = Activity::Start.new(semantic: :default)
59
+ Failure = Activity::End(:failure)
60
+ Success = Activity::End(:success)
61
+ end
62
+
50
63
  def Cct(activity)
51
64
  cct = Trailblazer::Developer::Render::Circuit.(activity)
52
65
  end
53
66
 
67
+ # TODO: Remove this once all it's references are removed
68
+ def implementing
69
+ Implementing
70
+ end
71
+
72
+ def flat_activity
73
+ return @_flat_activity if defined?(@_flat_activity)
74
+
75
+ intermediate = Inter.new(
76
+ {
77
+ Inter::TaskRef("Start.default") => [Inter::Out(:success, :B)],
78
+ Inter::TaskRef(:B, additional: true) => [Inter::Out(:success, :C)],
79
+ Inter::TaskRef(:C) => [Inter::Out(:success, "End.success")],
80
+ Inter::TaskRef("End.success", stop_event: true) => [Inter::Out(:success, nil)]
81
+ },
82
+ ["End.success"],
83
+ ["Start.default"], # start
84
+ )
85
+
86
+ implementation = {
87
+ "Start.default" => Schema::Implementation::Task(st = Implementing::Start, [Activity::Output(Activity::Right, :success)], []),
88
+ :B => Schema::Implementation::Task(b = Implementing.method(:b), [Activity::Output(Activity::Right, :success)], []),
89
+ :C => Schema::Implementation::Task(c = Implementing.method(:c), [Activity::Output(Activity::Right, :success)], []),
90
+ "End.success" => Schema::Implementation::Task(_es = Implementing::Success, [Activity::Output(Implementing::Success, :success)], []), # DISCUSS: End has one Output, signal is itself?
91
+ }
92
+
93
+ schema = Inter.(intermediate, implementation)
94
+
95
+ @_flat_activity = Activity.new(schema)
96
+ end
97
+
98
+ def nested_activity
99
+ return @_nested_activity if defined?(@_nested_activity)
100
+
101
+ intermediate = Inter.new(
102
+ {
103
+ Inter::TaskRef("Start.default") => [Inter::Out(:success, :B)],
104
+ Inter::TaskRef(:B, more: true) => [Inter::Out(:success, :D)],
105
+ Inter::TaskRef(:D) => [Inter::Out(:success, :E)],
106
+ Inter::TaskRef(:E) => [Inter::Out(:success, "End.success")],
107
+ Inter::TaskRef("End.success", stop_event: true) => [Inter::Out(:success, nil)]
108
+ },
109
+ ["End.success"],
110
+ ["Start.default"] # start
111
+ )
112
+
113
+ implementation = {
114
+ "Start.default" => Schema::Implementation::Task(st = Implementing::Start, [Activity::Output(Activity::Right, :success)], []),
115
+ :B => Schema::Implementation::Task(b = Implementing.method(:b), [Activity::Output(Activity::Right, :success)], []),
116
+ :D => Schema::Implementation::Task(c = bc, [Activity::Output(Implementing::Success, :success)], []),
117
+ :E => Schema::Implementation::Task(e = Implementing.method(:f), [Activity::Output(Activity::Right, :success)], []),
118
+ "End.success" => Schema::Implementation::Task(_es = Implementing::Success, [Activity::Output(Implementing::Success, :success)], []), # DISCUSS: End has one Output, signal is itself?
119
+ }
120
+
121
+ schema = Inter.(intermediate, implementation)
122
+
123
+ @_nested_activity = Activity.new(schema)
124
+ end
125
+
126
+ alias_method :bc, :flat_activity
127
+ alias_method :bde, :nested_activity
128
+
54
129
  # Tests {:circuit} and {:outputs} fields so far.
55
130
  def assert_process_for(process, *args)
56
131
  semantics, circuit = args[0..-2], args[-1]
@@ -1,7 +1,7 @@
1
1
  module Trailblazer
2
2
  module Version
3
3
  module Activity
4
- VERSION = "0.9.1"
4
+ VERSION = "0.9.4"
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trailblazer-activity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.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: 2019-09-20 00:00:00.000000000 Z
11
+ date: 2019-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trailblazer-context
@@ -108,8 +108,6 @@ files:
108
108
  - lib/trailblazer/activity.rb
109
109
  - lib/trailblazer/activity/circuit.rb
110
110
  - lib/trailblazer/activity/config.rb
111
- - lib/trailblazer/activity/introspect.rb
112
- - lib/trailblazer/activity/present.rb
113
111
  - lib/trailblazer/activity/schema.rb
114
112
  - lib/trailblazer/activity/schema/implementation.rb
115
113
  - lib/trailblazer/activity/schema/intermediate.rb
@@ -122,7 +120,6 @@ files:
122
120
  - lib/trailblazer/activity/task_wrap/runner.rb
123
121
  - lib/trailblazer/activity/task_wrap/variable_mapping.rb
124
122
  - lib/trailblazer/activity/testing.rb
125
- - lib/trailblazer/activity/trace.rb
126
123
  - lib/trailblazer/activity/version.rb
127
124
  - trailblazer-activity.gemspec
128
125
  homepage: http://trailblazer.to
@@ -145,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
142
  version: '0'
146
143
  requirements: []
147
144
  rubyforge_project:
148
- rubygems_version: 2.7.6
145
+ rubygems_version: 2.7.3
149
146
  signing_key:
150
147
  specification_version: 4
151
148
  summary: Runtime code for Trailblazer activities.
@@ -1,72 +0,0 @@
1
- module Trailblazer
2
- class Activity
3
- # The Introspect API provides inflections for `Activity` instances.
4
- # It abstracts internals about circuits and provides a convenient API to third-parties such as
5
- # tracing, rendering an activity, or finding particular tasks.
6
- module Introspect
7
- def self.Graph(*args)
8
- Graph.new(*args)
9
- end
10
-
11
- # TODO: order of step/fail/pass in Node would be cool to have
12
-
13
- # @private This API is still under construction.
14
- class Graph
15
- def initialize(activity)
16
- @activity = activity
17
- @schema = activity.to_h or raise
18
- @circuit = @schema[:circuit]
19
- @map = @circuit.to_h[:map]
20
- @configs = @schema[:nodes]
21
- end
22
-
23
- def find(id=nil, &block)
24
- return find_by_id(id) unless block_given?
25
- find_with_block(&block)
26
- end
27
-
28
- def collect(strategy: :circuit, &block)
29
- @map.keys.each_with_index.collect { |task, i| yield find_with_block { |node| node.task==task }, i }
30
- end
31
-
32
- def stop_events
33
- @circuit.to_h[:end_events]
34
- end
35
-
36
- private
37
-
38
- def find_by_id(id)
39
- node = @configs.find { |node| node.id == id } or return
40
- node_for(node)
41
- end
42
-
43
- def find_with_block(&block)
44
- existing = @configs.find { |node| yield Node(node.task, node.id, node.outputs, node.data) } or return
45
-
46
- node_for(existing)
47
- end
48
-
49
- def node_for(node_attributes)
50
- Node(node_attributes.task, node_attributes.id, node_attributes.outputs, outgoings_for(node_attributes), node_attributes.data)
51
- end
52
-
53
- def Node(*args)
54
- Node.new(*args).freeze
55
- end
56
-
57
- Node = Struct.new(:task, :id, :outputs, :outgoings, :data)
58
- Outgoing = Struct.new(:output, :task)
59
-
60
- def outgoings_for(node)
61
- outputs = node.outputs
62
- connections = @map[node.task]
63
-
64
- connections.collect do |signal, target|
65
- output = outputs.find { |out| out.signal == signal }
66
- Outgoing.new(output, target)
67
- end
68
- end
69
- end
70
- end #Introspect
71
- end
72
- end
@@ -1,63 +0,0 @@
1
- module Trailblazer
2
- class Activity
3
- # Task < Array
4
- # [ input, ..., output ]
5
-
6
- module Trace
7
- # TODO: make this simpler.
8
- module Present
9
- module_function
10
-
11
- INDENTATION = " |".freeze
12
- STEP_PREFIX = "-- ".freeze
13
-
14
- def default_renderer(task_node:, **)
15
- [ task_node[:level], %{#{task_node[:name]}} ]
16
- end
17
-
18
- def call(stack, level: 1, tree: [], renderer: method(:default_renderer), **options)
19
- tree(stack.to_a, level, tree: tree, renderer: renderer, **options)
20
- end
21
-
22
- def tree(stack, level, tree:, renderer:, **options)
23
- tree_for(stack, level, options.merge(tree: tree))
24
-
25
- nodes = tree.each_with_index.map do |task_node, position|
26
- renderer.(task_node: task_node, position: position, tree: tree)
27
- end
28
-
29
- render_tree_for(nodes)
30
- end
31
-
32
- def render_tree_for(nodes)
33
- nodes.map { |level, node|
34
- indentation = INDENTATION * (level -1)
35
- indentation = indentation[0...-1] + "`" if level == 1 || /End./.match(node) # start or end step
36
- indentation + STEP_PREFIX + node
37
- }.join("\n")
38
- end
39
-
40
- def tree_for(stack, level, tree:, **options)
41
- stack.each do |lvl| # always a Stack::Task[input, ..., output]
42
- input, output, nested = Trace::Level.input_output_nested_for_level(lvl)
43
-
44
- task = input.task
45
-
46
- graph = Introspect::Graph(input.activity)
47
-
48
- name = (node = graph.find { |node| node[:task] == task }) ? node[:id] : task
49
- name ||= task # FIXME: bullshit
50
-
51
- tree << { level: level, input: input, output: output, name: name, **options }
52
-
53
- if nested.any? # nesting
54
- tree_for(nested, level + 1, options.merge(tree: tree))
55
- end
56
-
57
- tree
58
- end
59
- end
60
- end
61
- end
62
- end
63
- end
@@ -1,144 +0,0 @@
1
- module Trailblazer
2
- class Activity
3
- module Trace
4
- class << self
5
- # Public entry point to activate tracing when running {activity}.
6
- def call(activity, (ctx, flow_options), circuit_options={})
7
- activity, (ctx, flow_options), circuit_options = Trace.arguments_for_call( activity, [ctx, flow_options], circuit_options ) # only run once for the entire circuit!
8
-
9
- signal, (ctx, flow_options) = Activity::TaskWrap.invoke(activity, [ctx, flow_options], circuit_options)
10
-
11
- return flow_options[:stack], signal, [ctx, flow_options]
12
- end
13
-
14
- alias_method :invoke, :call
15
-
16
- def arguments_for_call(activity, (options, flow_options), **circuit_options)
17
- tracing_flow_options = {
18
- stack: Trace::Stack.new,
19
- }
20
-
21
- tracing_circuit_options = {
22
- wrap_runtime: ::Hash.new(Trace.merge_plan), # DISCUSS: this overrides existing {:wrap_runtime}.
23
- }
24
-
25
- return activity, [ options, tracing_flow_options.merge(flow_options) ], circuit_options.merge(tracing_circuit_options)
26
- end
27
- end
28
-
29
- module_function
30
- # Insertions for the trace tasks that capture the arguments just before calling the task,
31
- # and before the TaskWrap is finished.
32
- #
33
- # @private
34
- def merge_plan
35
- TaskWrap::Pipeline::Merge.new(
36
- [TaskWrap::Pipeline.method(:insert_before), "task_wrap.call_task", ["task_wrap.capture_args", Trace.method(:capture_args)]],
37
- [TaskWrap::Pipeline.method(:append), nil, ["task_wrap.capture_return", Trace.method(:capture_return)]],
38
- )
39
- end
40
-
41
- # taskWrap step to capture incoming arguments of a step.
42
- def capture_args(wrap_config, original_args)
43
- original_args = capture_for(wrap_config[:task], *original_args)
44
-
45
- return wrap_config, original_args
46
- end
47
-
48
- # taskWrap step to capture outgoing arguments from a step.
49
- def capture_return(wrap_config, original_args)
50
- (original_options, original_flow_options, _) = original_args[0]
51
-
52
- original_flow_options[:stack] << Entity::Output.new(
53
- wrap_config[:task], {}, wrap_config[:return_signal]
54
- ).freeze
55
-
56
- original_flow_options[:stack].unindent!
57
-
58
-
59
- return wrap_config, original_args
60
- end
61
-
62
- # It's important to understand that {flow[:stack]} is mutated by design. This is needed so
63
- # in case of exceptions we still have a "global" trace - unfortunately Ruby doesn't allow
64
- # us a better way.
65
- def capture_for(task, (ctx, flow), activity:, **circuit_options)
66
- flow[:stack].indent!
67
-
68
- flow[:stack] << Entity::Input.new(
69
- task, activity, [ctx, ctx.inspect]
70
- ).freeze
71
-
72
- return [ctx, flow], circuit_options.merge(activity: activity)
73
- end
74
-
75
- # Structures used in {capture_args} and {capture_return}.
76
- # These get pushed onto one {Level} in a {Stack}.
77
- #
78
- # Level[
79
- # Level[ ==> this is a scalar task
80
- # Entity::Input
81
- # Entity::Output
82
- # ]
83
- # Level[ ==> nested task
84
- # Entity::Input
85
- # Level[
86
- # Entity::Input
87
- # Entity::Output
88
- # ]
89
- # Entity::Output
90
- # ]
91
- # ]
92
- Entity = Struct.new(:task, :activity, :data)
93
- Entity::Input = Class.new(Entity)
94
- Entity::Output = Class.new(Entity)
95
-
96
- class Level < Array
97
- def inspect
98
- %{<Level>#{super}}
99
- end
100
-
101
- # @param level {Trace::Level}
102
- def self.input_output_nested_for_level(level)
103
- input = level[0]
104
- output = level[-1]
105
-
106
- output, nested = output.is_a?(Entity::Output) ? [output, level-[input, output]] : [nil, level[1..-1]]
107
-
108
- return input, output, nested
109
- end
110
- end
111
-
112
- # Mutable/stateful per design. We want a (global) stack!
113
- class Stack
114
- def initialize
115
- @nested = Level.new
116
- @stack = [ @nested ]
117
- end
118
-
119
- def indent!
120
- current << indented = Level.new
121
- @stack << indented
122
- end
123
-
124
- def unindent!
125
- @stack.pop
126
- end
127
-
128
- def <<(args)
129
- current << args
130
- end
131
-
132
- def to_a
133
- @nested
134
- end
135
-
136
- private
137
-
138
- def current
139
- @stack.last
140
- end
141
- end # Stack
142
- end
143
- end
144
- end