Skip to content

Commit

Permalink
Support multiple abbreviations (#658)
Browse files Browse the repository at this point in the history
* Concentration Units (mixtures/solutions)

Added the following Concentration Units:
- MassConcentration: SI = kg/m3, typically mg/l
- VolumeConcentration : dimensionless, typically %
- MassFraction: SI = kg/kg, typically mg/kg

Modified the existing Molarity unit:
- Some operations that were originally based on the Density units now use the MassConcentration units instead (Note: despite the fact that they share the same measurement units- the Density is a distnct QuantyType from the MassConcentration)
- Removed all operators involving Molarity from the Density units

Defined some basic operations that were missing from the AmountOfSubstance/MolarMass/Mass units

Defined the triangular operations involving Mass/Molar/Volume concentrations (& the corresponding component's Density & MolarMass)

All unit tests included most were defined by actual chemists(which I AM NOT).
Note: one of the tests (QuantityIFormattableTests.VFormatEqualsValueToString)- was failing on my machine- it passes if I add CultureInfo.CurrentUICulture to the value.ToString() - as I presume was the intended behavior

* updated uppercase 'L' & BaseUnits in json

- updated liter abbreviations for g/l, g/dl, g/ml & kg/l to uppercase 'L'  (TODO Density?)
- added base units to all units in MassConcentration & Molarity (TODO Density?)

* BaseUnits, Obsolete methods & cosmetics

- corrected the BaseUnits for MassConcentration
- marked the invalid methods from Molarity/Density as Obsolete (were previously omitted)
- some cosmetic changes to the Unit Tests

* Removed Molarity.Molar as redundant (added abbreviation instead)

- MolesPerLiter: fixed the BaseUnits (default) to Deimeter/Mole
- Molar: removed in favor of using the alternative abbreviation 'M"
- MolarityTests - OneMilliMolarFromStringParsedCorrectly skipped while awaiting fix for #344

* Added a KnownQuantities class

- added a KnownQuantities class with a few constants that were used in multiple tests
- replaced the usages in MassConcentrationTests MolarityTests * VolumeConcentrationTests

* Testing with Theory + InlineData

- converted two of the MassConcentration tests to using Theory + InlineData

* Tests refactoring (Theory + InlineData)

- removed BaseUnits from GramPerDeciliter(not exact + overlap), kept it in GramPerLiter (as exact & non-overlapping), also kept it for GramPerMilliliter(exact + overlapping) because I thought it would be useful to have at least one such case for future testing
- moved the Mass/MolarMass operator to the Mass class (removing the MolarMass.extra)
- all tests refactored using Theory + Inline Data
- moved one or two tests to the appropriate .Test file
- removed a few redundant tests

* Make single line act-statements in tests

* Updated scripts to iterate over abbreviations

- Types.psm1: type of AbbreviationsWithPrefixes changed to object[]
- GenerateUnits.ps1: Add-PrefixUnits now iterates over all abbreviations (incl. with prefix)
- Duration: added the cyrilic equivalent to  "s": "sec" ("с", "сек")  to both the main and the prefixed abbrviations
- DurationTests: added a Theory with some of the main test cases for parsing seconds & milliseconds
- MolarityTests: removed the Skip for the awaiting test

* Update scripts WRC

- same fix applied to  the WRC project
  • Loading branch information
lipchev authored and angularsen committed Apr 22, 2019
1 parent 5e26a16 commit fa048aa
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 30 deletions.
4 changes: 2 additions & 2 deletions Common/UnitDefinitions/Duration.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@
},
{
"Culture": "ru-RU",
"Abbreviations": [ "с" ],
"AbbreviationsWithPrefixes": [ "нс", "мкс", "мс" ]
"Abbreviations": [ "с", "сек" ],
"AbbreviationsWithPrefixes": [ ["нс", "нсек"], ["мкс", "мксек"], ["мс", "мсек"] ]
}
]
}
Expand Down
17 changes: 17 additions & 0 deletions UnitsNet.Tests/CustomCode/DurationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Xunit;
using System;
using System.Globalization;

namespace UnitsNet.Tests.CustomCode
{
Expand Down Expand Up @@ -164,5 +165,21 @@ public void DurationTimesVolumeFlowEqualsVolume()
Volume volume = Duration.FromSeconds(20) * VolumeFlow.FromCubicMetersPerSecond(2);
Assert.Equal(Volume.FromCubicMeters(40), volume);
}

