html-proofer 3.6.0 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee04feecbb1a662c1c5023003314a6647292fd13
4
- data.tar.gz: f01200df1a2f69ea90a2bb8cb49feac80bb4593b
3
+ metadata.gz: 6849cc3fcff2f9484b194cbeb1e6a74c5ce569df
4
+ data.tar.gz: a926c5b784dc04b8437b042b11fd96b9f2e0e822
5
5
  SHA512:
6
- metadata.gz: aae793b1fd1d3672cba9a86557efad2b728dd4e09326076c24aeda5203fb03a6aa2600198ae50549d26712ffaf378d405e8f39121e9f0396d34d540f2f5a2c62
7
- data.tar.gz: 0ecb402b29e2721ca83acc1b6582d4642954d2378ad0bb992fdfaa93e6d6a326c7199fad2c5056186bfc18b78bf94565f5375fb6f05e8dda69efd90c3108f804
6
+ metadata.gz: bc5fb91918a157a54496abc4340f4731507a393aca4da5ce21f2afd42c83d49b7636d48777acabb1542e4854944aa0242c798605b3966fb5e55ee805648736d3
7
+ data.tar.gz: 1d7b2107525185bcdc87647c958f71c00d0fa575665a852306de8f945fb18652ad467b76473d5255d1b11de5c101e164363984340385de47aee7cc5482a713ea
data/bin/htmlproofer CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  STDOUT.sync = true
3
3
 
4
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w( .. lib ))
4
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
5
5
 
6
6
  require 'html-proofer'
7
7
  require 'mercenary'
@@ -51,7 +51,7 @@ Mercenary.program(:htmlproofer) do |p|
51
51
  options = {}
52
52
 
53
53
  # prepare everything to go to proofer
54
- p.options.select { |o| !opts[o.config_key].nil? }.each do |option|
54
+ p.options.reject { |o| opts[o.config_key].nil? }.each do |option|
55
55
  if opts[option.config_key].is_a?(Array)
56
56
  opts[option.config_key] = opts[option.config_key].map { |i| HTMLProofer::Configuration.to_regex?(i) }
57
57
  end
data/lib/html-proofer.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # rubocop:disable Style/FileName
2
+
1
3
  def require_all(path)
2
4
  dir = File.join(File.dirname(__FILE__), path)
3
5
  Dir[File.join(dir, '*.rb')].each do |f|
@@ -16,32 +18,30 @@ begin
16
18
  require 'awesome_print'
17
19
  require 'pry'
18
20
  rescue LoadError; end
19
-
20
21
  module HTMLProofer
21
-
22
22
  def check_file(file, options = {})
23
- fail ArgumentError unless file.is_a?(String)
23
+ raise ArgumentError unless file.is_a?(String)
24
24
  options[:type] = :file
25
25
  HTMLProofer::Runner.new(file, options)
26
26
  end
27
27
  module_function :check_file
28
28
 
29
29
  def check_directory(directory, options = {})
30
- fail ArgumentError unless directory.is_a?(String)
30
+ raise ArgumentError unless directory.is_a?(String)
31
31
  options[:type] = :directory
32
32
  HTMLProofer::Runner.new([directory], options)
33
33
  end
34
34
  module_function :check_directory
35
35
 
36
36
  def check_directories(directories, options = {})
37
- fail ArgumentError unless directories.is_a?(Array)
37
+ raise ArgumentError unless directories.is_a?(Array)
38
38
  options[:type] = :directory
39
39
  HTMLProofer::Runner.new(directories, options)
40
40
  end
41
41
  module_function :check_directories
42
42
 
43
43
  def check_links(links, options = {})
44
- fail ArgumentError unless links.is_a?(Array)
44
+ raise ArgumentError unless links.is_a?(Array)
45
45
  options[:type] = :links
46
46
  HTMLProofer::Runner.new(links, options)
47
47
  end
@@ -10,7 +10,7 @@ module HTMLProofer
10
10
  include HTMLProofer::Utils
11
11
 
