diff --git a/config/accessibility.yml b/config/accessibility.yml index 00f871c6..0b140de7 100644 --- a/config/accessibility.yml +++ b/config/accessibility.yml @@ -3,4 +3,7 @@ require: GitHub/Accessibility/ImageHasAlt: Enabled: true - StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/image-has-alt.md \ No newline at end of file + StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/image-has-alt.md +GitHub/Accessibility/NoRedundantImageAlt: + Enabled: true + StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/no-redundant-image-alt.md \ No newline at end of file diff --git a/guides/no-redundant-image-alt.md b/guides/no-redundant-image-alt.md new file mode 100644 index 00000000..2e4fad7f --- /dev/null +++ b/guides/no-redundant-image-alt.md @@ -0,0 +1,24 @@ +# GitHub/Accessibility/NoRedundantImageAlt + +## Rule Details + +Alt prop should not contain `image` or `picture` as screen readers already announce the element as an image + +## Resources + +- [W3C WAI Images Tutorial](https://www.w3.org/WAI/tutorials/images/) +- [Primer: Alternative text for images](https://primer.style/design/accessibility/alternative-text-for-images) + +## Examples +### **Incorrect** code for this rule 👎 + +```erb +<%= image_tag "cat.gif", size: "12x12", alt: "Picture of a cat" %> +``` + +### **Correct** code for this rule 👍 + +```erb + +<%= image_tag "cat.gif", size: "12x12", alt: "A black cat" %> +``` diff --git a/lib/rubocop/cop/github/accessibility/no_redundant_image_alt.rb b/lib/rubocop/cop/github/accessibility/no_redundant_image_alt.rb new file mode 100644 index 00000000..0f84a872 --- /dev/null +++ b/lib/rubocop/cop/github/accessibility/no_redundant_image_alt.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require "rubocop" + +module RuboCop + module Cop + module GitHub + module Accessibility + class NoRedundantImageAlt < Base + MSG = "Alt prop should not contain `image` or `picture` as screen readers already announce the element as an image" + REDUNDANT_ALT_WORDS = %w(image picture) + + def_node_search :redundant_alt?, "(pair (sym :alt) (str #contains_redundant_alt_text?))" + + def on_send(node) + receiver, method_name, _= *node + + if receiver.nil? && method_name == :image_tag + if redundant_alt?(node) + add_offense(node.loc.selector) + end + end + end + + private + + def contains_redundant_alt_text?(string) + return false if string.empty? + + if (string.downcase.split & REDUNDANT_ALT_WORDS).any? + return true + end + end + end + end + end + end +end diff --git a/test/accessibility/test_image_has_alt.rb b/test/test_image_has_alt.rb similarity index 100% rename from test/accessibility/test_image_has_alt.rb rename to test/test_image_has_alt.rb diff --git a/test/test_no_redundant_image_alt.rb b/test/test_no_redundant_image_alt.rb new file mode 100644 index 00000000..c8e91641 --- /dev/null +++ b/test/test_no_redundant_image_alt.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require_relative "./cop_test" +require "minitest/autorun" +require "rubocop/cop/github/accessibility/no_redundant_image_alt" + +class NoRedundantImageAlt < CopTest + def cop_class + RuboCop::Cop::GitHub::Accessibility::NoRedundantImageAlt + end + + def test_no_redundant_image_alt_offense + offenses = erb_investigate cop, <<-ERB, "app/views/products/index.html.erb" + <%= image_tag "cat.gif", size: "12x12", alt: "Picture of a cat" %> + ERB + + assert_equal 1, offenses.count + assert_equal "Alt prop should not contain `image` or `picture` as screen readers already announce the element as an image", offenses[0].message + end + + def test_no_redundant_image_alt_no_offense + offenses = erb_investigate cop, <<-ERB, "app/views/products/index.html.erb" + <%= image_tag "cat.gif", size: "12x12", alt: "A black cat" %> + ERB + + assert_equal 0, offenses.count + end +end