trailblazer-circuit 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 5a7e34849fb98696e6c453bbe8177d90b3932ecd
4
- data.tar.gz: 5c2d5ab3e575f380fda9f2976bddd77d2a5b9fb1
3
+ metadata.gz: 72877a8ce955ec1dc23b9f100bda0974e1bcd40f
4
+ data.tar.gz: c71ca90a053245f55c75573bea74584b2056f14c
5
5
  SHA512:
6
- metadata.gz: 9e64cefc10dfc6606ebe9be18cc918145ba4b1a4a62854b35a00e97b0dc26233a85d81e39b96f0534dc469f763c6796618b1350480bea30ec566f3c1a45ef1f1
7
- data.tar.gz: c71327201a57cddb155d70c5cb6e1bbb67daf040a988be09045831c2e93900e05072689f564ad0de1a1a6eafc837d4f5a956a269259f5fe09f9fc1b08684fdf0
6
+ metadata.gz: 4f8fa59da9c333fefdf5c5b37a273d520bbfc346c4d2d80a1455447b7bd85e878a523112e58e4a231ac220969b33e12428902c4fe8ab9155a615c0c093ade6a3
7
+ data.tar.gz: e4aef9035fe3a68b81fda3f178e6e37ac9fb9f04fe20b64e5de4cdd850e04b2214d398b9b1439c7d568634a43709ced757f7201174abce5a8fddae74f645fb19
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.0.2
2
+
3
+ * Make `flow_options` an immutable data structure just as `options`. It now needs to be returned from a `#call`.
4
+
1
5
  # 0.0.1
2
6
 
3
7
  * First release into an unsuspecting world. 🚀
@@ -16,24 +16,16 @@ module Trailblazer
16
16
  end
17
17
  end
18
18
 
19
- # DSL
20
- # Conveniently build an Activity with Circuit instance and
21
- # all its signals/events.
22
- def self.Activity(name=:default, events={}, end_events=nil, implementation=false, &block)
19
+ # Builder for an Activity with Circuit instance and events.
20
+ def self.Activity(name=:default, events={}, &block)
23
21
  # default events:
24
22
  start = events[:start] || { default: Start.new(:default) }
25
23
  _end = events[:end] || { default: End.new(:default) }
26
24
 
27
- events = { start: start }.merge(events)
28
- events = { end: _end }.merge(events)
29
-
30
- end_events ||= _end.values
25
+ events = { start: start, end: _end }.merge(events)
31
26
 
32
27
  evts = Events(events)
33
- circuit = Circuit(name, evts, end_events, &block)
34
-
35
- # DISCUSS: remove this!
36
- circuit = implementation.(circuit) if implementation
28
+ circuit = Circuit(name, evts, _end.values, &block)
37
29
 
38
30
  Activity.new(circuit, evts)
39
31
  end
@@ -0,0 +1,42 @@
1
+ module MiniTest::Assertions
2
+ def assert_activity_inspect(text, subject)
3
+ Trailblazer::Circuit::ActivityInspect(subject).must_equal text
4
+ end
5
+
6
+ def assert_event_inspect(text, subject)
7
+ Trailblazer::Circuit::EndInspect(subject).must_equal(text)
8
+ end
9
+ end
10
+
11
+
12
+ Trailblazer::Circuit::Activity.infect_an_assertion :assert_activity_inspect, :must_inspect
13
+ Trailblazer::Circuit::End.infect_an_assertion :assert_event_inspect, :must_inspect_end_fixme
14
+
15
+ class Trailblazer::Circuit
16
+ def self.EndInspect(event)
17
+ event.instance_eval { "#<#{self.class.to_s.split("::").last}: #{@name} #{@options}>" }
18
+ end
19
+
20
+ def self.ActivityInspect(activity, strip: ["AlterTest::"])
21
+ strip += ["Trailblazer::Circuit::"]
22
+ stripped = ->(target) { strip_for(target, strip) }
23
+
24
+ map, _ = activity.circuit.to_fields
25
+
26
+ content = map.collect do |task, connections|
27
+ bla =
28
+ connections.collect do |direction, target|
29
+ target_str = target.kind_of?(End) ? EndInspect(target) : stripped.(target)
30
+ "#{stripped.(direction)}=>#{target_str}"
31
+ end.join(", ")
32
+ task_str = task.kind_of?(End) ? EndInspect(task) : stripped.(task)
33
+ "#{task_str}=>{#{bla}}"
34
+ end.join(", ")
35
+ "{#{content}}"
36
+ end
37
+
38
+ def self.strip_for(target, strings)
39
+ strings.each { |stripped| target = target.to_s.gsub(stripped, "") }
40
+ target
41
+ end
42
+ end
@@ -4,15 +4,18 @@ module Trailblazer
4
4
 
