Enable and fix RSpec/DescribedClassModuleWrapping

This commit is contained in:
Douglas Eichelberger 2024-03-30 11:18:58 -07:00
parent 02a0ea8449
commit 03b815df82
9 changed files with 1622 additions and 1625 deletions

View File

@ -253,6 +253,8 @@ RSpec/NestedGroups:
RSpec/MultipleMemoizedHelpers:
Enabled: false
RSpec/DescribedClassModuleWrapping:
Enabled: true
# Annoying to have these autoremoved.
RSpec/Focus:
AutoCorrect: false

View File

@ -1,58 +1,56 @@
# frozen_string_literal: true
module Cask
RSpec.describe Download, :cask do
describe "#verify_download_integrity" do
subject(:verification) { described_class.new(cask).verify_download_integrity(downloaded_path) }
RSpec.describe Cask::Download, :cask do
describe "#verify_download_integrity" do
subject(:verification) { described_class.new(cask).verify_download_integrity(downloaded_path) }
let(:cask) { instance_double(Cask, token: "cask", sha256: expected_sha256) }
let(:cafebabe) { "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe" }
let(:deadbeef) { "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" }
let(:computed_sha256) { cafebabe }
let(:downloaded_path) { Pathname.new("cask.zip") }
let(:cask) { instance_double(Cask::Cask, token: "cask", sha256: expected_sha256) }
let(:cafebabe) { "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe" }
let(:deadbeef) { "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" }
let(:computed_sha256) { cafebabe }
let(:downloaded_path) { Pathname.new("cask.zip") }
before do
allow(downloaded_path).to receive_messages(file?: true, sha256: computed_sha256)
before do
allow(downloaded_path).to receive_messages(file?: true, sha256: computed_sha256)
end
context "when the expected checksum is :no_check" do
let(:expected_sha256) { :no_check }
it "skips the check" do
expect { verification }.to output(/skipping verification/).to_stderr
end
end
context "when the expected checksum is :no_check" do
let(:expected_sha256) { :no_check }
context "when expected and computed checksums match" do
let(:expected_sha256) { Checksum.new(cafebabe) }
it "skips the check" do
expect { verification }.to output(/skipping verification/).to_stderr
end
it "does not raise an error" do
expect { verification }.not_to raise_error
end
end
context "when expected and computed checksums match" do
let(:expected_sha256) { Checksum.new(cafebabe) }
context "when the expected checksum is nil" do
let(:expected_sha256) { nil }
it "does not raise an error" do
expect { verification }.not_to raise_error
end
it "outputs an error" do
expect { verification }.to output(/sha256 "#{computed_sha256}"/).to_stderr
end
end
context "when the expected checksum is nil" do
let(:expected_sha256) { nil }
context "when the expected checksum is empty" do
let(:expected_sha256) { Checksum.new("") }
it "outputs an error" do
expect { verification }.to output(/sha256 "#{computed_sha256}"/).to_stderr
end
it "outputs an error" do
expect { verification }.to output(/sha256 "#{computed_sha256}"/).to_stderr
end
end
context "when the expected checksum is empty" do
let(:expected_sha256) { Checksum.new("") }
context "when expected and computed checksums do not match" do
let(:expected_sha256) { Checksum.new(deadbeef) }
it "outputs an error" do
expect { verification }.to output(/sha256 "#{computed_sha256}"/).to_stderr
end
end
context "when expected and computed checksums do not match" do
let(:expected_sha256) { Checksum.new(deadbeef) }
it "raises an error" do
expect { verification }.to raise_error ChecksumMismatchError
end
it "raises an error" do
expect { verification }.to raise_error ChecksumMismatchError
end
end
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
# frozen_string_literal: true
require "socket"
require "formula_free_port"
module Homebrew
RSpec.describe FreePort do
include described_class
describe "#free_port" do
it "returns a free TCP/IP port" do
# IANA suggests user port from 1024 to 49151
# and dynamic port for 49152 to 65535
# http://www.iana.org/assignments/port-numbers
min_port = 1024
max_port = 65535
port = free_port
expect(port).to be_between(min_port, max_port)
expect { TCPServer.new(port).close }.not_to raise_error
end
end
end
end

