optparse-lite 0.0.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.
- data/NEWS.md +4 -0
- data/README +37 -0
- data/Rakefile +57 -0
- data/VERSION +1 -0
- data/doc/high-concept.md +436 -0
- data/doc/high-concept/terms.md +23 -0
- data/doc/installation.md +29 -0
- data/doc/svg/not-funny.svg +24 -0
- data/doc/usage.md +240 -0
- data/lib/optparse-lite.rb +982 -0
- data/lib/optparse-lite/test/gentest/gentest.rb +322 -0
- data/lib/optparse-lite/test/gentest/tasklib.rb +12 -0
- data/lib/optparse-lite/test/gentest/tasks.rb +14 -0
- data/lib/optparse-lite/test/gentest/tasks/gentest.rb +44 -0
- data/lib/optparse-lite/test/gentest/tasks/ungen.rb +64 -0
- data/lib/optparse-lite/test/nandoc-custom-tags.rb +6 -0
- data/lib/optparse-lite/test/nandoc-custom-tags/app.rb +102 -0
- data/lib/optparse-lite/test/nandoc-custom-tags/playback.rb +63 -0
- data/lib/optparse-lite/test/setup.rb +131 -0
- data/lib/optparse-lite/treebis-extlib.rb +5 -0
- data/test/test.rb +963 -0
- metadata +87 -0
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'syntax/convertors/html'
|
2
|
+
module OptparseLite
|
3
|
+
class AppTag < ::NanDoc::Filters::CustomTag
|
4
|
+
::NanDoc::Filters::CustomTags.register_class(self)
|
5
|
+
include NanDoc::SpecDoc::Playback::Terminal::ColorToHtml
|
6
|
+
include NanDoc::StringMethods # module_basename
|
7
|
+
ColorizeRuby = ::Syntax::Convertors::HTML.for_syntax('ruby')
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def =~ whole_file
|
11
|
+
/\(see: test[^ ]*\.rb - app - ["']/ =~ whole_file
|
12
|
+
end
|
13
|
+
end
|
14
|
+
def name
|
15
|
+
'optparse lite custom tag - app'
|
16
|
+
end
|
17
|
+
def run content
|
18
|
+
numetal = content.gsub(
|
19
|
+
/\(see: (test[^ ]*\.rb) - app - ["']([^"']+)["'](.*)\)/
|
20
|
+
) do
|
21
|
+
show_app_code($1, $2, $3)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
def tag_parser
|
25
|
+
TagParser.new
|
26
|
+
end
|
27
|
+
def show_app_code testfile, label, rest
|
28
|
+
opts = parse_rest_assert(rest)
|
29
|
+
NanDoc::Project.instance.require_test_file testfile
|
30
|
+
recs = NanDoc::SpecDoc::Recordings.get_for_key(:generic)
|
31
|
+
scn = NanDoc::SpecDoc::Playback::SexpScanner.new(recs)
|
32
|
+
scn.skip_to_after_assert :story, label
|
33
|
+
aa = scn.offset
|
34
|
+
scn.skip_to_after_assert :story_stop
|
35
|
+
bb = scn.offset - 2
|
36
|
+
these = scn.sexp[aa..bb]
|
37
|
+
meth = NanDoc::SpecDoc::Playback::Method.new
|
38
|
+
doc = NanDoc::Html::Tags.new
|
39
|
+
html_opts = opts[:epilogue] ? {} : opts # hack
|
40
|
+
doc.push_smart 'pre', 'ruby', '', html_opts
|
41
|
+
# the below is written inline in the tests, because we can
|
42
|
+
# if opts[:prologue]
|
43
|
+
# code = "#!/usr/bin/env ruby\n\n"
|
44
|
+
# doc.push_smart('pre','ruby', code) # no colorize!
|
45
|
+
# end
|
46
|
+
meth.run_sexp doc, these
|
47
|
+
if opts[:epilogue]
|
48
|
+
# scan back
|
49
|
+
j = scn.offset - 1
|
50
|
+
j -=1 while scn.sexp[j] && scn.sexp[j][0] != :optparse_app_module
|
51
|
+
if ! scn.sexp[j]
|
52
|
+
fail("primus sucks")
|
53
|
+
end
|
54
|
+
mod = scn.sexp[j][1]
|
55
|
+
use_mod = module_basename(mod)
|
56
|
+
ruby = "\n#{use_mod}.run"
|
57
|
+
doc.content.push "<br />"<<ColorizeRuby.convert(ruby, false)
|
58
|
+
end
|
59
|
+
html = doc.to_html
|
60
|
+
html
|
61
|
+
end
|
62
|
+
private
|
63
|
+
def parse_rest_assert str
|
64
|
+
return {} if str == ""
|
65
|
+
/\A - (.+)\Z/ =~ str or fail("can't parse rest: #{str.inspect}")
|
66
|
+
things = {}
|
67
|
+
case $1
|
68
|
+
when 'full'; things[:prologue] = true; things[:epilogue] = true;
|
69
|
+
else
|
70
|
+
things = JSON.parse($1) or fail("wanted json had: #{$1.inspect}")
|
71
|
+
end
|
72
|
+
things
|
73
|
+
end
|
74
|
+
end
|
75
|
+
class AppTag
|
76
|
+
class TagParser < ::NanDoc::Filters::CustomTag::TagParser
|
77
|
+
Symbols = {
|
78
|
+
:start => :path,
|
79
|
+
:path => {
|
80
|
+
:re => /[-\/_a-z0-9]*(?:test|spec)[-_a-z0-9]*\.rb/,
|
81
|
+
:desc => "test file path",
|
82
|
+
:next => [:sep, :app_keyword]
|
83
|
+
},
|
84
|
+
:sep => {
|
85
|
+
:re => / *(?:-|\/) */,
|
86
|
+
:desc => "separator {-|\\/}",
|
87
|
+
:no_sexp => true
|
88
|
+
},
|
89
|
+
:app_keyword => {
|
90
|
+
:re => /app\b/,
|
91
|
+
:desc => "'app' keyword",
|
92
|
+
:next => [:sep, :more_token]
|
93
|
+
},
|
94
|
+
:more_token => {
|
95
|
+
:desc => "open token (\"foo\" or \"'foo'\" or '\"foo\"')",
|
96
|
+
:re => /'[^']*'|"[^"]"|[^[:space:]]+/,# yeah we're not etc..
|
97
|
+
:next => Or[ :end, [:sep, :more_token] ]
|
98
|
+
}
|
99
|
+
}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
module OptparseLite
|
4
|
+
class PlaybackTag < ::NanDoc::Filters::CustomTag
|
5
|
+
::NanDoc::Filters::CustomTags.register_class(self)
|
6
|
+
include NanDoc::SpecDoc::Playback::Terminal::ColorToHtml
|
7
|
+
include NanDoc::StringMethods
|
8
|
+
include Nanoc3::Helpers::HTMLEscape
|
9
|
+
class << self
|
10
|
+
def =~ whole_file
|
11
|
+
/\(see: test[^ ]*\.rb - playback - ["']/ =~ whole_file
|
12
|
+
end
|
13
|
+
end
|
14
|
+
def name
|
15
|
+
'optparse lite custom tag - playback'
|
16
|
+
end
|
17
|
+
def run content
|
18
|
+
numetal = content.gsub(
|
19
|
+
/\(see: (test[^ ]*\.rb) - playback - ["']([^"']+)["'](?: - (.+))?\)/
|
20
|
+
) do
|
21
|
+
html = show_playback($1, $2, $3)
|
22
|
+
html
|
23
|
+
end
|
24
|
+
numetal
|
25
|
+
end
|
26
|
+
def show_playback testfile, testname, xtra
|
27
|
+
opts =
|
28
|
+
if xtra
|
29
|
+
JSON.parse(xtra) or fail("failed to parse json: #{xtra}")
|
30
|
+
else
|
31
|
+
{}
|
32
|
+
end
|
33
|
+
proj = NanDoc::Project.instance
|
34
|
+
proxy = proj.test_framework_proxy_for_file(testfile)
|
35
|
+
sexp = proxy.sexp_get testfile, testname
|
36
|
+
scn = NanDoc::SpecDoc::Playback::SexpScanner.new(sexp)
|
37
|
+
scn.scan_assert(:method)
|
38
|
+
doc = NanDoc::Html::Tags.new
|
39
|
+
while true do
|
40
|
+
app = scn.scan_assert(:app)[1]
|
41
|
+
name = app.spec.invocation_name
|
42
|
+
argv = scn.scan_assert(:argv)[1]
|
43
|
+
# command = "./#{name} #{argv.shelljoin}"
|
44
|
+
# shelljoin is ugly and dumb
|
45
|
+
command = "./#{name} #{myshelljoin(argv)}"
|
46
|
+
out = scn.scan_assert(:out)[1]
|
47
|
+
cmd_html = prompt_highlight2('~ > ', command)
|
48
|
+
doc.push_smart("pre", 'terminal', cmd_html, opts)
|
49
|
+
opts.clear
|
50
|
+
colored = terminal_color_to_html(out) || html_escape(out)
|
51
|
+
doc.content.push colored
|
52
|
+
if scn.current && scn.current.first == :app
|
53
|
+
doc.content.push "\n\n"
|
54
|
+
# stay -- rare tests that do multiple commands
|
55
|
+
else
|
56
|
+
break
|
57
|
+
end
|
58
|
+
end
|
59
|
+
html = doc.to_html
|
60
|
+
html
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'optparse-lite'
|
3
|
+
require 'nandoc/spec-doc'
|
4
|
+
|
5
|
+
NanDoc::SpecDoc::Playback::Method.handlers[:optparse_app_module] = [:skip]
|
6
|
+
NanDoc::SpecDoc::GenericAgent.custom_spec_hook(:grab_optparse_app) do
|
7
|
+
recordings.add(:optparse_app_module, :placeholder)
|
8
|
+
record = recordings[recordings.length - 1]
|
9
|
+
::OptparseLite.after_included_once do |mod|
|
10
|
+
record[1] = mod
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# extend minitest with optparse-lite-specific stuff!
|
15
|
+
module OptparseLite
|
16
|
+
module Test
|
17
|
+
class << self
|
18
|
+
attr_accessor :verbose # set below
|
19
|
+
end
|
20
|
+
module Capture
|
21
|
+
class Capturer
|
22
|
+
def initialize mod
|
23
|
+
# make a regexp that can deduce the local module name from the
|
24
|
+
# name of the class that minitest generates, e.g.:
|
25
|
+
# OptparseLite::Test => /^OptparseliteTest(.+)Spec/
|
26
|
+
@mod = mod
|
27
|
+
@regexp = Regexp.new('^'+
|
28
|
+
mod.to_s.split('::').map{|x| x.downcase.capitalize}.join +
|
29
|
+
'(.+)Spec'
|
30
|
+
)
|
31
|
+
end
|
32
|
+
def capture app=nil, &b
|
33
|
+
app ||= @application_module
|
34
|
+
do_record = @spec && @spec.respond_to?(:nandoc)
|
35
|
+
ui = app.send(:ui)
|
36
|
+
ui.push
|
37
|
+
if do_record
|
38
|
+
app.set_argv_hook do |argv|
|
39
|
+
@spec.nandoc.recordings.add(:app, app)
|
40
|
+
@spec.nandoc.recordings.add(:argv, argv)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@last_return_value = app.instance_eval(&b)
|
44
|
+
str = ui.pop.to_str # tacitly assumes stderr is empty, breaks else
|
45
|
+
if do_record
|
46
|
+
@spec.nandoc.recordings.add(:out, str)
|
47
|
+
end
|
48
|
+
$stdout.puts "\n\n#{str}\n" if Test.verbose
|
49
|
+
str
|
50
|
+
end
|
51
|
+
def capture2 app=nil, &b
|
52
|
+
do_record = @spec && @spec.respond_to?(:nandoc)
|
53
|
+
app ||= @application_module
|
54
|
+
ui = app.send(:ui)
|
55
|
+
ui.push
|
56
|
+
@last_return_value = app.instance_eval(&b)
|
57
|
+
out, err = ui.pop(true)
|
58
|
+
out, err = out.to_s, err.to_s
|
59
|
+
if Test.verbose
|
60
|
+
$stdout.puts "\n\nout:\n#{out}\n."
|
61
|
+
$stdout.puts "\n\nerr:\n#{out}\n."
|
62
|
+
end
|
63
|
+
if do_record
|
64
|
+
if ""!=out && ""!=err
|
65
|
+
fail("don't be a dick")
|
66
|
+
end
|
67
|
+
@spec.nandoc.recordings.add(:out, out + err)
|
68
|
+
end
|
69
|
+
[out, err]
|
70
|
+
end
|
71
|
+
def get_app_from_spec spec
|
72
|
+
name = @regexp.match(spec.class.to_s)[1].downcase
|
73
|
+
@cache ||= Hash[
|
74
|
+
@mod.constants.map{|x|[x.downcase, @mod.const_get(x)]}
|
75
|
+
]
|
76
|
+
@cache[name]
|
77
|
+
end
|
78
|
+
def init_fork spec
|
79
|
+
@application_module = get_app_from_spec(spec)
|
80
|
+
@spec = spec # this has nandoc
|
81
|
+
end
|
82
|
+
def fork thing
|
83
|
+
ret = dup
|
84
|
+
ret.init_fork(thing)
|
85
|
+
ret
|
86
|
+
end
|
87
|
+
attr_accessor :last_return_value
|
88
|
+
attr_accessor :regexp
|
89
|
+
end
|
90
|
+
class << self
|
91
|
+
def included mod
|
92
|
+
base = MiniTest::Spec
|
93
|
+
capturer_prototype = Capturer.new(mod)
|
94
|
+
base.send(:define_method, :capturer) do ||
|
95
|
+
@capturer ||= capturer_prototype.fork(self)
|
96
|
+
end
|
97
|
+
base.send(:define_method, :capture) do |*a, &b|
|
98
|
+
capturer.capture(*a, &b)
|
99
|
+
end
|
100
|
+
base.send(:define_method, :capture2) do |*a, &b|
|
101
|
+
capturer.capture2(*a, &b)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# core extensions just for tests!
|
110
|
+
class String
|
111
|
+
def noindent n=nil
|
112
|
+
n ||= /\A *(?! )/.match(self)[0].length
|
113
|
+
s = gsub(/^ {#{n}}/, '')
|
114
|
+
s
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
if ARGV.include? '-v'
|
119
|
+
OptparseLite::Test.verbose = true
|
120
|
+
end
|
121
|
+
|
122
|
+
# hack to turn off randomness, for running the simplest
|
123
|
+
# test cases first
|
124
|
+
#
|
125
|
+
if (idx = ARGV.index('--seed')) && '0'==ARGV[idx+1]
|
126
|
+
class MiniTest::TestCase
|
127
|
+
def test_order
|
128
|
+
:alpha
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/test/test.rb
ADDED
@@ -0,0 +1,963 @@
|
|
1
|
+
require 'optparse-lite/test/setup'
|
2
|
+
|
3
|
+
# wierd bug!!! ruby test/test.rb --seed 3611
|
4
|
+
|
5
|
+
module OptparseLite::Test
|
6
|
+
|
7
|
+
include OptparseLite::Test::Capture
|
8
|
+
NanDoc::SpecDoc.include_to(class << self; self end)
|
9
|
+
|
10
|
+
nandoc.story 'empty app'
|
11
|
+
nandoc.grab_optparse_app
|
12
|
+
nandoc.record_ruby
|
13
|
+
#!/usr/bin/env ruby
|
14
|
+
|
15
|
+
require 'optparse-lite'
|
16
|
+
class Empty
|
17
|
+
include OptparseLite
|
18
|
+
end
|
19
|
+
nandoc.record_ruby_stop
|
20
|
+
|
21
|
+
nandoc.story_stop
|
22
|
+
|
23
|
+
Empty.spec.invocation_name = "empty-app.rb"
|
24
|
+
|
25
|
+
describe Empty do
|
26
|
+
include NanDoc::SpecDoc
|
27
|
+
|
28
|
+
it 'empty-app.rb must work' do
|
29
|
+
nandoc.record
|
30
|
+
exp = <<-HERE.noindent
|
31
|
+
\e[32;mUsage:\e[0m empty-app.rb (this screen. no commands defined.)
|
32
|
+
HERE
|
33
|
+
act = capture{ run [] }
|
34
|
+
assert_no_diff(exp, act)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'no run' do
|
38
|
+
OptparseLite.suppress_run!
|
39
|
+
out, err = capture2{ run [] }
|
40
|
+
OptparseLite.enable_run!
|
41
|
+
assert_equal "run disabled. (probably for gentesting)\n", err
|
42
|
+
assert_equal "", out
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
nandoc.story 'one meth'
|
48
|
+
nandoc.grab_optparse_app
|
49
|
+
nandoc.record_ruby
|
50
|
+
class OneMeth
|
51
|
+
include OptparseLite
|
52
|
+
def bar
|
53
|
+
ui.puts 'done!'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
nandoc.record_ruby_stop
|
57
|
+
nandoc.story_stop
|
58
|
+
OneMeth.spec.invocation_name = "one-meth-app.rb"
|
59
|
+
|
60
|
+
describe OneMeth do
|
61
|
+
include NanDoc::SpecDoc
|
62
|
+
|
63
|
+
it 'one-meth-app.rb runs' do
|
64
|
+
nandoc.record
|
65
|
+
out = capture{ run ['bar'] }
|
66
|
+
assert_equal "done!\n", out
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
it "one-meth-app.rb works like help when the command is not found" do
|
71
|
+
nandoc.record
|
72
|
+
exp = <<-HERE.noindent
|
73
|
+
i don't know how to \e[32;mbazzle\e[0m.
|
74
|
+
try \e[32;mone-meth-app.rb\e[0m \e[32;m-h\e[0m for help.
|
75
|
+
HERE
|
76
|
+
act = capture{ run ["bazzle"] }
|
77
|
+
assert_no_diff(exp, act)
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
it 'one-meth-app.rb ask for help must work' do
|
82
|
+
nandoc.record
|
83
|
+
exp = <<-HERE.noindent
|
84
|
+
\e[32;mUsage:\e[0m one-meth-app.rb (bar) [<opts>] [<args>]
|
85
|
+
|
86
|
+
\e[32;mCommands:\e[0m
|
87
|
+
bar usage: bar
|
88
|
+
type -h after a command or subcommand name for more help
|
89
|
+
HERE
|
90
|
+
act = capture{ run ["-h"] }
|
91
|
+
assert_no_diff(exp, act)
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
it 'one-meth-app.rb no args must work' do
|
96
|
+
exp = <<-HERE.noindent
|
97
|
+
\e[32;mUsage:\e[0m one-meth-app.rb (bar) [<opts>] [<args>]
|
98
|
+
|
99
|
+
\e[32;mCommands:\e[0m
|
100
|
+
bar usage: bar
|
101
|
+
type -h after a command or subcommand name for more help
|
102
|
+
HERE
|
103
|
+
act = capture{ run [] }
|
104
|
+
assert_no_diff(exp, act)
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
it 'one-meth-app.rb ask for help bad command must work' do
|
109
|
+
exp = <<-HERE.noindent
|
110
|
+
i don't know how to \e[32;mska\e[0m.
|
111
|
+
try \e[32;mone-meth-app.rb\e[0m \e[32;m-h\e[0m for help.
|
112
|
+
HERE
|
113
|
+
act = capture{ run ["-h", "ska"] }
|
114
|
+
assert_no_diff(exp, act)
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
it 'one-meth-app.rb ask for help partial match must work' do
|
119
|
+
exp = <<-HERE.noindent
|
120
|
+
\e[32;mUsage:\e[0m one-meth-app.rb bar
|
121
|
+
HERE
|
122
|
+
act = capture{ run ["-h", "b"] }
|
123
|
+
assert_no_diff(exp, act)
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
it 'one-meth-app.rb ask for help full match must work' do
|
128
|
+
nandoc.record
|
129
|
+
exp = <<-HERE.noindent
|
130
|
+
\e[32;mUsage:\e[0m one-meth-app.rb bar
|
131
|
+
HERE
|
132
|
+
act = capture{ run ["-h", "bar"] }
|
133
|
+
assert_no_diff(exp, act)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
nandoc.story 'persistent'
|
139
|
+
nandoc.grab_optparse_app
|
140
|
+
nandoc.record_ruby
|
141
|
+
class PersistentService
|
142
|
+
include OptparseLite
|
143
|
+
def initialize
|
144
|
+
@num = 0
|
145
|
+
end
|
146
|
+
def ping
|
147
|
+
@num += 1
|
148
|
+
ui.puts "i have pinged #{@num} times"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
nandoc.record_ruby_stop
|
152
|
+
nandoc.story_stop
|
153
|
+
PersistentService.spec.invocation_name = "persistent-service-app.rb"
|
154
|
+
|
155
|
+
describe PersistentService do
|
156
|
+
include NanDoc::SpecDoc
|
157
|
+
|
158
|
+
it 'persistent-service-app.rb multiple requests' do
|
159
|
+
nandoc.record
|
160
|
+
exp = <<-HERE.noindent
|
161
|
+
i have pinged 1 times
|
162
|
+
HERE
|
163
|
+
act = capture{ run ["ping"] }
|
164
|
+
assert_no_diff(exp, act)
|
165
|
+
exp = <<-HERE.noindent
|
166
|
+
i have pinged 2 times
|
167
|
+
HERE
|
168
|
+
act = capture{ run ["ping"] }
|
169
|
+
assert_no_diff(exp, act)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
nandoc.story 'neg arity'
|
174
|
+
nandoc.grab_optparse_app
|
175
|
+
nandoc.record_ruby
|
176
|
+
class OneMethWithNegArity
|
177
|
+
include OptparseLite
|
178
|
+
def bar(*a); end
|
179
|
+
end
|
180
|
+
nandoc.record_ruby_stop
|
181
|
+
nandoc.story_stop
|
182
|
+
OneMethWithNegArity.spec.invocation_name = "one-meth-with-neg-arity-app.rb"
|
183
|
+
|
184
|
+
describe OneMethWithNegArity do
|
185
|
+
include NanDoc::SpecDoc
|
186
|
+
|
187
|
+
it 'one-meth-with-neg-arity-app.rb must work' do
|
188
|
+
nandoc.record
|
189
|
+
exp = <<-HERE.noindent
|
190
|
+
\e[32;mUsage:\e[0m one-meth-with-neg-arity-app.rb (bar) [<opts>] [<args>]
|
191
|
+
|
192
|
+
\e[32;mCommands:\e[0m
|
193
|
+
bar usage: bar [<arg1>]
|
194
|
+
type -h after a command or subcommand name for more help
|
195
|
+
HERE
|
196
|
+
act = capture{ run [] }
|
197
|
+
assert_no_diff(exp, act)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
class OneMethWithPosArity
|
203
|
+
include OptparseLite
|
204
|
+
def bar(a); end
|
205
|
+
end
|
206
|
+
OneMethWithPosArity.spec.invocation_name = "one-meth-with-pos-arity-app.rb"
|
207
|
+
|
208
|
+
describe OneMethWithPosArity do
|
209
|
+
include NanDoc::SpecDoc
|
210
|
+
|
211
|
+
it 'one-meth-with-pos-arity-app.rb must work' do
|
212
|
+
exp = <<-HERE.noindent
|
213
|
+
\e[32;mUsage:\e[0m one-meth-with-pos-arity-app.rb (bar) [<opts>] [<args>]
|
214
|
+
|
215
|
+
\e[32;mCommands:\e[0m
|
216
|
+
bar usage: bar <arg1>
|
217
|
+
type -h after a command or subcommand name for more help
|
218
|
+
HERE
|
219
|
+
act = capture{ run [] }
|
220
|
+
assert_no_diff(exp, act)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
nandoc.story 'one meth desc'
|
225
|
+
nandoc.grab_optparse_app
|
226
|
+
nandoc.record_ruby
|
227
|
+
class OneMethDesc
|
228
|
+
include OptparseLite
|
229
|
+
|
230
|
+
app.desc "when u wanna have a good time"
|
231
|
+
|
232
|
+
desc "this is for barring"
|
233
|
+
def bar; end
|
234
|
+
end
|
235
|
+
nandoc.record_ruby_stop
|
236
|
+
nandoc.story_stop
|
237
|
+
OneMethDesc.spec.invocation_name = "one-meth-desc-app.rb"
|
238
|
+
|
239
|
+
describe OneMethDesc do
|
240
|
+
include NanDoc::SpecDoc
|
241
|
+
|
242
|
+
it 'one-meth-desc-app.rb must work' do
|
243
|
+
nandoc.record
|
244
|
+
exp = <<-HERE.noindent
|
245
|
+
\e[32;mUsage:\e[0m one-meth-desc-app.rb (bar) [<opts>] [<args>]
|
246
|
+
when u wanna have a good time
|
247
|
+
|
248
|
+
\e[32;mCommands:\e[0m
|
249
|
+
bar this is for barring
|
250
|
+
type -h after a command or subcommand name for more help
|
251
|
+
HERE
|
252
|
+
act = capture{ run [] }
|
253
|
+
assert_no_diff(exp, act)
|
254
|
+
end
|
255
|
+
it 'one-meth-desc-app.rb ask for help must work' do
|
256
|
+
nandoc.record
|
257
|
+
exp = <<-HERE.noindent
|
258
|
+
\e[32;mUsage:\e[0m one-meth-desc-app.rb bar
|
259
|
+
\e[32;mDescription:\e[0m this is for barring
|
260
|
+
HERE
|
261
|
+
act = capture{ run ["-h", "bar"] }
|
262
|
+
assert_no_diff(exp, act)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
nandoc.story 'one meth usage'
|
268
|
+
nandoc.grab_optparse_app
|
269
|
+
nandoc.record_ruby
|
270
|
+
class OneMethUsage
|
271
|
+
include OptparseLite
|
272
|
+
usage "<paint> <ball>"
|
273
|
+
def bar a, b; end
|
274
|
+
end
|
275
|
+
nandoc.record_ruby_stop
|
276
|
+
nandoc.story_stop
|
277
|
+
|
278
|
+
OneMethUsage.spec.invocation_name = "one-meth-usage-app.rb"
|
279
|
+
|
280
|
+
describe OneMethUsage do
|
281
|
+
include NanDoc::SpecDoc
|
282
|
+
|
283
|
+
it 'one-meth-usage-app.rb must work' do
|
284
|
+
nandoc.record
|
285
|
+
exp = <<-HERE.noindent
|
286
|
+
\e[32;mUsage:\e[0m one-meth-usage-app.rb (bar) [<opts>] [<args>]
|
287
|
+
|
288
|
+
\e[32;mCommands:\e[0m
|
289
|
+
bar usage: bar <paint> <ball>
|
290
|
+
type -h after a command or subcommand name for more help
|
291
|
+
HERE
|
292
|
+
act = capture{ run [] }
|
293
|
+
assert_no_diff(exp, act)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
nandoc.story 'three meth'
|
299
|
+
nandoc.grab_optparse_app
|
300
|
+
nandoc.record_ruby
|
301
|
+
class ThreeMeth
|
302
|
+
include OptparseLite
|
303
|
+
def foo; end
|
304
|
+
def bar(arg1, arg2); end
|
305
|
+
desc "faz line one"
|
306
|
+
desc "faz line two"
|
307
|
+
def faz; end
|
308
|
+
end
|
309
|
+
nandoc.record_ruby_stop
|
310
|
+
nandoc.story_stop
|
311
|
+
ThreeMeth.spec.invocation_name = "three-meth-app.rb"
|
312
|
+
|
313
|
+
describe ThreeMeth do
|
314
|
+
include NanDoc::SpecDoc
|
315
|
+
|
316
|
+
it 'three-meth-app.rb no args must work' do
|
317
|
+
nandoc.record
|
318
|
+
exp = <<-HERE.noindent
|
319
|
+
\e[32;mUsage:\e[0m three-meth-app.rb (foo|bar|faz) [<opts>] [<args>]
|
320
|
+
|
321
|
+
\e[32;mCommands:\e[0m
|
322
|
+
foo usage: foo
|
323
|
+
bar usage: bar <arg1> <arg2>
|
324
|
+
faz faz line one
|
325
|
+
type -h after a command or subcommand name for more help
|
326
|
+
HERE
|
327
|
+
act = capture{ run [] }
|
328
|
+
assert_no_diff(exp, act)
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'three-meth-app.rb help requested command not found must work' do
|
332
|
+
nandoc.record
|
333
|
+
exp = <<-HERE.noindent
|
334
|
+
i don't know how to \e[32;mska\e[0m.
|
335
|
+
try \e[32;mthree-meth-app.rb\e[0m \e[32;m-h\e[0m for help.
|
336
|
+
HERE
|
337
|
+
act = capture{ run ["-h", "ska"] }
|
338
|
+
assert_no_diff(exp, act)
|
339
|
+
end
|
340
|
+
|
341
|
+
it 'three-meth-app.rb help requested partial match must work 1' do
|
342
|
+
nandoc.record
|
343
|
+
exp = <<-HERE.noindent
|
344
|
+
did you mean \e[32;mfoo\e[0m or \e[32;mfaz\e[0m?
|
345
|
+
try \e[32;mthree-meth-app.rb\e[0m \e[32;m-h\e[0m for help.
|
346
|
+
HERE
|
347
|
+
act = capture{ run ["-h", "f"] }
|
348
|
+
assert_no_diff(exp, act)
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'three-meth-app.rb help requested partial match must work 2' do
|
352
|
+
nandoc.record
|
353
|
+
exp = <<-HERE.noindent
|
354
|
+
\e[32;mUsage:\e[0m three-meth-app.rb faz
|
355
|
+
\e[32;mDescription:\e[0m
|
356
|
+
faz line one
|
357
|
+
faz line two
|
358
|
+
HERE
|
359
|
+
act = capture{ run ["-h", "fa"] }
|
360
|
+
assert_no_diff(exp, act)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe OptparseLite::OptsLike do
|
365
|
+
include NanDoc::SpecDoc
|
366
|
+
|
367
|
+
it "ops must be OptsLike" do
|
368
|
+
e = assert_raises(RuntimeError) do
|
369
|
+
class BadOpts
|
370
|
+
include OptparseLite
|
371
|
+
opts nil
|
372
|
+
def foo; end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
assert_equal(e.message, 'opts must be OptsLike')
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
|
380
|
+
module OptsStub
|
381
|
+
include OptparseLite::OptsLike
|
382
|
+
extend self
|
383
|
+
def syntax_tokens
|
384
|
+
['--fake', '-b=<foo>']
|
385
|
+
end
|
386
|
+
def doc_sexp
|
387
|
+
[[:hdr, 'Awesome Opts:'],
|
388
|
+
[:opt, '-h,--hey','awesome desc'],
|
389
|
+
[:opt, '-H,--HO=<ho>', 'awesome desc2']]
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
class CmdWithOpts
|
394
|
+
include OptparseLite
|
395
|
+
opts OptsStub
|
396
|
+
def foo; end
|
397
|
+
end
|
398
|
+
CmdWithOpts.spec.invocation_name = "cmd-with-opts-app.rb"
|
399
|
+
|
400
|
+
describe CmdWithOpts do
|
401
|
+
include NanDoc::SpecDoc
|
402
|
+
|
403
|
+
it 'cmd-with-opts-app.rb must work with stub' do
|
404
|
+
exp = <<-HERE.noindent
|
405
|
+
\e[32;mUsage:\e[0m cmd-with-opts-app.rb (foo) [<opts>] [<args>]
|
406
|
+
|
407
|
+
\e[32;mCommands:\e[0m
|
408
|
+
foo usage: foo [--fake] [-b=<foo>]
|
409
|
+
type -h after a command or subcommand name for more help
|
410
|
+
HERE
|
411
|
+
act = capture{ run [] }
|
412
|
+
assert_no_diff(exp, act)
|
413
|
+
end
|
414
|
+
it 'cmd-with-opts-app.rb multiline description stub' do
|
415
|
+
exp = <<-HERE.noindent
|
416
|
+
\e[32;mUsage:\e[0m cmd-with-opts-app.rb foo [--fake] [-b=<foo>]
|
417
|
+
\e[32;mAwesome Opts:\e[0m
|
418
|
+
-h,--hey awesome desc
|
419
|
+
-H,--HO=<ho> awesome desc2
|
420
|
+
HERE
|
421
|
+
act = capture{ run ["-h", "foo"] }
|
422
|
+
assert_no_diff(exp, act)
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
nandoc.story 'more usage'
|
427
|
+
nandoc.grab_optparse_app
|
428
|
+
nandoc.record_ruby
|
429
|
+
class CovPatch
|
430
|
+
include OptparseLite
|
431
|
+
|
432
|
+
usage '[-blah -blah] <blah1> <blah2>'
|
433
|
+
def wierd_usage
|
434
|
+
end
|
435
|
+
|
436
|
+
usage '-one -opt -another [<args>]'
|
437
|
+
def useless_interpolate a1, a2
|
438
|
+
end
|
439
|
+
end
|
440
|
+
nandoc.record_ruby_stop
|
441
|
+
nandoc.story_stop
|
442
|
+
|
443
|
+
CovPatch.spec.invocation_name = "cov-patch-app.rb"
|
444
|
+
|
445
|
+
describe CovPatch do
|
446
|
+
include NanDoc::SpecDoc
|
447
|
+
|
448
|
+
it 'cov-patch-app.rb displays wierd usage (no validation!?)' do # @todo
|
449
|
+
nandoc.record
|
450
|
+
exp = <<-HERE.noindent
|
451
|
+
\e[32;mUsage:\e[0m cov-patch-app.rb wierd-usage [-blah -blah] <blah1> <blah2>
|
452
|
+
HERE
|
453
|
+
act = capture{ run ["-h", "wierd-"] }
|
454
|
+
assert_no_diff(exp, act)
|
455
|
+
end
|
456
|
+
|
457
|
+
|
458
|
+
it 'cov-patch-app.rb interpolates args for no reason' do
|
459
|
+
nandoc.record
|
460
|
+
exp = <<-HERE.noindent
|
461
|
+
\e[32;mUsage:\e[0m cov-patch-app.rb useless-interpolate -one -opt -another <arg1> <arg2>
|
462
|
+
HERE
|
463
|
+
act = capture{ run ["-h", "use"] }
|
464
|
+
assert_no_diff(exp, act)
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
|
469
|
+
|
470
|
+
class OptsMock
|
471
|
+
include OptparseLite::OptsLike
|
472
|
+
def initialize(sexp); @sexp = sexp end
|
473
|
+
def doc_sexp; @sexp; end
|
474
|
+
def syntax_tokens
|
475
|
+
@sexp.select{|x| x.first==:opt}.map{|x| x[1]}
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
class BannerTime
|
480
|
+
include OptparseLite
|
481
|
+
|
482
|
+
opts OptsMock.new([
|
483
|
+
[:hdr, 'Eric Banner:'],
|
484
|
+
[:opt, '--foo, -Bar', 'some opt desc'],
|
485
|
+
[:opt, '-foobric', 'another'],
|
486
|
+
[:txt, 'multiline description that is'],
|
487
|
+
[:txt, 'not a banner:'],
|
488
|
+
[:opt, '--stanley','foobric'],
|
489
|
+
[:txt,'this is desc'],
|
490
|
+
[:hdr,'This is banner:'],
|
491
|
+
[:opt, '-a,-b','bloofis goofis']
|
492
|
+
])
|
493
|
+
def fix_desc opts, a, b=nil
|
494
|
+
end
|
495
|
+
end
|
496
|
+
BannerTime.spec.invocation_name = "banner-time-app.rb"
|
497
|
+
|
498
|
+
describe BannerTime do
|
499
|
+
include NanDoc::SpecDoc
|
500
|
+
|
501
|
+
it 'banner-time-app.rb must work' do
|
502
|
+
exp = <<-HERE.noindent
|
503
|
+
\e[32;mUsage:\e[0m banner-time-app.rb fix-desc [--foo, -Bar] [-foobric] [--stanley] [-a,-b] <arg1> [<arg2>]
|
504
|
+
\e[32;mEric Banner:\e[0m
|
505
|
+
--foo, -Bar some opt desc
|
506
|
+
-foobric another
|
507
|
+
multiline description that is
|
508
|
+
not a banner:
|
509
|
+
--stanley foobric
|
510
|
+
this is desc
|
511
|
+
\e[32;mThis is banner:\e[0m
|
512
|
+
-a,-b bloofis goofis
|
513
|
+
HERE
|
514
|
+
act = capture{ run ["-h", "fix"] }
|
515
|
+
assert_no_diff(exp, act)
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
|
520
|
+
describe OptparseLite::OptParser do
|
521
|
+
include NanDoc::SpecDoc
|
522
|
+
|
523
|
+
it "must fail on no mames param" do
|
524
|
+
e = assert_raises(RuntimeError) do
|
525
|
+
OptparseLite::OptParser.new{
|
526
|
+
opt '--[no-]mames[=<joai>]'
|
527
|
+
}.compile!
|
528
|
+
end
|
529
|
+
assert_match(/let's not take arguments with no- style opts/,e.message)
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
|
534
|
+
nandoc.story 'finally'
|
535
|
+
nandoc.grab_optparse_app
|
536
|
+
nandoc.record_ruby
|
537
|
+
class Finally
|
538
|
+
include OptparseLite
|
539
|
+
|
540
|
+
opts {
|
541
|
+
banner 'Fun Options:'
|
542
|
+
opt '-a, --alpha', 'desco', :foo
|
543
|
+
opt '-b, --beta=<foo>', 'desc for beta', :fooey, 'more desc for beta'
|
544
|
+
banner 'Eric Banner:'
|
545
|
+
banner 'not eric banner, just some desco'
|
546
|
+
banner 'another not banner, just some chit chat:'
|
547
|
+
opt '--gamma[=<baz>]','gamma is where it\'s at'
|
548
|
+
opt '--[no-]mames', :juae
|
549
|
+
}
|
550
|
+
def do_it opts, a, b=nil
|
551
|
+
|
552
|
+
end
|
553
|
+
end
|
554
|
+
nandoc.record_ruby_stop
|
555
|
+
nandoc.story_stop
|
556
|
+
Finally.spec.invocation_name = "finally-app.rb"
|
557
|
+
|
558
|
+
describe Finally do
|
559
|
+
|
560
|
+
include NanDoc::SpecDoc
|
561
|
+
|
562
|
+
it 'finally-app.rb general help' do
|
563
|
+
nandoc.record
|
564
|
+
exp = <<-HERE.noindent
|
565
|
+
\e[32;mUsage:\e[0m finally-app.rb (do-it) [<opts>] [<args>]
|
566
|
+
|
567
|
+
\e[32;mCommands:\e[0m
|
568
|
+
do-it usage: do-it [--alpha,-a] [--beta,-b=<foo>] [--gamma[=<baz>]] [--[no-]mames] <arg1> [<arg2>]
|
569
|
+
type -h after a command or subcommand name for more help
|
570
|
+
HERE
|
571
|
+
act = capture{ run [] }
|
572
|
+
assert_no_diff(exp, act)
|
573
|
+
end
|
574
|
+
|
575
|
+
it 'finally-app.rb command help' do
|
576
|
+
nandoc.record
|
577
|
+
exp = <<-HERE.noindent
|
578
|
+
\e[32;mUsage:\e[0m finally-app.rb do-it [--alpha,-a] [--beta,-b=<foo>] [--gamma[=<baz>]] [--[no-]mames] <arg1> [<arg2>]
|
579
|
+
\e[32;mFun Options:\e[0m
|
580
|
+
--alpha, -a desco
|
581
|
+
--beta, -b=<foo> desc for beta
|
582
|
+
more desc for beta
|
583
|
+
\e[32;mEric Banner:\e[0m
|
584
|
+
not eric banner, just some desco
|
585
|
+
another not banner, just some chit chat:
|
586
|
+
--gamma[=<baz>] gamma is where it's at
|
587
|
+
--[no-]mames
|
588
|
+
HERE
|
589
|
+
act = capture{ run ["-h", "do"] }
|
590
|
+
assert_no_diff(exp, act)
|
591
|
+
end
|
592
|
+
|
593
|
+
it 'finally-app.rb complains on optparse errors' do
|
594
|
+
nandoc.record
|
595
|
+
exp_out = <<-HERE.noindent
|
596
|
+
HERE
|
597
|
+
exp_err = <<-HERE.noindent
|
598
|
+
finally-app.rb: couldn't do-it because of the following errors:
|
599
|
+
\e[32;m--beta\e[0m requires a parameter (-b=<foo>)
|
600
|
+
i don't recognize the parameter: \e[32;m--not\e[0m
|
601
|
+
\e[32;m--alpha\e[0m does not take an arguement (\"yo\")
|
602
|
+
\e[32;mUsage:\e[0m finally-app.rb do-it [--alpha,-a] [--beta,-b=<foo>] [--gamma[=<baz>]] [--[no-]mames] <arg1> [<arg2>]
|
603
|
+
try \e[32;mfinally-app.rb\e[0m \e[32;mhelp\e[0m \e[32;mdo-it\e[0m for full syntax and usage.
|
604
|
+
HERE
|
605
|
+
act_out, act_err = capture2{ run ["do", "--not=an", "option", "--beta", "--alpha=yo", "--no-mames"] }
|
606
|
+
assert_no_diff(exp_out, act_out)
|
607
|
+
assert_no_diff(exp_err, act_err)
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
class Raiser
|
612
|
+
include OptparseLite
|
613
|
+
|
614
|
+
def arg_error
|
615
|
+
raise ArgumentError.new("this is an application-level arg error")
|
616
|
+
end
|
617
|
+
|
618
|
+
def rt_error
|
619
|
+
raise RuntimeError.new("this is an application-level runtime error")
|
620
|
+
end
|
621
|
+
|
622
|
+
def ui_level_error arg1, arg2
|
623
|
+
end
|
624
|
+
end
|
625
|
+
Raiser.spec.invocation_name = "raiser-app.rb"
|
626
|
+
|
627
|
+
describe Raiser do
|
628
|
+
include NanDoc::SpecDoc
|
629
|
+
|
630
|
+
|
631
|
+
it 'lets application level argument errors thru' do
|
632
|
+
e = assert_raises(ArgumentError) do
|
633
|
+
Raiser.run(%w(arg_error))
|
634
|
+
end
|
635
|
+
assert_match %r!arg error!, e.message
|
636
|
+
end
|
637
|
+
|
638
|
+
it 'lets application level runtime errors thru' do
|
639
|
+
e = assert_raises(RuntimeError) do
|
640
|
+
Raiser.run(%w(rt_error))
|
641
|
+
end
|
642
|
+
assert_match %!runtime error!, e.message
|
643
|
+
end
|
644
|
+
|
645
|
+
it 'rescues argument errors to the controller methods' do
|
646
|
+
exp_out = <<-HERE.noindent
|
647
|
+
HERE
|
648
|
+
exp_err = <<-HERE.noindent
|
649
|
+
raiser-app.rb: couldn't ui-level-error because of an error:
|
650
|
+
wrong number of arguments (0 for 2)
|
651
|
+
\e[32;mUsage:\e[0m raiser-app.rb ui-level-error <arg1> <arg2>
|
652
|
+
try \e[32;mraiser-app.rb\e[0m \e[32;mhelp\e[0m \e[32;mui-level-error\e[0m for full syntax and usage.
|
653
|
+
HERE
|
654
|
+
act_out, act_err = capture2{ run ["ui-"] }
|
655
|
+
assert_no_diff(exp_out, act_out)
|
656
|
+
assert_no_diff(exp_err, act_err)
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
describe OptparseLite::Np do
|
661
|
+
include NanDoc::SpecDoc
|
662
|
+
|
663
|
+
it "fails on this" do
|
664
|
+
e = assert_raises(RuntimeError) do
|
665
|
+
OptparseLite::Np.new(:the,'thing'){}
|
666
|
+
end
|
667
|
+
assert_match %r!blah blah!, e.message
|
668
|
+
e = assert_raises(RuntimeError) do
|
669
|
+
OptparseLite::Np.new(:the,'thing',10){||}
|
670
|
+
end
|
671
|
+
assert_match %r!count and block mutually exclusive!, e.message
|
672
|
+
end
|
673
|
+
end
|
674
|
+
|
675
|
+
|
676
|
+
nandoc.story 'agg opts'
|
677
|
+
nandoc.grab_optparse_app
|
678
|
+
nandoc.record_ruby
|
679
|
+
class AggOpts
|
680
|
+
include OptparseLite
|
681
|
+
opts {
|
682
|
+
banner 'Alpha Options:'
|
683
|
+
opt '-a, --alpha', 'this is alpha'
|
684
|
+
opt '-b', 'this is beta', :default=>'heh but it\'s argless'
|
685
|
+
}
|
686
|
+
desc "you will see this at the top above the opts? or not"
|
687
|
+
opts {
|
688
|
+
banner 'Gamma Options:'
|
689
|
+
opt '-g, --gamma=<foo>', 'this is gamma',
|
690
|
+
'multiline gamma', :default=>'great gams'
|
691
|
+
opt '-d, --delta'
|
692
|
+
}
|
693
|
+
def go_with_it opts, a, b=nil
|
694
|
+
opts = opts.merge(:first_arg=>a, :second_arg=>b)
|
695
|
+
resp = opts.keys.map(&:to_s).sort.map{|k| [k.to_sym, opts[k.to_sym]]}
|
696
|
+
ui.puts resp.inspect
|
697
|
+
end
|
698
|
+
end
|
699
|
+
nandoc.record_ruby_stop
|
700
|
+
nandoc.story_stop
|
701
|
+
AggOpts.spec.invocation_name = "agg-opts-app.rb"
|
702
|
+
|
703
|
+
describe AggOpts do
|
704
|
+
include NanDoc::SpecDoc
|
705
|
+
|
706
|
+
it 'agg-opts-app.rb help display' do
|
707
|
+
nandoc.record
|
708
|
+
exp = <<-HERE.noindent
|
709
|
+
\e[32;mUsage:\e[0m agg-opts-app.rb go-with-it [--alpha,-a] [-b] [--gamma,-g=<foo>] [--delta,-d] <arg1> [<arg2>]
|
710
|
+
\e[32;mAlpha Options:\e[0m
|
711
|
+
--alpha, -a this is alpha
|
712
|
+
-b this is beta
|
713
|
+
you will see this at the top above the opts? or not
|
714
|
+
\e[32;mGamma Options:\e[0m
|
715
|
+
--gamma, -g=<foo> this is gamma
|
716
|
+
multiline gamma
|
717
|
+
--delta, -d
|
718
|
+
HERE
|
719
|
+
act = capture{ run ["-h", "go"] }
|
720
|
+
assert_no_diff(exp, act)
|
721
|
+
end
|
722
|
+
|
723
|
+
it 'agg-opts-app.rb opt validation' do
|
724
|
+
nandoc.record
|
725
|
+
exp_out = <<-HERE.noindent
|
726
|
+
HERE
|
727
|
+
exp_err = <<-HERE.noindent
|
728
|
+
agg-opts-app.rb: couldn't go-with-it because of the following errors:
|
729
|
+
\e[32;m--alpha\e[0m does not take an arguement (\"foo\")
|
730
|
+
i don't recognize these parameters: \e[32;m--gamma,\e[0m and \e[32;m--digle\e[0m
|
731
|
+
\e[32;mUsage:\e[0m agg-opts-app.rb go-with-it [--alpha,-a] [-b] [--gamma,-g=<foo>] [--delta,-d] <arg1> [<arg2>]
|
732
|
+
try \e[32;magg-opts-app.rb\e[0m \e[32;mhelp\e[0m \e[32;mgo-with-it\e[0m for full syntax and usage.
|
733
|
+
HERE
|
734
|
+
act_out, act_err = capture2{ run ["go", "--digle=fingle,", "--gamma,", "--alpha=foo"] }
|
735
|
+
assert_no_diff(exp_out, act_out)
|
736
|
+
assert_no_diff(exp_err, act_err)
|
737
|
+
end
|
738
|
+
|
739
|
+
it 'agg-opts-app.rb must work' do
|
740
|
+
nandoc.record
|
741
|
+
exp = <<-HERE.noindent
|
742
|
+
[[:b, \"heh but it's argless\"], [:first_arg, \"foo\"], [:gamma, \"great gams\"], [:second_arg, nil]]
|
743
|
+
HERE
|
744
|
+
act = capture{ run ["go", "foo"] }
|
745
|
+
assert_no_diff(exp, act)
|
746
|
+
end
|
747
|
+
end
|
748
|
+
|
749
|
+
nandoc.story 'sub'
|
750
|
+
nandoc.grab_optparse_app
|
751
|
+
nandoc.record_ruby
|
752
|
+
class Sub
|
753
|
+
include OptparseLite
|
754
|
+
|
755
|
+
subcommands :fric, 'bric-dic', :frac
|
756
|
+
def foo(*a)
|
757
|
+
subcommand_dispatch(*a)
|
758
|
+
end
|
759
|
+
|
760
|
+
private
|
761
|
+
|
762
|
+
usage '[<opts>] <crank-harder>'
|
763
|
+
desc 'crank harder'
|
764
|
+
opts {
|
765
|
+
opt '-f', "this does blah", :accessor=>:f
|
766
|
+
}
|
767
|
+
def foo_fric opts, arg
|
768
|
+
opts.merge!({:arg=>arg, :method=>:foo_fric})
|
769
|
+
thing = opts.keys.map(&:to_s).sort.map{|x| [x, opts[x.to_sym]]}
|
770
|
+
ui.puts thing.inspect
|
771
|
+
opts
|
772
|
+
end
|
773
|
+
|
774
|
+
usage '[<opts>] <somefile>'
|
775
|
+
desc 'some awesome times'
|
776
|
+
opts {
|
777
|
+
opt '-b,--blah', "this does blah"
|
778
|
+
}
|
779
|
+
def foo_bric_dic opts, arg
|
780
|
+
opts.merge!({:arg=>arg, :method=>:foo_bric_dic})
|
781
|
+
thing = opts.keys.map(&:to_s).sort.map{|x| [x, opts[x.to_sym]]}
|
782
|
+
ui.puts thing.inspect
|
783
|
+
opts
|
784
|
+
end
|
785
|
+
|
786
|
+
def foo_frac
|
787
|
+
end
|
788
|
+
end
|
789
|
+
nandoc.record_ruby_stop
|
790
|
+
nandoc.story_stop
|
791
|
+
Sub.spec.invocation_name = "sub-app.rb"
|
792
|
+
|
793
|
+
describe Sub do
|
794
|
+
include NanDoc::SpecDoc
|
795
|
+
|
796
|
+
it 'sub-app.rb with command with no arg shows subcommand list' do
|
797
|
+
nandoc.record
|
798
|
+
exp = <<-HERE.noindent
|
799
|
+
\e[32;mUsage:\e[0m sub-app.rb foo (fric|bric-dic|frac) [<opts>] [<args>]
|
800
|
+
|
801
|
+
\e[32;mSub Commands:\e[0m
|
802
|
+
fric crank harder
|
803
|
+
bric-dic some awesome times
|
804
|
+
frac usage: foo frac
|
805
|
+
type -h after a command or subcommand name for more help
|
806
|
+
HERE
|
807
|
+
act = capture{ run ["foo"] }
|
808
|
+
assert_no_diff(exp, act)
|
809
|
+
act = capture{ run ["foo", "-h"] }
|
810
|
+
assert_no_diff(exp, act)
|
811
|
+
end
|
812
|
+
it 'sub-app.rb shows help on sub-command' do
|
813
|
+
nandoc.record
|
814
|
+
exp = <<-HERE.noindent
|
815
|
+
\e[32;mUsage:\e[0m sub-app.rb foo fric [-f] <crank-harder>
|
816
|
+
\e[32;mDescription:\e[0m crank harder
|
817
|
+
-f this does blah
|
818
|
+
HERE
|
819
|
+
act = capture{ run ["foo", "-h", "fric"] }
|
820
|
+
assert_no_diff(exp, act)
|
821
|
+
end
|
822
|
+
it 'sub-app.rb must work' do
|
823
|
+
nandoc.record
|
824
|
+
exp = <<-HERE.noindent
|
825
|
+
[[\"arg\", \"frak\"], [\"method\", :foo_fric]]
|
826
|
+
HERE
|
827
|
+
act = capture{ run ["foo", "fric", "frak"] }
|
828
|
+
assert_no_diff(exp, act)
|
829
|
+
exp = <<-HERE.noindent
|
830
|
+
[[\"arg\", \"frak\"], [\"method\", :foo_fric]]
|
831
|
+
HERE
|
832
|
+
act = capture{ run ["foo", "fri", "frak"] }
|
833
|
+
assert_no_diff(exp, act)
|
834
|
+
end
|
835
|
+
end
|
836
|
+
|
837
|
+
|
838
|
+
module Mod
|
839
|
+
include OptparseLite
|
840
|
+
opts {
|
841
|
+
banner 'Fun Options:'
|
842
|
+
opt '-a, --alpha', 'desco', :foo
|
843
|
+
opt '-b, --beta=<foo>', 'desc for beta', :fooey, 'more desc for beta'
|
844
|
+
banner 'Eric Banner:'
|
845
|
+
banner 'not eric banner, just some desco'
|
846
|
+
banner 'another not banner, just some chit chat:'
|
847
|
+
opt '--gamma[=<baz>]','gamma is where it\'s at'
|
848
|
+
opt '--[no-]mames', :juae
|
849
|
+
}
|
850
|
+
def foo opts, arg1, arg2
|
851
|
+
@ui.puts "rock on #{arg1} rock on #{arg2}"
|
852
|
+
end
|
853
|
+
|
854
|
+
def bar arg2
|
855
|
+
end
|
856
|
+
end
|
857
|
+
Mod.spec.invocation_name = "mod-app.rb"
|
858
|
+
|
859
|
+
describe Mod do
|
860
|
+
include NanDoc::SpecDoc
|
861
|
+
|
862
|
+
it 'mod-app.rb must work' do
|
863
|
+
exp = <<-HERE.noindent
|
864
|
+
rock on new york rock on chicago
|
865
|
+
HERE
|
866
|
+
act = capture{ run ["foo", "new york", "chicago"] }
|
867
|
+
assert_no_diff(exp, act)
|
868
|
+
end
|
869
|
+
it 'mod-app.rb supressed must work' do
|
870
|
+
OptparseLite.suppress_run!
|
871
|
+
out, err = capture2{ run [] }
|
872
|
+
OptparseLite.enable_run!
|
873
|
+
assert_equal "run disabled. (probably for gentesting)\n", err
|
874
|
+
assert_equal "", out
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
module ForeignParser
|
879
|
+
include OptparseLite
|
880
|
+
class MockParser
|
881
|
+
include OptparseLite::OptsLike
|
882
|
+
Response = OptparseLite::OptParser::Response
|
883
|
+
Error = OptparseLite::OptParser::Error
|
884
|
+
class VersionHaver
|
885
|
+
def version; 'awesome-foo 1.2.3' end
|
886
|
+
end
|
887
|
+
def parse argv
|
888
|
+
if argv.include?('-v')
|
889
|
+
return [
|
890
|
+
Response.new([
|
891
|
+
Error.new(
|
892
|
+
:help_requested, 'nosee',
|
893
|
+
:'version_requested?'=>true,
|
894
|
+
:parser => VersionHaver.new
|
895
|
+
)
|
896
|
+
]),
|
897
|
+
{}]
|
898
|
+
end
|
899
|
+
if argv.include?('-h')
|
900
|
+
return [
|
901
|
+
Response.new([
|
902
|
+
Error.new(:help_requested, 'nosee')
|
903
|
+
]),
|
904
|
+
{}]
|
905
|
+
end
|
906
|
+
if argv.include?('--help')
|
907
|
+
return [
|
908
|
+
Response.new([
|
909
|
+
Error.new(:help_requested, 'nosee', :'long_help?'=>true)
|
910
|
+
]),
|
911
|
+
{}]
|
912
|
+
end
|
913
|
+
|
914
|
+
[Response.new(),{}]
|
915
|
+
end
|
916
|
+
def syntax_tokens; ['-h','-v'] end
|
917
|
+
def doc_sexp; [[:txt,'just pass -v or -h to test this']] end
|
918
|
+
end
|
919
|
+
opts MockParser.new
|
920
|
+
def foo opts
|
921
|
+
@ui.puts opts.inspect
|
922
|
+
end
|
923
|
+
end
|
924
|
+
ForeignParser.spec.invocation_name = "foreign-parser-app.rb"
|
925
|
+
|
926
|
+
describe ForeignParser do
|
927
|
+
include NanDoc::SpecDoc
|
928
|
+
|
929
|
+
it '"foreign-parser-app.rb -h" lists commands' do
|
930
|
+
exp = <<-HERE.noindent
|
931
|
+
\e[32;mUsage:\e[0m foreign-parser-app.rb foo [-h] [-v]
|
932
|
+
\e[32;mDescription:\e[0m
|
933
|
+
just pass -v or -h to test this
|
934
|
+
HERE
|
935
|
+
act = capture{ run ["-h", "foo"] }
|
936
|
+
assert_no_diff(exp, act)
|
937
|
+
end
|
938
|
+
it '"foreign-parser-app.rb <command> -h" gives short command help' do
|
939
|
+
exp = <<-HERE.noindent
|
940
|
+
\e[32;mUsage:\e[0m foreign-parser-app.rb foo [-h] [-v]
|
941
|
+
try \e[32;mforeign-parser-app.rb\e[0m \e[32;mhelp\e[0m \e[32;mfoo\e[0m for full syntax and usage.
|
942
|
+
HERE
|
943
|
+
act = capture{ run ["foo", "-h"] }
|
944
|
+
assert_no_diff(exp, act)
|
945
|
+
end
|
946
|
+
it '"foreign-parser-app.rb <command> --help" gives longer help' do
|
947
|
+
exp = <<-HERE.noindent
|
948
|
+
\e[32;mUsage:\e[0m foreign-parser-app.rb foo [-h] [-v]
|
949
|
+
\e[32;mDescription:\e[0m
|
950
|
+
just pass -v or -h to test this
|
951
|
+
HERE
|
952
|
+
act = capture{ run ["foo", "--help"] }
|
953
|
+
assert_no_diff(exp, act)
|
954
|
+
end
|
955
|
+
it '"foreign-parser-app.rb <command> -v" shows version' do
|
956
|
+
exp = <<-HERE.noindent
|
957
|
+
awesome-foo 1.2.3
|
958
|
+
HERE
|
959
|
+
act = capture{ run ["foo", "-v"] }
|
960
|
+
assert_no_diff(exp, act)
|
961
|
+
end
|
962
|
+
end
|
963
|
+
end
|