5
5
  # Every `activity.call` is considered nested
6
6
  class Trace
7
+ # Trace is passed in as the `:runner` into Circuit#call and is called per task.
7
8
  def call(activity, direction, args, debug:raise, stack:raise, **flow_options)
8
9
  activity_name, _ = debug[activity]
9
10
  activity_name ||= activity
10
11
 
11
- Run.(activity, direction, args, stack:[], **flow_options).tap do |direction, outgoing_options, **flow_options| # TODO: USE KW ARG FOR :stack
12
- # raise activity_name.inspect if flow_options[:stack].nil? # TODO: remove this.
13
- # TODO: fix the inspect, we need a snapshot, deep-nested.
14
- stack << [activity_name, activity, direction, outgoing_options, outgoing_options.inspect, flow_options[:stack].any? ? flow_options[:stack] : nil ]
15
- end
12
+ # Use Circuit::Run to actually call the task.
13
+ direction, options, _flow_options = Run.(activity, direction, args, flow_options.merge(stack: []))
14
+
15
+ # TODO: fix the inspect, we need a snapshot, deep-nested.
16
+ stack << [activity_name, activity, direction, options, options.inspect, _flow_options[:stack].any? ? _flow_options[:stack] : nil ]
17
+
18
+ return direction, options, _flow_options.merge(stack: stack, debug: debug)
16
19
  end
17
20
  end # Trace
18
21
  end
@@ -1,5 +1,5 @@
1
1
  module Trailblazer
2
2
  class Circuit
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -1,48 +1,43 @@
1
1
  require "trailblazer/circuit/version"
2
2
 
3
- # Start, Suspend, Resume, End can return something other than the next symbol?
4
- # Nested could replace options with local options
5
-
6
-
7
3
  module Trailblazer
8
- # Circuit executes ties, finds next step and stops when reaching a Stop signal (or derived from).
4
+ # Running a Circuit instance will run all tasks sequentially depending on the former's result.
5
+ # Each task is called and retrieves the former task's return value.
9
6
  #
10
- # circuit.()
11
- #
12
- # Cicuit doesn't know anything about contexts, options, etc. tasks: what steps follows? call it!
13
- class Circuit
7
+ # result = circuit.(start_at, *args)
8
+ class Circuit
14
9
  def initialize(map, stop_events, name)
15
10
  @name = name
16
11
  @map = map
17
12
  @stop_events = stop_events
18
13
  end
19
14
 
20
- # the idea is to always have a breakpoint state that has only one outgoing edge. we then start from
21
- # that vertix. it's up to the caller to test if the "persisted" state == requested state.
22
- # activity: where to start
23
15
  Run = ->(activity, direction, *args) { activity.(direction, *args) }
24
16
 
25
- def call(activity, args, runner: Run, **o) # DISCUSS: should start activity be @activity and we omit it here?
17
+ # Runs the circuit. Stops when hitting a End event or subclass thereof.
18
+ # This method throws exceptions when the return value of a task doesn't match
19
+ # any wiring.
20
+ # @param activity A task from the circuit where to start
21
+ # @param args An array of options passed to the first task.
22
+ def call(activity, args, runner: Run, **o)
26
23
  # TODO: args
27
- direction = nil
24
+ direction = nil
25
+ flow_options = { runner: runner, debug: @name }.merge(o) # DISCUSS: make this better?
28
26
 
29
27
  loop do
