proptest atlas, find 🐛🐜🦋
authoralfadur
Tue, 26 Mar 2019 22:29:48 +0300
changeset 14722 c97faf0aef78
parent 14721 f9f71cccb5c3
child 14723 766ce87dfdfc
proptest atlas, find 🐛🐜🦋
rust/lib-hedgewars-engine/Cargo.toml
rust/lib-hedgewars-engine/src/render/atlas.rs
--- a/rust/lib-hedgewars-engine/Cargo.toml	Tue Mar 26 09:59:53 2019 -0400
+++ b/rust/lib-hedgewars-engine/Cargo.toml	Tue Mar 26 22:29:48 2019 +0300
@@ -18,6 +18,9 @@
 mapgen = { path = "../mapgen" }
 vec2d = { path = "../vec2d" }
 
+[dev-dependencies]
+proptest = "0.9.2"
+
 [lib]
 name = "hedgewars_engine"
 crate-type = ["dylib"]
--- a/rust/lib-hedgewars-engine/src/render/atlas.rs	Tue Mar 26 09:59:53 2019 -0400
+++ b/rust/lib-hedgewars-engine/src/render/atlas.rs	Tue Mar 26 22:29:48 2019 +0300
@@ -174,11 +174,7 @@
         if !self.texture_size.contains(size) {
             false
         } else {
-            if let Some(rect) = self
-                .atlases
-                .iter_mut()
-                .find_map(|a| a.insert(size))
-            {
+            if let Some(rect) = self.atlases.iter_mut().find_map(|a| a.insert(size)) {
 
             } else if !self.repack(size) {
                 let mut atlas = Atlas::new(self.texture_size);
@@ -217,6 +213,7 @@
 mod tests {
     use super::Atlas;
     use integral_geometry::{Rect, Size};
+    use proptest::prelude::*;
 
     #[test]
     fn insert() {
@@ -227,7 +224,61 @@
 
         let rect_size = Size::new(11, 3);
         let rect = atlas.insert(rect_size).unwrap();
+        
         assert_eq!(rect, Rect::at_origin(rect_size));
         assert_eq!(2, atlas.free_rects.len());
     }
+
+    #[derive(Debug, Clone)]
+    struct TestRect(Size);
+    struct TestRectParameters(Size);
+
+    impl Default for TestRectParameters {
+        fn default() -> Self {
+            Self(Size::square(64))
+        }
+    }
+
+    impl Arbitrary for TestRect {
+        type Parameters = TestRectParameters;
+
+        fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
+            (1..=args.0.width, 1..=args.0.height)
+                .prop_map(|(w, h)| TestRect(Size::new(w, h)))
+                .boxed()
+        }
+
+        type Strategy = BoxedStrategy<TestRect>;
+    }
+
+    trait HasSize {
+        fn size(&self) -> Size;
+    }
+
+    impl HasSize for TestRect {
+        fn size(&self) -> Size {
+            self.0
+        }
+    }
+
+    impl HasSize for Rect {
+        fn size(&self) -> Size {
+            self.size()
+        }
+    }
+
+    fn sum_area<S: HasSize>(items: &[S]) -> usize {
+        items.iter().map(|s| s.size().area()).sum()
+    }
+
+    proptest! {
+        #[test]
+        fn prop_insert(rects in Vec::<TestRect>::arbitrary()) {
+            let mut atlas = Atlas::new(Size::square(2048));
+            let inserted: Vec<_> = rects.iter().take_while(|TestRect(size)| atlas.insert(*size).is_some()).cloned().collect();
+
+            assert_eq!(inserted.len(), atlas.used_rects.len());
+            assert_eq!(sum_area(&inserted), sum_area(&atlas.used_rects));
+        }
+    }
 }