wrote most tests except for touches()

This commit is contained in:
ripytide
2022-12-06 20:30:52 +00:00
parent 3ed89cc250
commit f3221ec9c8
6 changed files with 508 additions and 35 deletions
Generated
+75
View File
@@ -8,6 +8,22 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "ctor"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "either"
version = "1.8.0"
@@ -23,6 +39,14 @@ dependencies = [
"either",
]
[[package]]
name = "labels"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "num-traits"
version = "0.2.15"
@@ -41,6 +65,27 @@ dependencies = [
"num-traits",
]
[[package]]
name = "output_vt100"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
dependencies = [
"winapi",
]
[[package]]
name = "pretty_assertions"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755"
dependencies = [
"ctor",
"diff",
"output_vt100",
"yansi",
]
[[package]]
name = "proc-macro2"
version = "1.0.47"
@@ -65,7 +110,9 @@ version = "0.0.1"
dependencies = [
"either",
"itertools",
"labels",
"ordered-float",
"pretty_assertions",
"serde",
]
@@ -105,3 +152,31 @@ name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "yansi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
+2
View File
@@ -27,6 +27,8 @@ categories = ["data-structures"]
either = "1.8.0"
serde = {version = "1.0.148", features = ["derive"]}
itertools = "0.10.5"
labels = {path = "../robot_sweet_shop/labels"}
pretty_assertions = "1.3.0"
[dev-dependencies]
ordered-float = "3.4.0"
+7
View File
@@ -20,6 +20,7 @@ along with range_bounds_map. If not, see <https://www.gnu.org/licenses/>.
use std::cmp::Ordering;
use std::ops::Bound;
use labels::{parent_tested, tested, trivial};
use serde::{Deserialize, Serialize};
/// An Ord newtype of [`Bound`] specific to [`start_bound()`].
@@ -60,6 +61,7 @@ impl<T> StartBound<T> {
/// an [`end_bound()`] in a range search
///
/// [`end_bound()`]: https://doc.rust-lang.org/std/ops/trait.RangeBounds.html#tymethod.end_bound
#[trivial]
pub(crate) fn into_end_bound(self) -> StartBound<T> {
match self {
//flipping is unnecessary
@@ -83,6 +85,7 @@ impl<T> PartialOrd for StartBound<T>
where
T: PartialOrd,
{
#[tested]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self, other) {
(StartBound::Included(start1), StartBound::Included(start2)) => start1.partial_cmp(start2),
@@ -120,6 +123,7 @@ where
//if they are equal say the item with priority is larger
//where false means left has priority and true means right
#[parent_tested]
fn partial_cmp_with_priority<T>(
left: &T,
right: &T,
@@ -143,12 +147,14 @@ impl<T> Ord for StartBound<T>
where
T: PartialOrd,
{
#[trivial]
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
impl<T> From<Bound<T>> for StartBound<T> {
#[trivial]
fn from(bound: Bound<T>) -> Self {
match bound {
Bound::Included(point) => StartBound::Included(point),
@@ -158,6 +164,7 @@ impl<T> From<Bound<T>> for StartBound<T> {
}
}
impl<T> From<StartBound<T>> for Bound<T> {
#[trivial]
fn from(start_bound: StartBound<T>) -> Bound<T> {
match start_bound {
StartBound::Included(point) => Bound::Included(point),
+407 -33
View File
@@ -25,6 +25,7 @@ use std::ops::{Bound, RangeBounds};
use either::Either;
use itertools::Itertools;
use labels::{tested, trivial, untested};
use serde::{Deserialize, Serialize};
use crate::bounds::StartBound;
@@ -274,6 +275,7 @@ where
/// let range_bounds_map: RangeBoundsMap<u8, Range<u8>, bool> =
/// RangeBoundsMap::new();
/// ```
#[trivial]
pub fn new() -> Self {
RangeBoundsMap {
starts: BTreeMap::new(),
@@ -292,6 +294,7 @@ where
/// range_bounds_map.insert_platonic(0..1, false).unwrap();
/// assert_eq!(range_bounds_map.len(), 1);
/// ```
#[trivial]
pub fn len(&self) -> usize {
self.starts.len()
}
@@ -316,6 +319,7 @@ where
/// );
/// assert_eq!(range_bounds_map.len(), 1);
/// ```
#[tested]
pub fn insert_platonic(
&mut self,
range_bounds: K,
@@ -358,6 +362,7 @@ where
/// assert_eq!(range_bounds_map.overlaps(&(4..=5)), true);
/// assert_eq!(range_bounds_map.overlaps(&(4..6)), true);
/// ```
#[trivial]
pub fn overlaps<Q>(&self, search_range_bounds: &Q) -> bool
where
Q: RangeBounds<I>,
@@ -387,6 +392,7 @@ where
/// [(&(1..4), &false), (&(4..8), &true)]
/// );
/// ```
#[tested]
pub fn overlapping<Q>(
&self,
range_bounds: &Q,
@@ -459,6 +465,7 @@ where
/// assert_eq!(range_bounds_map.get_at_point(&4), Some(&true));
/// assert_eq!(range_bounds_map.get_at_point(&101), None);
/// ```
#[trivial]
pub fn get_at_point(&self, point: &I) -> Option<&V> {
self.get_entry_at_point(point).map(|(_, value)| value)
}
@@ -481,6 +488,7 @@ where
/// assert_eq!(range_bounds_map.contains_point(&4), true);
/// assert_eq!(range_bounds_map.contains_point(&101), false);
/// ```
#[trivial]
pub fn contains_point(&self, point: &I) -> bool {
self.get_at_point(point).is_some()
}
@@ -501,6 +509,7 @@ where
///
/// assert_eq!(range_bounds_map.get_at_point(&1), Some(&true));
/// ```
#[tested]
pub fn get_at_point_mut(&mut self, point: &I) -> Option<&mut V> {
if let Some(overlapping_start_bound) = self
.get_entry_at_point(point)
@@ -538,6 +547,7 @@ where
/// );
/// assert_eq!(range_bounds_map.get_entry_at_point(&101), None);
/// ```
#[trivial]
pub fn get_entry_at_point(&self, point: &I) -> Option<(&K, &V)> {
//a zero-range included-included range is equivalent to a point
return self
@@ -569,6 +579,7 @@ where
/// assert_eq!(iter.next(), Some((&(8..100), &false)));
/// assert_eq!(iter.next(), None);
/// ```
#[trivial]
pub fn iter(&self) -> impl DoubleEndedIterator<Item = (&K, &V)> {
self.starts.iter().map(|(_, (key, value))| (key, value))
}
@@ -600,6 +611,7 @@ where
/// [(&(8..100), &false)]
/// );
/// ```
#[tested]
pub fn remove_overlapping<Q>(
&mut self,
range_bounds: &Q,
@@ -654,6 +666,7 @@ where
/// assert_eq!(base, after_cut);
/// assert_eq!(base.cut(&(60..=80)), Err(TryFromBoundsError));
/// ```
#[tested]
pub fn cut<Q>(&mut self, range_bounds: &Q) -> Result<(), TryFromBoundsError>
where
Q: RangeBounds<I>,
@@ -753,6 +766,7 @@ where
/// ]
/// );
/// ```
#[tested]
pub fn gaps<'a, Q>(
&'a self,
outer_range_bounds: &'a Q,
@@ -780,8 +794,6 @@ where
.chain(inners)
.chain(once(artificial_end));
eprintln!("\nnew:");
return artificials
.tuple_windows()
.map(|((_, first_end), (second_start, _))| {
@@ -814,6 +826,7 @@ where
/// true
/// );
/// ```
#[trivial]
pub fn contains_range_bounds<Q>(&self, range_bounds: &Q) -> bool
where
Q: RangeBounds<I>,
@@ -872,6 +885,7 @@ where
/// [(&(1..6), &true), (&(10..16), &false),]
/// );
/// ```
#[tested]
pub fn insert_coalesce_touching(
&mut self,
range_bounds: K,
@@ -977,6 +991,7 @@ where
/// [(&(-4..1), &true), (&(1..8), &true), (&(10..16), &false)]
/// );
/// ```
#[tested]
pub fn insert_coalesce_overlapping(
&mut self,
range_bounds: K,
@@ -1063,6 +1078,7 @@ where
/// [(&(-4..8), &true), (&(10..16), &false)]
/// );
/// ```
#[tested]
pub fn insert_coalesce_touching_or_overlapping(
&mut self,
range_bounds: K,
@@ -1121,6 +1137,7 @@ where
/// [(&(2..4), &false), (&(4..6), &true), (&(6..8), &false)]
/// );
/// ```
#[trivial]
pub fn overwrite(
&mut self,
range_bounds: K,
@@ -1143,6 +1160,7 @@ where
I: Ord + Clone,
{
type Error = OverlapError;
#[trivial]
fn try_from(pairs: [(K, V); N]) -> Result<Self, Self::Error> {
let mut range_bounds_map = RangeBoundsMap::new();
for (range_bounds, value) in pairs {
@@ -1152,11 +1170,28 @@ where
return Ok(range_bounds_map);
}
}
impl<I, K, V> TryFrom<Vec<(K, V)>> for RangeBoundsMap<I, K, V>
where
K: RangeBounds<I>,
I: Ord + Clone,
{
type Error = OverlapError;
#[trivial]
fn try_from(pairs: Vec<(K, V)>) -> Result<Self, Self::Error> {
let mut range_bounds_map = RangeBoundsMap::new();
for (range_bounds, value) in pairs {
range_bounds_map.insert_platonic(range_bounds, value)?;
}
return Ok(range_bounds_map);
}
}
impl<I, K, V> Default for RangeBoundsMap<I, K, V>
where
I: PartialOrd,
{
#[trivial]
fn default() -> Self {
RangeBoundsMap {
starts: BTreeMap::default(),
@@ -1171,6 +1206,7 @@ enum CutResult<I> {
Double((Bound<I>, Bound<I>), (Bound<I>, Bound<I>)),
}
#[tested]
fn cut_range_bounds<I, B, C>(
base_range_bounds: &B,
cut_range_bounds: &C,
@@ -1222,6 +1258,7 @@ where
}
}
#[trivial]
fn is_valid_range_bounds<Q, I>(range_bounds: &Q) -> bool
where
Q: RangeBounds<I>,
@@ -1236,6 +1273,7 @@ where
}
}
#[tested]
fn overlaps<I, A, B>(a: &A, b: &B) -> bool
where
A: RangeBounds<I>,
@@ -1269,6 +1307,7 @@ where
}
}
#[untested]
fn touches<I, A, B>(a: &A, b: &B) -> bool
where
A: RangeBounds<I>,
@@ -1296,6 +1335,7 @@ where
}
}
#[trivial]
fn flip_bound<I>(bound: Bound<&I>) -> Bound<&I> {
match bound {
Bound::Included(point) => Bound::Excluded(point),
@@ -1308,6 +1348,8 @@ fn flip_bound<I>(bound: Bound<&I>) -> Bound<&I> {
mod tests {
use std::ops::{Bound, Range, RangeBounds};
use pretty_assertions::assert_eq;
use super::*;
use crate::bounds::StartBound;
@@ -1320,28 +1362,44 @@ mod tests {
pub(crate) const NUMBERS_DOMAIN: &'static [u8] =
&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
#[rustfmt::skip]
#[test]
fn mass_overlaps_test() {
for range_bounds1 in all_valid_test_bounds() {
for range_bounds2 in all_valid_test_bounds() {
let our_answer = overlaps(&range_bounds1, &range_bounds2);
let mathematical_definition_of_overlap =
NUMBERS_DOMAIN.iter().any(|x| {
range_bounds1.contains(x) && range_bounds2.contains(x)
});
if our_answer != mathematical_definition_of_overlap {
dbg!(range_bounds1, range_bounds2);
dbg!(mathematical_definition_of_overlap, our_answer);
panic!("Discrepency in .overlaps() detected!");
}
fn insert_platonic_tests() {
assert_insert_platonic::<0>(basic(), (ii(0, 4), false), Err(OverlapError), None);
assert_insert_platonic::<0>(basic(), (ii(5, 6), false), Err(OverlapError), None);
assert_insert_platonic(basic(), (ee(6, 7), false), Ok(()), Some([
(ui(4), false),
(ee(5, 6), true),
(ii(6, 6), false),
(ee(6, 7), false),
]));
assert_insert_platonic::<0>(basic(), (ii(4, 5), true), Err(OverlapError), None);
assert_insert_platonic(basic(), (ei(4, 5), true), Ok(()), Some([
(ui(4), false),
(ei(4, 5), true),
(ee(5, 6), true),
(ii(6, 6), false),
(ee(6, 7), false),
]));
}
fn assert_insert_platonic<const N: usize>(
mut before: RangeBoundsMap<u8, TestBounds, bool>,
to_insert: (TestBounds, bool),
result: Result<(), OverlapError>,
after: Option<[(TestBounds, bool); N]>,
) {
let clone = before.clone();
assert_eq!(before.insert_platonic(to_insert.0, to_insert.1), result);
match after {
Some(after) => {
assert_eq!(before, RangeBoundsMap::try_from(after).unwrap())
}
None => assert_eq!(before, clone),
}
}
#[test]
fn mass_overlapping_test() {
fn overlapping_tests() {
//case zero
for overlap_range in all_valid_test_bounds() {
//you can't overlap nothing
@@ -1423,23 +1481,291 @@ mod tests {
}
}
impl<I> CutResult<I> {
fn contains(&self, point: &I) -> bool
where
I: PartialOrd,
{
match self {
CutResult::Nothing => false,
CutResult::Single(range_bounds) => range_bounds.contains(point),
CutResult::Double(first_range_bounds, second_range_bounds) => {
first_range_bounds.contains(point)
|| second_range_bounds.contains(point)
#[rustfmt::skip]
#[test]
fn remove_overlapping_tests() {
assert_remove_overlapping::<0, 0>(basic(), ii(5, 5), [], None);
assert_remove_overlapping(basic(), uu(), [
(ui(4), false),
(ee(5, 7), true),
(ii(7, 7), false),
(ie(14, 16), true),
], Some([]));
assert_remove_overlapping(basic(), ii(6, 7), [
(ee(5, 7), true),
(ii(7, 7), false),
], Some([
(ui(4), false), (ie(14, 16), true)
]));
assert_remove_overlapping(basic(), iu(6), [
(ee(5, 7), true),
(ii(7, 7), false),
(ie(14, 16), true),
], Some([
(ui(4), false),
]));
}
fn assert_remove_overlapping<const N: usize, const Y: usize>(
mut before: RangeBoundsMap<u8, TestBounds, bool>,
to_remove: TestBounds,
result: [(TestBounds, bool); N],
after: Option<[(TestBounds, bool); Y]>,
) {
let clone = before.clone();
assert_eq!(before.remove_overlapping(&to_remove).collect_vec(), result);
match after {
Some(after) => {
assert_eq!(before, RangeBoundsMap::try_from(after).unwrap())
}
None => assert_eq!(before, clone),
}
}
#[rustfmt::skip]
#[test]
fn cut_tests() {
assert_cut::<0>(basic(), ii(50, 60), Ok(()), None);
assert_cut(basic(), uu(), Ok(()), Some([]));
assert_cut(basic(), ui(6), Ok(()), Some([
(ee(6, 7), true),
(ii(7, 7), false),
(ie(14, 16), true),
]));
assert_cut(basic(), iu(6), Ok(()), Some([
(ui(4), false),
(ee(5, 6), true),
]));
}
fn assert_cut<const N: usize>(
mut before: RangeBoundsMap<u8, TestBounds, bool>,
to_cut: TestBounds,
result: Result<(), TryFromBoundsError>,
after: Option<[(TestBounds, bool); N]>,
) {
let clone = before.clone();
assert_eq!(before.cut(&to_cut), result);
match after {
Some(after) => {
assert_eq!(before, RangeBoundsMap::try_from(after).unwrap())
}
None => assert_eq!(before, clone),
}
}
fn basic() -> RangeBoundsMap<u8, TestBounds, bool> {
RangeBoundsMap::try_from([
(ui(4), false),
(ee(5, 7), true),
(ii(7, 7), false),
(ie(14, 16), true),
])
.unwrap()
}
#[test]
fn gaps_tests() {
assert_gaps(basic(), ii(50, 60), [ii(50, 60)]);
assert_gaps(basic(), iu(50), [iu(50)]);
assert_gaps(basic(), ee(3, 16), [ei(4, 5), ee(7, 14)]);
assert_gaps(basic(), ei(3, 16), [ei(4, 5), ee(7, 14), ii(16, 16)]);
assert_gaps(basic(), ue(5), [ee(4, 5)]);
assert_gaps(basic(), ui(3), []);
assert_gaps(basic(), ii(5, 5), [ii(5, 5)]);
assert_gaps(basic(), ii(6, 6), []);
assert_gaps(basic(), ii(7, 7), []);
assert_gaps(basic(), ii(8, 8), [ii(8, 8)]);
}
fn assert_gaps<const N: usize>(
range_bounds_map: RangeBoundsMap<u8, TestBounds, bool>,
outer_range_bounds: TestBounds,
result: [TestBounds; N],
) {
assert_eq!(
range_bounds_map
.gaps(&outer_range_bounds)
.map(|(start, end)| (start.cloned(), end.cloned()))
.collect_vec(),
result
);
}
#[rustfmt::skip]
#[test]
fn insert_coalesce_touching_tests() {
assert_insert_coalesce_touching::<0>(basic(), (ii(0, 4), false), Err(OverlapOrTryFromBoundsError::Overlap(OverlapError)), None);
assert_insert_coalesce_touching::<4>(basic(), (ee(7, 10), false), Ok(&ee(7, 10)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 10), false),
(ie(14, 16), true),
]));
assert_insert_coalesce_touching::<4>(basic(), (ee(7, 11), true), Ok(&ie(7, 11)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 11), true),
(ie(14, 16), true),
]));
assert_insert_coalesce_touching::<5>(basic(), (ee(13, 14), true), Ok(&ee(13, 14)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 7), false),
(ee(13, 14), true),
(ie(14, 16), true),
]));
assert_insert_coalesce_touching::<4>(basic(), (ei(13, 14), false), Ok(&ee(13, 16)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 7), false),
(ee(13, 16), false),
]));
assert_insert_coalesce_touching::<3>(basic(), (ii(7, 13), false), Ok(&ie(7, 16)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 16), false),
]));
}
fn assert_insert_coalesce_touching<const N: usize>(
mut before: RangeBoundsMap<u8, TestBounds, bool>,
to_insert: (TestBounds, bool),
result: Result<&TestBounds, OverlapOrTryFromBoundsError>,
after: Option<[(TestBounds, bool); N]>,
) {
let clone = before.clone();
assert_eq!(
before.insert_coalesce_touching(to_insert.0, to_insert.1),
result
);
match after {
Some(after) => {
assert_eq!(before, RangeBoundsMap::try_from(after).unwrap())
}
None => assert_eq!(before, clone),
}
}
#[rustfmt::skip]
#[test]
fn insert_coalesce_overlapping_tests() {
assert_insert_coalesce_overlapping::<4>(basic(), (ii(0, 2), true), Ok(&(ui(4))), Some([
(ui(4), true),
(ee(5, 7), true),
(ii(7, 7), false),
(ie(14, 16), true),
]));
assert_insert_coalesce_overlapping::<4>(basic(), (ie(14, 16), false), Ok(&ie(14, 16)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 10), false),
(ie(14, 16), false),
]));
assert_insert_coalesce_overlapping::<3>(basic(), (ii(7, 11), false), Ok(&ei(5, 11)), Some([
(ui(4), false),
(ei(5, 11), false),
(ie(14, 16), true),
]));
assert_insert_coalesce_overlapping::<4>(basic(), (ii(15, 18), true), Ok(&ii(14, 18)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 7), false),
(ii(14, 18), true),
]));
assert_insert_coalesce_overlapping::<1>(basic(), (uu(), false), Ok(&uu()), Some([
(uu(), false),
]));
}
fn assert_insert_coalesce_overlapping<const N: usize>(
mut before: RangeBoundsMap<u8, TestBounds, bool>,
to_insert: (TestBounds, bool),
result: Result<&TestBounds, TryFromBoundsError>,
after: Option<[(TestBounds, bool); N]>,
) {
let clone = before.clone();
assert_eq!(
before.insert_coalesce_overlapping(to_insert.0, to_insert.1),
result
);
match after {
Some(after) => {
assert_eq!(before, RangeBoundsMap::try_from(after).unwrap())
}
None => assert_eq!(before, clone),
}
}
#[rustfmt::skip]
#[test]
fn insert_coalesce_touching_or_overlapping_tests() {
assert_insert_coalesce_touching_or_overlapping::<4>(basic(), (ii(0, 2), true), Ok(&(ui(4))), Some([
(ui(4), true),
(ee(5, 7), true),
(ii(7, 7), false),
(ie(14, 16), true),
]));
assert_insert_coalesce_touching_or_overlapping::<4>(basic(), (ie(14, 16), false), Ok(&ie(14, 16)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 10), false),
(ie(14, 16), false),
]));
assert_insert_coalesce_touching_or_overlapping::<4>(basic(), (ii(15, 18), true), Ok(&ii(14, 18)), Some([
(ui(4), false),
(ee(5, 7), true),
(ie(7, 7), false),
(ii(14, 18), true),
]));
assert_insert_coalesce_touching_or_overlapping::<1>(basic(), (uu(), false), Ok(&uu()), Some([
(uu(), false),
]));
//the only difference from the insert_coalesce_overlapping
assert_insert_coalesce_touching_or_overlapping::<2>(basic(), (ii(7, 11), false), Ok(&ee(5, 16)), Some([
(ui(4), false),
(ee(5, 16), false),
]));
}
fn assert_insert_coalesce_touching_or_overlapping<const N: usize>(
mut before: RangeBoundsMap<u8, TestBounds, bool>,
to_insert: (TestBounds, bool),
result: Result<&TestBounds, TryFromBoundsError>,
after: Option<[(TestBounds, bool); N]>,
) {
let clone = before.clone();
assert_eq!(
before.insert_coalesce_touching_or_overlapping(
to_insert.0,
to_insert.1
),
result
);
match after {
Some(after) => {
assert_eq!(before, RangeBoundsMap::try_from(after).unwrap())
}
None => assert_eq!(before, clone),
}
}
#[test]
fn overlaps_tests() {
for range_bounds1 in all_valid_test_bounds() {
for range_bounds2 in all_valid_test_bounds() {
let our_answer = overlaps(&range_bounds1, &range_bounds2);
let mathematical_definition_of_overlap =
NUMBERS_DOMAIN.iter().any(|x| {
range_bounds1.contains(x) && range_bounds2.contains(x)
});
if our_answer != mathematical_definition_of_overlap {
dbg!(range_bounds1, range_bounds2);
dbg!(mathematical_definition_of_overlap, our_answer);
panic!("Discrepency in .overlaps() detected!");
}
}
}
}
#[test]
fn mass_cut_range_bounds_tests() {
fn cut_range_bounds_tests() {
for base in all_valid_test_bounds() {
for cut in all_valid_test_bounds() {
let cut_result = cut_range_bounds(&base, &cut);
@@ -1470,7 +1796,24 @@ mod tests {
}
}
}
impl<I> CutResult<I> {
fn contains(&self, point: &I) -> bool
where
I: PartialOrd,
{
match self {
CutResult::Nothing => false,
CutResult::Single(range_bounds) => range_bounds.contains(point),
CutResult::Double(first_range_bounds, second_range_bounds) => {
first_range_bounds.contains(point)
|| second_range_bounds.contains(point)
}
}
}
}
// Test Helper Functions
//======================
fn all_non_overlapping_test_bound_pairs() -> Vec<(TestBounds, TestBounds)> {
let mut output = Vec::new();
for test_bounds1 in all_valid_test_bounds() {
@@ -1491,14 +1834,14 @@ mod tests {
output.append(&mut all_finite_bounded_pairs());
//bounded-unbounded
for start_bound in all_finite_bounded() {
output.push((start_bound, Bound::Unbounded));
output.push((start_bound, u()));
}
//unbounded-bounded
for end_bound in all_finite_bounded() {
output.push((Bound::Unbounded, end_bound));
output.push((u(), end_bound));
}
//unbounded-unbounded
output.push((Bound::Unbounded, Bound::Unbounded));
output.push(uu());
return output;
}
@@ -1538,4 +1881,35 @@ mod tests {
true => Bound::Excluded(x),
}
}
fn uu() -> TestBounds {
(Bound::Unbounded, Bound::Unbounded)
}
fn ui(x: u8) -> TestBounds {
(Bound::Unbounded, Bound::Included(x))
}
fn ue(x: u8) -> TestBounds {
(Bound::Unbounded, Bound::Excluded(x))
}
fn iu(x: u8) -> TestBounds {
(Bound::Included(x), Bound::Unbounded)
}
//fn eu(x: u8) -> TestBounds {
//(Bound::Excluded(x), Bound::Unbounded)
//}
fn ii(x1: u8, x2: u8) -> TestBounds {
(Bound::Included(x1), Bound::Included(x2))
}
fn ie(x1: u8, x2: u8) -> TestBounds {
(Bound::Included(x1), Bound::Excluded(x2))
}
fn ei(x1: u8, x2: u8) -> TestBounds {
(Bound::Excluded(x1), Bound::Included(x2))
}
fn ee(x1: u8, x2: u8) -> TestBounds {
(Bound::Excluded(x1), Bound::Excluded(x2))
}
fn u() -> Bound<u8> {
Bound::Unbounded
}
}
+10
View File
@@ -22,6 +22,8 @@ use std::ops::{
RangeToInclusive,
};
use labels::{not_a_fn, trivial};
/// A "newtype" trait to copy [`TryFrom`].
///
/// I am forced to use this "newtype" instead of [`TryFrom`] because
@@ -35,6 +37,7 @@ use std::ops::{
/// [`TryFrom`]: https://doc.rust-lang.org/std/convert/trait.TryFrom.html
/// [`Range`]: https://doc.rust-lang.org/std/ops/struct.Range.html
pub trait TryFromBounds<I> {
#[not_a_fn]
fn try_from_bounds(
start_bound: Bound<I>,
end_bound: Bound<I>,
@@ -44,6 +47,7 @@ pub trait TryFromBounds<I> {
}
impl<I> TryFromBounds<I> for (Bound<I>, Bound<I>) {
#[trivial]
fn try_from_bounds(
start_bound: Bound<I>,
end_bound: Bound<I>,
@@ -53,6 +57,7 @@ impl<I> TryFromBounds<I> for (Bound<I>, Bound<I>) {
}
impl<I> TryFromBounds<I> for Range<I> {
#[trivial]
fn try_from_bounds(
start_bound: Bound<I>,
end_bound: Bound<I>,
@@ -65,6 +70,7 @@ impl<I> TryFromBounds<I> for Range<I> {
}
impl<I> TryFromBounds<I> for RangeInclusive<I> {
#[trivial]
fn try_from_bounds(
start_bound: Bound<I>,
end_bound: Bound<I>,
@@ -77,6 +83,7 @@ impl<I> TryFromBounds<I> for RangeInclusive<I> {
}
impl<I> TryFromBounds<I> for RangeFrom<I> {
#[trivial]
fn try_from_bounds(
start_bound: Bound<I>,
end_bound: Bound<I>,
@@ -89,6 +96,7 @@ impl<I> TryFromBounds<I> for RangeFrom<I> {
}
impl<I> TryFromBounds<I> for RangeTo<I> {
#[trivial]
fn try_from_bounds(
start_bound: Bound<I>,
end_bound: Bound<I>,
@@ -101,6 +109,7 @@ impl<I> TryFromBounds<I> for RangeTo<I> {
}
impl<I> TryFromBounds<I> for RangeToInclusive<I> {
#[trivial]
fn try_from_bounds(
start_bound: Bound<I>,
end_bound: Bound<I>,
@@ -113,6 +122,7 @@ impl<I> TryFromBounds<I> for RangeToInclusive<I> {
}
impl<I> TryFromBounds<I> for RangeFull {
#[trivial]
fn try_from_bounds(
start_bound: Bound<I>,
end_bound: Bound<I>,
+7 -2
View File
@@ -1,6 +1,10 @@
# testing
- apply labels to crate and test #[untested]'s
- test for atomnicity, if it fails it shouldn't affect the map
- test #[untested]'s
- add tests for TryFromBounds fails for those that produce them with
atomnicity tests
# features
- RangeMap, RangeSet, RangeInclusiveMap...
# docs
- write something somewhere about wrapper types for RangeBoundsMap
@@ -13,6 +17,7 @@
- use it in robot_Sweet_graph for a bit before publishing
# final checks
- check toml meta-data, github meta-data and readme opener
- copy map to set again
- copy readme to lib.rs docs again
- take a look around idiomatic rust for a bit first