max / quasi
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01MptwXZ8k65v19rFmdGAyki
1 file changed,
+58 insertions,
-8 deletions
| @@ -7324,6 +7324,37 @@ | |||
| 7324 | 7324 | pub fn row(mut self, mut row: Cells) -> Self { | |
| 7325 | 7325 | if !row.placed.is_empty() { | |
| 7326 | 7326 | let placed = std::mem::take(&mut row.placed); | |
| 7327 | + | debug_assert!( | |
| 7328 | + | placed | |
| 7329 | + | .iter() | |
| 7330 | + | .all(|(name, _)| self.columns.iter().any(|column| column.name == *name)), | |
| 7331 | + | "a cell named a column this table does not have; the name is dropped and the \ | |
| 7332 | + | cell is silently lost. Named: {:?}. Columns: {:?}", | |
| 7333 | + | placed.iter().map(|(name, _)| name).collect::<Vec<_>>(), | |
| 7334 | + | self.columns | |
| 7335 | + | .iter() | |
| 7336 | + | .map(|column| &column.name) | |
| 7337 | + | .collect::<Vec<_>>(), | |
| 7338 | + | ); | |
| 7339 | + | debug_assert!( | |
| 7340 | + | { | |
| 7341 | + | let mut names = self | |
| 7342 | + | .columns | |
| 7343 | + | .iter() | |
| 7344 | + | .map(|column| column.name.as_str()) | |
| 7345 | + | .collect::<Vec<_>>(); | |
| 7346 | + | names.sort_unstable(); | |
| 7347 | + | let before = names.len(); | |
| 7348 | + | names.dedup(); | |
| 7349 | + | names.len() == before | |
| 7350 | + | }, | |
| 7351 | + | "two columns share a name, so a named cell cannot say which it meant and both \ | |
| 7352 | + | take the first one's value. Columns: {:?}", | |
| 7353 | + | self.columns | |
| 7354 | + | .iter() | |
| 7355 | + | .map(|column| &column.name) | |
| 7356 | + | .collect::<Vec<_>>(), | |
| 7357 | + | ); | |
| 7327 | 7358 | row.values = self | |
| 7328 | 7359 | .columns | |
| 7329 | 7360 | .iter() | |
| @@ -9539,17 +9570,36 @@ | |||
| 9539 | 9570 | assert_eq!(read(&stranger), ["quasi", "", "the app stack"]); | |
| 9540 | 9571 | } | |
| 9541 | 9572 | ||
| 9542 | - | /// A column nothing named is empty, and a name no column has is dropped. | |
| 9573 | + | /// A column nothing named is empty rather than absent. | |
| 9543 | 9574 | #[test] | |
| 9544 | - | fn the_columns_decide_what_a_row_may_say() { | |
| 9545 | - | let table = Table::new([Column::new("Name")]).row( | |
| 9546 | - | Cells::default() | |
| 9547 | - | .at("Name", Cell::new("kick.wav")) | |
| 9548 | - | .at("Nonexistent", Cell::new("ignored")), | |
| 9549 | - | ); | |
| 9575 | + | fn a_column_nothing_named_is_empty() { | |
| 9576 | + | let table = Table::new([Column::new("Name"), Column::new("Size")]) | |
| 9577 | + | .row(Cells::default().at("Name", Cell::new("kick.wav"))); | |
| 9550 | 9578 | ||
| 9551 | - | assert_eq!(table.rows[0].values.len(), 1); | |
| 9579 | + | assert_eq!(table.rows[0].values.len(), 2); | |
| 9552 | 9580 | assert_eq!(table.rows[0].values[0].text(), "kick.wav"); | |
| 9581 | + | assert_eq!(table.rows[0].values[1].text(), ""); | |
| 9582 | + | } | |
| 9583 | + | ||
| 9584 | + | /// Naming a column the table does not have is a bug, and it is loud. | |
| 9585 | + | /// | |
| 9586 | + | /// The one failure mode naming introduces: the cell is dropped, so a typo | |
| 9587 | + | /// is an empty column rather than a compile error. Nothing above this can | |
| 9588 | + | /// catch it, because the row and the column list are written apart, so the | |
| 9589 | + | /// check lives where both are in hand. | |
| 9590 | + | #[test] | |
| 9591 | + | #[should_panic(expected = "a cell named a column this table does not have")] | |
| 9592 | + | fn naming_a_column_the_table_does_not_have_is_caught() { | |
| 9593 | + | let _ = Table::new([Column::new("Name")]) | |
| 9594 | + | .row(Cells::default().at("Nmae", Cell::new("kick.wav"))); | |
| 9595 | + | } | |
| 9596 | + | ||
| 9597 | + | /// Two columns with one name cannot be addressed apart. | |
| 9598 | + | #[test] | |
| 9599 | + | #[should_panic(expected = "two columns share a name")] | |
| 9600 | + | fn two_columns_sharing_a_name_is_caught() { | |
| 9601 | + | let _ = Table::new([Column::new("Actions"), Column::new("Actions")]) | |
| 9602 | + | .row(Cells::default().at("Actions", Cell::new("edit"))); | |
| 9553 | 9603 | } | |
| 9554 | 9604 | ||
| 9555 | 9605 | /// A row built by position still works and is untouched by resolution. |