Skip to content

Commit 12a9409

Browse files
committed
Validate options
Validate options on initialization so more user friendly and descriptive errors are thrown when options have invalid values.
1 parent c0e2bde commit 12a9409

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

lib/html_proofer.rb

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,22 @@ def check_file(file, options = {})
2525
raise ArgumentError unless file.is_a?(String)
2626
raise ArgumentError, "#{file} does not exist" unless File.exist?(file)
2727

28-
options[:type] = :file
28+
options = prepare_options(options, :file)
2929
HTMLProofer::Runner.new(file, options)
3030
end
3131

3232
def check_directory(directory, options = {})
3333
raise ArgumentError unless directory.is_a?(String)
3434
raise ArgumentError, "#{directory} does not exist" unless Dir.exist?(directory)
3535

36-
options[:type] = :directory
36+
options = prepare_options(options, :directory)
3737
HTMLProofer::Runner.new([directory], options)
3838
end
3939

4040
def check_directories(directories, options = {})
4141
raise ArgumentError unless directories.is_a?(Array)
4242

43-
options[:type] = :directory
43+
options = prepare_options(options, :directory)
4444
directories.each do |directory|
4545
raise ArgumentError, "#{directory} does not exist" unless Dir.exist?(directory)
4646
end
@@ -50,9 +50,20 @@ def check_directories(directories, options = {})
5050
def check_links(links, options = {})
5151
raise ArgumentError unless links.is_a?(Array)
5252

53-
options[:type] = :links
53+
options = prepare_options(options, :links)
5454
HTMLProofer::Runner.new(links, options)
5555
end
56+
57+
private
58+
59+
def prepare_options(options, type)
60+
options = {} if options.nil?
61+
62+
raise ArgumentError, "Options must be a Hash" unless options.is_a?(Hash)
63+
64+
options[:type] = type
65+
options
66+
end
5667
end
5768
end
5869

lib/html_proofer/configuration.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ module Configuration
4949

5050
class << self
5151
def generate_defaults(opts)
52+
validate_options(default_options, opts)
53+
5254
options = PROOFER_DEFAULTS.merge(opts)
5355

5456
options[:typhoeus] = HTMLProofer::Configuration::TYPHOEUS_DEFAULTS.merge(opts[:typhoeus] || {})
@@ -86,6 +88,24 @@ def parse_json_option(option_name, config, symbolize_names: true)
8688
raise ArgumentError, "Option '#{option_name} did not contain valid JSON."
8789
end
8890
end
91+
92+
private
93+
94+
def default_options
95+
PROOFER_DEFAULTS.merge(typhoeus: TYPHOEUS_DEFAULTS).merge(hydra: HYDRA_DEFAULTS).merge(parallel: PARALLEL_DEFAULTS)
96+
end
97+
98+
def validate_options(defaults, options)
99+
defaults.each do |key, default_value|
100+
next unless options.key?(key)
101+
102+
value = options[key]
103+
raise TypeError, "Invalid value for '#{key}': '#{value}'. Expected #{default_value.class}." unless value.is_a?(default_value.class)
104+
105+
# Iterate over nested hashes
106+
validate_options(default_value, value) if default_value.is_a?(Hash)
107+
end
108+
end
89109
end
90110
end
91111
end

spec/html-proofer/proofer_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,29 @@
4444
typhoeus: { verbose: true, headers: { "User-Agent" => "Mozilla/5.0 (compatible; My New User-Agent)" } })
4545
expect(http["request"]["headers"]["User-Agent"]).to(eq(["Mozilla/5.0 (compatible; My New User-Agent)"]))
4646
end
47+
48+
it "does not fail on nil options" do
49+
github_hash = File.join(FIXTURES_DIR, "links", "github_hash.html")
50+
HTMLProofer.check_file(github_hash, nil)
51+
end
52+
53+
it "fails with friendly error on non-Hash options" do
54+
links_dir = File.join(FIXTURES_DIR, "links")
55+
expect { HTMLProofer.check_directory(links_dir, "abc") }.to(raise_error(ArgumentError, "Options must be a Hash"))
56+
end
57+
58+
it "fails with friendly error on invalid option values" do
59+
options = {
60+
assume_extension: true,
61+
typhoeus: "abc",
62+
enforce_https: :yes_please,
63+
hydra: { max_concurrency: false },
64+
}
65+
options.each do |key, value|
66+
links_dir = File.join(FIXTURES_DIR, "links")
67+
expect { HTMLProofer.check_directory(links_dir, key => value).run }.to(raise_error(TypeError, /^Invalid value for '.*': '.*'\. Expected .*\./))
68+
end
69+
end
4770
end
4871

4972
describe "file ignores" do

0 commit comments

Comments
 (0)