Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

{Path(..., before)} should not be tied with {connect_to} #51

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions lib/trailblazer/activity/dsl/linear/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,39 +43,38 @@ def Id(id)
Id.new(id).freeze
end

def Path(track_color: "track_#{rand}", connect_to: nil, before: false, **options, &block)
def Path(track_color: "track_#{rand}", connect_to: nil, before: "End.success", **options, &block)
path = Activity::Path(track_name: track_color, **options)
activity = Class.new(path) { self.instance_exec(&block) }

seq = activity.instance_variable_get(:@state).to_h[:sequence] # TODO: fix @state interface
# Strip default ends `Start.default` and `End.success` (if present).
# Strip default `Start.default` and `End.success` ends.
seq = seq[1..-1].reject{ |row| row[3][:stop_event] && row[3][:id] == 'End.success' }

if connect_to
seq = connect_for_sequence(seq, connect_to: connect_to)
end

# Add the path elements before {End.success}.
# Termini (or :stop_event) are to be placed after {End.success}.
adds = seq.collect do |row|
options = row[3]

# the terminus of the path goes _after_ {End.success} into the "end group".
insert_method = options[:stop_event] ? Insert.method(:Append) : Insert.method(:Prepend)

insert_target = "End.success" # insert before/after
insert_target = before if before && connect_to.instance_of?(Trailblazer::Activity::DSL::Linear::Helper::Track) # FIXME: this is a bit hacky, of course!
row_options = row[3]

{
row: row,
insert: [insert_method, insert_target]
insert: insert_at(before, **row_options)
}
end

# Connect the Output() => Track(path_track)
return Track.new(track_color, adds, {})
end

# {Append} or {Prepend} path elements to given {step_id}.
# Termini (or :stop_event) are to be added after {End.success}.
private def insert_at(step_id, stop_event: false, **)
insert_method = stop_event ? Insert.method(:Append) : Insert.method(:Prepend)
[insert_method, step_id]
end

# Connect last row of the {sequence} to the given step via its {Id}
# Useful when steps needs to be inserted in between {Start} and {connect Id()}.
private def connect_for_sequence(sequence, connect_to:)
Expand Down
37 changes: 37 additions & 0 deletions test/docs/path_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,43 @@ class Charge < Trailblazer::Activity::Railway
{Trailblazer::Activity::Right} => #<End/:success>
#<End/:success>

#<End/:failure>
}
end

it "{Path() ..., before: :element} will add all path steps {before} given step with custom {End}" do
module G
class Charge < Trailblazer::Activity::Railway
step :b
step :f
step :a, before: :b, # note the {:before}
Output(:failure) => Path(before: :b) do
step :c
step :d, Output(:success) => End(:with_cc)
end
end
end

assert_process_for G::Charge, :with_cc, :success, :failure, %{
#<Start/:default>
{Trailblazer::Activity::Right} => <*a>
<*a>
{Trailblazer::Activity::Left} => <*c>
{Trailblazer::Activity::Right} => <*b>
<*c>
{Trailblazer::Activity::Right} => <*d>
<*d>
{Trailblazer::Activity::Right} => #<End/:with_cc>
<*b>
{Trailblazer::Activity::Left} => #<End/:failure>
{Trailblazer::Activity::Right} => <*f>
#<End/:with_cc>

<*f>
{Trailblazer::Activity::Left} => #<End/:failure>
{Trailblazer::Activity::Right} => #<End/:success>
#<End/:success>

#<End/:failure>
}
end
Expand Down