Skip to content

Commit 6bdbdc8

Browse files
committed
gh-50 Add tests to improve code coverage for spatial predicates
Add tests for: - FixedScaleFloatRelate: disjoint_with_fixed_scale, covers_with_fixed_scale - FloatOverlay: with_subj_and_clip_fixed_scale_custom - FloatPredicateOverlay: with_adapter, with_adapter_custom, with_subj_and_clip_custom, clear - Error handling for invalid scale values across all fixed-scale methods
1 parent b145cbb commit 6bdbdc8

2 files changed

Lines changed: 238 additions & 0 deletions

File tree

iOverlay/src/float/relate.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,4 +520,102 @@ mod tests {
520520
assert!(!left.within(&right));
521521
assert!(!left.covers(&right));
522522
}
523+
524+
#[test]
525+
fn test_predicate_overlay_with_adapter() {
526+
use crate::core::overlay::ShapeType;
527+
use i_float::adapter::FloatPointAdapter;
528+
529+
let square = vec![[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [10.0, 0.0]];
530+
let other = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
531+
532+
let iter = square.iter().chain(other.iter());
533+
let adapter = FloatPointAdapter::with_iter(iter);
534+
535+
let mut overlay = FloatPredicateOverlay::with_adapter(adapter, 16);
536+
overlay.add_source(&square, ShapeType::Subject);
537+
overlay.add_source(&other, ShapeType::Clip);
538+
assert!(overlay.intersects());
539+
}
540+
541+
#[test]
542+
fn test_predicate_overlay_with_adapter_custom() {
543+
use crate::core::fill_rule::FillRule;
544+
use crate::core::overlay::ShapeType;
545+
use crate::core::solver::Solver;
546+
use i_float::adapter::FloatPointAdapter;
547+
548+
let square = vec![[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [10.0, 0.0]];
549+
let other = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
550+
551+
let iter = square.iter().chain(other.iter());
552+
let adapter = FloatPointAdapter::with_iter(iter);
553+
554+
let mut overlay =
555+
FloatPredicateOverlay::with_adapter_custom(adapter, FillRule::NonZero, Solver::default(), 16);
556+
overlay.add_source(&square, ShapeType::Subject);
557+
overlay.add_source(&other, ShapeType::Clip);
558+
assert!(overlay.intersects());
559+
}
560+
561+
#[test]
562+
fn test_predicate_overlay_with_subj_and_clip_custom() {
563+
use crate::core::fill_rule::FillRule;
564+
use crate::core::solver::Solver;
565+
566+
let square = vec![[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [10.0, 0.0]];
567+
let other = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
568+
569+
let mut overlay = FloatPredicateOverlay::with_subj_and_clip_custom(
570+
&square,
571+
&other,
572+
FillRule::NonZero,
573+
Solver::default(),
574+
);
575+
assert!(overlay.intersects());
576+
}
577+
578+
#[test]
579+
fn test_predicate_overlay_clear() {
580+
use crate::core::overlay::ShapeType;
581+
582+
let square = vec![[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [10.0, 0.0]];
583+
let other = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
584+
585+
let mut overlay = FloatPredicateOverlay::with_subj_and_clip(&square, &other);
586+
assert!(overlay.intersects());
587+
588+
overlay.clear();
589+
590+
// Use coordinates within the original adapter bounds
591+
let touching = vec![[10.0, 0.0], [10.0, 10.0], [15.0, 10.0], [15.0, 0.0]];
592+
overlay.add_source(&square, ShapeType::Subject);
593+
overlay.add_source(&touching, ShapeType::Clip);
594+
// After clear and re-add, shapes touch but don't overlap interiors
595+
assert!(overlay.intersects());
596+
}
597+
598+
#[test]
599+
fn test_predicate_overlay_all_predicates() {
600+
let outer = vec![[0.0, 0.0], [0.0, 20.0], [20.0, 20.0], [20.0, 0.0]];
601+
let inner = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
602+
603+
let mut overlay = FloatPredicateOverlay::with_subj_and_clip(&inner, &outer);
604+
assert!(overlay.intersects());
605+
606+
overlay.clear();
607+
overlay.add_source(&inner, crate::core::overlay::ShapeType::Subject);
608+
overlay.add_source(&outer, crate::core::overlay::ShapeType::Clip);
609+
assert!(overlay.interiors_intersect());
610+
611+
overlay.clear();
612+
overlay.add_source(&inner, crate::core::overlay::ShapeType::Subject);
613+
overlay.add_source(&outer, crate::core::overlay::ShapeType::Clip);
614+
assert!(!overlay.touches());
615+
616+
overlay.clear();
617+
overlay.add_source(&inner, crate::core::overlay::ShapeType::Subject);
618+
overlay.add_source(&outer, crate::core::overlay::ShapeType::Clip);
619+
assert!(overlay.within());
620+
}
523621
}

iOverlay/src/float/scale.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,4 +505,144 @@ mod tests {
505505
FloatPredicateOverlay::with_subj_and_clip_fixed_scale(&square, &other, f64::INFINITY).is_err()
506506
);
507507
}
508+
509+
#[test]
510+
fn test_disjoint_with_fixed_scale() {
511+
let square = vec![[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [10.0, 0.0]];
512+
let other = vec![[20.0, 20.0], [20.0, 30.0], [30.0, 30.0], [30.0, 20.0]];
513+
514+
let result = square.disjoint_with_fixed_scale(&other, 1000.0);
515+
assert!(result.unwrap());
516+
517+
let overlapping = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
518+
let result = square.disjoint_with_fixed_scale(&overlapping, 1000.0);
519+
assert!(!result.unwrap());
520+
}
521+
522+
#[test]
523+
fn test_covers_with_fixed_scale() {
524+
let outer = vec![[0.0, 0.0], [0.0, 20.0], [20.0, 20.0], [20.0, 0.0]];
525+
let inner = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
526+
527+
let result = outer.covers_with_fixed_scale(&inner, 1000.0);
528+
assert!(result.unwrap());
529+
530+
let result = inner.covers_with_fixed_scale(&outer, 1000.0);
531+
assert!(!result.unwrap());
532+
}
533+
534+
#[test]
535+
fn test_fixed_scale_custom_overlay() {
536+
use crate::core::solver::Solver;
537+
538+
let left_rect = vec![[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]];
539+
let right_rect = vec![[1.0, 0.0], [1.0, 1.0], [2.0, 1.0], [2.0, 0.0]];
540+
541+
let shapes = FloatOverlay::with_subj_and_clip_fixed_scale_custom(
542+
&left_rect,
543+
&right_rect,
544+
Default::default(),
545+
Solver::default(),
546+
10.0,
547+
)
548+
.unwrap()
549+
.overlay(OverlayRule::Union, FillRule::EvenOdd);
550+
551+
assert_eq!(shapes.len(), 1);
552+
assert_eq!(shapes[0].len(), 1);
553+
assert_eq!(shapes[0][0].len(), 4);
554+
}
555+
556+
#[test]
557+
fn test_fixed_scale_custom_overlay_invalid() {
558+
use crate::core::solver::Solver;
559+
560+
let left_rect = vec![[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]];
561+
let right_rect = vec![[1.0, 0.0], [1.0, 1.0], [2.0, 1.0], [2.0, 0.0]];
562+
563+
let result = FloatOverlay::with_subj_and_clip_fixed_scale_custom(
564+
&left_rect,
565+
&right_rect,
566+
Default::default(),
567+
Solver::default(),
568+
-1.0,
569+
);
570+
assert!(result.is_err());
571+
}
572+
573+
#[test]
574+
fn test_fixed_scale_custom_overlay_scale_too_large() {
575+
use crate::core::solver::Solver;
576+
577+
let left_rect = vec![[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]];
578+
let right_rect = vec![[1.0, 0.0], [1.0, 1.0], [2.0, 1.0], [2.0, 0.0]];
579+
580+
let scale = (1u64 << 32) as f64;
581+
let result = FloatOverlay::with_subj_and_clip_fixed_scale_custom(
582+
&left_rect,
583+
&right_rect,
584+
Default::default(),
585+
Solver::default(),
586+
scale,
587+
);
588+
assert!(result.is_err());
589+
}
590+
591+
#[test]
592+
fn test_predicate_overlay_with_fixed_scale_custom() {
593+
use crate::core::solver::Solver;
594+
595+
let square = vec![[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [10.0, 0.0]];
596+
let other = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
597+
598+
let mut overlay = FloatPredicateOverlay::with_subj_and_clip_fixed_scale_custom(
599+
&square,
600+
&other,
601+
FillRule::NonZero,
602+
Solver::default(),
603+
1000.0,
604+
)
605+
.unwrap();
606+
assert!(overlay.intersects());
607+
}
608+
609+
#[test]
610+
fn test_predicate_overlay_with_fixed_scale_custom_invalid() {
611+
use crate::core::solver::Solver;
612+
613+
let square = vec![[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [10.0, 0.0]];
614+
let other = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
615+
616+
let result = FloatPredicateOverlay::with_subj_and_clip_fixed_scale_custom(
617+
&square,
618+
&other,
619+
FillRule::NonZero,
620+
Solver::default(),
621+
-1.0,
622+
);
623+
assert!(result.is_err());
624+
625+
let scale = (1u64 << 32) as f64;
626+
let result = FloatPredicateOverlay::with_subj_and_clip_fixed_scale_custom(
627+
&square,
628+
&other,
629+
FillRule::NonZero,
630+
Solver::default(),
631+
scale,
632+
);
633+
assert!(result.is_err());
634+
}
635+
636+
#[test]
637+
fn test_fixed_scale_relate_invalid_scale() {
638+
let square = vec![[0.0, 0.0], [0.0, 10.0], [10.0, 10.0], [10.0, 0.0]];
639+
let other = vec![[5.0, 5.0], [5.0, 15.0], [15.0, 15.0], [15.0, 5.0]];
640+
641+
assert!(square.intersects_with_fixed_scale(&other, -1.0).is_err());
642+
assert!(square.interiors_intersect_with_fixed_scale(&other, -1.0).is_err());
643+
assert!(square.touches_with_fixed_scale(&other, -1.0).is_err());
644+
assert!(square.within_with_fixed_scale(&other, -1.0).is_err());
645+
assert!(square.disjoint_with_fixed_scale(&other, -1.0).is_err());
646+
assert!(square.covers_with_fixed_scale(&other, -1.0).is_err());
647+
}
508648
}

0 commit comments

Comments
 (0)