mini-cli 0.3.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6954edd798ee19570124490d3c139443e54cf9db86da1cbf5e1ecf053f5b4de6
4
- data.tar.gz: e9c458ab08eb813875df22053ce3c5fd99c651bbe24f60d787a6d0968936d204
3
+ metadata.gz: 287658b0aa4ac5340cde3aced9e0a411ed6504713c18505706ad741c7c966a8b
4
+ data.tar.gz: 7b6c95ddc87554a011c3f28355f3e181a7be249432d906861a92092978f5b22b
5
5
  SHA512:
6
- metadata.gz: ad9884fa0f18600b69212a8f3b3c36108838d510879cde3d2a4525009439a3574c8eae1d7d7d4b567647fce04aa5cfaeee3fdceec8529381defc2533c1166559
7
- data.tar.gz: 287198992331abcd2fee44165775cad3a6905c15eb1fac71bee380d706ba5f2067b3b2d3498f9a7bc4f07fe92c447e417c854313b247f0b81db304f0810a582b
6
+ metadata.gz: 2fa1fb33a71928b5fea02349709ba6191992b5375b690a8b39fe8dcb8b932932abe61f02135ca747bf729c0ed758276f7d9b3f41f42a2db1f128ee56eeda1bcb
7
+ data.tar.gz: fb7397ede3cf0f0265dbafd47ef4e070153a37e3afdf5a583b68ea95dd4482e7c54522af941bdba45680ab195e0b305b286bac1c241e27b741162bb28822fcb2
data/lib/mini-cli/run.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require('shellwords')
4
+
3
5
  module MiniCli
4
6
  def run(*cmd, stdin_data: nil, status: false, chdir: nil)
5
7
  in_read, in_write = IO.pipe
@@ -14,6 +16,14 @@ module MiniCli
14
16
  in_write&.close
15
17
  end
16
18
 
19
+ def run_ruby(*cmd, **run_options)
20
+ run(Shellwords.join(__ruby_cmd + cmd), **run_options)
21
+ end
22
+
23
+ def run_script(script, status: false, chdir: nil)
24
+ run_ruby(stdin_data: script, status: status, chdir: chdir)
25
+ end
26
+
17
27
  private
18
28
 
19
29
  def __run_proc(stdin_data, in_write)
@@ -29,4 +39,13 @@ module MiniCli
29
39
  out.read
30
40
  end
31
41
  end
42
+
43
+ def __ruby_cmd
44
+ [
45
+ RbConfig.ruby,
46
+ '--disable=gems',
47
+ '--disable=did_you_mean',
48
+ '--disable=rubyopt'
49
+ ]
50
+ end
32
51
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniCli
4
- VERSION = '0.3.0'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/mini-cli.rb CHANGED
@@ -2,8 +2,11 @@
2
2
 
3
3
  module MiniCli
4
4
  def self.included(mod)
5
- source = caller_locations(1, 1).first.absolute_path
6
- mod.const_set(:MiniCli__, Instance.new(source))
5
+ mod.const_set(
6
+ :MiniCli__,
7
+ Instance.new(caller_locations(1, 1).first.absolute_path)
8
+ )
9
+ mod.private_constant(:MiniCli__)
7
10
  end
8
11
 
9
12
  def name(name = nil)
@@ -26,50 +29,68 @@ module MiniCli
26
29
  __minicli__.show_errors = value ? true : false
27
30
  end
28
31
 
32
+ def error_code
33
+ __minicli__.error_code
34
+ end
35
+
29
36
  def error(code, message = nil)
30
37
  $stderr.puts("#{name}: #{message}") if message && show_errors?
31
- exit(code)
38
+ exit(__minicli__.error_code = code)
32
39
  end
33
40
 
34
41
  def parse_argv(argv = nil, &argv_converter)
35
42
  return __minicli__.converter = argv_converter if argv_converter
