finally added some tests

This commit is contained in:
Sebastian Moser
2024-09-20 12:05:18 +02:00
parent c9c8e9291f
commit 6ae8a5d3f0
10 changed files with 356 additions and 44 deletions

View File

@@ -51,6 +51,15 @@ impl MizeId {
self.path.clone()
}
pub fn after_store_part(&self) -> Vec<String> {
let tmp = self.path();
let mut path_iter = tmp.into_iter();
path_iter.next();
let new_path: Vec<String> = path_iter.map(|v| v.to_owned()).collect();
return new_path;
}
pub fn namespace(&self) -> Namespace {
self.namespace.clone()
}
@@ -128,3 +137,46 @@ impl IntoMizeId for MizeId {
//}
#[cfg(test)]
mod test {
use crate::instance::Instance;
use super::*;
#[test]
fn test_id() -> MizeResult<()> {
let instance = Instance::empty()?;
let id_one = instance.new_id("0/config/hi")?;
assert_eq!(instance.get_namespace()?, id_one.namespace());
assert_eq!("0", id_one.store_part());
assert_eq!(vec!["config".to_owned(), "hi".to_owned()], id_one.after_store_part());
let id_two = instance.new_id("test.ns:hello/config/hi")?;
assert_eq!(instance.namespace_from_string("test.ns".to_owned())?, id_two.namespace());
assert_eq!("hello", id_two.store_part());
assert_eq!(vec!["config".to_owned(), "hi".to_owned()], id_one.after_store_part());
let id_three = instance.new_id("0/")?;
assert_eq!(instance.get_namespace()?, id_three.namespace());
assert_eq!("0", id_three.store_part());
assert_eq!(Vec::<String>::new(), id_three.after_store_part());
let id_four = instance.new_id("test.ns:0/")?;
assert_eq!(instance.namespace_from_string("test.ns".to_owned())?, id_four.namespace());
assert_eq!("0", id_four.store_part());
assert_eq!(Vec::<String>::new(), id_four.after_store_part());
let id_fife = instance.new_id("0")?;
assert_eq!(instance.get_namespace()?, id_fife.namespace());
assert_eq!("0", id_fife.store_part());
assert_eq!(Vec::<String>::new(), id_fife.after_store_part());
//TODO: add the parsing form mize:// urls....
Ok(())
}
}

View File

@@ -41,6 +41,9 @@ pub mod updater;
pub mod msg_thread;
pub mod module;
#[cfg(test)]
mod tests;
static MSG_CHANNEL_SIZE: usize = 200;
static BUILD_TIME_CONFIG: &str = include_str!(std::env!("MIZE_BUILD_CONFIG"));
@@ -267,7 +270,7 @@ impl Instance {
}
pub fn id_from_string(&self, string: String) -> MizeResult<MizeId> {
let vec_string: Vec<String> = string.split("/").map(|v| v.to_owned()).collect();
let vec_string: Vec<String> = string.split("/").map(|v| v.to_owned()).filter(|el| el.as_str() != "").collect();
self.id_from_vec_string(vec_string)
}
@@ -409,27 +412,6 @@ impl Instance {
debug!("spawning thread: {}", name_to_move);
let my_thread_id = my_thread_id_no_mutex_guard;
#[cfg(feature = "wasm-target")]
unsafe {
// console_log macro
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
macro_rules! console_log {
// Note that this is using the `log` function imported above during
// `bare_bones`
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}
//end of console_log macro
console_log!("in other threadddddddddddddd");
}
func()?;
let mut threads_inner = thread_mutex.lock()?;

148
src/core/instance/tests.rs Normal file
View File

@@ -0,0 +1,148 @@
use tracing_subscriber::registry::Data;
use crate::item::IntoItemData;
use super::*;
#[test]
fn test_set_sub_path() -> MizeResult<()> {
let instance = Instance::empty()?;
let data = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
[config.test]
inner = "inner"
"#)?;
let data_two = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
[config.test]
inner = "new inner"
"#)?;
let item = instance.new_item()?;
instance.set_blocking(item.id(), data.clone())?;
assert_eq!(item.as_data_full()?, data);
// try to set a sub path of item
instance.set(vec![item.id().store_part(), "config", "test", "inner"], "hello".into_item_data())?;
// the contents of item should then be like data_two
assert_eq!(instance.get(vec![item.id().store_part(), "config", "test", "inner"])?.as_data_full()?, ItemData::from_string("hello"));
assert_eq!(item.as_data_full()?, data_two);
Ok(())
}
#[test]
fn test_itemdata_set_path() -> MizeResult<()> {
let mut data = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
[config.test]
inner = "inner"
"#)?;
let data_two = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
[config.test]
inner = "new inner"
"#)?;
data.set_path(vec!["config", "test", "inner"], ItemData::from_string("new inner"))?;
assert_eq!(data, data_two);
Ok(())
}
#[test]
fn test_itemdata_merge() -> MizeResult<()> {
let mut data = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
[config.test]
inner = "inner"
"#)?;
let data_two = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
[config.test]
inner = "new inner"
"#)?;
assert_eq!(data.get_path(vec!["config", "test", "inner"])?, ItemData::from_string("inner"));
data.merge(data_two.clone());
assert_eq!(data, data_two);
assert_eq!(data.get_path(vec!["config", "test", "inner"])?, ItemData::from_string("new inner"));
Ok(())
}
#[test]
fn test_item_merge() -> MizeResult<()> {
let instance = Instance::empty()?;
let mut item = instance.new_item()?;
// here the item should contain "empty" data
assert_eq!(item.as_data_full()?, ItemData::new());
let data = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
[config.test]
inner = "inner"
"#)?;
let data_two = ItemData::from_toml(r#"
[config]
hi = "hello from config/hi"
[config.test]
inner = "new inner"
"#)?;
item.merge(data.clone())?;
// now it should contain data
assert_eq!(item.as_data_full()?, data);
let mut sub_item = instance.get(vec![item.id().store_part(), "config", "test", "inner"])?;
// the sub item should have the string "inner"
assert_eq!(sub_item.as_data_full()?, ItemData::from_string("inner"));
sub_item.merge(ItemData::from_string("new inner"));
assert_eq!(sub_item.as_data_full()?, ItemData::from_string("new inner"));
// also the item should be updated
assert_eq!(item.as_data_full()?, data_two);
Ok(())
}
#[test]
#[should_panic(expected = "correct panic")]
fn test_cant_set_non_existent_item() -> () {
let instance = Instance::empty().expect("wrong panic");
instance.set_blocking("5", "hello world".into_item_data()).expect("correct panic");
}

View File

@@ -64,8 +64,9 @@ macro_rules! console_log {
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}
//end of console_log macro
console_log!("handle operation....");
console_log!("handle operation....: {:?}", operation);
}
match operation {
Operation::Set(id, value, maybe_conn) => {
let item_data: ItemData = value.to_owned();
@@ -81,7 +82,7 @@ macro_rules! console_log {
};
for sub in vec.iter_mut() {
// don't handle sub of type connection, in case the update comes from this
// don't handle sub of type connection, in case the update comes from this
// connection
if let Some(conn) = maybe_conn {
if let Subscription::Connection(conn2) = sub {

View File

@@ -110,6 +110,7 @@ impl Item<'_> {
pub fn merge<V: Into<ItemData> + Debug >(&mut self, mut value: V) -> MizeResult<()> {
let mut data = self.as_data_full()?;
//let mut data = data_full.get_path(id_path_without_store_part)?;
trace!("item::merge data: {:?}", data);
trace!("item::merge id: {:?}", self.id());
@@ -173,6 +174,10 @@ impl ItemData {
&self.0
}
pub fn from_cbor(cbor: CborValue) -> ItemData {
ItemData (cbor)
}
pub fn null() -> CborValue {
CborValue::Null
}
@@ -244,6 +249,12 @@ pub fn item_data_set_path(data: &mut CborValue, path: Vec<String>, data_to_set:
//trace!("[ {} ] path: {:?}", "ARG".yellow(), path);
//trace!("[ {} ] data_to_set: {}", "ARG".yellow(), data_to_set.clone().into_item_data());
test_println!("###########################");
test_println!("data: {}", ItemData::from_cbor(data.clone()));
test_println!("path: {:?}", path);
test_println!("data_to_set: {}", ItemData::from_cbor(data_to_set.clone()));
test_println!("###########################");
let mut path_iter = path.clone().into_iter();
let path_el = match path_iter.nth(0) {
Some(val) => val,
@@ -474,7 +485,7 @@ impl IntoItemData for i128 {
impl fmt::Display for ItemData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\nItemData: ");
write!(f, "ItemData: ");
let display_writer = DisplayWriter (f);
self.0.serialize(&mut serde_json::Serializer::pretty(display_writer))
.map_err(|serde_err| std::fmt::Error)
@@ -495,3 +506,17 @@ impl<'a, 'b> io::Write for DisplayWriter<'a, 'b> {
fn flush(&mut self) -> std::result::Result<(), std::io::Error> { todo!() }
}
impl PartialEq for ItemData {
fn eq(&self, other: &Self) -> bool {
let mut buf: Vec<u8> = Vec::new();
let mut buf_other: Vec<u8> = Vec::new();
ciborium::into_writer(&self.0, &mut buf);
ciborium::into_writer(&other.0, &mut buf_other);
buf == buf_other
}
}
impl Eq for ItemData {}

View File

@@ -12,6 +12,7 @@ use crate::error::{MizeError, MizeResult, IntoMizeResult};
use crate::item::{Item, ItemData};
use crate::instance::Instance;
use crate::item::get_raw_from_cbor;
use crate::mize_err;
#[derive(Clone, Debug)]
pub struct MemStore {
@@ -30,7 +31,18 @@ impl Store for MemStore {
fn set(&self, id: MizeId, data: ItemData) -> MizeResult<()> {
let mut inner = self.inner.lock()?;
inner.map.insert(id_to_u64(id)?, data);
if let Some(old_data) = inner.map.get(&id_to_u64(id.clone())?) {
//if there is already data there, set at the correct path
let mut old_data = old_data.to_owned();
let path = id.after_store_part();
old_data.set_path(path, data)?;
inner.map.insert(id_to_u64(id)?, old_data);
} else {
// if no data exists for that store_part, just insert
inner.map.insert(id_to_u64(id)?, data);
}
return Ok(())
}
fn get_links(&self, item: Item) -> MizeResult<Vec<MizeId>> {
@@ -76,12 +88,32 @@ impl Store for MemStore {
None => ItemData::new(),
};
let tmp = id.path();
let mut path_iter = tmp.into_iter();
path_iter.next();
let new_path: Vec<String> = path_iter.map(|v| v.to_owned()).collect();
let new_path = id.after_store_part();
let ret_data = data.get_path(new_path)?;
#[cfg(feature = "wasm-target")]
unsafe {
// console_log macro
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
macro_rules! console_log {
// Note that this is using the `log` function imported above during
// `bare_bones`
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}
//end of console_log macro
console_log!("ret_data in data full in memstore: {:?}", ret_data);
}
return Ok(ret_data);
}
fn id_iter(&self) -> MizeResult<IdIter> {

View File

@@ -1,12 +1,34 @@
#![ allow( warnings ) ]
#[no_mangle]
pub fn main() {
println!("hello from main fn");
static PROTO_VERSION: u8 = 1;
#[macro_export]
macro_rules! test_println {
($($arg:tt)*) => {
#[cfg(test)]
print!("[[ {} ]] ", <&str as colored::Colorize>::blue("TEST"));
#[cfg(test)]
print!($($arg)*);
#[cfg(test)]
print!("\n");
};
}
static PROTO_VERSION: u8 = 1;
#[macro_export]
macro_rules! test_print {
($($arg:tt)*) => {
#[cfg(test)]
print!("[[ {} ]] ", <&str as colored::Colorize>::blue("TEST"));
#[cfg(test)]
print!($($arg)*);
};
}
// the core part has the code that can run on any platform
mod core {

View File

@@ -1,6 +1,8 @@
use std::ptr::NonNull;
use std::panic;
use web_sys::js_sys;
use crate::id::MizeId;
use crate::item::Item;
use crate::platform::wasm::js_sys::Function;
use web_sys::{WorkerOptions, WorkerType};
use web_sys::Worker;
@@ -37,6 +39,8 @@ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
// A function imitating `std::thread::spawn`.
// thanks to: https://www.tweag.io/blog/2022-11-24-wasm-threads-and-messages/
pub fn wasm_spawn(f: impl FnOnce() -> MizeResult<()> + Send + 'static) -> MizeResult<()> {
console_log!("no threading in the browser.....");
return Ok(());
// to get window.mize_worker_url, which is set by some js code, which gets "compiled" by a
// bundler, which sets window.mize_worker_url to the url of ./npm_pkg/worker.js
@@ -118,13 +122,13 @@ pub struct JsInstance {
inner: NonNull<Instance>,
}
/*
#[wasm_bindgen]
pub struct JsModule {
inner: NonNull<Box<dyn Module + Send + Sync>>,
//inner: *mut Mme,
pub struct JsItemHandle {
instance: NonNull<Instance>,
id: MizeId,
}
*/
#[wasm_bindgen]
impl JsInstance {
@@ -144,11 +148,44 @@ impl JsInstance {
}
#[wasm_bindgen]
pub unsafe fn test(&mut self) -> () {
console_log!("hiiiiiiiiiiiiiiii from test");
self.inner.as_mut().set("0/config/hello", "hello world".into_item_data());
pub unsafe fn set(&mut self, id: String, value: String) -> () {
let data = value.into_item_data();
console_log!("data in set: {}", data);
self.inner.as_mut().set_blocking(id, data);
}
//#[wasm_bindgen]
#[wasm_bindgen]
pub unsafe fn get_handle(&mut self, id: String) -> MizeResult<JsItemHandle> {
let item = self.inner.as_mut().get(id)?;
Ok(JsItemHandle { instance: self.inner, id: item.id()})
}
}
#[wasm_bindgen]
impl JsItemHandle {
#[wasm_bindgen]
pub unsafe fn value_string(&mut self) -> MizeResult<String> {
let item = self.instance.as_mut().get(self.id.clone())?;
let string = item.value_string()?;
Ok(string)
}
#[wasm_bindgen]
pub unsafe fn as_data_full(&mut self) -> MizeResult<JsValue> {
let item = self.instance.as_mut().get(self.id.clone())?;
let data_raw = item.as_data_full()?;
let jsvalue = serde_wasm_bindgen::to_value(data_raw.cbor())?;
Ok(jsvalue)
}
}
impl From<MizeError> for JsValue {
fn from(value: MizeError) -> Self {
let string = format!("{:?}", value);
string.into()
}
}