From 40defbfcd4e9de01c603c04e03926210fd4f39ab Mon Sep 17 00:00:00 2001 From: Petrik Date: Wed, 9 Aug 2023 18:48:10 +0200 Subject: [PATCH] Validate arguments for `method_option` and `class_option` `method_option` and `class_option` require a String or Symbol as the first argument. This can be somewhat confusing when `method_options` and `class_options` require a Hash as argument. --- lib/thor.rb | 5 ++++- lib/thor/base.rb | 3 +++ spec/thor_spec.rb | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/thor.rb b/lib/thor.rb index 7a3ea072..cf999e6e 100644 --- a/lib/thor.rb +++ b/lib/thor.rb @@ -141,7 +141,7 @@ def method_options(options = nil) # # magic # end # - # method_option :foo => :bar, :for => :previous_command + # method_option :foo, :for => :previous_command # # def next_command # # magic @@ -161,6 +161,9 @@ def method_options(options = nil) # :hide - If you want to hide this option from the help. # def method_option(name, options = {}) + unless [ Symbol, String ].any? { |klass| name.is_a?(klass) } + raise ArgumentError, "Expected a Symbol or String, got #{name.inspect}" + end scope = if options[:for] find_and_refresh_command(options[:for]).options else diff --git a/lib/thor/base.rb b/lib/thor/base.rb index 63763b34..d5f5bea0 100644 --- a/lib/thor/base.rb +++ b/lib/thor/base.rb @@ -326,6 +326,9 @@ def class_options(options = nil) # :hide:: -- If you want to hide this option from the help. # def class_option(name, options = {}) + unless [ Symbol, String ].any? { |klass| name.is_a?(klass) } + raise ArgumentError, "Expected a Symbol or String, got #{name.inspect}" + end build_option(name, options, class_options) end diff --git a/spec/thor_spec.rb b/spec/thor_spec.rb index 4f4852fa..16c88dce 100644 --- a/spec/thor_spec.rb +++ b/spec/thor_spec.rb @@ -750,6 +750,22 @@ def hi(name) expect(klass.start(%w(hi --loud jose))).to eq("Hi JOSE") end + it "method_option raises an ArgumentError if name is not a Symbol or String" do + expect do + Class.new(Thor) do + method_option loud: true, type: :boolean + end + end.to raise_error(ArgumentError, "Expected a Symbol or String, got {:loud=>true, :type=>:boolean}") + end + + it "class_option raises an ArgumentError if name is not a Symbol or String" do + expect do + Class.new(Thor) do + class_option loud: true, type: :boolean + end + end.to raise_error(ArgumentError, "Expected a Symbol or String, got {:loud=>true, :type=>:boolean}") + end + it "passes through unknown options" do klass = Class.new(Thor) do desc "unknown", "passing unknown options"