12
12
  DEFAULT_STORAGE_DIR = File.join('tmp', '.htmlproofer')
13
- DEFAULT_CACHE_FILE_NAME = "cache.log"
13
+ DEFAULT_CACHE_FILE_NAME = 'cache.log'.freeze
14
14
 
15
15
  attr_reader :exists, :cache_log, :storage_dir, :cache_file
16
16
 
@@ -54,17 +54,17 @@ module HTMLProofer
54
54
  when 'h'
55
55
  time.hours.ago
56
56
  else
57
- fail ArgumentError, "#{date} is not a valid timeframe!"
57
+ raise ArgumentError, "#{date} is not a valid timeframe!"
58
58
  end
59
59
  end
60
60
 
61
61
  def add(url, filenames, status, msg = '')
62
62
  data = {
63
- :time => @cache_time,
64
- :filenames => filenames,
65
- :status => status,
66
- :message => msg
67
- }
63
+ time: @cache_time,
64
+ filenames: filenames,
65
+ status: status,
66
+ message: msg
67
+ }
68
68
 
69
69
  @cache_log[clean_url(url)] = data
70
70
  end
@@ -148,28 +148,25 @@ module HTMLProofer
148
148
  end
149
149
 
150
150
  def setup_cache!(options)
151
- if options[:storage_dir]
152
- @storage_dir = options[:storage_dir]
153
- else
154
- @storage_dir = DEFAULT_STORAGE_DIR
155
- end
151
+ @storage_dir = if options[:storage_dir]
152
+ options[:storage_dir]
153
+ else
154
+ DEFAULT_STORAGE_DIR
155
+ end
156
156
 
157
- if !Dir.exist?(storage_dir)
158
- FileUtils.mkdir_p(storage_dir)
159
- end
157
+ FileUtils.mkdir_p(storage_dir) unless Dir.exist?(storage_dir)
160
158
 
161
- if options[:cache_file]
162
- cache_file_name = options[:cache_file]
163
- else
164
- cache_file_name = DEFAULT_CACHE_FILE_NAME
165
- end
159
+ cache_file_name = if options[:cache_file]
160
+ options[:cache_file]
161
+ else
162
+ DEFAULT_CACHE_FILE_NAME
163
+ end
166
164
 
167
165
  @cache_file = File.join(storage_dir, cache_file_name)
168
166
 
169
- if File.exist?(cache_file)
170
- contents = File.read(cache_file)
171
- @cache_log = contents.empty? ? {} : JSON.parse(contents)
172
- end
167
+ return unless File.exist?(cache_file)
168
+ contents = File.read(cache_file)
169
+ @cache_log = contents.empty? ? {} : JSON.parse(contents)
173
170
  end
174
171
  end
175
172
  end
@@ -30,12 +30,10 @@ class ImageCheck < ::HTMLProofer::Check
30
30
  # does the image exist?
31
31
  if missing_src?
32
32
  add_issue('image has no src or srcset attribute', line: line, content: content)
33
- else
34
- if @img.remote?
35
- add_to_external_urls(@img.url)
36
- elsif !@img.exists?
37
- add_issue("internal image #{@img.url} does not exist", line: line, content: content)
38
- end
33
+ elsif @img.remote?
34
+ add_to_external_urls(@img.url)
35
+ elsif !@img.exists?
36
+ add_issue("internal image #{@img.url} does not exist", line: line, content: content)
39
37
  end
40
38
 
41
39
  if !@img.ignore_alt? && (@img.alt.nil? || (empty_alt_tag? && !@img.ignore_empty_alt?))
@@ -40,6 +40,7 @@ class LinkCheck < ::HTMLProofer::Check
40
40
  next if @link.non_http_remote?
41
41
 
42
42
  if !@link.internal? && @link.remote?
43
+ check_sri(line, content) if @link.check_sri?
43
44
  # we need to skip these for now; although the domain main be valid,
44
45
  # curl/Typheous inaccurately return 404s for some links. cc https://git.io/vyCFx
