initial commit
This commit is contained in:
50
_bmad-output/implementation-artifacts/1-8-sheet-context.md
Normal file
50
_bmad-output/implementation-artifacts/1-8-sheet-context.md
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
epic: 1
|
||||
story: 1.8
|
||||
title: "Sheet Context"
|
||||
status: draft
|
||||
---
|
||||
|
||||
## Epic 1 — Core Calculation Engine (Rust Crate)
|
||||
**Goal:** Build `calcpad-engine` as a standalone Rust crate that powers all platforms. This is the foundation.
|
||||
|
||||
### Story 1.8: Sheet Context
|
||||
|
||||
As a CalcPad engine consumer,
|
||||
I want a `SheetContext` struct that holds all evaluation state including variables, line results, and dependency graphs,
|
||||
So that multi-line sheets are evaluated correctly and undo/redo is cheap.
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
**Given** a new `SheetContext` is created via `SheetContext::new()`
|
||||
**When** it is inspected
|
||||
**Then** it has no lines, no variables, and an empty dependency graph
|
||||
|
||||
**Given** a `SheetContext` with `ctx.set_line(0, "x = 10")` and `ctx.set_line(1, "x * 2")`
|
||||
**When** `ctx.eval()` is called
|
||||
**Then** it returns a `Vec<CalcResult>` of length 2
|
||||
**And** the first result is `10` and the second result is `20`
|
||||
|
||||
**Given** a `SheetContext` where line 0 defines `x = 10` and line 2 references `x`
|
||||
**When** line 0 is changed to `x = 20` and `ctx.eval()` is called
|
||||
**Then** line 2 is re-evaluated and reflects the updated value `x = 20`
|
||||
|
||||
**Given** a `SheetContext` with established state
|
||||
**When** it is cloned via `ctx.clone()`
|
||||
**Then** the clone is a deep copy that can be modified independently
|
||||
**And** the clone operation is cheap enough for undo/redo snapshots (sub-millisecond for 100-line sheets)
|
||||
|
||||
**Given** a `SheetContext` with a dependency graph where line 3 depends on line 1
|
||||
**When** only line 1 is modified
|
||||
**Then** the engine re-evaluates line 1 and line 3 but skips lines that are not in the dependency chain
|
||||
**And** unchanged, independent lines are not recomputed
|
||||
|
||||
**Given** a `SheetContext` where a circular dependency is introduced (e.g., line 1 references line 2 and line 2 references line 1)
|
||||
**When** `ctx.eval()` is called
|
||||
**Then** both lines return `CalcResult::Error` with a circular dependency message
|
||||
**And** the engine does not enter an infinite loop
|
||||
|
||||
**Given** a `SheetContext` with lines that include aggregator references such as `total` or `sum`
|
||||
**When** `ctx.eval()` is called
|
||||
**Then** the aggregators compute over the appropriate preceding lines
|
||||
**And** the dependency graph correctly tracks which lines feed into each aggregator
|
||||
Reference in New Issue
Block a user