[Theory]
[InlineData("1s", 1)]
[InlineData("2 seconds", 2)]
[InlineData("1 ms", 1e-3)]
[InlineData("1000 msec", 1)]
[InlineData("1 с", 1, "ru-RU")]
[InlineData("1 сек", 1, "ru-RU")]
[InlineData("1000 мс", 1, "ru-RU")]
[InlineData("1000 мсек", 1, "ru-RU")]
public void DurationFromStringUsingMultipleAbbreviationsParsedCorrectly(string textValue, double expectedSeconds, string culture = null)
{
var cultureInfo = culture == null ? null : new CultureInfo(culture);

AssertEx.EqualTolerance(expectedSeconds, Duration.Parse(textValue, cultureInfo).Seconds, SecondsTolerance);
}
}
}
6 changes: 2 additions & 4 deletions UnitsNet.Tests/CustomCode/MolarityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,10 @@ public void OneMolarFromStringParsedCorrectly()
Assert.Equal(Molarity.Parse("1M"), Molarity.Parse("1 mol/L"));
}

[Fact(Skip = "Awaiting fix for https://github.com/angularsen/UnitsNet/issues/344")]
[Fact]
public void OneMilliMolarFromStringParsedCorrectly()
{
var one_mM = Molarity.Parse("1000 mM");

Assert.Equal(1, one_mM.MolesPerLiter);
Assert.Equal(1, Molarity.Parse("1000 mM").MolesPerLiter);
}

}
Expand Down

Large diffs are not rendered by default.

33 changes: 23 additions & 10 deletions UnitsNet.WindowsRuntimeComponent/Scripts/GenerateUnits.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,29 @@ function Add-PrefixUnits {
FromUnitToBaseFunc="("+$unit.FromUnitToBaseFunc+") * $prefixFactor"
FromBaseToUnitFunc="("+$unit.FromBaseToUnitFunc+") / $prefixFactor"

Localization=$unit.Localization | % {
$abbrev = $prefixAbbreviation + $_.Abbreviations[0]
if ($_.AbbreviationsWithPrefixes) {
$abbrev = $_.AbbreviationsWithPrefixes[$prefixIndex]
}

New-Object PsObject -Property @{
Culture=$_.Culture
Abbreviations= $abbrev
}}
Localization=$unit.Localization | % {
foreach ($abbrSyno in $_.Abbreviations) {
$abbrev = $prefixAbbreviation + $abbrSyno
if ($_.AbbreviationsWithPrefixes) {
if($_.AbbreviationsWithPrefixes[$prefixIndex] -isnot [System.String]){
foreach($synoWithPrefix in $_.AbbreviationsWithPrefixes[$prefixIndex]){
New-Object PsObject -Property @{
Culture=$_.Culture
Abbreviations= $synoWithPrefix
}
}
continue
}
else{
$abbrev = $_.AbbreviationsWithPrefixes[$prefixIndex]
}
}
New-Object PsObject -Property @{
Culture=$_.Culture
Abbreviations= $abbrev
}
}
}
}

# Append prefix unit
Expand Down
2 changes: 1 addition & 1 deletion UnitsNet.WindowsRuntimeComponent/Scripts/Types.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Localization
{
[string]$Culture
[string[]]$Abbreviations = @()
[string[]]$AbbreviationsWithPrefixes = @()
[object[]]$AbbreviationsWithPrefixes = @()
}

class BaseDimensions
Expand Down
70 changes: 69 additions & 1 deletion UnitsNet/GeneratedCode/UnitAbbreviationsCache.g.cs

Large diffs are not rendered by default.

33 changes: 23 additions & 10 deletions UnitsNet/Scripts/GenerateUnits.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,29 @@ function Add-PrefixUnits {
FromUnitToBaseFunc="("+$unit.FromUnitToBaseFunc+") * $prefixFactor"
FromBaseToUnitFunc="("+$unit.FromBaseToUnitFunc+") / $prefixFactor"

Localization=$unit.Localization | % {
$abbrev = $prefixAbbreviation + $_.Abbreviations[0]
if ($_.AbbreviationsWithPrefixes) {
$abbrev = $_.AbbreviationsWithPrefixes[$prefixIndex]
}

New-Object PsObject -Property @{
Culture=$_.Culture
Abbreviations= $abbrev
}}
Localization=$unit.Localization | % {
foreach ($abbrSyno in $_.Abbreviations) {
$abbrev = $prefixAbbreviation + $abbrSyno
if ($_.AbbreviationsWithPrefixes) {
if($_.AbbreviationsWithPrefixes[$prefixIndex] -isnot [System.String]){
foreach($synoWithPrefix in $_.AbbreviationsWithPrefixes[$prefixIndex]){
New-Object PsObject -Property @{
Culture=$_.Culture
Abbreviations= $synoWithPrefix
}
}
continue
}
else{
$abbrev = $_.AbbreviationsWithPrefixes[$prefixIndex]
}
}
New-Object PsObject -Property @{
Culture=$_.Culture
Abbreviations= $abbrev
}
}
}
}

# Append prefix unit
Expand Down
2 changes: 1 addition & 1 deletion UnitsNet/Scripts/Types.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Localization
{
[string]$Culture
[string[]]$Abbreviations = @()
[string[]]$AbbreviationsWithPrefixes = @()
[object[]]$AbbreviationsWithPrefixes = @()
}

class BaseDimensions
Expand Down

0 comments on commit fa048aa

Please sign in to comment.