36
- argv ||= ARGV.dup
43
+ argv = Array.new(argv || ARGV)
37
44
  exit(show_help) if argv.index('--help') || argv.index('-h')
38
- __minicli__.convert(__minicli__.parse(argv, method(:error).to_proc))
45
+ __minicli__.main(argv, method(:error).to_proc)
39
46
  end
40
47
 
41
- def main(args = nil)
42
- at_exit do
43
- yield(args || parse_argv)
48
+ def main
49
+ __minicli__.run do
50
+ yield(parse_argv)
44
51
  rescue Interrupt
45
52
  error(130, 'aborted')
46
53
  end
47
54
  end
48
55
 
56
+ def before(&callback)
57
+ callback and __minicli__.before << callback
58
+ end
59
+
60
+ def after(&callback)
61
+ callback and __minicli__.after << callback
62
+ end
63
+
49
64
  private
50
65
 
51
66
  def __minicli__
52
- self.class::MiniCli__
67
+ self.class.const_get(:MiniCli__)
53
68
  end
54
69
 
55
70
  class Instance
56
71
  attr_reader :source
57
72
  attr_writer :converter
58
- attr_accessor :show_errors
73
+ attr_accessor :show_errors, :before, :after, :error_code
59
74
 
60
75
  def initialize(source)
61
76
  @source = source
62
77
  @name = File.basename(source, '.*')
63
- @parser = @converter = nil
78
+ @converter = @main_proc = nil
79
+ @parser = ArgvParser.new('', [])
80
+ @before = []
81
+ @after = []
64
82
  @show_errors = true
83
+ @before_ok = false
84
+ @error_code = 0
85
+ init_main
65
86
  end
66
87
 
67
- def name(name = nil)
88
+ def name(name)
68
89
  name ? @name = name.to_s : @name
69
90
  end
70
91
 
71
- def help(helptext, args)
72
- @parser = ArgvParser.new(helptext, args)
92
+ def help(*args)
93
+ @parser = ArgvParser.new(*args)
73
94
  end
74
95
 
75
96
  def show_help
@@ -77,18 +98,35 @@ module MiniCli
77
98
  true
78
99
  end
79
100
 
80
- def parse(argv, error)
81
- parser.parse(argv, error)
101
+ def run(&main_proc)
102
+ @main_proc = main_proc
82
103
  end
83
104
 
84
- def convert(args)
105
+ def main(argv, error)
106
+ @before.each(&:call)
107
+ @before_ok = true
108
+ args = parser.parse(argv, error)
85
109
  @converter ? @converter.call(args) || args : args
86
110
  end
87
111
 
88
112
  private
89
113
 
90
- def parser
91
- @parser ||= ArgvParser.new(nil, [])
114
+ attr_reader :parser
115
+
116
+ def init_main
117
+ at_exit do
118
+ next if $! and not ($!.kind_of?(SystemExit) and $!.success?)
119
+ shutdown unless @after.empty?
120
+ @main_proc&.call
121
+ end
122
+ end
123
+
124
+ def shutdown(pid = Process.pid)
125
+ at_exit do
126
+ next if Process.pid != pid
127
+ @after.reverse_each(&:call) if @before_ok
128
+ exit(@error_code)
129
+ end
92
130
  end
93
131
 
94
132
  class ArgvParser
@@ -96,16 +134,17 @@ module MiniCli
96
134
  @helptext = helptext.to_s
97
135
  @args = args.flatten.map!(&:to_s).uniq
98
136
  @options = nil
137
+ @show_options_text = true
99
138
  end
100
139
 
101
140
  def show_help(name)
102
141
  parse_help! unless @options
103
142
  print("Usage: #{name}")
104
- print(' [OPTIONS]') unless @options.empty?
143
+ print(' [<options>]') unless @options.empty?
105
144
  print(' ', @args.join(' ')) unless @args.empty?
106
145
  puts