45
46
  next if @link.try(:rel) == 'dns-prefetch'
@@ -107,18 +108,36 @@ class LinkCheck < ::HTMLProofer::Check
107
108
 
108
109
  def hash_check(html, href_hash)
109
110
  decoded_href_hash = URI.decode(href_hash)
110
- href_hash = "'#{href_hash.split("'").join("', \"'\", '")}', ''"
111
- decoded_href_hash = "'#{decoded_href_hash.split("'").join("', \"'\", '")}', ''"
112
- html.xpath("//*[case_insensitive_equals(@id, concat(#{href_hash}))]", \
113
- "//*[case_insensitive_equals(@name, concat(#{href_hash}))]", \
114
- "//*[case_insensitive_equals(@id, concat(#{decoded_href_hash}))]", \
115
- "//*[case_insensitive_equals(@name, concat(#{decoded_href_hash}))]", \
116
- XpathFunctions.new).length > 0
111
+ fragment_ids = [href_hash, decoded_href_hash]
112
+ fragment_ids.include?('top') || !find_fragments(html, fragment_ids).empty?
113
+ end
114
+
115
+ def find_fragments(html, fragment_ids)
116
+ xpaths = fragment_ids.flat_map do |frag_id|
117
+ escaped_frag_id = "'#{frag_id.split("'").join("', \"'\", '")}', ''"
118
+ [
119
+ "//*[case_insensitive_equals(@id, concat(#{escaped_frag_id}))]",
120
+ "//*[case_insensitive_equals(@name, concat(#{escaped_frag_id}))]"
121
+ ]
122
+ end
123
+ xpaths << XpathFunctions.new
124
+
125
+ html.xpath(*xpaths)
126
+ end
127
+
128
+ def check_sri(line, content)
129
+ if !defined?(@link.integrity) && !defined?(@link.crossorigin)
130
+ add_issue("SRI and CORS not provided in: #{@link.src}", line: line, content: content)
131
+ elsif !defined?(@link.integrity)
132
+ add_issue("Integrity is missing in: #{@link.src}", line: line, content: content)
133
+ elsif !defined?(@link.crossorigin)
134
+ add_issue("CORS not provided for external resource in: #{@link.src}", line: line, content: content)
135
+ end
117
136
  end
118
137
 
119
138
  class XpathFunctions
120
139
  def case_insensitive_equals(node_set, str_to_match)
121
- node_set.find_all {|node| node.to_s.downcase == str_to_match.to_s.downcase }
140
+ node_set.find_all { |node| node.to_s.casecmp(str_to_match.to_s.downcase).zero? }
122
141
  end
123
142
  end
124
143
  end
@@ -2,12 +2,12 @@
2
2
 
3
3
  class OpenGraphElement < ::HTMLProofer::Element
4
4
  attr_reader :src
5
-
5
+
6
6
  def initialize(obj, check)
7
7
  super(obj, check)
8
8
  # Fake up src from the content attribute
