markdown_exec 1.8.7 → 1.8.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,8 @@
1
- # encoding=utf-8
1
+ #!/usr/bin/env bundle exec ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ # encoding=utf-8
5
+
4
6
  require 'English'
5
7
  require 'clipboard'
6
8
  require 'fileutils'
@@ -142,9 +144,9 @@ module HashDelegatorSelf
142
144
  # HashDelegator.remove_file_without_standard_errors(temp_blocks_file_path)
143
145
  # end
144
146
 
145
- def error_handler(name = '', opts = {})
147
+ def error_handler(name = '', opts = {}, error: $!)
146
148
  Exceptions.error_handler(
147
- "HashDelegator.#{name} -- #{$!}",
149
+ "HashDelegator.#{name} -- #{error}",
148
150
  opts
149
151
  )
150
152
  end
@@ -555,6 +557,22 @@ module MarkdownExec
555
557
 
556
558
  # private
557
559
 
560
+ def calc_logged_stdout_filename
561
+ return unless @delegate_object[:saved_stdout_folder]
562
+
563
+ @delegate_object[:logged_stdout_filename] =
564
+ SavedAsset.stdout_name(blockname: @delegate_object[:block_name],
565
+ filename: File.basename(@delegate_object[:filename],
566
+ '.*'),
567
+ prefix: @delegate_object[:logged_stdout_filename_prefix],
568
+ time: Time.now.utc)
569
+
570
+ @logged_stdout_filespec =
571
+ @delegate_object[:logged_stdout_filespec] =
572
+ File.join @delegate_object[:saved_stdout_folder],
573
+ @delegate_object[:logged_stdout_filename]
574
+ end
575
+
558
576
  def cfile
559
577
  @cfile ||= CachedNestedFileReader.new(
560
578
  import_pattern: @delegate_object.fetch(:import_pattern) #, "^ *@import +(?<name>.+?) *$")
@@ -585,7 +603,7 @@ module MarkdownExec
585
603
  set_environment_variables_for_block(selected) if selected[:shell] == BlockType::VARS
586
604
 
587
605
  required = mdoc.collect_recursively_required_code(
588
- @delegate_object[:block_name],
606
+ selected[:nickname] || selected[:oname],
589
607
  label_format_above: @delegate_object[:shell_code_label_format_above],
590
608
  label_format_below: @delegate_object[:shell_code_label_format_below],
591
609
  block_source: block_source
@@ -599,7 +617,8 @@ module MarkdownExec
599
617
  warn format_and_highlight_dependencies(dependencies,
600
618
  highlight: required[:unmet_dependencies])
601
619
  runtime_exception(:runtime_exception_error_level,
602
- 'unmet_dependencies, flag: runtime_exception_error_level', required[:unmet_dependencies])
620
+ 'unmet_dependencies, flag: runtime_exception_error_level',
621
+ required[:unmet_dependencies])
603
622
  elsif true
604
623
  warn format_and_highlight_dependencies(dependencies,
605
624
  highlight: [@delegate_object[:block_name]])
@@ -613,26 +632,54 @@ module MarkdownExec
613
632
  @run_state.options = @delegate_object
614
633
  @run_state.started_at = Time.now.utc
615
634
 
616
- Open3.popen3(@delegate_object[:shell],
617
- '-c', command,
618
- @delegate_object[:filename],
619
- *args) do |stdin, stdout, stderr, exec_thr|
620
- handle_stream(stdout, ExecutionStreams::StdOut) do |line|
621
- yield nil, line, nil, exec_thr if block_given?
622
- end
623
- handle_stream(stderr, ExecutionStreams::StdErr) do |line|
624
- yield nil, nil, line, exec_thr if block_given?
625
- end
635
+ if @delegate_object[:execute_in_own_window] &&
636
+ @delegate_object[:execute_command_format].present? &&
637
+ @run_state.saved_filespec.present?
638
+ @run_state.in_own_window = true
639
+ system(
640
+ format(
641
+ @delegate_object[:execute_command_format],
642
+ {
643
+ batch_index: @run_state.batch_index,
644
+ batch_random: @run_state.batch_random,
645
+ block_name: @delegate_object[:block_name],
646
+ document_filename: File.basename(@delegate_object[:filename]),
647
+ document_filespec: @delegate_object[:filename],
648
+ home: Dir.pwd,
649
+ output_filename: File.basename(@delegate_object[:logged_stdout_filespec]),
650
+ output_filespec: @delegate_object[:logged_stdout_filespec],
651
+ script_filename: @run_state.saved_filespec,
652
+ script_filespec: File.join(Dir.pwd, @run_state.saved_filespec),
653
+ started_at: @run_state.started_at.strftime(
654
+ @delegate_object[:execute_command_title_time_format]
655
+ )
656
+ }
657
+ )
658
+ )
626
659
 
627
- in_thr = handle_stream($stdin, ExecutionStreams::StdIn) do |line|
628
- stdin.puts(line)
629
- yield line, nil, nil, exec_thr if block_given?
630
- end
660
+ else
661
+ @run_state.in_own_window = false
662
+ Open3.popen3(@delegate_object[:shell],
663
+ '-c', command,
664
+ @delegate_object[:filename],
665
+ *args) do |stdin, stdout, stderr, exec_thr|
666
+ handle_stream(stdout, ExecutionStreams::StdOut) do |line|
667
+ yield nil, line, nil, exec_thr if block_given?
668
+ end
669
+ handle_stream(stderr, ExecutionStreams::StdErr) do |line|
670
+ yield nil, nil, line, exec_thr if block_given?
671
+ end
672
+
673
+ in_thr = handle_stream($stdin, ExecutionStreams::StdIn) do |line|
674
+ stdin.puts(line)
675
+ yield line, nil, nil, exec_thr if block_given?
676
+ end
631
677
 
632
- wait_for_stream_processing
633
- exec_thr.join
634
- sleep 0.1
635
- in_thr.kill if in_thr&.alive?
678
+ wait_for_stream_processing
679
+ exec_thr.join
680
+ sleep 0.1
681
+ in_thr.kill if in_thr&.alive?
682
+ end
636
683
  end
637
684
 
638
685
  @run_state.completed_at = Time.now.utc
@@ -681,9 +728,13 @@ module MarkdownExec
681
728
  block_source: block_source)
682
729
  output_or_approval = @delegate_object[:output_script] || @delegate_object[:user_must_approve]
683
730
  display_required_code(required_lines) if output_or_approval
684
- allow_execution = @delegate_object[:user_must_approve] ? prompt_for_user_approval(required_lines) : true
731
+ allow_execution = if @delegate_object[:user_must_approve]
732
+ prompt_for_user_approval(required_lines, selected)
733
+ else
734
+ true
735
+ end
685
736
 
686
- execute_required_lines(required_lines) if allow_execution
737
+ execute_required_lines(required_lines, selected) if allow_execution
687
738
 
688
739
  link_state.block_name = nil
689
740
  LoadFileLinkState.new(LoadFile::Reuse, link_state)
@@ -704,7 +755,8 @@ module MarkdownExec
704
755
  # @return [Integer] The count of fenced code blocks in the file.
705
756
  def count_blocks_in_filename
706
757
  regex = Regexp.new(@delegate_object[:fenced_start_and_end_regex])
707
- lines = cfile.readlines(@delegate_object[:filename])
758
+ lines = cfile.readlines(@delegate_object[:filename],
759
+ import_paths: @delegate_object[:import_paths]&.split(':'))
708
760
  HashDelegator.count_matches_in_lines(lines, regex) / 2
709
761
  end
710
762
 
@@ -734,14 +786,14 @@ module MarkdownExec
734
786
  # @param use_chrome [Boolean] Indicates if the chrome styling should be applied.
735
787
  def create_and_add_chrome_blocks(blocks, fcb)
736
788
  match_criteria = [
737
- { match: :heading1_match, format: :menu_heading1_format, color: :menu_heading1_color },
738
- { match: :heading2_match, format: :menu_heading2_format, color: :menu_heading2_color },
739
- { match: :heading3_match, format: :menu_heading3_format, color: :menu_heading3_color },
740
- { match: :menu_divider_match, format: :menu_divider_format,
741
- color: :menu_divider_color },
742
- { match: :menu_note_match, format: :menu_note_format, color: :menu_note_color },
743
- { match: :menu_task_match, format: :menu_task_format, color: :menu_task_color }
789
+ { color: :menu_heading1_color, format: :menu_heading1_format, match: :heading1_match },
790
+ { color: :menu_heading2_color, format: :menu_heading2_format, match: :heading2_match },
791
+ { color: :menu_heading3_color, format: :menu_heading3_format, match: :heading3_match },
792
+ { color: :menu_divider_color, format: :menu_divider_format, match: :menu_divider_match },
793
+ { color: :menu_note_color, format: :menu_note_format, match: :menu_note_match },
794
+ { color: :menu_task_color, format: :menu_task_format, match: :menu_task_match }
744
795
  ]
796
+ # rubocop:enable Style/UnlessElse
745
797
  match_criteria.each do |criteria|
746
798
  unless @delegate_object[criteria[:match]].present? &&
747
799
  (mbody = fcb.body[0].match @delegate_object[criteria[:match]])
@@ -767,6 +819,29 @@ module MarkdownExec
767
819
  )
768
820
  end
769
821
 
822
+ # Prompts user if named block is the same as the prior execution.
823
+ #
824
+ # @return [Boolean] Execute the named block.
825
+ def debounce_allows
826
+ return true unless @delegate_object[:debounce_execution]
827
+
828
+ # filter block if selected in menu
829
+ return true if @run_state.block_name_from_cli
830
+
831
+ # return false if @prior_execution_block == @delegate_object[:block_name]
832
+ if @prior_execution_block == @delegate_object[:block_name]
833
+ return @allowed_execution_block == @prior_execution_block || prompt_approve_repeat
834
+ end
835
+
836
+ @prior_execution_block = @delegate_object[:block_name]
837
+ @allowed_execution_block = nil
838
+ true
839
+ end
840
+
841
+ def debounce_reset
842
+ @prior_execution_block = nil
843
+ end
844
+
770
845
  # Determines the state of a selected block in the menu based on the selected option.
771
846
  # It categorizes the selected option into either EXIT, BACK, or CONTINUE state.
772
847
  #
@@ -803,15 +878,23 @@ module MarkdownExec
803
878
  @delegate_object[:menu_divider_format].present? && @delegate_object[divider_key].present?
804
879
  end
805
880
 
881
+ def do_save_execution_output
882
+ return unless @delegate_object[:save_execution_output]
883
+ return if @run_state.in_own_window
884
+
885
+ HashDelegator.write_execution_output_to_file(@run_state.files,
886
+ @delegate_object[:logged_stdout_filespec])
887
+ end
888
+
806
889
  # Executes a block of code that has been approved for execution.
807
890
  # It sets the script block name, writes command files if required, and handles the execution
808
891
  # including output formatting and summarization.
809
892
  #
810
893
  # @param required_lines [Array<String>] The lines of code to be executed.
811
894
  # @param selected [FCB] The selected functional code block object.
812
- def execute_required_lines(required_lines = [])
813
- # @run_state.script_block_name = selected[:oname]
814
- write_command_file(required_lines) if @delegate_object[:save_executed_script]
895
+ def execute_required_lines(required_lines = [], selected = FCB.new)
896
+ write_command_file(required_lines, selected) if @delegate_object[:save_executed_script]
897
+ calc_logged_stdout_filename
815
898
  format_and_execute_command(required_lines)
816
899
  post_execution_process
817
900
  end
@@ -828,21 +911,26 @@ module MarkdownExec
828
911
  def execute_shell_type(selected, mdoc, link_state = LinkState.new,
829
912
  block_source:)
830
913
  if selected.fetch(:shell, '') == BlockType::LINK
914
+ debounce_reset
831
915
  push_link_history_and_trigger_load(selected.fetch(:body, ''), mdoc, selected,
832
916
  link_state)
833
917
 
834
918
  elsif @menu_user_clicked_back_link
919
+ debounce_reset
835
920
  pop_link_history_and_trigger_load
836
921
 
837
922
  elsif selected[:shell] == BlockType::OPTS
923
+ debounce_reset
838
924
  options_state = read_show_options_and_trigger_reuse(selected, link_state)
839
925
  @menu_base_options.merge!(options_state.options)
840
926
  @delegate_object.merge!(options_state.options)
841
927
  options_state.load_file_link_state
842
928
 
843
- else
929
+ elsif debounce_allows
844
930
  compile_execute_and_trigger_reuse(mdoc, selected, link_state,
845
931
  block_source: block_source)
932
+ else
933
+ LoadFileLinkState.new(LoadFile::Reuse, link_state)
846
934
  end
847
935
  end
848
936
 
@@ -904,12 +992,31 @@ module MarkdownExec
904
992
  @delegate_object[:block_stdout_scan])
905
993
 
906
994
  shell_color_option = SHELL_COLOR_OPTIONS[fcb[:shell]]
907
- fcb.title = fcb.oname = bm && bm[1] ? bm[:title] : titlexcall
908
- fcb.dname = apply_shell_color_option(fcb.oname, shell_color_option)
909
995
 
