Generate variant unit options in Ruby

This re-implements Angular JS function VariantUnitManager.variantUnitOptions()

Well.. almost. See next commit.
This commit is contained in:
David Cook
2024-02-21 13:25:01 +11:00
parent a1135f7db7
commit ea0067946d
2 changed files with 82 additions and 6 deletions

View File

@@ -20,6 +20,37 @@ class WeightsAndMeasures
scales[product_scale.to_f]['system']
end
# @returns enumerable with label and value for select
def self.variant_unit_options
available_units_sorted.flat_map do |measurement, measurement_info|
measurement_info.filter_map do |scale, unit_info|
scale_clean =
ActiveSupport::NumberHelper.number_to_rounded(scale, precision: nil,
strip_insignificant_zeros: true)
[
"#{I18n.t(measurement)} (#{unit_info['name']})", # Label (eg "Weight (g)")
"#{measurement}_#{scale_clean}", # Scale ID (eg "weight_1")
]
end
end <<
[
I18n.t('items'),
'items'
]
end
def self.available_units
Spree::Config.available_units.split(",")
end
def self.available_units_sorted
self::UNITS.transform_values do |measurement_info|
measurement_info.filter do |_scale, unit_info|
available_units.include?(unit_info['name'])
end.sort.to_h # sort by unit (hash key)
end
end
private
UNITS = {
@@ -49,7 +80,7 @@ class WeightsAndMeasures
return @units[@variant.product.variant_unit] if ignore_available_units
@units[@variant.product.variant_unit]&.reject { |_scale, unit_info|
available_units.exclude?(unit_info['name'])
self.class.available_units.exclude?(unit_info['name'])
}
end
@@ -67,8 +98,4 @@ class WeightsAndMeasures
largest_unit
end
def available_units
Spree::Config.available_units.split(",")
end
end

View File

@@ -55,7 +55,56 @@ describe WeightsAndMeasures do
end
end
describe "#scale_for_unit_value" do
describe "#variant_unit_options" do
let(:available_units) { "mg,g,kg,T,mL,cL,dL,L,kL,lb,oz,gal" }
subject { WeightsAndMeasures.variant_unit_options }
before do
allow(Spree::Config).to receive(:available_units).and_return(available_units)
end
it "returns options for each unit" do
expected_array = [
["Weight (mg)", "weight_0.001"],
["Weight (g)", "weight_1"],
["Weight (oz)", "weight_28.35"],
["Weight (lb)", "weight_453.6"],
["Weight (kg)", "weight_1000"],
["Weight (T)", "weight_1000000"],
["Volume (mL)", "volume_0.001"],
["Volume (cL)", "volume_0.01"],
["Volume (dL)", "volume_0.1"],
["Volume (L)", "volume_1"],
["Volume (gal)", "volume_4.54609"],
["Volume (kL)", "volume_1000"],
["Items", "items"],
]
pending "imperial measurements are duplicated"
expect(subject).to match_array expected_array # diff each element
expect(subject).to eq expected_array # test ordering also
end
describe "filtering available units" do
let(:available_units) { "g,kg,mL,L,lb,oz" }
it "returns options for available units only" do
expected_array = [
["Weight (g)", "weight_1"],
["Weight (oz)", "weight_28.35"],
["Weight (lb)", "weight_453.6"],
["Weight (kg)", "weight_1000"],
["Volume (mL)", "volume_0.001"],
["Volume (L)", "volume_1"],
["Items", "items"],
]
pending "imperial measurements are duplicated"
expect(subject).to match_array expected_array # diff each element
expect(subject).to eq expected_array # test ordering also
end
end
end
describe "#scales_for_unit_value" do
context "weight" do
before do
allow(product).to receive(:variant_unit) { "weight" }