9
- instance_variable_set("@src", @content)
10
-
9
+ instance_variable_set('@src', @content)
10
+
11
11
  @src.insert 0, 'http:' if @src =~ %r{^//}
12
12
  end
13
13
  end
@@ -16,11 +16,11 @@ class OpenGraphCheck < ::HTMLProofer::Check
16
16
  def missing_src?
17
17
  !@opengraph.src
18
18
  end
19
-
19
+
20
20
  def empty_src?
21
21
  blank?(@opengraph.src)
22
22
  end
23
-
23
+
24
24
  def run
25
25
  @html.css('meta[property="og:url"], meta[property="og:image"]').each do |m|
26
26
  @opengraph = OpenGraphElement.new(m, self)
@@ -19,17 +19,17 @@ class ScriptCheck < ::HTMLProofer::Check
19
19
  add_issue('script is empty and has no src attribute', line: line, content: content)
20
20
  elsif @script.remote?
21
21
  add_to_external_urls(@script.src)
22
+ check_sri(line, content) if @script.check_sri?
22
23
  elsif !@script.exists?
23
24
  add_issue("internal script #{@script.src} does not exist", line: line, content: content)
24
25
  end
25
- check_sri(line, content) if @script.check_sri?
26
26
  end
27
27
 
28
28
  external_urls
29
29
  end
30
30
 
31
31
  def check_sri(line, content)
32
- if !defined? @script.integrity and !defined? @script.crossorigin
32
+ if !defined? @script.integrity && !defined? @script.crossorigin
33
33
  add_issue("SRI and CORS not provided in: #{@script.src}", line: line, content: content)
34
34
  elsif !defined? @script.integrity
35
35
  add_issue("Integrity is missing in: #{@script.src}", line: line, content: content)
@@ -3,54 +3,54 @@ module HTMLProofer
3
3
  require_relative 'version'
4
4
 
5
5
  PROOFER_DEFAULTS = {
6
- :allow_hash_href => false,
7
- :alt_ignore => [],
8
- :assume_extension => false,
9
- :check_external_hash => false,
10
- :check_favicon => false,
11
- :check_html => false,
12
- :check_img_http => false,
13
- :check_opengraph => false,
14
- :checks_to_ignore => [],
15
- :check_sri => false,
16
- :directory_index_file => 'index.html',
17
- :disable_external => false,
18
- :empty_alt_ignore => false,
19
- :enforce_https => false,
20
- :error_sort => :path,
21
- :extension => '.html',
22
- :external_only => false,
23
- :file_ignore => [],
24
- :http_status_ignore => [],
25
- :internal_domains => [],
26
- :log_level => :info,
27
- :only_4xx => false,
28
- :url_ignore => [],
29
- :url_swap => {}
30
- }
6
+ allow_hash_href: false,
7
+ alt_ignore: [],
8
+ assume_extension: false,
9
+ check_external_hash: false,
10
+ check_favicon: false,
11
+ check_html: false,
12
+ check_img_http: false,
13
+ check_opengraph: false,
14
+ checks_to_ignore: [],
15
+ check_sri: false,
16
+ directory_index_file: 'index.html',
17
+ disable_external: false,
18
+ empty_alt_ignore: false,
19
+ enforce_https: false,
20
+ error_sort: :path,
21
+ extension: '.html',
22
+ external_only: false,
23
+ file_ignore: [],
24
+ http_status_ignore: [],
25
+ internal_domains: [],
26
+ log_level: :info,
27
+ only_4xx: false,
28
+ url_ignore: [],
29
+ url_swap: {}
30
+ }.freeze
31
31
 
32
32
  TYPHOEUS_DEFAULTS = {
33
- :followlocation => true,
34
- :headers => {
33
+ followlocation: true,
34
+ headers: {
35
35
  'User-Agent' => "Mozilla/5.0 (compatible; HTML Proofer/#{HTMLProofer::VERSION}; +https://github.com/gjtorikian/html-proofer)"
36
36
  },
37
- :connecttimeout => 10,
38
- :timeout => 30
39
- }
37
+ connecttimeout: 10,
38
+ timeout: 30
39
+ }.freeze
40
40
 
41
41
  HYDRA_DEFAULTS = {
42
- :max_concurrency => 50
43
- }
42
+ max_concurrency: 50
43
+ }.freeze
44
44
 
45
- PARALLEL_DEFAULTS = {}
45
+ PARALLEL_DEFAULTS = {}.freeze
46
46
 
47
47
  VALIDATION_DEFAULTS = {
48
- :report_script_embeds => false,
49
- :report_missing_names => false,
50
- :report_invalid_tags => false
51
- }
48
+ report_script_embeds: false,
49
+ report_missing_names: false,
50
+ report_invalid_tags: false
51
+ }.freeze
52
52
 
53
- CACHE_DEFAULTS = {}
53
+ CACHE_DEFAULTS = {}.freeze
54
54
 
55
55
  def self.to_regex?(item)
56
56
  if item.start_with?('/') && item.end_with?('/')