996
+ if @delegate_object[:block_name_nick_match].present? && fcb.oname =~ Regexp.new(@delegate_object[:block_name_nick_match])
997
+ fcb.nickname = $~[0]
998
+ fcb.title = fcb.oname = format_multiline_body_as_title(fcb.body)
999
+ else
1000
+ fcb.title = fcb.oname = bm && bm[1] ? bm[:title] : titlexcall
1001
+ end
1002
+
1003
+ fcb.dname = HashDelegator.indent_all_lines(
1004
+ apply_shell_color_option(fcb.oname, shell_color_option),
1005
+ fcb.fetch(:indent, nil)
1006
+ )
910
1007
  fcb
911
1008
  end
912
1009
 
1010
+ # Formats multiline body content as a title string.
1011
+ # indents all but first line with two spaces so it displays correctly in menu
1012
+ # @param body_lines [Array<String>] The lines of body content.
1013
+ # @return [String] Formatted title.
1014
+ def format_multiline_body_as_title(body_lines)
1015
+ body_lines.map.with_index do |line, index|
1016
+ index.zero? ? line : " #{line}"
1017
+ end.join("\n") + "\n"
1018
+ end
1019
+
913
1020
  # Updates the delegate object's state based on the provided block state.
914
1021
  # It sets the block name and determines if the user clicked the back link in the menu.
915
1022
  #
@@ -962,25 +1069,6 @@ module MarkdownExec
962
1069
  }
963
1070
  end
964
1071
 
965
- def initialize_and_save_execution_output
966
- return unless @delegate_object[:save_execution_output]
967
-
968
- @delegate_object[:logged_stdout_filename] =
969
- SavedAsset.stdout_name(blockname: @delegate_object[:block_name],
970
- filename: File.basename(@delegate_object[:filename],
971
- '.*'),
972
- prefix: @delegate_object[:logged_stdout_filename_prefix],
973
- time: Time.now.utc)
974
-
975
- @logged_stdout_filespec =
976
- @delegate_object[:logged_stdout_filespec] =
977
- File.join @delegate_object[:saved_stdout_folder],
978
- @delegate_object[:logged_stdout_filename]
979
- @logged_stdout_filespec = @delegate_object[:logged_stdout_filespec]
980
- HashDelegator.write_execution_output_to_file(@run_state.files,
981
- @delegate_object[:logged_stdout_filespec])
982
- end
983
-
984
1072
  # Iterates through blocks in a file, applying the provided block to each line.
985
1073
  # The iteration only occurs if the file exists.
986
1074
  # @yield [Symbol] :filter Yields to obtain selected messages for processing.
@@ -989,8 +1077,8 @@ module MarkdownExec
989
1077
 
990
1078
  state = initial_state
991
1079
  selected_messages = yield :filter
992
-
993
- cfile.readlines(@delegate_object[:filename]).each do |nested_line|
1080
+ cfile.readlines(@delegate_object[:filename],
1081
+ import_paths: @delegate_object[:import_paths]&.split(':')).each do |nested_line|
994
1082
  if nested_line
995
1083
  update_line_and_block_state(nested_line, state, selected_messages,
996
1084
  &block)
@@ -998,6 +1086,65 @@ module MarkdownExec
998
1086
  end
999
1087
  end
1000
1088
 
1089
+ def link_block_data_eval(link_state, code_lines, selected, link_block_data)
1090
+ all_code = HashDelegator.code_merge(link_state&.inherited_lines, code_lines)
1091
+
1092
+ if link_block_data.fetch(LinkDataKeys::Exec, false)
1093
+ @run_state.files = Hash.new([])
1094
+ output_lines = []
1095
+
1096
+ Open3.popen3(
1097
+ @delegate_object[:shell],
1098
+ '-c', all_code.join("\n")
1099
+ ) do |stdin, stdout, stderr, _exec_thr|
1100
+ handle_stream(stdout, ExecutionStreams::StdOut) do |line|
1101
+ output_lines.push(line)
1102
+ end
1103
+ handle_stream(stderr, ExecutionStreams::StdErr) do |line|
1104
+ output_lines.push(line)
1105
+ end
1106
+
1107
+ in_thr = handle_stream($stdin, ExecutionStreams::StdIn) do |line|
1108
+ stdin.puts(line)
1109
+ end
1110
+
1111
+ wait_for_stream_processing
1112
+ sleep 0.1
1113
+ in_thr.kill if in_thr&.alive?
1114
+ end
1115
+
1116
+ ## select output_lines that look like assignment or match other specs
1117
+ #
1118
+ output_lines = process_string_array(
1119
+ output_lines,
1120
+ begin_pattern: @delegate_object.fetch(:output_assignment_begin, nil),
1121
+ end_pattern: @delegate_object.fetch(:output_assignment_end, nil),
1122
+ scan1: @delegate_object.fetch(:output_assignment_match, nil),
1123
+ format1: @delegate_object.fetch(:output_assignment_format, nil)
1124
+ )
1125
+
1126
+ else
1127
+ output_lines = `#{all_code.join("\n")}`.split("\n")
1128
+ end
1129
+
1130
+ unless output_lines
1131
+ HashDelegator.error_handler('all_code eval output_lines is nil', { abort: true })
1132
+ end
1133
+
1134
+ label_format_above = @delegate_object[:shell_code_label_format_above]
1135
+ label_format_below = @delegate_object[:shell_code_label_format_below]
1136
+ block_source = { document_filename: link_state&.document_filename }
1137
+
1138
+ [label_format_above && format(label_format_above,
1139
+ block_source.merge({ block_name: selected[:oname] }))] +
1140
+ output_lines.map do |line|
1141
+ re = Regexp.new(link_block_data.fetch('pattern', '(?<line>.*)'))
1142
+ re.gsub_format(line, link_block_data.fetch('format', '%{line}')) if re =~ line
1143
+ end.compact +
1144
+ [label_format_below && format(label_format_below,
1145
+ block_source.merge({ block_name: selected[:oname] }))]
1146
+ end
1147
+
1001
1148
  def link_history_push_and_next(
1002
1149
  curr_block_name:, curr_document_filename:,
1003
1150
  inherited_block_names:, inherited_dependencies:, inherited_lines:,
@@ -1165,23 +1312,38 @@ module MarkdownExec
1165
1312
  ), level: level
1166
1313
  end
1167
1314
 
1168
- def pop_add_current_code_to_head_and_trigger_load(_link_state, block_names, code_lines,
1169
- dependencies)
1315
+ def pop_add_current_code_to_head_and_trigger_load(link_state, block_names, code_lines,
1316
+ dependencies, selected)
1170
1317
  pop = @link_history.pop # updatable
1171
- next_state = LinkState.new(
1172
- block_name: pop.block_name,
1173
- document_filename: pop.document_filename,
1174
- inherited_block_names:
1175
- (pop.inherited_block_names + block_names).sort.uniq,
1176
- inherited_dependencies:
1177
- dependencies.merge(pop.inherited_dependencies || {}), ### merge, not replace, key data
1178
- inherited_lines:
1179
- HashDelegator.code_merge(pop.inherited_lines, code_lines)
1180
- )
1181
- @link_history.push(next_state)
1318
+ if pop.document_filename
1319
+ next_state = LinkState.new(
1320
+ block_name: pop.block_name,
1321
+ document_filename: pop.document_filename,
1322
+ inherited_block_names:
1323
+ (pop.inherited_block_names + block_names).sort.uniq,
1324
+ inherited_dependencies:
1325
+ dependencies.merge(pop.inherited_dependencies || {}), ### merge, not replace, key data
1326
+ inherited_lines:
1327
+ HashDelegator.code_merge(pop.inherited_lines, code_lines)
1328
+ )
1329
+ @link_history.push(next_state)
1182
1330
 
1183
- next_state.block_name = nil
1184
- LoadFileLinkState.new(LoadFile::Load, next_state)
1331
+ next_state.block_name = nil
1332
+ LoadFileLinkState.new(LoadFile::Load, next_state)
1333
+ else
1334
+ # no history exists; must have been called independently => retain script
1335
+ link_history_push_and_next(
1336
+ curr_block_name: selected[:oname],
1337
+ curr_document_filename: @delegate_object[:filename],
1338
+ inherited_block_names: ((link_state&.inherited_block_names || []) + block_names).sort.uniq,
1339
+ inherited_dependencies: (link_state&.inherited_dependencies || {}).merge(dependencies || {}), ### merge, not replace, key data
1340
+ inherited_lines: HashDelegator.code_merge(link_state&.inherited_lines, code_lines),
1341
+ next_block_name: '', # not link_block_data['block'] || ''
1342
+ next_document_filename: @delegate_object[:filename], # not next_document_filename
1343
+ next_load_file: LoadFile::Reuse # not next_document_filename == @delegate_object[:filename] ? LoadFile::Reuse : LoadFile::Load
1344
+ )
1345
+ # LoadFileLinkState.new(LoadFile::Reuse, link_state)
1346
+ end
1185
1347
  end
1186
1348
 
1187
1349
  # This method handles the back-link operation in the Markdown execution context.
@@ -1200,7 +1362,7 @@ module MarkdownExec
1200
1362
  end
1201
1363
 
1202
1364
  def post_execution_process
1203
- initialize_and_save_execution_output
1365
+ do_save_execution_output
1204
1366
  output_execution_summary
1205
1367
  output_execution_result
1206
1368
  end
@@ -1216,7 +1378,7 @@ module MarkdownExec
1216
1378
  %i[block_name_include_match block_name_wrapper_match])
1217
1379
 
