Skip to content

Commit

Permalink
#assert_advance can render better error messages.
Browse files Browse the repository at this point in the history
  • Loading branch information
apotonick committed Feb 13, 2024
1 parent e946f1e commit 824dc5d
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 67 deletions.
1 change: 0 additions & 1 deletion lib/trailblazer/workflow/state/discovery.rb
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ def self.render_cli_event_table(discovery_state_table, render_ids: false, hide_l
# Find the next connected task, usually outgoing from a catch event.
def self.find_next_task_label(activity, catch_event)
task_after_catch = activity.to_h[:circuit].to_h[:map][catch_event][Trailblazer::Activity::Right]

Trailblazer::Activity::Introspect.Nodes(activity, task: task_after_catch).data[:label] || task_after_catch
end

Expand Down
54 changes: 19 additions & 35 deletions lib/trailblazer/workflow/test/plan.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,26 @@ def assert_positions(asserted_positions, expected_tuples, lanes:)
sorted_expected_positions = expected_positions.sort(&sorting_block)

sorted_asserted_positions.collect.with_index do |position, index|
assert_equal position, sorted_expected_positions[index], "baaaaal"
assert_equal position, sorted_expected_positions[index],
Assertions.error_message_for(position, sorted_expected_positions[index], lanes: lanes)
end

# FIXME: figure out why we can't just compare the entire array!
# assert_equal sorted_asserted_positions, sorted_expected_positions
end

def assert_advance(event_label, test_plan:, lanes:, schema:, message_flow:, **) # TODO: allow {ctx}
# Compile error message when the expected lane position doesn't match the actual one.
def self.error_message_for(position, expected_position, lanes:)
# TODO: make the labels use UTF8 icons etc, as in the CLI rendering code.
expected_label = State::Discovery::Testing.serialize_lane_position(position, lanes: lanes)[:comment]
actual_label = State::Discovery::Testing.serialize_lane_position(expected_position, lanes: lanes)[:comment]

"Lane #{lanes.invert[position.activity].inspect}:\n expected #{expected_label}\n actual #{actual_label}"
end

# Grab the start_position and expected_lane_positions from the discovered plan, run
# the collaboration from there and check if it actually reached the expected configuration.
def assert_advance(event_label, test_plan:, lanes:, schema:, message_flow:, expected_ctx:, **) # TODO: allow {ctx}
testing_row = test_plan.find { |row| row[:event_label] == event_label }

start_position = testing_row[:start_position]
Expand All @@ -48,7 +60,9 @@ def assert_advance(event_label, test_plan:, lanes:, schema:, message_flow:, **)
)

assert_positions configuration[:lane_positions], testing_row[:expected_lane_positions], lanes: lanes
assert_equal ctx.inspect, "asdf"

# assert_equal ctx.inspect, expected_ctx.inspect
ctx
end

end
Expand All @@ -67,38 +81,8 @@ def self.for(test_structure, input:)

%(
# test: #{row[:event_label]}
start_tuple = #{start_position[:tuple]} # #{start_position[:comment]}
start_position = Trailblazer::Workflow::State::Discovery.position_from_tuple(lanes, *start_tuple)
# current position.
#DISCUSS: here, we could also ask the State layer for the start configuration, on a different level.
lane_positions = [#{row[:start_configuration].collect do |row|
"Trailblazer::Workflow::State::Discovery.position_from_tuple(lanes, *#{row[:tuple].inspect})"
end.join(", ")}]
lane_positions = Trailblazer::Workflow::Collaboration::Positions.new(lane_positions)
configuration, (ctx, flow) = Trailblazer::Workflow::Collaboration::Synchronous.advance(
schema,
[{seq: []}, {throw: []}],
{}, # circuit_options
start_position: start_position,
lane_positions: lane_positions, # current position/"state"
message_flow: message_flow,
)
assert_positions configuration[:lane_positions], #{row[:expected_lane_positions].inspect}, lanes: lanes
# TODO: test {:last_lane}.
assert_equal configuration.lane_positions.keys, [lane_activity, lane_activity_ui]
assert_equal configuration.lane_positions.values.inspect, %([{"resumes"=>["catch-before-#{}"], :semantic=>[:suspend, "from initial_lane_positions"]}, \
#<Trailblazer::Workflow::Event::Suspend resumes=["catch-before-#{}"] type=:suspend semantic=[:suspend, "suspend-Gateway_14h0q7a"]>])
assert_equal ctx.inspect, %({:seq=>[:create_form]})
ctx = assert_advance "#{row[:event_label]}", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]
)
end
end
Expand Down
117 changes: 86 additions & 31 deletions test/collaboration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
# TODO: how can we prevent users from triggering lifecycle.Create? only UI events allowed?
#
class CollaborationTest < Minitest::Spec
require "trailblazer/test/assertions"
include Trailblazer::Test::Assertions # DISCUSS: this is for assert_advance and friends.


