mirror of
https://github.com/servo/servo.git
synced 2025-08-29 17:18:23 +01:00
indexeddb: Initialize DB version to zero in unit tests (#38911)
Continuation of https://github.com/servo/servo/pull/38819 Testing: Fixes indexeddb unit tests --------- Signed-off-by: Rodion Borovyk <rodion.borovyk@gmail.com>
This commit is contained in:
parent
814fa8ff2b
commit
3f6e2679dc
6 changed files with 227 additions and 235 deletions
|
@ -69,7 +69,6 @@ pub trait KvsEngine {
|
||||||
|
|
||||||
fn delete_store(&self, store_name: SanitizedName) -> Result<(), Self::Error>;
|
fn delete_store(&self, store_name: SanitizedName) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
#[expect(dead_code)]
|
|
||||||
fn close_store(&self, store_name: SanitizedName) -> Result<(), Self::Error>;
|
fn close_store(&self, store_name: SanitizedName) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
fn delete_database(self) -> Result<(), Self::Error>;
|
fn delete_database(self) -> Result<(), Self::Error>;
|
||||||
|
|
|
@ -536,234 +536,3 @@ impl KvsEngine for SqliteEngine {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use net_traits::indexeddb_thread::{
|
|
||||||
AsyncOperation, AsyncReadOnlyOperation, AsyncReadWriteOperation, CreateObjectResult,
|
|
||||||
IndexedDBKeyType, IndexedDBTxnMode, KeyPath,
|
|
||||||
};
|
|
||||||
use servo_url::ImmutableOrigin;
|
|
||||||
use url::Host;
|
|
||||||
|
|
||||||
use crate::indexeddb::engines::{KvsEngine, KvsOperation, KvsTransaction, SanitizedName};
|
|
||||||
use crate::indexeddb::idb_thread::IndexedDBDescription;
|
|
||||||
use crate::resource_thread::CoreResourceThreadPool;
|
|
||||||
|
|
||||||
fn test_origin() -> ImmutableOrigin {
|
|
||||||
ImmutableOrigin::Tuple(
|
|
||||||
"test_origin".to_string(),
|
|
||||||
Host::Domain("localhost".to_string()),
|
|
||||||
80,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_pool() -> Arc<CoreResourceThreadPool> {
|
|
||||||
Arc::new(CoreResourceThreadPool::new(1, "test".to_string()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_cycle() {
|
|
||||||
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
|
||||||
let thread_pool = get_pool();
|
|
||||||
// Test create
|
|
||||||
let _ = super::SqliteEngine::new(
|
|
||||||
base_dir.path(),
|
|
||||||
&IndexedDBDescription {
|
|
||||||
name: "test_db".to_string(),
|
|
||||||
origin: test_origin(),
|
|
||||||
},
|
|
||||||
1,
|
|
||||||
thread_pool.clone(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
// Test open
|
|
||||||
let db = super::SqliteEngine::new(
|
|
||||||
base_dir.path(),
|
|
||||||
&IndexedDBDescription {
|
|
||||||
name: "test_db".to_string(),
|
|
||||||
origin: test_origin(),
|
|
||||||
},
|
|
||||||
1,
|
|
||||||
thread_pool.clone(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let version = db.version().expect("Failed to get version");
|
|
||||||
assert_eq!(version, 1);
|
|
||||||
db.set_version(5).unwrap();
|
|
||||||
let new_version = db.version().expect("Failed to get new version");
|
|
||||||
assert_eq!(new_version, 5);
|
|
||||||
db.delete_database().expect("Failed to delete database");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_create_store() {
|
|
||||||
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
|
||||||
let thread_pool = get_pool();
|
|
||||||
let db = super::SqliteEngine::new(
|
|
||||||
base_dir.path(),
|
|
||||||
&IndexedDBDescription {
|
|
||||||
name: "test_db".to_string(),
|
|
||||||
origin: test_origin(),
|
|
||||||
},
|
|
||||||
1,
|
|
||||||
thread_pool,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let store_name = SanitizedName::new("test_store".to_string());
|
|
||||||
let result = db.create_store(store_name.clone(), None, true);
|
|
||||||
assert!(result.is_ok());
|
|
||||||
let create_result = result.unwrap();
|
|
||||||
assert_eq!(create_result, CreateObjectResult::Created);
|
|
||||||
// Try to create the same store again
|
|
||||||
let result = db.create_store(store_name.clone(), None, false);
|
|
||||||
assert!(result.is_ok());
|
|
||||||
let create_result = result.unwrap();
|
|
||||||
assert_eq!(create_result, CreateObjectResult::AlreadyExists);
|
|
||||||
// Ensure store was not overwritten
|
|
||||||
assert!(db.has_key_generator(store_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_key_path() {
|
|
||||||
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
|
||||||
let thread_pool = get_pool();
|
|
||||||
let db = super::SqliteEngine::new(
|
|
||||||
base_dir.path(),
|
|
||||||
&IndexedDBDescription {
|
|
||||||
name: "test_db".to_string(),
|
|
||||||
origin: test_origin(),
|
|
||||||
},
|
|
||||||
1,
|
|
||||||
thread_pool,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let store_name = SanitizedName::new("test_store".to_string());
|
|
||||||
let result = db.create_store(
|
|
||||||
store_name.clone(),
|
|
||||||
Some(KeyPath::String("test".to_string())),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
assert!(result.is_ok());
|
|
||||||
assert_eq!(
|
|
||||||
db.key_path(store_name),
|
|
||||||
Some(KeyPath::String("test".to_string()))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_delete_store() {
|
|
||||||
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
|
||||||
let thread_pool = get_pool();
|
|
||||||
let db = super::SqliteEngine::new(
|
|
||||||
base_dir.path(),
|
|
||||||
&IndexedDBDescription {
|
|
||||||
name: "test_db".to_string(),
|
|
||||||
origin: test_origin(),
|
|
||||||
},
|
|
||||||
1,
|
|
||||||
thread_pool,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
db.create_store(SanitizedName::new("test_store".to_string()), None, false)
|
|
||||||
.expect("Failed to create store");
|
|
||||||
// Delete the store
|
|
||||||
db.delete_store(SanitizedName::new("test_store".to_string()))
|
|
||||||
.expect("Failed to delete store");
|
|
||||||
// Try to delete the same store again
|
|
||||||
let result = db.delete_store(SanitizedName::new("test_store".into()));
|
|
||||||
assert!(result.is_err());
|
|
||||||
// Try to delete a non-existing store
|
|
||||||
let result = db.delete_store(SanitizedName::new("test_store".into()));
|
|
||||||
// Should work as per spec
|
|
||||||
assert!(result.is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_async_operations() {
|
|
||||||
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
|
||||||
let thread_pool = get_pool();
|
|
||||||
let db = super::SqliteEngine::new(
|
|
||||||
base_dir.path(),
|
|
||||||
&IndexedDBDescription {
|
|
||||||
name: "test_db".to_string(),
|
|
||||||
origin: test_origin(),
|
|
||||||
},
|
|
||||||
1,
|
|
||||||
thread_pool,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let store_name = SanitizedName::new("test_store".to_string());
|
|
||||||
db.create_store(store_name.clone(), None, false)
|
|
||||||
.expect("Failed to create store");
|
|
||||||
let channel = ipc_channel::ipc::channel().unwrap();
|
|
||||||
let channel2 = ipc_channel::ipc::channel().unwrap();
|
|
||||||
let channel3 = ipc_channel::ipc::channel().unwrap();
|
|
||||||
let channel4 = ipc_channel::ipc::channel().unwrap();
|
|
||||||
let channel5 = ipc_channel::ipc::channel().unwrap();
|
|
||||||
let channel6 = ipc_channel::ipc::channel().unwrap();
|
|
||||||
let rx = db.process_transaction(KvsTransaction {
|
|
||||||
mode: IndexedDBTxnMode::Readwrite,
|
|
||||||
requests: VecDeque::from(vec![
|
|
||||||
KvsOperation {
|
|
||||||
store_name: store_name.clone(),
|
|
||||||
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::PutItem {
|
|
||||||
sender: channel.0,
|
|
||||||
key: IndexedDBKeyType::Number(1.0),
|
|
||||||
value: vec![1, 2, 3],
|
|
||||||
should_overwrite: false,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
KvsOperation {
|
|
||||||
store_name: store_name.clone(),
|
|
||||||
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::GetItem {
|
|
||||||
sender: channel2.0,
|
|
||||||
key_range: super::IndexedDBKeyRange::only(IndexedDBKeyType::Number(1.0)),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
KvsOperation {
|
|
||||||
store_name: store_name.clone(),
|
|
||||||
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::GetItem {
|
|
||||||
sender: channel3.0,
|
|
||||||
key_range: super::IndexedDBKeyRange::only(IndexedDBKeyType::Number(5.0)),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
KvsOperation {
|
|
||||||
store_name: store_name.clone(),
|
|
||||||
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::Count {
|
|
||||||
sender: channel4.0,
|
|
||||||
key_range: super::IndexedDBKeyRange::only(IndexedDBKeyType::Number(1.0)),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
KvsOperation {
|
|
||||||
store_name: store_name.clone(),
|
|
||||||
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::RemoveItem {
|
|
||||||
sender: channel5.0,
|
|
||||||
key: IndexedDBKeyType::Number(1.0),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
KvsOperation {
|
|
||||||
store_name: store_name.clone(),
|
|
||||||
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::Clear(
|
|
||||||
channel6.0,
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
});
|
|
||||||
let _ = rx.blocking_recv().unwrap();
|
|
||||||
channel.1.recv().unwrap().unwrap();
|
|
||||||
let get_result = channel2.1.recv().unwrap();
|
|
||||||
let value = get_result.unwrap();
|
|
||||||
assert_eq!(value, Some(vec![1, 2, 3]));
|
|
||||||
let get_result = channel3.1.recv().unwrap();
|
|
||||||
let value = get_result.unwrap();
|
|
||||||
assert_eq!(value, None);
|
|
||||||
let amount = channel4.1.recv().unwrap().unwrap();
|
|
||||||
assert_eq!(amount, 1);
|
|
||||||
channel5.1.recv().unwrap().unwrap();
|
|
||||||
channel6.1.recv().unwrap().unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ impl IndexedDBThreadFactory for IpcSender<IndexedDBThreadMsg> {
|
||||||
|
|
||||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||||
pub struct IndexedDBDescription {
|
pub struct IndexedDBDescription {
|
||||||
pub(super) origin: ImmutableOrigin,
|
pub origin: ImmutableOrigin,
|
||||||
pub(super) name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndexedDBDescription {
|
impl IndexedDBDescription {
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
|
|
||||||
pub use self::idb_thread::IndexedDBThreadFactory;
|
pub use self::idb_thread::IndexedDBThreadFactory;
|
||||||
|
|
||||||
mod engines;
|
pub mod engines;
|
||||||
|
|
||||||
pub mod idb_thread;
|
pub mod idb_thread;
|
||||||
|
|
|
@ -15,6 +15,7 @@ mod hsts;
|
||||||
mod http_cache;
|
mod http_cache;
|
||||||
mod http_loader;
|
mod http_loader;
|
||||||
mod resource_thread;
|
mod resource_thread;
|
||||||
|
mod sqlite;
|
||||||
mod subresource_integrity;
|
mod subresource_integrity;
|
||||||
|
|
||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
|
|
223
components/net/tests/sqlite.rs
Normal file
223
components/net/tests/sqlite.rs
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use net::indexeddb::engines::{
|
||||||
|
KvsEngine, KvsOperation, KvsTransaction, SanitizedName, SqliteEngine,
|
||||||
|
};
|
||||||
|
use net::indexeddb::idb_thread::IndexedDBDescription;
|
||||||
|
use net::resource_thread::CoreResourceThreadPool;
|
||||||
|
use net_traits::indexeddb_thread::{
|
||||||
|
AsyncOperation, AsyncReadOnlyOperation, AsyncReadWriteOperation, CreateObjectResult,
|
||||||
|
IndexedDBKeyRange, IndexedDBKeyType, IndexedDBTxnMode, KeyPath,
|
||||||
|
};
|
||||||
|
use servo_url::ImmutableOrigin;
|
||||||
|
use url::Host;
|
||||||
|
|
||||||
|
fn test_origin() -> ImmutableOrigin {
|
||||||
|
ImmutableOrigin::Tuple(
|
||||||
|
"test_origin".to_string(),
|
||||||
|
Host::Domain("localhost".to_string()),
|
||||||
|
80,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_pool() -> Arc<CoreResourceThreadPool> {
|
||||||
|
Arc::new(CoreResourceThreadPool::new(1, "test".to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cycle() {
|
||||||
|
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
||||||
|
let thread_pool = get_pool();
|
||||||
|
// Test create
|
||||||
|
let _ = SqliteEngine::new(
|
||||||
|
base_dir.path(),
|
||||||
|
&IndexedDBDescription {
|
||||||
|
name: "test_db".to_string(),
|
||||||
|
origin: test_origin(),
|
||||||
|
},
|
||||||
|
thread_pool.clone(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
// Test open
|
||||||
|
let db = SqliteEngine::new(
|
||||||
|
base_dir.path(),
|
||||||
|
&IndexedDBDescription {
|
||||||
|
name: "test_db".to_string(),
|
||||||
|
origin: test_origin(),
|
||||||
|
},
|
||||||
|
thread_pool.clone(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let version = db.version().expect("Failed to get version");
|
||||||
|
assert_eq!(version, 0);
|
||||||
|
db.set_version(5).unwrap();
|
||||||
|
let new_version = db.version().expect("Failed to get new version");
|
||||||
|
assert_eq!(new_version, 5);
|
||||||
|
db.delete_database().expect("Failed to delete database");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_store() {
|
||||||
|
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
||||||
|
let thread_pool = get_pool();
|
||||||
|
let db = SqliteEngine::new(
|
||||||
|
base_dir.path(),
|
||||||
|
&IndexedDBDescription {
|
||||||
|
name: "test_db".to_string(),
|
||||||
|
origin: test_origin(),
|
||||||
|
},
|
||||||
|
thread_pool,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let store_name = SanitizedName::new("test_store".to_string());
|
||||||
|
let result = db.create_store(store_name.clone(), None, true);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let create_result = result.unwrap();
|
||||||
|
assert_eq!(create_result, CreateObjectResult::Created);
|
||||||
|
// Try to create the same store again
|
||||||
|
let result = db.create_store(store_name.clone(), None, false);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let create_result = result.unwrap();
|
||||||
|
assert_eq!(create_result, CreateObjectResult::AlreadyExists);
|
||||||
|
// Ensure store was not overwritten
|
||||||
|
assert!(db.has_key_generator(store_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_key_path() {
|
||||||
|
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
||||||
|
let thread_pool = get_pool();
|
||||||
|
let db = SqliteEngine::new(
|
||||||
|
base_dir.path(),
|
||||||
|
&IndexedDBDescription {
|
||||||
|
name: "test_db".to_string(),
|
||||||
|
origin: test_origin(),
|
||||||
|
},
|
||||||
|
thread_pool,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let store_name = SanitizedName::new("test_store".to_string());
|
||||||
|
let result = db.create_store(
|
||||||
|
store_name.clone(),
|
||||||
|
Some(KeyPath::String("test".to_string())),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
assert!(result.is_ok());
|
||||||
|
assert_eq!(
|
||||||
|
db.key_path(store_name),
|
||||||
|
Some(KeyPath::String("test".to_string()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_delete_store() {
|
||||||
|
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
||||||
|
let thread_pool = get_pool();
|
||||||
|
let db = SqliteEngine::new(
|
||||||
|
base_dir.path(),
|
||||||
|
&IndexedDBDescription {
|
||||||
|
name: "test_db".to_string(),
|
||||||
|
origin: test_origin(),
|
||||||
|
},
|
||||||
|
thread_pool,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
db.create_store(SanitizedName::new("test_store".to_string()), None, false)
|
||||||
|
.expect("Failed to create store");
|
||||||
|
// Delete the store
|
||||||
|
db.delete_store(SanitizedName::new("test_store".to_string()))
|
||||||
|
.expect("Failed to delete store");
|
||||||
|
// Try to delete the same store again
|
||||||
|
let result = db.delete_store(SanitizedName::new("test_store".into()));
|
||||||
|
assert!(result.is_err());
|
||||||
|
// Try to delete a non-existing store
|
||||||
|
let result = db.delete_store(SanitizedName::new("test_store".into()));
|
||||||
|
// Should work as per spec
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_async_operations() {
|
||||||
|
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
||||||
|
let thread_pool = get_pool();
|
||||||
|
let db = SqliteEngine::new(
|
||||||
|
base_dir.path(),
|
||||||
|
&IndexedDBDescription {
|
||||||
|
name: "test_db".to_string(),
|
||||||
|
origin: test_origin(),
|
||||||
|
},
|
||||||
|
thread_pool,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let store_name = SanitizedName::new("test_store".to_string());
|
||||||
|
db.create_store(store_name.clone(), None, false)
|
||||||
|
.expect("Failed to create store");
|
||||||
|
let channel = ipc_channel::ipc::channel().unwrap();
|
||||||
|
let channel2 = ipc_channel::ipc::channel().unwrap();
|
||||||
|
let channel3 = ipc_channel::ipc::channel().unwrap();
|
||||||
|
let channel4 = ipc_channel::ipc::channel().unwrap();
|
||||||
|
let channel5 = ipc_channel::ipc::channel().unwrap();
|
||||||
|
let channel6 = ipc_channel::ipc::channel().unwrap();
|
||||||
|
let rx = db.process_transaction(KvsTransaction {
|
||||||
|
mode: IndexedDBTxnMode::Readwrite,
|
||||||
|
requests: VecDeque::from(vec![
|
||||||
|
KvsOperation {
|
||||||
|
store_name: store_name.clone(),
|
||||||
|
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::PutItem {
|
||||||
|
sender: channel.0,
|
||||||
|
key: IndexedDBKeyType::Number(1.0),
|
||||||
|
value: vec![1, 2, 3],
|
||||||
|
should_overwrite: false,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
KvsOperation {
|
||||||
|
store_name: store_name.clone(),
|
||||||
|
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::GetItem {
|
||||||
|
sender: channel2.0,
|
||||||
|
key_range: IndexedDBKeyRange::only(IndexedDBKeyType::Number(1.0)),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
KvsOperation {
|
||||||
|
store_name: store_name.clone(),
|
||||||
|
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::GetItem {
|
||||||
|
sender: channel3.0,
|
||||||
|
key_range: IndexedDBKeyRange::only(IndexedDBKeyType::Number(5.0)),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
KvsOperation {
|
||||||
|
store_name: store_name.clone(),
|
||||||
|
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::Count {
|
||||||
|
sender: channel4.0,
|
||||||
|
key_range: IndexedDBKeyRange::only(IndexedDBKeyType::Number(1.0)),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
KvsOperation {
|
||||||
|
store_name: store_name.clone(),
|
||||||
|
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::RemoveItem {
|
||||||
|
sender: channel5.0,
|
||||||
|
key: IndexedDBKeyType::Number(1.0),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
KvsOperation {
|
||||||
|
store_name: store_name.clone(),
|
||||||
|
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::Clear(channel6.0)),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
let _ = rx.blocking_recv().unwrap();
|
||||||
|
channel.1.recv().unwrap().unwrap();
|
||||||
|
let get_result = channel2.1.recv().unwrap();
|
||||||
|
let value = get_result.unwrap();
|
||||||
|
assert_eq!(value, Some(vec![1, 2, 3]));
|
||||||
|
let get_result = channel3.1.recv().unwrap();
|
||||||
|
let value = get_result.unwrap();
|
||||||
|
assert_eq!(value, None);
|
||||||
|
let amount = channel4.1.recv().unwrap().unwrap();
|
||||||
|
assert_eq!(amount, 1);
|
||||||
|
channel5.1.recv().unwrap().unwrap();
|
||||||
|
channel6.1.recv().unwrap().unwrap();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue