Skip to content

Commit

Permalink
GTIN.prioritized_gtin_classes is private
Browse files Browse the repository at this point in the history
The only thing that still depended on it being public were the tests for
functionality that manipulated the list. The tests have been overhauled
to rely more on asserting behavior than internal state.
  • Loading branch information
Narnach committed Sep 20, 2022
1 parent 91d8c97 commit 284c50d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 44 deletions.
14 changes: 4 additions & 10 deletions lib/barcodevalidation/gtin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ def new(input)
(class_for_input(input) || BarcodeValidation::InvalidGTIN).new(input)
end

# Classes that inherit from GTIN::Base auto-register themselves here.
# Classes can prioritize themselves before others to implement subsets or other means of overlapping ranges.
#
# @api private Only for internal use.
# @see GTIN::Base.prioritize_before For when you want to manipulate priorities.
# @see GTIN::Base.abstract_class For when you want to make a GTIN class abstract (i.e. not included in this list)
def prioritized_gtin_classes
@prioritized_gtin_classes ||= []
end

# Adds the provided class to the back of the list of prioritized GTIN classes.
def append_gtin_class(gtin_class)
return if gtin_class?(gtin_class)
Expand Down Expand Up @@ -54,6 +44,10 @@ def reprioritize_before(high_priority_class, low_priority_class)

private

def prioritized_gtin_classes
@prioritized_gtin_classes ||= []
end

def class_for_input(input)
input = input.to_s.freeze
prioritized_gtin_classes.find { |klass| klass.handles?(input) }
Expand Down
63 changes: 29 additions & 34 deletions spec/lib/barcodevalidation/gtin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,30 +115,36 @@
describe "custom classes" do
after(:each) do
# Remove references to classes we may have generated during a test to ensure we don't pollute the list of classes for other tests
BarcodeValidation::GTIN.prioritized_gtin_classes.delete_if { |klass| klass.name.start_with?("MyCustom") }
classes_to_cleanup.each do |class_sym|
next unless Object.const_defined?(class_sym)

class_obj = Object.const_get(class_sym)
BarcodeValidation::GTIN.remove_gtin_class(class_obj)
Object.send(:remove_const, class_sym)
end
end

describe "inheritance" do
let(:classes_to_cleanup) { [:MyCustomGTIN] }

it "appends itself to BarcodeValidation::GTIN.prioritized_gtin_classes when inheriting from GTIN::Base" do
expect do
class MyCustomGTIN < BarcodeValidation::GTIN::Base
end
end.to change(BarcodeValidation::GTIN.prioritized_gtin_classes, :count).by(1)
class MyCustomGTIN < BarcodeValidation::GTIN::Base
end

expect(BarcodeValidation::GTIN.prioritized_gtin_classes.last).to eq(MyCustomGTIN)
expect(BarcodeValidation::GTIN.gtin_class?(MyCustomGTIN)).to eq(true)
end

it "appends itself to BarcodeValidation::GTIN.prioritized_gtin_classes when inheriting from a GTIN::Base descendant" do
expect do
class MyCustomGTIN12 < BarcodeValidation::GTIN::GTIN12
end
end.to change(BarcodeValidation::GTIN.prioritized_gtin_classes, :count).by(1)
class MyCustomGTIN < BarcodeValidation::GTIN::GTIN12
end

expect(BarcodeValidation::GTIN.prioritized_gtin_classes.last).to eq(MyCustomGTIN12)
expect(BarcodeValidation::GTIN.gtin_class?(MyCustomGTIN)).to eq(true)
end
end

describe "prioritize_before" do
let(:classes_to_cleanup) { [:MyCustomGTIN13] }

it "causes this class to be evaluated before the other one when checking which one handles a GTIN input" do
class MyCustomGTIN13 < BarcodeValidation::GTIN::GTIN13
prioritize_before BarcodeValidation::GTIN::GTIN13
Expand All @@ -148,42 +154,31 @@ def self.handles?(input)
end
end

custom_index = BarcodeValidation::GTIN.prioritized_gtin_classes.index(MyCustomGTIN13)
gtin13_index = BarcodeValidation::GTIN.prioritized_gtin_classes.index(BarcodeValidation::GTIN::GTIN13)

# Check the implementation details: that our custom class is earlier in the prioritized list of classes.
expect(custom_index).to eq(gtin13_index - 1)

# More important than implementation details: does it actually work?
expect(BarcodeValidation::GTIN.new("1234567890123").class).to eq(MyCustomGTIN13)
expect(BarcodeValidation::GTIN.new("1004567890123").class).to eq(BarcodeValidation::GTIN::GTIN13)
end
end

describe "abstract_class" do
let(:classes_to_cleanup) { %i[MyCustomAbstractGTIN MyCustomParentGTIN MyCustomChildGTIN] }

it "removes itself from BarcodeValidation::GTIN.prioritized_gtin_classes" do
expect do
class MyCustomAbstractGTIN < BarcodeValidation::GTIN::Base
abstract_class
end
end.not_to change(BarcodeValidation::GTIN.prioritized_gtin_classes, :count)
class MyCustomAbstractGTIN < BarcodeValidation::GTIN::Base
abstract_class
end

expect(BarcodeValidation::GTIN.prioritized_gtin_classes).not_to include(MyCustomAbstractGTIN)
expect(BarcodeValidation::GTIN.gtin_class?(MyCustomAbstractGTIN)).to eq(false)
end

it "is not inherited by children" do
expect do
class MyCustomParentGTIN < BarcodeValidation::GTIN::Base
abstract_class
end
end.not_to change(BarcodeValidation::GTIN.prioritized_gtin_classes, :count)
class MyCustomParentGTIN < BarcodeValidation::GTIN::Base
abstract_class
end

expect do
class MyCustomChildGTIN < MyCustomParentGTIN
end
end.to change(BarcodeValidation::GTIN.prioritized_gtin_classes, :count).by(1)
class MyCustomChildGTIN < MyCustomParentGTIN
end

expect(BarcodeValidation::GTIN.prioritized_gtin_classes.last).to eq(MyCustomChildGTIN)
expect(BarcodeValidation::GTIN.gtin_class?(MyCustomChildGTIN)).to eq(true)
end
end
end
Expand Down

0 comments on commit 284c50d

Please sign in to comment.