trailblazer-circuit 0.0.1 → 0.0.2

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
  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