def build_schema()
moderation_json = File.read("test/fixtures/v1/moderation.json")
signal, (ctx, _) = Trailblazer::Workflow::Generate.invoke([{json_document: moderation_json}, {}])
Expand Down Expand Up @@ -594,38 +598,89 @@ def render_states(states, lanes:, additional_state_data:, task_map:)
lanes = ___lanes___.invert

# test: ☝ ▶Revise
ctx = assert_advance "☝ ▶Revise", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# +----------------------+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
# | triggered catch | start_configuration_formatted | expected_lane_positions_formatted |
# +----------------------+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
# | ☝ ▶Create form | ☝ ▶Create form ⛾ ▶Create ☑ ▶#<Trail... | ☝ ▶Create ⛾ ▶Create ☑ ▶#<Trail... |
# | ☝ ▶Create | ☝ ▶Create ⛾ ▶Create ☑ ▶#<Trail... | ☝ ▶Update form ▶Notify approver ⛾ ▶Update ▶Notify approver ☑ ▶#<Trail... |
# | ☝ ▶Create ⛞ | ☝ ▶Create ⛾ ▶Create ☑ ▶#<Trail... | ☝ ▶Create ⛾ ▶Create ☑ ▶#<Trail... |
# | ☝ ▶Update form | ☝ ▶Update form ▶Notify approver ⛾ ▶Update ▶Notify approver ☑ ▶#<Trail... | ☝ ▶Update ⛾ ▶Update ▶Notify approver ☑ ▶#<Trail... |
# | ☝ ▶Notify approver | ☝ ▶Update form ▶Notify approver ⛾ ▶Update ▶Notify approver ☑ ▶#<Trail... | ☝ ▶Update form ▶Delete? form ▶Publish ⛾ ▶Publish ▶Delete ▶Update ☑ ◉End.fai... |
# | ☝ ▶Update | ☝ ▶Update ⛾ ▶Update ▶Notify approver ☑ ▶#<Trail... | ☝ ▶Update form ▶Notify approver ⛾ ▶Notify approver ▶Update ☑ ▶#<Trail... |
# | ☝ ▶Notify approver ⛞ | ☝ ▶Update form ▶Notify approver ⛾ ▶Update ▶Notify approver ☑ ▶#<Trail... | ☝ ▶Revise form ⛾ ▶Revise ☑ ◉End.suc... |
# | ☝ ▶Delete? form | ☝ ▶Update form ▶Delete? form ▶Publish ⛾ ▶Publish ▶Delete ▶Update ☑ ... | ☝ ▶Delete ▶Cancel ⛾ ▶Publish ▶Delete ▶Update ☑ ◉End.fai... |
# | ☝ ▶Publish | ☝ ▶Update form ▶Delete? form ▶Publish ⛾ ▶Publish ▶Delete ▶Update ☑ ... | ☝ ▶Archive ⛾ ▶Archive ☑ ◉End.fai... |
# | ☝ ▶Update ⛞ | ☝ ▶Update ⛾ ▶Update ▶Notify approver ☑ ▶#<Trail... | ☝ ▶Update ⛾ ▶Update ▶Notify approver ☑ ▶#<Trail... |
# | ☝ ▶Revise form | ☝ ▶Revise form ⛾ ▶Revise ☑ ... | ☝ ▶Revise ⛾ ▶Revise ☑ ◉End.suc... |
# | ☝ ▶Delete | ☝ ▶Delete ▶Cancel ⛾ ▶Publish ▶Delete ▶Update ☑ ... | ☝ ◉End.success ⛾ ◉End.success ☑ ◉End.fai... |
# | ☝ ▶Cancel | ☝ ▶Delete ▶Cancel ⛾ ▶Publish ▶Delete ▶Update ☑ ... | ☝ ▶Update form ▶Delete? form ▶Publish ⛾ ▶Publish ▶Delete ▶Update ☑ ◉End.fai... |
# | ☝ ▶Archive | ☝ ▶Archive ⛾ ▶Archive ☑ ... | ☝ ◉End.success ⛾ ◉End.success ☑ ◉End.fai... |
# | ☝ ▶Revise | ☝ ▶Revise ⛾ ▶Revise ☑ ... | ☝ ▶Update form ▶Notify approver ⛾ ▶Revise ▶Notify approver ☑ ◉End.suc... |
# +----------------------+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
# 15 rows in set

