Skip to content

Commit 7244e04

Browse files
authored
UnitAbbreviationsCache.CreateDefault should use the default QuantityInfoLookup (#1548)
- `UnitAbbreviationsCache`: refactored the constructors / Create factory methods, with the Map/Get methods throwing an exception for missing units / unmapped abbreviations - `UnitAbbreviationsCache`: replaced the `string[]` return types with `IReadOnlyList` (breaking change for `.Length` which now becomes `.Count`) - `UnitAbbreviationsCache`: removed the overload accepting a `UnitInfo` - `UnitParser`: optimized the unit-parsing-with-fallback-culture methods, making the `FromUnitAbbreviation` behavior consistent with that of `ParseUnit` - `UnitParser`: `UnitInfo GetUnitFromAbbreviation(string unitAbbreviation, IFormatProvider? formatProvider)` : flipped the parameters and made the method public (_this is optional_) - optimized the `Mass.ParseUnit` calls (avoiding the `UnitInfo` lookups) - completed the coverage of the `UnitParser` and `UnitAbbreviationsCache` fixes #1509
1 parent 67572d5 commit 7244e04

File tree

137 files changed

+1262
-773
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+1262
-773
lines changed

CodeGen/Generators/UnitsNetGen/QuantityGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ public static bool TryParse([NotNullWhen(true)]string? str, IFormatProvider? pro
565565
/// <exception cref=""UnitsNetException"">Error parsing string.</exception>
566566
public static {_unitEnumName} ParseUnit(string str, IFormatProvider? provider)
567567
{{
568-
return UnitsNetSetup.Default.UnitParser.Parse<{_unitEnumName}>(str, provider);
568+
return UnitParser.Default.Parse(str, Info.UnitInfos, provider).Value;
569569
}}
570570
571571
/// <inheritdoc cref=""TryParseUnit(string,IFormatProvider,out UnitsNet.Units.{_unitEnumName})""/>
@@ -586,7 +586,7 @@ public static bool TryParseUnit([NotNullWhen(true)]string? str, out {_unitEnumNa
586586
/// <param name=""provider"">Format to use when parsing number and unit. Defaults to <see cref=""CultureInfo.CurrentCulture"" /> if null.</param>
587587
public static bool TryParseUnit([NotNullWhen(true)]string? str, IFormatProvider? provider, out {_unitEnumName} unit)
588588
{{
589-
return UnitsNetSetup.Default.UnitParser.TryParse<{_unitEnumName}>(str, provider, out unit);
589+
return UnitParser.Default.TryParse(str, Info, provider, out unit);
590590
}}
591591
592592
#endregion

UnitsNet.Benchmark/Initializations/UnitAbbreviationsCacheInitializationBenchmarks.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,4 @@ public string WithSpecificQuantityAndCustomMapping()
4747
cache.MapUnitToDefaultAbbreviation(MassUnit.Gram, "zz");
4848
return cache.GetDefaultAbbreviation(MassUnit.Gram);
4949
}
50-
51-
[Benchmark]
52-
public string DefaultWithoutLookup()
53-
{
54-
var cache = UnitAbbreviationsCache.CreateDefault();
55-
return cache.GetAbbreviations(Mass.Info.BaseUnitInfo)[0];
56-
}
57-
58-
[Benchmark]
59-
public string EmptyWithoutLookup()
60-
{
61-
var cache = new UnitAbbreviationsCache();
62-
return cache.GetAbbreviations(Mass.Info.BaseUnitInfo)[0];
63-
}
64-
65-
[Benchmark]
66-
public string WithSpecificQuantityWithoutLookup()
67-
{
68-
var cache = new UnitAbbreviationsCache([Mass.Info]);
69-
return cache.GetAbbreviations(Mass.Info.BaseUnitInfo)[0];
70-
}
7150
}

UnitsNet.Tests/CustomQuantities/HowMuch.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public HowMuch(double value, HowMuchUnit unit)
2727

2828
public BaseDimensions Dimensions => BaseDimensions.Dimensionless;
2929

30-
public QuantityInfo QuantityInfo => new(
30+
public static QuantityInfo Info = new(
3131
nameof(HowMuch),
3232
typeof(HowMuchUnit),
3333
new UnitInfo[]
@@ -40,6 +40,11 @@ public HowMuch(double value, HowMuchUnit unit)
4040
Zero,
4141
BaseDimensions.Dimensionless);
4242

43+
QuantityInfo IQuantity.QuantityInfo
44+
{
45+
get { return Info; }
46+
}
47+
4348
public double As(Enum unit) => Convert.ToDouble(unit);
4449

4550
public double As(UnitSystem unitSystem) => throw new NotImplementedException();

UnitsNet.Tests/QuantityParserTests.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ public class QuantityParserTests
1313
[Fact]
1414
public void Parse_WithSingleCaseInsensitiveMatch_ParsesWithMatchedUnit()
1515
{
16-
var unitAbbreviationsCache = new UnitAbbreviationsCache();
16+
var unitAbbreviationsCache = new UnitAbbreviationsCache([HowMuch.Info]);
1717
unitAbbreviationsCache.MapUnitToAbbreviation(HowMuchUnit.Some, "foo");
1818
var quantityParser = new QuantityParser(unitAbbreviationsCache);
1919

2020
HowMuch q = quantityParser.Parse<HowMuch, HowMuchUnit>("1 FOO",
2121
null,
22-
(value, unit) => new HowMuch((double) value, unit));
22+
(value, unit) => new HowMuch(value, unit));
2323

2424
Assert.Equal(HowMuchUnit.Some, q.Unit);
2525
Assert.Equal(1, q.Value);
@@ -28,14 +28,14 @@ public void Parse_WithSingleCaseInsensitiveMatch_ParsesWithMatchedUnit()
2828
[Fact]
2929
public void Parse_WithOneCaseInsensitiveMatchAndOneExactMatch_ParsesWithTheExactMatchUnit()
3030
{
31-
var unitAbbreviationsCache = new UnitAbbreviationsCache();
31+
var unitAbbreviationsCache = new UnitAbbreviationsCache([HowMuch.Info]);
3232
unitAbbreviationsCache.MapUnitToAbbreviation(HowMuchUnit.Some, "foo");
3333
unitAbbreviationsCache.MapUnitToAbbreviation(HowMuchUnit.ATon, "FOO");
3434
var quantityParser = new QuantityParser(unitAbbreviationsCache);
3535

3636
HowMuch q = quantityParser.Parse<HowMuch, HowMuchUnit>("1 FOO",
3737
null,
38-
(value, unit) => new HowMuch((double) value, unit));
38+
(value, unit) => new HowMuch(value, unit));
3939

4040
Assert.Equal(HowMuchUnit.ATon, q.Unit);
4141
Assert.Equal(1, q.Value);
@@ -44,14 +44,14 @@ public void Parse_WithOneCaseInsensitiveMatchAndOneExactMatch_ParsesWithTheExact
4444
[Fact]
4545
public void Parse_WithMultipleCaseInsensitiveMatchesButNoExactMatches_ThrowsAmbiguousUnitParseException()
4646
{
47-
var unitAbbreviationsCache = new UnitAbbreviationsCache();
47+
var unitAbbreviationsCache = new UnitAbbreviationsCache([HowMuch.Info]);
4848
unitAbbreviationsCache.MapUnitToAbbreviation(HowMuchUnit.Some, "foo");
4949
unitAbbreviationsCache.MapUnitToAbbreviation(HowMuchUnit.ATon, "FOO");
5050
var quantityParser = new QuantityParser(unitAbbreviationsCache);
5151

5252
void Act()
5353
{
54-
quantityParser.Parse<HowMuch, HowMuchUnit>("1 Foo", null, (value, unit) => new HowMuch((double) value, unit));
54+
quantityParser.Parse<HowMuch, HowMuchUnit>("1 Foo", null, (value, unit) => new HowMuch(value, unit));
5555
}
5656

5757
var ex = Assert.Throws<AmbiguousUnitParseException>(Act);
@@ -61,13 +61,13 @@ void Act()
6161
[Fact]
6262
public void Parse_MappedCustomUnit()
6363
{
64-
var unitAbbreviationsCache = new UnitAbbreviationsCache();
64+
var unitAbbreviationsCache = new UnitAbbreviationsCache([HowMuch.Info]);
6565
unitAbbreviationsCache.MapUnitToAbbreviation(HowMuchUnit.Some, "fooh");
6666
var quantityParser = new QuantityParser(unitAbbreviationsCache);
6767

6868
HowMuch q = quantityParser.Parse<HowMuch, HowMuchUnit>("1 fooh",
6969
null,
70-
(value, unit) => new HowMuch((double) value, unit));
70+
(value, unit) => new HowMuch(value, unit));
7171

7272
Assert.Equal(HowMuchUnit.Some, q.Unit);
7373
Assert.Equal(1, q.Value);
@@ -76,13 +76,13 @@ public void Parse_MappedCustomUnit()
7676
[Fact]
7777
public void TryParse_MappedCustomUnit()
7878
{
79-
var unitAbbreviationsCache = new UnitAbbreviationsCache();
79+
var unitAbbreviationsCache = new UnitAbbreviationsCache([HowMuch.Info]);
8080
unitAbbreviationsCache.MapUnitToAbbreviation(HowMuchUnit.Some, "fooh");
8181
var quantityParser = new QuantityParser(unitAbbreviationsCache);
8282

8383
bool success = quantityParser.TryParse<HowMuch, HowMuchUnit>("1 fooh",
8484
null,
85-
(value, unit) => new HowMuch((double) value, unit),
85+
(value, unit) => new HowMuch(value, unit),
8686
out HowMuch q);
8787

8888
Assert.True(success);

UnitsNet.Tests/QuantityTests.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,21 +174,23 @@ public void FromUnitAbbreviation_MatchingCulture_ReturnsQuantity()
174174
}
175175

176176
[Fact]
177-
public void TryFromUnitAbbreviation_MatchingCulture_ReturnsQuantity()
177+
public void FromUnitAbbreviation_MatchingFallbackCulture_ReturnsQuantity()
178178
{
179-
Assert.False(Quantity.TryFromUnitAbbreviation(Russian, 5, "cm", out IQuantity? q));
179+
// The localized abbreviation is "см"
180+
IQuantity quantity = Quantity.FromUnitAbbreviation(Russian, 5, "cm");
181+
Assert.Equal(5, quantity.Value);
182+
Assert.Equal(LengthUnit.Centimeter, quantity.Unit);
180183
}
181184

182185
[Fact]
183-
public void FromUnitAbbreviation_MismatchingCulture_ThrowsUnitNotFoundException()
186+
public void TryFromUnitAbbreviation_MatchingFallbackCulture_ReturnsQuantity()
184187
{
185-
Assert.Throws<UnitNotFoundException>(() => Quantity.FromUnitAbbreviation(Russian, 5, "cm")); // Expected "см"
186-
}
187-
188-
[Fact]
189-
public void TryFromUnitAbbreviation_MismatchingCulture_ThrowsUnitNotFoundException()
190-
{
191-
Assert.Throws<UnitNotFoundException>(() => Quantity.FromUnitAbbreviation(Russian, 5, "cm")); // Expected "см"
188+
// The localized abbreviation is "см"
189+
var success = Quantity.TryFromUnitAbbreviation(Russian, 5, "cm", out IQuantity? quantity);
190+
Assert.True(success);
191+
Assert.NotNull(quantity);
192+
Assert.Equal(5, quantity.Value);
193+
Assert.Equal(LengthUnit.Centimeter, quantity.Unit);
192194
}
193195

194196
[Fact]

0 commit comments

Comments
 (0)