markdown_exec 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +11 -2
  3. data/CHANGELOG.md +19 -0
  4. data/Gemfile.lock +1 -1
  5. data/Rakefile +32 -8
  6. data/bats/bats.bats +33 -0
  7. data/bats/block-types.bats +56 -0
  8. data/bats/cli.bats +74 -0
  9. data/bats/fail.bats +11 -0
  10. data/bats/history.bats +34 -0
  11. data/bats/markup.bats +66 -0
  12. data/bats/mde.bats +29 -0
  13. data/bats/options.bats +92 -0
  14. data/bats/test_helper.bash +152 -0
  15. data/bin/tab_completion.sh +44 -20
  16. data/docs/dev/block-type-opts.md +10 -0
  17. data/docs/dev/block-type-port.md +24 -0
  18. data/docs/dev/block-type-vars.md +7 -0
  19. data/docs/dev/pass-through-arguments.md +8 -0
  20. data/docs/dev/specs-import.md +9 -0
  21. data/docs/dev/specs.md +83 -0
  22. data/docs/dev/text-decoration.md +7 -0
  23. data/examples/bash-blocks.md +4 -4
  24. data/examples/block-names.md +2 -2
  25. data/examples/import0.md +23 -0
  26. data/examples/import1.md +13 -0
  27. data/examples/link-blocks-vars.md +3 -3
  28. data/examples/opts-blocks-require.md +6 -6
  29. data/examples/table-markup.md +31 -0
  30. data/examples/text-markup.md +58 -0
  31. data/examples/vars-blocks.md +2 -2
  32. data/examples/wrap.md +87 -9
  33. data/lib/ansi_formatter.rb +12 -6
  34. data/lib/ansi_string.rb +153 -0
  35. data/lib/argument_processor.rb +160 -0
  36. data/lib/cached_nested_file_reader.rb +4 -2
  37. data/lib/ce_get_cost_and_usage.rb +4 -3
  38. data/lib/cli.rb +1 -1
  39. data/lib/colorize.rb +39 -11
  40. data/lib/constants.rb +17 -0
  41. data/lib/directory_searcher.rb +4 -2
  42. data/lib/doh.rb +190 -0
  43. data/lib/env.rb +1 -1
  44. data/lib/exceptions.rb +9 -6
  45. data/lib/fcb.rb +0 -199
  46. data/lib/filter.rb +18 -5
  47. data/lib/find_files.rb +8 -3
  48. data/lib/format_table.rb +406 -0
  49. data/lib/hash_delegator.rb +888 -603
  50. data/lib/hierarchy_string.rb +113 -25
  51. data/lib/input_sequencer.rb +16 -10
  52. data/lib/instance_method_wrapper.rb +2 -1
  53. data/lib/layered_hash.rb +143 -0
  54. data/lib/link_history.rb +22 -8
  55. data/lib/markdown_exec/version.rb +1 -1
  56. data/lib/markdown_exec.rb +413 -165
  57. data/lib/mdoc.rb +27 -34
  58. data/lib/menu.src.yml +825 -710
  59. data/lib/menu.yml +799 -703
  60. data/lib/namer.rb +6 -12
  61. data/lib/object_present.rb +1 -1
  62. data/lib/option_value.rb +7 -3
  63. data/lib/poly.rb +33 -14
  64. data/lib/resize_terminal.rb +60 -52
  65. data/lib/saved_assets.rb +45 -34
  66. data/lib/saved_files_matcher.rb +6 -3
  67. data/lib/streams_out.rb +7 -1
  68. data/lib/table_extractor.rb +166 -0
  69. data/lib/tap.rb +5 -6
  70. data/lib/text_analyzer.rb +144 -8
  71. metadata +26 -3
  72. data/lib/std_out_err_logger.rb +0 -119
data/lib/namer.rb CHANGED
@@ -3,7 +3,6 @@
3
3
 
4
4
  # encoding=utf-8
5
5
  require 'digest'
6
- # require_relative 'poly'
7
6
 
8
7
  $pd = false unless defined?($pd)
9
8
 
@@ -11,7 +10,9 @@ class Hash
11
10
  # block name in commands and documents
12
11
  def pub_name(**kwargs)
13
12
  full = fetch(:nickname, nil) || fetch(:oname, nil)
