mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge pull request #1180 from AppFlowy-IO/refactor/text_type_option_test
refactor: text type option test
This commit is contained in:
commit
e44b0a4bb8
@ -210,7 +210,7 @@ impl ViewController {
|
|||||||
let index = views
|
let index = views
|
||||||
.iter()
|
.iter()
|
||||||
.position(|view| view.id == view_id)
|
.position(|view| view.id == view_id)
|
||||||
.and_then(|index| Some(index as i32));
|
.map(|index| index as i32);
|
||||||
Ok(DeletedViewPB {
|
Ok(DeletedViewPB {
|
||||||
view_id: view_id.clone(),
|
view_id: view_id.clone(),
|
||||||
index,
|
index,
|
||||||
|
@ -29,9 +29,16 @@ pub trait CellDisplayable<CD> {
|
|||||||
// CD: Short for CellData. This type is the type return by apply_changeset function.
|
// CD: Short for CellData. This type is the type return by apply_changeset function.
|
||||||
// CS: Short for Changeset. Parse the string into specific Changeset type.
|
// CS: Short for Changeset. Parse the string into specific Changeset type.
|
||||||
pub trait CellDataOperation<CD, CS> {
|
pub trait CellDataOperation<CD, CS> {
|
||||||
/// The cell_data is able to parse into the specific data if CD impl the FromCellData trait.
|
/// Decode the cell data into `CD` that is certain type of data.
|
||||||
/// For example:
|
///
|
||||||
/// URLCellData, DateCellData. etc.
|
/// Each `CD` type represents as a specific field type data. For example:
|
||||||
|
/// FieldType::URL => URLCellData
|
||||||
|
/// FieldType::Date=> DateCellData
|
||||||
|
///
|
||||||
|
/// `decoded_field_type`: the field type of the cell data
|
||||||
|
///
|
||||||
|
/// Returns the error if the cell data can't be parsed into `CD`.
|
||||||
|
///
|
||||||
fn decode_cell_data(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: CellData<CD>,
|
cell_data: CellData<CD>,
|
||||||
@ -82,7 +89,7 @@ pub fn decode_any_cell_data<T: TryInto<AnyCellData, Error = FlowyError> + Debug>
|
|||||||
Ok(any_cell_data) => {
|
Ok(any_cell_data) => {
|
||||||
let AnyCellData { data, field_type } = any_cell_data;
|
let AnyCellData { data, field_type } = any_cell_data;
|
||||||
let to_field_type = field_rev.ty.into();
|
let to_field_type = field_rev.ty.into();
|
||||||
match try_decode_cell_data(data.into(), field_rev, &field_type, &to_field_type) {
|
match try_decode_cell_data(data.into(), &field_type, &to_field_type, field_rev) {
|
||||||
Ok(cell_bytes) => cell_bytes,
|
Ok(cell_bytes) => cell_bytes,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!("Decode cell data failed, {:?}", e);
|
tracing::error!("Decode cell data failed, {:?}", e);
|
||||||
@ -99,37 +106,42 @@ pub fn decode_any_cell_data<T: TryInto<AnyCellData, Error = FlowyError> + Debug>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Use the `to_field_type`'s TypeOption to parse the cell data into `from_field_type`'s data.
|
||||||
|
///
|
||||||
|
/// Each `FieldType` has its corresponding `TypeOption` that implements the `CellDisplayable`
|
||||||
|
/// and `CellDataOperation` traits.
|
||||||
|
///
|
||||||
pub fn try_decode_cell_data(
|
pub fn try_decode_cell_data(
|
||||||
cell_data: CellData<String>,
|
cell_data: CellData<String>,
|
||||||
|
from_field_type: &FieldType,
|
||||||
|
to_field_type: &FieldType,
|
||||||
field_rev: &FieldRevision,
|
field_rev: &FieldRevision,
|
||||||
s_field_type: &FieldType,
|
|
||||||
t_field_type: &FieldType,
|
|
||||||
) -> FlowyResult<CellBytes> {
|
) -> FlowyResult<CellBytes> {
|
||||||
let cell_data = cell_data.try_into_inner()?;
|
let cell_data = cell_data.try_into_inner()?;
|
||||||
let get_cell_data = || {
|
let get_cell_data = || {
|
||||||
let field_type: FieldTypeRevision = t_field_type.into();
|
let field_type: FieldTypeRevision = to_field_type.into();
|
||||||
let data = match t_field_type {
|
let data = match to_field_type {
|
||||||
FieldType::RichText => field_rev
|
FieldType::RichText => field_rev
|
||||||
.get_type_option::<RichTextTypeOptionPB>(field_type)?
|
.get_type_option::<RichTextTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
|
||||||
FieldType::Number => field_rev
|
FieldType::Number => field_rev
|
||||||
.get_type_option::<NumberTypeOptionPB>(field_type)?
|
.get_type_option::<NumberTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
|
||||||
FieldType::DateTime => field_rev
|
FieldType::DateTime => field_rev
|
||||||
.get_type_option::<DateTypeOptionPB>(field_type)?
|
.get_type_option::<DateTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
|
||||||
FieldType::SingleSelect => field_rev
|
FieldType::SingleSelect => field_rev
|
||||||
.get_type_option::<SingleSelectTypeOptionPB>(field_type)?
|
.get_type_option::<SingleSelectTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
|
||||||
FieldType::MultiSelect => field_rev
|
FieldType::MultiSelect => field_rev
|
||||||
.get_type_option::<MultiSelectTypeOptionPB>(field_type)?
|
.get_type_option::<MultiSelectTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
|
||||||
FieldType::Checkbox => field_rev
|
FieldType::Checkbox => field_rev
|
||||||
.get_type_option::<CheckboxTypeOptionPB>(field_type)?
|
.get_type_option::<CheckboxTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
|
||||||
FieldType::URL => field_rev
|
FieldType::URL => field_rev
|
||||||
.get_type_option::<URLTypeOptionPB>(field_type)?
|
.get_type_option::<URLTypeOptionPB>(field_type)?
|
||||||
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
|
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
|
||||||
};
|
};
|
||||||
Some(data)
|
Some(data)
|
||||||
};
|
};
|
||||||
@ -224,6 +236,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<usize> for CellData<String> {
|
||||||
|
fn from(n: usize) -> Self {
|
||||||
|
CellData(Some(n.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> std::convert::From<T> for CellData<T> {
|
impl<T> std::convert::From<T> for CellData<T> {
|
||||||
fn from(val: T) -> Self {
|
fn from(val: T) -> Self {
|
||||||
CellData(Some(val))
|
CellData(Some(val))
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
#![allow(clippy::module_inception)]
|
#![allow(clippy::module_inception)]
|
||||||
|
mod text_tests;
|
||||||
mod text_type_option;
|
mod text_type_option;
|
||||||
|
|
||||||
pub use text_type_option::*;
|
pub use text_type_option::*;
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::entities::FieldType;
|
||||||
|
use crate::services::cell::CellDataOperation;
|
||||||
|
use crate::services::field::FieldBuilder;
|
||||||
|
use crate::services::field::*;
|
||||||
|
|
||||||
|
// Test parser the cell data which field's type is FieldType::Date to cell data
|
||||||
|
// which field's type is FieldType::Text
|
||||||
|
#[test]
|
||||||
|
fn date_type_to_text_type() {
|
||||||
|
let type_option = RichTextTypeOptionPB::default();
|
||||||
|
let field_type = FieldType::DateTime;
|
||||||
|
let field_rev = FieldBuilder::from_field_type(&field_type).build();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
type_option
|
||||||
|
.decode_cell_data(1647251762.into(), &field_type, &field_rev)
|
||||||
|
.unwrap()
|
||||||
|
.parser::<DateCellDataParser>()
|
||||||
|
.unwrap()
|
||||||
|
.date,
|
||||||
|
"Mar 14,2022".to_owned()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test parser the cell data which field's type is FieldType::SingleSelect to cell data
|
||||||
|
// which field's type is FieldType::Text
|
||||||
|
#[test]
|
||||||
|
fn single_select_to_text_type() {
|
||||||
|
let type_option = RichTextTypeOptionPB::default();
|
||||||
|
|
||||||
|
let field_type = FieldType::SingleSelect;
|
||||||
|
let done_option = SelectOptionPB::new("Done");
|
||||||
|
let option_id = done_option.id.clone();
|
||||||
|
let single_select = SingleSelectTypeOptionBuilder::default().add_option(done_option.clone());
|
||||||
|
let field_rev = FieldBuilder::new(single_select).build();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
type_option
|
||||||
|
.decode_cell_data(option_id.into(), &field_type, &field_rev)
|
||||||
|
.unwrap()
|
||||||
|
.parser::<SelectOptionCellDataParser>()
|
||||||
|
.unwrap()
|
||||||
|
.select_options,
|
||||||
|
vec![done_option],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -58,7 +58,7 @@ impl CellDataOperation<String, String> for RichTextTypeOptionPB {
|
|||||||
|| decoded_field_type.is_multi_select()
|
|| decoded_field_type.is_multi_select()
|
||||||
|| decoded_field_type.is_number()
|
|| decoded_field_type.is_number()
|
||||||
{
|
{
|
||||||
try_decode_cell_data(cell_data, field_rev, decoded_field_type, decoded_field_type)
|
try_decode_cell_data(cell_data, decoded_field_type, decoded_field_type, field_rev)
|
||||||
} else {
|
} else {
|
||||||
self.display_data(cell_data, decoded_field_type, field_rev)
|
self.display_data(cell_data, decoded_field_type, field_rev)
|
||||||
}
|
}
|
||||||
@ -104,85 +104,3 @@ impl CellBytesParser for TextCellDataParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::entities::FieldType;
|
|
||||||
use crate::services::cell::CellDataOperation;
|
|
||||||
|
|
||||||
use crate::services::field::FieldBuilder;
|
|
||||||
use crate::services::field::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn text_description_test() {
|
|
||||||
let type_option = RichTextTypeOptionPB::default();
|
|
||||||
|
|
||||||
// date
|
|
||||||
let field_type = FieldType::DateTime;
|
|
||||||
let date_time_field_rev = FieldBuilder::from_field_type(&field_type).build();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
type_option
|
|
||||||
.decode_cell_data(1647251762.to_string().into(), &field_type, &date_time_field_rev)
|
|
||||||
.unwrap()
|
|
||||||
.parser::<DateCellDataParser>()
|
|
||||||
.unwrap()
|
|
||||||
.date,
|
|
||||||
"Mar 14,2022".to_owned()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Single select
|
|
||||||
let done_option = SelectOptionPB::new("Done");
|
|
||||||
let done_option_id = done_option.id.clone();
|
|
||||||
let single_select = SingleSelectTypeOptionBuilder::default().add_option(done_option.clone());
|
|
||||||
let single_select_field_rev = FieldBuilder::new(single_select).build();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
type_option
|
|
||||||
.decode_cell_data(
|
|
||||||
done_option_id.into(),
|
|
||||||
&FieldType::SingleSelect,
|
|
||||||
&single_select_field_rev
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.parser::<SelectOptionCellDataParser>()
|
|
||||||
.unwrap()
|
|
||||||
.select_options,
|
|
||||||
vec![done_option],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Multiple select
|
|
||||||
let google_option = SelectOptionPB::new("Google");
|
|
||||||
let facebook_option = SelectOptionPB::new("Facebook");
|
|
||||||
let ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR);
|
|
||||||
let cell_data_changeset = SelectOptionCellChangeset::from_insert(&ids).to_str();
|
|
||||||
let multi_select = MultiSelectTypeOptionBuilder::default()
|
|
||||||
.add_option(google_option.clone())
|
|
||||||
.add_option(facebook_option.clone());
|
|
||||||
let multi_select_field_rev = FieldBuilder::new(multi_select).build();
|
|
||||||
let multi_type_option = MultiSelectTypeOptionPB::from(&multi_select_field_rev);
|
|
||||||
let cell_data = multi_type_option
|
|
||||||
.apply_changeset(cell_data_changeset.into(), None)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
type_option
|
|
||||||
.decode_cell_data(cell_data.into(), &FieldType::MultiSelect, &multi_select_field_rev)
|
|
||||||
.unwrap()
|
|
||||||
.parser::<SelectOptionCellDataParser>()
|
|
||||||
.unwrap()
|
|
||||||
.select_options,
|
|
||||||
vec![google_option, facebook_option]
|
|
||||||
);
|
|
||||||
|
|
||||||
//Number
|
|
||||||
let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD);
|
|
||||||
let number_field_rev = FieldBuilder::new(number).build();
|
|
||||||
assert_eq!(
|
|
||||||
type_option
|
|
||||||
.decode_cell_data("18443".to_owned().into(), &FieldType::Number, &number_field_rev)
|
|
||||||
.unwrap()
|
|
||||||
.to_string(),
|
|
||||||
"$18,443".to_owned()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user