markdown_exec 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -4
  3. data/CHANGELOG.md +28 -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 +40 -5
  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 +41 -0
  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 +939 -611
  50. data/lib/hierarchy_string.rb +221 -0
  51. data/lib/input_sequencer.rb +19 -11
  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 +420 -165
  57. data/lib/mdoc.rb +38 -38
  58. data/lib/menu.src.yml +832 -680
  59. data/lib/menu.yml +814 -689
  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 +236 -0
  71. metadata +28 -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)