requirement: require instances to use a subclass

This commit is contained in:
Bo Anderson 2022-08-24 23:48:08 +01:00
parent ea44c21822
commit 93647e5c98
No known key found for this signature in database
GPG Key ID: 3DB94E204E137D65
3 changed files with 16 additions and 11 deletions

View File

@ -20,6 +20,10 @@ class Requirement
attr_reader :tags, :name, :cask, :download attr_reader :tags, :name, :cask, :download
def initialize(tags = []) def initialize(tags = [])
# Only allow instances of subclasses. This base class enforces no constraints on its own.
# Individual subclasses use the `satisfy` DSL to define those constraints.
raise "Do not call `Requirement.new' directly without a subclass." unless self.class < Requirement
@cask = self.class.cask @cask = self.class.cask
@download = self.class.download @download = self.class.download
tags.each do |tag| tags.each do |tag|

View File

@ -12,7 +12,7 @@ describe Requirement do
let(:klass) { Class.new(described_class) } let(:klass) { Class.new(described_class) }
describe "#tags" do describe "#tags" do
subject { described_class.new(tags) } subject { klass.new(tags) }
context "with a single tag" do context "with a single tag" do
let(:tags) { ["bar"] } let(:tags) { ["bar"] }
@ -149,7 +149,7 @@ describe Requirement do
describe "#build?" do describe "#build?" do
context "when the :build tag is specified" do context "when the :build tag is specified" do
subject { described_class.new([:build]) } subject { klass.new([:build]) }
it { is_expected.to be_a_build_requirement } it { is_expected.to be_a_build_requirement }
end end
@ -186,24 +186,24 @@ describe Requirement do
end end
describe "#eql? and #==" do describe "#eql? and #==" do
subject(:requirement) { described_class.new } subject(:requirement) { klass.new }
it "returns true if the names and tags are equal" do it "returns true if the names and tags are equal" do
other = described_class.new other = klass.new
expect(requirement).to eql(other) expect(requirement).to eql(other)
expect(requirement).to eq(other) expect(requirement).to eq(other)
end end
it "returns false if names differ" do it "returns false if names differ" do
other = described_class.new other = klass.new
allow(other).to receive(:name).and_return("foo") allow(other).to receive(:name).and_return("foo")
expect(requirement).not_to eql(other) expect(requirement).not_to eql(other)
expect(requirement).not_to eq(other) expect(requirement).not_to eq(other)
end end
it "returns false if tags differ" do it "returns false if tags differ" do
other = described_class.new([:optional]) other = klass.new([:optional])
expect(requirement).not_to eql(other) expect(requirement).not_to eql(other)
expect(requirement).not_to eq(other) expect(requirement).not_to eq(other)
@ -211,21 +211,21 @@ describe Requirement do
end end
describe "#hash" do describe "#hash" do
subject(:requirement) { described_class.new } subject(:requirement) { klass.new }
it "is equal if names and tags are equal" do it "is equal if names and tags are equal" do
other = described_class.new other = klass.new
expect(requirement.hash).to eq(other.hash) expect(requirement.hash).to eq(other.hash)
end end
it "differs if names differ" do it "differs if names differ" do
other = described_class.new other = klass.new
allow(other).to receive(:name).and_return("foo") allow(other).to receive(:name).and_return("foo")
expect(requirement.hash).not_to eq(other.hash) expect(requirement.hash).not_to eq(other.hash)
end end
it "differs if tags differ" do it "differs if tags differ" do
other = described_class.new([:optional]) other = klass.new([:optional])
expect(requirement.hash).not_to eq(other.hash) expect(requirement.hash).not_to eq(other.hash)
end end
end end

View File

@ -12,7 +12,8 @@ describe Requirements do
end end
it "merges duplicate requirements" do it "merges duplicate requirements" do
requirements << Requirement.new << Requirement.new klass = Class.new(Requirement)
requirements << klass.new << klass.new
expect(requirements.count).to eq(1) expect(requirements.count).to eq(1)
end end
end end