@@ -11,12 +11,12 @@ module HTMLProofer
11
11
  def initialize(obj, check)
12
12
  # Construct readable ivars for every element
13
13
  obj.attributes.each_pair do |attribute, value|
14
- name = "#{attribute.tr('-:.', '_')}".to_sym
14
+ name = attribute.tr('-:.', '_').to_s.to_sym
15
15
  (class << self; self; end).send(:attr_reader, name)
16
16
  instance_variable_set("@#{name}", value.value)
17
17
  end
18
18
 
19
- @aria_hidden = @aria_hidden == "true" ? true : false
19
+ @aria_hidden = @aria_hidden == 'true' ? true : false
20
20
 
21
21
  @text = obj.content
22
22
  @check = check
@@ -28,7 +28,7 @@ module HTMLProofer
28
28
 
29
29
  parent_attributes = obj.ancestors.map { |a| a.try(:attributes) }
30
30
  parent_attributes.pop # remove document at the end
31
- @parent_ignorable = parent_attributes.any? { |a| !a["data-proofer-ignore"].nil? }
31
+ @parent_ignorable = parent_attributes.any? { |a| !a['data-proofer-ignore'].nil? }
32
32
 
33
33
  # fix up missing protocols
34
34
  @href.insert 0, 'http:' if @href =~ %r{^//}
@@ -38,10 +38,8 @@ module HTMLProofer
38
38
 
39
39
  def url
40
40
  return @url if defined?(@url)
41
- @url = (@src || @srcset || @href || '').gsub("\u200b", '')
42
- if base
43
- @url = Addressable::URI.join(base.attr('href'), url).to_s
44
- end
41
+ @url = (@src || @srcset || @href || '').delete("\u200b")
42
+ @url = Addressable::URI.join(base.attr('href') || '', url).to_s if base
45
43
  return @url if @check.options[:url_swap].empty?
46
44
  @url = swap(@url, @check.options[:url_swap])
47
45
  end
@@ -70,7 +68,7 @@ module HTMLProofer
70
68
 
71
69
  # path is to an external server
72
70
  def remote?
73
- %w( http https ).include? scheme
71
+ %w[http https].include? scheme
74
72
  end
75
73
 
76
74
  def non_http_remote?
@@ -84,7 +82,7 @@ module HTMLProofer
84
82
  return true if url =~ /^javascript:/
85
83
 
86
84
  # ignore base64 encoded images
87
- if %w(ImageCheck FaviconCheck).include? @type
85
+ if %w[ImageCheck FaviconCheck].include? @type
88
86
  return true if url =~ /^data:image/
89
87
  end
90
88
 
@@ -201,14 +199,12 @@ module HTMLProofer
201
199
  end
202
200
 
203
201
  def html
204
- if internal?
205
- # If link is on the same page, then URL is on the current page so can use the same HTML as for current page
206
- if hash_link || param_link
207
- @html
208
- elsif slash_link
209
- # link on another page, e.g. /about#Team - need to get HTML from the other page
210
- create_nokogiri(absolute_path)
211
- end
202
+ # If link is on the same page, then URL is on the current page so can use the same HTML as for current page
203
+ if (hash_link || param_link) && internal?
204
+ @html
205
+ elsif slash_link && internal?
206
+ # link on another page, e.g. /about#Team - need to get HTML from the other page
207
+ create_nokogiri(absolute_path)
212
208
  end
213
209
  end
214
210
  end
@@ -6,11 +6,11 @@ module HTMLProofer
6
6
  include Yell::Loggable
7
7
 
8
8
  def initialize(log_level)
9
- @logger = Yell.new(:format => false, \
10
- :name => 'HTMLProofer', \
11
- :level => "gte.#{log_level}") do |l|
12
- l.adapter :stdout, :level => [:debug, :info, :warn]
13
- l.adapter :stderr, :level => [:error, :fatal]
9
+ @logger = Yell.new(format: false, \
10
+ name: 'HTMLProofer', \
11
+ level: "gte.#{log_level}") do |l|
12
+ l.adapter :stdout, level: %i[debug info warn]
13
+ l.adapter :stderr, level: %i[error fatal]
14
14
  end
15
15
  end
16
16
 
@@ -91,7 +91,7 @@ module HTMLProofer
91
91
  end
92
92
 
93
93
  def check_path(path)
94
- result = { :external_urls => {}, :failures => [] }
94
+ result = { external_urls: {}, failures: [] }
95
95
  html = create_nokogiri(path)
96
96
 
97
97
  @src = [@src] if @type == :file
@@ -164,7 +164,7 @@ module HTMLProofer
164
164
  sorted_failures.sort_and_report
165
165
  count = @failures.length
166
166
  failure_text = pluralize(count, 'failure', 'failures')
167
- fail @logger.colorize :red, "HTML-Proofer found #{failure_text}!"
167
+ raise @logger.colorize :red, "HTML-Proofer found #{failure_text}!"
168
168
  end
169
169
  end
170
170
  end
@@ -123,7 +123,7 @@ module HTMLProofer
123
123
  def clean_url(href)
124
124
  # catch any obvious issues, like strings in port numbers
125
125
  parsed = Addressable::URI.parse(href)
126
- if href !~ %r{^([!#$&-;=?-\[\]_a-z~]|%[0-9a-fA-F]{2})+$}
126
+ if href !~ /^([!#{$&}-;=?-\[\]_a-z~]|%[0-9a-fA-F]{2})+$/
127
127
  parsed.normalize
128
128
  else
129
129
  href
@@ -131,7 +131,7 @@ module HTMLProofer
131
131
  end
132
132
 
133
133
  def queue_request(method, href, filenames)
134
- opts = @options[:typhoeus].merge({ :method => method })
134
+ opts = @options[:typhoeus].merge(method: method)
135
135
  request = Typhoeus::Request.new(href, opts)
136
136
  request.on_complete { |response| response_handler(response, filenames) }
137
137
  @hydra.queue request
@@ -179,7 +179,7 @@ module HTMLProofer
179
179
 
180
180
  # user-content is a special addition by GitHub.
181
181
  xpath = %(//*[@name="#{hash}"]|//*[@id="#{hash}"])
182
- if URI.parse(href).host.match(/github\.com/i)
182
+ if URI.parse(href).host =~ /github\.com/i
183
183
  xpath << %(|//*[@name="user-content-#{hash}"]|//*[@id="user-content-#{hash}"])
184
184
  end
185
185
 
@@ -7,11 +7,11 @@ module HTMLProofer
7
7
  end
8
8
 
9
9
  def create_nokogiri(path)
10
- if File.exist? path
11
- content = File.open(path).read
12
- else
13
- content = path
14
- end
10
+ content = if File.exist? path
11
+ File.open(path).read
12
+ else
13
+ path
14
+ end
15
15
 
16
16
  Nokogiri::HTML(clean_content(content))
17
17
  end
@@ -1,3 +1,3 @@
1
1
  module HTMLProofer
2
- VERSION = '3.6.0'.freeze
2
+ VERSION = '3.7.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-proofer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.0
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-21 00:00:00.000000000 Z
11
+ date: 2017-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mercenary
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.5'
33
+ version: '1.7'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.5'
40
+ version: '1.7'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: colored
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -142,6 +142,34 @@ dependencies:
142
142
  - - ">="
143
143
  - !ruby/object:Gem::Version
144
144
  version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: rubocop
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: rubocop-github
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
145
173
  - !ruby/object:Gem::Dependency
146
174
  name: rspec
147
175
  requirement: !ruby/object:Gem::Requirement
@@ -272,7 +300,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
272
300
  version: '0'
273
301
  requirements: []
274
302
  rubyforge_project:
275
- rubygems_version: 2.4.5.1
303
+ rubygems_version: 2.6.12
276
304
  signing_key:
277
305
  specification_version: 4
278
306
  summary: A set of tests to validate your HTML output. These tests check if your image