Skip to content

Commit fa3f57e

Browse files
authored
Add Information, BitRate, Duration, and Frequency relations (#1699)
## Motivation Fixes #1652. UnitsNet already generates quantity relation operators from `Common/UnitRelations.json`, but a few natural relations around information, bit rate, duration, and frequency were missing. This meant formulas such as information per duration, bit rate over frequency, and refresh period from frequency had to go through scalar properties instead of staying in UnitsNet quantity types. ## Changes - Add relations for `Information = BitRate * Duration`, `1 = Frequency * Duration`, and `BitRate = Information * Frequency`. - Regenerate the affected quantity operators for `Information`, `BitRate`, `Duration`, and `Frequency`. - Add regression tests in the existing quantity test files that own those relation scenarios. - Document where generated relation tests should live. ## Validation - `dotnet test UnitsNet.Tests --filter "FullyQualifiedName~BitRateTests|FullyQualifiedName~DurationTests|FullyQualifiedName~FrequencyTests|FullyQualifiedName~InformationTests"`
1 parent c56fa7b commit fa3f57e

10 files changed

Lines changed: 169 additions & 0 deletions

File tree

Common/UnitRelations.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"1 = Area.SquareMeter * ReciprocalArea.InverseSquareMeter",
33
"1 = Density.KilogramPerCubicMeter * SpecificVolume.CubicMeterPerKilogram",
44
"1 = ElectricResistivity.OhmMeter * ElectricConductivity.SiemensPerMeter",
5+
"1 = Frequency.PerSecond * Duration.Second",
56
"1 = Length.Meter * ReciprocalLength.InverseMeter",
67
"Acceleration.MeterPerSecondSquared = Jerk.MeterPerSecondCubed * Duration.Second",
78
"AmountOfSubstance.Mole = MolarFlow.MolePerSecond * Duration.Second",
@@ -14,6 +15,7 @@
1415
"AreaDensity.KilogramPerSquareMeter = Density.KilogramPerCubicMeter * Length.Meter",
1516
"AreaMomentOfInertia.MeterToTheFourth = Area.SquareMeter * Area.SquareMeter",
1617
"AreaMomentOfInertia.MeterToTheFourth = Volume.CubicMeter * Length.Meter",
18+
"BitRate.BitPerSecond = Information.Bit * Frequency.PerSecond",
1719
"double = SpecificEnergy.JoulePerKilogram * BrakeSpecificFuelConsumption.KilogramPerJoule",
1820
"DynamicViscosity.NewtonSecondPerMeterSquared = Density.KilogramPerCubicMeter * KinematicViscosity.SquareMeterPerSecond",
1921
"ElectricCharge.AmpereHour = ElectricCurrent.Ampere * Duration.Hour",
@@ -35,6 +37,7 @@
3537
"ForcePerLength.NewtonPerMeter = Force.Newton * ReciprocalLength.InverseMeter",
3638
"ForcePerLength.NewtonPerMeter = Pressure.NewtonPerSquareMeter * Length.Meter",
3739
"ForcePerLength.NewtonPerMeter = SpecificWeight.NewtonPerCubicMeter * Area.SquareMeter",
40+
"Information.Bit = BitRate.BitPerSecond * Duration.Second",
3841
"KinematicViscosity.SquareMeterPerSecond = Length.Meter * Speed.MeterPerSecond",
3942
"Length.Meter = Area.SquareMeter * ReciprocalLength.InverseMeter",
4043
"Length.Meter = Speed.MeterPerSecond * Duration.Second",

Docs/adding-operator-overloads.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ There is a large number of operator overloads, to facilitate strongly typed comp
55
Operators that can be expressed as a multiplication, division, or inverse relation may be generated from
66
`Common/UnitRelations.json`; see [Quantity relations](quantity-and-unit-definition-schema.md#quantity-relations).
77

8+
For generated relation tests, use the existing relation-test ownership pattern:
9+
10+
- Multiplication tests go in `<LeftQuantity>Tests.cs`, where `LeftQuantity` is the first operand in the explicit `UnitRelations.json` entry. Put the inferred reversed multiplication test there too.
11+
- Inferred division tests go in `<ResultQuantity>Tests.cs`, because the generated division operators are exposed by the result quantity.
12+
- Inverse relation tests go in each quantity's own test file, because each side gets its own `Inverse()` method.
13+
814
1. Put operator overload in `Length.extra.cs` if the **first parameter** is `Length`
915
2. Add a short xmldoc summary as per the example below. You can add more descriptions if it is useful.
1016
3. Add a unit test case and place it in the equivalent file `LengthTests.cs`.

UnitsNet.Tests/CustomCode/BitRateTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323

2424
using System;
25+
using Xunit;
2526

2627
namespace UnitsNet.Tests.CustomCode
2728
{
@@ -72,5 +73,37 @@ public class BitRateTests : BitRateTestsBase
7273
protected override double ExbibitsPerSecondInOneBitPerSecond => 8.67361738E-19;
7374
protected override double ExbibytesPerSecondInOneBitPerSecond => 1.0842021724855E-19;
7475
protected override double ExbioctetsPerSecondInOneBitPerSecond => 1.0842021724855E-19;
76+
77+
[Fact]
78+
public void BitRateTimesDurationEqualsInformation()
79+
{
80+
Information information = BitRate.FromKilobitsPerSecond(10) * Duration.FromSeconds(3);
81+
82+
Assert.Equal(30000, information.Bits);
83+
}
84+
85+
[Fact]
86+
public void DurationTimesBitRateEqualsInformation()
87+
{
88+
Information information = Duration.FromMilliseconds(500) * BitRate.FromKilobitsPerSecond(10);
89+
90+
Assert.Equal(5000, information.Bits);
91+
}
92+
93+
[Fact]
94+
public void BitRateDividedByFrequencyEqualsInformation()
95+
{
96+
Information information = BitRate.FromKilobitsPerSecond(16) / Frequency.FromHertz(2);
97+
98+
Assert.Equal(8000, information.Bits);
99+
}
100+
101+
[Fact]
102+
public void BitRateDividedByInformationEqualsFrequency()
103+
{
104+
Frequency frequency = BitRate.FromKilobitsPerSecond(16) / Information.FromKilobytes(1);
105+
106+
Assert.Equal(2, frequency.Hertz);
107+
}
75108
}
76109
}

UnitsNet.Tests/CustomCode/DurationTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,5 +242,13 @@ public void DurationTimesForceChangeRate()
242242
Force force = Duration.FromSeconds(10) * ForceChangeRate.FromNewtonsPerSecond(100);
243243
Assert.Equal(Force.FromNewtons(1000), force);
244244
}
245+
246+
[Fact]
247+
public void DurationInverseEqualsFrequency()
248+
{
249+
Frequency frequency = Duration.FromMilliseconds(250).Inverse();
250+
251+
Assert.Equal(4, frequency.Hertz);
252+
}
245253
}
246254
}

