Skip to content

Commit df5ba2b

Browse files
authored
Merge pull request #569 from erikhuda/check_default_type
Add `check_default_type!`
2 parents 92e0569 + 1b6c106 commit df5ba2b

File tree

6 files changed

+53
-11
lines changed

6 files changed

+53
-11
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
## 0.20.0
2+
* Add `check_default_type!` to check if the default value of an option matches the defined type.
3+
It removes the warning on usage and gives the command authors the possibility to check for programming errors.
4+
25
* Add `disable_required_check!` to disable check for required options in some commands.
36
It is a substitute of `disable_class_options` that was not working as intended.
47

lib/thor/base.rb

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,21 @@ def check_unknown_options?(config) #:nodoc:
151151
!!check_unknown_options
152152
end
153153

154+
# If you want to raise an error when the default value of an option does not match
155+
# the type call check_default_type!
156+
# This is disabled by default for compatibility.
157+
def check_default_type!
158+
@check_default_type = true
159+
end
160+
161+
def check_default_type #:nodoc:
162+
@check_default_type ||= from_superclass(:check_default_type, false)
163+
end
164+
165+
def check_default_type? #:nodoc:
166+
!!check_default_type
167+
end
168+
154169
# If true, option parsing is suspended as soon as an unknown option or a
155170
# regular argument is encountered. All remaining arguments are passed to
156171
# the command as regular arguments.
@@ -549,7 +564,7 @@ def is_thor_reserved_word?(word, type) #:nodoc:
549564
# options<Hash>:: Described in both class_option and method_option.
550565
# scope<Hash>:: Options hash that is being built up
551566
def build_option(name, options, scope) #:nodoc:
552-
scope[name] = Thor::Option.new(name, options)
567+
scope[name] = Thor::Option.new(name, options.merge(:check_default_type => check_default_type?))
553568
end
554569

555570
# Receives a hash of options, parse them and add to the scope. This is a

lib/thor/parser/option.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class Option < Argument #:nodoc:
55
VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
66

77
def initialize(name, options = {})
8+
@check_default_type = options[:check_default_type]
89
options[:required] = false unless options.key?(:required)
910
super
1011
@lazy_default = options[:lazy_default]
@@ -110,7 +111,7 @@ def #{type}?
110111

111112
def validate!
112113
raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
113-
validate_default_type!
114+
validate_default_type! if @check_default_type
114115
end
115116

116117
def validate_default_type!
@@ -127,8 +128,7 @@ def validate_default_type!
127128
@default.class.name.downcase.to_sym
128129
end
129130

130-
# TODO: This should raise an ArgumentError in a future version of Thor
131-
warn "WARNING: Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
131+
raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
132132
end
133133

134134
def dasherized?

spec/helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
SimpleCov.start do
1010
add_filter "/spec"
11-
minimum_coverage(91.69)
11+
minimum_coverage(90)
1212
end
1313
end
1414

spec/parser/option_spec.rb

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,21 @@ def option(name, options = {})
134134
expect(option).to be_required
135135
end
136136

137-
it "raises an error if default is inconsistent with type" do
138-
expect(capture(:stderr) do
139-
option("foo_bar", :type => :numeric, :default => "baz")
140-
end.chomp).to eq('WARNING: Expected numeric default value for \'--foo-bar\'; got "baz" (string)')
137+
it "raises an error if default is inconsistent with type and check_default_type is true" do
138+
expect do
139+
option("foo_bar", :type => :numeric, :default => "baz", :check_default_type => true)
140+
end.to raise_error(ArgumentError, 'Expected numeric default value for \'--foo-bar\'; got "baz" (string)')
141+
end
142+
143+
it "does not raises an error if default is an symbol and type string and check_default_type is true" do
144+
expect do
145+
option("foo", :type => :string, :default => :bar, :check_default_type => true)
146+
end.not_to raise_error
141147
end
142148

143-
it "does not raises an error if default is an symbol and type string" do
149+
it "does not raises an error if default is inconsistent with type and check_default_type is false" do
144150
expect do
145-
option("foo", :type => :string, :default => :bar)
151+
option("foo_bar", :type => :numeric, :default => "baz", :check_default_type => false)
146152
end.not_to raise_error
147153
end
148154

spec/thor_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,24 @@ def unknown(*args)
583583
expect(klass.start(%w(unknown foo --bar baz))).to eq(%w(foo))
584584
end
585585

586+
it "does not check the default type when check_default_type! is not called" do
587+
expect do
588+
Class.new(Thor) do
589+
option "bar", :type => :numeric, :default => "foo"
590+
end
591+
end.not_to raise_error
592+
end
593+
594+
it "checks the default type when check_default_type! is called" do
595+
expect do
596+
Class.new(Thor) do
597+
check_default_type!
598+
599+
option "bar", :type => :numeric, :default => "foo"
600+
end
601+
end.to raise_error(ArgumentError, "Expected numeric default value for '--bar'; got \"foo\" (string)")
602+
end
603+
586604
it "send as a command name" do
587605
expect(MyScript.start(%w(send))).to eq(true)
588606
end

0 commit comments

Comments
 (0)