optparse-lite 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|