14
- full&.to_s&.pub_name(**kwargs).tap { |ret| pp [__LINE__, 'Hash.pub_name() ->', ret] if $pd }
13
+ full&.to_s&.pub_name(**kwargs).tap { |ret|
14
+ pp [__LINE__, 'Hash.pub_name() ->', ret] if $pd
15
+ }
15
16
  end
16
17
  end
17
18
 
@@ -36,15 +37,8 @@ class String
36
37
  self
37
38
  end
38
39
 
39
- trimmed.gsub(pattern, replacement).tap { |ret| pp [__LINE__, 'String.pub_name() ->', ret] if $pd }
40
+ trimmed.gsub(pattern, replacement).tap { |ret|
41
+ pp [__LINE__, 'String.pub_name() ->', ret] if $pd
42
+ }
40
43
  end
41
44
  end
42
-
43
- # require 'ostruct'
44
-
45
- # class BlkS < OpenStruct
46
- # # Method to fetch the value associated with the attribute :nickname or :oname
47
- # def pub_name
48
- # self.nickname || self.oname
49
- # end
50
- # end
@@ -43,7 +43,7 @@ class Object
43
43
  when 'FalseClass', 'TrueClass'
44
44
  true
45
45
  else
46
- self && (!respond_to?(:present?) || !present?)
46
+ self && (!respond_to?(:empty?) || !empty?)
47
47
  end
48
48
  end
49
49
  end
data/lib/option_value.rb CHANGED
@@ -16,7 +16,7 @@ module MarkdownExec
16
16
  return default if value.nil?
17
17
 
18
18
  case value
19
- when String, Integer
19
+ when String, Integer, Array, Hash
20
20
  value
21
21
  when TrueClass, FalseClass
22
22
  value ? true : false
@@ -64,8 +64,12 @@ if $PROGRAM_NAME == __FILE__
64
64
  assert_equal false, MarkdownExec::OptionValue.for_hash(false)
65
65
  end
66
66
 
67
- def test_for_hash_with_empty_value
68
- assert_equal 'default', MarkdownExec::OptionValue.for_hash([], 'default')
67
+ def test_for_hash_with_empty_array
68
+ assert_equal [], MarkdownExec::OptionValue.for_hash([], 'default')
69
+ end
70
+
71
+ def test_for_hash_with_empty_hash
72
+ assert_equal({}, MarkdownExec::OptionValue.for_hash({}, 'default'))
69
73
  end
70
74
 
71
75
  def test_for_yaml_with_string
data/lib/poly.rb CHANGED
@@ -8,7 +8,9 @@ $pd = false
8
8
  class Poly
9
9
  # attr_reader :table
10
10
  def initialize(table = {})
11
- @table = table.tap{|ret| pp [__LINE__,'Poly.initialize()','table',table.to_yaml] if $pd }
11
+ @table = table.tap { |ret|
12
+ pp [__LINE__, 'Poly.initialize()', 'table', table.to_yaml] if $pd
13
+ }
12
14
  end
13
15
 
14
16
  def fetch(key, *args)
@@ -20,16 +22,21 @@ class Poly
20
22
  elsif block_given?
21
23
  yield key_sym
22
24
  elsif args.count.positive?
23
- # binding.irb
25
+ # binding.irb
24
26
  args.first
25
27
  else
26
- binding.irb
28
+ binding.irb
27
29
  raise KeyError, "key not found: #{key}"
28
- end.tap{|ret| pp([__LINE__,"Poly.fetch #{key} #{args}",'->',ret]) if $pd }
30
+ end.tap { |ret|
31
+ pp([__LINE__, "Poly.fetch #{key} #{args}", '->',
32
+ ret]) if $pd
33
+ }
29
34
  end
30
35
 
31
36
  def key?(name)
32
- @table.key?(name.to_sym).tap{|ret| pp([__LINE__,"Poly.key? #{name}",'->',ret]) if $pd }
37
+ @table.key?(name.to_sym).tap { |ret|
38
+ pp([__LINE__, "Poly.key? #{name}", '->', ret]) if $pd
39
+ }
33
40
  end
34
41
 
35
42
  def method_missing(name, *args)
@@ -55,12 +62,17 @@ binding.irb
55
62
  else
56
63
  pt = 'table read'
57
64
  @table[name.to_sym]
