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
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TableExtractor
4
+ # Extract tables from an array of text lines formatted in Markdown style
5
+ # @param [Array<String>] lines The array of text lines
6
+ # @return [Array<Hash>] An array of tables with row count, column count, and start index
7
+ def self.extract_tables(lines)
8
+ tables = []
9
+ inside_table = false
10
+ table_start = nil
11
+ row_count = 0
12
+ column_count = 0
13
+
14
+ separator_regexp = /^[ \t]*\|? *(?::?-+:?) *( *\| *(?::?-+:?) *)+\|? *$/
15
+
16
+ lines.each_with_index do |line, index|
17
+ # Match line separators with at least 2 columns
18
+ if line.strip.match?(separator_regexp)
19
+ if inside_table
20
+ # Add the current table before starting a new one
21
+ tables << {
22
+ rows: row_count,
23
+ columns: column_count,
24
+ start_index: table_start
25
+ }
26
+ end
27
+ # Start a new table
28
+ table_start = index - 1 if table_start.nil?
29
+ column_count = line.split('|').count - 1
30
+ row_count = 2 # Reset to 2 to account for the header and separator rows
31
+ inside_table = true
32
+ elsif inside_table && (line.strip.start_with?('|') || line.include?('|'))
33
+ row_count += 1
34
+ elsif inside_table
35
+ # Add the current table and reset the state
36
+ tables << {
37
+ rows: row_count,
38
+ columns: column_count,
39
+ start_index: table_start
40
+ }
41
+ inside_table = false
42
+ table_start = nil
43
+ row_count = 0
44
+ column_count = 0
45
+ end
46
+ end
47
+
48
+ # Handle case where table ends at the last line
49
+ if inside_table
50
+ tables << {
51
+ rows: row_count,
52
+ columns: column_count,
53
+ start_index: table_start
54
+ }
55
+ end
56
+
57
+ tables
58
+ end
59
+ end
60
+
61
+ return if $PROGRAM_NAME != __FILE__
62
+
63
+ require 'minitest/autorun'
64
+
65
+ class TestTableExtractor < Minitest::Test
66
+ def test_single_table
67
+ lines = [
68
+ '| Species| Genus| Family',
69
+ '|-|-|-',
70
+ '| Pongo tapanuliensis| Pongo| Hominidae',
71
+ '| | Histiophryne| Antennariidae'
72
+ ]
73
+ expected = [{ rows: 4, columns: 3, start_index: 0 }]
74
+ assert_equal expected, TableExtractor.extract_tables(lines)
75
+ end
76
+
77
+ def test_indented_table
78
+ lines = [
79
+ "\t | Species| Genus| Family",
80
+ "\t |-|-|-",
81
+ "\t | Pongo tapanuliensis| Pongo| Hominidae",
82
+ "\t | | Histiophryne| Antennariidae"
83
+ ]
84
+ expected = [{ rows: 4, columns: 3, start_index: 0 }]
85
+ assert_equal expected, TableExtractor.extract_tables(lines)
86
+ end
87
+
88
+ def test_multiple_tables
89
+ lines = [
90
+ '| Species| Genus| Family',
91
+ '|-|-|-',
92
+ '| Pongo tapanuliensis| Pongo| Hominidae',
93
+ '| | Histiophryne| Antennariidae',
94
+ '',
95
+ '| Name| Species',
96
+ '|-|-',
97
+ '| Tapanuli Orangutan| Pongo tapanuliensis'
98
+ ]
99
+ expected = [
100
+ { rows: 4, columns: 3, start_index: 0 },
101
+ { rows: 3, columns: 2, start_index: 5 }
102
+ ]
103
+ assert_equal expected, TableExtractor.extract_tables(lines)
104
+ end
105
+
106
+ def test_no_tables
107
+ lines = [
108
+ 'This is a regular line.',
109
+ 'Another regular line.'
110
+ ]
111
+ expected = []
112
+ assert_equal expected, TableExtractor.extract_tables(lines)
113
+ end
114
+
115
+ def test_inconsistent_columns
116
+ lines = [
117
+ '| Species| Genus| Family',
118
+ '|-|-',
119
+ '| Pongo tapanuliensis| Pongo| Hominidae',
120
+ '| | Histiophryne| Antennariidae',
121
+ '',
122
+ '| Name| Species',
123
+ '|-|-|-',
124
+ '| Tapanuli Orangutan| Pongo tapanuliensis'
125
+ ]
126
+ # number of columns determined from row of dividers
127
+ expected = [{ rows: 4, columns: 2, start_index: 0 },
128
+ { rows: 3, columns: 3, start_index: 5 }]
129
+ assert_equal expected, TableExtractor.extract_tables(lines)
130
+ end
131
+
132
+ def test_table_at_end_of_lines
133
+ lines = [
134
+ 'Some introductory text.',
135
+ '| Species| Genus| Family',
136
+ '|-|-|-',
137
+ '| Pongo tapanuliensis| Pongo| Hominidae',
138
+ '| | Histiophryne| Antennariidae'
139
+ ]
140
+ expected = [{ rows: 4, columns: 3, start_index: 1 }]
141
+ assert_equal expected, TableExtractor.extract_tables(lines)
142
+ end
143
+
144
+ def test_table_without_starting_pipe
145
+ lines = [
146
+ 'Some introductory text.',
147
+ 'Platform| Target Environment| Command',
148
+ '|-|-|-',
149
+ '| Pongo tapanuliensis| Pongo| Hominidae',
150
+ '| | Histiophryne| Antennariidae'
151
+ ]
152
+ expected = [{ rows: 4, columns: 3, start_index: 1 }]
153
+ assert_equal expected, TableExtractor.extract_tables(lines)
154
+ end
155
+
156
+ def test_table_with_colon_hyphens
157
+ lines = [
158
+ '| Name| Age| City',
159
+ '|:-:|:-|:-:',
160
+ '| John Doe| 30| New York',
161
+ '| Jane Doe| 25| Los Angeles'
162
+ ]
163
+ expected = [{ rows: 4, columns: 3, start_index: 0 }]
164
+ assert_equal expected, TableExtractor.extract_tables(lines)
165
+ end
166
+ end
data/lib/tap.rb CHANGED
@@ -35,8 +35,6 @@ unless defined?(Env)
35
35
  end
