From 73faf1d52464a82d1089364746d1a8e8bcb665e2 Mon Sep 17 00:00:00 2001 From: Peter Tseng Date: Tue, 13 Sep 2016 22:17:30 -0700 Subject: [PATCH 1/2] react: example: Check all dependents to avoid partial write Fixes #202 --- exercises/react/example.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/exercises/react/example.rs b/exercises/react/example.rs index 8fdd8eeb9..f3ac5c60c 100644 --- a/exercises/react/example.rs +++ b/exercises/react/example.rs @@ -47,12 +47,14 @@ impl <'a, T: Copy + PartialEq> Reactor<'a, T> { } pub fn create_compute T + 'a>(&mut self, dependencies: &[CellID], compute_func: F) -> Result { + // Check all dependencies' validity before modifying any of them, + // so that we don't perform an incorrect partial write. + if !dependencies.iter().all(|&id| id < self.cells.len()) { + return Err("Nonexistent input"); + } let new_id = self.cells.len(); for &id in dependencies { - match self.cells.get_mut(id) { - Some(c) => c.dependents.push(new_id), - None => return Err("Nonexistent input"), - } + self.cells.get_mut(id).unwrap().dependents.push(new_id); } let inputs: Vec<_> = dependencies.iter().map(|&id| self.value(id).unwrap()).collect(); let initial = compute_func(&inputs); From 1f327b5ea8c53954766e91ca4762bb7a8c05009c Mon Sep 17 00:00:00 2001 From: Peter Tseng Date: Tue, 13 Sep 2016 22:24:22 -0700 Subject: [PATCH 2/2] react: test partially-valid compute cell create --- exercises/react/tests/react.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/exercises/react/tests/react.rs b/exercises/react/tests/react.rs index 6ac600811..1a72e8943 100644 --- a/exercises/react/tests/react.rs +++ b/exercises/react/tests/react.rs @@ -53,6 +53,19 @@ fn error_creating_compute_cell_if_input_doesnt_exist() { assert!(Reactor::new().create_compute(&vec![input], |_| 0).is_err()); } +#[test] +#[ignore] +fn do_not_break_cell_if_creating_compute_cell_with_valid_and_invalid_input() { + let mut dummy_reactor = Reactor::new(); + let _ = dummy_reactor.create_input(1); + let dummy_cell = dummy_reactor.create_input(2); + let mut reactor = Reactor::new(); + let input = reactor.create_input(1); + assert!(reactor.create_compute(&vec![input, dummy_cell], |_| 0).is_err()); + assert!(reactor.set_value(input, 5).is_ok()); + assert_eq!(reactor.value(input).unwrap(), 5); +} + #[test] #[ignore] fn compute_cells_update_value_when_dependencies_are_changed() {