58
- end.tap{|ret| pp([__LINE__,"Poly.method_missing #{name} #{args.map(&:to_s).join(' ')}",pt,'->',ret]) if $pd }
65
+ end.tap { |ret|
66
+ pp([__LINE__,
67
+ "Poly.method_missing #{name} #{args.map(&:to_s).join(' ')}", pt, '->', ret]) if $pd
68
+ }
59
69
  end
60
70
 
61
71
  def respond_to_missing?(name, include_private = false)
62
72
  # name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super
63
- (name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super).tap{|ret| pp([__LINE__,"Poly.respond_to_missing? #{name}",'->',ret]) if $pd }
73
+ (name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super).tap { |ret|
74
+ pp([__LINE__, "Poly.respond_to_missing? #{name}", '->', ret]) if $pd
75
+ }
64
76
  end
65
77
 
66
78
  def [](key)
@@ -68,7 +80,7 @@ binding.irb
68
80
  send("get_#{key}")
69
81
  else
70
82
  @table[key.to_sym]
71
- end.tap{|ret| pp([__LINE__,"Poly.[] #{key}",'->',ret]) if $pd }
83
+ end.tap { |ret| pp([__LINE__, "Poly.[] #{key}", '->', ret]) if $pd }
72
84
  end
73
85
 
74
86
  def []=(key, value)
@@ -76,7 +88,10 @@ binding.irb
76
88
  send("set_#{key}", value)
77
89
  else
78
90
  @table[key.to_sym] = value
79
- end.tap{|ret| pp([__LINE__,"Poly.[]= #{key} #{value}",'->',ret]) if $pd }
91
+ end.tap { |ret|
92
+ pp([__LINE__, "Poly.[]= #{key} #{value}", '->',
93
+ ret]) if $pd
94
+ }
80
95
  end
81
96
 
82
97
  # for export to Prompt library
@@ -84,18 +99,22 @@ binding.irb
84
99
  # Proc.new { |x| @table.merge x }
85
100
  # end
86
101
  def merge(*args)
87
- # pp caller
88
- # binding.irb
89
- @table.merge(*args).tap{|ret| pp([__LINE__,"Poly.merge",'->',ret]) if $pd }
102
+ # pp caller
103
+ # binding.irb
104
+ @table.merge(*args).tap { |ret|
105
+ pp([__LINE__, "Poly.merge", '->', ret]) if $pd
106
+ }
90
107
  end
91
108
 
92
109
  # for export to Prompt library
93
110
  def to_h
94
- @table.tap{|ret| pp([__LINE__,"Poly.to_h",'->',ret]) if $pd }
111
+ @table.tap { |ret| pp([__LINE__, "Poly.to_h", '->', ret]) if $pd }
95
112
  end
96
113
 
97
114
  def to_yaml
98
- @table.to_yaml.tap{|ret| pp([__LINE__,"Poly.to_yaml",'->',ret]) if $pd }
115
+ @table.to_yaml.tap { |ret|
116
+ pp([__LINE__, "Poly.to_yaml", '->', ret]) if $pd
117
+ }
99
118
  end
100
119
  end
101
120
 
@@ -10,60 +10,66 @@ require 'timeout'
10
10
  # If so, it sends escape sequences to query the terminal size and reads the response.
11
11
  # It then compares the current terminal size with the calculated size and adjusts if necessary.
12
12
  # If the terminal emulator is unsupported, it prints an error message.
13
- def resize_terminal(show_dims: false, show_rectangle: false)
13
+ # 2024-8-23 add require_stdout to allow for testing
14
+ def resize_terminal(show_dims: false, show_rectangle: false,
15
+ require_stdout: true)
14
16
  # Check if running in an interactive terminal and no arguments are provided
15
- if $stdin.tty?
16
- begin
17
- # Save the current state and send the escape sequence to get the cursor position
18
- print "\e7\e[r\e[999;999H\e[6n\e8"
19
- $stdout.flush
20
-
21
- # Read the response from the terminal
22
- response = String.new
23
- Timeout.timeout(5) do
24
- loop do
25
- char = $stdin.getch
26
- response << char
27
- break if response.include?('R')
28
- end
29
- end
17
+ unless $stdin.tty?
18
+ warn 'Usage: resize_terminal'
19
+ return
20
+ end
30
21
 
