diff --git a/lib/html_proofer.rb b/lib/html_proofer.rb
index ca79c06e..1790aa16 100644
--- a/lib/html_proofer.rb
+++ b/lib/html_proofer.rb
@@ -25,7 +25,7 @@ def check_file(file, options = {})
raise ArgumentError unless file.is_a?(String)
raise ArgumentError, "#{file} does not exist" unless File.exist?(file)
- options[:type] = :file
+ options = prepare_options(options, :file)
HTMLProofer::Runner.new(file, options)
end
@@ -33,14 +33,14 @@ def check_directory(directory, options = {})
raise ArgumentError unless directory.is_a?(String)
raise ArgumentError, "#{directory} does not exist" unless Dir.exist?(directory)
- options[:type] = :directory
+ options = prepare_options(options, :directory)
HTMLProofer::Runner.new([directory], options)
end
def check_directories(directories, options = {})
raise ArgumentError unless directories.is_a?(Array)
- options[:type] = :directory
+ options = prepare_options(options, :directory)
directories.each do |directory|
raise ArgumentError, "#{directory} does not exist" unless Dir.exist?(directory)
end
@@ -50,9 +50,20 @@ def check_directories(directories, options = {})
def check_links(links, options = {})
raise ArgumentError unless links.is_a?(Array)
- options[:type] = :links
+ options = prepare_options(options, :links)
HTMLProofer::Runner.new(links, options)
end
+
+ private
+
+ def prepare_options(options, type)
+ options = {} if options.nil?
+
+ raise ArgumentError, "Options must be a Hash" unless options.is_a?(Hash)
+
+ options[:type] = type
+ options
+ end
end
end
diff --git a/lib/html_proofer/configuration.rb b/lib/html_proofer/configuration.rb
index e49d6ede..a5593b49 100644
--- a/lib/html_proofer/configuration.rb
+++ b/lib/html_proofer/configuration.rb
@@ -49,6 +49,8 @@ module Configuration
class << self
def generate_defaults(opts)
+ validate_options(default_options, opts)
+
options = PROOFER_DEFAULTS.merge(opts)
options[:typhoeus] = HTMLProofer::Configuration::TYPHOEUS_DEFAULTS.merge(opts[:typhoeus] || {})
@@ -86,6 +88,24 @@ def parse_json_option(option_name, config, symbolize_names: true)
raise ArgumentError, "Option '#{option_name} did not contain valid JSON."
end
end
+
+ private
+
+ def default_options
+ PROOFER_DEFAULTS.merge(typhoeus: TYPHOEUS_DEFAULTS).merge(hydra: HYDRA_DEFAULTS).merge(parallel: PARALLEL_DEFAULTS)
+ end
+
+ def validate_options(defaults, options)
+ defaults.each do |key, default_value|
+ next unless options.key?(key)
+
+ value = options[key]
+ raise TypeError, "Invalid value for '#{key}': '#{value}'. Expected #{default_value.class}." unless value.is_a?(default_value.class)
+
+ # Iterate over nested hashes
+ validate_options(default_value, value) if default_value.is_a?(Hash)
+ end
+ end
end
end
end
diff --git a/spec/html-proofer/proofer_spec.rb b/spec/html-proofer/proofer_spec.rb
index ba1e7260..433e90ba 100644
--- a/spec/html-proofer/proofer_spec.rb
+++ b/spec/html-proofer/proofer_spec.rb
@@ -44,6 +44,29 @@
typhoeus: { verbose: true, headers: { "User-Agent" => "Mozilla/5.0 (compatible; My New User-Agent)" } })
expect(http["request"]["headers"]["User-Agent"]).to(eq(["Mozilla/5.0 (compatible; My New User-Agent)"]))
end
+
+ it "does not fail on nil options" do
+ github_hash = File.join(FIXTURES_DIR, "links", "github_hash.html")
+ HTMLProofer.check_file(github_hash, nil)
+ end
+
+ it "fails with friendly error on non-Hash options" do
+ links_dir = File.join(FIXTURES_DIR, "links")
+ expect { HTMLProofer.check_directory(links_dir, "abc") }.to(raise_error(ArgumentError, "Options must be a Hash"))
+ end
+
+ it "fails with friendly error invalid option values" do
+ options = {
+ assume_extension: true,
+ typhoeus: "abc",
+ enforce_https: :yes_please,
+ hydra: { max_concurrency: false },
+ }
+ options.each do |key, value|
+ links_dir = File.join(FIXTURES_DIR, "links")
+ expect { HTMLProofer.check_directory(links_dir, key => value).run }.to(raise_error(TypeError, /^Invalid value for '.*': '.*'\. Expected .*\./))
+ end
+ end
end
describe "file ignores" do