Skip to content

Commit 52629bd

Browse files
committed
Add check_default_type!
It check if the default value of an option matches the defined type. This removes the warning on usage since there is no much what the command users could do about it and give the command authors the possibility to check for programming errors.
1 parent 92e0569 commit 52629bd

File tree

5 files changed

+52
-10
lines changed

5 files changed

+52
-10
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/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)