31
- if response.empty?
32
- warn "Error: No response received from terminal. Response: #{response.inspect}"
33
- return 1
34
- end
22
+ return if require_stdout && !$stdout.tty?
35
23
 
36
- # Match the response to extract the terminal dimensions
37
- match_data = response.match(/\[(\d+);(\d+)R/)
38
- unless match_data
39
- warn "Error: Failed to match terminal response pattern. Response: #{response.inspect}"
40
- return 1
41
- end
24
+ # Save the current state and send the escape sequence to get the cursor position
25
+ print "\e7\e[r\e[999;999H\e[6n\e8"
26
+ $stdout.flush
27
+
28
+ # Read the response from the terminal
29
+ response = String.new
30
+ Timeout.timeout(5) do
31
+ loop do
32
+ char = $stdin.getch
33
+ response << char
34
+ break if response.include?('R')
35
+ end
36
+ end
42
37
 
43
- calculated_rows, calculated_columns = match_data.captures.map(&:to_i)
38
+ if response.empty?
39
+ warn "Error: No response received from terminal. Response: #{response.inspect}"
40
+ return 1
41
+ end
44
42
 
45
- if ENV['COLUMNS'].to_i == calculated_columns && ENV['LINES'].to_i == calculated_rows
46
- puts "#{ENV.fetch('TERM', nil)} #{calculated_columns}x#{calculated_rows}"
47
- elsif calculated_columns.positive? && calculated_rows.positive?
48
- warn "#{ENV.fetch('COLUMNS', nil)}x#{ENV.fetch('LINES', nil)} -> #{calculated_columns}x#{calculated_rows}" if show_dims
49
- system("stty cols #{calculated_columns} rows #{calculated_rows}")
50
- else
51
- warn "Error: Calculated terminal size is invalid. Columns: #{calculated_columns}, Rows: #{calculated_rows}"
52
- return 1
53
- end
43
+ # Match the response to extract the terminal dimensions
44
+ match_data = response.match(/\[(\d+);(\d+)R/)
45
+ unless match_data
46
+ warn "Error: Failed to match terminal response pattern. Response: #{response.inspect}"
47
+ return 1
48
+ end
54
49
 
55
- # Display a text rectangle if the option is enabled
56
- display_terminal_rectangle(calculated_columns, calculated_rows) if show_rectangle
57
- rescue Timeout::Error
58
- warn 'Error: Timeout while reading terminal response. Unsupported terminal emulator.'
59
- 1
60
- rescue StandardError => err
61
- warn "Error: #{err.message}. Unsupported terminal emulator."
62
- 1
63
- end
50
+ calculated_rows, calculated_columns = match_data.captures.map(&:to_i)
51
+
52
+ if ENV['COLUMNS'].to_i == calculated_columns && ENV['LINES'].to_i == calculated_rows
53
+ puts "#{ENV.fetch('TERM', nil)} #{calculated_columns}x#{calculated_rows}"
54
+ elsif calculated_columns.positive? && calculated_rows.positive?
55
+ warn "#{ENV.fetch('COLUMNS',
56
+ nil)}x#{ENV.fetch('LINES',
57
+ nil)} -> #{calculated_columns}x#{calculated_rows}" if show_dims
58
+ system("stty cols #{calculated_columns} rows #{calculated_rows}")
64
59
  else
65
- warn 'Usage: resize_terminal'
60
+ warn "Error: Calculated terminal size is invalid. Columns: #{calculated_columns}, Rows: #{calculated_rows}"
61
+ return 1
66
62
  end
63
+
64
+ # Display a text rectangle if the option is enabled
65
+ display_terminal_rectangle(calculated_columns,
66
+ calculated_rows) if show_rectangle
67
+ rescue Timeout::Error
68
+ warn 'Error: Timeout while reading terminal response. Unsupported terminal emulator.'
69
+ 1
70
+ rescue StandardError => err
71
+ warn "Error: #{err.message}. Unsupported terminal emulator."
72
+ 1
67
73
  end
68
74
 
69
75
  # This function draws a rectangle of the given width and height
@@ -119,7 +125,7 @@ class ResizeTerminalTest < Minitest::Test
119
125
  $stdin.stub(:getch, -> { response.slice!(0) || '' }) do
120
126
  assert_output("\e7\e[r\e[999;999H\e[6n\e8xterm-256color #{columns}x24\n") do