# test: ☝ ▶Create form
ctx = assert_advance "☝ ▶Create form", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:create_form], reader: :[]

# test: ☝ ▶Create
ctx = assert_advance "☝ ▶Create", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:ui_create, :create], reader: :[]

# test: ☝ ▶Create ⛞
ctx = assert_advance "☝ ▶Create ⛞", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Update form
ctx = assert_advance "☝ ▶Update form", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Notify approver
ctx = assert_advance "☝ ▶Notify approver", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Update
ctx = assert_advance "☝ ▶Update", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Notify approver ⛞
ctx = assert_advance "☝ ▶Notify approver ⛞", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Delete? form
ctx = assert_advance "☝ ▶Delete? form", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Publish
ctx = assert_advance "☝ ▶Publish", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Update ⛞
ctx = assert_advance "☝ ▶Update ⛞", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Revise form
ctx = assert_advance "☝ ▶Revise form", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Delete
ctx = assert_advance "☝ ▶Delete", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Cancel
ctx = assert_advance "☝ ▶Cancel", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

# test: ☝ ▶Archive
ctx = assert_advance "☝ ▶Archive", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]

assert_advance "☝ ▶Revise", ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow

# start_tuple = ["UI", "catch-before-Activity_1wiumzv"] # ["before", "Revise"]
# start_position = Trailblazer::Workflow::State::Discovery.position_from_tuple(lanes, *start_tuple)

# # current position.
# #DISCUSS: here, we could also ask the State layer for the start configuration, on a different level.
# lane_positions = [Trailblazer::Workflow::State::Discovery.position_from_tuple(lanes, *["lifecycle", "suspend-Gateway_01p7uj7"]), Trailblazer::Workflow::State::Discovery.position_from_tuple(lanes, *["UI", "suspend-Gateway_1xs96ik"])]

# lane_positions = Trailblazer::Workflow::Collaboration::Positions.new(lane_positions)


# configuration, (ctx, flow) = Trailblazer::Workflow::Collaboration::Synchronous.advance(
# schema,
# [{seq: []}, {throw: []}],
# {}, # circuit_options

# start_position: start_position,
# lane_positions: lane_positions, # current position/"state"

# message_flow: message_flow,
# )

# assert_positions configuration[:lane_positions], [{:tuple=>["approver", "End.success"], :comment=>[:terminus, :success]}, {:tuple=>["lifecycle", "suspend-Gateway_1kl7pnm"], :comment=>["before", ["Revise", "Notify approver"]]}, {:tuple=>["UI", "suspend-Gateway_1g3fhu2"], :comment=>["before", ["Update form", "Notify approver"]]}], lanes: lanes

# assert_positions "☝ ▶Revise", configuration[:lane_positions], lanes: lanes





# test: ☝ ▶Revise
ctx = assert_advance "☝ ▶Revise", expected_ctx: {}, test_plan: testing_structure, lanes: lanes, schema: schema, message_flow: message_flow
assert_exposes ctx, seq: [:revise, :revise], reader: :[]



Expand Down

0 comments on commit 824dc5d

Please sign in to comment.