markdown_exec 1.3.3.4 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+
6
+ ##
7
+ # This class is used to represent a block label which can be constructed using various components.
8
+ # It handles initialization using a hash and provides a method to create a label string.
9
+ #
10
+ # Example Usage:
11
+ # block = {
12
+ # filename: 'example.md',
13
+ # headings: ['Header1', 'Header2'],
14
+ # menu_blocks_with_docname: true,
15
+ # menu_blocks_with_headings: false,
16
+ # title: 'Sample Title',
17
+ # body: 'Sample Body',
18
+ # text: 'Sample Text'
19
+ # }
20
+ # label_obj = BlockLabel.new(block)
21
+ # label_str = label_obj.make
22
+ #
23
+
24
+ class BlockLabel
25
+ def self.make(filename:, headings:, menu_blocks_with_docname:, menu_blocks_with_headings:, title:, body:, text:)
26
+ label = title
27
+ label = body if label.nil? || label.empty?
28
+ label = text if label.nil? || label.empty?
29
+
30
+ parts = [label]
31
+
32
+ parts << headings.compact.join(' # ') if menu_blocks_with_headings
33
+ parts << filename if menu_blocks_with_docname
34
+
35
+ parts.join(' ')
36
+ rescue StandardError => err
37
+ warn(error = "ERROR ** BlockLabel.make(); #{err.inspect}")
38
+ binding.pry if $tap_enable
39
+ raise ArgumentError, error
40
+ end
41
+ end
42
+
43
+ if $PROGRAM_NAME == __FILE__
44
+ require 'minitest/autorun'
45
+
46
+ class BlockLabelTest < Minitest::Test
47
+ def setup
48
+ @block_data = {
49
+ filename: 'example.md',
50
+ headings: %w[Header1 Header2],
51
+ menu_blocks_with_docname: true,
52
+ menu_blocks_with_headings: false,
53
+ title: 'Sample Title',
54
+ body: 'Sample Body',
55
+ text: 'Sample Text'
56
+ }
57
+ end
58
+
59
+ def test_make_method
60
+ assert_equal 'Sample Title example.md', BlockLabel.make(**@block_data)
61
+ end
62
+
63
+ def test_make_method_without_title
64
+ @block_data[:title] = nil
65
+ label = BlockLabel.make(**@block_data)
66
+ assert_equal 'Sample Body example.md', label
67
+ end
68
+
69
+ def test_make_method_without_title_and_body
70
+ @block_data[:title] = nil
71
+ @block_data[:body] = nil
72
+ label = BlockLabel.make(**@block_data)
73
+ assert_equal 'Sample Text example.md', label
74
+ end
75
+
76
+ def test_make_method_with_headings
77
+ @block_data[:menu_blocks_with_headings] = true
78
+ label = BlockLabel.make(**@block_data)
79
+ assert_equal 'Sample Title Header1 # Header2 example.md', label
80
+ end
81
+ end
82
+ end
data/lib/env_opts.rb CHANGED
@@ -93,9 +93,9 @@ class EnvOpts
93
93
  args_ind = 0
94
94
  while args_ind < argv.count
95
95
  args_consumed = 0
96
- arg = argv.fetch(args_ind, '') #.tap_inspect 'argument', source: 'EnvOpts'
96
+ arg = argv.fetch(args_ind, '')
97
97
  if arg.start_with? '--'
98
- opt_name = arg[2..-1] #.tap_inspect 'opt_name', source: 'EnvOpts'
98
+ opt_name = arg[2..-1]
99
99
  args_consumed = consume_arguments(opt_name,
100
100
  argv.fetch(args_ind + 1, nil))
101
101
  end
@@ -136,7 +136,7 @@ class EnvOpts
136
136
  # option names use hyphens
137
137
  #
138
138
  def self.symbol_name_to_option_name(name)
139
- name.to_s.gsub('_', '-') #.tap_inspect
139
+ name.to_s.gsub('_', '-')
140
140
  end
141
141
 
142
142
  private
@@ -144,7 +144,7 @@ class EnvOpts
144
144
  # convert key name or symbol to an option name
145
145
  #
146
146
  def key_name_to_option_name(key)
