From d1f2e40786b96619ab5c1b6be607c158c6fbabda Mon Sep 17 00:00:00 2001 From: Nick Sutterer Date: Sun, 18 Feb 2024 18:46:35 +0100 Subject: [PATCH] better formatting for suspends. working on Test::Plan comment header rendering. --- lib/trailblazer/workflow/discovery/present.rb | 22 +++-- lib/trailblazer/workflow/test/plan.rb | 88 ++++++++++++++++++- test/discovery_test.rb | 18 ++-- 3 files changed, 111 insertions(+), 17 deletions(-) diff --git a/lib/trailblazer/workflow/discovery/present.rb b/lib/trailblazer/workflow/discovery/present.rb index c7b7d6e..e4af248 100644 --- a/lib/trailblazer/workflow/discovery/present.rb +++ b/lib/trailblazer/workflow/discovery/present.rb @@ -13,15 +13,20 @@ def label_for_next_task(activity, catch_event) Trailblazer::Activity::Introspect.Nodes(activity, task: task_after_catch).data[:label] || task_after_catch end - def readable_name_for_catch_event(activity, catch_event, lanes_cfg: {}) + def readable_name_for_catch_event(activity, catch_event, show_lane_icon: true, lanes_cfg: {}) envelope_icon = "(✉)➔" # TODO: implement {envelope_icon} flag. envelope_icon = "⏵︎" - lane_label = lane_label_for(activity, catch_event, lanes_cfg: lanes_cfg) + lane_label = if show_lane_icon + _lane_label = lane_label_for(activity, catch_event, lanes_cfg: lanes_cfg) + "#{_lane_label} " + else + "" + end event_label = label_for_next_task(activity, catch_event) - "#{lane_label} #{envelope_icon}#{event_label}" + "#{lane_label}#{envelope_icon}#{event_label}" end # Compute real catch events from the ID for a particular resume. @@ -32,12 +37,15 @@ def resumes_from_suspend(activity, suspend) end def readable_name_for_suspend_or_terminus(activity, event, **options) + lane_icon = lane_label_for(activity, event, **options) + if event.to_h["resumes"].nil? # Terminus. - readable_lane_position = "◉End.#{event.to_h[:semantic]}" + readable_lane_position = "#{lane_icon} ◉End.#{event.to_h[:semantic]}" else - readable_lane_position = Present.resumes_from_suspend(activity, event).collect do |catch_event| - Present.readable_name_for_catch_event(activity, catch_event, **options) - end.join(",") + catch_labels = Present.resumes_from_suspend(activity, event).collect do |catch_event| + Present.readable_name_for_catch_event(activity, catch_event, show_lane_icon: false, **options) + end.join(" ") + "#{lane_icon} #{catch_labels}" end end diff --git a/lib/trailblazer/workflow/test/plan.rb b/lib/trailblazer/workflow/test/plan.rb index 0d9649f..025729b 100644 --- a/lib/trailblazer/workflow/test/plan.rb +++ b/lib/trailblazer/workflow/test/plan.rb @@ -70,8 +70,10 @@ def assert_advance(event_label, test_plan:, lanes:, schema:, message_flow:, expe end module Plan + module_function + # Code fragment with assertions for the discovered/configured test plan. - def self.for(test_structure, input:) + def for(test_structure, input:) code_string = test_structure.collect do |row| @@ -88,6 +90,90 @@ def self.for(test_structure, input:) ) end end + + def render_comment_header(discovered_states, **options) + CommentHeader.(discovered_states, **options) + end + + module CommentHeader + module_function + + def call(discovered_states, **options) + + all_start_position_labels = discovered_states.collect do |row| + row[:positions_before][0].collect do |activity, task| + [ + activity, + Discovery::Present.readable_name_for_suspend_or_terminus(activity, task, **options) + ] + end + end + + start_position_combined_column = format_positions_column(all_start_position_labels, **options) + + rows = discovered_states.collect.with_index do |row, index| + positions_before, start_position = row[:positions_before] + + Hash[ + "triggered catch", + start_position_label(start_position, row, **options), + + "start configuration", + # start_configuration(positions_before, **options) + start_position_combined_column[index], + ] + end + + Discovery::Present::Table.render(["triggered catch", "start configuration"], rows) + end + + def start_position_label(start_position, row, **options) + outcome = row[:outcome] + + start_position_label_for(start_position, expected_outcome: outcome, **options) + end + + def start_position_label_for(position, expected_outcome:, **options) + event_label = Discovery::Present.readable_name_for_catch_event(*position.to_a, **options) + + event_label += " ⛞" if expected_outcome == :failure # FIXME: what happens to :symbol after serialization? + + event_label + end + + + def compute_combined_column_widths(position_rows, lanes_cfg:, **) + # Find out the longest entry per lane. + columns = lanes_cfg.collect { |_, cfg| [cfg[:activity], []] }.to_h # { => [], ...} + + position_rows.each do |event_labels| + event_labels.each do |(activity, suspend_label)| + length = suspend_label ? suspend_label.length : 0 # DISCUSS: why can {suspend_label} be nil? + + columns[activity] << length + end + end + + _columns_2_length = columns.collect { |activity, lengths| [activity, lengths.max] }.to_h + end + + def format_positions_column(position_rows, lanes_cfg:, **options) + columns_2_length = compute_combined_column_widths(position_rows, lanes_cfg: lanes_cfg, **options) + + rows = position_rows.collect do |event_labels| + columns = event_labels.collect do |activity, suspend_label| + col_length = columns_2_length[activity] + + suspend_label.ljust(col_length, " ") + end + + content = columns.join(" ") + end + + rows + end + end + end end # Test diff --git a/test/discovery_test.rb b/test/discovery_test.rb index b51447b..a4467e4 100644 --- a/test/discovery_test.rb +++ b/test/discovery_test.rb @@ -270,25 +270,25 @@ def assert_position_after(actual_configuration, expected_ids, lanes:) | catch-before-Activity_1psp91r | suspend-gw-to-catch-before-Activity_0wwfenp | suspend-Gateway_14h0q7a | | ☝ ⏵︎Create | ⛾ ⏵︎Create | ☝ ⏵︎Create | | catch-before-Activity_1psp91r | suspend-gw-to-catch-before-Activity_0wwfenp | suspend-Gateway_14h0q7a | -| ☝ ⏵︎Update form | ⛾ ⏵︎Update,⛾ ⏵︎Notify approver | ☝ ⏵︎Update form,☝ ⏵︎Notify approver | +| ☝ ⏵︎Update form | ⛾ ⏵︎Update ⏵︎Notify approver | ☝ ⏵︎Update form ⏵︎Notify approver | | catch-before-Activity_1165bw9 | suspend-Gateway_0fnbg3r | suspend-Gateway_0kknfje | -| ☝ ⏵︎Notify approver | ⛾ ⏵︎Update,⛾ ⏵︎Notify approver | ☝ ⏵︎Update form,☝ ⏵︎Notify approver | +| ☝ ⏵︎Notify approver | ⛾ ⏵︎Update ⏵︎Notify approver | ☝ ⏵︎Update form ⏵︎Notify approver | | catch-before-Activity_1dt5di5 | suspend-Gateway_0fnbg3r | suspend-Gateway_0kknfje | -| ☝ ⏵︎Update | ⛾ ⏵︎Update,⛾ ⏵︎Notify approver | ☝ ⏵︎Update | +| ☝ ⏵︎Update | ⛾ ⏵︎Update ⏵︎Notify approver | ☝ ⏵︎Update | | catch-before-Activity_0j78uzd | suspend-Gateway_0fnbg3r | suspend-Gateway_0nxerxv | -| ☝ ⏵︎Notify approver | ⛾ ⏵︎Update,⛾ ⏵︎Notify approver | ☝ ⏵︎Update form,☝ ⏵︎Notify approver | +| ☝ ⏵︎Notify approver | ⛾ ⏵︎Update ⏵︎Notify approver | ☝ ⏵︎Update form ⏵︎Notify approver | | catch-before-Activity_1dt5di5 | suspend-Gateway_0fnbg3r | suspend-Gateway_0kknfje | -| ☝ ⏵︎Delete? form | ⛾ ⏵︎Publish,⛾ ⏵︎Delete,⛾ ⏵︎Update | ☝ ⏵︎Update form,☝ ⏵︎Delete? form,☝ ⏵︎Publish | +| ☝ ⏵︎Delete? form | ⛾ ⏵︎Publish ⏵︎Delete ⏵︎Update | ☝ ⏵︎Update form ⏵︎Delete? form ⏵︎Publish | | catch-before-Activity_0ha7224 | suspend-Gateway_1hp2ssj | suspend-Gateway_1sq41iq | -| ☝ ⏵︎Publish | ⛾ ⏵︎Publish,⛾ ⏵︎Delete,⛾ ⏵︎Update | ☝ ⏵︎Update form,☝ ⏵︎Delete? form,☝ ⏵︎Publish | +| ☝ ⏵︎Publish | ⛾ ⏵︎Publish ⏵︎Delete ⏵︎Update | ☝ ⏵︎Update form ⏵︎Delete? form ⏵︎Publish | | catch-before-Activity_0bsjggk | suspend-Gateway_1hp2ssj | suspend-Gateway_1sq41iq | -| ☝ ⏵︎Update | ⛾ ⏵︎Update,⛾ ⏵︎Notify approver | ☝ ⏵︎Update | +| ☝ ⏵︎Update | ⛾ ⏵︎Update ⏵︎Notify approver | ☝ ⏵︎Update | | catch-before-Activity_0j78uzd | suspend-Gateway_0fnbg3r | suspend-Gateway_0nxerxv | | ☝ ⏵︎Revise form | ⛾ ⏵︎Revise | ☝ ⏵︎Revise form | | catch-before-Activity_0zsock2 | suspend-Gateway_01p7uj7 | suspend-gw-to-catch-before-Activity_0zsock2 | -| ☝ ⏵︎Delete | ⛾ ⏵︎Publish,⛾ ⏵︎Delete,⛾ ⏵︎Update | ☝ ⏵︎Delete,☝ ⏵︎Cancel | +| ☝ ⏵︎Delete | ⛾ ⏵︎Publish ⏵︎Delete ⏵︎Update | ☝ ⏵︎Delete ⏵︎Cancel | | catch-before-Activity_15nnysv | suspend-Gateway_1hp2ssj | suspend-Gateway_100g9dn | -| ☝ ⏵︎Cancel | ⛾ ⏵︎Publish,⛾ ⏵︎Delete,⛾ ⏵︎Update | ☝ ⏵︎Delete,☝ ⏵︎Cancel | +| ☝ ⏵︎Cancel | ⛾ ⏵︎Publish ⏵︎Delete ⏵︎Update | ☝ ⏵︎Delete ⏵︎Cancel | | catch-before-Activity_1uhozy1 | suspend-Gateway_1hp2ssj | suspend-Gateway_100g9dn | | ☝ ⏵︎Archive | ⛾ ⏵︎Archive | ☝ ⏵︎Archive | | catch-before-Activity_0fy41qq | suspend-gw-to-catch-before-Activity_1hgscu3 | suspend-gw-to-catch-before-Activity_0fy41qq |