Skip to content

Commit 361223d

Browse files
authored
Merge branch 'develop' into Slice-fixes
2 parents 0a0e4dd + b0e9aca commit 361223d

File tree

4 files changed

+328
-55
lines changed

4 files changed

+328
-55
lines changed

Cql/CoreTests/PrimitiveTests.cs

Lines changed: 186 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Hl7.Cql.Abstractions;
1010
using Hl7.Cql.CodeGeneration.NET.Toolkit;
1111
using Hl7.Cql.Compiler;
12+
using Hl7.Cql.Elm;
1213
using Hl7.Cql.Fhir;
1314
using Hl7.Cql.Iso8601;
1415
using Hl7.Cql.Operators;
@@ -3540,7 +3541,191 @@ public void QuantityToString()
35403541
s.Should().Be("125 'cm'");
35413542
}
35423543

3543-
#region Slice tests
3544+
[TestMethod]
3545+
public void Add_Date_Quantity()
3546+
{
3547+
var rc = GetNewContext();
3548+
var fcq = rc.Operators;
3549+
3550+
var inputDate = new CqlDate(9999, 12, 30);
3551+
var quantity = new CqlQuantity(1, "day");
3552+
CqlDate expectedDate = new CqlDate(9999, 12, 31);
3553+
var newDate = fcq.Add(inputDate, quantity);
3554+
Assert.IsNotNull(newDate);
3555+
Assert.AreEqual(expectedDate, newDate);
3556+
}
3557+
3558+
[TestMethod]
3559+
public void Add_Date_Quantity_To_MaxDate()
3560+
{
3561+
var rc = GetNewContext();
3562+
var fcq = rc.Operators;
3563+
3564+
var quantity = new CqlQuantity(1, "day");
3565+
var inputDateMaxValue = CqlDate.MaxValue;
3566+
var newDateAddMax = fcq.Add(inputDateMaxValue, quantity);
3567+
Assert.IsNull(newDateAddMax);
3568+
}
3569+
3570+
[TestMethod]
3571+
public void Subtract_Date_Quantity()
3572+
{
3573+
var rc = GetNewContext();
3574+
var fcq = rc.Operators;
3575+
3576+
var inputDate = new CqlDate(1, 1, 2);
3577+
var quantity = new CqlQuantity(1, "day");
3578+
CqlDate expectedDate = new CqlDate(1, 1, 1);
3579+
var newDate = fcq.Subtract(inputDate, quantity);
3580+
Assert.IsNotNull(newDate);
3581+
Assert.AreEqual(expectedDate, newDate);
3582+
}
3583+
3584+
[TestMethod]
3585+
public void Subtract_Date_Quantity_To_MinDate()
3586+
{
3587+
var rc = GetNewContext();
3588+
var fcq = rc.Operators;
3589+
3590+
var quantity = new CqlQuantity(1, "day");
3591+
var inputDateMinValue = CqlDate.MinValue;
3592+
var newDateSubtractedMin = fcq.Subtract(inputDateMinValue, quantity);
3593+
Assert.IsNull(newDateSubtractedMin);
3594+
}
3595+
3596+
[TestMethod]
3597+
public void Add_Integers()
3598+
{
3599+
var rc = GetNewContext();
3600+
var fcq = rc.Operators;
3601+
3602+
int expectedResult = 2;
3603+
var addedValue = fcq.Add(1, 1);
3604+
Assert.IsNotNull(addedValue);
3605+
Assert.AreEqual(expectedResult, addedValue);
3606+
}
3607+
3608+
[TestMethod]
3609+
public void Add_Integer_To_MaxInteger()
3610+
{
3611+
var rc = GetNewContext();
3612+
var fcq = rc.Operators;
3613+
3614+
var addedValue = fcq.Add(int.MaxValue, 1);
3615+
Assert.IsNull(addedValue);
3616+
}
3617+
3618+
[TestMethod]
3619+
public void Add_Longs()
3620+
{
3621+
var rc = GetNewContext();
3622+
var fcq = rc.Operators;
3623+
3624+
long expectedResult = 2L;
3625+
var addedValue = fcq.Add(1L, 1L);
3626+
Assert.IsNotNull(addedValue);
3627+
Assert.AreEqual(expectedResult, addedValue);
3628+
}
3629+
3630+
[TestMethod]
3631+
public void Add_Long_To_MaxLong()
3632+
{
3633+
var rc = GetNewContext();
3634+
var fcq = rc.Operators;
3635+
3636+
var addedValue = fcq.Add(long.MaxValue, 1L);
3637+
Assert.IsNull(addedValue);
3638+
}
3639+
3640+
[TestMethod]
3641+
public void Add_Decimals()
3642+
{
3643+
var rc = GetNewContext();
3644+
var fcq = rc.Operators;
3645+
3646+
decimal expectedResult = 2m;
3647+
var addedValue = fcq.Add(1m, 1m);
3648+
Assert.IsNotNull(addedValue);
3649+
Assert.AreEqual(expectedResult, addedValue);
3650+
}
3651+
3652+
[TestMethod]
3653+
public void Add_Decimal_To_MaxDecimal()
3654+
{
3655+
var rc = GetNewContext();
3656+
var fcq = rc.Operators;
3657+
3658+
var addedValue = fcq.Add(decimal.MaxValue, 1m);
3659+
Assert.IsNull(addedValue);
3660+
}
3661+
3662+
[TestMethod]
3663+
public void Subtract_Integers()
3664+
{
3665+
var rc = GetNewContext();
3666+
var fcq = rc.Operators;
3667+
3668+
int expectedResult = 1;
3669+
var subtractedValue = fcq.Subtract(2, 1);
3670+
Assert.IsNotNull(subtractedValue);
3671+
Assert.AreEqual(expectedResult, subtractedValue);
3672+
}
3673+
3674+
[TestMethod]
3675+
public void Subtract_Integer_To_MinInteger()
3676+
{
3677+
var rc = GetNewContext();
3678+
var fcq = rc.Operators;
3679+
3680+
var subtractedValue = fcq.Subtract(int.MinValue, 1);
3681+
Assert.IsNull(subtractedValue);
3682+
}
3683+
3684+
[TestMethod]
3685+
public void Subtract_Longs()
3686+
{
3687+
var rc = GetNewContext();
3688+
var fcq = rc.Operators;
3689+
3690+
long expectedResult = 1L;
3691+
var subtractedValue = fcq.Subtract(2L, 1L);
3692+
Assert.IsNotNull(subtractedValue);
3693+
Assert.AreEqual(expectedResult, subtractedValue);
3694+
}
3695+
3696+
[TestMethod]
3697+
public void Subtract_Long_To_MinLong()
3698+
{
3699+
var rc = GetNewContext();
3700+
var fcq = rc.Operators;
3701+
3702+
var subtractedValue = fcq.Subtract(long.MinValue, 1L);
3703+
Assert.IsNull(subtractedValue);
3704+
}
3705+
3706+
[TestMethod]
3707+
public void Subtract_Decimals()
3708+
{
3709+
var rc = GetNewContext();
3710+
var fcq = rc.Operators;
3711+
3712+
decimal expectedResult = 1m;
3713+
var subtractedValue = fcq.Subtract(2m, 1m);
3714+
Assert.IsNotNull(subtractedValue);
3715+
Assert.AreEqual(expectedResult, subtractedValue);
3716+
}
3717+
3718+
[TestMethod]
3719+
public void Subtract_Decimal_To_MinDecimal()
3720+
{
3721+
var rc = GetNewContext();
3722+
var fcq = rc.Operators;
3723+
3724+
var subtractedValue = fcq.Subtract(decimal.MinValue, 1m);
3725+
Assert.IsNull(subtractedValue);
3726+
}
3727+
3728+
#region Slice tests
35443729

