Skip to content

Commit 082effa

Browse files
committed
simplify tests, handle coef errors
1 parent b31b061 commit 082effa

File tree

3 files changed

+42
-62
lines changed

3 files changed

+42
-62
lines changed

native/explorer/src/datatypes.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -629,13 +629,17 @@ impl ExDecimal {
629629
}
630630
}
631631

632-
pub fn signed_coef(self) -> i128 {
632+
pub fn signed_coef(self) -> Result<i128, ExplorerError> {
633633
let base = self.sign as i128 * self.coef;
634634
if self.exp > 0 {
635635
base.checked_mul(10_i128.pow(self.exp as u32))
636-
.expect("coefficient overflow")
636+
.ok_or_else(|| {
637+
ExplorerError::Other(
638+
"cannot decode a valid decimal from term; check that `coef` fits into an `i128`. error: throw(<term>)".to_string()
639+
)
640+
})
637641
} else {
638-
base
642+
Ok(base)
639643
}
640644
}
641645

@@ -653,7 +657,7 @@ impl ExDecimal {
653657

654658
impl Literal for ExDecimal {
655659
fn lit(self) -> Expr {
656-
let coef = self.signed_coef();
660+
let coef = self.signed_coef().unwrap();
657661
let scale = self.scale();
658662

659663
Expr::Literal(LiteralValue::Scalar(Scalar::new(
@@ -721,6 +725,7 @@ impl<'a> rustler::Decoder<'a> for ExValidValue<'a> {
721725
} else if let Ok(duration) = term.decode::<ExDuration>() {
722726
Ok(ExValidValue::Duration(duration))
723727
} else if let Ok(decimal) = term.decode::<ExDecimal>() {
728+
decimal.signed_coef().map_err(|_| rustler::Error::BadArg)?;
724729
Ok(ExValidValue::Decimal(decimal))
725730
} else {
726731
Err(rustler::Error::BadArg)

native/explorer/src/series/from_list.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,14 +240,16 @@ pub fn s_from_list_decimal(
240240
})
241241
}
242242

243-
TermType::Map => item
244-
.decode::<ExDecimal>()
245-
.map(|ex_decimal| AnyValue::Decimal(ex_decimal.signed_coef(), ex_decimal.scale()))
246-
.map_err(|error| {
247-
ExplorerError::Other(format!(
243+
TermType::Map => {
244+
match item.decode::<ExDecimal>() {
245+
Ok(ex_decimal) => ex_decimal
246+
.signed_coef()
247+
.map(|coef| AnyValue::Decimal(coef, ex_decimal.scale())),
248+
Err(error) => Err(ExplorerError::Other(format!(
248249
"cannot decode a valid decimal from term; check that `coef` fits into an `i128`. error: {error:?}"
249-
))
250-
}),
250+
))),
251+
}
252+
}
251253
TermType::Atom => Ok(AnyValue::Null),
252254

253255
TermType::Float => item

test/explorer/series_test.exs

Lines changed: 24 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,64 +1998,37 @@ defmodule Explorer.SeriesTest do
19981998
assert Series.to_list(s3) === [Decimal.new("2.2"), Decimal.new("4.0"), Decimal.new("6.1")]
19991999
end
20002000

2001-
test "adding decimal series with scientific notation" do
2002-
# Test positive values with positive exponents
2003-
s1 = Series.from_list([Decimal.new("2.1e10"), Decimal.new("3.5e10"), Decimal.new("1.0e10")])
2004-
s2 = Series.from_list([Decimal.new("1.0e10"), Decimal.new("2.0e10"), Decimal.new("3.0e10")])
2005-
2006-
s3 = Series.add(s1, s2)
2007-
[v1, v2, v3] = Series.to_list(s3)
2008-
2009-
assert Decimal.eq?(v1, Decimal.new("3.1e10"))
2010-
assert Decimal.eq?(v2, Decimal.new("5.5e10"))
2011-
assert Decimal.eq?(v3, Decimal.new("4.0e10"))
2012-
2013-
# Test negative values with positive exponents
2014-
s4 =
2015-
Series.from_list([Decimal.new("-2.1e10"), Decimal.new("-3.5e10"), Decimal.new("-1.0e10")])
2016-
2017-
s5 = Series.from_list([Decimal.new("1.0e10"), Decimal.new("2.0e10"), Decimal.new("3.0e10")])
2018-
2019-
s6 = Series.add(s4, s5)
2020-
[v4, v5, v6] = Series.to_list(s6)
2021-
2022-
assert Decimal.eq?(v4, Decimal.new("-1.1e10"))
2023-
assert Decimal.eq?(v5, Decimal.new("-1.5e10"))
2024-
assert Decimal.eq?(v6, Decimal.new("2.0e10"))
2025-
2026-
# Test mixed negative and positive values
2027-
s7 =
2028-
Series.from_list([Decimal.new("-2.1e10"), Decimal.new("3.5e10"), Decimal.new("-1.0e10")])
2029-
2030-
s8 =
2031-
Series.from_list([Decimal.new("-1.0e10"), Decimal.new("-2.0e10"), Decimal.new("3.0e10")])
2032-
2033-
s9 = Series.add(s7, s8)
2034-
[v7, v8, v9] = Series.to_list(s9)
2035-
2036-
assert Decimal.eq?(v7, Decimal.new("-3.1e10"))
2037-
assert Decimal.eq?(v8, Decimal.new("1.5e10"))
2038-
assert Decimal.eq?(v9, Decimal.new("2.0e10"))
2039-
end
2001+
test "adding decimal series with positive and negative exponents" do
2002+
s1 =
2003+
Series.from_list([
2004+
Decimal.new("2.1e20"),
2005+
Decimal.new("-3.5e10"),
2006+
Decimal.new("1.5e-15"),
2007+
Decimal.new("1.0e2")
2008+
])
20402009

2041-
test "adding decimal series with maximum safe values" do
2042-
# Test maximum safe values in both scientific and normal notation
2043-
# Max safe is around 1e27 for i128 (< 2^127 ≈ 1.7e38)
2044-
s1 = Series.from_list([Decimal.new("1.0e27"), Decimal.new("1000000000000000000000000000")])
2045-
s2 = Series.from_list([Decimal.new("2.0e27"), Decimal.new("2000000000000000000000000000")])
2010+
s2 =
2011+
Series.from_list([
2012+
Decimal.new("1.0e20"),
2013+
Decimal.new("2.0e10"),
2014+
Decimal.new("2.5e-15"),
2015+
Decimal.new("5.0e-2")
2016+
])
20462017

20472018
s3 = Series.add(s1, s2)
2048-
[v1, v2] = Series.to_list(s3)
2019+
[v1, v2, v3, v4] = Series.to_list(s3)
20492020

2050-
assert Decimal.eq?(v1, Decimal.new("3.0e27"))
2051-
assert Decimal.eq?(v2, Decimal.new("3000000000000000000000000000"))
2021+
assert Decimal.eq?(v1, Decimal.new("3.1e20"))
2022+
assert Decimal.eq?(v2, Decimal.new("-1.5e10"))
2023+
assert Decimal.eq?(v3, Decimal.new("4.0e-15"))
2024+
assert Decimal.eq?(v4, Decimal.new("100.05"))
20522025
end
20532026

20542027
test "overflow with values exceeding i128 limits" do
2055-
# This should fail: 3.4e38 exceeds i128 max (2^127 - 1 ≈ 1.7e38)
2056-
assert_raise ErlangError, fn ->
2057-
Series.from_list([Decimal.new("3.4e38")])
2058-
end
2028+
assert_raise RuntimeError,
2029+
"Generic Error: cannot decode a valid decimal from term;" <>
2030+
" check that `coef` fits into an `i128`. error: throw(<term>)",
2031+
fn -> Series.from_list([Decimal.new("3.4e38")]) end
20592032
end
20602033
end
20612034

0 commit comments

Comments
 (0)