107
- puts(nil, 'Options:') unless @options.empty?
108
- puts(@helptext) unless @helptext.empty?
146
+ puts(nil, 'Options:') if @show_options_text
147
+ puts(@helptext.gsub('<*name*>', name)) unless @helptext.empty?
109
148
  end
110
149
 
111
150
  def parse(argv, error)
@@ -116,13 +155,16 @@ module MiniCli
116
155
 
117
156
  private
118
157
 
158
+ def error(msg)
159
+ @error[1, msg]
160
+ end
161
+
119
162
  def parse_argv(argv)
120
163
  arguments = []
121
164
  while (arg = argv.shift)
122
165
  case arg
123
166
  when '--'
124
- arguments += argv
125
- break
167
+ break arguments += argv
126
168
  when /\A--([[[:alnum:]]-]+)\z/
127
169
  handle_option(Regexp.last_match[1], argv)
128
170
  when /\A-([[:alnum:]]+)\z/
@@ -134,10 +176,6 @@ module MiniCli
134
176
  arguments
135
177
  end
136
178
 
137
- def error(msg)
138
- @error[1, msg]
139
- end
140
-
141
179
  def process(arguments)
142
180
  @args.each do |arg|
143
181
  process_arg(arg, arguments.shift) unless arg.index('..')
@@ -148,33 +186,38 @@ module MiniCli
148
186
  end
149
187
 
150
188
  def process_arg(arg, value)
151
- if arg.start_with?('[')
152
- @result[arg[1..-2]] = value if value
189
+ if arg[0] == '[' && arg[-1] == ']'
190
+ return unless value
191
+ arg = arg[1..-2]
153
192
  else
154
- @result[arg] = value || error("parameter expected - #{arg}")
193
+ error("parameter expected - #{arg}") unless value
155
194
  end
195
+ @result[(arg[0] == '<' && arg[-1] == '>') ? arg[1..-2] : arg] = value
156
196
  end
157
197
 
158
- def handle_option(option, argv, test = ->(k) { option == k })
159
- key = @options[option] || error("unknown option - #{option}")
160
- @result[key] = test[key] and return
198
+ def handle_option(option, argv, pref = '-')
199
+ key = @options[option] || error("unknown option - #{pref}-#{option}")
200
+ return @result[key[1..-1]] = true if key[0] == '!'
161
201
  @result[key] = value = argv.shift
162
- return unless value.nil? || value.start_with?('-')
163
- error("parameter #{key} expected - --#{option}")
202
+ return unless value.nil? || value[0] == '-'
203
+ error("parameter <#{key}> expected - #{pref}-#{option}")
164
204
  end
165
205
 
166
206
  def parse_options(options, argv)
167
- test = ->(k) { k == k.downcase }
168
- options.each_char { |opt| handle_option(opt, argv, test) }
207
+ options.each_char { |opt| handle_option(opt, argv, nil) }
169
208
  end
170
209
 
171
210
  def parse_help!
172
211
  @options = {}
173
212
  @helptext.each_line do |line|
174
213
  case line
