mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
refactor build with generic tester
This commit is contained in:
parent
ffc4a67e2e
commit
ce6412722f
@ -83,6 +83,9 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra/.dart_tool" />
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra/.dart_tool" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra/build" />
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra/.pub" />
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/.pub" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/.dart_tool" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/app_flowy/packages/flowy_infra_ui/build" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
@ -29,7 +29,7 @@ impl FlowySDK {
|
|||||||
FlowySDK::init_log(&self.root);
|
FlowySDK::init_log(&self.root);
|
||||||
|
|
||||||
tracing::info!("🔥 Root path: {}", self.root);
|
tracing::info!("🔥 Root path: {}", self.root);
|
||||||
flowy_infra::kv::KVStore::init(&self.root);
|
let _ = flowy_infra::kv::KVStore::init(&self.root);
|
||||||
FlowySDK::init_modules(&self.root, self.server);
|
FlowySDK::init_modules(&self.root, self.server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ edition = "2018"
|
|||||||
flowy-sdk = { path = "../flowy-sdk"}
|
flowy-sdk = { path = "../flowy-sdk"}
|
||||||
flowy-dispatch = { path = "../flowy-dispatch"}
|
flowy-dispatch = { path = "../flowy-dispatch"}
|
||||||
flowy-user = { path = "../flowy-user"}
|
flowy-user = { path = "../flowy-user"}
|
||||||
|
flowy-workspace = { path = "../flowy-workspace"}
|
||||||
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
bincode = { version = "1.3"}
|
bincode = { version = "1.3"}
|
||||||
|
@ -1,46 +1,52 @@
|
|||||||
use crate::{helper::new_user_after_login, init_sdk, tester::Tester};
|
use flowy_dispatch::prelude::{FromBytes, ToBytes};
|
||||||
use flowy_dispatch::prelude::{EventDispatch, FromBytes, ModuleRequest, ToBytes};
|
use flowy_user::entities::UserDetail;
|
||||||
use flowy_user::{entities::UserDetail, event::UserEvent::SignOut};
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TestBuilder<Error> {
|
use crate::tester::{TesterContext, TesterTrait};
|
||||||
login: Option<bool>,
|
use flowy_user::errors::UserError;
|
||||||
inner: Option<Tester<Error>>,
|
use flowy_workspace::errors::WorkspaceError;
|
||||||
pub user_detail: Option<UserDetail>,
|
use std::marker::PhantomData;
|
||||||
}
|
|
||||||
|
|
||||||
impl<Error> TestBuilder<Error>
|
pub type WorkspaceTestBuilder = TestBuilder<FixedUserTester<WorkspaceError>>;
|
||||||
where
|
impl WorkspaceTestBuilder {
|
||||||
Error: FromBytes + Debug,
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
TestBuilder::<Error> {
|
Self {
|
||||||
login: None,
|
tester: Box::new(FixedUserTester::<WorkspaceError>::new()),
|
||||||
inner: None,
|
|
||||||
user_detail: None,
|
user_detail: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type UserTestBuilder = TestBuilder<RandomUserTester<UserError>>;
|
||||||
|
impl UserTestBuilder {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tester: Box::new(RandomUserTester::<UserError>::new()),
|
||||||
|
user_detail: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TestBuilder<T: TesterTrait> {
|
||||||
|
pub tester: Box<T>,
|
||||||
|
pub user_detail: Option<UserDetail>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> TestBuilder<T>
|
||||||
|
where
|
||||||
|
T: TesterTrait,
|
||||||
|
{
|
||||||
pub fn login(mut self) -> Self {
|
pub fn login(mut self) -> Self {
|
||||||
let user_detail = new_user_after_login();
|
let user_detail = self.tester.login();
|
||||||
self.user_detail = Some(user_detail);
|
self.user_detail = Some(user_detail);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn logout(self) -> Self {
|
pub fn logout(self) -> Self {
|
||||||
init_sdk();
|
self.tester.logout();
|
||||||
let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn event<E>(mut self, event: E) -> Self
|
|
||||||
where
|
|
||||||
E: Eq + Hash + Debug + Clone + Display,
|
|
||||||
{
|
|
||||||
self.inner = Some(Tester::<Error>::new(event));
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,12 +54,20 @@ where
|
|||||||
where
|
where
|
||||||
P: ToBytes,
|
P: ToBytes,
|
||||||
{
|
{
|
||||||
self.inner.as_mut().unwrap().set_request(request);
|
self.tester.set_payload(request);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn event<E>(mut self, event: E) -> Self
|
||||||
|
where
|
||||||
|
E: Eq + Hash + Debug + Clone + Display,
|
||||||
|
{
|
||||||
|
self.tester.set_event(event);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_send(mut self) -> Self {
|
pub fn sync_send(mut self) -> Self {
|
||||||
self.inner.as_mut().unwrap().sync_send();
|
self.tester.sync_send();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,22 +75,70 @@ where
|
|||||||
where
|
where
|
||||||
R: FromBytes,
|
R: FromBytes,
|
||||||
{
|
{
|
||||||
let inner = self.inner.take().unwrap();
|
self.tester.parse::<R>()
|
||||||
inner.parse::<R>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error(mut self) -> Error {
|
pub fn error(mut self) -> <T as TesterTrait>::Error { self.tester.error() }
|
||||||
let inner = self.inner.take().unwrap();
|
|
||||||
inner.error()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assert_error(mut self) -> Self {
|
pub fn assert_error(mut self) -> Self {
|
||||||
self.inner.as_mut().unwrap().assert_error();
|
self.tester.assert_error();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_success(mut self) -> Self {
|
pub fn assert_success(mut self) -> Self {
|
||||||
self.inner.as_mut().unwrap().assert_success();
|
self.tester.assert_success();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct RandomUserTester<Error> {
|
||||||
|
context: TesterContext,
|
||||||
|
err_phantom: PhantomData<Error>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Error> RandomUserTester<Error>
|
||||||
|
where
|
||||||
|
Error: FromBytes + Debug,
|
||||||
|
{
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
context: TesterContext::default(),
|
||||||
|
err_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Error> TesterTrait for RandomUserTester<Error>
|
||||||
|
where
|
||||||
|
Error: FromBytes + Debug,
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn context(&mut self) -> &mut TesterContext { &mut self.context }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FixedUserTester<Error> {
|
||||||
|
context: TesterContext,
|
||||||
|
err_phantom: PhantomData<Error>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Error> FixedUserTester<Error>
|
||||||
|
where
|
||||||
|
Error: FromBytes + Debug,
|
||||||
|
{
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
context: TesterContext::default(),
|
||||||
|
err_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Error> TesterTrait for FixedUserTester<Error>
|
||||||
|
where
|
||||||
|
Error: FromBytes + Debug,
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn context(&mut self) -> &mut TesterContext { &mut self.context }
|
||||||
|
}
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
use crate::{init_sdk, tester::Tester};
|
|
||||||
use flowy_dispatch::prelude::*;
|
|
||||||
use flowy_user::{
|
|
||||||
entities::{SignInRequest, UserDetail},
|
|
||||||
errors::UserError,
|
|
||||||
event::UserEvent::{SignIn, SignOut},
|
|
||||||
};
|
|
||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
pub fn root_dir() -> String {
|
pub fn root_dir() -> String {
|
||||||
@ -23,21 +16,6 @@ pub fn root_dir() -> String {
|
|||||||
root_dir
|
root_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_user_after_login() -> UserDetail {
|
|
||||||
init_sdk();
|
|
||||||
let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut));
|
|
||||||
let request = SignInRequest {
|
|
||||||
email: valid_email(),
|
|
||||||
password: valid_password(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut tester = Tester::<UserError>::new(SignIn);
|
|
||||||
tester.set_request(request);
|
|
||||||
tester.sync_send();
|
|
||||||
|
|
||||||
tester.parse::<UserDetail>()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn valid_email() -> String { "annie@appflowy.io".to_string() }
|
pub(crate) fn valid_email() -> String { "annie@appflowy.io".to_string() }
|
||||||
|
|
||||||
pub(crate) fn valid_password() -> String { "HelloWorld!123".to_string() }
|
pub(crate) fn valid_password() -> String { "HelloWorld!123".to_string() }
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
mod builder;
|
pub mod builder;
|
||||||
mod helper;
|
mod helper;
|
||||||
mod tester;
|
mod tester;
|
||||||
|
|
||||||
use crate::helper::root_dir;
|
use crate::helper::root_dir;
|
||||||
use flowy_sdk::FlowySDK;
|
use flowy_sdk::FlowySDK;
|
||||||
use std::{sync::Once, thread};
|
use std::sync::Once;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::{builder::TestBuilder, tester::Tester};
|
pub use crate::{
|
||||||
|
builder::{TestBuilder, *},
|
||||||
|
helper::*,
|
||||||
|
tester::Tester,
|
||||||
|
};
|
||||||
pub use flowy_dispatch::prelude::*;
|
pub use flowy_dispatch::prelude::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
use crate::init_sdk;
|
use crate::{
|
||||||
|
helper::{valid_email, valid_password},
|
||||||
|
init_sdk,
|
||||||
|
};
|
||||||
use flowy_dispatch::prelude::*;
|
use flowy_dispatch::prelude::*;
|
||||||
pub use flowy_sdk::*;
|
pub use flowy_sdk::*;
|
||||||
use flowy_user::prelude::*;
|
use flowy_user::{
|
||||||
|
errors::UserError,
|
||||||
|
event::UserEvent::{SignIn, SignOut},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
use std::{
|
use std::{
|
||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
@ -89,32 +96,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RandomUserTester<Error> {
|
|
||||||
context: TesterContext,
|
|
||||||
err_phantom: PhantomData<Error>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Error> RandomUserTester<Error>
|
|
||||||
where
|
|
||||||
Error: FromBytes + Debug,
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
context: TesterContext::default(),
|
|
||||||
err_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Error> TesterTrait for RandomUserTester<Error>
|
|
||||||
where
|
|
||||||
Error: FromBytes + Debug,
|
|
||||||
{
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn context(&mut self) -> &mut TesterContext { &mut self.context }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TesterContext {
|
pub struct TesterContext {
|
||||||
request: Option<ModuleRequest>,
|
request: Option<ModuleRequest>,
|
||||||
status_code: StatusCode,
|
status_code: StatusCode,
|
||||||
@ -140,12 +121,20 @@ pub trait TesterTrait {
|
|||||||
|
|
||||||
fn assert_success(&mut self) { self.context().status_code = StatusCode::Ok; }
|
fn assert_success(&mut self) { self.context().status_code = StatusCode::Ok; }
|
||||||
|
|
||||||
|
fn set_event<E>(&mut self, event: E)
|
||||||
|
where
|
||||||
|
E: Eq + Hash + Debug + Clone + Display,
|
||||||
|
{
|
||||||
|
init_sdk();
|
||||||
|
self.context().request = Some(ModuleRequest::new(event));
|
||||||
|
}
|
||||||
|
|
||||||
fn set_payload<P>(&mut self, payload: P)
|
fn set_payload<P>(&mut self, payload: P)
|
||||||
where
|
where
|
||||||
P: ToBytes,
|
P: ToBytes,
|
||||||
{
|
{
|
||||||
let bytes = payload.into_bytes().unwrap();
|
let bytes = payload.into_bytes().unwrap();
|
||||||
let mut module_request = self.context().request.take().unwrap();
|
let module_request = self.context().request.take().unwrap();
|
||||||
self.context().request = Some(module_request.payload(bytes));
|
self.context().request = Some(module_request.payload(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,4 +162,23 @@ pub trait TesterTrait {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn login(&self) -> UserDetail {
|
||||||
|
init_sdk();
|
||||||
|
let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut));
|
||||||
|
let request = SignInRequest {
|
||||||
|
email: valid_email(),
|
||||||
|
password: valid_password(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut tester = Tester::<UserError>::new(SignIn);
|
||||||
|
tester.set_request(request);
|
||||||
|
tester.sync_send();
|
||||||
|
tester.parse::<UserDetail>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn logout(&self) {
|
||||||
|
init_sdk();
|
||||||
|
let _ = EventDispatch::sync_send(ModuleRequest::new(SignOut));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
use flowy_test::prelude::TestBuilder;
|
pub use flowy_test::builder::UserTestBuilder;
|
||||||
use flowy_user::errors::UserError;
|
|
||||||
|
|
||||||
pub type UserTestBuilder = TestBuilder<UserError>;
|
|
||||||
|
|
||||||
pub(crate) fn invalid_email_test_case() -> Vec<String> {
|
pub(crate) fn invalid_email_test_case() -> Vec<String> {
|
||||||
// https://gist.github.com/cjaoude/fd9910626629b53c4d25
|
// https://gist.github.com/cjaoude/fd9910626629b53c4d25
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::helper::*;
|
use crate::helper::*;
|
||||||
|
|
||||||
use flowy_user::{errors::UserErrorCode, event::UserEvent::*, prelude::*};
|
use flowy_user::{errors::UserErrorCode, event::UserEvent::*, prelude::*};
|
||||||
use serial_test::*;
|
use serial_test::*;
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::helper::*;
|
use crate::helper::*;
|
||||||
|
|
||||||
use flowy_user::{errors::*, event::UserEvent::*, prelude::*};
|
use flowy_user::{errors::*, event::UserEvent::*, prelude::*};
|
||||||
use serial_test::*;
|
use serial_test::*;
|
||||||
|
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
use flowy_test::prelude::TestBuilder;
|
pub use flowy_test::builder::WorkspaceTestBuilder;
|
||||||
use flowy_workspace::errors::WorkspaceError;
|
|
||||||
|
|
||||||
pub type WorkspaceTestBuilder = TestBuilder<WorkspaceError>;
|
|
||||||
|
|
||||||
pub(crate) fn invalid_workspace_name_test_case() -> Vec<String> {
|
pub(crate) fn invalid_workspace_name_test_case() -> Vec<String> {
|
||||||
vec!["", "1234".repeat(100).as_str()]
|
vec!["", "1234".repeat(100).as_str()]
|
||||||
|
Loading…
Reference in New Issue
Block a user