-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtests.rs
More file actions
147 lines (131 loc) · 4.53 KB
/
Copy pathtests.rs
File metadata and controls
147 lines (131 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! Testing specific to `num-primitive`
//!
//! NOTE: we're not attempting much functional testing in this crate, because we're not actually
//! *implementing* much of anything, just connecting to existing inherent items on the primitive
//! types. If those are wrong, that's an issue for the standard library.
//!
//! The use of forwarding macros with the same name mostly eliminates the chance of typos
//! referencing the wrong things, and the `unconditional-recursion` lint makes sure we're calling
//! something other than ourself.
//!
//! We should still write tests for issues that are unique to us though. An example from early
//! experiments is that the `TryFrom` error types were not constrained, so even a simple
//! `Result::unwrap` wouldn't work -- so now we have `PrimitiveError` and some tests for that.
extern crate alloc;
use alloc::boxed::Box;
use core::convert::Infallible;
use core::error::Error;
use core::num::{ParseFloatError, ParseIntError};
use crate::{
PrimitiveError, PrimitiveFloat, PrimitiveInteger, PrimitiveNumber, PrimitiveSigned,
PrimitiveUnsigned,
};
fn check_result<'a, T: PrimitiveNumber, E: PrimitiveError>(r: Result<T, E>, ok: T) {
// Cloning and equating results requires `E: Clone + PartialEq`
assert_eq!(r.clone(), Ok(ok));
// Unwrapping requires `E: Debug`
assert_eq!(r.clone().unwrap(), ok);
// `?`-convert to a boxed error
let result: Result<T, Box<dyn Error + 'a>> = (|| Ok(r.clone()?))();
assert_eq!(result.unwrap(), ok);
// `?`-convert to a boxed thread-safe error
let result: Result<T, Box<dyn Error + Send + Sync + 'a>> = (|| Ok(r.clone()?))();
assert_eq!(result.unwrap(), ok);
}
#[test]
fn parse() {
// `PrimitiveNumber` is not specific about the `FromStr` error type,
// only constraining that it implements `PrimitiveError`.
fn check<T: PrimitiveNumber>(s: &str, ok: T) {
check_result(s.parse(), ok);
}
check("0", 0u32);
}
#[test]
fn parse_float() {
// `PrimitiveFloat` is specific about the `FromStr` error type.
fn check<T: PrimitiveFloat>(s: &str, ok: T) {
let r: Result<T, ParseFloatError> = s.parse();
assert_eq!(r, Ok(ok));
}
check("0", 0f32);
}
#[test]
fn parse_int() {
// `PrimitiveInteger` is specific about the `FromStr` error type.
fn check<T: PrimitiveInteger>(s: &str, ok: T) {
let r: Result<T, ParseIntError> = s.parse();
assert_eq!(r, Ok(ok));
}
check("0", 0u32);
}
#[test]
fn try_from() {
// `PrimitiveInteger` is not specific about the `TryFrom` error type,
// only constraining that it implements `PrimitiveError`.
fn check<T: PrimitiveInteger>(x: i32, ok: T) {
check_result(T::try_from(x), ok);
}
check(0i32, 0u32);
}
#[test]
fn try_from_signed() {
// `PrimitiveSigned` is specific that `TryFrom<i8>` is infallible.
// (implied by `From<i8>`, but we still need an explicit constraint)
fn check<T: PrimitiveSigned>(x: i8, ok: T) {
let r: Result<T, Infallible> = T::try_from(x);
assert_eq!(r, Ok(ok));
}
check(0i8, 0i32);
}
#[test]
fn try_from_unsigned() {
// `PrimitiveUnsigned` is specific that `TryFrom<u8>` is infallible.
// (implied by `From<u8>`, but we still need an explicit constraint)
fn check<T: PrimitiveUnsigned>(x: u8, ok: T) {
let r: Result<T, Infallible> = T::try_from(x);
assert_eq!(r, Ok(ok));
}
check(0u8, 0u32);
}
#[test]
fn try_into() {
// `PrimitiveInteger` is not specific about the `TryInto` error type,
// only constraining that it implements `PrimitiveError`.
fn check<T: PrimitiveInteger>(x: T, ok: u32) {
check_result(x.try_into(), ok);
}
check(0i32, 0u32);
}
#[test]
fn constants() {
fn check<T: PrimitiveNumber>() {
for (i, c) in T::CONST.into_iter().enumerate() {
assert_eq!(T::as_from(i), c);
assert_eq!(i, c.as_to());
}
// explicitly const context
assert_eq!(T::as_from(0i32), const { T::CONST[0] });
assert_eq!(T::as_from(1i32), const { T::CONST[1] });
assert_eq!(T::as_from(42i32), const { T::CONST[42] });
}
check::<f32>();
check::<f64>();
check::<i8>();
check::<i16>();
check::<i32>();
check::<i64>();
check::<i128>();
check::<isize>();
check::<u8>();
check::<u16>();
check::<u32>();
check::<u64>();
check::<u128>();
check::<usize>();
}
#[test]
fn constant_float_zero() {
assert!(<f32 as PrimitiveNumber>::CONST[0].is_sign_positive());
assert!(<f64 as PrimitiveNumber>::CONST[0].is_sign_positive());
}