121
127
  # assert_output('', '') do
122
- resize_terminal
128
+ resize_terminal(require_stdout: false)
123
129
  end
124
130
  end
125
131
  end
@@ -131,8 +137,9 @@ class ResizeTerminalTest < Minitest::Test
131
137
  ARGV.replace([])
132
138
  $stdin.stub(:getch, -> { '' }) do
133
139
  # assert_output(nil, /Error: No response received from terminal/) do
134
- assert_output(nil, "Error: Timeout while reading terminal response. Unsupported terminal emulator.\n") do
135
- assert_equal 1, resize_terminal
140
+ assert_output(nil,
141
+ "Error: Timeout while reading terminal response. Unsupported terminal emulator.\n") do
142
+ assert_equal 1, resize_terminal(require_stdout: false)
136
143
  end
137
144
  end
138
145
  end
@@ -144,8 +151,9 @@ class ResizeTerminalTest < Minitest::Test
144
151
  ARGV.replace([])
145
152
  response = "\e[999;999H\e[6n\e[InvalidResponse".dup
146
153
  $stdin.stub(:getch, -> { response.slice!(0) || '' }) do
147
- assert_output(nil, /Error: Failed to match terminal response pattern/) do
148
- assert_equal 1, resize_terminal
154
+ assert_output(nil,
155
+ /Error: Failed to match terminal response pattern/) do
156
+ assert_equal 1, resize_terminal(require_stdout: false)
149
157
  end
150
158
  end
151
159
  end
@@ -157,7 +165,7 @@ class ResizeTerminalTest < Minitest::Test
157
165
  ARGV.replace([])
158
166
  Timeout.stub(:timeout, ->(_) { raise Timeout::Error }) do
159
167
  assert_output(nil, /Error: Timeout while reading terminal response/) do
160
- assert_equal 1, resize_terminal
168
+ assert_equal 1, resize_terminal(require_stdout: false)
161
169
  end
162
170
  end
163
171
  end
data/lib/saved_assets.rb CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  # encoding=utf-8
5
5
  require_relative 'namer'
6
+ require_relative 'object_present'
6
7
 
7
8
  module MarkdownExec
8
9
  # SavedAsset
@@ -25,16 +26,15 @@ module MarkdownExec
25
26
  # @param ftime [String] the time format (default: DEFAULT_FTIME)
26
27
  # @param exts [String] the extension to append (default: '.sh')
27
28
  def initialize(
28
- saved_asset_format:, filename: nil, prefix: nil, time: nil, blockname: nil,
29
- ftime: DEFAULT_FTIME, exts: nil,
30
- mark: nil, join_str: nil
29
+ saved_asset_format:, blockname: nil, exts: nil,
30
+ filename: nil, ftime: DEFAULT_FTIME, join_str: nil,
31
+ mark: nil, prefix: nil, time: nil
31
32
  )
32
- @filename = filename ? filename.pub_name : '*' # [String] the name of the file
33
- @prefix = prefix || '*' # [String] the prefix to use
34
- @time = time ? time.strftime(ftime) : '*' # [Time] the time object for formatting
35
- @blockname = blockname ? blockname.pub_name : '*' # [String] the block name to include
36
- # @ftime = ftime # [String] the time format (default: DEFAULT_FTIME)
37
- @exts = exts || '.*' # [String] the extension to append (default: '.sh')
33
+ @filename = filename.present? ? filename.pub_name : '*'
34
+ @prefix = prefix || '*'
35
+ @time = time ? time.strftime(ftime) : '*'
36
+ @blockname = blockname ? blockname.pub_name : '*'
37
+ @exts = exts || '.*'
38
38
  @mark = mark || MARK_STR
39
39
  @join_str = join_str || JOIN_STR
40
40
  @saved_asset_format = saved_asset_format
@@ -64,6 +64,9 @@ return if $PROGRAM_NAME != __FILE__
64
64
 
65
65
  require 'minitest/autorun'
66
66
 
67
+ SAVED_ASSET_FORMAT = '%{prefix}%{join}%{time}%{join}%{filename}%{join}' \
68
+ '%{mark}%{join}%{blockname}%{join}%{exts}'
69
+
67
70
  class SavedAssetTest < Minitest::Test
68
71
  def test_script_name_with_special_characters_in_blockname