147
- (key.is_a?(Symbol) ? EnvOpts.symbol_name_to_option_name(key) : key) #.tap_inspect
147
+ (key.is_a?(Symbol) ? EnvOpts.symbol_name_to_option_name(key) : key)
148
148
  end
149
149
 
150
150
  # get cast of environment variable
@@ -175,7 +175,7 @@ class EnvOpts
175
175
  # option names use hyphens
176
176
  #
177
177
  def method_name_to_option_name(name)
178
- name.to_s.gsub('_', '-') #.tap_inspect
178
+ name.to_s.gsub('_', '-')
179
179
  end
180
180
 
181
181
  # read and write options using the option name as a method
@@ -187,7 +187,7 @@ class EnvOpts
187
187
  set_key_value_as_cast(name, value)
188
188
  else
189
189
  @values[method_name_to_option_name(method_name)]
190
- end #.tap_inspect "ref #{method_name}", source: 'EnvOpts'
190
+ end
191
191
  end
192
192
 
193
193
  # option name to environment name
@@ -146,7 +146,7 @@ class EnvironmentOptParse
146
146
  include Menu
147
147
 
148
148
  def initialize(menu: {}, lambdas: nil, options: nil, version: nil)
149
- @menu = if menu.class.to_s == 'String'
149
+ @menu = if menu.instance_of?(::String)
150
150
  filetext = File.read(menu).tap_yaml 'filetext'
151
151
  fileyaml = YAML.load(filetext)
152
152
  fileyaml.map(&:sym_keys)
@@ -156,7 +156,7 @@ class EnvironmentOptParse
156
156
  @lambdas = lambdas
157
157
  @version = version || '0.1'
158
158
  # @options = {}
159
- @options = if options.class.to_s == 'String'
159
+ @options = if options.instance_of?(::String)
160
160
  YAML.safe_load(File.read(options)).sym_keys.tap_yaml '@options'
161
161
  else
162
162
  {}
@@ -193,7 +193,7 @@ class EnvironmentOptParse
193
193
  exit
194
194
  },
195
195
  val_as_bool: lambda { |value|
196
- value.class.to_s == 'String' ? (value.chomp != '0') : value
196
+ value.instance_of?(::String) ? (value.chomp != '0') : value
197
197
  },
198
198
  val_as_int: ->(value) { value.to_i },
199
199
  val_as_str: ->(value) { value.to_s },
