288 lines
8.3 KiB
Rust
288 lines
8.3 KiB
Rust
#![cfg(feature = "macros")]
|
|
|
|
use pyo3::prelude::*;
|
|
|
|
#[path = "../src/tests/common.rs"]
|
|
mod common;
|
|
|
|
#[pyclass(eq)]
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub enum MyEnum {
|
|
Variant,
|
|
OtherVariant,
|
|
}
|
|
|
|
#[pyclass(eq, ord)]
|
|
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd)]
|
|
pub enum MyEnumOrd {
|
|
Variant,
|
|
OtherVariant,
|
|
}
|
|
|
|
#[test]
|
|
fn test_enum_eq_enum() {
|
|
Python::with_gil(|py| {
|
|
let var1 = Py::new(py, MyEnum::Variant).unwrap();
|
|
let var2 = Py::new(py, MyEnum::Variant).unwrap();
|
|
let other_var = Py::new(py, MyEnum::OtherVariant).unwrap();
|
|
py_assert!(py, var1 var2, "var1 == var2");
|
|
py_assert!(py, var1 other_var, "var1 != other_var");
|
|
py_assert!(py, var1 var2, "(var1 != var2) == False");
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_enum_eq_incomparable() {
|
|
Python::with_gil(|py| {
|
|
let var1 = Py::new(py, MyEnum::Variant).unwrap();
|
|
py_assert!(py, var1, "(var1 == 'foo') == False");
|
|
py_assert!(py, var1, "(var1 != 'foo') == True");
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_enum_ord_comparable_opt_in_only() {
|
|
Python::with_gil(|py| {
|
|
let var1 = Py::new(py, MyEnum::Variant).unwrap();
|
|
let var2 = Py::new(py, MyEnum::OtherVariant).unwrap();
|
|
// ordering on simple enums if opt in only, thus raising an error below
|
|
py_expect_exception!(py, var1 var2, "(var1 > var2) == False", PyTypeError);
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_simple_enum_ord_comparable() {
|
|
Python::with_gil(|py| {
|
|
let var1 = Py::new(py, MyEnumOrd::Variant).unwrap();
|
|
let var2 = Py::new(py, MyEnumOrd::OtherVariant).unwrap();
|
|
let var3 = Py::new(py, MyEnumOrd::OtherVariant).unwrap();
|
|
py_assert!(py, var1 var2, "(var1 > var2) == False");
|
|
py_assert!(py, var1 var2, "(var1 < var2) == True");
|
|
py_assert!(py, var1 var2, "(var1 >= var2) == False");
|
|
py_assert!(py, var2 var3, "(var3 >= var2) == True");
|
|
py_assert!(py, var1 var2, "(var1 <= var2) == True");
|
|
})
|
|
}
|
|
|
|
#[pyclass(eq, ord)]
|
|
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd)]
|
|
pub enum MyComplexEnumOrd {
|
|
Variant(i32),
|
|
OtherVariant(String),
|
|
}
|
|
|
|
#[pyclass(eq, ord)]
|
|
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd)]
|
|
pub enum MyComplexEnumOrd2 {
|
|
Variant { msg: String, idx: u32 },
|
|
OtherVariant { name: String, idx: u32 },
|
|
}
|
|
|
|
#[test]
|
|
fn test_complex_enum_ord_comparable() {
|
|
Python::with_gil(|py| {
|
|
let var1 = Py::new(py, MyComplexEnumOrd::Variant(-2)).unwrap();
|
|
let var2 = Py::new(py, MyComplexEnumOrd::Variant(5)).unwrap();
|
|
let var3 = Py::new(py, MyComplexEnumOrd::OtherVariant("a".to_string())).unwrap();
|
|
let var4 = Py::new(py, MyComplexEnumOrd::OtherVariant("b".to_string())).unwrap();
|
|
py_assert!(py, var1 var2, "(var1 > var2) == False");
|
|
py_assert!(py, var1 var2, "(var1 < var2) == True");
|
|
py_assert!(py, var1 var2, "(var1 >= var2) == False");
|
|
py_assert!(py, var1 var2, "(var1 <= var2) == True");
|
|
|
|
py_assert!(py, var1 var3, "(var1 >= var3) == False");
|
|
py_assert!(py, var1 var3, "(var1 <= var3) == True");
|
|
|
|
py_assert!(py, var3 var4, "(var3 >= var4) == False");
|
|
py_assert!(py, var3 var4, "(var3 <= var4) == True");
|
|
|
|
let var5 = Py::new(
|
|
py,
|
|
MyComplexEnumOrd2::Variant {
|
|
msg: "hello".to_string(),
|
|
idx: 1,
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var6 = Py::new(
|
|
py,
|
|
MyComplexEnumOrd2::Variant {
|
|
msg: "hello".to_string(),
|
|
idx: 1,
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var7 = Py::new(
|
|
py,
|
|
MyComplexEnumOrd2::Variant {
|
|
msg: "goodbye".to_string(),
|
|
idx: 7,
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var8 = Py::new(
|
|
py,
|
|
MyComplexEnumOrd2::Variant {
|
|
msg: "about".to_string(),
|
|
idx: 0,
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var9 = Py::new(
|
|
py,
|
|
MyComplexEnumOrd2::OtherVariant {
|
|
name: "albert".to_string(),
|
|
idx: 1,
|
|
},
|
|
)
|
|
.unwrap();
|
|
|
|
py_assert!(py, var5 var6, "(var5 == var6) == True");
|
|
py_assert!(py, var5 var6, "(var5 <= var6) == True");
|
|
py_assert!(py, var6 var7, "(var6 <= var7) == False");
|
|
py_assert!(py, var6 var7, "(var6 >= var7) == True");
|
|
py_assert!(py, var5 var8, "(var5 > var8) == True");
|
|
py_assert!(py, var8 var9, "(var9 > var8) == True");
|
|
})
|
|
}
|
|
|
|
#[pyclass(eq, ord)]
|
|
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd)]
|
|
pub struct Point {
|
|
x: i32,
|
|
y: i32,
|
|
z: i32,
|
|
}
|
|
|
|
#[test]
|
|
fn test_struct_numeric_ord_comparable() {
|
|
Python::with_gil(|py| {
|
|
let var1 = Py::new(py, Point { x: 10, y: 2, z: 3 }).unwrap();
|
|
let var2 = Py::new(py, Point { x: 2, y: 2, z: 3 }).unwrap();
|
|
let var3 = Py::new(py, Point { x: 1, y: 22, z: 4 }).unwrap();
|
|
let var4 = Py::new(py, Point { x: 1, y: 3, z: 4 }).unwrap();
|
|
let var5 = Py::new(py, Point { x: 1, y: 3, z: 4 }).unwrap();
|
|
py_assert!(py, var1 var2, "(var1 > var2) == True");
|
|
py_assert!(py, var1 var2, "(var1 <= var2) == False");
|
|
py_assert!(py, var2 var3, "(var3 < var2) == True");
|
|
py_assert!(py, var3 var4, "(var3 > var4) == True");
|
|
py_assert!(py, var4 var5, "(var4 == var5) == True");
|
|
py_assert!(py, var3 var5, "(var3 != var5) == True");
|
|
})
|
|
}
|
|
|
|
#[pyclass(eq, ord)]
|
|
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd)]
|
|
pub struct Person {
|
|
surname: String,
|
|
given_name: String,
|
|
}
|
|
|
|
#[test]
|
|
fn test_struct_string_ord_comparable() {
|
|
Python::with_gil(|py| {
|
|
let var1 = Py::new(
|
|
py,
|
|
Person {
|
|
surname: "zzz".to_string(),
|
|
given_name: "bob".to_string(),
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var2 = Py::new(
|
|
py,
|
|
Person {
|
|
surname: "aaa".to_string(),
|
|
given_name: "sally".to_string(),
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var3 = Py::new(
|
|
py,
|
|
Person {
|
|
surname: "eee".to_string(),
|
|
given_name: "qqq".to_string(),
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var4 = Py::new(
|
|
py,
|
|
Person {
|
|
surname: "ddd".to_string(),
|
|
given_name: "aaa".to_string(),
|
|
},
|
|
)
|
|
.unwrap();
|
|
|
|
py_assert!(py, var1 var2, "(var1 > var2) == True");
|
|
py_assert!(py, var1 var2, "(var1 <= var2) == False");
|
|
py_assert!(py, var1 var3, "(var1 >= var3) == True");
|
|
py_assert!(py, var2 var3, "(var2 >= var3) == False");
|
|
py_assert!(py, var3 var4, "(var3 >= var4) == True");
|
|
py_assert!(py, var3 var4, "(var3 != var4) == True");
|
|
})
|
|
}
|
|
|
|
#[pyclass(eq, ord)]
|
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
|
pub struct Record {
|
|
name: String,
|
|
title: String,
|
|
idx: u32,
|
|
}
|
|
|
|
impl PartialOrd for Record {
|
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
Some(self.idx.partial_cmp(&other.idx).unwrap())
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_struct_custom_ord_comparable() {
|
|
Python::with_gil(|py| {
|
|
let var1 = Py::new(
|
|
py,
|
|
Record {
|
|
name: "zzz".to_string(),
|
|
title: "bbb".to_string(),
|
|
idx: 9,
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var2 = Py::new(
|
|
py,
|
|
Record {
|
|
name: "ddd".to_string(),
|
|
title: "aaa".to_string(),
|
|
idx: 1,
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var3 = Py::new(
|
|
py,
|
|
Record {
|
|
name: "vvv".to_string(),
|
|
title: "ggg".to_string(),
|
|
idx: 19,
|
|
},
|
|
)
|
|
.unwrap();
|
|
let var4 = Py::new(
|
|
py,
|
|
Record {
|
|
name: "vvv".to_string(),
|
|
title: "ggg".to_string(),
|
|
idx: 19,
|
|
},
|
|
)
|
|
.unwrap();
|
|
|
|
py_assert!(py, var1 var2, "(var1 > var2) == True");
|
|
py_assert!(py, var1 var2, "(var1 <= var2) == False");
|
|
py_assert!(py, var1 var3, "(var1 >= var3) == False");
|
|
py_assert!(py, var2 var3, "(var2 >= var3) == False");
|
|
py_assert!(py, var3 var4, "(var3 == var4) == True");
|
|
py_assert!(py, var2 var4, "(var2 != var4) == True");
|
|
})
|
|
}
|