Skip to content

Commit b9828dd

Browse files
committed
add tests for different pre_add_expos and different expo fractions
1 parent aada8ab commit b9828dd

File tree

1 file changed

+81
-34
lines changed

1 file changed

+81
-34
lines changed

pyth-sdk/src/price.rs

Lines changed: 81 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ impl Price {
639639

640640
#[cfg(test)]
641641
mod test {
642-
use quickcheck::{Arbitrary, Gen, TestResult};
642+
use quickcheck::TestResult;
643643
use std::convert::TryFrom;
644644

645645
use crate::price::{
@@ -672,17 +672,6 @@ mod test {
672672
.unwrap()
673673
}
674674

675-
// arbitrary trait for quickcheck
676-
impl Arbitrary for Price {
677-
fn arbitrary(g: &mut Gen) -> Price {
678-
Price {
679-
price: i64::try_from(i32::arbitrary(g)).ok().unwrap(),
680-
conf: 0,
681-
expo: -9,//i32::arbitrary(g),
682-
publish_time: 0
683-
}
684-
}
685-
}
686675

687676
#[test]
688677
fn test_normalize() {
@@ -1700,6 +1689,53 @@ mod test {
17001689
pc(7_000_000, 0, -9)
17011690
);
17021691

1692+
// test with different pre_add_expos than -9
1693+
succeeds(
1694+
0,
1695+
pc(100, 0, -2),
1696+
100,
1697+
pc(8000, 0, -4),
1698+
50,
1699+
-1,
1700+
pc(9, 0, -1)
1701+
);
1702+
succeeds(
1703+
100_000,
1704+
pc(200_000, 0, -6),
1705+
200_000,
1706+
pc(-20_000_000_000, 0, -11),
1707+
175_000,
1708+
-4,
1709+
pc(-1_000, 0, -4)
1710+
);
1711+
succeeds(
1712+
2000,
1713+
pc(75, 0, 3),
1714+
10000,
1715+
pc(675_000_000, 0, -3),
1716+
6000,
1717+
-2,
1718+
pc(37_500_000, 0, -2)
1719+
);
1720+
succeeds(
1721+
0,
1722+
pc(100, 0, 2),
1723+
100,
1724+
pc(0, 0, -12),
1725+
200,
1726+
-12,
1727+
pc(-10_000_000_000_000_000, 0, -12)
1728+
);
1729+
succeeds(
1730+
0,
1731+
pc(10, 0, 9),
1732+
1000,
1733+
pc(2, 0, 10),
1734+
6000,
1735+
6,
1736+
pc(70_000, 0, 6)
1737+
);
1738+
17031739
// test loss due to scaling
17041740
// lose more bc scale to higher expo
17051741
succeeds(
@@ -1761,6 +1797,16 @@ mod test {
17611797
-9,
17621798
pc(50, 0, -9)
17631799
);
1800+
// test with xs that yield fractions with significantly different expos
1801+
succeeds(
1802+
0,
1803+
pc(100_000_000, 0, -9),
1804+
1_000_000_000_000_000,
1805+
pc(0, 0, -9),
1806+
10_000_000,
1807+
-9,
1808+
pc(99_999_999, 0, -9)
1809+
);
17641810

17651811
// Test with end range of possible inputs in prices to identify precision inaccuracy
17661812
// precision inaccuracy due to loss in scaling
@@ -1939,33 +1985,34 @@ mod test {
19391985
);
19401986
}
19411987

1988+
pub fn construct_quickcheck_affine_combination_price(price: i64) -> Price {
1989+
return Price {
1990+
price: price,
1991+
conf: 0,
1992+
expo: -9,
1993+
publish_time: 0
1994+
}
1995+
}
1996+
19421997
// quickcheck to confirm affine_combination introduces no error if normalization done explicitly on prices first
19431998
#[quickcheck]
1944-
fn quickcheck_affine_combination_normalize_prices(x1_inp: i32, y1: Price, x2_inp: i32, y2: Price, x_query_inp: i32) -> TestResult {
1999+
fn quickcheck_affine_combination_normalize_prices(x1_inp: i32, p1: i32, x2_inp: i32, p2: i32, x_query_inp: i32) -> TestResult {
2000+
// generating xs and prices from i32 to limit the range to reasonable values and guard against overflow/bespoke constraint setting for quickcheck
2001+
let y1 = construct_quickcheck_affine_combination_price(i64::try_from(p1).ok().unwrap());
2002+
let y2 = construct_quickcheck_affine_combination_price(i64::try_from(p2).ok().unwrap());
2003+
19452004
let x1 = i64::try_from(x1_inp).ok().unwrap();
19462005
let x2 = i64::try_from(x2_inp).ok().unwrap();
19472006
let x_query = i64::try_from(x_query_inp).ok().unwrap();
19482007

2008+
// stick with single expo for ease of testing and generation
19492009
let pre_add_expo = -9;
19502010

1951-
// require x2 > x1
2011+
// require x2 > x1, as needed for affine_combination
19522012
if x1 >= x2 {
19532013
return TestResult::discard()
19542014
}
19552015

1956-
// require low pre_add_expo
1957-
if pre_add_expo >= 2 {
1958-
return TestResult::discard()
1959-
}
1960-
1961-
// require reasonable price/conf range
1962-
if (y1.price > 2*MAX_PD_V_I64) || (y1.price < 2*MIN_PD_V_I64) {
1963-
return TestResult::discard()
1964-
}
1965-
if (y2.price > 2*MAX_PD_V_I64) || (y2.price < 2*MIN_PD_V_I64) {
1966-
return TestResult::discard()
1967-
}
1968-
19692016
let result_orig = Price::affine_combination(x1, y1, x2, y2, x_query, pre_add_expo).unwrap();
19702017

19712018
let y1_norm = y1.normalize().unwrap();
@@ -1978,14 +2025,19 @@ mod test {
19782025

19792026
// quickcheck to confirm affine_combination introduces bounded error if close fraction x/y passed in first
19802027
#[quickcheck]
1981-
fn quickcheck_affine_combination_normalize_fractions(x1_inp: i32, y1: Price, x2_inp: i32, y2: Price, x_query_inp: i32) -> TestResult {
2028+
fn quickcheck_affine_combination_normalize_fractions(x1_inp: i32, p1: i32, x2_inp: i32, p2: i32, x_query_inp: i32) -> TestResult {
2029+
// generating xs and prices from i32 to limit the range to reasonable values and guard against overflow/bespoke constraint setting for quickcheck
2030+
let y1 = construct_quickcheck_affine_combination_price(i64::try_from(p1).ok().unwrap());
2031+
let y2 = construct_quickcheck_affine_combination_price(i64::try_from(p2).ok().unwrap());
2032+
19822033
let x1 = i64::try_from(x1_inp).ok().unwrap();
19832034
let x2 = i64::try_from(x2_inp).ok().unwrap();
19842035
let x_query = i64::try_from(x_query_inp).ok().unwrap();
19852036

2037+
// stick with single expo for ease of testing and generation
19862038
let pre_add_expo = -9;
19872039

1988-
// require x2 > x1
2040+
// require x2 > x1, as needed for affine_combination
19892041
if x1 >= x2 {
19902042
return TestResult::discard()
19912043
}
@@ -1994,11 +2046,6 @@ mod test {
19942046
return TestResult::discard()
19952047
}
19962048

1997-
// require low pre_add_expo
1998-
if pre_add_expo >= 2 {
1999-
return TestResult::discard()
2000-
}
2001-
20022049
// require reasonable price/conf range
20032050
if (y1.price > 2*MAX_PD_V_I64) || (y1.price < 2*MIN_PD_V_I64) {
20042051
return TestResult::discard()

0 commit comments

Comments
 (0)