
- Since moving `comments_hash` to `Stanza`, we've been using the wrong kind of "comments": the comments for the _stanza_, not the comments for the entire Cask. - Add a test to ensure this actually works. There was previously an infinite loop here due to the bad `comments`, visible in a `StanzaOrder` cop test, which I speculatively added a failing test for. Turns out that supporting nested stanza _ordering_ (vs. just grouping) is a whole separate piece of work (there are multiple TODOs there already), so I've backed that out and will do that separately.
617 lines
14 KiB
Ruby
617 lines
14 KiB
Ruby
# typed: false
|
|
# frozen_string_literal: true
|
|
|
|
require "rubocops/rubocop-cask"
|
|
require "test/rubocops/cask/shared_examples/cask_cop"
|
|
|
|
describe RuboCop::Cop::Cask::StanzaGrouping do
|
|
include CaskCop
|
|
|
|
subject(:cop) { described_class.new }
|
|
|
|
let(:missing_line_msg) do
|
|
"Cask/StanzaGrouping: stanza groups should be separated by a single empty line"
|
|
end
|
|
let(:extra_line_msg) do
|
|
"Cask/StanzaGrouping: stanzas within the same group should have no lines between them"
|
|
end
|
|
|
|
context "when there is only one stanza" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "does not report any offenses"
|
|
end
|
|
|
|
context "when no stanzas are incorrectly grouped" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "does not report any offenses"
|
|
end
|
|
|
|
context "when no stanzas or variable assignments are incorrectly grouped" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
|
|
version :latest
|
|
sha256 :no_check
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "does not report any offenses"
|
|
end
|
|
|
|
context "when one stanza is incorrectly grouped" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
|
|
sha256 :no_check
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
end
|
|
CASK
|
|
end
|
|
let(:expected_offenses) do
|
|
[{
|
|
message: extra_line_msg,
|
|
severity: :convention,
|
|
line: 3,
|
|
column: 0,
|
|
source: "\n",
|
|
}]
|
|
end
|
|
|
|
include_examples "reports offenses"
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when the arch stanza is incorrectly grouped" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
version :latest
|
|
sha256 :no_check
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
|
|
version :latest
|
|
sha256 :no_check
|
|
end
|
|
CASK
|
|
end
|
|
let(:expected_offenses) do
|
|
[{
|
|
message: missing_line_msg,
|
|
severity: :convention,
|
|
line: 3,
|
|
column: 0,
|
|
source: " version :latest",
|
|
}]
|
|
end
|
|
|
|
include_examples "reports offenses"
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when one variable assignment is incorrectly grouped" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
version :latest
|
|
sha256 :no_check
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
|
|
version :latest
|
|
sha256 :no_check
|
|
end
|
|
CASK
|
|
end
|
|
let(:expected_offenses) do
|
|
[{
|
|
message: missing_line_msg,
|
|
severity: :convention,
|
|
line: 4,
|
|
column: 0,
|
|
source: " version :latest",
|
|
}]
|
|
end
|
|
|
|
include_examples "reports offenses"
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when many stanzas are incorrectly grouped" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
|
|
name 'Foo'
|
|
|
|
homepage 'https://foo.brew.sh'
|
|
|
|
app 'Foo.app'
|
|
uninstall :quit => 'com.example.foo',
|
|
:kext => 'com.example.foo.kextextension'
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
homepage 'https://foo.brew.sh'
|
|
|
|
app 'Foo.app'
|
|
|
|
uninstall :quit => 'com.example.foo',
|
|
:kext => 'com.example.foo.kextextension'
|
|
end
|
|
CASK
|
|
end
|
|
let(:expected_offenses) do
|
|
[{
|
|
message: missing_line_msg,
|
|
severity: :convention,
|
|
line: 4,
|
|
column: 0,
|
|
source: " url 'https://foo.brew.sh/foo.zip'",
|
|
}, {
|
|
message: extra_line_msg,
|
|
severity: :convention,
|
|
line: 5,
|
|
column: 0,
|
|
source: "\n",
|
|
}, {
|
|
message: extra_line_msg,
|
|
severity: :convention,
|
|
line: 7,
|
|
column: 0,
|
|
source: "\n",
|
|
}, {
|
|
message: missing_line_msg,
|
|
severity: :convention,
|
|
line: 11,
|
|
column: 0,
|
|
source: " uninstall :quit => 'com.example.foo',",
|
|
}]
|
|
end
|
|
|
|
include_examples "reports offenses"
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when many stanzas and variable assignments are incorrectly grouped" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
|
|
platform = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
version :latest
|
|
sha256 :no_check
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
|
|
name 'Foo'
|
|
|
|
homepage 'https://foo.brew.sh'
|
|
|
|
app 'Foo.app'
|
|
uninstall :quit => 'com.example.foo',
|
|
:kext => 'com.example.foo.kextextension'
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
platform = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
|
|
version :latest
|
|
sha256 :no_check
|
|
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
homepage 'https://foo.brew.sh'
|
|
|
|
app 'Foo.app'
|
|
|
|
uninstall :quit => 'com.example.foo',
|
|
:kext => 'com.example.foo.kextextension'
|
|
end
|
|
CASK
|
|
end
|
|
let(:expected_offenses) do
|
|
[{
|
|
message: extra_line_msg,
|
|
severity: :convention,
|
|
line: 4,
|
|
column: 0,
|
|
source: "\n",
|
|
}, {
|
|
message: missing_line_msg,
|
|
severity: :convention,
|
|
line: 6,
|
|
column: 0,
|
|
source: " version :latest",
|
|
}, {
|
|
message: missing_line_msg,
|
|
severity: :convention,
|
|
line: 8,
|
|
column: 0,
|
|
source: " url 'https://foo.brew.sh/foo.zip'",
|
|
}, {
|
|
message: extra_line_msg,
|
|
severity: :convention,
|
|
line: 9,
|
|
column: 0,
|
|
source: "\n",
|
|
}, {
|
|
message: extra_line_msg,
|
|
severity: :convention,
|
|
line: 11,
|
|
column: 0,
|
|
source: "\n",
|
|
}, {
|
|
message: missing_line_msg,
|
|
severity: :convention,
|
|
line: 15,
|
|
column: 0,
|
|
source: " uninstall :quit => 'com.example.foo',",
|
|
}]
|
|
end
|
|
|
|
include_examples "reports offenses"
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when caveats stanza is incorrectly grouped" do
|
|
let(:source) do
|
|
format(<<~CASK, caveats: caveats.strip)
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
app 'Foo.app'
|
|
%<caveats>s
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
format(<<~CASK, caveats: caveats.strip)
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
|
|
app 'Foo.app'
|
|
|
|
%<caveats>s
|
|
end
|
|
CASK
|
|
end
|
|
|
|
context "when caveats is a one-line string" do
|
|
let(:caveats) { "caveats 'This is a one-line caveat.'" }
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when caveats is a heredoc" do
|
|
let(:caveats) do
|
|
<<~CAVEATS
|
|
caveats <<~EOS
|
|
This is a multiline caveat.
|
|
|
|
Let's hope it doesn't cause any problems!
|
|
EOS
|
|
CAVEATS
|
|
end
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when caveats is a block" do
|
|
let(:caveats) do
|
|
<<~CAVEATS
|
|
caveats do
|
|
puts 'This is a multiline caveat.'
|
|
|
|
puts "Let's hope it doesn't cause any problems!"
|
|
end
|
|
CAVEATS
|
|
end
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
end
|
|
|
|
context "when the postflight stanza is incorrectly grouped" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
app 'Foo.app'
|
|
postflight do
|
|
puts 'We have liftoff!'
|
|
end
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
|
|
app 'Foo.app'
|
|
|
|
postflight do
|
|
puts 'We have liftoff!'
|
|
end
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when a stanza has a comment" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
# comment with an empty line between
|
|
|
|
# comment directly above
|
|
postflight do
|
|
puts 'We have liftoff!'
|
|
end
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
app 'Foo.app'
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
version :latest
|
|
sha256 :no_check
|
|
|
|
# comment with an empty line between
|
|
|
|
# comment directly above
|
|
postflight do
|
|
puts 'We have liftoff!'
|
|
end
|
|
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
|
|
app 'Foo.app'
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when a stanza has a comment and there is a variable assignment" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
# comment with an empty line between
|
|
version :latest
|
|
sha256 :no_check
|
|
|
|
# comment directly above
|
|
postflight do
|
|
puts 'We have liftoff!'
|
|
end
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
app 'Foo.app'
|
|
end
|
|
CASK
|
|
end
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
arch arm: "arm64", intel: "x86_64"
|
|
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
|
|
|
# comment with an empty line between
|
|
version :latest
|
|
sha256 :no_check
|
|
|
|
# comment directly above
|
|
postflight do
|
|
puts 'We have liftoff!'
|
|
end
|
|
|
|
url 'https://foo.brew.sh/foo.zip'
|
|
name 'Foo'
|
|
|
|
app 'Foo.app'
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
context "when stanzas are nested one-level in `on_*` blocks" do
|
|
describe "basic nesting" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
on_arm do
|
|
version "1.0.2"
|
|
|
|
sha256 :no_check
|
|
end
|
|
on_intel do
|
|
version "0.9.8"
|
|
sha256 :no_check
|
|
url "https://foo.brew.sh/foo-intel.zip"
|
|
end
|
|
end
|
|
CASK
|
|
end
|
|
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
on_arm do
|
|
version "1.0.2"
|
|
sha256 :no_check
|
|
end
|
|
on_intel do
|
|
version "0.9.8"
|
|
sha256 :no_check
|
|
|
|
url "https://foo.brew.sh/foo-intel.zip"
|
|
end
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
describe "nested `on_*` blocks with comments" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
on_arm do
|
|
version "1.0.2"
|
|
|
|
sha256 :no_check # comment on same line
|
|
end
|
|
on_intel do
|
|
version "0.9.8"
|
|
sha256 :no_check
|
|
end
|
|
end
|
|
CASK
|
|
end
|
|
|
|
let(:correct_source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
on_arm do
|
|
version "1.0.2"
|
|
sha256 :no_check # comment on same line
|
|
end
|
|
on_intel do
|
|
version "0.9.8"
|
|
sha256 :no_check
|
|
end
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "autocorrects source"
|
|
end
|
|
|
|
# TODO: Maybe this should be fixed too?
|
|
describe "inner erroneously grouped nested livecheck block contents are ignored" do
|
|
let(:source) do
|
|
<<~CASK
|
|
cask 'foo' do
|
|
on_arm do
|
|
version "1.0.2"
|
|
sha256 :no_check
|
|
|
|
url "https://foo.brew.sh/foo-arm.zip"
|
|
|
|
livecheck do
|
|
url "https://foo.brew.sh/foo-arm-versions.html"
|
|
end
|
|
end
|
|
on_intel do
|
|
version "0.9.8"
|
|
sha256 :no_check
|
|
|
|
url "https://foo.brew.sh/foo-intel.zip"
|
|
|
|
livecheck do
|
|
regex(/RegExhibit\s+(\d+(?:.\d+)+)/i)
|
|
url "https://foo.brew.sh/foo-intel-versions.html"
|
|
end
|
|
end
|
|
end
|
|
CASK
|
|
end
|
|
|
|
include_examples "does not report any offenses"
|
|
end
|
|
end
|
|
end
|