Skip to content

No fall-back culture when using UnitAbbreviationsCache.CreateEmpty #1509

Closed
@lipchev

Description

@lipchev

Have a look at this test (it's targeting the v6 but that should be reproducible in v5)

        [Fact]
        public void MapUnitToDefaultAbbreviation_GivenUnitAndNoCulture_SetsDefaultAbbreviationForUnitForCurrentCulture()
        {
            using var cultureScope = new CultureScope(NorwegianCultureName);
            var cache = new UnitAbbreviationsCache();

            cache.MapUnitToDefaultAbbreviation(MassUnit.Gram, "zz");

            Assert.Equal("zz", cache.GetDefaultAbbreviation(MassUnit.Gram));
            Assert.Equal("g", cache.GetDefaultAbbreviation(MassUnit.Gram, AmericanCulture));
        }

It fails with

Expected: "g"
Actual: ""

Everything works fine when initializing with the list of QuantityInfo:

        [Fact]
        public void MapUnitToDefaultAbbreviation_WithDefaultLookup_GivenUnitAndNoCulture_SetsDefaultAbbreviationForUnitForCurrentCulture()
        {
            using var cultureScope = new CultureScope(NorwegianCultureName);
            var cache = UnitAbbreviationsCache.CreateDefault();

            cache.MapUnitToDefaultAbbreviation(MassUnit.Gram, "zz");

            Assert.Equal("zz", cache.GetDefaultAbbreviation(MassUnit.Gram));
            Assert.Equal("g", cache.GetDefaultAbbreviation(MassUnit.Gram, AmericanCulture));
        }

The reason why this doesn't work is not immediately obvious- it's because when calling MapUnitToDefaultAbbreviation, when the UnitInfo is not found in the QuantityInfoLookup the PerformAbbreviationMapping creates a dummy UnitInfo which doesn't have anything set for the QuantityName property.

In my opinion, the best solution would be to use these constructors:

        /// <summary>
        ///      Create an instance of the cache and load all the built-in quantities defined in the library.
        /// </summary>
        /// <returns>Instance for mapping any of the built-in units.</returns>
        public UnitAbbreviationsCache()
            :this(UnitsNetSetup.Default.QuantityInfoLookup)
        {
        }
        
        /// <summary>
        ///     Creates an instance of the cache using the specified set of quantities.
        /// </summary>
        /// <returns>Instance for mapping the units of the provided quantities.</returns>
        public UnitAbbreviationsCache(IReadOnlyCollection<QuantityInfo> quantities)
            :this(new QuantityInfoLookup(quantities))
        {
        }

        /// <summary>
        ///     Creates an instance of the cache using the specified set of quantities.
        /// </summary>
        /// <remarks>
        ///     Access type is <c>internal</c> until this class is matured and ready for external use.
        /// </remarks>
        internal UnitAbbreviationsCache(QuantityInfoLookup quantities)
        {
            Quantities = quantities;
        }

and throw an exception when the UnitInfo isn't found in the cache (when mapping or getting).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions