choosy 0.1.0 → 0.2.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/README.markdown +229 -221
- data/Rakefile +21 -3
- data/examples/bar.rb +44 -0
- data/examples/foo.rb +198 -0
- data/examples/superfoo.rb +125 -0
- data/lib/VERSION +1 -1
- data/lib/choosy/argument.rb +51 -0
- data/lib/choosy/base_command.rb +22 -7
- data/lib/choosy/command.rb +12 -4
- data/lib/choosy/dsl/argument_builder.rb +88 -0
- data/lib/choosy/dsl/base_command_builder.rb +71 -56
- data/lib/choosy/dsl/command_builder.rb +14 -2
- data/lib/choosy/dsl/option_builder.rb +43 -83
- data/lib/choosy/dsl/super_command_builder.rb +37 -9
- data/lib/choosy/option.rb +13 -11
- data/lib/choosy/parse_result.rb +8 -27
- data/lib/choosy/parser.rb +20 -16
- data/lib/choosy/printing/color.rb +39 -21
- data/lib/choosy/printing/erb_printer.rb +12 -3
- data/lib/choosy/printing/formatting_element.rb +17 -0
- data/lib/choosy/printing/help_printer.rb +204 -117
- data/lib/choosy/printing/terminal.rb +53 -0
- data/lib/choosy/super_command.rb +6 -6
- data/lib/choosy/super_parser.rb +26 -15
- data/lib/choosy/verifier.rb +61 -6
- data/spec/choosy/base_command_spec.rb +27 -2
- data/spec/choosy/command_spec.rb +31 -9
- data/spec/choosy/dsl/argument_builder_spec.rb +180 -0
- data/spec/choosy/dsl/base_command_builder_spec.rb +87 -44
- data/spec/choosy/dsl/commmand_builder_spec.rb +15 -4
- data/spec/choosy/dsl/option_builder_spec.rb +101 -191
- data/spec/choosy/dsl/super_command_builder_spec.rb +34 -9
- data/spec/choosy/parser_spec.rb +30 -8
- data/spec/choosy/printing/color_spec.rb +19 -5
- data/spec/choosy/printing/help_printer_spec.rb +152 -73
- data/spec/choosy/printing/terminal_spec.rb +27 -0
- data/spec/choosy/super_command_spec.rb +17 -17
- data/spec/choosy/super_parser_spec.rb +20 -10
- data/spec/choosy/verifier_spec.rb +137 -47
- data/spec/integration/command-A_spec.rb +6 -6
- data/spec/integration/command-B_spec.rb +45 -0
- data/spec/integration/supercommand-A_spec.rb +33 -27
- data/spec/integration/supercommand-B_spec.rb +32 -0
- data/spec/spec_helpers.rb +8 -5
- metadata +95 -54
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'choosy/errors'
|
2
|
+
require 'choosy/printing/color'
|
3
|
+
|
4
|
+
module Choosy::Printing
|
5
|
+
module Terminal
|
6
|
+
DEFAULT_LINE_COUNT = 25
|
7
|
+
DEFAULT_COLUMN_COUNT = 80
|
8
|
+
|
9
|
+
def lines
|
10
|
+
@lines ||= find_terminal_size('LINES', 'lines', 0) || DEFAULT_LINE_COUNT
|
11
|
+
end
|
12
|
+
|
13
|
+
def lines=(value)
|
14
|
+
@lines = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def columns
|
18
|
+
@columns ||= find_terminal_size('COLUMNS', 'cols', 1) || DEFAULT_COLUMN_COUNT
|
19
|
+
end
|
20
|
+
|
21
|
+
def columns=(value)
|
22
|
+
@columns = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def color
|
26
|
+
@color ||= Color.new
|
27
|
+
end
|
28
|
+
|
29
|
+
# directly from hirb
|
30
|
+
def command_exists?(command)
|
31
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).any? {|d| File.exists? File.join(d, command) }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
# https://github.com/cldwalker/hirb
|
36
|
+
# modified from hirb
|
37
|
+
def find_terminal_size(env_name, tput_name, stty_index)
|
38
|
+
begin
|
39
|
+
if ENV[env_name] =~ /^\d$/
|
40
|
+
ENV[env_name].to_i
|
41
|
+
elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV['TERM'])) && command_exists?('tput')
|
42
|
+
`tput #{tput_name}`.to_i
|
43
|
+
elsif STDIN.tty? && command_exists?('stty')
|
44
|
+
`stty size`.scan(/\d+/).map { |s| s.to_i }[stty_index]
|
45
|
+
else
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
rescue
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/choosy/super_command.rb
CHANGED
@@ -6,7 +6,7 @@ require 'choosy/dsl/super_command_builder'
|
|
6
6
|
|
7
7
|
module Choosy
|
8
8
|
class SuperCommand < BaseCommand
|
9
|
-
|
9
|
+
attr_accessor :metaname
|
10
10
|
|
11
11
|
def command_builders
|
12
12
|
@command_builders ||= {}
|
@@ -21,7 +21,7 @@ module Choosy
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def parsimonious?
|
24
|
-
@
|
24
|
+
@parsimonious ||= false
|
25
25
|
end
|
26
26
|
|
27
27
|
def execute!(args)
|
@@ -52,12 +52,12 @@ module Choosy
|
|
52
52
|
def handle_help(hc)
|
53
53
|
command_name = hc.message
|
54
54
|
|
55
|
-
if command_name
|
56
|
-
printer.print!(self)
|
55
|
+
if command_name == Choosy::DSL::SuperCommandBuilder::SUPER
|
56
|
+
puts printer.print!(self)
|
57
57
|
else
|
58
58
|
builder = command_builders[command_name]
|
59
59
|
if builder
|
60
|
-
printer.print!(builder.command)
|
60
|
+
puts printer.print!(builder.command)
|
61
61
|
else
|
62
62
|
$stdout << "#{@name}: #{format_help(command_name)}\n"
|
63
63
|
exit 1
|
@@ -66,7 +66,7 @@ module Choosy
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def format_help(command)
|
69
|
-
help = if command_builders[
|
69
|
+
help = if command_builders[Choosy::DSL::SuperCommandBuilder::HELP]
|
70
70
|
"See '#{@name} help'."
|
71
71
|
else
|
72
72
|
""
|
data/lib/choosy/super_parser.rb
CHANGED
@@ -1,40 +1,50 @@
|
|
1
1
|
require 'choosy/errors'
|
2
2
|
require 'choosy/parser'
|
3
3
|
require 'choosy/parse_result'
|
4
|
+
require 'choosy/verifier'
|
5
|
+
require 'choosy/dsl/super_command_builder'
|
4
6
|
|
5
7
|
module Choosy
|
6
8
|
class SuperParser
|
7
|
-
attr_reader :terminals
|
9
|
+
attr_reader :terminals, :verifier
|
8
10
|
|
9
|
-
def initialize(super_command
|
11
|
+
def initialize(super_command)
|
10
12
|
@super_command = super_command
|
11
|
-
@
|
13
|
+
@verifier = Verifier.new
|
12
14
|
generate_terminals
|
13
15
|
end
|
14
16
|
|
15
|
-
def parsimonious?
|
16
|
-
@parsimonious
|
17
|
-
end
|
18
|
-
|
19
17
|
def parse!(args)
|
20
18
|
result = parse_globals(args)
|
21
19
|
unparsed = result.unparsed
|
22
20
|
|
23
21
|
while unparsed.length > 0
|
24
22
|
command_result = parse_command(unparsed, terminals)
|
25
|
-
command_result.options.merge!(result.options)
|
26
23
|
result.subresults << command_result
|
27
24
|
|
28
25
|
unparsed = command_result.unparsed
|
29
26
|
end
|
30
27
|
|
28
|
+
result.subresults.each do |subresult|
|
29
|
+
if subresult.command.name == Choosy::DSL::SuperCommandBuilder::HELP
|
30
|
+
verifier.verify!(subresult)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
verifier.verify!(result)
|
35
|
+
|
36
|
+
result.subresults.each do |subresult|
|
37
|
+
subresult.options.merge!(result.options)
|
38
|
+
verifier.verify!(subresult)
|
39
|
+
end
|
40
|
+
|
31
41
|
result
|
32
42
|
end
|
33
43
|
|
34
44
|
private
|
35
45
|
def generate_terminals
|
36
46
|
@terminals = []
|
37
|
-
if parsimonious?
|
47
|
+
if @super_command.parsimonious?
|
38
48
|
@super_command.commands.each do |c|
|
39
49
|
@terminals << c.name.to_s
|
40
50
|
end
|
@@ -43,14 +53,14 @@ module Choosy
|
|
43
53
|
|
44
54
|
def parse_globals(args)
|
45
55
|
result = SuperParseResult.new(@super_command)
|
46
|
-
parser = Parser.new(@super_command, true)
|
56
|
+
parser = Parser.new(@super_command, true, @terminals)
|
47
57
|
parser.parse!(args, result)
|
48
|
-
|
58
|
+
verifier.verify_special!(result)
|
49
59
|
|
50
60
|
# if we found a global action, we should have hit it by now...
|
51
61
|
if result.unparsed.length == 0
|
52
|
-
if @super_command.command_builders[
|
53
|
-
raise Choosy::HelpCalled.new(
|
62
|
+
if @super_command.command_builders[Choosy::DSL::SuperCommandBuilder::HELP]
|
63
|
+
raise Choosy::HelpCalled.new(Choosy::DSL::SuperCommandBuilder::SUPER)
|
54
64
|
else
|
55
65
|
raise Choosy::SuperParseError.new("requires a command")
|
56
66
|
end
|
@@ -72,9 +82,10 @@ module Choosy
|
|
72
82
|
|
73
83
|
command = command_builder.command
|
74
84
|
parser = Parser.new(command, false, terminals)
|
75
|
-
command_result =
|
85
|
+
command_result = Choosy::ParseResult.new(command, true)
|
86
|
+
parser.parse!(args, command_result)
|
76
87
|
|
77
|
-
command_result
|
88
|
+
command_result
|
78
89
|
end
|
79
90
|
end
|
80
91
|
end
|
data/lib/choosy/verifier.rb
CHANGED
@@ -3,29 +3,61 @@ require 'choosy/dsl/option_builder'
|
|
3
3
|
|
4
4
|
module Choosy
|
5
5
|
class Verifier
|
6
|
-
def
|
6
|
+
def verify!(result)
|
7
7
|
result.command.options.each do |option|
|
8
8
|
required?(option, result)
|
9
9
|
populate!(option, result)
|
10
10
|
convert!(option, result)
|
11
11
|
validate!(option, result)
|
12
12
|
end
|
13
|
+
|
14
|
+
verify_arguments!(result)
|
15
|
+
end
|
16
|
+
|
17
|
+
def verify_special!(result)
|
18
|
+
result.command.options.each do |option|
|
19
|
+
if special?(option)
|
20
|
+
validate!(option, result)
|
21
|
+
end
|
22
|
+
end
|
13
23
|
end
|
14
24
|
|
15
25
|
def verify_arguments!(result)
|
16
|
-
if result.command.
|
17
|
-
result.
|
26
|
+
if result.command.is_a?(Choosy::Command)
|
27
|
+
prefix = if result.subresult?
|
28
|
+
"#{result.command.name}: "
|
29
|
+
else
|
30
|
+
""
|
31
|
+
end
|
32
|
+
|
33
|
+
if result.command.arguments
|
34
|
+
arguments = result.command.arguments
|
35
|
+
|
36
|
+
if result.args.length < arguments.arity.min
|
37
|
+
raise Choosy::ValidationError.new("#{prefix}too few arguments (minimum is #{arguments.arity.min})")
|
38
|
+
elsif result.args.length > arguments.arity.max
|
39
|
+
raise Choosy::ValidationError.new("#{prefix}too many arguments (max is #{arguments.arity.max}): '#{result.args[arguments.arity.max]}'")
|
40
|
+
end
|
41
|
+
|
42
|
+
if arguments.validation_step
|
43
|
+
arguments.validation_step.call(result.args, result.options)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
if result.args.length > 0
|
47
|
+
raise Choosy::ValidationError.new("#{prefix}no arguments allowed: #{result.args.join(' ')}")
|
48
|
+
end
|
49
|
+
end
|
18
50
|
end
|
19
51
|
end
|
20
52
|
|
21
53
|
def required?(option, result)
|
22
54
|
if option.required? && result[option.name].nil?
|
23
|
-
raise ValidationError.new("
|
55
|
+
raise ValidationError.new("required option missing: '#{option.long_flag}'")
|
24
56
|
end
|
25
57
|
end
|
26
58
|
|
27
59
|
def populate!(option, result)
|
28
|
-
return if option
|
60
|
+
return if special?(option)
|
29
61
|
|
30
62
|
if !result.options.has_key?(option.name) # Not already set
|
31
63
|
if !option.default_value.nil? # Has default?
|
@@ -47,10 +79,23 @@ module Choosy
|
|
47
79
|
end
|
48
80
|
end
|
49
81
|
|
82
|
+
def restricted?(option, result)
|
83
|
+
return unless option.restricted?
|
84
|
+
|
85
|
+
value = result[option.name]
|
86
|
+
if option.arity.max > 1
|
87
|
+
value.each do |val|
|
88
|
+
check(option.allowable_values, val)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
check(option.allowable_values, value)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
50
95
|
def validate!(option, result)
|
51
96
|
value = result[option.name]
|
52
97
|
if option.validation_step && exists?(value)
|
53
|
-
option.validation_step.call(value)
|
98
|
+
option.validation_step.call(value, result.options)
|
54
99
|
end
|
55
100
|
end
|
56
101
|
|
@@ -58,5 +103,15 @@ module Choosy
|
|
58
103
|
def exists?(value)
|
59
104
|
value && value != []
|
60
105
|
end
|
106
|
+
|
107
|
+
def special?(option)
|
108
|
+
option.name == Choosy::DSL::OptionBuilder::HELP || option.name == Choosy::DSL::OptionBuilder::VERSION
|
109
|
+
end
|
110
|
+
|
111
|
+
def check(allowable, value)
|
112
|
+
if !allowable.include?(value)
|
113
|
+
raise ValidationError.new("unrecognized value (only #{allowable.map{|s| "'#{s}'"}.join(', ')} allowed): '#{value}'")
|
114
|
+
end
|
115
|
+
end
|
61
116
|
end
|
62
117
|
end
|
@@ -3,9 +3,34 @@ require 'choosy/command'
|
|
3
3
|
|
4
4
|
module Choosy
|
5
5
|
describe BaseCommand do
|
6
|
+
before :each do
|
7
|
+
@cmd = Command.new :cmd
|
8
|
+
end
|
6
9
|
it "should finalize the builder" do
|
7
|
-
cmd
|
8
|
-
cmd.printer.should be_a(Choosy::Printing::HelpPrinter)
|
10
|
+
@cmd.printer.should be_a(Choosy::Printing::HelpPrinter)
|
9
11
|
end
|
12
|
+
|
13
|
+
it "should order the options in dependency order" do
|
14
|
+
@cmd.alter do
|
15
|
+
integer :count, "Count" do
|
16
|
+
depends_on :bold
|
17
|
+
end
|
18
|
+
|
19
|
+
boolean :bold, "Bold" do
|
20
|
+
depends_on :font, :config
|
21
|
+
end
|
22
|
+
|
23
|
+
symbol :font, "Font" do
|
24
|
+
depends_on :config
|
25
|
+
end
|
26
|
+
|
27
|
+
file :config, "The config"
|
28
|
+
file :access, "Access code" do
|
29
|
+
depends_on :config, :count
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
@cmd.options.map {|o| o.name}.should eql([:config, :font, :bold, :count, :access])
|
34
|
+
end
|
10
35
|
end
|
11
36
|
end
|
data/spec/choosy/command_spec.rb
CHANGED
@@ -5,13 +5,15 @@ require 'choosy/printing/help_printer'
|
|
5
5
|
module Choosy
|
6
6
|
describe Command do
|
7
7
|
before :each do
|
8
|
-
@c = Command.new :foo
|
8
|
+
@c = Command.new :foo do
|
9
|
+
arguments
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
13
|
describe :parse! do
|
12
14
|
it "should print out the version number" do
|
13
|
-
@c.alter do
|
14
|
-
|
15
|
+
@c.alter do
|
16
|
+
version "blah"
|
15
17
|
end
|
16
18
|
|
17
19
|
o = capture :stdout do
|
@@ -24,16 +26,15 @@ module Choosy
|
|
24
26
|
end
|
25
27
|
|
26
28
|
it "should print out the help info" do
|
27
|
-
@c.alter do
|
28
|
-
|
29
|
-
|
30
|
-
c.help
|
29
|
+
@c.alter do
|
30
|
+
summary "Summary"
|
31
|
+
help
|
31
32
|
end
|
32
33
|
|
33
34
|
o = capture :stdout do
|
34
|
-
attempting {
|
35
|
+
#attempting {
|
35
36
|
@c.parse!(['--help'])
|
36
|
-
}.should raise_error(SystemExit)
|
37
|
+
#}.should raise_error(SystemExit)
|
37
38
|
end
|
38
39
|
|
39
40
|
o.should match(/-h, --help/)
|
@@ -46,6 +47,27 @@ module Choosy
|
|
46
47
|
@c.execute!(['a', 'b'])
|
47
48
|
}.should raise_error(Choosy::ConfigurationError, /No executor/)
|
48
49
|
end
|
50
|
+
|
51
|
+
it "should call an proc" do
|
52
|
+
p = nil
|
53
|
+
@c.executor = Proc.new {|args, options| p = args}
|
54
|
+
@c.execute!(['a', 'b'])
|
55
|
+
p.should eql(['a', 'b'])
|
56
|
+
end
|
57
|
+
|
58
|
+
class FakeExecutor
|
59
|
+
attr_reader :called
|
60
|
+
def execute!(args, options)
|
61
|
+
@called = args
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should call an executor if given" do
|
66
|
+
exec = FakeExecutor.new
|
67
|
+
@c.executor = exec
|
68
|
+
@c.execute!(['a'])
|
69
|
+
exec.called.should eql(['a'])
|
70
|
+
end
|
49
71
|
end
|
50
72
|
end
|
51
73
|
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'spec_helpers'
|
2
|
+
require 'choosy/dsl/argument_builder'
|
3
|
+
|
4
|
+
module Choosy::DSL
|
5
|
+
describe ArgumentBuilder do
|
6
|
+
before :each do
|
7
|
+
@builder = ArgumentBuilder.new
|
8
|
+
@argument = @builder.argument
|
9
|
+
end
|
10
|
+
|
11
|
+
describe :required do
|
12
|
+
it "should set the argument" do
|
13
|
+
@builder.required
|
14
|
+
@argument.required?.should be(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should set the argument on non-nil/non-true" do
|
18
|
+
@builder.required 1
|
19
|
+
@argument.required?.should be(false)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should set the argument on false" do
|
23
|
+
@builder.required false
|
24
|
+
@argument.required?.should be(false)
|
25
|
+
end
|
26
|
+
end#required
|
27
|
+
|
28
|
+
describe :metaname do
|
29
|
+
it "should be able to set the name of the metaname" do
|
30
|
+
@builder.metaname 'PARAM'
|
31
|
+
@argument.metaname.should eql('PARAM')
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should set the arity on STD+ to 1+" do
|
35
|
+
@builder.metaname 'STD+'
|
36
|
+
@argument.arity.should eql(1..1000)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should set the arity on STD to 1" do
|
40
|
+
@builder.metaname 'STD'
|
41
|
+
@argument.arity.should eql(1..1)
|
42
|
+
end
|
43
|
+
end#metaname
|
44
|
+
|
45
|
+
describe :count do
|
46
|
+
describe "when welformed" do
|
47
|
+
it "should set :at_least the right arity" do
|
48
|
+
@builder.count :at_least => 32
|
49
|
+
@argument.arity.should eql(32..1000)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should set :at_most the right arity" do
|
53
|
+
@builder.count :at_most => 31
|
54
|
+
@argument.arity.should eql(1..31)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should set :once to the right arity" do
|
58
|
+
@builder.count :once
|
59
|
+
@argument.arity.should eql(1..1)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should set :zero to the right arity" do
|
63
|
+
@builder.count :zero
|
64
|
+
@argument.arity.should eql(0..0)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should set :none to the right arity" do
|
68
|
+
@builder.count :none
|
69
|
+
@argument.arity.should eql(0..0)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should set a number exactly" do
|
73
|
+
@builder.count 3
|
74
|
+
@argument.arity.should eql(3..3)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should allow for a range" do
|
78
|
+
@builder.count 1..2
|
79
|
+
@argument.arity.should eql(1..2)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "when malformed" do
|
84
|
+
it "should fail when the :exactly isn't a number" do
|
85
|
+
attempting {
|
86
|
+
@builder.count :exactly => 'p'
|
87
|
+
}.should raise_error(Choosy::ConfigurationError, /number/)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should fail when the :at_most isn't a number" do
|
91
|
+
attempting {
|
92
|
+
@builder.count :at_most => 'p'
|
93
|
+
}.should raise_error(Choosy::ConfigurationError, /number/)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should fail when the :at_least isn't a number" do
|
97
|
+
attempting {
|
98
|
+
@builder.count :at_least => 'p'
|
99
|
+
}.should raise_error(Choosy::ConfigurationError, /number/)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should fail when the :count isn't a number" do
|
103
|
+
attempting {
|
104
|
+
@builder.count 'p'
|
105
|
+
}.should raise_error(Choosy::ConfigurationError, /number/)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should fail when the :at_least is greater than :at_most" do
|
109
|
+
attempting {
|
110
|
+
@builder.count :at_least => 3, :at_most => 2
|
111
|
+
}.should raise_error(Choosy::ConfigurationError, /lower bound/)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end#count
|
115
|
+
|
116
|
+
describe :cast do
|
117
|
+
it "should allow symbol casts" do
|
118
|
+
@builder.cast :int
|
119
|
+
@argument.cast_to.should eql(:integer)
|
120
|
+
end
|
121
|
+
|
122
|
+
class CustomConverter
|
123
|
+
def convert(value)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should allow for custom conversions" do
|
128
|
+
conv = CustomConverter.new
|
129
|
+
@builder.cast conv
|
130
|
+
@argument.cast_to.should be(conv)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should fail if it doesn't know about a Type" do
|
134
|
+
attempting {
|
135
|
+
@builder.cast Choosy::Error
|
136
|
+
}.should raise_error(Choosy::ConfigurationError, /Unknown conversion/)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should fail if it doesn't know about a symbol" do
|
140
|
+
attempting {
|
141
|
+
@builder.cast :unknown_type
|
142
|
+
}.should raise_error(Choosy::ConfigurationError, /Unknown conversion/)
|
143
|
+
end
|
144
|
+
end#cast
|
145
|
+
|
146
|
+
describe :die do
|
147
|
+
it "should fail with a specific error" do
|
148
|
+
attempting {
|
149
|
+
@builder.die("Malformed argument")
|
150
|
+
}.should raise_error(Choosy::ValidationError, /argument error: Malformed/)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe :validate do
|
155
|
+
it "should save the context of the validation in a Proc to call later" do
|
156
|
+
@builder.validate do
|
157
|
+
puts "Hi!"
|
158
|
+
end
|
159
|
+
@argument.validation_step.should be_a(Proc)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should have access to the larger context when called" do
|
163
|
+
value = nil
|
164
|
+
@builder.validate do
|
165
|
+
value = 'here'
|
166
|
+
end
|
167
|
+
@argument.validation_step.call
|
168
|
+
value.should eql('here')
|
169
|
+
end
|
170
|
+
end#validate
|
171
|
+
|
172
|
+
describe :finalize! do
|
173
|
+
it "should set the arity if not already set" do
|
174
|
+
@builder.finalize!
|
175
|
+
@argument.arity.should eql(0..0)
|
176
|
+
end
|
177
|
+
end#finalize!
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|