aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorMarkus Reiter2017-02-28 13:42:52 +0100
committerMarkus Reiter2017-02-28 13:46:13 +0100
commitebe4042b2f9b7b66e1c2ee9082de002795ea0b81 (patch)
treea42d18c48a0a5384ff124d0071a74560759e3997 /Library
parent668d7a0c49127e2a5e6c3dd01cc518b241d4f110 (diff)
downloadbrew-ebe4042b2f9b7b66e1c2ee9082de002795ea0b81.tar.bz2
Convert FormulaAuditor test to spec.
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/test/audit_test.rb464
-rw-r--r--Library/Homebrew/test/dev-cmd/audit_spec.rb498
-rw-r--r--Library/Homebrew/test/spec_helper.rb4
3 files changed, 502 insertions, 464 deletions
diff --git a/Library/Homebrew/test/audit_test.rb b/Library/Homebrew/test/audit_test.rb
deleted file mode 100644
index b8f01602c..000000000
--- a/Library/Homebrew/test/audit_test.rb
+++ /dev/null
@@ -1,464 +0,0 @@
-require "testing_env"
-require "fileutils"
-require "pathname"
-require "formulary"
-require "dev-cmd/audit"
-
-class FormulaAuditorTests < Homebrew::TestCase
- def setup
- super
- @dir = mktmpdir
- end
-
- def formula_auditor(name, text, options = {})
- path = Pathname.new "#{@dir}/#{name}.rb"
- path.open("w") do |f|
- f.write text
- end
- FormulaAuditor.new Formulary.factory(path), options
- end
-
- def test_init_no_problems
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- assert_equal [], fa.problems
- end
-
- def test_audit_file_permissions
- File.stubs(:umask).returns 022
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- path = fa.formula.path
- path.chmod 0400
-
- fa.audit_file
- assert_equal ["Incorrect file permissions (400): chmod 644 #{path}"],
- fa.problems
- end
-
- def test_audit_file_data_no_end
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- patch :DATA
- end
- EOS
- fa.audit_file
- assert_equal ["'DATA' was found, but no '__END__'"], fa.problems
- end
-
- def test_audit_file_end_no_data
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- __END__
- a patch goes here
- EOS
- fa.audit_file
- assert_equal ["'__END__' was found, but 'DATA' is not used"], fa.problems
- end
-
- def test_audit_file_no_trailing_newline
- fa = formula_auditor "foo", 'class Foo<Formula; url "file:///foo-1.0.tgz";end'
- fa.audit_file
- assert_equal ["File should end with a newline"], fa.problems
- end
-
- def test_audit_file_not_strict_no_issue
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- homepage "http://example.com"
- end
- EOS
- fa.audit_file
- assert_equal [], fa.problems
- end
-
- def test_audit_file_strict_ordering_issue
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- homepage "http://example.com"
- end
- EOS
- fa.audit_file
- assert_equal ["`homepage` (line 3) should be put before `url` (line 2)"],
- fa.problems
- end
-
- def test_audit_file_strict_resource_placement
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- url "https://example.com/foo-1.0.tgz"
-
- resource "foo2" do
- url "https://example.com/foo-2.0.tgz"
- end
-
- depends_on "openssl"
- end
- EOS
- fa.audit_file
- assert_equal ["`depends_on` (line 8) should be put before `resource` (line 4)"],
- fa.problems
- end
-
- def test_audit_file_strict_plist_placement
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- url "https://example.com/foo-1.0.tgz"
-
- test do
- assert_match "Dogs are terrific", shell_output("./dogs")
- end
-
- def plist
- end
- end
- EOS
- fa.audit_file
- assert_equal ["`plist block` (line 8) should be put before `test block` (line 4)"],
- fa.problems
- end
-
- def test_audit_file_strict_url_outside_of_stable_block
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- stable do
- # stuff
- end
- end
- EOS
- fa.audit_file
- assert_equal ["`url` should be put inside `stable block`"], fa.problems
- end
-
- def test_audit_file_strict_head_and_head_do
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- head "http://example.com/foo.git"
- head do
- # stuff
- end
- end
- EOS
- fa.audit_file
- assert_equal ["Should not have both `head` and `head do`"], fa.problems
- end
-
- def test_audit_file_strict_bottle_and_bottle_do
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- bottle do
- # bottles go here
- end
- bottle :unneeded
- end
- EOS
- fa.audit_file
- assert_equal ["Should not have `bottle :unneeded/:disable` and `bottle do`"],
- fa.problems
- end
-
- def test_audit_class_no_test
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
- fa.audit_class
- assert_equal [], fa.problems
-
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
- fa.audit_class
- assert_equal ["A `test do` test block should be added"], fa.problems
- end
-
- def test_audit_class_github_gist_formula
- needs_compat
- require "compat/formula_specialties"
-
- ENV.delete("HOMEBREW_DEVELOPER")
- fa = shutup do
- formula_auditor "foo", <<-EOS.undent
- class Foo < GithubGistFormula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
- end
- fa.audit_class
- assert_equal ["GithubGistFormula is deprecated, use Formula instead"],
- fa.problems
- end
-
- def test_audit_class_script_file_formula
- needs_compat
- require "compat/formula_specialties"
-
- ENV.delete("HOMEBREW_DEVELOPER")
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < ScriptFileFormula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
- fa.audit_class
- assert_equal ["ScriptFileFormula is deprecated, use Formula instead"],
- fa.problems
- end
-
- def test_audit_class_aws_formula
- needs_compat
- require "compat/formula_specialties"
-
- ENV.delete("HOMEBREW_DEVELOPER")
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < AmazonWebServicesFormula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
- fa.audit_class
- assert_equal ["AmazonWebServicesFormula is deprecated, use Formula instead"],
- fa.problems
- end
-
- def test_audit_line_pkgshare
- fa = formula_auditor "foo", <<-EOS.undent, strict: true
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
- fa.audit_line 'ohai "#{share}/foo"', 3
- assert_equal "Use \#{pkgshare} instead of \#{share}/foo", fa.problems.shift
-
- fa.audit_line 'ohai "#{share}/foo/bar"', 3
- assert_equal "Use \#{pkgshare} instead of \#{share}/foo", fa.problems.shift
-
- fa.audit_line 'ohai share/"foo"', 3
- assert_equal 'Use pkgshare instead of (share/"foo")', fa.problems.shift
-
- fa.audit_line 'ohai share/"foo/bar"', 3
- assert_equal 'Use pkgshare instead of (share/"foo")', fa.problems.shift
-
- fa.audit_line 'ohai "#{share}/foo-bar"', 3
- assert_equal [], fa.problems
- fa.audit_line 'ohai share/"foo-bar"', 3
- assert_equal [], fa.problems
- fa.audit_line 'ohai share/"bar"', 3
- assert_equal [], fa.problems
- end
-
- # Regression test for https://github.com/Homebrew/legacy-homebrew/pull/48744
- # Formulae with "++" in their name would break various audit regexps:
- # Error: nested *?+ in regexp: /^libxml++3\s/
- def test_audit_plus_plus_name
- fa = formula_auditor "foolibc++", <<-EOS.undent, strict: true
- class Foolibcxx < Formula
- desc "foolibc++ is a test"
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- fa.audit_desc
- assert_equal "Description shouldn't include the formula name",
- fa.problems.shift
-
- fa.audit_line 'ohai "#{share}/foolibc++"', 3
- assert_equal "Use \#{pkgshare} instead of \#{share}/foolibc++", fa.problems.shift
-
- fa.audit_line 'ohai share/"foolibc++"', 3
- assert_equal 'Use pkgshare instead of (share/"foolibc++")', fa.problems.shift
- end
-
- def test_audit_line_space_in_class_inheritance
- fa = formula_auditor "foo", "class Foo<Formula; url '/foo-1.0.tgz'; end"
- fa.audit_line "class Foo<Formula", 1
- assert_equal "Use a space in class inheritance: class Foo < Formula",
- fa.problems.shift
- end
-
- def test_audit_line_default_template
- fa = formula_auditor "foo", "class Foo < Formula; url '/foo-1.0.tgz'; end"
-
- fa.audit_line '# system "cmake", ".", *std_cmake_args', 3
- assert_equal "Commented cmake call found",
- fa.problems.shift
-
- fa.audit_line "# PLEASE REMOVE", 3
- assert_equal "Please remove default template comments",
- fa.problems.shift
- end
-
- def test_audit_github_repository_no_api
- fa = formula_auditor "foo", <<-EOS.undent, strict: true, online: true
- class Foo < Formula
- homepage "https://github.com/example/example"
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- ENV["HOMEBREW_NO_GITHUB_API"] = "1"
-
- fa.audit_github_repository
- assert_equal [], fa.problems
- end
-
- def test_audit_caveats
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- homepage "http://example.com/foo"
- url "http://example.com/foo-1.0.tgz"
-
- def caveats
- "setuid"
- end
- end
- EOS
-
- fa.audit_caveats
- assert_equal ["Don't recommend setuid in the caveats, suggest sudo instead."],
- fa.problems
- end
-
- def test_audit_desc
- formula_descriptions = [
- { name: "foo", desc: nil,
- problem: "Formula should have a desc" },
- { name: "bar", desc: "bar" * 30,
- problem: "Description is too long" },
- { name: "baz", desc: "Baz commandline tool",
- problem: "Description should use \"command-line\"" },
- { name: "qux", desc: "A tool called Qux",
- problem: "Description shouldn't start with an indefinite article" },
- ]
-
- formula_descriptions.each do |formula|
- content = <<-EOS.undent
- class #{Formulary.class_s(formula[:name])} < Formula
- url "http://example.com/#{formula[:name]}-1.0.tgz"
- desc "#{formula[:desc]}"
- end
- EOS
-
- fa = formula_auditor formula[:name], content, strict: true
- fa.audit_desc
- assert_match formula[:problem], fa.problems.first
- end
- end
-
- def test_audit_homepage
- fa = formula_auditor "foo", <<-EOS.undent, online: true
- class Foo < Formula
- homepage "ftp://example.com/foo"
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- fa.audit_homepage
- assert_equal ["The homepage should start with http or https (URL is #{fa.formula.homepage})."],
- fa.problems
-
- formula_homepages = {
- "bar" => "http://www.freedesktop.org/wiki/bar",
- "baz" => "http://www.freedesktop.org/wiki/Software/baz",
- "qux" => "https://code.google.com/p/qux",
- "quux" => "http://github.com/quux",
- "corge" => "http://savannah.nongnu.org/corge",
- "grault" => "http://grault.github.io/",
- "garply" => "http://www.gnome.org/garply",
- "sf1" => "http://foo.sourceforge.net/",
- "sf2" => "http://foo.sourceforge.net",
- "sf3" => "http://foo.sf.net/",
- "sf4" => "http://foo.sourceforge.io/",
- "waldo" => "http://www.gnu.org/waldo",
- }
-
- formula_homepages.each do |name, homepage|
- fa = formula_auditor name, <<-EOS.undent
- class #{Formulary.class_s(name)} < Formula
- homepage "#{homepage}"
- url "http://example.com/#{name}-1.0.tgz"
- end
- EOS
-
- fa.audit_homepage
- if homepage =~ %r{http:\/\/www\.freedesktop\.org}
- if homepage =~ /Software/
- assert_match "#{homepage} should be styled " \
- "`https://wiki.freedesktop.org/www/Software/project_name`",
- fa.problems.first
- else
- assert_match "#{homepage} should be styled " \
- "`https://wiki.freedesktop.org/project_name`",
- fa.problems.first
- end
- elsif homepage =~ %r{https:\/\/code\.google\.com}
- assert_match "#{homepage} should end with a slash", fa.problems.first
- elsif homepage =~ /foo\.(sf|sourceforge)\.net/
- assert_match "#{homepage} should be `https://foo.sourceforge.io/`", fa.problems.first
- else
- assert_match "Please use https:// for #{homepage}", fa.problems.first
- end
- end
- end
-
- def test_audit_without_homepage
- fa = formula_auditor "foo", <<-EOS.undent, online: true
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- end
- EOS
-
- fa.audit_homepage
- assert_match "Formula should have a homepage.", fa.problems.first
- end
-
- def test_audit_xcodebuild_suggests_symroot
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- homepage "http://example.com"
-
- def install
- xcodebuild "-project", "meow.xcodeproject"
- end
- end
- EOS
-
- fa.audit_text
-
- assert_match 'xcodebuild should be passed an explicit "SYMROOT"', fa.problems.first
- end
-
- def test_audit_bare_xcodebuild_suggests_symroot_also
- fa = formula_auditor "foo", <<-EOS.undent
- class Foo < Formula
- url "http://example.com/foo-1.0.tgz"
- homepage "http://example.com"
-
- def install
- xcodebuild
- end
- end
- EOS
-
- fa.audit_text
-
- assert_match 'xcodebuild should be passed an explicit "SYMROOT"', fa.problems.first
- end
-end
diff --git a/Library/Homebrew/test/dev-cmd/audit_spec.rb b/Library/Homebrew/test/dev-cmd/audit_spec.rb
index 397e6912d..c4afe6592 100644
--- a/Library/Homebrew/test/dev-cmd/audit_spec.rb
+++ b/Library/Homebrew/test/dev-cmd/audit_spec.rb
@@ -59,3 +59,501 @@ describe FormulaText do
expect(ft.without_patch).to eq("class End < Formula\n \nend")
end
end
+
+describe FormulaAuditor do
+ def formula_auditor(name, text, options = {})
+ path = Pathname.new "#{dir}/#{name}.rb"
+ path.open("w") do |f|
+ f.write text
+ end
+
+ described_class.new(Formulary.factory(path), options)
+ end
+
+ let(:dir) { @dir = Pathname.new(Dir.mktmpdir) }
+
+ after(:each) do
+ dir.rmtree unless @dir.nil?
+ end
+
+ describe "#problems" do
+ it "is empty by default" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ expect(fa.problems).to be_empty
+ end
+ end
+
+ describe "#audit_file" do
+ specify "file permissions" do
+ allow(File).to receive(:umask).and_return(022)
+
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ path = fa.formula.path
+ path.chmod 0400
+
+ fa.audit_file
+ expect(fa.problems)
+ .to eq(["Incorrect file permissions (400): chmod 644 #{path}"])
+ end
+
+ specify "DATA but no __END__" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ patch :DATA
+ end
+ EOS
+
+ fa.audit_file
+ expect(fa.problems).to eq(["'DATA' was found, but no '__END__'"])
+ end
+
+ specify "__END__ but no DATA" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ __END__
+ a patch goes here
+ EOS
+
+ fa.audit_file
+ expect(fa.problems).to eq(["'__END__' was found, but 'DATA' is not used"])
+ end
+
+ specify "no trailing newline" do
+ fa = formula_auditor "foo", 'class Foo<Formula; url "file:///foo-1.0.tgz";end'
+
+ fa.audit_file
+ expect(fa.problems).to eq(["File should end with a newline"])
+ end
+
+ specify "no issue" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ homepage "http://example.com"
+ end
+ EOS
+
+ fa.audit_file
+ expect(fa.problems).to eq([])
+ end
+
+ specify "strict: ordering issue" do
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ homepage "http://example.com"
+ end
+ EOS
+
+ fa.audit_file
+ expect(fa.problems)
+ .to eq(["`homepage` (line 3) should be put before `url` (line 2)"])
+ end
+
+ specify "strict: resource placement" do
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true
+ class Foo < Formula
+ url "https://example.com/foo-1.0.tgz"
+
+ resource "foo2" do
+ url "https://example.com/foo-2.0.tgz"
+ end
+
+ depends_on "openssl"
+ end
+ EOS
+
+ fa.audit_file
+ expect(fa.problems)
+ .to eq(["`depends_on` (line 8) should be put before `resource` (line 4)"])
+ end
+
+ specify "strict: plist placement" do
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true
+ class Foo < Formula
+ url "https://example.com/foo-1.0.tgz"
+
+ test do
+ expect(shell_output("./dogs")).to match("Dogs are terrific")
+ end
+
+ def plist
+ end
+ end
+ EOS
+
+ fa.audit_file
+ expect(fa.problems)
+ .to eq(["`plist block` (line 8) should be put before `test block` (line 4)"])
+ end
+
+ specify "strict: url outside of stable block" do
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ stable do
+ # stuff
+ end
+ end
+ EOS
+
+ fa.audit_file
+ expect(fa.problems).to eq(["`url` should be put inside `stable block`"])
+ end
+
+ specify "strict: head and head do" do
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true
+ class Foo < Formula
+ head "http://example.com/foo.git"
+ head do
+ # stuff
+ end
+ end
+ EOS
+
+ fa.audit_file
+ expect(fa.problems).to eq(["Should not have both `head` and `head do`"])
+ end
+
+ specify "strict: bottle and bottle do" do
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ bottle do
+ # bottles go here
+ end
+ bottle :unneeded
+ end
+ EOS
+
+ fa.audit_file
+ expect(fa.problems)
+ .to eq(["Should not have `bottle :unneeded/:disable` and `bottle do`"])
+ end
+ end
+
+ describe "#audit_class" do
+ specify "missing test" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_class
+ expect(fa.problems).to eq([])
+
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_class
+ expect(fa.problems).to eq(["A `test do` test block should be added"])
+ end
+
+ specify "GithubGistFormula", :needs_compat do
+ ENV.delete("HOMEBREW_DEVELOPER")
+
+ fa = shutup do
+ formula_auditor "foo", <<-EOS.undent
+ class Foo < GithubGistFormula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+ end
+
+ fa.audit_class
+ expect(fa.problems)
+ .to eq(["GithubGistFormula is deprecated, use Formula instead"])
+ end
+
+ specify "ScriptFileFormula", :needs_compat do
+ ENV.delete("HOMEBREW_DEVELOPER")
+
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < ScriptFileFormula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_class
+ expect(fa.problems)
+ .to eq(["ScriptFileFormula is deprecated, use Formula instead"])
+ end
+
+ specify "AmazonWebServicesFormula", :needs_compat do
+ ENV.delete("HOMEBREW_DEVELOPER")
+
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < AmazonWebServicesFormula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_class
+ expect(fa.problems)
+ .to eq(["AmazonWebServicesFormula is deprecated, use Formula instead"])
+ end
+ end
+
+ describe "#audit_line" do
+ specify "pkgshare" do
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_line 'ohai "#{share}/foo"', 3
+ expect(fa.problems.shift).to eq("Use \#{pkgshare} instead of \#{share}/foo")
+
+ fa.audit_line 'ohai "#{share}/foo/bar"', 3
+ expect(fa.problems.shift).to eq("Use \#{pkgshare} instead of \#{share}/foo")
+
+ fa.audit_line 'ohai share/"foo"', 3
+ expect(fa.problems.shift).to eq('Use pkgshare instead of (share/"foo")')
+
+ fa.audit_line 'ohai share/"foo/bar"', 3
+ expect(fa.problems.shift).to eq('Use pkgshare instead of (share/"foo")')
+
+ fa.audit_line 'ohai "#{share}/foo-bar"', 3
+ expect(fa.problems).to eq([])
+
+ fa.audit_line 'ohai share/"foo-bar"', 3
+ expect(fa.problems).to eq([])
+
+ fa.audit_line 'ohai share/"bar"', 3
+ expect(fa.problems).to eq([])
+ end
+
+ # Regression test for https://github.com/Homebrew/legacy-homebrew/pull/48744
+ # Formulae with "++" in their name would break various audit regexps:
+ # Error: nested *?+ in regexp: /^libxml++3\s/
+ specify "++ in name" do
+ fa = formula_auditor "foolibc++", <<-EOS.undent, strict: true
+ class Foolibcxx < Formula
+ desc "foolibc++ is a test"
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_desc
+ expect(fa.problems.shift)
+ .to eq("Description shouldn't include the formula name")
+
+ fa.audit_line 'ohai "#{share}/foolibc++"', 3
+ expect(fa.problems.shift)
+ .to eq("Use \#{pkgshare} instead of \#{share}/foolibc++")
+
+ fa.audit_line 'ohai share/"foolibc++"', 3
+ expect(fa.problems.shift)
+ .to eq('Use pkgshare instead of (share/"foolibc++")')
+ end
+
+ specify "no space in class inheritance" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo<Formula
+ url '/foo-1.0.tgz'
+ end
+ EOS
+
+ fa.audit_line "class Foo<Formula", 1
+ expect(fa.problems.shift)
+ .to eq("Use a space in class inheritance: class Foo < Formula")
+ end
+
+ specify "default template" do
+ fa = formula_auditor "foo", "class Foo < Formula; url '/foo-1.0.tgz'; end"
+
+ fa.audit_line '# system "cmake", ".", *std_cmake_args', 3
+ expect(fa.problems.shift).to eq("Commented cmake call found")
+
+ fa.audit_line "# PLEASE REMOVE", 3
+ expect(fa.problems.shift).to eq("Please remove default template comments")
+ end
+ end
+
+ describe "#audit_github_repository" do
+ specify "#audit_github_repository when HOMEBREW_NO_GITHUB_API is set" do
+ ENV["HOMEBREW_NO_GITHUB_API"] = "1"
+
+ fa = formula_auditor "foo", <<-EOS.undent, strict: true, online: true
+ class Foo < Formula
+ homepage "https://github.com/example/example"
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_github_repository
+ expect(fa.problems).to eq([])
+ end
+ end
+
+ specify "#audit_caveats" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ homepage "http://example.com/foo"
+ url "http://example.com/foo-1.0.tgz"
+
+ def caveats
+ "setuid"
+ end
+ end
+ EOS
+
+ fa.audit_caveats
+ expect(fa.problems)
+ .to eq(["Don't recommend setuid in the caveats, suggest sudo instead."])
+ end
+
+ specify "#audit_desc" do
+ formula_descriptions = [
+ { name: "foo", desc: nil,
+ problem: "Formula should have a desc" },
+ { name: "bar", desc: "bar" * 30,
+ problem: "Description is too long" },
+ { name: "baz", desc: "Baz commandline tool",
+ problem: "Description should use \"command-line\"" },
+ { name: "qux", desc: "A tool called Qux",
+ problem: "Description shouldn't start with an indefinite article" },
+ ]
+
+ formula_descriptions.each do |formula|
+ content = <<-EOS.undent
+ class #{Formulary.class_s(formula[:name])} < Formula
+ url "http://example.com/#{formula[:name]}-1.0.tgz"
+ desc "#{formula[:desc]}"
+ end
+ EOS
+
+ fa = formula_auditor formula[:name], content, strict: true
+ fa.audit_desc
+ expect(fa.problems.first).to match(formula[:problem])
+ end
+ end
+
+ describe "#audit_homepage" do
+ specify "homepage URLs" do
+ fa = formula_auditor "foo", <<-EOS.undent, online: true
+ class Foo < Formula
+ homepage "ftp://example.com/foo"
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_homepage
+ expect(fa.problems)
+ .to eq(["The homepage should start with http or https (URL is #{fa.formula.homepage})."])
+
+ formula_homepages = {
+ "bar" => "http://www.freedesktop.org/wiki/bar",
+ "baz" => "http://www.freedesktop.org/wiki/Software/baz",
+ "qux" => "https://code.google.com/p/qux",
+ "quux" => "http://github.com/quux",
+ "corge" => "http://savannah.nongnu.org/corge",
+ "grault" => "http://grault.github.io/",
+ "garply" => "http://www.gnome.org/garply",
+ "sf1" => "http://foo.sourceforge.net/",
+ "sf2" => "http://foo.sourceforge.net",
+ "sf3" => "http://foo.sf.net/",
+ "sf4" => "http://foo.sourceforge.io/",
+ "waldo" => "http://www.gnu.org/waldo",
+ }
+
+ formula_homepages.each do |name, homepage|
+ fa = formula_auditor name, <<-EOS.undent
+ class #{Formulary.class_s(name)} < Formula
+ homepage "#{homepage}"
+ url "http://example.com/#{name}-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_homepage
+ if homepage =~ %r{http:\/\/www\.freedesktop\.org}
+ if homepage =~ /Software/
+ expect(fa.problems.first).to match(
+ "#{homepage} should be styled " \
+ "`https://wiki.freedesktop.org/www/Software/project_name`",
+ )
+ else
+ expect(fa.problems.first).to match(
+ "#{homepage} should be styled " \
+ "`https://wiki.freedesktop.org/project_name`",
+ )
+ end
+ elsif homepage =~ %r{https:\/\/code\.google\.com}
+ expect(fa.problems.first)
+ .to match("#{homepage} should end with a slash")
+ elsif homepage =~ /foo\.(sf|sourceforge)\.net/
+ expect(fa.problems.first)
+ .to match("#{homepage} should be `https://foo.sourceforge.io/`")
+ else
+ expect(fa.problems.first)
+ .to match("Please use https:// for #{homepage}")
+ end
+ end
+ end
+
+ specify "missing homepage" do
+ fa = formula_auditor "foo", <<-EOS.undent, online: true
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ end
+ EOS
+
+ fa.audit_homepage
+ expect(fa.problems.first).to match("Formula should have a homepage.")
+ end
+ end
+
+ describe "#audit_text" do
+ specify "xcodebuild suggests symroot" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ homepage "http://example.com"
+
+ def install
+ xcodebuild "-project", "meow.xcodeproject"
+ end
+ end
+ EOS
+
+ fa.audit_text
+ expect(fa.problems.first)
+ .to match('xcodebuild should be passed an explicit "SYMROOT"')
+ end
+
+ specify "bare xcodebuild also suggests symroot" do
+ fa = formula_auditor "foo", <<-EOS.undent
+ class Foo < Formula
+ url "http://example.com/foo-1.0.tgz"
+ homepage "http://example.com"
+
+ def install
+ xcodebuild
+ end
+ end
+ EOS
+
+ fa.audit_text
+ expect(fa.problems.first)
+ .to match('xcodebuild should be passed an explicit "SYMROOT"')
+ end
+ end
+end
diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb
index 193de6b8f..7905142a8 100644
--- a/Library/Homebrew/test/spec_helper.rb
+++ b/Library/Homebrew/test/spec_helper.rb
@@ -36,6 +36,10 @@ RSpec.configure do |config|
config.include(Test::Helper::Fixtures)
config.include(Test::Helper::Formula)
+ config.before(:each, :needs_compat) do
+ skip "Requires compatibility layer." if ENV["HOMEBREW_NO_COMPAT"]
+ end
+
config.before(:each, :needs_official_cmd_taps) do
skip "Needs official command Taps." unless ENV["HOMEBREW_TEST_OFFICIAL_CMD_TAPS"]
end