View File

@ -0,0 +1,42 @@
# frozen_string_literal: true
require "formula_text_auditor"
RSpec.describe Homebrew::FormulaTextAuditor do
alias_matcher :have_data, :be_data
alias_matcher :have_end, :be_end
alias_matcher :have_trailing_newline, :be_trailing_newline
let(:dir) { mktmpdir }
def formula_text(name, body = nil, options = {})
path = dir/"#{name}.rb"
path.write <<~RUBY
class #{Formulary.class_s(name)} < Formula
#{body}
end
#{options[:patch]}
RUBY
described_class.new(path)
end
specify "simple valid Formula" do
ft = formula_text "valid", <<~RUBY
url "https://www.brew.sh/valid-1.0.tar.gz"
RUBY
expect(ft).to have_trailing_newline
expect(ft =~ /\burl\b/).to be_truthy
expect(ft.line_number(/desc/)).to be_nil
expect(ft.line_number(/\burl\b/)).to eq(2)
expect(ft).to include("Valid")
end
specify "#trailing_newline?" do
ft = formula_text "newline"
expect(ft).to have_trailing_newline
end
end

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
require "socket"
require "formula_free_port"
RSpec.describe Homebrew::FreePort do
include described_class
describe "#free_port" do
it "returns a free TCP/IP port" do
# IANA suggests user port from 1024 to 49151
# and dynamic port for 49152 to 65535
# http://www.iana.org/assignments/port-numbers
min_port = 1024
max_port = 65535
port = free_port
expect(port).to be_between(min_port, max_port)
expect { TCPServer.new(port).close }.not_to raise_error
end
end
end

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
require "rubocops/shell_commands"
RSpec.describe RuboCop::Cop::Homebrew::ExecShellMetacharacters do
subject(:cop) { described_class.new }
context "when auditing exec calls" do
it "reports aan offense when output piping is used" do
expect_offense(<<~RUBY)
fork do
exec "foo bar > output"
^^^^^^^^^^^^^^^^^^ Homebrew/ExecShellMetacharacters: Don't use shell metacharacters in `exec`. Implement the logic in Ruby instead, using methods like `$stdout.reopen`.
end
RUBY
end
it "reports no offenses when no metacharacters are used" do
expect_no_offenses(<<~RUBY)
fork do
exec "foo bar"
end
RUBY
end
end
end

View File

