mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: add date filter tests
This commit is contained in:
parent
4f30f8e2cd
commit
ec1113b134
@ -1,6 +1,8 @@
|
|||||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||||
use flowy_error::ErrorCode;
|
use flowy_error::ErrorCode;
|
||||||
use flowy_grid_data_model::revision::GridFilterRevision;
|
use flowy_grid_data_model::revision::GridFilterRevision;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
|
||||||
@ -9,7 +11,30 @@ pub struct GridDateFilter {
|
|||||||
pub condition: DateFilterCondition,
|
pub condition: DateFilterCondition,
|
||||||
|
|
||||||
#[pb(index = 2, one_of)]
|
#[pb(index = 2, one_of)]
|
||||||
pub content: Option<String>,
|
pub start: Option<i64>,
|
||||||
|
|
||||||
|
#[pb(index = 3, one_of)]
|
||||||
|
pub end: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Default)]
|
||||||
|
struct DateRange {
|
||||||
|
start: Option<i64>,
|
||||||
|
end: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for DateRange {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
serde_json::to_string(self).unwrap_or("".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for DateRange {
|
||||||
|
type Err = serde_json::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
serde_json::from_str(s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
|
#[derive(Debug, Clone, PartialEq, Eq, ProtoBuf_Enum)]
|
||||||
@ -48,9 +73,21 @@ impl std::convert::TryFrom<u8> for DateFilterCondition {
|
|||||||
}
|
}
|
||||||
impl std::convert::From<Arc<GridFilterRevision>> for GridDateFilter {
|
impl std::convert::From<Arc<GridFilterRevision>> for GridDateFilter {
|
||||||
fn from(rev: Arc<GridFilterRevision>) -> Self {
|
fn from(rev: Arc<GridFilterRevision>) -> Self {
|
||||||
GridDateFilter {
|
let condition = DateFilterCondition::try_from(rev.condition).unwrap_or(DateFilterCondition::DateIs);
|
||||||
condition: DateFilterCondition::try_from(rev.condition).unwrap_or(DateFilterCondition::DateIs),
|
let mut filter = GridDateFilter {
|
||||||
content: rev.content.clone(),
|
condition,
|
||||||
}
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(range) = rev
|
||||||
|
.content
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|content| DateRange::from_str(content).ok())
|
||||||
|
{
|
||||||
|
filter.start = range.start;
|
||||||
|
filter.end = range.end;
|
||||||
|
};
|
||||||
|
|
||||||
|
filter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use crate::entities::{CellChangeset, FieldType, GridDateFilter};
|
use crate::entities::{CellChangeset, FieldType};
|
||||||
use crate::entities::{CellIdentifier, CellIdentifierPayload};
|
use crate::entities::{CellIdentifier, CellIdentifierPayload};
|
||||||
use crate::impl_type_option;
|
use crate::impl_type_option;
|
||||||
use crate::services::cell::{
|
use crate::services::cell::{
|
||||||
AnyCellData, CellData, CellDataChangeset, CellDataOperation, CellFilterOperation, DecodedCellData,
|
AnyCellData, CellData, CellDataChangeset, CellDataOperation, DecodedCellData, FromCellChangeset, FromCellString,
|
||||||
FromCellChangeset, FromCellString,
|
|
||||||
};
|
};
|
||||||
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
@ -110,6 +109,10 @@ impl DateTypeOption {
|
|||||||
|
|
||||||
fn utc_date_time_from_timestamp(&self, timestamp: i64) -> chrono::DateTime<chrono::Utc> {
|
fn utc_date_time_from_timestamp(&self, timestamp: i64) -> chrono::DateTime<chrono::Utc> {
|
||||||
let native = NaiveDateTime::from_timestamp(timestamp, 0);
|
let native = NaiveDateTime::from_timestamp(timestamp, 0);
|
||||||
|
let native2 = NaiveDateTime::from_timestamp(timestamp, 0);
|
||||||
|
|
||||||
|
if native > native2 {}
|
||||||
|
|
||||||
self.utc_date_time_from_native(native)
|
self.utc_date_time_from_native(native)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,19 +121,10 @@ impl DateTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellFilterOperation<GridDateFilter> for DateTypeOption {
|
impl CellDataOperation<DateTimestamp, DateCellChangeset> for DateTypeOption {
|
||||||
fn apply_filter(&self, any_cell_data: AnyCellData, _filter: &GridDateFilter) -> FlowyResult<bool> {
|
|
||||||
if !any_cell_data.is_date() {
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
Ok(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CellDataOperation<TimestampParser, DateCellChangeset> for DateTypeOption {
|
|
||||||
fn decode_cell_data(
|
fn decode_cell_data(
|
||||||
&self,
|
&self,
|
||||||
cell_data: CellData<TimestampParser>,
|
cell_data: CellData<DateTimestamp>,
|
||||||
decoded_field_type: &FieldType,
|
decoded_field_type: &FieldType,
|
||||||
_field_rev: &FieldRevision,
|
_field_rev: &FieldRevision,
|
||||||
) -> FlowyResult<DecodedCellData> {
|
) -> FlowyResult<DecodedCellData> {
|
||||||
@ -168,17 +162,36 @@ impl CellDataOperation<TimestampParser, DateCellChangeset> for DateTypeOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TimestampParser(i64);
|
pub struct DateTimestamp(i64);
|
||||||
|
impl AsRef<i64> for DateTimestamp {
|
||||||
|
fn as_ref(&self) -> &i64 {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromCellString for TimestampParser {
|
impl std::convert::From<DateTimestamp> for i64 {
|
||||||
|
fn from(timestamp: DateTimestamp) -> Self {
|
||||||
|
timestamp.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromCellString for DateTimestamp {
|
||||||
fn from_cell_str(s: &str) -> FlowyResult<Self>
|
fn from_cell_str(s: &str) -> FlowyResult<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
let num = s.parse::<i64>().unwrap_or(0);
|
let num = s.parse::<i64>().unwrap_or(0);
|
||||||
Ok(TimestampParser(num))
|
Ok(DateTimestamp(num))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::convert::From<AnyCellData> for DateTimestamp {
|
||||||
|
fn from(data: AnyCellData) -> Self {
|
||||||
|
let num = data.cell_data.parse::<i64>().unwrap_or(0);
|
||||||
|
DateTimestamp(num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DateTypeOptionBuilder(DateTypeOption);
|
pub struct DateTypeOptionBuilder(DateTypeOption);
|
||||||
impl_into_box_type_option_builder!(DateTypeOptionBuilder);
|
impl_into_box_type_option_builder!(DateTypeOptionBuilder);
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
use crate::entities::GridDateFilter;
|
|
||||||
|
|
||||||
impl GridDateFilter {}
|
|
@ -1,12 +1,9 @@
|
|||||||
use crate::entities::{
|
use crate::entities::{
|
||||||
FieldType, GridCheckboxFilter, GridDateFilter, GridNumberFilter, GridSelectOptionFilter, GridTextFilter,
|
FieldType, GridCheckboxFilter, GridDateFilter, GridNumberFilter, GridSelectOptionFilter, GridTextFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
|
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
use flowy_grid_data_model::revision::{FieldRevision, RowRevision};
|
||||||
use flowy_sync::client_grid::GridRevisionPad;
|
use flowy_sync::client_grid::GridRevisionPad;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
@ -179,7 +179,7 @@ fn filter_cell(
|
|||||||
field_type,
|
field_type,
|
||||||
};
|
};
|
||||||
let any_cell_data = AnyCellData::try_from(cell_rev).ok()?;
|
let any_cell_data = AnyCellData::try_from(cell_rev).ok()?;
|
||||||
let is_hidden = match &filter_id.field_type {
|
let is_visible = match &filter_id.field_type {
|
||||||
FieldType::RichText => filter_cache.text_filter.get(&filter_id).and_then(|filter| {
|
FieldType::RichText => filter_cache.text_filter.get(&filter_id).and_then(|filter| {
|
||||||
Some(
|
Some(
|
||||||
field_rev
|
field_rev
|
||||||
@ -238,7 +238,7 @@ fn filter_cell(
|
|||||||
}),
|
}),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let is_visible = !is_hidden.unwrap_or(false);
|
let is_visible = !is_visible.unwrap_or(true);
|
||||||
match filter_result.visible_by_field_id.get(&filter_id) {
|
match filter_result.visible_by_field_id.get(&filter_id) {
|
||||||
None => {
|
None => {
|
||||||
if is_visible {
|
if is_visible {
|
||||||
|
@ -4,7 +4,7 @@ use crate::services::field::{CheckboxCellData, CheckboxTypeOption};
|
|||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
|
|
||||||
impl GridCheckboxFilter {
|
impl GridCheckboxFilter {
|
||||||
pub fn apply(&self, cell_data: &CheckboxCellData) -> bool {
|
pub fn is_visible(&self, cell_data: &CheckboxCellData) -> bool {
|
||||||
let is_check = cell_data.is_check();
|
let is_check = cell_data.is_check();
|
||||||
match self.condition {
|
match self.condition {
|
||||||
CheckboxCondition::IsChecked => is_check,
|
CheckboxCondition::IsChecked => is_check,
|
||||||
@ -19,7 +19,7 @@ impl CellFilterOperation<GridCheckboxFilter> for CheckboxTypeOption {
|
|||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
let checkbox_cell_data: CheckboxCellData = any_cell_data.try_into()?;
|
let checkbox_cell_data: CheckboxCellData = any_cell_data.try_into()?;
|
||||||
Ok(filter.apply(&checkbox_cell_data))
|
Ok(filter.is_visible(&checkbox_cell_data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,9 +33,9 @@ mod tests {
|
|||||||
let checkbox_filter = GridCheckboxFilter {
|
let checkbox_filter = GridCheckboxFilter {
|
||||||
condition: CheckboxCondition::IsChecked,
|
condition: CheckboxCondition::IsChecked,
|
||||||
};
|
};
|
||||||
for (value, r) in [("true", true), ("yes", true), ("false", false), ("no", false)] {
|
for (value, visible) in [("true", true), ("yes", true), ("false", false), ("no", false)] {
|
||||||
let data = CheckboxCellData(value.to_owned());
|
let data = CheckboxCellData(value.to_owned());
|
||||||
assert_eq!(checkbox_filter.apply(&data), r);
|
assert_eq!(checkbox_filter.is_visible(&data), visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,9 +44,9 @@ mod tests {
|
|||||||
let checkbox_filter = GridCheckboxFilter {
|
let checkbox_filter = GridCheckboxFilter {
|
||||||
condition: CheckboxCondition::IsUnChecked,
|
condition: CheckboxCondition::IsUnChecked,
|
||||||
};
|
};
|
||||||
for (value, r) in [("false", true), ("no", true), ("true", false), ("yes", false)] {
|
for (value, visible) in [("false", true), ("no", true), ("true", false), ("yes", false)] {
|
||||||
let data = CheckboxCellData(value.to_owned());
|
let data = CheckboxCellData(value.to_owned());
|
||||||
assert_eq!(checkbox_filter.apply(&data), r);
|
assert_eq!(checkbox_filter.is_visible(&data), visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
use crate::entities::{DateFilterCondition, GridDateFilter};
|
||||||
|
use crate::services::cell::{AnyCellData, CellFilterOperation};
|
||||||
|
use crate::services::field::{DateTimestamp, DateTypeOption};
|
||||||
|
use flowy_error::FlowyResult;
|
||||||
|
|
||||||
|
impl GridDateFilter {
|
||||||
|
pub fn is_visible<T: Into<i64>>(&self, cell_timestamp: T) -> bool {
|
||||||
|
if self.start.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let cell_timestamp = cell_timestamp.into();
|
||||||
|
let start_timestamp = *self.start.as_ref().unwrap();
|
||||||
|
// We assume that the cell_timestamp doesn't contain hours, just day.
|
||||||
|
match self.condition {
|
||||||
|
DateFilterCondition::DateIs => cell_timestamp == start_timestamp,
|
||||||
|
DateFilterCondition::DateBefore => cell_timestamp < start_timestamp,
|
||||||
|
DateFilterCondition::DateAfter => cell_timestamp > start_timestamp,
|
||||||
|
DateFilterCondition::DateOnOrBefore => cell_timestamp <= start_timestamp,
|
||||||
|
DateFilterCondition::DateOnOrAfter => cell_timestamp >= start_timestamp,
|
||||||
|
DateFilterCondition::DateWithIn => {
|
||||||
|
if let Some(end_timestamp) = self.end.as_ref() {
|
||||||
|
cell_timestamp >= start_timestamp && cell_timestamp <= *end_timestamp
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DateFilterCondition::DateIsEmpty => cell_timestamp == (0 as i64),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CellFilterOperation<GridDateFilter> for DateTypeOption {
|
||||||
|
fn apply_filter(&self, any_cell_data: AnyCellData, filter: &GridDateFilter) -> FlowyResult<bool> {
|
||||||
|
if !any_cell_data.is_date() {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
let timestamp: DateTimestamp = any_cell_data.into();
|
||||||
|
Ok(filter.is_visible(timestamp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#![allow(clippy::all)]
|
||||||
|
use crate::entities::{DateFilterCondition, GridDateFilter};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn date_filter_is_test() {
|
||||||
|
let filter = GridDateFilter {
|
||||||
|
condition: DateFilterCondition::DateIs,
|
||||||
|
start: Some(123),
|
||||||
|
end: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (val, visible) in vec![(123, true), (12, false)] {
|
||||||
|
assert_eq!(filter.is_visible(val as i64), visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn date_filter_before_test() {
|
||||||
|
let filter = GridDateFilter {
|
||||||
|
condition: DateFilterCondition::DateBefore,
|
||||||
|
start: Some(123),
|
||||||
|
end: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (val, visible) in vec![(123, false), (122, true)] {
|
||||||
|
assert_eq!(filter.is_visible(val as i64), visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn date_filter_before_or_on_test() {
|
||||||
|
let filter = GridDateFilter {
|
||||||
|
condition: DateFilterCondition::DateOnOrBefore,
|
||||||
|
start: Some(123),
|
||||||
|
end: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (val, visible) in vec![(123, true), (122, true)] {
|
||||||
|
assert_eq!(filter.is_visible(val as i64), visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn date_filter_after_test() {
|
||||||
|
let filter = GridDateFilter {
|
||||||
|
condition: DateFilterCondition::DateAfter,
|
||||||
|
start: Some(123),
|
||||||
|
end: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (val, visible) in vec![(1234, true), (122, false), (0, false)] {
|
||||||
|
assert_eq!(filter.is_visible(val as i64), visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn date_filter_within_test() {
|
||||||
|
let filter = GridDateFilter {
|
||||||
|
condition: DateFilterCondition::DateWithIn,
|
||||||
|
start: Some(123),
|
||||||
|
end: Some(130),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (val, visible) in vec![(123, true), (130, true), (132, false)] {
|
||||||
|
assert_eq!(filter.is_visible(val as i64), visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
mod checkbox_filter;
|
||||||
|
mod date_filter;
|
||||||
|
mod number_filter;
|
||||||
|
mod select_option_filter;
|
||||||
|
mod text_filter;
|
||||||
|
mod url_filter;
|
||||||
|
|
||||||
|
pub use checkbox_filter::*;
|
||||||
|
pub use date_filter::*;
|
||||||
|
pub use number_filter::*;
|
||||||
|
pub use select_option_filter::*;
|
||||||
|
pub use text_filter::*;
|
||||||
|
pub use url_filter::*;
|
@ -7,7 +7,7 @@ use rust_decimal::Decimal;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
impl GridNumberFilter {
|
impl GridNumberFilter {
|
||||||
pub fn apply(&self, num_cell_data: &NumberCellData) -> bool {
|
pub fn is_visible(&self, num_cell_data: &NumberCellData) -> bool {
|
||||||
if self.content.is_none() {
|
if self.content.is_none() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ impl CellFilterOperation<GridNumberFilter> for NumberTypeOption {
|
|||||||
let cell_data = any_cell_data.cell_data;
|
let cell_data = any_cell_data.cell_data;
|
||||||
let num_cell_data = self.format_cell_data(&cell_data)?;
|
let num_cell_data = self.format_cell_data(&cell_data)?;
|
||||||
|
|
||||||
Ok(filter.apply(&num_cell_data))
|
Ok(filter.is_visible(&num_cell_data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,15 +57,15 @@ mod tests {
|
|||||||
content: Some("123".to_owned()),
|
content: Some("123".to_owned()),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (num_str, r) in [("123", true), ("1234", false), ("", false)] {
|
for (num_str, visible) in [("123", true), ("1234", false), ("", false)] {
|
||||||
let data = NumberCellData::from_str(num_str).unwrap();
|
let data = NumberCellData::from_str(num_str).unwrap();
|
||||||
assert_eq!(number_filter.apply(&data), r);
|
assert_eq!(number_filter.is_visible(&data), visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
let format = NumberFormat::USD;
|
let format = NumberFormat::USD;
|
||||||
for (num_str, r) in [("$123", true), ("1234", false), ("", false)] {
|
for (num_str, visible) in [("$123", true), ("1234", false), ("", false)] {
|
||||||
let data = NumberCellData::from_format_str(num_str, true, &format).unwrap();
|
let data = NumberCellData::from_format_str(num_str, true, &format).unwrap();
|
||||||
assert_eq!(number_filter.apply(&data), r);
|
assert_eq!(number_filter.is_visible(&data), visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
@ -74,9 +74,9 @@ mod tests {
|
|||||||
condition: NumberFilterCondition::GreaterThan,
|
condition: NumberFilterCondition::GreaterThan,
|
||||||
content: Some("12".to_owned()),
|
content: Some("12".to_owned()),
|
||||||
};
|
};
|
||||||
for (num_str, r) in [("123", true), ("10", false), ("30", true), ("", false)] {
|
for (num_str, visible) in [("123", true), ("10", false), ("30", true), ("", false)] {
|
||||||
let data = NumberCellData::from_str(num_str).unwrap();
|
let data = NumberCellData::from_str(num_str).unwrap();
|
||||||
assert_eq!(number_filter.apply(&data), r);
|
assert_eq!(number_filter.is_visible(&data), visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,9 +86,9 @@ mod tests {
|
|||||||
condition: NumberFilterCondition::LessThan,
|
condition: NumberFilterCondition::LessThan,
|
||||||
content: Some("100".to_owned()),
|
content: Some("100".to_owned()),
|
||||||
};
|
};
|
||||||
for (num_str, r) in [("12", true), ("1234", false), ("30", true), ("", true)] {
|
for (num_str, visible) in [("12", true), ("1234", false), ("30", true), ("", true)] {
|
||||||
let data = NumberCellData::from_str(num_str).unwrap();
|
let data = NumberCellData::from_str(num_str).unwrap();
|
||||||
assert_eq!(number_filter.apply(&data), r);
|
assert_eq!(number_filter.is_visible(&data), visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ use crate::services::field::{MultiSelectTypeOption, SingleSelectTypeOption};
|
|||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
|
|
||||||
impl GridSelectOptionFilter {
|
impl GridSelectOptionFilter {
|
||||||
pub fn apply(&self, selected_options: &SelectedSelectOptions) -> bool {
|
pub fn is_visible(&self, selected_options: &SelectedSelectOptions) -> bool {
|
||||||
let selected_option_ids: Vec<&String> = selected_options.options.iter().map(|option| &option.id).collect();
|
let selected_option_ids: Vec<&String> = selected_options.options.iter().map(|option| &option.id).collect();
|
||||||
match self.condition {
|
match self.condition {
|
||||||
SelectOptionCondition::OptionIs => {
|
SelectOptionCondition::OptionIs => {
|
||||||
@ -46,7 +46,7 @@ impl CellFilterOperation<GridSelectOptionFilter> for MultiSelectTypeOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data));
|
let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data));
|
||||||
Ok(filter.apply(&selected_options))
|
Ok(filter.is_visible(&selected_options))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ impl CellFilterOperation<GridSelectOptionFilter> for SingleSelectTypeOption {
|
|||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data));
|
let selected_options = SelectedSelectOptions::from(self.selected_select_option(any_cell_data));
|
||||||
Ok(filter.apply(&selected_options))
|
Ok(filter.is_visible(&selected_options))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,29 +78,29 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
filter_1.apply(&SelectedSelectOptions {
|
filter_1.is_visible(&SelectedSelectOptions {
|
||||||
options: vec![option_1.clone(), option_2.clone()],
|
options: vec![option_1.clone(), option_2.clone()],
|
||||||
}),
|
}),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
filter_1.apply(&SelectedSelectOptions {
|
filter_1.is_visible(&SelectedSelectOptions {
|
||||||
options: vec![option_1.clone(), option_2.clone(), option_3.clone()],
|
options: vec![option_1.clone(), option_2.clone(), option_3.clone()],
|
||||||
}),
|
}),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
filter_1.apply(&SelectedSelectOptions {
|
filter_1.is_visible(&SelectedSelectOptions {
|
||||||
options: vec![option_1.clone(), option_3.clone()],
|
options: vec![option_1.clone(), option_3.clone()],
|
||||||
}),
|
}),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(filter_1.apply(&SelectedSelectOptions { options: vec![] }), true);
|
assert_eq!(filter_1.is_visible(&SelectedSelectOptions { options: vec![] }), true);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
filter_1.apply(&SelectedSelectOptions {
|
filter_1.is_visible(&SelectedSelectOptions {
|
||||||
options: vec![option_1.clone()],
|
options: vec![option_1.clone()],
|
||||||
}),
|
}),
|
||||||
true,
|
true,
|
@ -4,7 +4,7 @@ use crate::services::field::{RichTextTypeOption, TextCellData};
|
|||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
|
|
||||||
impl GridTextFilter {
|
impl GridTextFilter {
|
||||||
pub fn apply<T: AsRef<str>>(&self, cell_data: T) -> bool {
|
pub fn is_visible<T: AsRef<str>>(&self, cell_data: T) -> bool {
|
||||||
let cell_data = cell_data.as_ref();
|
let cell_data = cell_data.as_ref();
|
||||||
let s = cell_data.to_lowercase();
|
let s = cell_data.to_lowercase();
|
||||||
if let Some(content) = self.content.as_ref() {
|
if let Some(content) = self.content.as_ref() {
|
||||||
@ -31,7 +31,7 @@ impl CellFilterOperation<GridTextFilter> for RichTextTypeOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let text_cell_data: TextCellData = any_cell_data.try_into()?;
|
let text_cell_data: TextCellData = any_cell_data.try_into()?;
|
||||||
Ok(filter.apply(text_cell_data))
|
Ok(filter.is_visible(text_cell_data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -46,10 +46,10 @@ mod tests {
|
|||||||
content: Some("appflowy".to_owned()),
|
content: Some("appflowy".to_owned()),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert!(text_filter.apply("AppFlowy"));
|
assert!(text_filter.is_visible("AppFlowy"));
|
||||||
assert_eq!(text_filter.apply("appflowy"), true);
|
assert_eq!(text_filter.is_visible("appflowy"), true);
|
||||||
assert_eq!(text_filter.apply("Appflowy"), true);
|
assert_eq!(text_filter.is_visible("Appflowy"), true);
|
||||||
assert_eq!(text_filter.apply("AppFlowy.io"), false);
|
assert_eq!(text_filter.is_visible("AppFlowy.io"), false);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn text_filter_start_with_test() {
|
fn text_filter_start_with_test() {
|
||||||
@ -58,9 +58,9 @@ mod tests {
|
|||||||
content: Some("appflowy".to_owned()),
|
content: Some("appflowy".to_owned()),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(text_filter.apply("AppFlowy.io"), true);
|
assert_eq!(text_filter.is_visible("AppFlowy.io"), true);
|
||||||
assert_eq!(text_filter.apply(""), false);
|
assert_eq!(text_filter.is_visible(""), false);
|
||||||
assert_eq!(text_filter.apply("https"), false);
|
assert_eq!(text_filter.is_visible("https"), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -70,9 +70,9 @@ mod tests {
|
|||||||
content: Some("appflowy".to_owned()),
|
content: Some("appflowy".to_owned()),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(text_filter.apply("https://github.com/appflowy"), true);
|
assert_eq!(text_filter.is_visible("https://github.com/appflowy"), true);
|
||||||
assert_eq!(text_filter.apply("App"), false);
|
assert_eq!(text_filter.is_visible("App"), false);
|
||||||
assert_eq!(text_filter.apply("appflowy.io"), false);
|
assert_eq!(text_filter.is_visible("appflowy.io"), false);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn text_filter_empty_test() {
|
fn text_filter_empty_test() {
|
||||||
@ -81,8 +81,8 @@ mod tests {
|
|||||||
content: Some("appflowy".to_owned()),
|
content: Some("appflowy".to_owned()),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(text_filter.apply(""), true);
|
assert_eq!(text_filter.is_visible(""), true);
|
||||||
assert_eq!(text_filter.apply("App"), false);
|
assert_eq!(text_filter.is_visible("App"), false);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn text_filter_contain_test() {
|
fn text_filter_contain_test() {
|
||||||
@ -91,10 +91,10 @@ mod tests {
|
|||||||
content: Some("appflowy".to_owned()),
|
content: Some("appflowy".to_owned()),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(text_filter.apply("https://github.com/appflowy"), true);
|
assert_eq!(text_filter.is_visible("https://github.com/appflowy"), true);
|
||||||
assert_eq!(text_filter.apply("AppFlowy"), true);
|
assert_eq!(text_filter.is_visible("AppFlowy"), true);
|
||||||
assert_eq!(text_filter.apply("App"), false);
|
assert_eq!(text_filter.is_visible("App"), false);
|
||||||
assert_eq!(text_filter.apply(""), false);
|
assert_eq!(text_filter.is_visible(""), false);
|
||||||
assert_eq!(text_filter.apply("github"), false);
|
assert_eq!(text_filter.is_visible("github"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,6 +10,6 @@ impl CellFilterOperation<GridTextFilter> for URLTypeOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let text_cell_data: TextCellData = any_cell_data.try_into()?;
|
let text_cell_data: TextCellData = any_cell_data.try_into()?;
|
||||||
Ok(filter.apply(&text_cell_data))
|
Ok(filter.is_visible(&text_cell_data))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +1,5 @@
|
|||||||
mod checkbox_filter;
|
|
||||||
mod date_filter;
|
|
||||||
mod filter_cache;
|
mod filter_cache;
|
||||||
mod filter_service;
|
mod filter_service;
|
||||||
mod number_filter;
|
mod impls;
|
||||||
mod select_option_filter;
|
|
||||||
mod text_filter;
|
|
||||||
mod url_filter;
|
|
||||||
|
|
||||||
pub(crate) use filter_service::*;
|
pub(crate) use filter_service::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user