69
72
  filename = 'sample.txt'
@@ -71,10 +74,11 @@ class SavedAssetTest < Minitest::Test
71
74
  time = Time.new(2023, 1, 1, 12, 0, 0)
72
75
  blockname = 'block/1:2'
73
76
 
74
- expected_name = 'test_2023-01-01-12-00-00_sample_txt_,_block_1_2.sh'
75
- assert_equal expected_name, MarkdownExec::SavedAsset.script_name(
76
- filename: filename, prefix: prefix, time: time, blockname: blockname
77
- )
77
+ expected_name = 'test_2023-01-01-12-00-00_sample_txt_~_block_1_2_.*'
78
+ assert_equal expected_name, MarkdownExec::SavedAsset.new(
79
+ blockname: blockname, filename: filename, prefix: prefix,
80
+ saved_asset_format: SAVED_ASSET_FORMAT, time: time
81
+ ).generate_name
78
82
  end
79
83
 
80
84
  def test_stdout_name_with_special_characters_in_blockname
@@ -83,10 +87,11 @@ class SavedAssetTest < Minitest::Test
83
87
  time = Time.new(2023, 1, 1, 12, 0, 0)
84
88
  blockname = 'block/1:2'
85
89
 
86
- expected_name = 'test_2023-01-01-12-00-00_sample_txt_,_block_1_2.out.txt'
87
- assert_equal expected_name, MarkdownExec::SavedAsset.stdout_name(
90
+ expected_name = 'test_2023-01-01-12-00-00_sample_txt_~_block_1_2_.*'
91
+ assert_equal expected_name, MarkdownExec::SavedAsset.new(
92
+ saved_asset_format: SAVED_ASSET_FORMAT,
88
93
  filename: filename, prefix: prefix, time: time, blockname: blockname
89
- )
94
+ ).generate_name
90
95
  end
91
96
 
92
97
  def test_wildcard_name_with_all_parameters
@@ -94,11 +99,12 @@ class SavedAssetTest < Minitest::Test
94
99
  prefix = 'test'
95
100
  time = Time.new(2023, 1, 1, 12, 0, 0)
96
101
  blockname = 'block/1:2'
97
- expected_wildcard = 'test_2023-01-01-12-00-00_sample_txt_,_block_1_2.sh'
102
+ expected_wildcard = 'test_2023-01-01-12-00-00_sample_txt_~_block_1_2_.*'
98
103
 
99
- assert_equal expected_wildcard, MarkdownExec::SavedAsset.wildcard_name(
104
+ assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
105
+ saved_asset_format: SAVED_ASSET_FORMAT,
100
106
  filename: filename, prefix: prefix, time: time, blockname: blockname
101
- )
107
+ ).generate_name
102
108
  end
103
109
 
104
110
  def test_wildcard_name_with_missing_time
@@ -106,11 +112,12 @@ class SavedAssetTest < Minitest::Test
106
112
  prefix = 'test'
107
113
  time = nil
108
114
  blockname = 'block/1:2'
109
- expected_wildcard = 'test_*_sample_txt_,_block_1_2.sh'
115
+ expected_wildcard = 'test_*_sample_txt_~_block_1_2_.*'
110
116
 
111
- assert_equal expected_wildcard, MarkdownExec::SavedAsset.wildcard_name(
117
+ assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
118
+ saved_asset_format: SAVED_ASSET_FORMAT,
112
119
  filename: filename, prefix: prefix, time: time, blockname: blockname
113
- )
120
+ ).generate_name
114
121
  end
115
122
 
116
123
  def test_wildcard_name_with_missing_filename
@@ -118,11 +125,12 @@ class SavedAssetTest < Minitest::Test
118
125
  prefix = 'test'
119
126
  time = Time.new(2023, 1, 1, 12, 0, 0)
120
127
  blockname = 'block/1:2'
121
- expected_wildcard = 'test_2023-01-01-12-00-00_*_,_block_1_2.sh'
128
+ expected_wildcard = 'test_2023-01-01-12-00-00_*_~_block_1_2_.*'
122
129
 
123
- assert_equal expected_wildcard, MarkdownExec::SavedAsset.wildcard_name(
130
+ assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
131
+ saved_asset_format: SAVED_ASSET_FORMAT,
124
132
  filename: filename, prefix: prefix, time: time, blockname: blockname
125
- )
133
+ ).generate_name
126
134
  end