175
- when /-([[:alnum:]]), --([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/
214
+ when /Options:$/
215
+ @show_options_text = false
216
+ when /-([[:alnum:]]), --([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/,
217
+ /-([[:alnum:]]), --([[[:alnum:]]-]+) \<([[:lower:]]+)\>\s+\S+/
176
218
  option_with_argument(Regexp.last_match)
177
- when /--([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/
219
+ when /--([[[:alnum:]]-]+) ([[:upper:]]+)\s+\S+/,
220
+ /--([[[:alnum:]]-]+) \<([[:lower:]]+)\>\s+\S+/
178
221
  short_option_with_argument(Regexp.last_match)
179
222
  when /-([[:alnum:]]), --([[[:alnum:]]-]+)\s+\S+/
180
223
  option(Regexp.last_match)
@@ -182,6 +225,7 @@ module MiniCli
182
225
  short_option(Regexp.last_match)
183
226
  end
184
227
  end
228
+ @show_options_text &= !@options.empty?
185
229
  end
186
230
 
187
231
  def option_with_argument(match)
@@ -193,11 +237,11 @@ module MiniCli
193
237
  end
194
238
 
195
239
  def option(match)
196
- @options[match[1]] = @options[match[2]] = match[2]
240
+ @options[match[1]] = @options[match[2]] = "!#{match[2]}"
197
241
  end
198
242
 
199
243
  def short_option(match)
200
- @options[match[1]] = match[1]
244
+ @options[match[1]] = "!#{match[1]}"
201
245
  end
202
246
  end
203
247
  end
data/mini-cli.gemspec CHANGED
@@ -2,30 +2,30 @@
2
2
 
3
3
  require_relative './lib/mini-cli/version'
4
4
 
5
- GemSpec = Gem::Specification.new do |gem|
6
- gem.name = 'mini-cli'
7
- gem.version = MiniCli::VERSION
8
- gem.summary = 'The lean CLI framework for Ruby'
9
- gem.description = <<~DESC
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'mini-cli'
7
+ spec.version = MiniCli::VERSION
8
+ spec.required_ruby_version = '>= 2.5.0'
9
+
10
+ spec.summary = 'The lean CLI framework for Ruby'
11
+ spec.description = <<~DESC
10
12
  This gem is a lean, easy to use CLI framework with a very small footprint.
11
13
  It provides an easy to use argument parsing, help displaying and
12
14
  minimalistic error handling.
13
15
  DESC
14
- gem.author = 'Mike Blumtritt'
15
- gem.homepage = 'https://github.com/mblumtritt/mini-cli'
16
- gem.metadata = {
17
- 'source_code_uri' => 'https://github.com/mblumtritt/mini-cli',
18
- 'bug_tracker_uri' => 'https://github.com/mblumtritt/mini-cli/issues'
19
- }
20
16
 
21
- gem.required_ruby_version = '>= 2.5.0'
17
+ spec.author = 'Mike Blumtritt'
18
+ spec.homepage = 'https://github.com/mblumtritt/mini-cli'
19
+ spec.metadata['source_code_uri'] = 'https://github.com/mblumtritt/mini-cli'
20
+ spec.metadata['bug_tracker_uri'] =
21
+ 'https://github.com/mblumtritt/mini-cli/issues'
22
22
 
23
- gem.add_development_dependency 'bundler'
24
- gem.add_development_dependency 'minitest'
25
- gem.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'minitest'
25
+ spec.add_development_dependency 'rake'
26
26
 
27
- all_files = %x(git ls-files -z).split(0.chr)
28
- gem.test_files = all_files.grep(%r{^(spec|test)/})
29
- gem.files = all_files - gem.test_files
30
- gem.extra_rdoc_files = %w[README.md]
27
+ all_files = Dir.chdir(__dir__) { `git ls-files -z`.split(0.chr) }
28
+ spec.test_files = all_files.grep(%r{^(spec|test)/})
29
+ spec.files = all_files - spec.test_files
30
+ spec.extra_rdoc_files = %w[README.md]
31
31
  end
data/rakefile.rb CHANGED
@@ -3,13 +3,11 @@
3
3
  require 'rake/testtask'
4
4
  require 'bundler/gem_tasks'
5
5
 
6
- STDOUT.sync = STDERR.sync = true
6
+ $stdout.sync = $stderr.sync = true
7
7
 
8
- CLOBBER << 'prj'
8
+ task(:default) { exec('rake --tasks') }
9
9
 
10
- task :default do
11
- exec "#{$PROGRAM_NAME} --tasks"
12
- end
10
+ CLOBBER << 'prj'
13
11
 
14
12
  Rake::TestTask.new(:test) do |t|
15
13
  t.ruby_opts = %w[-w]
@@ -4,25 +4,34 @@ require_relative '../lib/mini-cli'
4
4
 
5
5
  include MiniCli
6
6
 
7
- help <<~HELP, %w[TARGET [SOURCE]]
8
- -n, --name NAME option requires NAME argument, has shortcut
9
- --url URL option requires URL argument
10
- -s, --switch option without any argument, has shortcut
11
- --opt option without any argument
7
+ help <<~HELP, %w[<target> [<source>]]
8
+
9
+ Demonstration of converting arguments to a custom argument class.
10
+
11
+ Options:
12
+ -n, --name <name> option requires <name> argument, has shortcut
13
+ --url <url> option requires <url> argument
14
+ -s, --switch option without any argument, has shortcut
15
+ --opt option without any argument
12
16
  HELP
13
17
 
14
18
  main { |cfg| cfg.each_pair { |key, value| puts("#{key}: #{value}") } }
15
19
 
16
20
  parse_argv do |args|
17
- Struct.new(:target, :sources, :name, :url, :switch, :opt).new.tap do |cfg|
18
- cfg.target = args['TARGET']
19
- cfg.sources = args['FILES'] # args['FILES'] is an array containing all surplus arguments
20
- source = args['SOURCE'] || ENV['SOURCE']
21
- cfg.sources.unshift(source) if source
22
- cfg.sources << 'STDIN' if cfg.sources.empty?
23
- cfg.name = args['NAME'] || 'default_name'
24
- cfg.url = args['URL'] || 'www.url.test'
25
- cfg.switch = args.key?('switch')
26
- cfg.opt = args.key?('opt')
27
- end
21
+ # args['FILES'] is an array containing all surplus arguments
22
+ Struct
23
+ .new(:target, :sources, :name, :url, :switch, :opt)
24
+ .new(
25
+ args['target'],
26
+ args['FILES'],
27
+ args['name'] || 'default_name',
28
+ args['url'] || 'www.url.test',
29
+ args.key?('switch'),
30
+ args.key?('opt')
31
+ )
32
+ .tap do |cfg|
33
+ source = args['source'] || ENV['SOURCE']
34
+ cfg.sources.unshift(source) if source
35
+ cfg.sources << 'STDIN' if cfg.sources.empty?
36
+ end
28
37
  end
data/samples/demo.rb CHANGED
@@ -4,18 +4,24 @@ require_relative '../lib/mini-cli'
4
4
 
5
5
  include MiniCli
6
6
 
7
- help <<~HELP, %w[TARGET [SOURCE]]
8
- -n, --name NAME option requires NAME argument, has shortcut
9
- --url URL option requires URL argument
10
- -s, --switch option without any argument, has shortcut
11
- --opt option without any argument
7
+ help <<~HELP, %w[<target> [<source>]]
8
+
9
+ Demonstration of general Mini-CLI behavior.
10
+
11
+ Options:
12
+ -n, --name <name> option requires <name> argument, has shortcut
13
+ --url <url> option requires <url> argument
14
+ -s, --switch option without any argument, has shortcut
15
+ --opt option without any argument
16
+
17
+ Try to call this <*name*> command with various options and arguments.
12
18
  HELP
13
19
 
14
20
  main do |args|
15
- puts("TARGET: #{args['TARGET']}")
16
- puts("SOURCE: #{args['SOURCE']}") if args.key?('SOURCE')
17
- puts("NAME: #{args['NAME']}") if args.key?('NAME')
18
- puts("URL: #{args['URL']}") if args.key?('URL')
21
+ puts("target: #{args['target']}")
22
+ puts("source: #{args['source']}") if args.key?('source')
23
+ puts("name: #{args['name']}") if args.key?('name')
24
+ puts("url: #{args['url']}") if args.key?('url')
19
25
  puts("FILES: #{args['FILES']}") unless args['FILES'].empty?
20
26
  puts('--switch was given') if args.key?('switch')
21
27
  puts('--opt was given') if args.key?('opt')
data/test/apps/noop.rb ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ # completely empty command
3
+
4
+ require_relative '../../lib/mini-cli'
5
+ include(MiniCli)
6
+ main {}
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # demonstrates the call sequence
3
+
4
+ require_relative '../../lib/mini-cli'
5
+ include(MiniCli)
6
+
7
+ help <<~HELP
8
+ -x, --exit early exit
9
+ -e, --error exit with error
10
+ HELP
11
+
12
+ main do |*args|
13
+ puts('main' + args.inspect)
14
+ exit if args.first['exit']
15
+ error(42, '!error!') if args.first['error']
16
+ end
17
+
18
+ before { |*args| puts('before_1' + args.inspect) }
19
+ after { |*args| puts('after_1' + args.inspect) }
20
+ before { |*args| puts('before_2' + args.inspect) }
21
+ after { |*args| puts('after_2' + args.inspect) }
22
+
23
+ parse_argv do |*args|
24
+ puts('parse_argv' + args.inspect)
25
+ args.first
26
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'shellwords'
5
+ require_relative '../helper'
6
+
7
+ class ExecTest < Minitest::Test
8
+ def test_noop
9
+ assert_empty(assert_no_err('noop.rb'))
10
+ end
11
+
12
+ def test_noop_help
13
+ assert_equal("Usage: noop\n", assert_no_err('noop.rb', '--help'))
14
+ end
15
+
16
+ def test_sequence
17
+ expected = [
18
+ 'before_1[]',
19
+ 'before_2[]',
20
+ "parse_argv[{\"FILES\"=>[]}]",
21
+ "main[{\"FILES\"=>[]}]",
22
+ 'after_2[]',
23
+ 'after_1[]'
24
+ ]
25
+ assert_equal(expected, assert_no_err('sequence.rb').split("\n"))
26
+ end
27
+
28
+ def test_sequence_help
29
+ expected = [
30
+ 'Usage: sequence [<options>]',
31
+ '',
32
+ 'Options:',
33
+ '-x, --exit early exit',
34
+ '-e, --error exit with error'
35
+ ]
36
+ assert_equal(expected, assert_no_err('sequence.rb', '--help').split("\n"))
37
+ end
38
+
39
+ def test_sequence_early_exit
40
+ expected = [
41
+ 'before_1[]',
42
+ 'before_2[]',
43
+ "parse_argv[{\"exit\"=>true, \"FILES\"=>[]}]",
44
+ "main[{\"exit\"=>true, \"FILES\"=>[]}]",
45
+ 'after_2[]',
46
+ 'after_1[]'
47
+ ]
48
+ assert_equal(expected, assert_no_err('sequence.rb', '-x').split("\n"))
49
+ end
50
+
51
+ def test_sequence_error
52
+ expected = [
53
+ 'before_1[]',
54
+ 'before_2[]',
55
+ "parse_argv[{\"error\"=>true, \"FILES\"=>[]}]",
56
+ "main[{\"error\"=>true, \"FILES\"=>[]}]",
57
+ 'after_2[]',
58
+ 'after_1[]'
59
+ ]
60
+ std, err, status = invoke('sequence.rb', '-e')
61
+ assert_same(42, status.exitstatus)
62
+ assert_equal("sequence: !error!\n", err)
63
+ assert_equal(expected, std.split("\n"))
64
+ end
65
+
66
+ def assert_no_err(...)
67
+ std, err = assert_success(...)
68
+ assert_empty(err)
69
+ std
70
+ end
71
+
72
+ def assert_success(...)
73
+ std, err, status = invoke(...)
74
+ assert(status.success?)
75
+ return std, err
76
+ end
77
+
78
+ def invoke(name, *args)
79
+ Open3.capture3(
80
+ Shellwords.join(
81
+ [
82
+ RbConfig.ruby,
83
+ '--disable',
84
+ 'gems',
85
+ '--disable',
86
+ 'did_you_mean',
87
+ '--disable',
88
+ 'rubyopt',
89
+ File.expand_path("../apps/#{name}", __dir__)
90
+ ] + args
91
+ )
92
+ )
93
+ end
94
+ end
@@ -13,12 +13,17 @@ class MainTest < Test
13
13
  subject = Class.new { include MiniCli }.new
14
14
 
15
15
  expected_methods = %i[
16
+ after
17
+ before
16
18
  error
19
+ error_code
17
20
  help
18
21
  main
19
22
  name
20
23
  parse_argv
21
24
  run
25
+ run_ruby
26
+ run_script
22
27
  show_errors=
23
28
  show_errors?
24
29
  show_help
@@ -176,4 +181,13 @@ class MainTest < Test
176
181
  result = subject.parse_argv(as_argv('-nup name port in out opt file'))
177
182
  assert_equal(expected, result)
178
183
  end
184
+
185
+ def test_run
186
+ call_sequence = []
187
+ subject.main { call_sequence << :main }
188
+ subject.before { call_sequence << :start_1 }
189
+ subject.after { call_sequence << :end_1 }
190
+ subject.before { call_sequence << :start_2 }
191
+ subject.after { call_sequence << :end_2 }
192
+ end
179
193
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helper'
4
+
5
+ class RubyRunTest < Test
6
+ def test_simple
7
+ result = subject.run_script('puts("Hello World")')
8
+ assert_equal("Hello World\n", result)
9
+ end
10
+
11
+ def test_error
12
+ result = subject.run_script('UNDEFINED')
13
+ assert_match(/NameError/, result)
14
+ end
15
+
16
+ def test_chdir
17
+ home = Dir.home
18
+ refute(home == Dir.pwd)
19
+ result = subject.run_script('print Dir.pwd', chdir: home)
20
+ assert_equal(home, result)
21
+ end
22
+
23
+ def test_status
24
+ status, result = subject.run_script('print :Ok', status: true)
25
+ assert_instance_of(Process::Status, status)
26
+ assert(status.success?)
27
+ assert_equal('Ok', result)
28
+ end
29
+
30
+ def test_status_error
31
+ status, result = subject.run_script('print :Err;exit 42', status: true)
32
+ assert_instance_of(Process::Status, status)
33
+ refute(status.success?)
34
+ assert_same(42, status.exitstatus)
35
+ assert_equal('Err', result)
36
+ end
37
+
38
+ def test_stream
39
+ stream = StringIO.new('puts "Hello World"')
40
+ result = subject.run_script(stream)
41
+ assert_equal("Hello World\n", result)
42
+ end
43
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-20 00:00:00.000000000 Z
11
+ date: 2021-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -74,8 +74,12 @@ files:
74
74
  - samples/custom_args.rb
75
75
  - samples/demo.rb
76
76
  - samples/simple.rb
77
+ - test/apps/noop.rb
78
+ - test/apps/sequence.rb
77
79
  - test/helper.rb
80
+ - test/mini-cli/exec_test.rb
78
81
  - test/mini-cli/main_test.rb
82
+ - test/mini-cli/ruby_run_test.rb
79
83
  - test/mini-cli/run_test.rb
80
84
  homepage: https://github.com/mblumtritt/mini-cli
81
85
  licenses: []
@@ -97,11 +101,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
101
  - !ruby/object:Gem::Version
98
102
  version: '0'
99
103
  requirements: []
100
- rubygems_version: 3.1.4
104
+ rubygems_version: 3.2.28
101
105
  signing_key:
102
106
  specification_version: 4
103
107
  summary: The lean CLI framework for Ruby
104
108
  test_files:
109
+ - test/apps/noop.rb
110
+ - test/apps/sequence.rb
105
111
  - test/helper.rb
112
+ - test/mini-cli/exec_test.rb
106
113
  - test/mini-cli/main_test.rb
114
+ - test/mini-cli/ruby_run_test.rb
107
115
  - test/mini-cli/run_test.rb