30
- # puts "[#{@name}]. #{activity}"
31
- direction, args = runner.(activity, direction, args, runner: runner, debug: @name, **o)
28
+ direction, args, flow_options = runner.( activity, direction, args, flow_options )
32
29
 
33
- # last task in a process is always either its Stop or its Suspend.
34
- return [ direction, args, **o ] if @stop_events.include?(activity)
30
+ # Stop execution of the circuit when we hit a stop event (< End). This could be an activity's End of Suspend.
31
+ return [ direction, args, flow_options ] if @stop_events.include?(activity)
35
32
 
36
33
  activity = next_for(activity, direction) do |next_activity, in_map|
37
- # puts "[#{@name}]...`#{activity}`[#{direction}] => #{next_activity}"
38
-
39
34
  raise IllegalInputError.new("#{@name} #{activity}") unless in_map
40
- # last activity didn't emit knowns signal, it's not connected.
41
35
  raise IllegalOutputSignalError.new("from #{@name};;#{activity}"+ direction.inspect) unless next_activity
42
36
  end
43
37
  end
44
38
  end
45
39
 
40
+ # Returns the circuit's components.
46
41
  def to_fields
47
42
  [ @map, @stop_events, @name]
48
43
  end
@@ -66,28 +61,14 @@ module Trailblazer
66
61
  class IllegalOutputSignalError < RuntimeError
67
62
  end
68
63
 
69
- def Right
70
- Right
71
- end
72
-
73
- def Left
74
- Left
75
- end
76
-
64
+ # End event is just another callable task.
65
+ # Any instance of subclass of End will halt the circuit's execution when hit.
77
66
  class End
78
67
  def initialize(name, options={})
79
68
  @name = name
80
69
  @options = options
81
70
  end
82
71
 
83
- def to_s
84
- %{#<End: #{@name} #{@options.inspect}>}
85
- end
86
-
87
- def inspect
88
- to_s
89
- end
90
-
91
72
  def call(direction, *args)
92
73
  [ self, *args ]
93
74
  end
@@ -95,27 +76,25 @@ module Trailblazer
95
76
 
96
77
  class Start < End
97
78
  def call(direction, *args)
98
- [Right, *args]
79
+ [ Right, *args ]
99
80
  end
81
+ end
100
82
 
101
- def to_s
102
- %{#<Start: #{@name} #{@options.inspect}>}
103
- end
83
+ # Builder for Circuit::End when defining the Activity's circuit.
84
+ def self.End(name, options={})
85
+ End.new(name, options)
104
86
  end
105
87
 
106
- # # run a nested process.
88
+ # Builder for running a nested process from a specific `start_at` position.
107
89
  def self.Nested(activity, start_with=activity[:Start])
108
- # TODO: currently, we only support only 1 start event. you can use multiple in BPMN.
109
- # "The BPMN standard allows for multiple start and end events to be used at the same process level. "
110
90
  ->(start_at, options, *args) {
111
- # puts "@@@@@ #{options.inspect}"
112
91
  activity.(start_with, options, *args)
113
92
  }
114
93
  end
115
94
 
116
- class Direction; end
95
+ class Direction; end
117
96
  class Right < Direction; end
118
- class Left < Direction; end
97
+ class Left < Direction; end
119
98
  end
120
99
  end
121
100
 
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "bundler", "~> 1.14"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "minitest", "~> 5.0"
25
- spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "raise"
26
26
 
27
27
  spec.required_ruby_version = '>= 2.0.0'
28
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trailblazer-circuit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-27 00:00:00.000000000 Z
11
+ date: 2017-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: pry
56
+ name: raise
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -86,6 +86,7 @@ files:
86
86
  - lib/trailblazer/circuit/alter.rb
87
87
  - lib/trailblazer/circuit/present.rb
88
88
  - lib/trailblazer/circuit/task.rb
89
+ - lib/trailblazer/circuit/testing.rb
89
90
  - lib/trailblazer/circuit/trace.rb
90
91
  - lib/trailblazer/circuit/version.rb
91
92
  - trailblazer-circuit.gemspec