oxedyne/fe2o3/fe2o3_pearlite/tests/contents.rs
2.7 KiB, 1 run
created by r1870400018:60984, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | use oxedyne_fe2o3_pearlite::contents::Contents; |
| 2 | |
| 3 | use oxedyne_fe2o3_austenite::emit::pearl::{ |
| 4 | OutlineEntry, |
| 5 | PearlDoc, |
| 6 | }; |
| 7 | use oxedyne_fe2o3_austenite::ir::Sp; |
| 8 | |
| 9 | fn entry(level: u8, title: &str, page: Option<u32>, y_pt: f64) -> OutlineEntry { |
| 10 | OutlineEntry { |
| 11 | level, |
| 12 | number: String::new(), |
| 13 | title: title.to_string(), |
| 14 | page, |
| 15 | y: page.map(|_| Sp::from_pt(y_pt)), |
| 16 | } |
| 17 | } |
| 18 | |
| 19 | // 0 Intro(1) 1 Scope(2) 2 Detail(3) 3 Aside(2) 4 Method(1) 5 Lost(2, unplaced) 6 Deep(3, straight |
| 20 | // under a level 1). |
| 21 | fn sample() -> Contents { |
| 22 | Contents::new(vec![ |
| 23 | entry(1, "Intro", Some(1), 100.0), |
| 24 | entry(2, "Scope", Some(1), 300.0), |
| 25 | entry(3, "Detail", Some(2), 50.0), |
| 26 | entry(2, "Aside", Some(2), 400.0), |
| 27 | entry(1, "Method", Some(3), 80.0), |
| 28 | entry(2, "Lost", None, 0.0), |
| 29 | entry(3, "Deep", Some(3), 500.0), |
| 30 | ]) |
| 31 | } |
| 32 | |
| 33 | #[test] |
| 34 | fn test_contents_nests_by_level() { |
| 35 | let c = sample(); |
| 36 | let depths: Vec<usize> = (0..c.len()).map(|i| c.depth(i)).collect(); |
| 37 | assert_eq!(depths, vec![0, 1, 2, 1, 0, 1, 2]); |
| 38 | let kids: Vec<bool> = (0..c.len()).map(|i| c.has_children(i)).collect(); |
| 39 | assert_eq!(kids, vec![true, true, false, false, true, true, false]); |
| 40 | } |
| 41 | |
| 42 | #[test] |
| 43 | fn test_contents_folding_hides_descendants_and_marks_the_branch() { |
| 44 | let mut c = sample(); |
| 45 | assert_eq!(c.visible(), vec![0, 1, 2, 3, 4, 5, 6]); |
| 46 | assert!(c.toggle(0)); |
| 47 | assert_eq!(c.visible(), vec![0, 4, 5, 6]); |
| 48 | // The current heading inside a folded branch is shown on the branch's row. |
| 49 | assert_eq!(c.shown_for(2), 0); |
| 50 | assert_eq!(c.shown_for(5), 5); |
| 51 | // A leaf does not fold. |
| 52 | assert!(!c.toggle(2)); |
| 53 | assert!(c.toggle(0)); |
| 54 | assert_eq!(c.visible().len(), 7); |
| 55 | } |
| 56 | |
| 57 | #[test] |
| 58 | fn test_contents_current_is_the_last_heading_above_the_view() { |
| 59 | let c = sample(); |
| 60 | // A simple stack: 1000 pixels a page, one pixel a point. |
| 61 | let pos = |e: &OutlineEntry| e.page.map(|p| (p as f64 - 1.0) * 1000.0 + e.y.map(|y| y.to_pt()).unwrap_or(0.0)); |
| 62 | assert_eq!(c.current(pos, 0.0), None); |
| 63 | assert_eq!(c.current(pos, 100.0), Some(0)); |
| 64 | assert_eq!(c.current(pos, 1100.0), Some(2)); |
| 65 | assert_eq!(c.current(pos, 1450.0), Some(3)); |
| 66 | // The unplaced heading is never current. |
| 67 | assert_eq!(c.current(pos, 2090.0), Some(4)); |
| 68 | assert_eq!(c.current(pos, 9000.0), Some(6)); |
| 69 | } |
| 70 | |
| 71 | #[test] |
| 72 | fn test_contents_from_the_hierarchy_sample() { |
| 73 | let path = concat!(env!("CARGO_MANIFEST_DIR"), "/../fe2o3_austenite/web/pearl-reader/samples/hierarchy.prl"); |
| 74 | let doc = match PearlDoc::read_file(path) { |
| 75 | Ok(d) => d, |
| 76 | Err(e) => panic!("{}", e), |
| 77 | }; |
| 78 | let outline = match doc.outline() { |
| 79 | Ok(o) => o, |
| 80 | Err(e) => panic!("{}", e), |
| 81 | }; |
| 82 | let c = Contents::new(outline); |
| 83 | assert!(c.len() > 3, "the hierarchy sample carries an outline"); |
| 84 | assert!((0..c.len()).any(|i| c.depth(i) > 0), "and it nests"); |
| 85 | assert!(c.entries().iter().all(|e| e.page.is_some()), "every heading is placed"); |
| 86 | } |