From 7895a3baf487010441b141b26615b55d249bc666 Mon Sep 17 00:00:00 2001 From: Maksim Dimitrov Date: Thu, 8 Jun 2023 22:39:04 +0300 Subject: [PATCH] Add custom messages to asserts Signed-off-by: Maksim Dimitrov --- src/context/mod.rs | 134 ++++++++++++++++++++++++++++++++++++++++++--- src/instance.rs | 24 ++++++++ 2 files changed, 149 insertions(+), 9 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index a82c51a..7c4d888 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -254,10 +254,7 @@ impl MatchstickInstanceContext { let expected_val: String = asc_get(&self.wasm_ctx, expected_val_ptr, &GasCounter::new())?; if !self.store.contains_key(&entity_type) { - logging::error!( - "(assert.fieldEquals) No entities with type '{}' found.", - &entity_type - ); + logging::error!("No entities with type '{}' found.", &entity_type); return Ok(false); } @@ -265,7 +262,7 @@ impl MatchstickInstanceContext { let entities = self.store.get(&entity_type).unwrap(); if !entities.contains_key(&id) { logging::error!( - "(assert.fieldEquals) No entity with type '{}' and id '{}' found.", + "No entity with type '{}' and id '{}' found.", &entity_type, &id ); @@ -276,7 +273,7 @@ impl MatchstickInstanceContext { let entity = entities.get(&id).unwrap(); if !entity.contains_key(&field_name) { logging::error!( - "(assert.fieldEquals) No field named '{}' on entity with type '{}' and id '{}' found.", + "No field named '{}' on entity with type '{}' and id '{}' found.", &field_name, &entity_type, &id @@ -288,7 +285,7 @@ impl MatchstickInstanceContext { let val = entity.get(&field_name).unwrap(); if val.to_string() != expected_val { logging::error!( - "(assert.fieldEquals) Expected field '{}' to equal '{}', but was '{}' instead.", + "Expected field '{}' to equal '{}', but was '{}' instead.", &field_name, &expected_val, val @@ -323,7 +320,7 @@ impl MatchstickInstanceContext { if exp_val != act_val { logging::error!( - "(assert.equals) Expected value was '{}' but actual value was '{}'", + "Expected value was '{}' but actual value was '{}'", exp_val, act_val ); @@ -348,7 +345,7 @@ impl MatchstickInstanceContext { && self.store.get(&entity_type).unwrap().contains_key(&id) { logging::error!( - "(assert.notInStore) Value for entity type: '{}' and id: '{}' was found in store.", + "Value for entity type: '{}' and id: '{}' was found in store.", entity_type, id ); @@ -358,6 +355,125 @@ impl MatchstickInstanceContext { Ok(true) } + /// Overloading the assert function with custom error message for backwards compatibility with matchstick-as + + /// function _assert.fieldEquals( + /// entityType: string, id: string, + /// fieldName: string, expectedVal: string, + /// message: string, + /// ): bool + pub fn assert_field_equals_with_message( + &mut self, + _gas: &GasCounter, + entity_type_ptr: AscPtr, + id_ptr: AscPtr, + field_name_ptr: AscPtr, + expected_val_ptr: AscPtr, + message_ptr: AscPtr, + ) -> Result { + update_derived_relations_in_store(self); + let entity_type: String = asc_get(&self.wasm_ctx, entity_type_ptr, &GasCounter::new())?; + let id: String = asc_get(&self.wasm_ctx, id_ptr, &GasCounter::new())?; + let field_name: String = asc_get(&self.wasm_ctx, field_name_ptr, &GasCounter::new())?; + let expected_val: String = asc_get(&self.wasm_ctx, expected_val_ptr, &GasCounter::new())?; + let message: String = asc_get(&self.wasm_ctx, message_ptr, &GasCounter::new())?; + + if !self.store.contains_key(&entity_type) { + logging::error!("No entities with type '{}' found.", &entity_type); + + return Ok(false); + } + + let entities = self.store.get(&entity_type).unwrap(); + if !entities.contains_key(&id) { + logging::error!( + "No entity with type '{}' and id '{}' found.", + &entity_type, + &id + ); + + return Ok(false); + } + + let entity = entities.get(&id).unwrap(); + if !entity.contains_key(&field_name) { + logging::error!( + "No field named '{}' on entity with type '{}' and id '{}' found.", + &field_name, + &entity_type, + &id + ); + + return Ok(false); + } + + let val = entity.get(&field_name).unwrap(); + if val.to_string() != expected_val { + logging::error!("{}", message); + + return Ok(false); + }; + + Ok(true) + } + + /// function _assert.equals(expected: ethereum.Value, actual: ethereum.Value, message: string): bool + pub fn assert_equals_with_message( + &mut self, + _gas: &GasCounter, + expected_ptr: u32, + actual_ptr: u32, + message_ptr: AscPtr, + ) -> Result { + update_derived_relations_in_store(self); + let expected: Token = asc_get::<_, AscEnum, _>( + &self.wasm_ctx, + expected_ptr.into(), + &GasCounter::new(), + )?; + let actual: Token = asc_get::<_, AscEnum, _>( + &self.wasm_ctx, + actual_ptr.into(), + &GasCounter::new(), + )?; + let message: String = asc_get(&self.wasm_ctx, message_ptr, &GasCounter::new())?; + + let exp_val = get_token_value(expected); + let act_val = get_token_value(actual); + + if exp_val != act_val { + logging::error!("{}", message); + + return Ok(false); + } + + Ok(true) + } + + /// function _assert.notInStore(entityType: string, id: string, message: string): bool + pub fn assert_not_in_store_with_message( + &mut self, + _gas: &GasCounter, + entity_type_ptr: AscPtr, + id_ptr: AscPtr, + message_ptr: AscPtr, + ) -> Result { + update_derived_relations_in_store(self); + let entity_type: String = asc_get(&self.wasm_ctx, entity_type_ptr, &GasCounter::new())?; + let id: String = asc_get(&self.wasm_ctx, id_ptr, &GasCounter::new())?; + let message: String = asc_get(&self.wasm_ctx, message_ptr, &GasCounter::new())?; + + if self.store.contains_key(&entity_type) + && self.store.get(&entity_type).unwrap().contains_key(&id) + { + logging::error!("{}", message); + + return Ok(false); + } + + Ok(true) + } + /// function store.get(entityType: string, id: string): Entity pub fn mock_store_get( &mut self, diff --git a/src/instance.rs b/src/instance.rs index 0d64fdf..3925c28 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -475,6 +475,30 @@ impl MatchstickInstance { id_ptr ); + link!( + "_assert.fieldEqualsWithMessage", + assert_field_equals_with_message, + entity_type_ptr, + id_ptr, + field_name_ptr, + expected_val_ptr, + message_ptr + ); + link!( + "_assert.equalsWithMessage", + assert_equals_with_message, + expected_ptr, + actual_ptr, + message_ptr + ); + link!( + "_assert.notInStoreWithMessage", + assert_not_in_store_with_message, + entity_type_ptr, + id_ptr, + message_ptr + ); + link!("countEntities", count_entities, entity_type); // Linking gas function