|
5 | 5 | // Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details. |
6 | 6 | // ------------------------------------------------------------------------------------------------ |
7 | 7 |
|
| 8 | +use stack_graphs::cycles::AppendingCycleDetector; |
| 9 | +use stack_graphs::cycles::JoiningCycleDetector; |
8 | 10 | use stack_graphs::graph::StackGraph; |
9 | 11 | use stack_graphs::partial::PartialPaths; |
| 12 | +use stack_graphs::stitching::Database; |
| 13 | +use stack_graphs::CancelAfterDuration; |
| 14 | +use std::time::Duration; |
10 | 15 |
|
11 | 16 | use crate::util::*; |
12 | 17 |
|
@@ -123,3 +128,67 @@ fn two_steps_forward_one_step_back_path_is_productive() { |
123 | 128 |
|
124 | 129 | assert!(p.is_productive(&graph, &mut partials)); |
125 | 130 | } |
| 131 | + |
| 132 | +// ---------------------------------------------------------------------------- |
| 133 | +// cycle detection |
| 134 | + |
| 135 | +#[test] |
| 136 | +fn appending_simple_identity_cycle_is_detected() { |
| 137 | + let mut graph = StackGraph::new(); |
| 138 | + let file = graph.add_file("test").unwrap(); |
| 139 | + let r = StackGraph::root_node(); |
| 140 | + let s = create_scope_node(&mut graph, file, false); |
| 141 | + let foo_ref = create_push_symbol_node(&mut graph, file, "foo", false); |
| 142 | + let foo_def = create_pop_symbol_node(&mut graph, file, "foo", false); |
| 143 | + |
| 144 | + let mut partials = PartialPaths::new(); |
| 145 | + create_partial_path_and_edges(&mut graph, &mut partials, &[r, foo_ref, s, foo_def, r]).unwrap(); |
| 146 | + |
| 147 | + // test appending cycle detector |
| 148 | + { |
| 149 | + let mut cd = AppendingCycleDetector::from_node(r); |
| 150 | + assert!(cd.appended(&graph, &mut partials, foo_ref)); |
| 151 | + assert!(cd.appended(&graph, &mut partials, s)); |
| 152 | + assert!(cd.appended(&graph, &mut partials, foo_def)); |
| 153 | + assert!(!cd.appended(&graph, &mut partials, r)); |
| 154 | + } |
| 155 | + |
| 156 | + // test termination of path finding |
| 157 | + { |
| 158 | + let mut path_count = 0usize; |
| 159 | + let cancellation_flag = CancelAfterDuration::new(Duration::from_secs(10)); |
| 160 | + let result = partials.find_minimal_partial_path_set_in_file( |
| 161 | + &graph, |
| 162 | + file, |
| 163 | + &cancellation_flag, |
| 164 | + |_, _, _| path_count += 1, |
| 165 | + ); |
| 166 | + assert!(result.is_ok()); |
| 167 | + assert_eq!(0, path_count); |
| 168 | + } |
| 169 | +} |
| 170 | + |
| 171 | +#[test] |
| 172 | +fn joining_simple_identity_cycle_is_detected() { |
| 173 | + let mut graph = StackGraph::new(); |
| 174 | + let file = graph.add_file("test").unwrap(); |
| 175 | + let r = StackGraph::root_node(); |
| 176 | + let s = create_scope_node(&mut graph, file, true); |
| 177 | + let foo_ref = create_push_symbol_node(&mut graph, file, "foo", false); |
| 178 | + let foo_def = create_pop_symbol_node(&mut graph, file, "foo", false); |
| 179 | + |
| 180 | + let mut partials = PartialPaths::new(); |
| 181 | + let p0 = create_partial_path_and_edges(&mut graph, &mut partials, &[r, foo_ref, s]).unwrap(); |
| 182 | + let p1 = create_partial_path_and_edges(&mut graph, &mut partials, &[s, foo_def, r]).unwrap(); |
| 183 | + |
| 184 | + let mut db = Database::new(); |
| 185 | + let p0 = db.add_partial_path(&graph, &mut partials, p0); |
| 186 | + let p1 = db.add_partial_path(&graph, &mut partials, p1); |
| 187 | + |
| 188 | + // test joining cycle detector |
| 189 | + { |
| 190 | + let mut cd = |
| 191 | + JoiningCycleDetector::from_partial_path_handle(&graph, &mut partials, &mut db, p0); |
| 192 | + assert!(!cd.joined(&graph, &mut partials, &mut db, p1.into())); |
| 193 | + } |
| 194 | +} |
0 commit comments