1218
1380
  fcb.merge!(
1219
- name: HashDelegator.indent_all_lines(fcb.dname, fcb.fetch(:indent, nil)),
1381
+ name: fcb.dname,
1220
1382
  label: BlockLabel.make(
1221
1383
  body: fcb[:body],
1222
1384
  filename: @delegate_object[:filename],
@@ -1250,6 +1412,61 @@ module MarkdownExec
1250
1412
  end
1251
1413
  end
1252
1414
 
1415
+ def process_string_array(arr, begin_pattern: nil, end_pattern: nil, scan1: nil,
1416
+ format1: nil)
1417
+ in_block = !begin_pattern.present?
1418
+ collected_lines = []
1419
+
1420
+ arr.each do |line|
1421
+ if in_block
1422
+ if end_pattern.present? && line.match?(end_pattern)
1423
+ in_block = false
1424
+ elsif scan1.present?
1425
+ if format1.present?
1426
+ caps = extract_named_captures_from_option(line, scan1)
1427
+ if caps
1428
+ formatted = format(format1, caps)
1429
+ collected_lines << formatted
1430
+ end
1431
+ else
1432
+ caps = line.match(scan1)
1433
+ if caps
1434
+ formatted = caps[0]
1435
+ collected_lines << formatted
1436
+ end
1437
+ end
1438
+ else
1439
+ collected_lines << line
1440
+ end
1441
+ elsif begin_pattern.present? && line.match?(begin_pattern)
1442
+ in_block = true
1443
+ end
1444
+ end
1445
+
1446
+ collected_lines
1447
+ end
1448
+
1449
+ def prompt_approve_repeat
1450
+ sel = @prompt.select(
1451
+ string_send_color(@delegate_object[:prompt_debounce],
1452
+ :prompt_color_after_script_execution),
1453
+ default: @delegate_object[:prompt_no],
1454
+ filter: true,
1455
+ quiet: true
1456
+ ) do |menu|
1457
+ menu.choice @delegate_object[:prompt_yes]
1458
+ menu.choice @delegate_object[:prompt_no]
1459
+ menu.choice @delegate_object[:prompt_uninterrupted]
1460
+ end
1461
+ return false if sel == @delegate_object[:prompt_no]
1462
+ return true if sel == @delegate_object[:prompt_yes]
1463
+
1464
+ @allowed_execution_block = @prior_execution_block
1465
+ true
1466
+ rescue TTY::Reader::InputInterrupt
1467
+ exit 1
1468
+ end
1469
+
1253
1470
  ##
1254
1471
  # Presents a menu to the user for approving an action and performs additional tasks based on the selection.
1255
1472
  # The function provides options for approval, rejection, copying data to clipboard, or saving data to a file.
@@ -1265,7 +1482,7 @@ module MarkdownExec
1265
1482
  #
1266
1483
  # @return [Boolean] Returns true if the user approves (selects 'Yes'), false otherwise.
1267
1484
  ##
1268
- def prompt_for_user_approval(required_lines)
1485
+ def prompt_for_user_approval(required_lines, selected)
1269
1486
  # Present a selection menu for user approval.
1270
1487
  sel = @prompt.select(
1271
1488
  string_send_color(@delegate_object[:prompt_approve_block],
@@ -1285,7 +1502,7 @@ module MarkdownExec
1285
1502
  if sel == MenuOptions::SCRIPT_TO_CLIPBOARD
1286
1503
  copy_to_clipboard(required_lines)
1287
1504
  elsif sel == MenuOptions::SAVE_SCRIPT
1288
- save_to_file(required_lines)
1505
+ save_to_file(required_lines, selected)
1289
1506
  end
1290
1507
 
1291
1508
  sel == MenuOptions::YES
@@ -1326,6 +1543,7 @@ module MarkdownExec
1326
1543
  #
1327
1544
  (link_block_data['vars'] || []).each do |(key, value)|
1328
1545
  ENV[key] = value.to_s
1546
+ ### add to inherited_lines
1329
1547
  end
1330
1548
 
1331
1549
  ## collect blocks specified by block
@@ -1347,31 +1565,22 @@ module MarkdownExec
1347
1565
  end
1348
1566
  next_document_filename = link_block_data['file'] || @delegate_object[:filename]
1349
1567
 
1350
- # if an eval link block, evaluate code_lines and return its standard output
1568
+ ## append blocks loaded per LinkDataKeys::Load
1351
1569
  #
1352
- if link_block_data.fetch('eval', false)
1353
- all_code = HashDelegator.code_merge(link_state&.inherited_lines, code_lines)
1354
- output = `#{all_code.join("\n")}`.split("\n")
1355
- label_format_above = @delegate_object[:shell_code_label_format_above]
1356
- label_format_below = @delegate_object[:shell_code_label_format_below]
1357
- block_source = { document_filename: link_state&.document_filename }
1358
-
1359
- code_lines = [label_format_above && format(label_format_above,
1360
- block_source.merge({ block_name: selected[:oname] }))] +
1361
- output.map do |line|
1362
- re = Regexp.new(link_block_data.fetch('pattern', '(?<line>.*)'))
1363
- if re =~ line
1364
- re.gsub_format(line, link_block_data.fetch('format', '%{line}'))
1365
- end
1366
- end.compact +
1367
- [label_format_below && format(label_format_below,
1368
- block_source.merge({ block_name: selected[:oname] }))]
1570
+ if (load_filespec = link_block_data.fetch(LinkDataKeys::Load, '')).present?
1571
+ code_lines += File.readlines(load_filespec, chomp: true)
1572
+ end
1369
1573
 
1574
+ # if an eval link block, evaluate code_lines and return its standard output
1575
+ #
1576
+ if link_block_data.fetch(LinkDataKeys::Eval,
1577
+ false) || link_block_data.fetch(LinkDataKeys::Exec, false)
1578
+ code_lines = link_block_data_eval(link_state, code_lines, selected, link_block_data)
1370
1579
  end
1371
1580
 
1372
- if link_block_data['return']
1581
+ if link_block_data[LinkDataKeys::Return]
1373
1582
  pop_add_current_code_to_head_and_trigger_load(link_state, block_names, code_lines,
1374
- dependencies)
1583
+ dependencies, selected)
1375
1584
 
1376
1585
  else
1377
1586
  link_history_push_and_next(
@@ -1406,8 +1615,8 @@ module MarkdownExec
1406
1615
  exit @delegate_object[exception_sym]
1407
1616
  end
1408
1617
 
1409
- def save_to_file(required_lines)
1410
- write_command_file(required_lines)
1618
+ def save_to_file(required_lines, selected)
1619
+ write_command_file(required_lines, selected)
1411
1620
  @fout.fout "File saved: #{@run_state.saved_filespec}"
1412
1621
  end
1413
1622
 
@@ -1423,21 +1632,27 @@ module MarkdownExec
1423
1632
  block_name: @delegate_object[:block_name],
1424
1633
  document_filename: @delegate_object[:filename]
1425
1634
  )
1426
- block_name_from_cli = link_state.block_name.present?
1635
+ @run_state.block_name_from_cli = link_state.block_name.present?
1427
1636
  @cli_block_name = link_state.block_name
1428
- now_using_cli = block_name_from_cli
1637
+ now_using_cli = @run_state.block_name_from_cli
1429
1638
  menu_default_dname = nil
1430
1639
 
1640
+ @run_state.batch_random = Random.new.rand
1641
+ @run_state.batch_index = 0
1642
+
1431
1643
  loop do
1644
+ @run_state.batch_index += 1
1645
+ @run_state.in_own_window = false
1646
+
1432
1647
  # &bsp 'loop', block_name_from_cli, @cli_block_name
1433
- block_name_from_cli, now_using_cli, blocks_in_file, menu_blocks, mdoc = \
1434
- set_delobj_menu_loop_vars(block_name_from_cli, now_using_cli, link_state)
1648
+ @run_state.block_name_from_cli, now_using_cli, blocks_in_file, menu_blocks, mdoc = \
1649
+ set_delobj_menu_loop_vars(@run_state.block_name_from_cli, now_using_cli, link_state)
1435
1650
 
1436
1651
  # cli or user selection
1437
1652
  #
1438
1653
  block_state = load_cli_or_user_selected_block(blocks_in_file, menu_blocks,
1439
1654
  menu_default_dname)
1440
- # &bsp 'block_name_from_cli:',block_name_from_cli
1655
+ # &bsp '@run_state.block_name_from_cli:',@run_state.block_name_from_cli
1441
1656
  if !block_state
1442
1657
  HashDelegator.error_handler('block_state missing', { abort: true })
1443
1658
  elsif block_state.state == MenuState::EXIT
@@ -1448,12 +1663,12 @@ module MarkdownExec
1448
1663
  dump_and_warn_block_state(block_state.block)
1449
1664
  link_state, menu_default_dname = exec_bash_next_state(block_state.block, mdoc,
1450
1665
  link_state)
1451
- if prompt_user_exit(block_name_from_cli, block_state.block)
1666
+ if prompt_user_exit(@run_state.block_name_from_cli, block_state.block)
1452
1667
  # &bsp 'prompt_user_exit -> break'
1453
1668
  break
1454
1669
  end
1455
1670
 
1456
- link_state.block_name, block_name_from_cli, cli_break = \
1671
+ link_state.block_name, @run_state.block_name_from_cli, cli_break = \
1457
1672
  HashDelegator.next_link_state(!shift_cli_argument, now_using_cli, block_state)
1458
1673
 
1459
1674
  if !block_state.block[:block_name_from_ui] && cli_break
@@ -1572,11 +1787,16 @@ module MarkdownExec
1572
1787
  selection = @prompt.select(prompt_text,
1573
1788
  names,
1574
1789
  opts.merge(filter: true))
1790
+
1575
1791
  item = if names.first.instance_of?(String)
1576
1792
  { dname: selection }
1577
1793
  else
1578
1794
  names.find { |item| item[:dname] == selection }
1579
1795
  end
1796
+ unless item
1797
+ HashDelegator.error_handler('select_option_with_metadata', error: 'menu item not found')
1798
+ exit 1
1799
+ end
1580
1800
 
1581
1801
  item.merge(
1582
1802
  if selection == menu_chrome_colored_option(:menu_option_back_name)
@@ -1594,7 +1814,7 @@ module MarkdownExec
1594
1814
  end
1595
1815
 
1596
1816
  def set_environment_variables_for_block(selected)
1597
- YAML.load(selected[:body].join("\n")).each do |key, value|
1817
+ YAML.load(selected[:body].join("\n"))&.each do |key, value|
1598
1818
  ENV[key] = value.to_s
1599
1819
  next unless @delegate_object[:menu_vars_set_format].present?
1600
1820
 
@@ -1623,13 +1843,22 @@ module MarkdownExec
1623
1843
  !name.match(Regexp.new(@delegate_object[:block_name_wrapper_match]))
1624
1844
  end
1625
1845
 
1846
+ dname = oname = title = ''
1847
+ nickname = nil
1848
+ if @delegate_object[:block_name_nick_match].present? && oname =~ Regexp.new(@delegate_object[:block_name_nick_match])
1849
+ nickname = $~[0]
1850
+ else
1851
+ dname = oname = title = fcb_title_groups.fetch(:name, '')
1852
+ end
1853
+
1626
1854
  MarkdownExec::FCB.new(
1627
1855
  body: [],
1628
1856
  call: rest.match(Regexp.new(@delegate_object[:block_calls_scan]))&.to_a&.first,
1629
- dname: fcb_title_groups.fetch(:name, ''),
1857
+ dname: dname,
1630
1858
  headings: headings,
1631
1859
  indent: fcb_title_groups.fetch(:indent, ''),
1632
- oname: fcb_title_groups.fetch(:name, ''),
1860
+ nickname: nickname,
1861
+ oname: oname,
1633
1862
  reqs: reqs,
1634
1863
  shell: fcb_title_groups.fetch(:shell, ''),
1635
1864
  stdin: if (tn = rest.match(/<(?<type>\$)?(?<name>[A-Za-z_-]\S+)/))
@@ -1638,7 +1867,7 @@ module MarkdownExec
1638
1867
  stdout: if (tn = rest.match(/>(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/))
1639
1868
  tn.named_captures.sym_keys
1640
1869
  end,
1641
- title: fcb_title_groups.fetch(:name, ''),
1870
+ title: title,
1642
1871
  wraps: wraps
1643
1872
  )
1644
1873
  end
@@ -1767,15 +1996,17 @@ module MarkdownExec
1767
1996
  end
1768
1997
 
1769
1998
  # Handles the core logic for generating the command file's metadata and content.
1770
- def write_command_file(required_lines)
1999
+ def write_command_file(required_lines, selected)
1771
2000
  return unless @delegate_object[:save_executed_script]
1772
2001
 
1773
2002
  time_now = Time.now.utc
1774
2003
  @run_state.saved_script_filename =
1775
- SavedAsset.script_name(blockname: @delegate_object[:block_name],
1776
- filename: @delegate_object[:filename],
1777
- prefix: @delegate_object[:saved_script_filename_prefix],
1778
- time: time_now)
2004
+ SavedAsset.script_name(
2005
+ blockname: selected[:nickname] || selected[:oname],
2006
+ filename: @delegate_object[:filename],
2007
+ prefix: @delegate_object[:saved_script_filename_prefix],
2008
+ time: time_now
2009
+ )
1779
2010
  @run_state.saved_filespec =
1780
2011
  File.join(@delegate_object[:saved_script_folder],
1781
2012
  @run_state.saved_script_filename)
@@ -1824,848 +2055,850 @@ module MarkdownExec
1824
2055
  end
1825
2056
  end
1826
2057
 
1827
- if $PROGRAM_NAME == __FILE__
1828
- require 'bundler/setup'
1829
- Bundler.require(:default)
2058
+ return if $PROGRAM_NAME != __FILE__
1830
2059
 
1831
- require 'minitest/autorun'
1832
- require 'mocha/minitest'
2060
+ require 'bundler/setup'
2061
+ Bundler.require(:default)
1833
2062
 
1834
- module MarkdownExec
1835
- class TestHashDelegator < Minitest::Test
1836
- def setup
1837
- @hd = HashDelegator.new
1838
- @mdoc = mock('MarkdownDocument')
1839
- end
2063
+ require 'minitest/autorun'
2064
+ require 'mocha/minitest'
1840
2065
 
1841
- def test_calling_execute_required_lines_calls_command_execute_with_argument_args_value
1842
- pigeon = 'E'
1843
- obj = {
1844
- output_execution_label_format: '',
1845
- output_execution_label_name_color: 'plain',
1846
- output_execution_label_value_color: 'plain'
1847
- }
2066
+ module MarkdownExec
2067
+ class TestHashDelegator < Minitest::Test
2068
+ def setup
2069
+ @hd = HashDelegator.new
2070
+ @mdoc = mock('MarkdownDocument')
2071
+ end
2072
+
2073
+ def test_calling_execute_required_lines_calls_command_execute_with_argument_args_value
2074
+ pigeon = 'E'
2075
+ obj = {
2076
+ output_execution_label_format: '',
2077
+ output_execution_label_name_color: 'plain',
2078
+ output_execution_label_value_color: 'plain'
2079
+ }
1848
2080
 
1849
- c = MarkdownExec::HashDelegator.new(obj)
1850
- c.pass_args = pigeon
2081
+ c = MarkdownExec::HashDelegator.new(obj)
2082
+ c.pass_args = pigeon
1851
2083
 
1852
- # Expect that method opts_command_execute is called with argument args having value pigeon
1853
- c.expects(:command_execute).with(
1854
- '',
1855
- args: pigeon
1856
- )
2084
+ # Expect that method opts_command_execute is called with argument args having value pigeon
2085
+ c.expects(:command_execute).with(
2086
+ '',
2087
+ args: pigeon
2088
+ )
1857
2089
 
1858
- # Call method opts_execute_required_lines
1859
- c.execute_required_lines([])
1860
- end
2090
+ # Call method opts_execute_required_lines
2091
+ c.execute_required_lines
2092
+ end
1861
2093
 
1862
- # Test case for empty body
1863
- def test_push_link_history_and_trigger_load_with_empty_body
1864
- assert_equal LoadFile::Reuse,
1865
- @hd.push_link_history_and_trigger_load([], nil, FCB.new).load_file
1866
- end
2094
+ # Test case for empty body
2095
+ def test_push_link_history_and_trigger_load_with_empty_body
2096
+ assert_equal LoadFile::Reuse,
2097
+ @hd.push_link_history_and_trigger_load([], nil, FCB.new).load_file
2098
+ end
1867
2099
 
1868
- # Test case for non-empty body without 'file' key
1869
- def test_push_link_history_and_trigger_load_without_file_key
1870
- body = ["vars:\n KEY: VALUE"]
1871
- assert_equal LoadFile::Reuse,
1872
- @hd.push_link_history_and_trigger_load(body, nil, FCB.new).load_file
1873
- end
2100
+ # Test case for non-empty body without 'file' key
2101
+ def test_push_link_history_and_trigger_load_without_file_key
2102
+ body = ["vars:\n KEY: VALUE"]
2103
+ assert_equal LoadFile::Reuse,
2104
+ @hd.push_link_history_and_trigger_load(body, nil, FCB.new).load_file
2105
+ end
1874
2106
 
1875
- # Test case for non-empty body with 'file' key
1876
- def test_push_link_history_and_trigger_load_with_file_key
1877
- body = ["file: sample_file\nblock: sample_block\nvars:\n KEY: VALUE"]
1878
- expected_result = LoadFileLinkState.new(LoadFile::Load,
1879
- LinkState.new(block_name: 'sample_block',
1880
- document_filename: 'sample_file',
1881
- inherited_dependencies: {},
1882
- inherited_lines: []))
1883
- assert_equal expected_result,
1884
- @hd.push_link_history_and_trigger_load(body, nil, FCB.new(block_name: 'sample_block',
1885
- filename: 'sample_file'))
1886
- end
2107
+ # Test case for non-empty body with 'file' key
2108
+ def test_push_link_history_and_trigger_load_with_file_key
2109
+ body = ["file: sample_file\nblock: sample_block\nvars:\n KEY: VALUE"]
2110
+ expected_result = LoadFileLinkState.new(LoadFile::Load,
2111
+ LinkState.new(block_name: 'sample_block',
2112
+ document_filename: 'sample_file',
2113
+ inherited_dependencies: {},
2114
+ inherited_lines: []))
2115
+ assert_equal expected_result,
2116
+ @hd.push_link_history_and_trigger_load(body, nil, FCB.new(block_name: 'sample_block',
2117
+ filename: 'sample_file'))
2118
+ end
1887
2119
 
1888
- def test_indent_all_lines_with_indent
1889
- body = "Line 1\nLine 2"
1890
- indent = ' ' # Two spaces
1891
- expected_result = " Line 1\n Line 2"
1892
- assert_equal expected_result, HashDelegator.indent_all_lines(body, indent)
1893
- end
2120
+ def test_indent_all_lines_with_indent
2121
+ body = "Line 1\nLine 2"
2122
+ indent = ' ' # Two spaces
2123
+ expected_result = " Line 1\n Line 2"
2124
+ assert_equal expected_result, HashDelegator.indent_all_lines(body, indent)
2125
+ end
1894
2126
 
1895
- def test_indent_all_lines_without_indent
1896
- body = "Line 1\nLine 2"
1897
- indent = nil
2127
+ def test_indent_all_lines_without_indent
2128
+ body = "Line 1\nLine 2"
2129
+ indent = nil
1898
2130
 
1899
- assert_equal body, HashDelegator.indent_all_lines(body, indent)
1900
- end
2131
+ assert_equal body, HashDelegator.indent_all_lines(body, indent)
2132
+ end
1901
2133
 
1902
- def test_indent_all_lines_with_empty_indent
1903
- body = "Line 1\nLine 2"
1904
- indent = ''
2134
+ def test_indent_all_lines_with_empty_indent
2135
+ body = "Line 1\nLine 2"
2136
+ indent = ''
1905
2137
 
1906
- assert_equal body, HashDelegator.indent_all_lines(body, indent)
1907
- end
2138
+ assert_equal body, HashDelegator.indent_all_lines(body, indent)
2139
+ end
1908
2140
 
1909
- def test_safeval_successful_evaluation
1910
- assert_equal 4, HashDelegator.safeval('2 + 2')
1911
- end
2141
+ def test_safeval_successful_evaluation
2142
+ assert_equal 4, HashDelegator.safeval('2 + 2')
2143
+ end
1912
2144
 
1913
- def test_safeval_rescue_from_error
1914
- HashDelegator.stubs(:error_handler).with('safeval')
1915
- assert_nil HashDelegator.safeval('invalid code')
1916
- end
2145
+ def test_safeval_rescue_from_error
2146
+ HashDelegator.stubs(:error_handler).with('safeval')
2147
+ assert_nil HashDelegator.safeval('invalid code')
2148
+ end
1917
2149
 
1918
- def test_set_fcb_title
1919
- # sample input and output data for testing default_block_title_from_body method
1920
- input_output_data = [
1921
- {
1922
- input: MarkdownExec::FCB.new(title: nil,
1923
- body: ["puts 'Hello, world!'"]),
1924
- output: "puts 'Hello, world!'"
1925
- },
1926
- {
1927
- input: MarkdownExec::FCB.new(title: '',
1928
- body: ['def add(x, y)',
1929
- ' x + y', 'end']),
1930
- output: "def add(x, y)\n x + y\n end\n"
1931
- },
1932
- {
1933
- input: MarkdownExec::FCB.new(title: 'foo', body: %w[bar baz]),
1934
- output: 'foo' # expect the title to remain unchanged
1935
- }
1936
- ]
2150
+ def test_set_fcb_title
2151
+ # sample input and output data for testing default_block_title_from_body method
2152
+ input_output_data = [
2153
+ {
2154
+ input: MarkdownExec::FCB.new(title: nil,
2155
+ body: ["puts 'Hello, world!'"]),
2156
+ output: "puts 'Hello, world!'"
2157
+ },
2158
+ {
2159
+ input: MarkdownExec::FCB.new(title: '',
2160
+ body: ['def add(x, y)',
2161
+ ' x + y', 'end']),
2162
+ output: "def add(x, y)\n x + y\n end\n"
2163
+ },
2164
+ {
2165
+ input: MarkdownExec::FCB.new(title: 'foo', body: %w[bar baz]),
2166
+ output: 'foo' # expect the title to remain unchanged
2167
+ }
2168
+ ]
1937
2169
 
1938
- # iterate over the input and output data and
1939
- # assert that the method sets the title as expected
1940
- input_output_data.each do |data|
1941
- input = data[:input]
1942
- output = data[:output]
1943
- HashDelegator.default_block_title_from_body(input)
1944
- assert_equal output, input.title
1945
- end
2170
+ # iterate over the input and output data and
2171
+ # assert that the method sets the title as expected
2172
+ input_output_data.each do |data|
2173
+ input = data[:input]
2174
+ output = data[:output]
2175
+ HashDelegator.default_block_title_from_body(input)
2176
+ assert_equal output, input.title
1946
2177
  end
2178
+ end
1947
2179
 
1948
- class TestHashDelegatorAppendDivider < Minitest::Test
1949
- def setup
1950
- @hd = HashDelegator.new
1951
- @hd.instance_variable_set(:@delegate_object, {
1952
- menu_divider_format: 'Format',
1953
- menu_initial_divider: 'Initial Divider',
1954
- menu_final_divider: 'Final Divider',
1955
- menu_divider_color: :color
1956
- })
1957
- @hd.stubs(:string_send_color).returns('Formatted Divider')
1958
- HashDelegator.stubs(:safeval).returns('Safe Value')
1959
- end
2180
+ class TestHashDelegatorAppendDivider < Minitest::Test
2181
+ def setup
2182
+ @hd = HashDelegator.new
2183
+ @hd.instance_variable_set(:@delegate_object, {
2184
+ menu_divider_format: 'Format',
2185
+ menu_initial_divider: 'Initial Divider',
2186
+ menu_final_divider: 'Final Divider',
2187
+ menu_divider_color: :color
2188
+ })
2189
+ @hd.stubs(:string_send_color).returns('Formatted Divider')
2190
+ HashDelegator.stubs(:safeval).returns('Safe Value')
2191
+ end
1960
2192
 
1961
- def test_append_divider_initial
1962
- menu_blocks = []
1963
- @hd.append_divider(menu_blocks, :initial)
2193
+ def test_append_divider_initial
2194
+ menu_blocks = []
2195
+ @hd.append_divider(menu_blocks, :initial)
1964
2196
 
1965
- assert_equal 1, menu_blocks.size
1966
- assert_equal 'Formatted Divider', menu_blocks.first.dname
1967
- end
2197
+ assert_equal 1, menu_blocks.size
2198
+ assert_equal 'Formatted Divider', menu_blocks.first.dname
2199
+ end
1968
2200
 
1969
- def test_append_divider_final
1970
- menu_blocks = []
1971
- @hd.append_divider(menu_blocks, :final)
2201
+ def test_append_divider_final
2202
+ menu_blocks = []
2203
+ @hd.append_divider(menu_blocks, :final)
1972
2204
 
1973
- assert_equal 1, menu_blocks.size
1974
- assert_equal 'Formatted Divider', menu_blocks.last.dname
1975
- end
2205
+ assert_equal 1, menu_blocks.size
2206
+ assert_equal 'Formatted Divider', menu_blocks.last.dname
2207
+ end
1976
2208
 
1977
- def test_append_divider_without_format
1978
- @hd.instance_variable_set(:@delegate_object, {})
1979
- menu_blocks = []
1980
- @hd.append_divider(menu_blocks, :initial)
2209
+ def test_append_divider_without_format
2210
+ @hd.instance_variable_set(:@delegate_object, {})
2211
+ menu_blocks = []
2212
+ @hd.append_divider(menu_blocks, :initial)
1981
2213
 
1982
- assert_empty menu_blocks
1983
- end
2214
+ assert_empty menu_blocks
1984
2215
  end
2216
+ end
1985
2217
 
1986
- class TestHashDelegatorBlockFind < Minitest::Test
1987
- def setup
1988
- @hd = HashDelegator.new
1989
- end
2218
+ class TestHashDelegatorBlockFind < Minitest::Test
2219
+ def setup
2220
+ @hd = HashDelegator.new
2221
+ end
1990
2222
 
1991
- def test_block_find_with_match
1992
- blocks = [{ key: 'value1' }, { key: 'value2' }]
1993
- result = HashDelegator.block_find(blocks, :key, 'value1')
1994
- assert_equal({ key: 'value1' }, result)
1995
- end
2223
+ def test_block_find_with_match
2224
+ blocks = [{ key: 'value1' }, { key: 'value2' }]
2225
+ result = HashDelegator.block_find(blocks, :key, 'value1')
2226
+ assert_equal({ key: 'value1' }, result)
2227
+ end
1996
2228
 
1997
- def test_block_find_without_match
1998
- blocks = [{ key: 'value1' }, { key: 'value2' }]
1999
- result = HashDelegator.block_find(blocks, :key, 'value3')
2000
- assert_nil result
2001
- end
2229
+ def test_block_find_without_match
2230
+ blocks = [{ key: 'value1' }, { key: 'value2' }]
2231
+ result = HashDelegator.block_find(blocks, :key, 'value3')
2232
+ assert_nil result
2233
+ end
2002
2234
 
2003
- def test_block_find_with_default
2004
- blocks = [{ key: 'value1' }, { key: 'value2' }]
2005
- result = HashDelegator.block_find(blocks, :key, 'value3', 'default')
2006
- assert_equal 'default', result
2007
- end
2235
+ def test_block_find_with_default
2236
+ blocks = [{ key: 'value1' }, { key: 'value2' }]
2237
+ result = HashDelegator.block_find(blocks, :key, 'value3', 'default')
2238
+ assert_equal 'default', result
2008
2239
  end
2240
+ end
2009
2241
 
2010
- class TestHashDelegatorBlocksFromNestedFiles < Minitest::Test
2011
- def setup
2012
- @hd = HashDelegator.new
2013
- @hd.stubs(:iter_blocks_from_nested_files).yields(:blocks, FCB.new)
2014
- @hd.stubs(:get_block_summary).returns(FCB.new)
2015
- @hd.stubs(:create_and_add_chrome_blocks)
2016
- @hd.instance_variable_set(:@delegate_object, {})
2017
- HashDelegator.stubs(:error_handler)
2018
- end
2242
+ class TestHashDelegatorBlocksFromNestedFiles < Minitest::Test
2243
+ def setup
2244
+ @hd = HashDelegator.new
2245
+ @hd.stubs(:iter_blocks_from_nested_files).yields(:blocks, FCB.new)
2246
+ @hd.stubs(:get_block_summary).returns(FCB.new)
2247
+ @hd.stubs(:create_and_add_chrome_blocks)
2248
+ @hd.instance_variable_set(:@delegate_object, {})
2249
+ HashDelegator.stubs(:error_handler)
2250
+ end
2019
2251
 
2020
- def test_blocks_from_nested_files
2021
- result = @hd.blocks_from_nested_files
2252
+ def test_blocks_from_nested_files
2253
+ result = @hd.blocks_from_nested_files
2022
2254
 
2023
- assert_kind_of Array, result
2024
- assert_kind_of FCB, result.first
2025
- end
2255
+ assert_kind_of Array, result
2256
+ assert_kind_of FCB, result.first
2257
+ end
2026
2258
 
2027
- def test_blocks_from_nested_files_with_no_chrome
2028
- @hd.instance_variable_set(:@delegate_object, { no_chrome: true })
2029
- @hd.expects(:create_and_add_chrome_blocks).never
2259
+ def test_blocks_from_nested_files_with_no_chrome
2260
+ @hd.instance_variable_set(:@delegate_object, { no_chrome: true })
2261
+ @hd.expects(:create_and_add_chrome_blocks).never
2030
2262
 
2031
- result = @hd.blocks_from_nested_files
2263
+ result = @hd.blocks_from_nested_files
2032
2264
 
2033
- assert_kind_of Array, result
2034
- end
2265
+ assert_kind_of Array, result
2035
2266
  end
2267
+ end
2036
2268
 
2037
- class TestHashDelegatorCollectRequiredCodeLines < Minitest::Test
2038
- def setup
2039
- @hd = HashDelegator.new
2040
- @hd.instance_variable_set(:@delegate_object, {})
2041
- @mdoc = mock('YourMDocClass')
2042
- @selected = { shell: BlockType::VARS, body: ['key: value'] }
2043
- HashDelegator.stubs(:read_required_blocks_from_temp_file).returns([])
2044
- @hd.stubs(:string_send_color)
2045
- @hd.stubs(:print)
2046
- end
2269
+ class TestHashDelegatorCollectRequiredCodeLines < Minitest::Test
2270
+ def setup
2271
+ @hd = HashDelegator.new
2272
+ @hd.instance_variable_set(:@delegate_object, {})
2273
+ @mdoc = mock('YourMDocClass')
2274
+ @selected = { shell: BlockType::VARS, body: ['key: value'] }
2275
+ HashDelegator.stubs(:read_required_blocks_from_temp_file).returns([])
2276
+ @hd.stubs(:string_send_color)
2277
+ @hd.stubs(:print)
2278
+ end
2047
2279
 
2048
- def test_collect_required_code_lines_with_vars
2049
- YAML.stubs(:load).returns({ 'key' => 'value' })
2050
- @mdoc.stubs(:collect_recursively_required_code).returns({ code: ['code line'] })
2051
- result = @hd.collect_required_code_lines(@mdoc, @selected, block_source: {})
2280
+ def test_collect_required_code_lines_with_vars
2281
+ YAML.stubs(:load).returns({ 'key' => 'value' })
2282
+ @mdoc.stubs(:collect_recursively_required_code).returns({ code: ['code line'] })
2283
+ result = @hd.collect_required_code_lines(@mdoc, @selected, block_source: {})
2052
2284
 
2053
- assert_equal ['code line'], result
2054
- end
2285
+ assert_equal ['code line'], result
2055
2286
  end
2287
+ end
2056
2288
 
2057
- class TestHashDelegatorCommandOrUserSelectedBlock < Minitest::Test
2058
- def setup
2059
- @hd = HashDelegator.new
2060
- @hd.instance_variable_set(:@delegate_object, {})
2061
- HashDelegator.stubs(:error_handler)
2062
- @hd.stubs(:wait_for_user_selected_block)
2063
- end
2289
+ class TestHashDelegatorCommandOrUserSelectedBlock < Minitest::Test
2290
+ def setup
2291
+ @hd = HashDelegator.new
2292
+ @hd.instance_variable_set(:@delegate_object, {})
2293
+ HashDelegator.stubs(:error_handler)
2294
+ @hd.stubs(:wait_for_user_selected_block)
2295
+ end
2064
2296
 
2065
- def test_command_selected_block
2066
- all_blocks = [{ oname: 'block1' }, { oname: 'block2' }]
2067
- @hd.instance_variable_set(:@delegate_object,
2068
- { block_name: 'block1' })
2297
+ def test_command_selected_block
2298
+ all_blocks = [{ oname: 'block1' }, { oname: 'block2' }]
2299
+ @hd.instance_variable_set(:@delegate_object,
2300
+ { block_name: 'block1' })
2069
2301
 
2070
- result = @hd.load_cli_or_user_selected_block(all_blocks, [], nil)
2302
+ result = @hd.load_cli_or_user_selected_block(all_blocks, [], nil)
2071
2303
 
2072
- assert_equal all_blocks.first.merge(block_name_from_ui: false), result.block
2073
- assert_nil result.state
2074
- end
2304
+ assert_equal all_blocks.first.merge(block_name_from_ui: false), result.block
2305
+ assert_nil result.state
2306
+ end
2075
2307
 
2076
- def test_user_selected_block
2077
- block_state = SelectedBlockMenuState.new({ oname: 'block2' },
2078
- :some_state)
2079
- @hd.stubs(:wait_for_user_selected_block).returns(block_state)
2308
+ def test_user_selected_block
2309
+ block_state = SelectedBlockMenuState.new({ oname: 'block2' },
2310
+ :some_state)
2311
+ @hd.stubs(:wait_for_user_selected_block).returns(block_state)
2080
2312
 
2081
- result = @hd.load_cli_or_user_selected_block([], [], nil)
2313
+ result = @hd.load_cli_or_user_selected_block([], [], nil)
2082
2314
 
2083
- assert_equal block_state.block.merge(block_name_from_ui: true), result.block
2084
- assert_equal :some_state, result.state
2085
- end
2315
+ assert_equal block_state.block.merge(block_name_from_ui: true), result.block
2316
+ assert_equal :some_state, result.state
2086
2317
  end
2318
+ end
2087
2319
 
2088
- class TestHashDelegatorCountBlockInFilename < Minitest::Test
2089
- def setup
2090
- @hd = HashDelegator.new
2091
- @hd.instance_variable_set(:@delegate_object,
2092
- { fenced_start_and_end_regex: '^```',
2093
- filename: '/path/to/file' })
2094
- @hd.stubs(:cfile).returns(mock('cfile'))
2095
- end
2320
+ class TestHashDelegatorCountBlockInFilename < Minitest::Test
2321
+ def setup
2322
+ @hd = HashDelegator.new
2323
+ @hd.instance_variable_set(:@delegate_object,
2324
+ { fenced_start_and_end_regex: '^```',
2325
+ filename: '/path/to/file' })
2326
+ @hd.stubs(:cfile).returns(mock('cfile'))
2327
+ end
2096
2328
 
2097
- def test_count_blocks_in_filename
2098
- file_content = ["```ruby\n", "puts 'Hello'\n", "```\n",
2099
- "```python\n", "print('Hello')\n", "```\n"]
2100
- @hd.cfile.stubs(:readlines).with('/path/to/file').returns(file_content)
2329
+ def test_count_blocks_in_filename
2330
+ file_content = ["```ruby\n", "puts 'Hello'\n", "```\n",
2331
+ "```python\n", "print('Hello')\n", "```\n"]
2332
+ @hd.cfile.stubs(:readlines).with('/path/to/file',
2333
+ import_paths: nil).returns(file_content)
2101
2334
 
2102
- count = @hd.count_blocks_in_filename
2335
+ count = @hd.count_blocks_in_filename
2103
2336
 
2104
- assert_equal 2, count
2105
- end
2337
+ assert_equal 2, count
2338
+ end
2106
2339
 
2107
- def test_count_blocks_in_filename_with_no_matches
2108
- file_content = ["puts 'Hello'\n", "print('Hello')\n"]
2109
- @hd.cfile.stubs(:readlines).with('/path/to/file').returns(file_content)
2340
+ def test_count_blocks_in_filename_with_no_matches
2341
+ file_content = ["puts 'Hello'\n", "print('Hello')\n"]
2342
+ @hd.cfile.stubs(:readlines).with('/path/to/file',
2343
+ import_paths: nil).returns(file_content)
2110
2344
 
2111
- count = @hd.count_blocks_in_filename
2345
+ count = @hd.count_blocks_in_filename
2112
2346
 
2113
- assert_equal 0, count
2114
- end
2347
+ assert_equal 0, count
2115
2348
  end
2349
+ end
2116
2350
 
2117
- class TestHashDelegatorCreateAndWriteFile < Minitest::Test
2118
- def setup
2119
- @hd = HashDelegator.new
2120
- HashDelegator.stubs(:error_handler)
2121
- FileUtils.stubs(:mkdir_p)
2122
- File.stubs(:write)
2123
- File.stubs(:chmod)
2124
- end
2351
+ class TestHashDelegatorCreateAndWriteFile < Minitest::Test
2352
+ def setup
2353
+ @hd = HashDelegator.new
2354
+ HashDelegator.stubs(:error_handler)
2355
+ FileUtils.stubs(:mkdir_p)
2356
+ File.stubs(:write)
2357
+ File.stubs(:chmod)
2358
+ end
2125
2359
 
2126
- def test_create_file_and_write_string_with_permissions
2127
- file_path = '/path/to/file'
2128
- content = 'sample content'
2129
- chmod_value = 0o644
2360
+ def test_create_file_and_write_string_with_permissions
2361
+ file_path = '/path/to/file'
2362
+ content = 'sample content'
2363
+ chmod_value = 0o644
2130
2364
 
2131
- FileUtils.expects(:mkdir_p).with('/path/to').once
2132
- File.expects(:write).with(file_path, content).once
2133
- File.expects(:chmod).with(chmod_value, file_path).once
2365
+ FileUtils.expects(:mkdir_p).with('/path/to').once
2366
+ File.expects(:write).with(file_path, content).once
2367
+ File.expects(:chmod).with(chmod_value, file_path).once
2134
2368
 
2135
- HashDelegator.create_file_and_write_string_with_permissions(file_path, content,
2136
- chmod_value)
2369
+ HashDelegator.create_file_and_write_string_with_permissions(file_path, content,
2370
+ chmod_value)
2137
2371
 
2138
- assert true # Placeholder for actual test assertions
2139
- end
2372
+ assert true # Placeholder for actual test assertions
2373
+ end
2140
2374
 
2141
- def test_create_and_write_file_without_chmod
2142
- file_path = '/path/to/file'
2143
- content = 'sample content'
2144
- chmod_value = 0
2375
+ def test_create_and_write_file_without_chmod
2376
+ file_path = '/path/to/file'
2377
+ content = 'sample content'
2378
+ chmod_value = 0
2145
2379
 
2146
- FileUtils.expects(:mkdir_p).with('/path/to').once
2147
- File.expects(:write).with(file_path, content).once
2148
- File.expects(:chmod).never
2380
+ FileUtils.expects(:mkdir_p).with('/path/to').once
2381
+ File.expects(:write).with(file_path, content).once
2382
+ File.expects(:chmod).never
2149
2383
 
2150
- HashDelegator.create_file_and_write_string_with_permissions(file_path, content,
2151
- chmod_value)
2384
+ HashDelegator.create_file_and_write_string_with_permissions(file_path, content,
2385
+ chmod_value)
2152
2386
 
2153
- assert true # Placeholder for actual test assertions
2154
- end
2387
+ assert true # Placeholder for actual test assertions
2155
2388
  end
2389
+ end
2156
2390
 
2157
- class TestHashDelegatorDetermineBlockState < Minitest::Test
2158
- def setup
2159
- @hd = HashDelegator.new
2160
- @hd.stubs(:menu_chrome_formatted_option).returns('Formatted Option')
2161
- end
2162
-
2163
- def test_determine_block_state_exit
2164
- selected_option = { oname: 'Formatted Option' }
2165
- @hd.stubs(:menu_chrome_formatted_option).with(:menu_option_exit_name).returns('Formatted Option')
2166
-
2167
- result = @hd.determine_block_state(selected_option)
2168
-
2169
- assert_equal MenuState::EXIT, result.state
2170
- assert_nil result.block
2171
- end
2391
+ class TestHashDelegatorDetermineBlockState < Minitest::Test
2392
+ def setup
2393
+ @hd = HashDelegator.new
2394
+ @hd.stubs(:menu_chrome_formatted_option).returns('Formatted Option')
2395
+ end
2172
2396
 
2173
- def test_determine_block_state_back
2174
- selected_option = { oname: 'Formatted Back Option' }
2175
- @hd.stubs(:menu_chrome_formatted_option).with(:menu_option_back_name).returns('Formatted Back Option')
2176
- result = @hd.determine_block_state(selected_option)
2397
+ def test_determine_block_state_exit
2398
+ selected_option = { oname: 'Formatted Option' }
2399
+ @hd.stubs(:menu_chrome_formatted_option).with(:menu_option_exit_name).returns('Formatted Option')
2177
2400
 
2178
- assert_equal MenuState::BACK, result.state
2179
- assert_equal selected_option, result.block
2180
- end
2401
+ result = @hd.determine_block_state(selected_option)
2181
2402
 
2182
- def test_determine_block_state_continue
2183
- selected_option = { oname: 'Other Option' }
2403
+ assert_equal MenuState::EXIT, result.state
2404
+ assert_nil result.block
2405
+ end
2184
2406
 
2185
- result = @hd.determine_block_state(selected_option)
2407
+ def test_determine_block_state_back
2408
+ selected_option = { oname: 'Formatted Back Option' }
2409
+ @hd.stubs(:menu_chrome_formatted_option).with(:menu_option_back_name).returns('Formatted Back Option')
2410
+ result = @hd.determine_block_state(selected_option)
2186
2411
 
2187
- assert_equal MenuState::CONTINUE, result.state
2188
- assert_equal selected_option, result.block
2189
- end
2412
+ assert_equal MenuState::BACK, result.state
2413
+ assert_equal selected_option, result.block
2190
2414
  end
2191
2415
 
2192
- class TestHashDelegatorDisplayRequiredCode < Minitest::Test
2193
- def setup
2194
- @hd = HashDelegator.new
2195
- @hd.instance_variable_set(:@fout, mock('fout'))
2196
- @hd.instance_variable_set(:@delegate_object, {})
2197
- @hd.stubs(:string_send_color)
2198
- end
2416
+ def test_determine_block_state_continue
2417
+ selected_option = { oname: 'Other Option' }
2199
2418
 
2200
- def test_display_required_code
2201
- required_lines = %w[line1 line2]
2202
- @hd.instance_variable_get(:@delegate_object).stubs(:[]).with(:script_preview_head).returns('Header')
2203
- @hd.instance_variable_get(:@delegate_object).stubs(:[]).with(:script_preview_tail).returns('Footer')
2204
- @hd.instance_variable_get(:@fout).expects(:fout).times(4)
2419
+ result = @hd.determine_block_state(selected_option)
2205
2420
 
2206
- @hd.display_required_code(required_lines)
2421
+ assert_equal MenuState::CONTINUE, result.state
2422
+ assert_equal selected_option, result.block
2423
+ end
2424
+ end
2207
2425
 
2208
- # Verifying that fout is called for each line and for header & footer
2209
- assert true # Placeholder for actual test assertions
2210
- end
2426
+ class TestHashDelegatorDisplayRequiredCode < Minitest::Test
2427
+ def setup
2428
+ @hd = HashDelegator.new
2429
+ @hd.instance_variable_set(:@fout, mock('fout'))
2430
+ @hd.instance_variable_set(:@delegate_object, {})
2431
+ @hd.stubs(:string_send_color)
2211
2432
  end
2212
2433
 
2213
- class TestHashDelegatorFetchColor < Minitest::Test
2214
- def setup
2215
- @hd = HashDelegator.new
2216
- @hd.instance_variable_set(:@delegate_object, {})
2217
- end
2434
+ def test_display_required_code
2435
+ required_lines = %w[line1 line2]
2436
+ @hd.instance_variable_get(:@delegate_object).stubs(:[]).with(:script_preview_head).returns('Header')
2437
+ @hd.instance_variable_get(:@delegate_object).stubs(:[]).with(:script_preview_tail).returns('Footer')
2438
+ @hd.instance_variable_get(:@fout).expects(:fout).times(4)
2218
2439
 
2219
- def test_fetch_color_with_valid_data
2220
- @hd.instance_variable_get(:@delegate_object).stubs(:fetch).with(
2221
- :execution_report_preview_head, ''
2222
- ).returns('Data String')
2223
- @hd.stubs(:string_send_color).with('Data String',
2224
- :execution_report_preview_frame_color).returns('Colored Data String')
2440
+ @hd.display_required_code(required_lines)
2225
2441
 
2226
- result = @hd.fetch_color
2442
+ # Verifying that fout is called for each line and for header & footer
2443
+ assert true # Placeholder for actual test assertions
2444
+ end
2445
+ end
2227
2446
 
2228
- assert_equal 'Colored Data String', result
2229
- end
2447
+ class TestHashDelegatorFetchColor < Minitest::Test
2448
+ def setup
2449
+ @hd = HashDelegator.new
2450
+ @hd.instance_variable_set(:@delegate_object, {})
2451
+ end
2230
2452
 
2231
- def test_fetch_color_with_missing_data
2232
- @hd.instance_variable_get(:@delegate_object).stubs(:fetch).with(
2233
- :execution_report_preview_head, ''
2234
- ).returns('')
2235
- @hd.stubs(:string_send_color).with('',
2236
- :execution_report_preview_frame_color).returns('Default Colored String')
2453
+ def test_fetch_color_with_valid_data
2454
+ @hd.instance_variable_get(:@delegate_object).stubs(:fetch).with(
2455
+ :execution_report_preview_head, ''
2456
+ ).returns('Data String')
2457
+ @hd.stubs(:string_send_color).with('Data String',
2458
+ :execution_report_preview_frame_color).returns('Colored Data String')
2237
2459
 
2238
- result = @hd.fetch_color
2460
+ result = @hd.fetch_color
2239
2461
 
2240
- assert_equal 'Default Colored String', result
2241
- end
2462
+ assert_equal 'Colored Data String', result
2242
2463
  end
2243
2464
 
2244
- class TestHashDelegatorFormatReferencesSendColor < Minitest::Test
2245
- def setup
2246
- @hd = HashDelegator.new
2247
- @hd.instance_variable_set(:@delegate_object, {})
2248
- end
2465
+ def test_fetch_color_with_missing_data
2466
+ @hd.instance_variable_get(:@delegate_object).stubs(:fetch).with(
2467
+ :execution_report_preview_head, ''
2468
+ ).returns('')
2469
+ @hd.stubs(:string_send_color).with('',
2470
+ :execution_report_preview_frame_color).returns('Default Colored String')
2249
2471
 
2250
- def test_format_references_send_color_with_valid_data
2251
- @hd.instance_variable_get(:@delegate_object).stubs(:fetch).with(
2252
- :output_execution_label_format, ''
2253
- ).returns('Formatted: %{key}')
2254
- @hd.stubs(:string_send_color).returns('Colored String')
2472
+ result = @hd.fetch_color
2255
2473
 
2256
- result = @hd.format_references_send_color(context: { key: 'value' },
2257
- color_sym: :execution_report_preview_frame_color)
2474
+ assert_equal 'Default Colored String', result
2475
+ end
2476
+ end
2258
2477
 
2259
- assert_equal 'Colored String', result
2260
- end
2478
+ class TestHashDelegatorFormatReferencesSendColor < Minitest::Test
2479
+ def setup
2480
+ @hd = HashDelegator.new
2481
+ @hd.instance_variable_set(:@delegate_object, {})
2482
+ end
2261
2483
 
2262
- def test_format_references_send_color_with_missing_format
2263
- @hd.instance_variable_get(:@delegate_object).stubs(:fetch).with(
2264
- :output_execution_label_format, ''
2265
- ).returns('')
2266
- @hd.stubs(:string_send_color).returns('Default Colored String')
2484
+ def test_format_references_send_color_with_valid_data
2485
+ @hd.instance_variable_get(:@delegate_object).stubs(:fetch).with(
2486
+ :output_execution_label_format, ''
2487
+ ).returns('Formatted: %{key}')
2488
+ @hd.stubs(:string_send_color).returns('Colored String')
2267
2489
 
2268
- result = @hd.format_references_send_color(context: { key: 'value' },
2269
- color_sym: :execution_report_preview_frame_color)
2490
+ result = @hd.format_references_send_color(context: { key: 'value' },
2491
+ color_sym: :execution_report_preview_frame_color)
2270
2492
 
2271
- assert_equal 'Default Colored String', result
2272
- end
2493
+ assert_equal 'Colored String', result
2273
2494
  end
2274
2495
 
2275
- class TestHashDelegatorFormatExecutionStreams < Minitest::Test
2276
- def setup
2277
- @hd = HashDelegator.new
2278
- @hd.instance_variable_set(:@run_state, mock('run_state'))
2279
- end
2496
+ def test_format_references_send_color_with_missing_format
2497
+ @hd.instance_variable_get(:@delegate_object).stubs(:fetch).with(
2498
+ :output_execution_label_format, ''
2499
+ ).returns('')
2500
+ @hd.stubs(:string_send_color).returns('Default Colored String')
2280
2501
 
2281
- def test_format_execution_streams_with_valid_key
2282
- result = HashDelegator.format_execution_streams(:stdout,
2283
- { stdout: %w[output1 output2] })
2502
+ result = @hd.format_references_send_color(context: { key: 'value' },
2503
+ color_sym: :execution_report_preview_frame_color)
2284
2504
 
2285
- assert_equal 'output1output2', result
2286
- end
2505
+ assert_equal 'Default Colored String', result
2506
+ end
2507
+ end
2287
2508
 
2288
- def test_format_execution_streams_with_empty_key
2289
- @hd.instance_variable_get(:@run_state).stubs(:files).returns({})
2509
+ class TestHashDelegatorFormatExecutionStreams < Minitest::Test
2510
+ def setup
2511
+ @hd = HashDelegator.new
2512
+ @hd.instance_variable_set(:@run_state, mock('run_state'))
2513
+ end
2290
2514
 
2291
- result = HashDelegator.format_execution_streams(:stderr)
2515
+ def test_format_execution_streams_with_valid_key
2516
+ result = HashDelegator.format_execution_streams(:stdout,
2517
+ { stdout: %w[output1 output2] })
2292
2518
 
2293
- assert_equal '', result
2294
- end
2519
+ assert_equal 'output1output2', result
2520
+ end
2295
2521
 
2296
- def test_format_execution_streams_with_nil_files
2297
- @hd.instance_variable_get(:@run_state).stubs(:files).returns(nil)
2522
+ def test_format_execution_streams_with_empty_key
2523
+ @hd.instance_variable_get(:@run_state).stubs(:files).returns({})
2298
2524
 
2299
- result = HashDelegator.format_execution_streams(:stdin)
2525
+ result = HashDelegator.format_execution_streams(:stderr)
2300
2526
 
2301
- assert_equal '', result
2302
- end
2527
+ assert_equal '', result
2303
2528
  end
2304
2529
 
2305
- class TestHashDelegatorHandleBackLink < Minitest::Test
2306
- def setup
2307
- @hd = HashDelegator.new
2308
- @hd.stubs(:history_state_pop)
2309
- end
2530
+ def test_format_execution_streams_with_nil_files
2531
+ @hd.instance_variable_get(:@run_state).stubs(:files).returns(nil)
2310
2532
 
2311
- def test_pop_link_history_and_trigger_load
2312
- # Verifying that history_state_pop is called
2313
- # @hd.expects(:history_state_pop).once
2533
+ result = HashDelegator.format_execution_streams(:stdin)
2314
2534
 
2315
- result = @hd.pop_link_history_and_trigger_load
2535
+ assert_equal '', result
2536
+ end
2537
+ end
2316
2538
 
2317
- # Asserting the result is an instance of LoadFileLinkState
2318
- assert_instance_of LoadFileLinkState, result
2319
- assert_equal LoadFile::Load, result.load_file
2320
- assert_nil result.link_state.block_name
2321
- end
2539
+ class TestHashDelegatorHandleBackLink < Minitest::Test
2540
+ def setup
2541
+ @hd = HashDelegator.new
2542
+ @hd.stubs(:history_state_pop)
2322
2543
  end
2323
2544
 
2324
- class TestHashDelegatorHandleBlockState < Minitest::Test
2325
- def setup
2326
- @hd = HashDelegator.new
2327
- @mock_block_state = mock('block_state')
2328
- end
2545
+ def test_pop_link_history_and_trigger_load
2546
+ # Verifying that history_state_pop is called
2547
+ # @hd.expects(:history_state_pop).once
2329
2548
 
2330
- def test_handle_back_or_continue_with_back
2331
- @mock_block_state.stubs(:state).returns(MenuState::BACK)
2332
- @mock_block_state.stubs(:block).returns({ oname: 'sample_block' })
2549
+ result = @hd.pop_link_history_and_trigger_load
2333
2550
 
2334
- @hd.handle_back_or_continue(@mock_block_state)
2551
+ # Asserting the result is an instance of LoadFileLinkState
2552
+ assert_instance_of LoadFileLinkState, result
2553
+ assert_equal LoadFile::Load, result.load_file
2554
+ assert_nil result.link_state.block_name
2555
+ end
2556
+ end
2335
2557
 
2336
- assert_equal 'sample_block',
2337
- @hd.instance_variable_get(:@delegate_object)[:block_name]
2338
- assert @hd.instance_variable_get(:@menu_user_clicked_back_link)
2339
- end
2558
+ class TestHashDelegatorHandleBlockState < Minitest::Test
2559
+ def setup
2560
+ @hd = HashDelegator.new
2561
+ @mock_block_state = mock('block_state')
2562
+ end
2340
2563
 
2341
- def test_handle_back_or_continue_with_continue
2342
- @mock_block_state.stubs(:state).returns(MenuState::CONTINUE)
2343
- @mock_block_state.stubs(:block).returns({ oname: 'another_block' })
2564
+ def test_handle_back_or_continue_with_back
2565
+ @mock_block_state.stubs(:state).returns(MenuState::BACK)
2566
+ @mock_block_state.stubs(:block).returns({ oname: 'sample_block' })
2344
2567
 
2345
- @hd.handle_back_or_continue(@mock_block_state)
2568
+ @hd.handle_back_or_continue(@mock_block_state)
2346
2569
 
2347
- assert_equal 'another_block',
2348
- @hd.instance_variable_get(:@delegate_object)[:block_name]
2349
- refute @hd.instance_variable_get(:@menu_user_clicked_back_link)
2350
- end
2570
+ assert_equal 'sample_block',
2571
+ @hd.instance_variable_get(:@delegate_object)[:block_name]
2572
+ assert @hd.instance_variable_get(:@menu_user_clicked_back_link)
2573
+ end
2351
2574
 
2352
- def test_handle_back_or_continue_with_other
2353
- @mock_block_state.stubs(:state).returns(nil) # MenuState::OTHER
2354
- @mock_block_state.stubs(:block).returns({ oname: 'other_block' })
2575
+ def test_handle_back_or_continue_with_continue
2576
+ @mock_block_state.stubs(:state).returns(MenuState::CONTINUE)
2577
+ @mock_block_state.stubs(:block).returns({ oname: 'another_block' })
2355
2578
 
2356
- @hd.handle_back_or_continue(@mock_block_state)
2579
+ @hd.handle_back_or_continue(@mock_block_state)
2357
2580
 
2358
- assert_nil @hd.instance_variable_get(:@delegate_object)[:block_name]
2359
- assert_nil @hd.instance_variable_get(:@menu_user_clicked_back_link)
2360
- end
2581
+ assert_equal 'another_block',
2582
+ @hd.instance_variable_get(:@delegate_object)[:block_name]
2583
+ refute @hd.instance_variable_get(:@menu_user_clicked_back_link)
2361
2584
  end
2362
2585
 
2363
- class TestHashDelegatorHandleGenericBlock < Minitest::Test
2364
- def setup
2365
- @hd = HashDelegator.new
2366
- @mock_document = mock('MarkdownDocument')
2367
- @selected_item = mock('FCB')
2368
- end
2369
-
2370
- def test_compile_execute_and_trigger_reuse_without_user_approval
2371
- # Mock the delegate object configuration
2372
- @hd.instance_variable_set(:@delegate_object,
2373
- { output_script: false,
2374
- user_must_approve: false })
2586
+ def test_handle_back_or_continue_with_other
2587
+ @mock_block_state.stubs(:state).returns(nil) # MenuState::OTHER
2588
+ @mock_block_state.stubs(:block).returns({ oname: 'other_block' })
2375
2589
 
2376
- # Test the method without user approval
2377
- # Expectations and assertions go here
2378
- end
2590
+ @hd.handle_back_or_continue(@mock_block_state)
2379
2591
 
2380
- def test_compile_execute_and_trigger_reuse_with_user_approval
2381
- # Mock the delegate object configuration
2382
- @hd.instance_variable_set(:@delegate_object,
2383
- { output_script: false,
2384
- user_must_approve: true })
2592
+ assert_nil @hd.instance_variable_get(:@delegate_object)[:block_name]
2593
+ assert_nil @hd.instance_variable_get(:@menu_user_clicked_back_link)
2594
+ end
2595
+ end
2385
2596
 
2386
- # Test the method with user approval
2387
- # Expectations and assertions go here
2388
- end
2597
+ class TestHashDelegatorHandleGenericBlock < Minitest::Test
2598
+ def setup
2599
+ @hd = HashDelegator.new
2600
+ @mock_document = mock('MarkdownDocument')
2601
+ @selected_item = mock('FCB')
2602
+ end
2389
2603
 
2390
- def test_compile_execute_and_trigger_reuse_with_output_script
2391
- # Mock the delegate object configuration
2392
- @hd.instance_variable_set(:@delegate_object,
2393
- { output_script: true,
2394
- user_must_approve: false })
2604
+ def test_compile_execute_and_trigger_reuse_without_user_approval
2605
+ # Mock the delegate object configuration
2606
+ @hd.instance_variable_set(:@delegate_object,
2607
+ { output_script: false,
2608
+ user_must_approve: false })
2395
2609
 
2396
- # Test the method with output script option
2397
- # Expectations and assertions go here
2398
- end
2610
+ # Test the method without user approval
2611
+ # Expectations and assertions go here
2399
2612
  end
2400
2613
 
2401
- # require 'stringio'
2614
+ def test_compile_execute_and_trigger_reuse_with_user_approval
2615
+ # Mock the delegate object configuration
2616
+ @hd.instance_variable_set(:@delegate_object,
2617
+ { output_script: false,
2618
+ user_must_approve: true })
2402
2619
 
2403
- class TestHashDelegatorHandleStream < Minitest::Test
2404
- def setup
2405
- @hd = HashDelegator.new
2406
- @hd.instance_variable_set(:@run_state,
2407
- OpenStruct.new(files: { stdout: [] }))
2408
- @hd.instance_variable_set(:@delegate_object,
2409
- { output_stdout: true })
2410
- end
2620
+ # Test the method with user approval
2621
+ # Expectations and assertions go here
2622
+ end
2411
2623
 
2412
- def test_handle_stream
2413
- stream = StringIO.new("line 1\nline 2\n")
2414
- file_type = :stdout
2624
+ def test_compile_execute_and_trigger_reuse_with_output_script
2625
+ # Mock the delegate object configuration
2626
+ @hd.instance_variable_set(:@delegate_object,
2627
+ { output_script: true,
2628
+ user_must_approve: false })
2415
2629
 
2416
- Thread.new { @hd.handle_stream(stream, file_type) }
2630
+ # Test the method with output script option
2631
+ # Expectations and assertions go here
2632
+ end
2633
+ end
2417
2634
 
2418
- @hd.wait_for_stream_processing
2635
+ # require 'stringio'
2419
2636
 
2420
- assert_equal ['line 1', 'line 2'],
2421
- @hd.instance_variable_get(:@run_state).files[:stdout]
2422
- end
2637
+ class TestHashDelegatorHandleStream < Minitest::Test
2638
+ def setup
2639
+ @hd = HashDelegator.new
2640
+ @hd.instance_variable_set(:@run_state,
2641
+ OpenStruct.new(files: { stdout: [] }))
2642
+ @hd.instance_variable_set(:@delegate_object,
2643
+ { output_stdout: true })
2644
+ end
2423
2645
 
2424
- def test_handle_stream_with_io_error
2425
- stream = StringIO.new("line 1\nline 2\n")
2426
- file_type = :stdout
2427
- stream.stubs(:each_line).raises(IOError)
2646
+ def test_handle_stream
2647
+ stream = StringIO.new("line 1\nline 2\n")
2648
+ file_type = :stdout
2428
2649
 
2429
- Thread.new { @hd.handle_stream(stream, file_type) }
2650
+ Thread.new { @hd.handle_stream(stream, file_type) }
2430
2651
 
2431
- @hd.wait_for_stream_processing
2652
+ @hd.wait_for_stream_processing
2432
2653
 
2433
- assert_equal [],
2434
- @hd.instance_variable_get(:@run_state).files[:stdout]
2435
- end
2654
+ assert_equal ['line 1', 'line 2'],
2655
+ @hd.instance_variable_get(:@run_state).files[:stdout]
2436
2656
  end
2437
2657
 
2438
- class TestHashDelegatorIterBlocksFromNestedFiles < Minitest::Test
2439
- def setup
2440
- @hd = HashDelegator.new
2441
- @hd.instance_variable_set(:@delegate_object,
2442
- { filename: 'test.md' })
2443
- @hd.stubs(:check_file_existence).with('test.md').returns(true)
2444
- @hd.stubs(:initial_state).returns({})
2445
- @hd.stubs(:cfile).returns(Minitest::Mock.new)
2446
- @hd.stubs(:update_line_and_block_state)
2447
- end
2448
-
2449
- def test_iter_blocks_from_nested_files
2450
- @hd.cfile.expect(:readlines, ['line 1', 'line 2'], ['test.md'])
2451
- selected_messages = ['filtered message']
2658
+ def test_handle_stream_with_io_error
2659
+ stream = StringIO.new("line 1\nline 2\n")
2660
+ file_type = :stdout
2661
+ stream.stubs(:each_line).raises(IOError)
2452
2662
 
2453
- result = @hd.iter_blocks_from_nested_files { selected_messages }
2454
- assert_equal ['line 1', 'line 2'], result
2663
+ Thread.new { @hd.handle_stream(stream, file_type) }
2455
2664
 
2456
- @hd.cfile.verify
2457
- end
2665
+ @hd.wait_for_stream_processing
2458
2666
 
2459
- def test_iter_blocks_from_nested_files_with_no_file
2460
- @hd.stubs(:check_file_existence).with('test.md').returns(false)
2667
+ assert_equal [],
2668
+ @hd.instance_variable_get(:@run_state).files[:stdout]
2669
+ end
2670
+ end
2461
2671
 
2462
- assert_nil(@hd.iter_blocks_from_nested_files do
2463
- ['filtered message']
2464
- end)
2465
- end
2672
+ class TestHashDelegatorIterBlocksFromNestedFiles < Minitest::Test
2673
+ def setup
2674
+ @hd = HashDelegator.new
2675
+ @hd.instance_variable_set(:@delegate_object,
2676
+ { filename: 'test.md' })
2677
+ @hd.stubs(:check_file_existence).with('test.md').returns(true)
2678
+ @hd.stubs(:initial_state).returns({})
2679
+ @hd.stubs(:cfile).returns(Minitest::Mock.new)
2680
+ @hd.stubs(:update_line_and_block_state)
2466
2681
  end
2467
2682
 
2468
- class TestHashDelegatorMenuChromeColoredOption < Minitest::Test
2469
- def setup
2470
- @hd = HashDelegator.new
2471
- @hd.instance_variable_set(:@delegate_object, {
2472
- menu_option_back_name: 'Back',
2473
- menu_chrome_color: :red,
2474
- menu_chrome_format: '-- %s --'
2475
- })
2476
- @hd.stubs(:menu_chrome_formatted_option).with(:menu_option_back_name).returns('-- Back --')
2477
- @hd.stubs(:string_send_color).with('-- Back --',
2478
- :menu_chrome_color).returns('-- Back --'.red)
2479
- end
2683
+ def test_iter_blocks_from_nested_files
2684
+ @hd.cfile.expect(:readlines, ['line 1', 'line 2'], ['test.md'], import_paths: nil)
2685
+ selected_messages = ['filtered message']
2480
2686
 
2481
- def test_menu_chrome_colored_option_with_color
2482
- assert_equal '-- Back --'.red,
2483
- @hd.menu_chrome_colored_option(:menu_option_back_name)
2484
- end
2687
+ result = @hd.iter_blocks_from_nested_files { selected_messages }
2688
+ assert_equal ['line 1', 'line 2'], result
2485
2689
 
2486
- def test_menu_chrome_colored_option_without_color
2487
- @hd.instance_variable_set(:@delegate_object,
2488
- { menu_option_back_name: 'Back' })
2489
- assert_equal '-- Back --',
2490
- @hd.menu_chrome_colored_option(:menu_option_back_name)
2491
- end
2690
+ @hd.cfile.verify
2492
2691
  end
2493
2692
 
2494
- class TestHashDelegatorMenuChromeFormattedOptionWithoutFormat < Minitest::Test
2495
- def setup
2496
- @hd = HashDelegator.new
2497
- @hd.instance_variable_set(:@delegate_object, {
2498
- menu_option_back_name: "'Back'",
2499
- menu_chrome_format: '-- %s --'
2500
- })
2501
- HashDelegator.stubs(:safeval).with("'Back'").returns('Back')
2502
- end
2503
-
2504
- def test_menu_chrome_formatted_option_with_format
2505
- assert_equal '-- Back --',
2506
- @hd.menu_chrome_formatted_option(:menu_option_back_name)
2507
- end
2693
+ def test_iter_blocks_from_nested_files_with_no_file
2694
+ @hd.stubs(:check_file_existence).with('test.md').returns(false)
2508
2695
 
2509
- def test_menu_chrome_formatted_option_without_format
2510
- @hd.instance_variable_set(:@delegate_object,
2511
- { menu_option_back_name: "'Back'" })
2512
- assert_equal 'Back',
2513
- @hd.menu_chrome_formatted_option(:menu_option_back_name)
2514
- end
2696
+ assert_nil(@hd.iter_blocks_from_nested_files do
2697
+ ['filtered message']
2698
+ end)
2515
2699
  end
2700
+ end
2516
2701
 
2517
- class TestHashDelegatorStartFencedBlock < Minitest::Test
2518
- def setup
2519
- @hd = HashDelegator.new({
2520
- block_name_wrapper_match: 'WRAPPER_REGEX',
2521
- block_calls_scan: 'CALLS_REGEX'
2702
+ class TestHashDelegatorMenuChromeColoredOption < Minitest::Test
2703
+ def setup
2704
+ @hd = HashDelegator.new
2705
+ @hd.instance_variable_set(:@delegate_object, {
2706
+ menu_option_back_name: 'Back',
2707
+ menu_chrome_color: :red,
2708
+ menu_chrome_format: '-- %s --'
2522
2709
  })
2523
- end
2524
-
2525
- def test_start_fenced_block
2526
- line = '```fenced'
2527
- headings = ['Heading 1']
2528
- regex = /```(?<name>\w+)(?<rest>.*)/
2529
-
2530
- fcb = @hd.start_fenced_block(line, headings, regex)
2531
-
2532
- assert_instance_of MarkdownExec::FCB, fcb
2533
- assert_equal headings, fcb.headings
2534
- assert_equal 'fenced', fcb.dname
2535
- end
2710
+ @hd.stubs(:menu_chrome_formatted_option).with(:menu_option_back_name).returns('-- Back --')
2711
+ @hd.stubs(:string_send_color).with('-- Back --',
2712
+ :menu_chrome_color).returns('-- Back --'.red)
2536
2713
  end
2537
2714
 
2538
- class TestHashDelegatorStringSendColor < Minitest::Test
2539
- def setup
2540
- @hd = HashDelegator.new
2541
- @hd.instance_variable_set(:@delegate_object,
2542
- { red: 'red', green: 'green' })
2543
- end
2715
+ def test_menu_chrome_colored_option_with_color
2716
+ assert_equal '-- Back --'.red,
2717
+ @hd.menu_chrome_colored_option(:menu_option_back_name)
2718
+ end
2544
2719
 
2545
- def test_string_send_color
2546
- assert_equal 'Hello'.red, @hd.string_send_color('Hello', :red)
2547
- assert_equal 'World'.green,
2548
- @hd.string_send_color('World', :green)
2549
- assert_equal 'Default'.plain,
2550
- @hd.string_send_color('Default', :blue)
2551
- end
2720
+ def test_menu_chrome_colored_option_without_color
2721
+ @hd.instance_variable_set(:@delegate_object,
2722
+ { menu_option_back_name: 'Back' })
2723
+ assert_equal '-- Back --',
2724
+ @hd.menu_chrome_colored_option(:menu_option_back_name)
2552
2725
  end
2726
+ end
2553
2727
 
2554
- def test_yield_line_if_selected_with_line
2555
- block_called = false
2556
- HashDelegator.yield_line_if_selected('Test line', [:line]) do |type, content|
2557
- block_called = true
2558
- assert_equal :line, type
2559
- assert_equal 'Test line', content.body[0]
2560
- end
2561
- assert block_called
2728
+ class TestHashDelegatorMenuChromeFormattedOptionWithoutFormat < Minitest::Test
2729
+ def setup
2730
+ @hd = HashDelegator.new
2731
+ @hd.instance_variable_set(:@delegate_object, {
2732
+ menu_option_back_name: "'Back'",
2733
+ menu_chrome_format: '-- %s --'
2734
+ })
2735
+ HashDelegator.stubs(:safeval).with("'Back'").returns('Back')
2562
2736
  end
2563
2737
 
2564
- def test_yield_line_if_selected_without_line
2565
- block_called = false
2566
- HashDelegator.yield_line_if_selected('Test line', [:other]) do |_|
2567
- block_called = true
2568
- end
2569
- refute block_called
2738
+ def test_menu_chrome_formatted_option_with_format
2739
+ assert_equal '-- Back --',
2740
+ @hd.menu_chrome_formatted_option(:menu_option_back_name)
2570
2741
  end
2571
2742
 
2572
- def test_yield_line_if_selected_without_block
2573
- result = HashDelegator.yield_line_if_selected('Test line', [:line])
2574
- assert_nil result
2743
+ def test_menu_chrome_formatted_option_without_format
2744
+ @hd.instance_variable_set(:@delegate_object,
2745
+ { menu_option_back_name: "'Back'" })
2746
+ assert_equal 'Back',
2747
+ @hd.menu_chrome_formatted_option(:menu_option_back_name)
2575
2748
  end
2576
2749
  end
2577
2750
 
2578
- class TestHashDelegatorUpdateMenuAttribYieldSelectedWithBody < Minitest::Test
2751
+ class TestHashDelegatorStartFencedBlock < Minitest::Test
2579
2752
  def setup
2580
- @hd = HashDelegator.new
2581
- @fcb = mock('Fcb')
2582
- @fcb.stubs(:body).returns(true)
2583
- HashDelegator.stubs(:initialize_fcb_names)
2584
- HashDelegator.stubs(:default_block_title_from_body)
2585
- Filter.stubs(:yield_to_block_if_applicable)
2753
+ @hd = HashDelegator.new({
2754
+ block_name_wrapper_match: 'WRAPPER_REGEX',
2755
+ block_calls_scan: 'CALLS_REGEX'
2756
+ })
2586
2757
  end
2587
2758
 
2588
- def test_update_menu_attrib_yield_selected_with_body
2589
- HashDelegator.expects(:initialize_fcb_names).with(@fcb)
2590
- HashDelegator.expects(:default_block_title_from_body).with(@fcb)
2591
- Filter.expects(:yield_to_block_if_applicable).with(@fcb, [:some_message], {})
2759
+ def test_start_fenced_block
2760
+ line = '```fenced'
2761
+ headings = ['Heading 1']
2762
+ regex = /```(?<name>\w+)(?<rest>.*)/
2592
2763
 
2593
- HashDelegator.update_menu_attrib_yield_selected(@fcb, [:some_message])
2594
- end
2764
+ fcb = @hd.start_fenced_block(line, headings, regex)
2595
2765
 
2596
- def test_update_menu_attrib_yield_selected_without_body
2597
- @fcb.stubs(:body).returns(nil)
2598
- HashDelegator.expects(:initialize_fcb_names).with(@fcb)
2599
- HashDelegator.update_menu_attrib_yield_selected(@fcb, [:some_message])
2766
+ assert_instance_of MarkdownExec::FCB, fcb
2767
+ assert_equal headings, fcb.headings
2768
+ assert_equal 'fenced', fcb.dname
2600
2769
  end
2601
2770
  end
2602
2771
 
2603
- class TestHashDelegatorWaitForUserSelectedBlock < Minitest::Test
2772
+ class TestHashDelegatorStringSendColor < Minitest::Test
2604
2773
  def setup
2605
2774
  @hd = HashDelegator.new
2606
- HashDelegator.stubs(:error_handler)
2775
+ @hd.instance_variable_set(:@delegate_object,
2776
+ { red: 'red', green: 'green' })
2607
2777
  end
2608
2778
 
2609
- def test_wait_for_user_selected_block_with_back_state
2610
- mock_block_state = Struct.new(:state, :block).new(MenuState::BACK,
2611
- { oname: 'back_block' })
2612
- @hd.stubs(:wait_for_user_selection).returns(mock_block_state)
2779
+ def test_string_send_color
2780
+ assert_equal 'Hello'.red, @hd.string_send_color('Hello', :red)
2781
+ assert_equal 'World'.green,
2782
+ @hd.string_send_color('World', :green)
2783
+ assert_equal 'Default'.plain,
2784
+ @hd.string_send_color('Default', :blue)
2785
+ end
2786
+ end
2613
2787
 
2614
- result = @hd.wait_for_user_selected_block([], ['Block 1', 'Block 2'],
2615
- nil)
2788
+ def test_yield_line_if_selected_with_line
2789
+ block_called = false
2790
+ HashDelegator.yield_line_if_selected('Test line', [:line]) do |type, content|
2791
+ block_called = true
2792
+ assert_equal :line, type
2793
+ assert_equal 'Test line', content.body[0]
2794
+ end
2795
+ assert block_called
2796
+ end
2616
2797
 
2617
- assert_equal 'back_block',
2618
- @hd.instance_variable_get(:@delegate_object)[:block_name]
2619
- assert @hd.instance_variable_get(:@menu_user_clicked_back_link)
2620
- assert_equal mock_block_state, result
2798
+ def test_yield_line_if_selected_without_line
2799
+ block_called = false
2800
+ HashDelegator.yield_line_if_selected('Test line', [:other]) do |_|
2801
+ block_called = true
2621
2802
  end
2803
+ refute block_called
2804
+ end
2622
2805
 
2623
- def test_wait_for_user_selected_block_with_continue_state
2624
- mock_block_state = Struct.new(:state, :block).new(
2625
- MenuState::CONTINUE, { oname: 'continue_block' }
2626
- )
2627
- @hd.stubs(:wait_for_user_selection).returns(mock_block_state)
2806
+ def test_yield_line_if_selected_without_block
2807
+ result = HashDelegator.yield_line_if_selected('Test line', [:line])
2808
+ assert_nil result
2809
+ end
2810
+ end
2628
2811
 
2629
- result = @hd.wait_for_user_selected_block([], ['Block 1', 'Block 2'],
2630
- nil)
2812
+ class TestHashDelegatorUpdateMenuAttribYieldSelectedWithBody < Minitest::Test
2813
+ def setup
2814
+ @hd = HashDelegator.new
2815
+ @fcb = mock('Fcb')
2816
+ @fcb.stubs(:body).returns(true)
2817
+ HashDelegator.stubs(:initialize_fcb_names)
2818
+ HashDelegator.stubs(:default_block_title_from_body)
2819
+ Filter.stubs(:yield_to_block_if_applicable)
2820
+ end
2631
2821
 
2632
- assert_equal 'continue_block',
2633
- @hd.instance_variable_get(:@delegate_object)[:block_name]
2634
- refute @hd.instance_variable_get(:@menu_user_clicked_back_link)
2635
- assert_equal mock_block_state, result
2636
- end
2822
+ def test_update_menu_attrib_yield_selected_with_body
2823
+ HashDelegator.expects(:initialize_fcb_names).with(@fcb)
2824
+ HashDelegator.expects(:default_block_title_from_body).with(@fcb)
2825
+ Filter.expects(:yield_to_block_if_applicable).with(@fcb, [:some_message], {})
2826
+
2827
+ HashDelegator.update_menu_attrib_yield_selected(@fcb, [:some_message])
2637
2828
  end
2638
2829
 
2639
- class TestHashDelegatorYieldToBlock < Minitest::Test
2640
- def setup
2641
- @hd = HashDelegator.new
2642
- @fcb = mock('Fcb')
2643
- MarkdownExec::Filter.stubs(:fcb_select?).returns(true)
2644
- end
2830
+ def test_update_menu_attrib_yield_selected_without_body
2831
+ @fcb.stubs(:body).returns(nil)
2832
+ HashDelegator.expects(:initialize_fcb_names).with(@fcb)
2833
+ HashDelegator.update_menu_attrib_yield_selected(@fcb, [:some_message])
2834
+ end
2835
+ end
2645
2836
 
2646
- def test_yield_to_block_if_applicable_with_correct_conditions
2647
- block_called = false
2648
- Filter.yield_to_block_if_applicable(@fcb, [:blocks]) do |type, fcb|
2649
- block_called = true
2650
- assert_equal :blocks, type
2651
- assert_equal @fcb, fcb
2652
- end
2653
- assert block_called
2654
- end
2837
+ class TestHashDelegatorWaitForUserSelectedBlock < Minitest::Test
2838
+ def setup
2839
+ @hd = HashDelegator.new
2840
+ HashDelegator.stubs(:error_handler)
2841
+ end
2655
2842
 
2656
- def test_yield_to_block_if_applicable_without_block
2657
- result = Filter.yield_to_block_if_applicable(@fcb, [:blocks])
2658
- assert_nil result
2843
+ def test_wait_for_user_selected_block_with_back_state
2844
+ mock_block_state = Struct.new(:state, :block).new(MenuState::BACK,
2845
+ { oname: 'back_block' })
2846
+ @hd.stubs(:wait_for_user_selection).returns(mock_block_state)
2847
+
2848
+ result = @hd.wait_for_user_selected_block([], ['Block 1', 'Block 2'],
2849
+ nil)
2850
+
2851
+ assert_equal 'back_block',
2852
+ @hd.instance_variable_get(:@delegate_object)[:block_name]
2853
+ assert @hd.instance_variable_get(:@menu_user_clicked_back_link)
2854
+ assert_equal mock_block_state, result
2855
+ end
2856
+
2857
+ def test_wait_for_user_selected_block_with_continue_state
2858
+ mock_block_state = Struct.new(:state, :block).new(
2859
+ MenuState::CONTINUE, { oname: 'continue_block' }
2860
+ )
2861
+ @hd.stubs(:wait_for_user_selection).returns(mock_block_state)
2862
+
2863
+ result = @hd.wait_for_user_selected_block([], ['Block 1', 'Block 2'],
2864
+ nil)
2865
+
2866
+ assert_equal 'continue_block',
2867
+ @hd.instance_variable_get(:@delegate_object)[:block_name]
2868
+ refute @hd.instance_variable_get(:@menu_user_clicked_back_link)
2869
+ assert_equal mock_block_state, result
2870
+ end
2871
+ end
2872
+
2873
+ class TestHashDelegatorYieldToBlock < Minitest::Test
2874
+ def setup
2875
+ @hd = HashDelegator.new
2876
+ @fcb = mock('Fcb')
2877
+ MarkdownExec::Filter.stubs(:fcb_select?).returns(true)
2878
+ end
2879
+
2880
+ def test_yield_to_block_if_applicable_with_correct_conditions
2881
+ block_called = false
2882
+ Filter.yield_to_block_if_applicable(@fcb, [:blocks]) do |type, fcb|
2883
+ block_called = true
2884
+ assert_equal :blocks, type
2885
+ assert_equal @fcb, fcb
2659
2886
  end
2887
+ assert block_called
2888
+ end
2660
2889
 
2661
- def test_yield_to_block_if_applicable_with_incorrect_conditions
2662
- block_called = false
2663
- MarkdownExec::Filter.stubs(:fcb_select?).returns(false)
2664
- Filter.yield_to_block_if_applicable(@fcb, [:non_blocks]) do |_|
2665
- block_called = true
2666
- end
2667
- refute block_called
2890
+ def test_yield_to_block_if_applicable_without_block
2891
+ result = Filter.yield_to_block_if_applicable(@fcb, [:blocks])
2892
+ assert_nil result
2893
+ end
2894
+
2895
+ def test_yield_to_block_if_applicable_with_incorrect_conditions
2896
+ block_called = false
2897
+ MarkdownExec::Filter.stubs(:fcb_select?).returns(false)
2898
+ Filter.yield_to_block_if_applicable(@fcb, [:non_blocks]) do |_|
2899
+ block_called = true
2668
2900
  end
2901
+ refute block_called
2669
2902
  end
2670
- end # module MarkdownExec
2671
- end
2903
+ end
2904
+ end # module MarkdownExec