127
135
 
128
136
  def test_wildcard_name_with_missing_prefix
@@ -130,11 +138,12 @@ class SavedAssetTest < Minitest::Test
130
138
  prefix = nil
131
139
  time = Time.new(2023, 1, 1, 12, 0, 0)
132
140
  blockname = 'block/1:2'
133
- expected_wildcard = '*_2023-01-01-12-00-00_sample_txt_,_block_1_2.sh'
141
+ expected_wildcard = '*_2023-01-01-12-00-00_sample_txt_~_block_1_2_.*'
134
142
 
135
- assert_equal expected_wildcard, MarkdownExec::SavedAsset.wildcard_name(
143
+ assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
144
+ saved_asset_format: SAVED_ASSET_FORMAT,
136
145
  filename: filename, prefix: prefix, time: time, blockname: blockname
137
- )
146
+ ).generate_name
138
147
  end
139
148
 
140
149
  def test_wildcard_name_with_missing_blockname
@@ -142,11 +151,12 @@ class SavedAssetTest < Minitest::Test
142
151
  prefix = 'test'
143
152
  time = Time.new(2023, 1, 1, 12, 0, 0)
144
153
  blockname = nil
145
- expected_wildcard = 'test_2023-01-01-12-00-00_sample_txt_,_*.sh'
154
+ expected_wildcard = 'test_2023-01-01-12-00-00_sample_txt_~_*_.*'
146
155
 
147
- assert_equal expected_wildcard, MarkdownExec::SavedAsset.wildcard_name(
156
+ assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
157
+ saved_asset_format: SAVED_ASSET_FORMAT,
148
158
  filename: filename, prefix: prefix, time: time, blockname: blockname
149
- )
159
+ ).generate_name
150
160
  end
151
161
 
152
162
  def test_wildcard_name_with_all_missing
@@ -154,10 +164,11 @@ class SavedAssetTest < Minitest::Test
154
164
  prefix = nil
155
165
  time = nil
156
166
  blockname = nil
157
- expected_wildcard = '*_*_*_,_*.sh'
167
+ expected_wildcard = '*_*_*_~_*_.*'
158
168
 
159
- assert_equal expected_wildcard, MarkdownExec::SavedAsset.wildcard_name(
169
+ assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
170
+ saved_asset_format: SAVED_ASSET_FORMAT,
160
171
  filename: filename, prefix: prefix, time: time, blockname: blockname
161
- )
172
+ ).generate_name
162
173
  end
163
174
  end
@@ -45,15 +45,18 @@ if $PROGRAM_NAME == __FILE__
45
45
  end
46
46
 
47
47
  def test_list_all
48
- assert_kind_of Array, MarkdownExec::SavedFilesMatcher.list_all(@folder, @glob)
48
+ assert_kind_of Array,
49
+ MarkdownExec::SavedFilesMatcher.list_all(@folder, @glob)
49
50
  end
50
51
 
51
52
  def test_most_recent
52
- assert_match(/\.md$/, MarkdownExec::SavedFilesMatcher.most_recent(@folder, @glob))
53
+ assert_match(/\.md$/,
54
+ MarkdownExec::SavedFilesMatcher.most_recent(@folder, @glob))
53
55
  end
54
56
 
55
57
  def test_most_recent_list
56
- result = MarkdownExec::SavedFilesMatcher.most_recent_list(@folder, @glob, 5)
58
+ result = MarkdownExec::SavedFilesMatcher.most_recent_list(@folder, @glob,
59
+ 5)
57
60
  assert_kind_of Array, result
58
61
  assert_operator result.size, :<=, 16
59
62
  end
data/lib/streams_out.rb CHANGED
@@ -11,7 +11,13 @@ class StreamsOut
11
11
  end
12
12
 
13
13
  def append_stream_line(stream, line)
14
- @streams << { stream: stream, line: line, timestamp: Time.now }
14
+ @streams << OpenStruct.new(stream: stream, line: line, timestamp: Time.now)
15
+ end
16
+
17
+ def stream_lines(stream)
18
+ @streams.select do |v|
19
+ v[:stream] == stream
20
+ end.map(&:line)
15
21
  end
16
22
 
17
23
  def write_execution_output_to_file(filespec)