UnitsNet.Tests/CustomCode/FrequencyTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet.
33

44
using System;
5+
using Xunit;
56

67
namespace UnitsNet.Tests
78
{
@@ -30,5 +31,13 @@ public class FrequencyTests : FrequencyTestsBase
3031
protected override double RadiansPerSecondInOneHertz => 2 * Math.PI;
3132

3233
protected override double BeatsPerMinuteInOneHertz => 60;
34+
35+
[Fact]
36+
public void FrequencyInverseEqualsDuration()
37+
{
38+
Duration duration = Frequency.FromHertz(2).Inverse();
39+
40+
Assert.Equal(0.5, duration.Seconds);
41+
}
3342
}
3443
}

UnitsNet.Tests/CustomCode/InformationTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,37 @@ public void OneKBHas1000Bytes()
9191
{
9292
Assert.Equal(1000, Information.FromKilobytes(1).Bytes);
9393
}
94+
95+
[Fact]
96+
public void InformationDividedByDurationEqualsBitRate()
97+
{
98+
BitRate bitRate = Information.FromKilobytes(3) / Duration.FromSeconds(2);
99+
100+
Assert.Equal(12000, bitRate.BitsPerSecond);
101+
}
102+
103+
[Fact]
104+
public void InformationDividedByBitRateEqualsDuration()
105+
{
106+
Duration duration = Information.FromMegabits(3) / BitRate.FromMegabitsPerSecond(2);
107+
108+
Assert.Equal(1.5, duration.Seconds);
109+
}
110+
111+
[Fact]
112+
public void InformationTimesFrequencyEqualsBitRate()
113+
{
114+
BitRate bitRate = Information.FromBytes(100) * Frequency.FromHertz(2);
115+
116+
Assert.Equal(1600, bitRate.BitsPerSecond);
117+
}
118+
119+
[Fact]
120+
public void FrequencyTimesInformationEqualsBitRate()
121+
{
122+
BitRate bitRate = Frequency.FromHertz(2) * Information.FromBytes(100);
123+
124+
Assert.Equal(1600, bitRate.BitsPerSecond);
125+
}
94126
}
95127
}

UnitsNet/GeneratedCode/Quantities/BitRate.g.cs

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/Duration.g.cs

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/Frequency.g.cs

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/Information.g.cs

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)