use crate::*;
use crate::FmtMode::{Eng, Fix, Sci, Std};
use crate::NumFmtBuffer;
use crate::test_values::StdFixValues;
fn test_format_opt(values: Vec<(f64, Option<u32>, Option<u32>, FmtMode, bool, &str)>) {
let mut error = false;
for (idx, (value, width, precision, mode, trailing_dot_zero, exp_string)) in values.into_iter().enumerate() {
let options = FmtOptions {
width,
precision,
trailing_dot_zero,
mode,
..FmtOptions::default()
};
let string = value.format_opt(&options);
if string != exp_string {
error = true;
println!("test #{idx}: expecting '{exp_string}' but got '{string}'");
} else {
}
}
assert!(!error);
}
#[test]
fn std() {
let values = vec![
(1.0, None, None, Std, true, "1.0"),
(1.0, None, None, Std, false, "1"),
(10.0, None, None, Std, true, "10.0"),
(10.0, None, None, Std, false, "10"),
(1.0, Some(10), Some(2), Std, false, "1.00"),
(10.0, Some(10), Some(2), Std, false, "10.00"),
(2.0, None, Some(0), Std, false, "2"),
(2.0, None, Some(0), Std, true, "2"),
(100000.0, Some(5), None, Std, false, "1e5"),
(100000.0, Some(5), None, Std, true, "1.0e5"),
(1200.0, Some(4), Some(2), Std, false, "1200"),
(1234.0, Some(4), Some(2), Std, false, "1234"),
(1200.0, Some(3), Some(2), Std, false, "1e3"),
(1234.0, Some(3), Some(2), Std, false, "1e3"),
(1500.0, Some(3), Some(2), Std, false, "2e3"),
(2500.0, Some(3), Some(2), Std, false, "2e3"),
(120000.0, Some(5), Some(2), Std, false, "1.2e5"),
(125000.0, Some(5), Some(2), Std, false, "1.2e5"),
(115000.0, Some(5), Some(2), Std, false, "1.2e5"),
(120000.0, Some(4), None, Std, false, "1e5"),
(150000.0, Some(4), None, Std, false, "2e5"),
(120000.0, Some(5), None, Std, false, "1.2e5"),
(1150000000.0, Some(5), Some(1), Std, false, "1.2e9"),
(9950000000.0, Some(5), Some(1), Std, false, "1e10"),
(10.25, Some(10), Some(2), Std, false, "10.25"),
(10.95, Some(10), None, Std, false, "10.95"),
(10.95, Some(4), None, Std, false, "11.0"),
(10.95, Some(4), Some(3), Std, false, "11.0"),
(10.95, Some(4), Some(0), Std, false, "11"),
(9.95, Some(3), Some(3), Std, false, "10"),
(9.95, Some(4), Some(1), Std, false, "10.0"),
(2222.25, Some(3), None, Std, false, "2e3"),
(9999.95, Some(3), None, Std, false, "1e4"),
(9999.95, Some(3), Some(1), Std, false, "1e4"),
(1.5, None, Some(4), Std, true, "1.5000"),
(1.5, Some(10), Some(4), Std, true, "1.5000"),
(1.5, Some(4), Some(4), Std, true, "1.50"),
(1.5, None, Some(0), Std, false, "2"),
(1.5, None, Some(0), Std, true, "2"),
(1.5, None, None, Std, true, "1.5"),
(99999.95, Some(5), Some(1), Std, false, "1.0e5"),
(12000.0, None, Some(1), Std, true, "12000.0"),
(12000.0, None, None, Std, true, "12000.0"),
(12000.0, None, None, Std, false, "12000"),
(12000.0, None, Some(4), Std, true, "12000.0000"),
(1.0, None, Some(4), Std, true, "1.0000"),
(1.0, None, Some(0), Std, true, "1"),
(12000.0, Some(10), Some(1), Std, true, "12000.0"),
(12000.0, Some(10), None, Std, true, "12000.0"),
(12000.0, Some(10), None, Std, false, "12000"),
(12000.0, Some(10), Some(4), Std, true, "12000.0000"),
(1.0, Some(10), Some(4), Std, true, "1.0000"),
(1.0, Some(10), Some(0), Std, true, "1"),
(12000.0, Some(8), Some(4), Std, true, "12000.00"),
(1.0, Some(4), Some(4), Std, true, "1.00"),
(0.5, None, Some(0), Std, false, "0"),
(0.5, None, Some(0), Std, true, "0"),
(0.5, None, None, Std, false, "0.5"),
(0.1234, None, None, Std, true, "0.1234"),
(0.1234, Some(10), None, Std, true, "0.1234"),
(0.0123, Some(4), None, Std, true, "0.01"),
(0.0995, Some(5), None, Std, true, "0.100"),
(0.9995, Some(5), None, Std, true, "1.000"),
(0.0001, Some(4), None, Std, true, "1e-4"),
(0.1234, Some(8), Some(2), Std, true, "0.12"),
(0.00001234, Some(6), Some(2), Std, true, "1.2e-5"),
(0.0000995, Some(6), Some(2), Std, true, "1.0e-4"),
(0.0005, None, Some(4), Std, true, "0.0005"),
(0.0005, None, Some(6), Std, true, "0.000500"),
(0.099, Some(4), Some(2), Std, false, "0.10"),
(0.00099, Some(6), Some(4), Std, false, "0.0010"),
(99.999, Some(6), Some(2), Std, false, "100.00"),
(99.999, None, Some(2), Std, false, "100.00"),
(99.995, None, Some(2), Std, false, "100.00"),
(99.989, None, Some(2), Std, false, "99.99"),
];
test_format_opt(values);
}
#[test]
fn limit_fix_std() {
let lim = StdFixValues::new();
let values = vec![
(lim.max_fix, None, None, Fix, true, lim.max_fix_str.as_str()),
(lim.low_fix, None, None, Fix, true, lim.low_fix_str.as_str()),
(lim.low_fix, None, None, Std, true, lim.low_sci_str.as_str()),
(lim.min_fix, None, None, Fix, true, lim.min_fix_str.as_str()),
(lim.min_fix, None, None, Std, true, lim.min_fix_str.as_str()),
(lim.max_fix, None, None, Fix, true, lim.max_fix_str.as_str()),
(lim.max_fix, None, None, Std, true, lim.max_fix_str.as_str()),
(lim.high_fix, None, None, Fix, true, lim.high_fix_str.as_str()),
(lim.high_fix, None, None, Std, true, lim.high_sci_str.as_str()),
];
test_format_opt(values);
}
#[test]
fn sci() {
let values = vec![
(1.0, None, None, Sci, false, "1e0"),
(-1.0, None, None, Sci, false, "-1e0"),
(1.0, None, None, Sci, true, "1.0e0"),
(1.0, None, Some(2), Sci, true, "1.00e0"),
(10.0, None, None, Sci, false, "1e1"),
(10.0, None, None, Sci, true, "1.0e1"),
(10.0, None, Some(2), Sci, true, "1.00e1"),
(1.0e5, None, None, Sci, false, "1e5"),
(1.0e10, None, None, Sci, false, "1e10"),
(1.0e15, None, None, Sci, false, "1e15"),
(1.0e100, None, None, Sci, false, "1e100"),
(1.0e150, None, None, Sci, false, "1e150"),
(1.0e125, None, None, Sci, false, "1e125"),
(1.0e-5, None, None, Sci, false, "1e-5"),
(1.0e-10, None, None, Sci, false, "1e-10"),
(1.0e-15, None, None, Sci, false, "1e-15"),
(1.0e-100, None, None, Sci, false, "1e-100"),
(1.0e-150, None, None, Sci, false, "1e-150"),
(1.0e-125, None, None, Sci, false, "1e-125"),
(9.995e-10, Some(7), Some(3), Sci, false, "1.00e-9"),
(9.295e-10, Some(7), Some(3), Sci, false, "9.3e-10"),
(9.295e-9, Some(7), Some(3), Sci, false, "9.30e-9"),
(9.295e-9, Some(9), Some(3), Sci, false, "9.295e-9"),
(9.999e9, Some(4), None, Sci, false, "1e10"),
(9.999e99, Some(5), None, Sci, false, "1e100"),
(9.999e9, Some(5), None, Sci, true, "1e10"),
(9.999e99, Some(6), None, Sci, true, "1e100"),
(9.999e9, Some(6), None, Sci, true, "1.0e10"),
(9.999e99, Some(7), None, Sci, true, "1.0e100"),
(-9.999e9, Some(5), None, Sci, true, "-1e10"),
(-9.999e99, Some(6), None, Sci, true, "-1e100"),
(-9.999e9, Some(6), None, Sci, true, "-1e10"),
(-9.999e99, Some(7), None, Sci, true, "-1e100"),
];
test_format_opt(values);
}
#[test]
fn eng() {
let values = vec![
(0.9995, None, Some(2), Eng, true, "1.00e0"),
(0.9995, None, Some(2), Std, true, "1.00"),
(100.0, None, Some(0), Eng, true, "100e0"),
(10.0, None, Some(0), Eng, true, "10e0"),
(1.0, None, Some(0), Eng, true, "1e0"),
(1000.0, None, Some(0), Eng, true, "1e3"),
(1.234, None, Some(1), Eng, true, "1.2e0"),
(12.34, None, Some(1), Eng, true, "12e0"),
(123.4, None, Some(1), Eng, true, "120e0"),
(1234.0, None, Some(1), Eng, true, "1.2e3"),
(1.234, None, Some(2), Eng, true, "1.23e0"),
(12.34, None, Some(2), Eng, true, "12.3e0"),
(123.4, None, Some(2), Eng, true, "123e0"),
(1234.0, None, Some(2), Eng, true, "1.23e3"),
(1.234, None, Some(3), Eng, true, "1.234e0"),
(12.34, None, Some(3), Eng, true, "12.34e0"),
(123.4, None, Some(3), Eng, true, "123.4e0"),
(1234.0, None, Some(3), Eng, true, "1.234e3"),
(1000.0, None, Some(0), Eng, true, "1e3"),
(10000.0, None, Some(0), Eng, true, "10e3"),
(100000.0, None, Some(0), Eng, true, "100e3"),
(1000000.0, None, Some(0), Eng, true, "1e6"),
(10000000.0, None, Some(0), Eng, true, "10e6"),
(100000000.0, None, Some(0), Eng, true, "100e6"),
(1000000000.0, None, Some(0), Eng, true, "1e9"),
(10000000000.0, None, Some(0), Eng, true, "10e9"),
(100000000000.0, None, Some(0), Eng, true, "100e9"),
(1000000000000.0, None, Some(0), Eng, true, "1e12"),
(10000000000000.0, None, Some(0), Eng, true, "10e12"),
(100000000000000.0, None, Some(0), Eng, true, "100e12"),
(1000000000000000.0, None, Some(0), Eng, true, "1e15"),
(10000000000000000.0, None, Some(0), Eng, true, "10e15"),
];
test_format_opt(values);
}
#[test]
fn special() {
let values = vec![
(999.999, Some(0), Some(5), Std, true, "1e3"),
(f64::NAN, None, None, Std, false, "NaN"),
(f64::NEG_INFINITY, None, None, Std, false, "-inf"),
(f64::INFINITY, None, None, Std, false, "inf"),
(-0.0, None, None, Std, true, "-0.0"),
(0.0, None, None, Std, false, "0"),
(0.0, None, None, Std, true, "0.0"),
(f64::EPSILON, None, None, Sci, true, "2.220446049250313e-16"),
(f64::MIN, None, None, Sci, true, "-1.7976931348623157e308"),
(f64::MIN_POSITIVE, None, None, Sci, true, "2.2250738585072014e-308"),
(f64::MAX, None, None, Sci, true, "1.7976931348623157e308"),
(1.0e-307, None, None, Sci, true, "1.0e-307"),
(1.0e308, None, None, Sci, true, "1.0e308"),
(1234.1234, Some(0), None, Std, true, "1e3"),
(1234.1234, Some(0), Some(4), Std, true, "1e3"),
(999.999, Some(0), Some(5), Std, true, "1e3"),
];
test_format_opt(values);
}
#[test]
fn digits() {
let values = vec![
(1.0, None, None, Std, false, "1"),
(12.0, None, None, Std, false, "12"),
(123.0, None, None, Std, false, "123"),
(1234.0, None, None, Std, false, "1234"),
(12345.0, None, None, Std, false, "12345"),
(123456.0, None, None, Std, false, "123456"),
(1234567.0, None, None, Std, false, "1234567"),
(12345678.0, None, None, Std, false, "12345678"),
(123456789.0, None, None, Std, false, "123456789"),
(1234567890.0, None, None, Std, false, "1234567890"),
(12345678901.0, None, None, Std, false, "12345678901"),
(123456789012.0, None, None, Std, false, "123456789012"),
(1234567890123.0, None, None, Std, false, "1234567890123"),
(12345678901234.0, None, None, Std, false, "12345678901234"),
(123456789012345.0, None, None, Std, false, "123456789012345"),
(1234567890123456.0, None, None, Std, false, "1234567890123456"),
(12345678901234568.0, None, None, Std, false, "12345678901234568"),
(10.0, None, None, Std, false, "10"),
(100.0, None, None, Std, false, "100"),
(1000.0, None, None, Std, false, "1000"),
(10000.0, None, None, Std, false, "10000"),
(100000.0, None, None, Std, false, "100000"),
(1000000.0, None, None, Std, false, "1000000"),
(10000000.0, None, None, Std, false, "10000000"),
(100000000.0, None, None, Std, false, "100000000"),
(1000000000.0, None, None, Std, false, "1000000000"),
(10000000000.0, None, None, Std, false, "10000000000"),
(100000000000.0, None, None, Std, false, "100000000000"),
(1000000000000.0, None, None, Std, false, "1000000000000"),
(10000000000000.0, None, None, Std, false, "10000000000000"),
(100000000000000.0, None, None, Std, false, "100000000000000"),
(1000000000000000.0, None, None, Std, false, "1000000000000000"),
(1000000010000.0, None, None, Std, false, "1000000010000"),
(1e1, None, None, Sci, false, "1e1"),
(1e2, None, None, Sci, false, "1e2"),
(1e4, None, None, Sci, false, "1e4"),
(1e8, None, None, Sci, false, "1e8"),
(1e9, None, None, Sci, false, "1e9"),
(1e10, None, None, Sci, false, "1e10"),
(1e11, None, None, Sci, false, "1e11"),
(1e100, None, None, Sci, false, "1e100"),
(1e110, None, None, Sci, false, "1e110"),
(1e101, None, None, Sci, false, "1e101"),
];
test_format_opt(values);
}
#[test]
fn rounding_even() {
let values = vec![
(0.4, None, Some(0), Std, false, "0"),
(0.5, None, Some(0), Std, false, "0"),
(1.4, None, Some(0), Std, false, "1"),
(1.5, None, Some(0), Std, false, "2"),
(2.4, None, Some(0), Std, false, "2"),
(2.5, None, Some(0), Std, false, "2"),
(0.4, None, None, Std, false, "0.4"),
(0.5, None, None, Std, false, "0.5"),
(1.4, None, None, Std, false, "1.4"),
(1.5, None, None, Std, false, "1.5"),
(2.4, None, None, Std, false, "2.4"),
(2.5, None, None, Std, false, "2.5"),
];
test_format_opt(values);
}
#[test]
fn round() {
let values = vec![
("#04#", 1, 2, false, "#04#", false, false), ("#4#", 1, 1, true, "04#", true, false), ("#5#", 1, 1, true, "05#", true, false), ("#6#", 1, 1, true, "16#", true, false), ("#05#", 1, 2, false, "#05#", false, false), ("#15#", 1, 2, false, "#25#", false, false), ("#25#", 1, 2, false, "#25#", false, false), ("#35#", 1, 2, false, "#45#", false, false), ("#45#", 1, 2, false, "#45#", false, false), ("#55#", 1, 2, false, "#65#", false, false), ("#65#", 1, 2, false, "#65#", false, false), ("#75#", 1, 2, false, "#85#", false, false), ("#85#", 1, 2, false, "#85#", false, false), ("#95#", 1, 2, false, "#10#", false, true), ("#149#", 1, 2, false, "#149#", false, false), ("#151#", 1, 2, false, "#251#", false, false), ("#251#", 1, 2, false, "#351#", false, false), ("#95#", 1, 2, false, "#10#", false, true), ("##95#", 2, 3, true, "#105#", true, false), ("##9999#", 2, 5, true, "#10009#", true, false),
("##9989#", 2, 5, true, "##9999#", false, false),
("##9899#", 2, 5, true, "##9909#", false, false),
("##8999#", 2, 5, true, "##9009#", false, false),
];
for (idx, (buffer, start, prev, can_eat_left, exp_buffer, exp_left, exp_right)) in values.into_iter().enumerate() {
unsafe {
let mut buf = buffer.as_bytes().to_owned();
let start_ptr = buf.as_mut_ptr().add(start);
let prev_ptr = buf.as_mut_ptr().add(prev);
let potential_tie = *prev_ptr.add(1) == b'#';
let (left, right) = NumFmtBuffer::round(start_ptr, prev_ptr, potential_tie, can_eat_left);
let msg = format!("test #{idx}: ");
let res_buf = String::from_utf8(buf).unwrap();
assert_eq!(left, exp_left, "{}left", msg);
assert_eq!(right, exp_right, "{}right", msg);
assert_eq!(res_buf, exp_buffer, "{}buffer", msg);
}
}
}
#[test]
fn negative_zero() {
let mut options = FmtOptions::default();
let mzero = -0.0;
let pzero = 0.0;
assert_eq!(mzero.format_opt(&options), "-0.0");
assert_eq!(pzero.format_opt(&options), "0.0");
options.negative_zero = false;
assert_eq!(mzero.format_opt(&options), "0.0");
assert_eq!(pzero.format_opt(&options), "0.0");
}