35453730
/* Refer http://cql.hl7.org/09-b-cqlreference.html for operation details on Skip, Tail and Take cql operators
35463731
* These CQL operators uses Slice semantics from http://cql.hl7.org/04-logicalspecification.html#slice
@@ -3722,7 +3907,6 @@ public void Slice_linkedList_source()
37223907
Assert.IsNotNull(slicedList);
37233908
CollectionAssert.AreEqual(expectedList, slicedList.ToList());
37243909
}
3725-
37263910
#endregion
37273911
}
37283912
}

Cql/Cql.Abstractions/Primitives/CqlDate.cs

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -153,50 +153,42 @@ public static bool TryParse(string s, out CqlDate? cqlDate)
153153
quantity = quantity.NormalizeTo(Precision);
154154
var value = -1 * quantity.value!.Value;
155155
var dto = Value.DateTimeOffset;
156-
try
156+
switch (quantity.unit![0])
157157
{
158-
switch (quantity.unit![0])
159-
{
160-
case 'a':
161-
dto = dto.AddYears((int)value);
162-
break;
163-
case 'm':
164-
if (quantity.unit.Length > 1)
158+
case 'a':
159+
dto = dto.AddYears((int)value);
160+
break;
161+
case 'm':
162+
if (quantity.unit.Length > 1)
163+
{
164+
switch (quantity.unit[1])
165165
{
166-
switch (quantity.unit[1])
167-
{
168-
case 'o':
169-
dto = dto.AddMonths((int)value);
170-
break;
171-
case 'i':
172-
dto = dto.AddMinutes(Math.Truncate((double)value));
173-
break;
174-
case 's':
175-
dto = dto.AddMilliseconds(Math.Truncate((double)value));
176-
break;
177-
default: throw new ArgumentException($"Unknown date unit {quantity.unit} supplied");
178-
}
166+
case 'o':
167+
dto = dto.AddMonths((int)value);
168+
break;
169+
case 'i':
170+
dto = dto.AddMinutes(Math.Truncate((double)value));
171+
break;
172+
case 's':
173+
dto = dto.AddMilliseconds(Math.Truncate((double)value));
174+
break;
175+
default: throw new ArgumentException($"Unknown date unit {quantity.unit} supplied");
179176
}
180-
break;
181-
case 'd':
182-
dto = dto.AddDays((int)value!);
183-
break;
184-
case 'w':
185-
dto = dto.AddDays((int)(value! * CqlDateTimeMath.DaysPerWeek));
186-
break;
187-
case 'h':
188-
dto = dto.AddHours(Math.Truncate((double)value));
189-
break;
190-
case 's':
191-
dto = dto.AddSeconds(Math.Truncate((double)value));
192-
break;
193-
default: throw new ArgumentException($"Unknown date unit {quantity.unit} supplied");
194-
}
195-
}
196-
catch (ArgumentOutOfRangeException)
197-
{
198-
// In cases where e.g. Predecessor is called on minimum Date.
199-
return null;
177+
}
178+
break;
179+
case 'd':
180+
dto = dto.AddDays((int)value!);
181+
break;
182+
case 'w':
183+
dto = dto.AddDays((int)(value! * CqlDateTimeMath.DaysPerWeek));
184+
break;
185+
case 'h':
186+
dto = dto.AddHours(Math.Truncate((double)value));
187+
break;
188+
case 's':
189+
dto = dto.AddSeconds(Math.Truncate((double)value));
190+
break;
191+
default: throw new ArgumentException($"Unknown date unit {quantity.unit} supplied");
200192
}
201193

202194
var newIsoDate = new DateIso8601(dto, Value.Precision);

Cql/Cql.Runtime/Operators/CqlOperators.ArithmeticOperators.cs

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,42 @@ internal partial class CqlOperators
5454
public int? Add(int? left, int? right)
5555
{
5656
if (left == null || right == null) return null;
57-
else return left + right;
57+
try
58+
{
59+
return checked(left + right);
60+
}
61+
catch (OverflowException e)
62+
{
63+
Message(new { left, right, e }, "CqlOperators.ArithmeticOperators.Add", "Warning", "Ignored overflow errors from type integer addition, returned null.");
64+
return null;
65+
}
5866
}
5967

6068
public long? Add(long? left, long? right)
6169
{
6270
if (left == null || right == null) return null;
63-
else return left + right;
71+
try
72+
{
73+
return checked(left + right);
74+
}
75+
catch (OverflowException e)
76+
{
77+
Message(new { left, right, e }, "CqlOperators.ArithmeticOperators.Add", "Warning", "Ignored overflow errors from type long addition, returned null.");
78+
return null;
79+
}
6480
}
6581
public decimal? Add(decimal? left, decimal? right)
6682
{
6783
if (left == null || right == null) return null;
68-
else return left + right;
84+
try
85+
{
86+
return checked(left + right);
87+
}
88+
catch (OverflowException e)
89+
{
90+
Message(new { left, right, e }, "CqlOperators.ArithmeticOperators.Add", "Warning", "Ignored overflow errors from type decimal addition, returned null.");
91+
return null;
92+
}
6993
}
7094

7195
public CqlQuantity? Add(CqlQuantity? left, CqlQuantity? right)
@@ -674,18 +698,42 @@ internal partial class CqlOperators
674698
public int? Subtract(int? left, int? right)
675699
{
676700
if (left == null || right == null) return null;
677-
else return left - right;
701+
try
702+
{
703+
return checked(left - right);
704+
}
705+
catch (OverflowException e)
706+
{
707+
Message(new { left, right, e }, "CqlOperators.ArithmeticOperators.Subtract", "Warning", "Ignored overflow errors from type integer subtraction, returned null.");
708+
return null;
709+
}
678710
}
679711

680712
public long? Subtract(long? left, long? right)
681713
{
682714
if (left == null || right == null) return null;
683-
else return left - right;
715+
try
716+
{
717+
return checked(left - right);
718+
}
719+
catch (OverflowException e)
720+
{
721+
Message(new { left, right, e }, "CqlOperators.ArithmeticOperators.Subtract", "Warning", "Ignored overflow errors from type long subtraction, returned null.");
722+
return null;
723+
}
684724
}
685725
public decimal? Subtract(decimal? left, decimal? right)
686726
{
687727
if (left == null || right == null) return null;
688-
else return left - right;
728+
try
729+
{
730+
return checked(left - right);
731+
}
732+
catch (OverflowException e)
733+
{
734+
Message(new { left, right, e }, "CqlOperators.ArithmeticOperators.Subtract", "Warning", "Ignored overflow errors from type decimal subtraction, returned null.");
735+
return null;
736+
}
689737
}
690738

691739
public CqlQuantity? Subtract(CqlQuantity? left, CqlQuantity? right)

0 commit comments

Comments
 (0)