@ -2,239 +2,210 @@
require "rubocops/shell_commands"
module RuboCop
module Cop
module Homebrew
::RSpec.describe ShellCommands do
subject(:cop) { described_class.new }
RSpec.describe RuboCop::Cop::Homebrew::ShellCommands do
subject(:cop) { described_class.new }
context "when auditing shell commands" do
it "reports and corrects an offense when `system` arguments should be separated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
system "foo bar"
^^^^^^^^^ Homebrew/ShellCommands: Separate `system` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
system "foo", "bar"
end
end
RUBY
end
it "reports and corrects an offense when `system` arguments involving interpolation should be separated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
system "\#{bin}/foo bar"
^^^^^^^^^^^^^^^^ Homebrew/ShellCommands: Separate `system` commands into `"\#{bin}/foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
system "\#{bin}/foo", "bar"
end
end
RUBY
end
it "reports no offenses when `system` with metacharacter arguments are called" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
system "foo bar > baz"
end
end
RUBY
end
it "reports no offenses when trailing arguments to `system` are unseparated" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
system "foo", "bar baz"
end
end
RUBY
end
it "reports no offenses when `Utils.popen` arguments are unseparated" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
Utils.popen("foo bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.popen_read` arguments are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_read` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("foo", "bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.safe_popen_read` arguments are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.safe_popen_read("foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.safe_popen_read` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.safe_popen_read("foo", "bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.popen_write` arguments are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.popen_write("foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_write` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.popen_write("foo", "bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.safe_popen_write` arguments are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.safe_popen_write("foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.safe_popen_write` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.safe_popen_write("foo", "bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.popen_read` arguments with interpolation are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("\#{bin}/foo bar")
^^^^^^^^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_read` commands into `"\#{bin}/foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("\#{bin}/foo", "bar")
end
end
RUBY
end
it "reports no offenses when `Utils.popen_read` arguments with metacharacters are unseparated" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("foo bar > baz")
end
end
RUBY
end
it "reports no offenses when trailing arguments to `Utils.popen_read` are unseparated" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("foo", "bar baz")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.popen_read` arguments are unseparated after a shell env" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read({ "SHELL" => "bash"}, "foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_read` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read({ "SHELL" => "bash"}, "foo", "bar")
end
end
RUBY
context "when auditing shell commands" do
it "reports and corrects an offense when `system` arguments should be separated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
system "foo bar"
^^^^^^^^^ Homebrew/ShellCommands: Separate `system` commands into `"foo", "bar"`
end
end
end
RUBY
::RSpec.describe ExecShellMetacharacters do
subject(:cop) { described_class.new }
context "when auditing exec calls" do
it "reports aan offense when output piping is used" do
expect_offense(<<~RUBY)
fork do
exec "foo bar > output"
^^^^^^^^^^^^^^^^^^ Homebrew/ExecShellMetacharacters: Don't use shell metacharacters in `exec`. Implement the logic in Ruby instead, using methods like `$stdout.reopen`.
end
RUBY
end
it "reports no offenses when no metacharacters are used" do
expect_no_offenses(<<~RUBY)
fork do
exec "foo bar"
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
system "foo", "bar"
end
end
end
RUBY
end
it "reports and corrects an offense when `system` arguments involving interpolation should be separated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
system "\#{bin}/foo bar"
^^^^^^^^^^^^^^^^ Homebrew/ShellCommands: Separate `system` commands into `"\#{bin}/foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
system "\#{bin}/foo", "bar"
end
end
RUBY
end
it "reports no offenses when `system` with metacharacter arguments are called" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
system "foo bar > baz"
end
end
RUBY
end
it "reports no offenses when trailing arguments to `system` are unseparated" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
system "foo", "bar baz"
end
end
RUBY
end
it "reports no offenses when `Utils.popen` arguments are unseparated" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
Utils.popen("foo bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.popen_read` arguments are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_read` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("foo", "bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.safe_popen_read` arguments are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.safe_popen_read("foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.safe_popen_read` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.safe_popen_read("foo", "bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.popen_write` arguments are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.popen_write("foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_write` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.popen_write("foo", "bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.safe_popen_write` arguments are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.safe_popen_write("foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.safe_popen_write` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.safe_popen_write("foo", "bar")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.popen_read` arguments with interpolation are unseparated" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("\#{bin}/foo bar")
^^^^^^^^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_read` commands into `"\#{bin}/foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("\#{bin}/foo", "bar")
end
end
RUBY
end
it "reports no offenses when `Utils.popen_read` arguments with metacharacters are unseparated" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("foo bar > baz")
end
end
RUBY
end
it "reports no offenses when trailing arguments to `Utils.popen_read` are unseparated" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read("foo", "bar baz")
end
end
RUBY
end
it "reports and corrects an offense when `Utils.popen_read` arguments are unseparated after a shell env" do
expect_offense(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read({ "SHELL" => "bash"}, "foo bar")
^^^^^^^^^ Homebrew/ShellCommands: Separate `Utils.popen_read` commands into `"foo", "bar"`
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
def install
Utils.popen_read({ "SHELL" => "bash"}, "foo", "bar")
end
end
RUBY
end
end
end