mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-31 22:26:57 -06:00
Recalc: an array that read another array's old spill is evaluated again
When two dynamic arrays were recalculated in the same pass and the first read the second's spill area before the second was evaluated, it read the old values. Formulas reading a spill area that changed are evaluated again, but dynamic arrays were left out of that second round (only to keep an array from re-queuing itself), so with D11 = SEQUENCE(1,3,A1) and G5 = UNIQUE(VSTACK(F9:F12,A1)), changing A1 from 1 to 10 left 3 in G6 instead of 12. Only the array itself is left out now.
This commit is contained in:
@@ -571,7 +571,7 @@ impl Calc {
|
||||
if let Some(r) = changed_range {
|
||||
let mut deps = Vec::new();
|
||||
self.graph.dependents_of_range(k.0, r, &mut deps);
|
||||
spill_changes.extend(deps);
|
||||
spill_changes.extend(deps.into_iter().filter(|d| d != k));
|
||||
}
|
||||
if let Some(o) = old
|
||||
&& !sheet.spill_ranges.get(&k.1).is_some_and(|n| n.contains(o.start) && n.contains(o.end))
|
||||
@@ -599,7 +599,6 @@ impl Calc {
|
||||
}
|
||||
spill_changes.sort_by_key(|(s, c)| (*s, c.row, c.col));
|
||||
spill_changes.dedup();
|
||||
spill_changes.retain(|k| !spills.contains_key(k));
|
||||
if spill_changes.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -206,6 +206,19 @@ fn a_spill_that_goes_away_unblocks_another() {
|
||||
assert_eq!((v(&s, "E10"), v(&s, "G10")), (Value::Number(1.0), Value::Number(3.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_array_reading_another_arrays_spill_is_updated() {
|
||||
// G5 is evaluated before D11 in the same pass, so it first reads D11's old spill.
|
||||
let mut s = s();
|
||||
s.execute("cell.set", json!({"cell": "A1", "input": "1"})).unwrap();
|
||||
s.execute("cell.set", json!({"cell": "D11", "input": "=SEQUENCE(1,3,A1)"})).unwrap();
|
||||
s.execute("cell.set", json!({"cell": "G5", "input": "=UNIQUE(VSTACK(F9:F12,A1))"})).unwrap();
|
||||
s.execute("cell.set", json!({"cell": "A1", "input": "10"})).unwrap();
|
||||
assert_eq!((v(&s, "G6"), v(&s, "G7")), (Value::Number(12.0), Value::Number(10.0)));
|
||||
s.execute("formulas.calculateNow", json!({})).unwrap();
|
||||
assert_eq!((v(&s, "G6"), v(&s, "G7")), (Value::Number(12.0), Value::Number(10.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_command_survives_empty_params() {
|
||||
let mut s = Session::new();
|
||||
|
||||
Reference in New Issue
Block a user