From 43cec1000088d885504d05d7bbbcaa514b6e008a Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Sun, 30 Jul 2017 16:02:06 +0530 Subject: audit: Port patches audit code to a rubocop --- Library/Homebrew/dev-cmd/audit.rb | 31 -------------------- Library/Homebrew/rubocops/extend/formula_cop.rb | 34 +++++++++++++++++++++ Library/Homebrew/rubocops/legacy_patches_cop.rb | 39 +++++-------------------- 3 files changed, 42 insertions(+), 62 deletions(-) diff --git a/Library/Homebrew/dev-cmd/audit.rb b/Library/Homebrew/dev-cmd/audit.rb index 7b5befaa0..1f07fa89e 100644 --- a/Library/Homebrew/dev-cmd/audit.rb +++ b/Library/Homebrew/dev-cmd/audit.rb @@ -630,7 +630,6 @@ class FormulaAuditor end next if spec.patches.empty? - spec.patches.each { |p| patch_problems(p) if p.external? } next unless @new_formula problem "New formulae should not require patches to build. Patches should be submitted and accepted upstream first." end @@ -786,36 +785,6 @@ class FormulaAuditor end end - def patch_problems(patch) - case patch.url - when %r{https?://github\.com/.+/.+/(?:commit|pull)/[a-fA-F0-9]*.(?:patch|diff)} - unless patch.url =~ /\?full_index=\w+$/ - problem <<-EOS.undent - GitHub patches should use the full_index parameter: - #{patch.url}?full_index=1 - EOS - end - when /raw\.github\.com/, %r{gist\.github\.com/raw}, %r{gist\.github\.com/.+/raw}, - %r{gist\.githubusercontent\.com/.+/raw} - unless patch.url =~ /[a-fA-F0-9]{40}/ - problem "GitHub/Gist patches should specify a revision:\n#{patch.url}" - end - when %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)} - problem <<-EOS.undent - use GitHub pull request URLs: - https://github.com/#{Regexp.last_match(1)}/#{Regexp.last_match(2)}/pull/#{Regexp.last_match(3)}.patch?full_index=1 - Rather than patch-diff: - #{patch.url} - EOS - when %r{macports/trunk} - problem "MacPorts patches should specify a revision instead of trunk:\n#{patch.url}" - when %r{^http://trac\.macports\.org} - problem "Patches from MacPorts Trac should be https://, not http:\n#{patch.url}" - when %r{^http://bugs\.debian\.org} - problem "Patches from Debian should be https://, not http:\n#{patch.url}" - end - end - def audit_text bin_names = Set.new bin_names << formula.name diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index 4be0c0fe3..e4a9a5b45 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -380,6 +380,40 @@ module RuboCop add_offense(@offensive_node, @offense_source_range, msg) end + def patch_problems(patch) + patch_url = string_content(patch) + gh_patch_patterns = Regexp.union([%r{/raw\.github\.com/}, + %r{gist\.github\.com/raw}, + %r{gist\.github\.com/.+/raw}, + %r{gist\.githubusercontent\.com/.+/raw}]) + if regex_match_group(patch, gh_patch_patterns) + unless patch_url =~ /[a-fA-F0-9]{40}/ + problem "GitHub/Gist patches should specify a revision:\n#{patch_url}" + end + end + + gh_patch_diff_pattern = %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)} + if match_obj = regex_match_group(patch, gh_patch_diff_pattern) + problem <<-EOS.undent + use GitHub pull request URLs: + https://github.com/#{match_obj[1]}/#{match_obj[2]}/pull/#{match_ojb[3]}.patch + Rather than patch-diff: + #{patch_url} + EOS + end + + if regex_match_group(patch, %r{macports/trunk}) + problem "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}" + end + + if regex_match_group(patch, %r{^http://trac\.macports\.org}) + problem "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}" + end + + return unless regex_match_group(patch, %r{^http://bugs\.debian\.org}) + problem "Patches from Debian should be https://, not http:\n#{patch_url}" + end + private def formula_class?(node) diff --git a/Library/Homebrew/rubocops/legacy_patches_cop.rb b/Library/Homebrew/rubocops/legacy_patches_cop.rb index e569f650e..25a580b12 100644 --- a/Library/Homebrew/rubocops/legacy_patches_cop.rb +++ b/Library/Homebrew/rubocops/legacy_patches_cop.rb @@ -13,39 +13,16 @@ module RuboCop problem "Use the patch DSL instead of defining a 'patches' method" legacy_patches.each { |p| patch_problems(p) } end + end - def patch_problems(patch) - patch_url = string_content(patch) - gh_patch_patterns = Regexp.union([%r{/raw\.github\.com/}, - %r{gist\.github\.com/raw}, - %r{gist\.github\.com/.+/raw}, - %r{gist\.githubusercontent\.com/.+/raw}]) - if regex_match_group(patch, gh_patch_patterns) - unless patch_url =~ /[a-fA-F0-9]{40}/ - problem "GitHub/Gist patches should specify a revision:\n#{patch_url}" - end - end - - gh_patch_diff_pattern = %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)} - if match_obj = regex_match_group(patch, gh_patch_diff_pattern) - problem <<-EOS.undent - use GitHub pull request URLs: - https://github.com/#{match_obj[1]}/#{match_obj[2]}/pull/#{match_ojb[3]}.patch - Rather than patch-diff: - #{patch_url} - EOS - end - - if regex_match_group(patch, %r{macports/trunk}) - problem "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}" - end - - if regex_match_group(patch, %r{^http://trac\.macports\.org}) - problem "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}" + class ExternalPatches < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body) + patches = find_all_blocks(body, :patch) + patches.each do |patch_block| + url_node = find_node_method_by_name(patch_block, :url) + url_string = parameters(url_node).first + patch_problems(url_string) end - - return unless regex_match_group(patch, %r{^http://bugs\.debian\.org}) - problem "Patches from Debian should be https://, not http:\n#{patch_url}" end end end -- cgit v1.2.3 From 66ffdb5b062d8361433897c723f40a66cf382e82 Mon Sep 17 00:00:00 2001 From: Gautham Goli Date: Tue, 1 Aug 2017 20:59:17 +0530 Subject: Refactor legacy_patches_cop to merge external patch audit rules in a single cop and add tests --- Library/Homebrew/rubocops.rb | 2 +- Library/Homebrew/rubocops/extend/formula_cop.rb | 34 ---- Library/Homebrew/rubocops/legacy_patches_cop.rb | 30 --- Library/Homebrew/rubocops/patches_cop.rb | 62 +++++++ .../test/rubocops/legacy_patches_cop_spec.rb | 128 ------------- Library/Homebrew/test/rubocops/patches_cop_spec.rb | 201 +++++++++++++++++++++ 6 files changed, 264 insertions(+), 193 deletions(-) delete mode 100644 Library/Homebrew/rubocops/legacy_patches_cop.rb create mode 100644 Library/Homebrew/rubocops/patches_cop.rb delete mode 100644 Library/Homebrew/test/rubocops/legacy_patches_cop_spec.rb create mode 100644 Library/Homebrew/test/rubocops/patches_cop_spec.rb diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index 4323e044c..b1144e075 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -6,7 +6,7 @@ require_relative "./rubocops/homepage_cop" require_relative "./rubocops/text_cop" require_relative "./rubocops/caveats_cop" require_relative "./rubocops/checksum_cop" -require_relative "./rubocops/legacy_patches_cop" +require_relative "./rubocops/patches_cop" require_relative "./rubocops/conflicts_cop" require_relative "./rubocops/options_cop" require_relative "./rubocops/urls_cop" diff --git a/Library/Homebrew/rubocops/extend/formula_cop.rb b/Library/Homebrew/rubocops/extend/formula_cop.rb index e4a9a5b45..4be0c0fe3 100644 --- a/Library/Homebrew/rubocops/extend/formula_cop.rb +++ b/Library/Homebrew/rubocops/extend/formula_cop.rb @@ -380,40 +380,6 @@ module RuboCop add_offense(@offensive_node, @offense_source_range, msg) end - def patch_problems(patch) - patch_url = string_content(patch) - gh_patch_patterns = Regexp.union([%r{/raw\.github\.com/}, - %r{gist\.github\.com/raw}, - %r{gist\.github\.com/.+/raw}, - %r{gist\.githubusercontent\.com/.+/raw}]) - if regex_match_group(patch, gh_patch_patterns) - unless patch_url =~ /[a-fA-F0-9]{40}/ - problem "GitHub/Gist patches should specify a revision:\n#{patch_url}" - end - end - - gh_patch_diff_pattern = %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)} - if match_obj = regex_match_group(patch, gh_patch_diff_pattern) - problem <<-EOS.undent - use GitHub pull request URLs: - https://github.com/#{match_obj[1]}/#{match_obj[2]}/pull/#{match_ojb[3]}.patch - Rather than patch-diff: - #{patch_url} - EOS - end - - if regex_match_group(patch, %r{macports/trunk}) - problem "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}" - end - - if regex_match_group(patch, %r{^http://trac\.macports\.org}) - problem "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}" - end - - return unless regex_match_group(patch, %r{^http://bugs\.debian\.org}) - problem "Patches from Debian should be https://, not http:\n#{patch_url}" - end - private def formula_class?(node) diff --git a/Library/Homebrew/rubocops/legacy_patches_cop.rb b/Library/Homebrew/rubocops/legacy_patches_cop.rb deleted file mode 100644 index 25a580b12..000000000 --- a/Library/Homebrew/rubocops/legacy_patches_cop.rb +++ /dev/null @@ -1,30 +0,0 @@ -require_relative "./extend/formula_cop" -require_relative "../extend/string" - -module RuboCop - module Cop - module FormulaAudit - # This cop checks for and audits legacy patches in Formulae - class LegacyPatches < FormulaCop - def audit_formula(_node, _class_node, _parent_class_node, body) - patches_node = find_method_def(body, :patches) - return if patches_node.nil? - legacy_patches = find_strings(patches_node) - problem "Use the patch DSL instead of defining a 'patches' method" - legacy_patches.each { |p| patch_problems(p) } - end - end - - class ExternalPatches < FormulaCop - def audit_formula(_node, _class_node, _parent_class_node, body) - patches = find_all_blocks(body, :patch) - patches.each do |patch_block| - url_node = find_node_method_by_name(patch_block, :url) - url_string = parameters(url_node).first - patch_problems(url_string) - end - end - end - end - end -end diff --git a/Library/Homebrew/rubocops/patches_cop.rb b/Library/Homebrew/rubocops/patches_cop.rb new file mode 100644 index 000000000..fb14d8acc --- /dev/null +++ b/Library/Homebrew/rubocops/patches_cop.rb @@ -0,0 +1,62 @@ +require_relative "./extend/formula_cop" +require_relative "../extend/string" + +module RuboCop + module Cop + module FormulaAudit + # This cop audits patches in Formulae + class Patches < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body) + external_patches = find_all_blocks(body, :patch) + external_patches.each do |patch_block| + url_node = find_every_method_call_by_name(patch_block, :url).first + url_string = parameters(url_node).first + patch_problems(url_string) + end + + patches_node = find_method_def(body, :patches) + return if patches_node.nil? + legacy_patches = find_strings(patches_node) + problem "Use the patch DSL instead of defining a 'patches' method" + legacy_patches.each { |p| patch_problems(p) } + end + + private + + def patch_problems(patch) + patch_url = string_content(patch) + gh_patch_patterns = Regexp.union([%r{/raw\.github\.com/}, + %r{gist\.github\.com/raw}, + %r{gist\.github\.com/.+/raw}, + %r{gist\.githubusercontent\.com/.+/raw}]) + if regex_match_group(patch, gh_patch_patterns) + unless patch_url =~ /[a-fA-F0-9]{40}/ + problem "GitHub/Gist patches should specify a revision:\n#{patch_url}" + end + end + + gh_patch_diff_pattern = %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)} + if match_obj = regex_match_group(patch, gh_patch_diff_pattern) + problem <<-EOS.undent + use GitHub pull request URLs: + https://github.com/#{match_obj[1]}/#{match_obj[2]}/pull/#{match_obj[3]}.patch + Rather than patch-diff: + #{patch_url} + EOS + end + + if regex_match_group(patch, %r{macports/trunk}) + problem "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}" + end + + if regex_match_group(patch, %r{^http://trac\.macports\.org}) + problem "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}" + end + + return unless regex_match_group(patch, %r{^http://bugs\.debian\.org}) + problem "Patches from Debian should be https://, not http:\n#{patch_url}" + end + end + end + end +end diff --git a/Library/Homebrew/test/rubocops/legacy_patches_cop_spec.rb b/Library/Homebrew/test/rubocops/legacy_patches_cop_spec.rb deleted file mode 100644 index a08fa614d..000000000 --- a/Library/Homebrew/test/rubocops/legacy_patches_cop_spec.rb +++ /dev/null @@ -1,128 +0,0 @@ -require "rubocop" -require "rubocop/rspec/support" -require_relative "../../extend/string" -require_relative "../../rubocops/legacy_patches_cop" - -describe RuboCop::Cop::FormulaAudit::LegacyPatches do - subject(:cop) { described_class.new } - - context "When auditing legacy patches" do - it "When there is no legacy patch" do - source = <<-EOS.undent - class Foo < Formula - url 'http://example.com/foo-1.0.tgz' - end - EOS - inspect_source(cop, source) - expect(cop.offenses).to eq([]) - end - - it "Formula with `def patches`" do - source = <<-EOS.undent - class Foo < Formula - homepage "ftp://example.com/foo" - url "http://example.com/foo-1.0.tgz" - def patches - DATA - end - end - EOS - - expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method", - severity: :convention, - line: 4, - column: 2, - source: source }] - - inspect_source(cop, source) - - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end - end - - it "Patch URLs" do - patch_urls = [ - "https://raw.github.com/mogaal/sendemail", - "https://mirrors.ustc.edu.cn/macports/trunk/", - "http://trac.macports.org/export/102865/trunk/dports/mail/uudeview/files/inews.c.patch", - "http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=patch-libunac1.txt;att=1;bug=623340", - ] - patch_urls.each do |patch_url| - source = <<-EOS.undent - class Foo < Formula - homepage "ftp://example.com/foo" - url "http://example.com/foo-1.0.tgz" - def patches - "#{patch_url}" - end - end - EOS - - inspect_source(cop, source) - if patch_url =~ %r{/raw\.github\.com/} - expected_offenses = [{ message: "GitHub/Gist patches should specify a revision:\n#{patch_url}", - severity: :convention, - line: 5, - column: 12, - source: source }] - elsif patch_url =~ %r{macports/trunk} - expected_offenses = [{ message: "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}", - severity: :convention, - line: 5, - column: 33, - source: source }] - elsif patch_url =~ %r{^http://trac\.macports\.org} - expected_offenses = [{ message: "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}", - severity: :convention, - line: 5, - column: 5, - source: source }] - elsif patch_url =~ %r{^http://bugs\.debian\.org} - expected_offenses = [{ message: "Patches from Debian should be https://, not http:\n#{patch_url}", - severity: :convention, - line: 5, - column: 5, - source: source }] - end - expected_offenses.zip([cop.offenses.last]).each do |expected, actual| - expect_offense(expected, actual) - end - end - end - - it "Formula with nested `def patches`" do - source = <<-EOS.undent - class Foo < Formula - homepage "ftp://example.com/foo" - url "http://example.com/foo-1.0.tgz" - def patches - files = %w[patch-domain_resolver.c patch-colormask.c patch-trafshow.c patch-trafshow.1 patch-configure] - { - :p0 => - files.collect{|p| "http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/\#{p}"} - } - end - end - EOS - - expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method", - severity: :convention, - line: 4, - column: 2, - source: source }, - { message: "Patches from MacPorts Trac should be https://, not http:\n"\ - "http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/", - severity: :convention, - line: 8, - column: 26, - source: source }] - - inspect_source(cop, source) - - expected_offenses.zip(cop.offenses).each do |expected, actual| - expect_offense(expected, actual) - end - end - end -end diff --git a/Library/Homebrew/test/rubocops/patches_cop_spec.rb b/Library/Homebrew/test/rubocops/patches_cop_spec.rb new file mode 100644 index 000000000..4bd79bf35 --- /dev/null +++ b/Library/Homebrew/test/rubocops/patches_cop_spec.rb @@ -0,0 +1,201 @@ +require "rubocop" +require "rubocop/rspec/support" +require_relative "../../extend/string" +require_relative "../../rubocops/patches_cop" + +describe RuboCop::Cop::FormulaAudit::Patches do + subject(:cop) { described_class.new } + + context "When auditing legacy patches" do + it "When there is no legacy patch" do + source = <<-EOS.undent + class Foo < Formula + url 'http://example.com/foo-1.0.tgz' + end + EOS + inspect_source(cop, source) + expect(cop.offenses).to eq([]) + end + + it "Formula with `def patches`" do + source = <<-EOS.undent + class Foo < Formula + homepage "ftp://example.com/foo" + url "http://example.com/foo-1.0.tgz" + def patches + DATA + end + end + EOS + + expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method", + severity: :convention, + line: 4, + column: 2, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + + it "Patch URLs" do + patch_urls = [ + "https://raw.github.com/mogaal/sendemail", + "https://mirrors.ustc.edu.cn/macports/trunk/", + "http://trac.macports.org/export/102865/trunk/dports/mail/uudeview/files/inews.c.patch", + "http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=patch-libunac1.txt;att=1;bug=623340", + "https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch", + ] + patch_urls.each do |patch_url| + source = <<-EOS.undent + class Foo < Formula + homepage "ftp://example.com/foo" + url "http://example.com/foo-1.0.tgz" + def patches + "#{patch_url}" + end + end + EOS + + inspect_source(cop, source) + if patch_url =~ %r{/raw\.github\.com/} + expected_offenses = [{ message: "GitHub/Gist patches should specify a revision:\n#{patch_url}", + severity: :convention, + line: 5, + column: 12, + source: source }] + elsif patch_url =~ %r{macports/trunk} + expected_offenses = [{ message: "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}", + severity: :convention, + line: 5, + column: 33, + source: source }] + elsif patch_url =~ %r{^http://trac\.macports\.org} + expected_offenses = [{ message: "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}", + severity: :convention, + line: 5, + column: 5, + source: source }] + elsif patch_url =~ %r{^http://bugs\.debian\.org} + expected_offenses = [{ message: "Patches from Debian should be https://, not http:\n#{patch_url}", + severity: :convention, + line: 5, + column: 5, + source: source }] + elsif patch_url =~ %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)} + expected_offenses = [{ message: "use GitHub pull request URLs:\n"\ + " https://github.com/foo/foo-bar/pull/100.patch\n"\ + "Rather than patch-diff:\n"\ + " https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch\n", + severity: :convention, + line: 5, + column: 5, + source: source }] + end + expected_offenses.zip([cop.offenses.last]).each do |expected, actual| + expect_offense(expected, actual) + end + end + end + + it "Formula with nested `def patches`" do + source = <<-EOS.undent + class Foo < Formula + homepage "ftp://example.com/foo" + url "http://example.com/foo-1.0.tgz" + def patches + files = %w[patch-domain_resolver.c patch-colormask.c patch-trafshow.c patch-trafshow.1 patch-configure] + { + :p0 => + files.collect{|p| "http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/\#{p}"} + } + end + end + EOS + + expected_offenses = [{ message: "Use the patch DSL instead of defining a 'patches' method", + severity: :convention, + line: 4, + column: 2, + source: source }, + { message: "Patches from MacPorts Trac should be https://, not http:\n"\ + "http://trac.macports.org/export/68507/trunk/dports/net/trafshow/files/", + severity: :convention, + line: 8, + column: 26, + source: source }] + + inspect_source(cop, source) + + expected_offenses.zip(cop.offenses).each do |expected, actual| + expect_offense(expected, actual) + end + end + end + + context "When auditing external patches" do + it "Patch URLs" do + patch_urls = [ + "https://raw.github.com/mogaal/sendemail", + "https://mirrors.ustc.edu.cn/macports/trunk/", + "http://trac.macports.org/export/102865/trunk/dports/mail/uudeview/files/inews.c.patch", + "http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=patch-libunac1.txt;att=1;bug=623340", + "https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch", + ] + patch_urls.each do |patch_url| + source = <<-EOS.undent + class Foo < Formula + homepage "ftp://example.com/foo" + url "http://example.com/foo-1.0.tgz" + patch do + url "#{patch_url}" + sha256 "63376b8fdd6613a91976106d9376069274191860cd58f039b29ff16de1925621" + end + end + EOS + + inspect_source(cop, source) + if patch_url =~ %r{/raw\.github\.com/} + expected_offenses = [{ message: "GitHub/Gist patches should specify a revision:\n#{patch_url}", + severity: :convention, + line: 5, + column: 16, + source: source }] + elsif patch_url =~ %r{macports/trunk} + expected_offenses = [{ message: "MacPorts patches should specify a revision instead of trunk:\n#{patch_url}", + severity: :convention, + line: 5, + column: 37, + source: source }] + elsif patch_url =~ %r{^http://trac\.macports\.org} + expected_offenses = [{ message: "Patches from MacPorts Trac should be https://, not http:\n#{patch_url}", + severity: :convention, + line: 5, + column: 9, + source: source }] + elsif patch_url =~ %r{^http://bugs\.debian\.org} + expected_offenses = [{ message: "Patches from Debian should be https://, not http:\n#{patch_url}", + severity: :convention, + line: 5, + column: 9, + source: source }] + elsif patch_url =~ %r{https?://patch-diff\.githubusercontent\.com/raw/(.+)/(.+)/pull/(.+)\.(?:diff|patch)} + expected_offenses = [{ message: "use GitHub pull request URLs:\n"\ + " https://github.com/foo/foo-bar/pull/100.patch\n"\ + "Rather than patch-diff:\n"\ + " https://patch-diff.githubusercontent.com/raw/foo/foo-bar/pull/100.patch\n", + severity: :convention, + line: 5, + column: 9, + source: source }] + end + expected_offenses.zip([cop.offenses.last]).each do |expected, actual| + expect_offense(expected, actual) + end + end + end + end +end -- cgit v1.2.3