1515package ucum
1616
1717import (
18+ "math"
1819 "testing"
1920)
2021
22+ // almostEqual checks if two float64 values are approximately equal within a small tolerance
23+ func almostEqual (a , b float64 ) bool {
24+ return math .Abs (a - b ) < 1e-10
25+ }
26+
2127func TestConvertUnit (t * testing.T ) {
2228 tests := []struct {
2329 name string
@@ -32,6 +38,38 @@ func TestConvertUnit(t *testing.T) {
3238 {"g to kg" , 1000.0 , "g" , "kg" , 1.0 },
3339 {"same units" , 1.0 , "m" , "m" , 1.0 },
3440 {"empty units" , 1.0 , "" , "" , 1.0 }, // "" is treated as "1"
41+
42+ // Clinical mass units
43+ {"mg to g" , 1000.0 , "mg" , "g" , 1.0 },
44+ {"g to mg" , 1.0 , "g" , "mg" , 1000.0 },
45+ {"mg to kg" , 1000000.0 , "mg" , "kg" , 1.0 },
46+ {"kg to mg" , 1.0 , "kg" , "mg" , 1000000.0 },
47+
48+ // Clinical volume units
49+ {"mL to L" , 1000.0 , "mL" , "L" , 1.0 },
50+ {"L to mL" , 1.0 , "L" , "mL" , 1000.0 },
51+ {"mL to dL" , 100.0 , "mL" , "dL" , 1.0 },
52+ {"dL to mL" , 1.0 , "dL" , "mL" , 100.0 },
53+
54+ // Clinical enzyme units
55+ {"U to mU" , 1.0 , "U" , "mU" , 1000.0 },
56+ {"mU to U" , 1000.0 , "mU" , "U" , 1.0 },
57+ {"U to uU" , 1.0 , "U" , "uU" , 1000000.0 },
58+ {"uU to U" , 1000000.0 , "uU" , "U" , 1.0 },
59+ {"U to nU" , 1.0 , "U" , "nU" , 1000000000.0 },
60+ {"nU to U" , 1000000000.0 , "nU" , "U" , 1.0 },
61+ {"U to kU" , 1000.0 , "U" , "kU" , 1.0 },
62+ {"kU to U" , 1.0 , "kU" , "U" , 1000.0 },
63+
64+ // Clinical osmolality units
65+ {"osm to mosm" , 1.0 , "osm" , "mosm" , 1000.0 },
66+ {"mosm to osm" , 1000.0 , "mosm" , "osm" , 1.0 },
67+
68+ // Clinical equivalents
69+ {"eq to meq" , 1.0 , "eq" , "meq" , 1000.0 },
70+ {"meq to eq" , 1000.0 , "meq" , "eq" , 1.0 },
71+ {"eq to ueq" , 1.0 , "eq" , "ueq" , 1000000.0 },
72+ {"ueq to eq" , 1000000.0 , "ueq" , "eq" , 1.0 },
3573 }
3674
3775 for _ , tt := range tests {
@@ -40,7 +78,7 @@ func TestConvertUnit(t *testing.T) {
4078 if err != nil {
4179 t .Errorf ("ConvertUnit(%v, %q, %q) failed with error = %v" , tt .fromVal , tt .fromUnit , tt .toUnit , err )
4280 }
43- if val != tt .wantVal {
81+ if ! almostEqual ( val , tt .wantVal ) {
4482 t .Errorf ("ConvertUnit(%v, %q, %q) val = %v, want %v" , tt .fromVal , tt .fromUnit , tt .toUnit , val , tt .wantVal )
4583 }
4684 })
@@ -147,6 +185,32 @@ func TestValidateUnit(t *testing.T) {
147185 {"cql date unit minute when allowed" , "minute" , false , true },
148186 {"cql date unit second when allowed" , "second" , false , true },
149187 {"cql date unit millisecond when allowed" , "millisecond" , false , true },
188+
189+ // Clinical units
190+ {"clinical mass unit mg" , "mg" , false , false },
191+ {"clinical volume unit mL" , "mL" , false , false },
192+ {"clinical enzyme unit U" , "U" , false , false },
193+ {"clinical enzyme unit mU" , "mU" , false , false },
194+ {"clinical enzyme unit uU" , "uU" , false , false },
195+ {"clinical enzyme unit nU" , "nU" , false , false },
196+ {"clinical enzyme unit kU" , "kU" , false , false },
197+ {"clinical osmolality unit osm" , "osm" , false , false },
198+ {"clinical osmolality unit mosm" , "mosm" , false , false },
199+ {"clinical equivalent unit eq" , "eq" , false , false },
200+ {"clinical equivalent unit meq" , "meq" , false , false },
201+ {"clinical equivalent unit ueq" , "ueq" , false , false },
202+
203+ // Common clinical compound units
204+ {"compound unit mg/dL" , "mg/dL" , false , false },
205+ {"compound unit mg/mL" , "mg/mL" , false , false },
206+ {"compound unit U/L" , "U/L" , false , false },
207+ {"compound unit mU/mL" , "mU/mL" , false , false },
208+ {"compound unit mg/L" , "mg/L" , false , false },
209+ {"compound unit mL/h" , "mL/h" , false , false },
210+ {"compound unit mg/h" , "mg/h" , false , false },
211+ {"compound unit U/mL" , "U/mL" , false , false },
212+ {"compound unit mosm/L" , "mosm/L" , false , false },
213+ {"compound unit meq/L" , "meq/L" , false , false },
150214 }
151215
152216 for _ , tt := range tests {
0 commit comments