36
36
  end
37
37
 
38
- # rubocop:disable Metrics/ParameterLists
39
-
40
38
  ## application-level debug control
41
39
  #
42
40
  # :reek:TooManyConstants
@@ -98,8 +96,8 @@ module Tap
98
96
 
99
97
  # :reek:ControlParameter
100
98
  # :reek:LongParameterList
101
- def tap_inspect(name_ = nil, caller_first: nil, mask: TDD, name: DN, source: nil,
102
- type: nil)
99
+ def tap_inspect(name_ = nil, caller_first: nil, mask: TDD, name: DN,
100
+ source: nil, type: nil)
103
101
  return self unless $tap_enable
104
102
  return self unless (mask & $tap_mask).positive?
105
103
 
@@ -107,7 +105,8 @@ module Tap
107
105
  outs = []
108
106
  outs.push(source.to_s) if source.present?
109
107
 
110
- vs = (caller_first || caller[0]).scan(/in `?(\S+)'$/).fetch(0, []).fetch(0, '')
108
+ vs = (caller_first || caller[0]).scan(/in `?(\S+)'$/)
109
+ .fetch(0, []).fetch(0, '')
111
110
  outs.push("#{vs}()") if vs.present?
112
111
 
113
112
  outs.push(tap_named_value(name_ || name, method(fn).call))
@@ -143,7 +142,7 @@ module Tap
143
142
  # :reek:ControlParameter
144
143
  # :reek:LongParameterList
145
144
  def tap_yaml(name_ = nil, caller_first: nil, mask: TDD, name: DN, source: nil)
146
- tap_inspect name_, caller_first: (caller_first || caller[0]),
145
+ tap_inspect name_, caller_first: caller_first || caller[0],
147
146
  mask: mask, name: name, source: source, type: :yaml
148
147
  end
149
148
 
data/lib/text_analyzer.rb CHANGED
@@ -11,13 +11,17 @@ module TextAnalyzer
11
11
  # @return [Array<Hash>, Array<Array<Hash>>] an array or nested arrays of highlighted segments
12
12
  #
13
13
  # @raise [ArgumentError] if the hierarchy structure is neither a String nor an Array
14
- def self.analyze_hierarchy(hierarchy, pattern, default_color, match_color)
14
+ def self.analyze_hierarchy(
15
+ hierarchy, pattern, default_color, match_color,
16
+ text_sym: :text, style_sym: :color
17
+ )
15
18
  case hierarchy
16
19
  when String
17
20
  highlight_segments(hierarchy, pattern, default_color, match_color)
21
+
18
22
  when Hash
19
- decorated = highlight_segments(hierarchy[:text], pattern,
20
- hierarchy[:color], match_color)
23
+ decorated = highlight_segments(hierarchy[text_sym], pattern,
24
+ hierarchy[style_sym], match_color)
21
25
 
22
26
  case decorated
23
27
  when String
@@ -31,18 +35,19 @@ module TextAnalyzer
31
35
  else
32
36
  decorated
33
37
  end
38
+
34
39
  when Array
35
40
  hierarchy.map do |element|
36
41
  analyze_hierarchy(element, pattern, default_color, match_color)
37
42
  end
38
- when HierarchyString
39
43
 
44
+ when HierarchyString
40
45
  hierarchy.replace_text! do |substring|
41
- substring ### no change
46
+ substring # no change
42
47
  end
43
48
 
44
49
  else
45
- binding.irb
50
+ warn [hierarchy.class, hierarchy].inspect
46
51
  raise ArgumentError, 'Invalid hierarchy structure'
47
52
  end
48
53
  end
@@ -77,14 +82,14 @@ module TextAnalyzer
77
82
  # @yieldparam segment [String] a segment of the text
78
83
  # @yieldparam is_match [Boolean] true if the segment matches the pattern, false otherwise
79
84
  def self.yield_matches_and_non_matches(text, pattern)
80
- last_end = 0
85
+ last_end = nil
81
86
 
82
87
  text.scan(pattern) do |match|
83
88
  match_start = Regexp.last_match.begin(0)
84
89
  match_end = Regexp.last_match.end(0)
85
90
 
86
91
  # Yield the non-matching segment before the match
87
- yield text[last_end...match_start], false if match_start > last_end
92
+ yield text[(last_end || 0)...match_start], false if last_end.nil? || match_start > last_end
88
93
 
89
94
  # Yield the matching segment
90
95
  yield match.first, true
@@ -92,9 +97,140 @@ module TextAnalyzer
92
97
  last_end = match_end
93
98
  end
94
99
 
100
+ last_end ||= 0
95
101
  # Yield any remaining non-matching segment after the last match
96
102
  return unless last_end < text.length
97
103
 
98
104
  yield text[last_end..-1], false
99
105
  end
100
106
  end
107
+
108
+ return if $PROGRAM_NAME != __FILE__
109
+
110
+ require 'minitest/autorun'
111
+ require_relative 'hierarchy_string'
112
+
113
+ $default_color = :upcase
114
+ $match_color = :downcase
115
+
116
+ class TestTextAnalyzer < Minitest::Test
117
+ def test_analyze_hierarchy_with_string
118
+ text = 'This is a test string.'
119
+ pattern = /(test)/
120
+
121
+ expected_output = [[[
122
+ { text: 'This is a ', color: $default_color },
123
+ { text: 'test', color: $match_color },
124
+ { text: ' string.', color: $default_color }
125
+ ]]]
126
+
127
+ tree = HierarchyString.new([{ text: text, color: $default_color }])
128
+ assert_equal expected_output,
129
+ TextAnalyzer.analyze_hierarchy(tree.substrings, pattern, $default_color,
130
+ $match_color)
131
+ end
132
+
133
+ def test_analyze_hierarchy_with_array
134
+ hierarchy = [
135
+ 'This is a test string.',
136
+ 'Another test line.'
137
+ ]
138
+ pattern = /(test)/
139
+
140
+ expected_output = [
141
+ [
142
+ { text: 'This is a ', color: $default_color },
143
+ { text: 'test', color: $match_color },
144
+ { text: ' string.', color: $default_color }
145
+ ],
146
+ [
147
+ { text: 'Another ', color: $default_color },
148
+ { text: 'test', color: $match_color },
149
+ { text: ' line.', color: $default_color }
150
+ ]
151
+ ]
152
+
153
+ assert_equal expected_output,
154
+ TextAnalyzer.analyze_hierarchy(hierarchy, pattern,
155
+ $default_color, $match_color)
156
+ end
157
+
158
+ def test_analyze_hierarchy_with_nested_array
159
+ hierarchy = [
160
+ 'This is a test string.',
161
+ ['Another test line.', 'Yet another test.']
162
+ ]
163
+ pattern = /(test)/
164
+
165
+ expected_output = [
166
+ [
167
+ { text: 'This is a ', color: $default_color },
168
+ { text: 'test', color: $match_color },
169
+ { text: ' string.', color: $default_color }
170
+ ],
171
+ [
172
+ [
173
+ { text: 'Another ', color: $default_color },
174
+ { text: 'test', color: $match_color },
175
+ { text: ' line.', color: $default_color }
176
+ ],
177
+ [
178
+ { text: 'Yet another ', color: $default_color },
179
+ { text: 'test', color: $match_color },
180
+ { text: '.', color: $default_color }
181
+ ]
182
+ ]
183
+ ]
184
+
185
+ assert_equal expected_output,
186
+ TextAnalyzer.analyze_hierarchy(hierarchy, pattern,
187
+ $default_color, $match_color)
188
+ end
189
+
190
+ def test_analyze_hierarchy_with_invalid_type
191
+ hierarchy = 12_345
192
+ # hierarchy = HierarchyString.new([{ text: '12345', color: $default_color }])
193
+ pattern = /(test)/
194
+
195
+ assert_raises(ArgumentError) do
196
+ TextAnalyzer.analyze_hierarchy(hierarchy, pattern, $default_color,
197
+ $match_color)
198
+ end
199
+ end
200
+
201
+ def test_highlight_segments
202
+ text = 'This is a test string.'
203
+ pattern = /(test)/
204
+
205
+ expected_output = [
206
+ { text: 'This is a ', color: $default_color },
207
+ { text: 'test', color: $match_color },
208
+ { text: ' string.', color: $default_color }
209
+ ]
210
+
211
+ assert_equal expected_output,
212
+ TextAnalyzer.highlight_segments(text, pattern, $default_color,
213
+ $match_color)
214
+ end
215
+
216
+ def test_yield_matches_and_non_matches
217
+ text = 'This is a test string with multiple tests.'
218
+ pattern = /(test)/
219
+ segments = []
220
+
221
+ TextAnalyzer.yield_matches_and_non_matches(text,
222
+ pattern) do |segment, is_match|
223
+ segments << { text: segment, is_match: is_match }
224
+ end
225
+
226
+ expected_output = [
227
+ { text: 'This is a ', is_match: false },
228
+ { text: 'test', is_match: true },
229
+ { text: ' string with multiple ', is_match: false },
230
+ { text: 'test', is_match: true },
231
+ { text: 's.', is_match: false }
232
+ ]
233
+
234
+ assert_equal expected_output, segments
235
+ end
236
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown_exec
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fareed Stevenson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-05 00:00:00.000000000 Z
11
+ date: 2024-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -106,6 +106,15 @@ files:
106
106
  - assets/output_of_execution.png
107
107
  - assets/select_a_block.png
108
108
  - assets/select_a_file.png
109
+ - bats/bats.bats
110
+ - bats/block-types.bats
111
+ - bats/cli.bats
112
+ - bats/fail.bats
113
+ - bats/history.bats
114
+ - bats/markup.bats
115
+ - bats/mde.bats
116
+ - bats/options.bats
117
+ - bats/test_helper.bash
109
118
  - bin/bmde
110
119
  - bin/colorize_env_vars.sh
111
120
  - bin/console
@@ -113,6 +122,13 @@ files:
113
122
  - bin/setup
114
123
  - bin/tab_completion.sh
115
124
  - bin/tab_completion.sh.erb
125
+ - docs/dev/block-type-opts.md
126
+ - docs/dev/block-type-port.md
127
+ - docs/dev/block-type-vars.md
128
+ - docs/dev/pass-through-arguments.md
129
+ - docs/dev/specs-import.md
130
+ - docs/dev/specs.md
131
+ - docs/dev/text-decoration.md
116
132
  - examples/bash-blocks.md
117
133
  - examples/block-names.md
118
134
  - examples/block_names.md
@@ -149,9 +165,13 @@ files:
149
165
  - examples/port-blocks.md
150
166
  - examples/save.md
151
167
  - examples/search.md
168
+ - examples/table-markup.md
169
+ - examples/text-markup.md
152
170
  - examples/vars-blocks.md
153
171
  - examples/wrap.md
154
172
  - lib/ansi_formatter.rb
173
+ - lib/ansi_string.rb
174
+ - lib/argument_processor.rb
155
175
  - lib/array.rb
156
176
  - lib/array_util.rb
157
177
  - lib/block_label.rb
@@ -163,17 +183,20 @@ files:
163
183
  - lib/colorize.rb
164
184
  - lib/constants.rb
165
185
  - lib/directory_searcher.rb
186
+ - lib/doh.rb
166
187
  - lib/env.rb
167
188
  - lib/exceptions.rb
168
189
  - lib/fcb.rb
169
190
  - lib/filter.rb
170
191
  - lib/find_files.rb
192
+ - lib/format_table.rb
171
193
  - lib/fout.rb
172
194
  - lib/hash.rb
173
195
  - lib/hash_delegator.rb
174
196
  - lib/hierarchy_string.rb
175
197
  - lib/input_sequencer.rb
176
198
  - lib/instance_method_wrapper.rb
199
+ - lib/layered_hash.rb
177
200
  - lib/link_history.rb
178
201
  - lib/markdown_exec.rb
179
202
  - lib/markdown_exec/version.rb
@@ -190,9 +213,9 @@ files:
190
213
  - lib/saved_assets.rb
191
214
  - lib/saved_files_matcher.rb
192
215
  - lib/shared.rb
193
- - lib/std_out_err_logger.rb
194
216
  - lib/streams_out.rb
195
217
  - lib/string_util.rb
218
+ - lib/table_extractor.rb
196
219
  - lib/tap.rb
197
220
  - lib/text_analyzer.rb
198
221
  homepage: https://rubygems.org/gems/markdown_exec
@@ -1,119 +0,0 @@
1
- #!/usr/bin/env -S bundle exec ruby
2
- # frozen_string_literal: true
3
-
4
- # encoding=utf-8
5
- require 'logger'
6
-
7
- # Logger::LogDevice is used by Logger, the parent class of StdOutErrLogger
8
- class Logger::LogDevice
9
- # remove header
10
- def add_log_header(file); end
11
- end
12
-
13
- # Custom logger to direct info to stdout and warn and above to stderr
14
- #
15
- class StdOutErrLogger < Logger
16
- attr_reader :file
17
-
18
- # def initialize(file = nil)
19
- def initialize(file = "#{__dir__}/../tmp/hash_delegator_next_link_state.yaml")
20
- @file = file
21
- super(file || $stdout)
22
- self.formatter = proc do |_severity, _datetime, _progname, msg|
23
- "#{msg}\n"
24
- end
25
- end
26
-
27
- def add(severity, message = nil, progname = nil, &block)
28
- message = (message || block&.call || progname) if message.nil?
29
- message = "- #{message.to_json}\n"
30
- ### message = message.join("\n") if message.is_a? Array
31
- out = format_message(format_severity(severity), Time.now, progname, message)
32
- if severity == Logger::UNKNOWN # does not follow spec, outputs to stderr for IO
33
- # $stderr.puts(out)
34
- super
35
- elsif severity >= Logger::WARN
36
- if @file
37
- super
38
- else
39
- warn(out)
40
- end
41
- elsif @file
42
- super
43
- else
44
- $stdout.puts(out)
45
- end
46
- end
47
- end
48
-
49
- return if $PROGRAM_NAME != __FILE__
50
-
51
- require 'minitest/autorun'
52
-
53
- class StdOutErrLoggerTest < Minitest::Test
54
- # Redirect STDOUT and STDERR to capture them for assertions
55
- def setup
56
- @original_stdout = $stdout
57
- @original_stderr = $stderr
58
- $stdout = StringIO.new
59
- $stderr = StringIO.new
60
- end
61
-
62
- def teardown
63
- $stdout = @original_stdout
64
- $stderr = @original_stderr
65
- end
66
-
67
- def test_initialize_without_file
68
- logger = StdOutErrLogger.new
69
- assert_nil logger.file
70
- assert_equal Logger::DEBUG, logger.level
71
- end
72
-
73
- def test_initialize_with_file
74
- Tempfile.open do |file|
75
- logger = StdOutErrLogger.new(file.path)
76
- assert_equal file.path, logger.file
77
- end
78
- end
79
-
80
- def test_logging_info
81
- logger = StdOutErrLogger.new
82
- logger.info('Info message')
83
- assert_equal "Info message\n", $stdout.string
84
- assert_empty $stderr.string
85
- end
86
-
87
- def test_logging_warning
88
- logger = StdOutErrLogger.new
89
- logger.warn('Warning message')
90
- assert_empty $stdout.string
91
- assert_equal "Warning message\n", $stderr.string
92
- end
93
-
94
- def test_logging_error
95
- logger = StdOutErrLogger.new
96
- logger.error('Error message')
97
- assert_empty $stdout.string
98
- assert_equal "Error message\n", $stderr.string
99
- end
100
-
101
- def test_logging_with_array
102
- logger = StdOutErrLogger.new
103
- logger.info(['Message line 1', 'Message line 2'])
104
- assert_equal "Message line 1\nMessage line 2\n", $stdout.string
105
- end
106
-
107
- def test_logging_with_block
108
- logger = StdOutErrLogger.new
109
- logger.info { 'Block message' }
110
- assert_equal "Block message\n", $stdout.string
111
- end
112
-
113
- def test_logging_unknown_severity
114
- logger = StdOutErrLogger.new
115
- logger.add(Logger::UNKNOWN, 'Unknown severity message')
116
- assert_empty $stdout.string
117
- assert_equal "Unknown severity message\n", $stderr.string
118
- end
119
- end