data/lib/fcb.rb ADDED
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+
6
+ module MarkdownExec
7
+ class Error < StandardError; end
8
+
9
+ # Fenced Code Block (FCB)
10
+ #
11
+ # This class represents a fenced code block in a markdown document.
12
+ # It allows for setting and getting attributes related to the code block,
13
+ # such as body, call, headings, and more.
14
+ #
15
+ class FCB
16
+ def initialize(options = {})
17
+ @attrs = {
18
+ body: nil,
19
+ call: nil,
20
+ headings: [],
21
+ name: nil,
22
+ reqs: [],
23
+ shell: '',
24
+ title: '',
25
+ random: Random.new.rand,
26
+ text: nil # displayable in menu
27
+ }.merge(options)
28
+ end
29
+
30
+ def to_h
31
+ @attrs
32
+ end
33
+
34
+ def to_yaml
35
+ @attrs.to_yaml
36
+ end
37
+
38
+ private
39
+
40
+ # 2023-10-07 proposed but not functional with code
41
+ #
42
+ # def method_missing(method, *args, &block)
43
+ # method_name = method.to_s
44
+
45
+ # if method_name[-1] == '='
46
+ # @attrs[method_name.chop.to_sym] = args[0]
47
+ # elsif @attrs.key?(method_name.to_sym)
48
+ # @attrs[method_name.to_sym]
49
+ # else
50
+ # super
51
+ # end
52
+ # rescue StandardError => err
53
+ # warn(error = "ERROR ** FCB.method_missing(method: #{method_name}, *args: #{args.inspect}, &block)")
54
+ # warn err.inspect
55
+ # warn(caller[0..4])
56
+ # raise err # Here, we simply propagate the original error instead of wrapping it in a StandardError.
57
+ # end
58
+
59
+ # :reek:ManualDispatch
60
+ def method_missing(method, *args, &block)
61
+ method_name = method.to_s
62
+
63
+ if @attrs.respond_to?(method_name)
64
+ @attrs.send(method_name, *args, &block)
65
+ elsif method_name[-1] == '='
66
+ @attrs[method_name.chop.to_sym] = args[0]
67
+ else
68
+ @attrs[method_name.to_sym]
69
+ end
70
+ rescue StandardError => err
71
+ warn("ERROR ** FCB.method_missing(method: #{method_name}," \
72
+ " *args: #{args.inspect}, &block)")
73
+ warn err.inspect
74
+ warn(caller[0..4])
75
+ # raise StandardError, error
76
+ raise err # Here, we simply propagate the original error instead of wrapping it in a StandardError.
77
+ end
78
+
79
+ def respond_to_missing?(method_name, _include_private = false)
80
+ @attrs.key?(method_name.to_sym) || super
81
+ end
82
+ end
83
+ end
84
+
85
+ if $PROGRAM_NAME == __FILE__
86
+ require 'minitest/autorun'
87
+ require 'yaml'
88
+
89
+ class FCBTest < Minitest::Test
90
+ def setup
91
+ @fcb_data = {
92
+ body: 'Sample body',
93
+ call: 'Sample call',
94
+ headings: %w[Header1 Header2],
95
+ name: 'Sample name',
96
+ reqs: %w[req1 req2],
97
+ shell: 'bash',
98
+ text: 'Sample Text',
99
+ title: 'Sample Title'
100
+ }
101
+ @fcb = MarkdownExec::FCB.new(@fcb_data)
102
+ end
103
+
104
+ def test_initialization_with_correct_data
105
+ assert_equal 'Sample body', @fcb.body
106
+ assert_equal %w[Header1 Header2], @fcb.headings
107
+ end
108
+
109
+ def test_to_h_method
110
+ assert_equal @fcb_data.merge({ random: @fcb.random }), @fcb.to_h
111
+ end
112
+
113
+ def test_to_yaml_method
114
+ assert_equal YAML.load(@fcb_data.merge({ random: @fcb.random }).to_yaml),
115
+ YAML.load(@fcb.to_yaml)
116
+ end
117
+
118
+ def test_method_missing_getter
119
+ assert_equal 'Sample Title', @fcb.title
120
+ end
121
+
122
+ def test_method_missing_setter
123
+ @fcb.title = 'New Title'
124
+ assert_equal 'New Title', @fcb.title
125
+ end
126
+
127
+ # 2023-10-09 does not trigger error; treats as option name
128
+ #
129
+ # def test_method_missing_with_unknown_method
130
+ # assert_raises(NoMethodError) { @fcb.unknown_method }
131
+ # end
132
+ end
133
+ end
data/lib/filter.rb ADDED
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+
6
+ module MarkdownExec
7
+ # Filter
8
+ #
9
+ # The Filter class provides utilities to determine the inclusion of fenced code blocks (FCB)
10
+ # based on a set of provided options. The primary function, `fcb_select?`, checks
11
+ # various properties of an FCB and decides whether to include or exclude it.
12
+ #
13
+ # :reek:UtilityFunction
14
+
15
+ class Filter
16
+ def self.fcb_select?(options, fcb)
17
+ filters = {
18
+ name_default: true,
19
+ name_exclude: nil,
20
+ name_select: nil,
21
+ shell_default: true,
22
+ shell_exclude: nil,
23
+ shell_select: nil,
24
+ hidden_name: nil
25
+ }
26
+
27
+ name = fcb.fetch(:name, '')
28
+ shell = fcb.fetch(:shell, '')
29
+
30
+ apply_name_filters(options, filters, name)
31
+ apply_shell_filters(options, filters, shell)
32
+ apply_other_filters(options, filters, fcb)
33
+
34
+ evaluate_filters(options, filters)
35
+ rescue StandardError => err
36
+ warn("ERROR ** Filter::fcb_select?(); #{err.inspect}")
37
+ raise err
38
+ end
39
+
40
+ def self.apply_name_filters(options, filters, name)
41
+ if name.present? && options[:block_name]
42
+ if name =~ /#{options[:block_name]}/
43
+ filters[:name_select] = true
44
+ filters[:name_exclude] = false
45
+ else
46
+ filters[:name_exclude] = true
47
+ filters[:name_select] = false
48
+ end
49
+ end
50
+
51
+ if name.present? && filters[:name_select].nil? && options[:select_by_name_regex].present?
52
+ filters[:name_select] = !!(name =~ /#{options[:select_by_name_regex]}/)
53
+ end
54
+
55
+ unless name.present? && filters[:name_exclude].nil? && options[:exclude_by_name_regex].present?
56
+ return
57
+ end
58
+
59
+ filters[:name_exclude] = !!(name =~ /#{options[:exclude_by_name_regex]}/)
60
+ end
61
+
62
+ def self.apply_shell_filters(options, filters, shell)
63
+ filters[:shell_expect] = shell == 'expect'
64
+
65
+ if shell.present? && options[:select_by_shell_regex].present?
66
+ filters[:shell_select] = !!(shell =~ /#{options[:select_by_shell_regex]}/)
67
+ end
68
+
69
+ return unless shell.present? && options[:exclude_by_shell_regex].present?
70
+
71
+ filters[:shell_exclude] = !!(shell =~ /#{options[:exclude_by_shell_regex]}/)
72
+ end
73
+
74
+ def self.apply_other_filters(options, filters, fcb)
75
+ name = fcb.fetch(:name, '')
76
+ shell = fcb.fetch(:shell, '')
77
+ filters[:fcb_chrome] = fcb.fetch(:chrome, false)
78
+
79
+ if name.present? && options[:hide_blocks_by_name] &&
80
+ options[:block_name_hidden_match].present?
81
+ filters[:hidden_name] = !!(name =~ /#{options[:block_name_hidden_match]}/)
82
+ end
83
+
84
+ if shell.present? && options[:hide_blocks_by_shell] &&
85
+ options[:block_shell_hidden_match].present?
86
+ !!(shell =~ /#{options[:block_shell_hidden_match]}/)
87
+ end
88
+
89
+ return unless options[:bash_only]
90
+
91
+ filters[:shell_default] = (shell == 'bash')
92
+ end
93
+
94
+ def self.evaluate_filters(options, filters)
95
+ if options[:no_chrome] && filters[:fcb_chrome]
96
+ false
97
+ elsif options[:exclude_expect_blocks] && filters[:shell_expect]
98
+ false
99
+ elsif filters[:hidden_name] == true
100
+ true
101
+ elsif filters[:name_exclude] == true || filters[:shell_exclude] == true || filters[:name_select] == false || filters[:shell_select] == false
102
+ false
103
+ elsif filters[:name_select] == true || filters[:shell_select] == true
104
+ true
105
+ elsif filters[:name_default] == false || filters[:shell_default] == false
106
+ false
107
+ else
108
+ true
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ if $PROGRAM_NAME == __FILE__
115
+ require 'minitest/autorun'
116
+
117
+ require_relative 'tap'
118
+ include Tap
119
+
120
+ class FilterTest < Minitest::Test
121
+ def test_no_chrome_condition
122
+ options = { no_chrome: true }
123
+ fcb = { chrome: true }
124
+ refute MarkdownExec::Filter.fcb_select?(options, fcb)
125
+ end
126
+
127
+ def test_exclude_expect_blocks_condition
128
+ options = { exclude_expect_blocks: true }
129
+ fcb = { shell: 'expect' }
130
+ refute MarkdownExec::Filter.fcb_select?(options, fcb)
131
+ end
132
+
133
+ def test_hidden_name_condition
134
+ options = { hide_blocks_by_name: true, block_name_hidden_match: 'hidden' }
135
+ fcb = { name: 'hidden_block' }
136
+ assert MarkdownExec::Filter.fcb_select?(options, fcb)
137
+ end
138
+
139
+ def test_name_exclude_condition
140
+ options = { block_name: 'test' }
141
+ fcb = { name: 'sample' }
142
+ refute MarkdownExec::Filter.fcb_select?(options, fcb)
143
+ end
144
+
145
+ def test_shell_exclude_condition
146
+ options = { exclude_by_shell_regex: 'exclude_this' }
147
+ fcb = { shell: 'exclude_this_shell' }
148
+ refute MarkdownExec::Filter.fcb_select?(options, fcb)
149
+ end
150
+
151
+ def test_name_select_condition
152
+ options = { select_by_name_regex: 'select' }
153
+ fcb = { name: 'select_this' }
154
+ assert MarkdownExec::Filter.fcb_select?(options, fcb)
155
+ end
156
+
157
+ def test_shell_select_condition
158
+ options = { select_by_shell_regex: 'select_this' }
159
+ fcb = { shell: 'select_this_shell' }
160
+ assert MarkdownExec::Filter.fcb_select?(options, fcb)
161
+ end
162
+
163
+ def test_bash_only_condition_true
164
+ options = { bash_only: true }
165
+ fcb = { shell: 'bash' }
166
+ assert MarkdownExec::Filter.fcb_select?(options, fcb)
167
+ end
168
+
169
+ def test_bash_only_condition_false
170
+ options = { bash_only: true }
171
+ fcb = { shell: 'zsh' }
172
+ refute MarkdownExec::Filter.fcb_select?(options, fcb)
173
+ end
174
+
175
+ def test_default_case
176
+ options = {}
177
+ fcb = {}
178
+ assert MarkdownExec::Filter.fcb_select?(options, fcb)
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,195 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+
6
+ require_relative 'filter'
7
+
8
+ module MarkdownExec
9
+ ##
10
+ # MarkdownBlockManager represents an imported markdown document.
11
+ #
12
+ # It provides methods to extract and manipulate specific sections
13
+ # of the document, such as code blocks. It also supports recursion
14
+ # to fetch related or dependent blocks.
15
+ #
16
+ class MarkdownBlockManager
17
+ attr_reader :block_table
18
+
19
+ def initialize(block_table)
20
+ @block_table = block_table
21
+ end
22
+
23
+ def collect_required_code(name)
24
+ gather_required_blocks(name)
25
+ .map do |block|
26
+ process_block_code(block)
27
+ end.flatten(1)
28
+ end
29
+
30
+ def get_block(name, default = {})
31
+ @block_table.select { |block| block.fetch(:name, '') == name }.fetch(0, default)
32
+ end
33
+
34
+ def gather_required_blocks(name)
35
+ named_block = get_block(name)
36
+ if named_block.nil? || named_block.keys.empty?
37
+ raise "Named code block `#{name}` not found."
38
+ end
39
+
40
+ all_blocks = [named_block.fetch(:name, '')] + required_blocks(named_block[:reqs])
41
+ @block_table.select { |block| all_blocks.include? block.fetch(:name, '') }
42
+ .map do |block|
43
+ process_block_references(block)
44
+ end.flatten(1)
45
+ end
46
+
47
+ def hide_block_given_options(opts, block)
48
+ (opts[:hide_blocks_by_name] &&
49
+ block[:name]&.match(Regexp.new(opts[:block_name_hidden_match])) &&
50
+ (block[:name]&.present? || block[:label]&.present?)
51
+ )
52
+ end
53
+
54
+ def blocks_per_options(opts = {})
55
+ filtered_blocks = @block_table.select do |block_group|
56
+ Filter.block_selected? opts, block_group
57
+ end
58
+ if opts[:hide_blocks_by_name]
59
+ filtered_blocks.reject { |block| hide_block_given_options opts, block }
60
+ else
61
+ filtered_blocks
62
+ end.map do |block|
63
+ block
64
+ end
65
+ end
66
+
67
+ def required_blocks(reqs)
68
+ return [] unless reqs
69
+
70
+ remaining = reqs
71
+ collected = []
72
+ while remaining.count.positive?
73
+ remaining = remaining.map do |req|
74
+ next if collected.include? req
75
+
76
+ collected += [req]
77
+ get_block(req).fetch(:reqs, [])
78
+ end
79
+ .compact
80
+ .flatten(1)
81
+ end
82
+ collected
83
+ end
84
+
85
+ # Helper method to process block code
86
+ def process_block_code(block)
87
+ body = block[:body].join("\n")
88
+
89
+ if block[:cann]
90
+ xcall = block[:cann][1..-2]
91
+ mstdin = xcall.match(/<(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
92
+ mstdout = xcall.match(/>(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
93
+
94
+ yqcmd = if mstdin[:type]
95
+ "echo \"$#{mstdin[:name]}\" | yq '#{body}'"
96
+ else
97
+ "yq e '#{body}' '#{mstdin[:name]}'"
98
+ end
99
+ if mstdout[:type]
100
+ "export #{mstdout[:name]}=$(#{yqcmd})"
101
+ else
102
+ "#{yqcmd} > '#{mstdout[:name]}'"
103
+ end
104
+ elsif block[:stdout]
105
+ stdout = block[:stdout]
106
+ body = block[:body].join("\n")
107
+ if stdout[:type]
108
+ %(export #{stdout[:name]}=$(cat <<"EOF"\n#{body}\nEOF\n))
109
+ else
110
+ "cat > '#{stdout[:name]}' <<\"EOF\"\n" \
111
+ "#{body}\n" \
112
+ "EOF\n"
113
+ end
114
+ else
115
+ block[:body]
116
+ end
117
+ end
118
+
119
+ # Helper method to process block references
120
+ def process_block_references(block)
121
+ if (call = block[:call])
122
+ [get_block("[#{call.match(/^%\((\S+) |\)/)[1]}]")
123
+ .merge({ cann: call })]
124
+ else
125
+ []
126
+ end + [block]
127
+ end
128
+ end
129
+ end
130
+
131
+ if $PROGRAM_NAME == __FILE__
132
+ # require 'bundler/setup'
133
+ # Bundler.require(:default)
134
+
135
+ require 'minitest/autorun'
136
+
137
+ require_relative 'tap'
138
+ include Tap
139
+
140
+ module MarkdownExec
141
+ class TestMDoc < Minitest::Test
142
+ def setup
143
+ @table = [
144
+ { name: 'block1', body: ['code for block1'], reqs: ['block2'] },
145
+ { name: 'block2', body: ['code for block2'], reqs: nil },
146
+ { name: 'block3', body: ['code for block3'], reqs: ['block1'] }
147
+ ]
148
+ @doc = MDoc.new(@table)
149
+ end
150
+
151
+ def test_collect_recursively_required_code
152
+ result = @doc.collect_recursively_required_code('block1')
153
+ expected_result = @table[0][:body] + @table[1][:body]
154
+ assert_equal expected_result, result
155
+ end
156
+
157
+ def test_get_block_by_name
158
+ result = @doc.get_block_by_name('block1')
159
+ assert_equal @table[0], result
160
+
161
+ result_missing = @doc.get_block_by_name('missing_block')
162
+ assert_equal({}, result_missing)
163
+ end
164
+
165
+ def test_get_required_blocks
166
+ result = @doc.get_required_blocks('block3')
167
+ expected_result = [@table[0], @table[1], @table[2]]
168
+ assert_equal expected_result, result
169
+
170
+ assert_raises(RuntimeError) { @doc.get_required_blocks('missing_block') }
171
+ end
172
+
173
+ def test_hide_menu_block_per_options
174
+ opts = { hide_blocks_by_name: true, block_name_hidden_match: 'block1' }
175
+ block = { name: 'block1' }
176
+ result = @doc.hide_menu_block_per_options(opts, block)
177
+ assert result # this should be true based on the given logic
178
+ end
179
+
180
+ def test_fcbs_per_options
181
+ opts = { hide_blocks_by_name: true, block_name_hidden_match: 'block1' }
182
+ result = @doc.fcbs_per_options(opts)
183
+ assert_equal [@table[1], @table[2]], result
184
+ end
185
+
186
+ def test_recursively_required
187
+ result = @doc.recursively_required(['block3'])
188
+ assert_equal %w[block3 block1 block2], result
189
+
190
+ result_no_reqs = @doc.recursively_required(nil)
191
+ assert_equal [], result_no_reqs
192
+ end
193
+ end
194
+ end
195
+ end
@@ -7,5 +7,5 @@ module MarkdownExec
7
7
  BIN_NAME = 'mde'
8
8
  GEM_NAME = 'markdown_exec'
9
9
  TAP_DEBUG = 'MDE_DEBUG'
10
- VERSION = '1.3.3.4'
10
+ VERSION = '1.3.6'
11
11
  end