mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: unit test for cell content
This commit is contained in:
parent
f10e324b73
commit
602aab45e2
@ -1,9 +1,11 @@
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::cell::{CellData, FromCellString};
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::revision::CellRevision;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
|
||||
/// AnyCellData is a generic CellData, you can parse the cell_data according to the field_type.
|
||||
/// When the type of field is changed, it's different from the field_type of AnyCellData.
|
||||
/// So it will return an empty data. You could check the CellDataOperation trait for more information.
|
||||
@ -46,6 +48,15 @@ impl std::convert::TryFrom<CellRevision> for AnyCellData {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::convert::From<AnyCellData> for CellData<T>
|
||||
where
|
||||
T: FromCellString,
|
||||
{
|
||||
fn from(any_call_data: AnyCellData) -> Self {
|
||||
CellData::from(any_call_data.data)
|
||||
}
|
||||
}
|
||||
|
||||
impl AnyCellData {
|
||||
pub fn new(content: String, field_type: FieldType) -> Self {
|
||||
AnyCellData {
|
||||
@ -102,6 +113,11 @@ impl AnyCellData {
|
||||
#[derive(Default)]
|
||||
pub struct CellBytes(pub Bytes);
|
||||
|
||||
pub trait CellBytesParser {
|
||||
type Object;
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object>;
|
||||
}
|
||||
|
||||
impl CellBytes {
|
||||
pub fn new<T: AsRef<[u8]>>(data: T) -> Self {
|
||||
let bytes = Bytes::from(data.as_ref().to_vec());
|
||||
@ -116,12 +132,19 @@ impl CellBytes {
|
||||
Ok(Self(bytes))
|
||||
}
|
||||
|
||||
pub fn parse<'a, T: TryFrom<&'a [u8]>>(&'a self) -> FlowyResult<T>
|
||||
pub fn with_parser<P>(&self, parser: P) -> FlowyResult<P::Object>
|
||||
where
|
||||
<T as TryFrom<&'a [u8]>>::Error: std::fmt::Debug,
|
||||
P: CellBytesParser,
|
||||
{
|
||||
T::try_from(self.0.as_ref()).map_err(internal_error)
|
||||
parser.parse(&self.0)
|
||||
}
|
||||
|
||||
// pub fn parse<'a, T: TryFrom<&'a [u8]>>(&'a self) -> FlowyResult<T>
|
||||
// where
|
||||
// <T as TryFrom<&'a [u8]>>::Error: std::fmt::Debug,
|
||||
// {
|
||||
// T::try_from(self.0.as_ref()).map_err(internal_error)
|
||||
// }
|
||||
}
|
||||
|
||||
impl ToString for CellBytes {
|
||||
|
@ -163,9 +163,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<String> for CellData<String> {
|
||||
fn from(s: String) -> Self {
|
||||
CellData(Some(s))
|
||||
impl<T> std::convert::From<T> for CellData<T> {
|
||||
fn from(val: T) -> Self {
|
||||
CellData(Some(val))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CheckboxTypeOptionBuilder(CheckboxTypeOption);
|
||||
@ -69,7 +70,7 @@ impl CellDataOperation<CheckboxCellData, String> for CheckboxTypeOption {
|
||||
_cell_rev: Option<CellRevision>,
|
||||
) -> Result<String, FlowyError> {
|
||||
let changeset = changeset.try_into_inner()?;
|
||||
let cell_data = CheckboxCellData::from_str(&changeset);
|
||||
let cell_data = CheckboxCellData::from_str(&changeset)?;
|
||||
Ok(cell_data.to_string())
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::services::cell::{AnyCellData, FromCellString};
|
||||
use crate::services::cell::{CellBytesParser, FromCellString};
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub const YES: &str = "Yes";
|
||||
pub const NO: &str = "No";
|
||||
@ -7,7 +9,21 @@ pub const NO: &str = "No";
|
||||
pub struct CheckboxCellData(pub String);
|
||||
|
||||
impl CheckboxCellData {
|
||||
pub fn from_str(s: &str) -> Self {
|
||||
pub fn is_check(&self) -> bool {
|
||||
self.0 == YES
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for CheckboxCellData {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for CheckboxCellData {
|
||||
type Err = FlowyError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let lower_case_str: &str = &s.to_lowercase();
|
||||
let val = match lower_case_str {
|
||||
"1" => Some(true),
|
||||
@ -20,29 +36,11 @@ impl CheckboxCellData {
|
||||
};
|
||||
|
||||
match val {
|
||||
Some(true) => Self(YES.to_string()),
|
||||
Some(false) => Self(NO.to_string()),
|
||||
None => Self("".to_string()),
|
||||
Some(true) => Ok(Self(YES.to_string())),
|
||||
Some(false) => Ok(Self(NO.to_string())),
|
||||
None => Ok(Self("".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_check(&self) -> bool {
|
||||
&self.0 == YES
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for CheckboxCellData {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<AnyCellData> for CheckboxCellData {
|
||||
type Error = FlowyError;
|
||||
|
||||
fn try_from(value: AnyCellData) -> Result<Self, Self::Error> {
|
||||
Ok(Self::from_str(&value.data))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromCellString for CheckboxCellData {
|
||||
@ -50,7 +48,7 @@ impl FromCellString for CheckboxCellData {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Ok(Self::from_str(s))
|
||||
Self::from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,3 +57,13 @@ impl ToString for CheckboxCellData {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
pub struct CheckboxCellDataParser;
|
||||
impl CellBytesParser for CheckboxCellDataParser {
|
||||
type Object = CheckboxCellData;
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
match String::from_utf8(bytes.to_vec()) {
|
||||
Ok(s) => CheckboxCellData::from_str(&s),
|
||||
Err(_) => Ok(CheckboxCellData("".to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
mod checkbox_option;
|
||||
mod checkbox_option_entities;
|
||||
mod tests;
|
||||
mod checkbox_tests;
|
||||
|
||||
pub use checkbox_option::*;
|
||||
pub use checkbox_option_entities::*;
|
||||
|
@ -1,22 +1,17 @@
|
||||
use crate::entities::{FieldType};
|
||||
|
||||
use crate::entities::FieldType;
|
||||
use crate::impl_type_option;
|
||||
use crate::services::cell::{
|
||||
AnyCellData, CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable, FromCellChangeset,
|
||||
FromCellString,
|
||||
};
|
||||
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
|
||||
use crate::services::field::{
|
||||
BoxTypeOptionBuilder, DateCellChangeset, DateCellData, DateFormat, DateTimestamp, TimeFormat, TypeOptionBuilder,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use chrono::format::strftime::StrftimeItems;
|
||||
use chrono::{NaiveDateTime, Timelike};
|
||||
use flowy_derive::{ProtoBuf};
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
// Date
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
|
||||
pub struct DateTypeOption {
|
||||
@ -129,7 +124,8 @@ impl CellDisplayable<DateTimestamp> for DateTypeOption {
|
||||
_field_rev: &FieldRevision,
|
||||
) -> FlowyResult<CellBytes> {
|
||||
let timestamp = cell_data.try_into_inner()?;
|
||||
CellBytes::from(self.today_desc_from_timestamp(timestamp))
|
||||
let date_cell_data = self.today_desc_from_timestamp(timestamp);
|
||||
CellBytes::from(date_cell_data)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::entities::CellChangeset;
|
||||
use crate::entities::{CellIdentifier, CellIdentifierPayload};
|
||||
use crate::services::cell::{AnyCellData, FromCellChangeset, FromCellString};
|
||||
use crate::services::cell::{CellBytesParser, FromCellChangeset, FromCellString};
|
||||
use bytes::Bytes;
|
||||
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
||||
@ -117,12 +118,6 @@ impl FromCellString for DateTimestamp {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<AnyCellData> for DateTimestamp {
|
||||
fn from(data: AnyCellData) -> Self {
|
||||
let num = data.data.parse::<i64>().unwrap_or(0);
|
||||
DateTimestamp(num)
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug, Copy, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)]
|
||||
pub enum DateFormat {
|
||||
Local = 0,
|
||||
@ -204,3 +199,12 @@ impl std::default::Default for TimeFormat {
|
||||
TimeFormat::TwentyFourHour
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DateCellDataParser();
|
||||
impl CellBytesParser for DateCellDataParser {
|
||||
type Object = DateCellData;
|
||||
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
DateCellData::try_from(bytes.as_ref()).map_err(internal_error)
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
mod tests {
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::cell::{CellDataChangeset, CellDataOperation};
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::field::{DateCellChangeset, DateCellData, DateFormat, DateTypeOption, TimeFormat};
|
||||
use crate::services::field::*;
|
||||
// use crate::services::field::{DateCellChangeset, DateCellData, DateFormat, DateTypeOption, TimeFormat};
|
||||
use flowy_grid_data_model::revision::FieldRevision;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
@ -260,7 +260,7 @@ mod tests {
|
||||
let decoded_data = type_option
|
||||
.decode_cell_data(encoded_data.into(), &FieldType::DateTime, field_rev)
|
||||
.unwrap()
|
||||
.parse::<DateCellData>()
|
||||
.with_parser(DateCellDataParser())
|
||||
.unwrap();
|
||||
|
||||
if type_option.include_time {
|
@ -1,6 +1,6 @@
|
||||
mod date_option;
|
||||
mod date_option_entities;
|
||||
mod tests;
|
||||
mod date_tests;
|
||||
|
||||
pub use date_option::*;
|
||||
pub use date_option_entities::*;
|
||||
|
@ -2,7 +2,7 @@
|
||||
mod format;
|
||||
mod number_option;
|
||||
mod number_option_entities;
|
||||
mod tests;
|
||||
mod number_tests;
|
||||
|
||||
pub use format::*;
|
||||
pub use number_option::*;
|
||||
|
@ -1,8 +1,6 @@
|
||||
use crate::impl_type_option;
|
||||
|
||||
use crate::entities::FieldType;
|
||||
use crate::impl_type_option;
|
||||
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation};
|
||||
use crate::services::field::number_currency::Currency;
|
||||
use crate::services::field::type_options::number_type_option::format::*;
|
||||
use crate::services::field::{BoxTypeOptionBuilder, NumberCellData, TypeOptionBuilder};
|
||||
use bytes::Bytes;
|
||||
@ -11,7 +9,7 @@ use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
|
||||
use rust_decimal::Decimal;
|
||||
use rusty_money::Money;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
use crate::services::cell::CellBytesParser;
|
||||
use crate::services::field::number_currency::Currency;
|
||||
use crate::services::field::{strip_currency_symbol, NumberFormat, STRIP_SYMBOL};
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use bytes::Bytes;
|
||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
||||
use rust_decimal::Decimal;
|
||||
use rusty_money::Money;
|
||||
use std::str::FromStr;
|
||||
@ -68,17 +70,17 @@ impl NumberCellData {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for NumberCellData {
|
||||
type Err = rust_decimal::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s.is_empty() {
|
||||
return Ok(Self::default());
|
||||
}
|
||||
let decimal = Decimal::from_str(s)?;
|
||||
Ok(Self::from_decimal(decimal))
|
||||
}
|
||||
}
|
||||
// impl FromStr for NumberCellData {
|
||||
// type Err = FlowyError;
|
||||
//
|
||||
// fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
// if s.is_empty() {
|
||||
// return Ok(Self::default());
|
||||
// }
|
||||
// let decimal = Decimal::from_str(s).map_err(internal_error)?;
|
||||
// Ok(Self::from_decimal(decimal))
|
||||
// }
|
||||
// }
|
||||
|
||||
impl ToString for NumberCellData {
|
||||
fn to_string(&self) -> String {
|
||||
@ -91,3 +93,13 @@ impl ToString for NumberCellData {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct NumberCellDataParser(pub NumberFormat);
|
||||
impl CellBytesParser for NumberCellDataParser {
|
||||
type Object = NumberCellData;
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
match String::from_utf8(bytes.to_vec()) {
|
||||
Ok(s) => NumberCellData::from_format_str(&s, true, &self.0),
|
||||
Err(_) => Ok(NumberCellData::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ mod tests {
|
||||
type_option
|
||||
.decode_cell_data(cell_data.into(), &field_type, field_rev)
|
||||
.unwrap()
|
||||
.parse::<SelectOptionCellData>()
|
||||
.with_parser(SelectOptionCellDataParser())
|
||||
.unwrap()
|
||||
.select_options,
|
||||
);
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::entities::{CellChangeset, CellIdentifier, CellIdentifierPayload, FieldType};
|
||||
use crate::services::cell::{AnyCellData, CellBytes, CellData, CellDisplayable, FromCellChangeset, FromCellString};
|
||||
use crate::services::cell::{CellBytes, CellBytesParser, CellData, CellDisplayable, FromCellChangeset, FromCellString};
|
||||
use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
|
||||
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
||||
use flowy_grid_data_model::parser::NotEmptyStr;
|
||||
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataEntry};
|
||||
use nanoid::nanoid;
|
||||
@ -160,20 +161,6 @@ impl SelectOptionIds {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<AnyCellData> for SelectOptionIds {
|
||||
type Error = FlowyError;
|
||||
|
||||
fn try_from(value: AnyCellData) -> Result<Self, Self::Error> {
|
||||
Ok(Self::from(value.data))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<AnyCellData> for CellData<SelectOptionIds> {
|
||||
fn from(any_cell_data: AnyCellData) -> Self {
|
||||
any_cell_data.data.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromCellString for SelectOptionIds {
|
||||
fn from_cell_str(s: &str) -> FlowyResult<Self>
|
||||
where
|
||||
@ -215,6 +202,25 @@ impl std::ops::DerefMut for SelectOptionIds {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
pub struct SelectOptionIdsParser();
|
||||
impl CellBytesParser for SelectOptionIdsParser {
|
||||
type Object = SelectOptionIds;
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
match String::from_utf8(bytes.to_vec()) {
|
||||
Ok(s) => Ok(SelectOptionIds::from(s)),
|
||||
Err(_) => Ok(SelectOptionIds::from("".to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SelectOptionCellDataParser();
|
||||
impl CellBytesParser for SelectOptionCellDataParser {
|
||||
type Object = SelectOptionCellData;
|
||||
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
SelectOptionCellData::try_from(bytes.as_ref()).map_err(internal_error)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, ProtoBuf)]
|
||||
pub struct SelectOptionCellChangesetPayload {
|
||||
|
@ -162,7 +162,7 @@ mod tests {
|
||||
type_option
|
||||
.decode_cell_data(cell_data.into(), &field_type, field_rev)
|
||||
.unwrap()
|
||||
.parse::<SelectOptionCellData>()
|
||||
.with_parser(SelectOptionCellDataParser())
|
||||
.unwrap()
|
||||
.select_options,
|
||||
);
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::entities::FieldType;
|
||||
use crate::impl_type_option;
|
||||
use crate::services::cell::{
|
||||
try_decode_cell_data, AnyCellData, CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable,
|
||||
try_decode_cell_data, CellBytes, CellBytesParser, CellData, CellDataChangeset, CellDataOperation, CellDisplayable,
|
||||
FromCellString,
|
||||
};
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||
use bytes::Bytes;
|
||||
@ -83,11 +84,23 @@ impl AsRef<str> for TextCellData {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<AnyCellData> for TextCellData {
|
||||
type Error = FlowyError;
|
||||
impl FromCellString for TextCellData {
|
||||
fn from_cell_str(s: &str) -> FlowyResult<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Ok(TextCellData(s.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
fn try_from(value: AnyCellData) -> Result<Self, Self::Error> {
|
||||
Ok(TextCellData(value.data))
|
||||
pub struct TextCellDataParser();
|
||||
impl CellBytesParser for TextCellDataParser {
|
||||
type Object = TextCellData;
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
match String::from_utf8(bytes.to_vec()) {
|
||||
Ok(s) => Ok(TextCellData(s)),
|
||||
Err(_) => Ok(TextCellData("".to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +124,7 @@ mod tests {
|
||||
type_option
|
||||
.decode_cell_data(1647251762.to_string().into(), &field_type, &date_time_field_rev)
|
||||
.unwrap()
|
||||
.parse::<DateCellData>()
|
||||
.with_parser(DateCellDataParser())
|
||||
.unwrap()
|
||||
.date,
|
||||
"Mar 14,2022".to_owned()
|
||||
@ -131,7 +144,7 @@ mod tests {
|
||||
&single_select_field_rev
|
||||
)
|
||||
.unwrap()
|
||||
.parse::<SelectOptionCellData>()
|
||||
.with_parser(SelectOptionCellDataParser())
|
||||
.unwrap()
|
||||
.select_options,
|
||||
vec![done_option],
|
||||
@ -154,7 +167,7 @@ mod tests {
|
||||
type_option
|
||||
.decode_cell_data(cell_data.into(), &FieldType::MultiSelect, &multi_select_field_rev)
|
||||
.unwrap()
|
||||
.parse::<SelectOptionCellData>()
|
||||
.with_parser(SelectOptionCellDataParser())
|
||||
.unwrap()
|
||||
.select_options,
|
||||
vec![google_option, facebook_option]
|
||||
|
@ -1,6 +1,6 @@
|
||||
mod tests;
|
||||
mod url_option;
|
||||
mod url_option_entities;
|
||||
mod url_tests;
|
||||
|
||||
pub use url_option::*;
|
||||
pub use url_option_entities::*;
|
||||
|
@ -1,13 +1,11 @@
|
||||
use crate::entities::FieldType;
|
||||
use crate::impl_type_option;
|
||||
use crate::services::cell::{
|
||||
AnyCellData, CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable, FromCellString,
|
||||
};
|
||||
use crate::services::cell::{CellBytes, CellData, CellDataChangeset, CellDataOperation, CellDisplayable};
|
||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder, URLCellData};
|
||||
use bytes::Bytes;
|
||||
use fancy_regex::Regex;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
||||
use flowy_error::{FlowyError, FlowyResult};
|
||||
use flowy_grid_data_model::revision::{CellRevision, FieldRevision, TypeOptionDataDeserializer, TypeOptionDataEntry};
|
||||
use lazy_static::lazy_static;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -64,16 +62,12 @@ impl CellDataOperation<URLCellData, String> for URLTypeOption {
|
||||
changeset: CellDataChangeset<String>,
|
||||
_cell_rev: Option<CellRevision>,
|
||||
) -> Result<String, FlowyError> {
|
||||
let changeset = changeset.try_into_inner()?;
|
||||
let content = changeset.try_into_inner()?;
|
||||
let mut url = "".to_string();
|
||||
if let Ok(Some(m)) = URL_REGEX.find(&changeset) {
|
||||
if let Ok(Some(m)) = URL_REGEX.find(&content) {
|
||||
url = auto_append_scheme(m.as_str());
|
||||
}
|
||||
URLCellData {
|
||||
url,
|
||||
content: changeset,
|
||||
}
|
||||
.to_json()
|
||||
URLCellData { url, content }.to_json()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::services::cell::{AnyCellData, FromCellString};
|
||||
use crate::services::cell::{CellBytesParser, FromCellString};
|
||||
use bytes::Bytes;
|
||||
use flowy_derive::ProtoBuf;
|
||||
use flowy_error::{internal_error, FlowyError, FlowyResult};
|
||||
use flowy_error::{internal_error, FlowyResult};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, ProtoBuf)]
|
||||
@ -25,16 +26,17 @@ impl URLCellData {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct URLCellDataParser();
|
||||
impl CellBytesParser for URLCellDataParser {
|
||||
type Object = URLCellData;
|
||||
|
||||
fn parse(&self, bytes: &Bytes) -> FlowyResult<Self::Object> {
|
||||
URLCellData::try_from(bytes.as_ref()).map_err(internal_error)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromCellString for URLCellData {
|
||||
fn from_cell_str(s: &str) -> FlowyResult<Self> {
|
||||
serde_json::from_str::<URLCellData>(s).map_err(internal_error)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::TryFrom<AnyCellData> for URLCellData {
|
||||
type Error = FlowyError;
|
||||
|
||||
fn try_from(data: AnyCellData) -> Result<Self, Self::Error> {
|
||||
serde_json::from_str::<URLCellData>(&data.data).map_err(internal_error)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
mod tests {
|
||||
use crate::entities::FieldType;
|
||||
use crate::services::cell::{CellData, CellDataOperation};
|
||||
use crate::services::field::FieldBuilder;
|
||||
use crate::services::field::{FieldBuilder, URLCellDataParser};
|
||||
use crate::services::field::{URLCellData, URLTypeOption};
|
||||
use flowy_grid_data_model::revision::FieldRevision;
|
||||
|
||||
@ -61,7 +61,7 @@ mod tests {
|
||||
type_option
|
||||
.decode_cell_data(encoded_data.into(), field_type, field_rev)
|
||||
.unwrap()
|
||||
.parse::<URLCellData>()
|
||||
.with_parser(URLCellDataParser())
|
||||
.unwrap()
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::{CheckboxCondition, GridCheckboxFilter};
|
||||
use crate::services::cell::{AnyCellData, CellFilterOperation};
|
||||
use crate::services::cell::{AnyCellData, CellData, CellFilterOperation};
|
||||
use crate::services::field::{CheckboxCellData, CheckboxTypeOption};
|
||||
use flowy_error::FlowyResult;
|
||||
|
||||
@ -18,7 +18,8 @@ impl CellFilterOperation<GridCheckboxFilter> for CheckboxTypeOption {
|
||||
if !any_cell_data.is_checkbox() {
|
||||
return Ok(true);
|
||||
}
|
||||
let checkbox_cell_data: CheckboxCellData = any_cell_data.try_into()?;
|
||||
let cell_data: CellData<CheckboxCellData> = any_cell_data.into();
|
||||
let checkbox_cell_data = cell_data.try_into_inner()?;
|
||||
Ok(filter.is_visible(&checkbox_cell_data))
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::{DateFilterCondition, GridDateFilter};
|
||||
use crate::services::cell::{AnyCellData, CellFilterOperation};
|
||||
use crate::services::cell::{AnyCellData, CellData, CellFilterOperation};
|
||||
use crate::services::field::{DateTimestamp, DateTypeOption};
|
||||
use flowy_error::FlowyResult;
|
||||
|
||||
@ -34,7 +34,8 @@ impl CellFilterOperation<GridDateFilter> for DateTypeOption {
|
||||
if !any_cell_data.is_date() {
|
||||
return Ok(true);
|
||||
}
|
||||
let timestamp: DateTimestamp = any_cell_data.into();
|
||||
let cell_data: CellData<DateTimestamp> = any_cell_data.into();
|
||||
let timestamp = cell_data.try_into_inner()?;
|
||||
Ok(filter.is_visible(timestamp))
|
||||
}
|
||||
}
|
||||
|
@ -47,9 +47,7 @@ impl CellFilterOperation<GridNumberFilter> for NumberTypeOption {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::entities::{GridNumberFilter, NumberFilterCondition};
|
||||
|
||||
use crate::services::field::{NumberCellData, NumberFormat};
|
||||
use std::str::FromStr;
|
||||
#[test]
|
||||
fn number_filter_equal_test() {
|
||||
let number_filter = GridNumberFilter {
|
||||
@ -58,7 +56,7 @@ mod tests {
|
||||
};
|
||||
|
||||
for (num_str, visible) in [("123", true), ("1234", false), ("", false)] {
|
||||
let data = NumberCellData::from_str(num_str).unwrap();
|
||||
let data = NumberCellData::from_format_str(num_str, true, &NumberFormat::Num).unwrap();
|
||||
assert_eq!(number_filter.is_visible(&data), visible);
|
||||
}
|
||||
|
||||
@ -75,7 +73,7 @@ mod tests {
|
||||
content: Some("12".to_owned()),
|
||||
};
|
||||
for (num_str, visible) in [("123", true), ("10", false), ("30", true), ("", false)] {
|
||||
let data = NumberCellData::from_str(num_str).unwrap();
|
||||
let data = NumberCellData::from_format_str(num_str, true, &NumberFormat::Num).unwrap();
|
||||
assert_eq!(number_filter.is_visible(&data), visible);
|
||||
}
|
||||
}
|
||||
@ -87,7 +85,7 @@ mod tests {
|
||||
content: Some("100".to_owned()),
|
||||
};
|
||||
for (num_str, visible) in [("12", true), ("1234", false), ("30", true), ("", true)] {
|
||||
let data = NumberCellData::from_str(num_str).unwrap();
|
||||
let data = NumberCellData::from_format_str(num_str, true, &NumberFormat::Num).unwrap();
|
||||
assert_eq!(number_filter.is_visible(&data), visible);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::{GridTextFilter, TextFilterCondition};
|
||||
use crate::services::cell::{AnyCellData, CellFilterOperation};
|
||||
use crate::services::cell::{AnyCellData, CellData, CellFilterOperation};
|
||||
use crate::services::field::{RichTextTypeOption, TextCellData};
|
||||
use flowy_error::FlowyResult;
|
||||
|
||||
@ -30,7 +30,8 @@ impl CellFilterOperation<GridTextFilter> for RichTextTypeOption {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let text_cell_data: TextCellData = any_cell_data.try_into()?;
|
||||
let cell_data: CellData<TextCellData> = any_cell_data.into();
|
||||
let text_cell_data = cell_data.try_into_inner()?;
|
||||
Ok(filter.is_visible(text_cell_data))
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::entities::GridTextFilter;
|
||||
use crate::services::cell::{AnyCellData, CellFilterOperation};
|
||||
use crate::services::cell::{AnyCellData, CellData, CellFilterOperation};
|
||||
use crate::services::field::{TextCellData, URLTypeOption};
|
||||
use flowy_error::FlowyResult;
|
||||
|
||||
@ -9,7 +9,8 @@ impl CellFilterOperation<GridTextFilter> for URLTypeOption {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let text_cell_data: TextCellData = any_cell_data.try_into()?;
|
||||
let cell_data: CellData<TextCellData> = any_cell_data.into();
|
||||
let text_cell_data = cell_data.try_into_inner()?;
|
||||
Ok(filter.is_visible(&text_cell_data))
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use crate::entities::CellIdentifier;
|
||||
use crate::entities::*;
|
||||
use crate::manager::{GridTaskSchedulerRwLock, GridUser};
|
||||
use crate::services::block_manager::GridBlockManager;
|
||||
use crate::services::cell::{apply_cell_data_changeset, decode_any_cell_data};
|
||||
use crate::services::cell::{apply_cell_data_changeset, decode_any_cell_data, CellBytes};
|
||||
use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder};
|
||||
use crate::services::filter::{GridFilterChangeset, GridFilterService};
|
||||
use crate::services::persistence::block_index::BlockIndexCache;
|
||||
@ -340,16 +340,16 @@ impl GridRevisionEditor {
|
||||
}
|
||||
|
||||
pub async fn get_cell(&self, params: &CellIdentifier) -> Option<Cell> {
|
||||
let cell_bytes = self.get_cell_bytes(params).await?;
|
||||
Some(Cell::new(¶ms.field_id, cell_bytes.to_vec()))
|
||||
}
|
||||
|
||||
pub async fn get_cell_bytes(&self, params: &CellIdentifier) -> Option<CellBytes> {
|
||||
let field_rev = self.get_field_rev(¶ms.field_id).await?;
|
||||
let row_rev = self.block_manager.get_row_rev(¶ms.row_id).await.ok()??;
|
||||
|
||||
let cell_rev = row_rev.cells.get(¶ms.field_id)?.clone();
|
||||
let data = decode_any_cell_data(cell_rev.data, &field_rev).to_vec();
|
||||
Some(Cell::new(¶ms.field_id, data))
|
||||
}
|
||||
|
||||
pub async fn get_cell_display(&self, _params: &CellIdentifier) -> Option<String> {
|
||||
todo!()
|
||||
Some(decode_any_cell_data(cell_rev.data, &field_rev))
|
||||
}
|
||||
|
||||
pub async fn get_cell_rev(&self, row_id: &str, field_id: &str) -> FlowyResult<Option<CellRevision>> {
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::grid::block_test::script::GridRowTest;
|
||||
use crate::grid::block_test::script::RowScript::*;
|
||||
use flowy_grid::entities::FieldType;
|
||||
use flowy_grid_data_model::revision::RowMetaChangeset;
|
||||
|
||||
#[tokio::test]
|
||||
@ -67,15 +68,48 @@ async fn grid_row_add_cells_test() {
|
||||
let mut test = GridRowTest::new().await;
|
||||
let mut builder = test.row_builder();
|
||||
|
||||
builder.insert_text_cell("hello world");
|
||||
builder.insert_number_cell("18,443");
|
||||
builder.insert_date_cell("1647251762");
|
||||
builder.insert_single_select_cell(|options| options.first().unwrap());
|
||||
let text_field_id = builder.insert_text_cell("hello world");
|
||||
let number_field_id = builder.insert_number_cell("18,443");
|
||||
let date_field_id = builder.insert_date_cell("1647251762");
|
||||
let single_select_field_id = builder.insert_single_select_cell(|options| options.first().unwrap());
|
||||
builder.insert_multi_select_cell(|options| options);
|
||||
builder.insert_checkbox_cell("false");
|
||||
builder.insert_url_cell("1");
|
||||
let url_field_id = builder.insert_url_cell("https://appflowy.io");
|
||||
|
||||
let row_rev = builder.build();
|
||||
let scripts = vec![CreateRow { row_rev }];
|
||||
let row_id = row_rev.id.clone();
|
||||
let scripts = vec![
|
||||
CreateRow { row_rev },
|
||||
AssertCell {
|
||||
row_id: row_id.clone(),
|
||||
field_id: text_field_id,
|
||||
field_type: FieldType::RichText,
|
||||
expected: "hello world".to_owned(),
|
||||
},
|
||||
AssertCell {
|
||||
row_id: row_id.clone(),
|
||||
field_id: number_field_id,
|
||||
field_type: FieldType::Number,
|
||||
expected: "$18,443.00".to_owned(),
|
||||
},
|
||||
AssertCell {
|
||||
row_id: row_id.clone(),
|
||||
field_id: single_select_field_id,
|
||||
field_type: FieldType::SingleSelect,
|
||||
expected: "Completed".to_owned(),
|
||||
},
|
||||
AssertCell {
|
||||
row_id: row_id.clone(),
|
||||
field_id: date_field_id,
|
||||
field_type: FieldType::DateTime,
|
||||
expected: "2022/03/14".to_owned(),
|
||||
},
|
||||
AssertCell {
|
||||
row_id: row_id.clone(),
|
||||
field_id: url_field_id,
|
||||
field_type: FieldType::URL,
|
||||
expected: "https://appflowy.io/".to_owned(),
|
||||
},
|
||||
];
|
||||
test.run_scripts(scripts).await;
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
use crate::grid::block_test::util::GridRowTestBuilder;
|
||||
use crate::grid::grid_editor::GridEditorTest;
|
||||
use flowy_grid::entities::{CellIdentifier, RowInfo};
|
||||
use flowy_grid::entities::{CellIdentifier, FieldType, RowInfo};
|
||||
|
||||
use flowy_grid::services::field::{
|
||||
DateCellDataParser, NumberCellDataParser, NumberFormat, NumberTypeOption, SelectOptionCellDataParser,
|
||||
SelectOptionIdsParser, SelectOptionOperation, SingleSelectTypeOption, TextCellDataParser, URLCellDataParser,
|
||||
};
|
||||
use flowy_grid_data_model::revision::{
|
||||
GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowMetaChangeset, RowRevision,
|
||||
};
|
||||
@ -24,7 +28,8 @@ pub enum RowScript {
|
||||
AssertCell {
|
||||
row_id: String,
|
||||
field_id: String,
|
||||
expected_display: Option<String>,
|
||||
field_type: FieldType,
|
||||
expected: String,
|
||||
},
|
||||
AssertRowCount(usize),
|
||||
CreateBlock {
|
||||
@ -101,20 +106,15 @@ impl GridRowTest {
|
||||
RowScript::AssertCell {
|
||||
row_id,
|
||||
field_id,
|
||||
expected_display,
|
||||
field_type,
|
||||
expected,
|
||||
} => {
|
||||
let id = CellIdentifier {
|
||||
grid_id: self.grid_id.clone(),
|
||||
field_id,
|
||||
row_id,
|
||||
};
|
||||
let display = self.editor.get_cell_display(&id).await;
|
||||
match expected_display {
|
||||
None => {}
|
||||
Some(expected_display) => {
|
||||
assert_eq!(display.unwrap(), expected_display);
|
||||
}
|
||||
}
|
||||
self.compare_cell_content(id, field_type, expected).await;
|
||||
}
|
||||
RowScript::AssertRow { expected_row } => {
|
||||
let row = &*self
|
||||
@ -153,6 +153,72 @@ impl GridRowTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn compare_cell_content(&self, cell_id: CellIdentifier, field_type: FieldType, expected: String) {
|
||||
match field_type {
|
||||
FieldType::RichText => {
|
||||
let cell_data = self
|
||||
.editor
|
||||
.get_cell_bytes(&cell_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.with_parser(TextCellDataParser())
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(cell_data.as_ref(), &expected);
|
||||
}
|
||||
FieldType::Number => {
|
||||
let field_rev = self.editor.get_field_rev(&cell_id.field_id).await.unwrap();
|
||||
let number_type_option = field_rev
|
||||
.get_type_option_entry::<NumberTypeOption>(FieldType::Number.into())
|
||||
.unwrap();
|
||||
let cell_data = self
|
||||
.editor
|
||||
.get_cell_bytes(&cell_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.with_parser(NumberCellDataParser(number_type_option.format.clone()))
|
||||
.unwrap();
|
||||
assert_eq!(cell_data.to_string(), expected);
|
||||
}
|
||||
FieldType::DateTime => {
|
||||
let cell_data = self
|
||||
.editor
|
||||
.get_cell_bytes(&cell_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.with_parser(DateCellDataParser())
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(cell_data.date, expected);
|
||||
}
|
||||
FieldType::SingleSelect => {
|
||||
let select_options = self
|
||||
.editor
|
||||
.get_cell_bytes(&cell_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.with_parser(SelectOptionCellDataParser())
|
||||
.unwrap();
|
||||
let select_option = select_options.select_options.first().unwrap();
|
||||
assert_eq!(select_option.name, expected);
|
||||
}
|
||||
FieldType::MultiSelect => {}
|
||||
FieldType::Checkbox => {}
|
||||
FieldType::URL => {
|
||||
let cell_data = self
|
||||
.editor
|
||||
.get_cell_bytes(&cell_id)
|
||||
.await
|
||||
.unwrap()
|
||||
.with_parser(URLCellDataParser())
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(cell_data.content, expected);
|
||||
assert_eq!(cell_data.url, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for GridRowTest {
|
||||
|
@ -23,21 +23,24 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_text_cell(&mut self, data: &str) {
|
||||
pub fn insert_text_cell(&mut self, data: &str) -> String {
|
||||
let text_field = self.field_rev_with_type(&FieldType::RichText);
|
||||
self.inner_builder
|
||||
.insert_cell(&text_field.id, data.to_string())
|
||||
.unwrap();
|
||||
|
||||
text_field.id.clone()
|
||||
}
|
||||
|
||||
pub fn insert_number_cell(&mut self, data: &str) {
|
||||
pub fn insert_number_cell(&mut self, data: &str) -> String {
|
||||
let number_field = self.field_rev_with_type(&FieldType::Number);
|
||||
self.inner_builder
|
||||
.insert_cell(&number_field.id, data.to_string())
|
||||
.unwrap();
|
||||
number_field.id.clone()
|
||||
}
|
||||
|
||||
pub fn insert_date_cell(&mut self, data: &str) {
|
||||
pub fn insert_date_cell(&mut self, data: &str) -> String {
|
||||
let value = serde_json::to_string(&DateCellChangeset {
|
||||
date: Some(data.to_string()),
|
||||
time: None,
|
||||
@ -45,6 +48,7 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
.unwrap();
|
||||
let date_field = self.field_rev_with_type(&FieldType::DateTime);
|
||||
self.inner_builder.insert_cell(&date_field.id, value).unwrap();
|
||||
date_field.id.clone()
|
||||
}
|
||||
|
||||
pub fn insert_checkbox_cell(&mut self, data: &str) {
|
||||
@ -54,14 +58,13 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn insert_url_cell(&mut self, data: &str) {
|
||||
let number_field = self.field_rev_with_type(&FieldType::URL);
|
||||
self.inner_builder
|
||||
.insert_cell(&number_field.id, data.to_string())
|
||||
.unwrap();
|
||||
pub fn insert_url_cell(&mut self, data: &str) -> String {
|
||||
let url_field = self.field_rev_with_type(&FieldType::URL);
|
||||
self.inner_builder.insert_cell(&url_field.id, data.to_string()).unwrap();
|
||||
url_field.id.clone()
|
||||
}
|
||||
|
||||
pub fn insert_single_select_cell<F>(&mut self, f: F)
|
||||
pub fn insert_single_select_cell<F>(&mut self, f: F) -> String
|
||||
where
|
||||
F: Fn(&Vec<SelectOption>) -> &SelectOption,
|
||||
{
|
||||
@ -71,6 +74,8 @@ impl<'a> GridRowTestBuilder<'a> {
|
||||
self.inner_builder
|
||||
.insert_select_option_cell(&single_select_field.id, option.id.clone())
|
||||
.unwrap();
|
||||
|
||||
single_select_field.id.clone()
|
||||
}
|
||||
|
||||
pub fn insert_multi_select_cell<F>(&mut self, f: F)
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::grid::filter_test::script::FilterScript::*;
|
||||
use crate::grid::filter_test::script::*;
|
||||
use flowy_grid::entities::{CreateGridFilterPayload, TextFilterCondition};
|
||||
use flowy_grid::entities::{CreateGridFilterPayload, FieldType, TextFilterCondition};
|
||||
use flowy_grid_data_model::revision::FieldRevision;
|
||||
|
||||
#[tokio::test]
|
||||
async fn grid_filter_create_test() {
|
||||
let mut test = GridFilterTest::new().await;
|
||||
let field_rev = test.text_field();
|
||||
let field_rev = test.get_field_rev(FieldType::RichText);
|
||||
let payload = CreateGridFilterPayload::new(field_rev, TextFilterCondition::TextIsEmpty, Some("abc".to_owned()));
|
||||
let scripts = vec![InsertGridTableFilter { payload }, AssertTableFilterCount { count: 1 }];
|
||||
test.run_scripts(scripts).await;
|
||||
@ -16,7 +16,7 @@ async fn grid_filter_create_test() {
|
||||
#[should_panic]
|
||||
async fn grid_filter_invalid_condition_panic_test() {
|
||||
let mut test = GridFilterTest::new().await;
|
||||
let field_rev = test.text_field().clone();
|
||||
let field_rev = test.get_field_rev(FieldType::RichText).clone();
|
||||
|
||||
// 100 is not a valid condition, so this test should be panic.
|
||||
let payload = CreateGridFilterPayload::new(&field_rev, 100, Some("".to_owned()));
|
||||
@ -27,7 +27,7 @@ async fn grid_filter_invalid_condition_panic_test() {
|
||||
#[tokio::test]
|
||||
async fn grid_filter_delete_test() {
|
||||
let mut test = GridFilterTest::new().await;
|
||||
let field_rev = test.text_field().clone();
|
||||
let field_rev = test.get_field_rev(FieldType::RichText).clone();
|
||||
let payload = create_filter(&field_rev, TextFilterCondition::TextIsEmpty, "abc");
|
||||
let scripts = vec![InsertGridTableFilter { payload }, AssertTableFilterCount { count: 1 }];
|
||||
test.run_scripts(scripts).await;
|
||||
@ -36,7 +36,7 @@ async fn grid_filter_delete_test() {
|
||||
test.run_scripts(vec![
|
||||
DeleteGridTableFilter {
|
||||
filter_id: filter.id,
|
||||
field_rev,
|
||||
field_rev: field_rev.as_ref().clone(),
|
||||
},
|
||||
AssertTableFilterCount { count: 0 },
|
||||
])
|
||||
|
@ -64,7 +64,7 @@ impl GridEditorTest {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn get_row_revs(&self) -> Vec<Arc<RowRevision>> {
|
||||
pub async fn get_row_revs(&self) -> Vec<Arc<RowRevision>> {
|
||||
self.editor
|
||||
.grid_block_snapshots(None)
|
||||
.await
|
||||
@ -79,12 +79,12 @@ impl GridEditorTest {
|
||||
self.editor.get_grid_filter(&layout_type).await.unwrap()
|
||||
}
|
||||
|
||||
pub fn text_field(&self) -> &FieldRevision {
|
||||
pub fn get_field_rev(&self, field_type: FieldType) -> &Arc<FieldRevision> {
|
||||
self.field_revs
|
||||
.iter()
|
||||
.filter(|field_rev| {
|
||||
let t_field_type: FieldType = field_rev.field_type_rev.into();
|
||||
t_field_type == FieldType::RichText
|
||||
t_field_type == field_type
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.pop()
|
||||
@ -129,7 +129,6 @@ fn make_test_grid() -> BuildGridContext {
|
||||
FieldType::SingleSelect => {
|
||||
// Single Select
|
||||
let single_select = SingleSelectTypeOptionBuilder::default()
|
||||
.option(SelectOption::new("Live"))
|
||||
.option(SelectOption::new("Completed"))
|
||||
.option(SelectOption::new("Planned"))
|
||||
.option(SelectOption::new("Paused"));
|
||||
|
Loading…
Reference in New Issue
Block a user