diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart index 5e406c0c26..bc5c683414 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart @@ -7,10 +7,10 @@ import 'package:flowy_sdk/dispatch/dispatch.dart'; import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart'; import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart index 28f8bf1b10..c5cfe397a3 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart @@ -5,6 +5,7 @@ import 'package:flowy_sdk/log.dart'; import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:table_calendar/table_calendar.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart index 00780143cc..7c03354134 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/date_cell_bloc.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_bloc.dart index e1fe39c3bf..6129f90f71 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_bloc.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_editor_bloc.dart index 6e4990943f..dcb643d535 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/url_cell_editor_bloc.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/url_type_option_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart index 8784422c54..556b33d40f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart @@ -1,5 +1,6 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart index f4031dc9ce..b9b2f8e89d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/date.dart @@ -9,7 +9,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/date_type_option_entities.pb.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_option.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_option_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option_entities.rs similarity index 97% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_option_entities.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option_entities.rs index 5a8bf1e7a7..54cde9b310 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_option_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/checkbox_type_option_entities.rs @@ -57,7 +57,7 @@ impl ToString for CheckboxCellData { self.0.clone() } } -pub struct CheckboxCellDataParser; +pub struct CheckboxCellDataParser(); impl CellBytesParser for CheckboxCellDataParser { type Object = CheckboxCellData; fn parse(&self, bytes: &Bytes) -> FlowyResult { diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/mod.rs index 35b6500a0d..61013fac08 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/checkbox_type_option/mod.rs @@ -1,6 +1,6 @@ -mod checkbox_option; -mod checkbox_option_entities; mod checkbox_tests; +mod checkbox_type_option; +mod checkbox_type_option_entities; -pub use checkbox_option::*; -pub use checkbox_option_entities::*; +pub use checkbox_type_option::*; +pub use checkbox_type_option_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_option.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_option_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option_entities.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_option_entities.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/date_type_option_entities.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/mod.rs index fe00a14889..8ca49fdd15 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option/mod.rs @@ -1,6 +1,6 @@ -mod date_option; -mod date_option_entities; mod date_tests; +mod date_type_option; +mod date_type_option_entities; -pub use date_option::*; -pub use date_option_entities::*; +pub use date_type_option::*; +pub use date_type_option_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/mod.rs index 32a91961c9..4b2bcc1ecd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/mod.rs @@ -1,9 +1,9 @@ #![allow(clippy::module_inception)] mod format; -mod number_option; -mod number_option_entities; mod number_tests; +mod number_type_option; +mod number_type_option_entities; pub use format::*; -pub use number_option::*; -pub use number_option_entities::*; +pub use number_type_option::*; +pub use number_type_option_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_option.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_option_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option_entities.rs similarity index 98% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_option_entities.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option_entities.rs index 7e47556fe5..6297114a07 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_option_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option_entities.rs @@ -2,7 +2,7 @@ use crate::services::cell::CellBytesParser; use crate::services::field::number_currency::Currency; use crate::services::field::{strip_currency_symbol, NumberFormat, STRIP_SYMBOL}; use bytes::Bytes; -use flowy_error::{internal_error, FlowyError, FlowyResult}; +use flowy_error::{FlowyError, FlowyResult}; use rust_decimal::Decimal; use rusty_money::Money; use std::str::FromStr; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/mod.rs index 9f41c61fdd..3c1d2287cd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/mod.rs @@ -1,2 +1,2 @@ -mod text_option; -pub use text_option::*; +mod text_type_option; +pub use text_type_option::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_type_option.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_option.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option/text_type_option.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/mod.rs index 6c8dc96f88..e3b2ae16bd 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/mod.rs @@ -1,6 +1,6 @@ -mod url_option; -mod url_option_entities; mod url_tests; +mod url_type_option; +mod url_type_option_entities; -pub use url_option::*; -pub use url_option_entities::*; +pub use url_type_option::*; +pub use url_type_option_entities::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_type_option.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_option.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_type_option.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_option_entities.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_type_option_entities.rs similarity index 100% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_option_entities.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/url_type_option/url_type_option_entities.rs diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index f9a618d145..70804f1404 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -270,10 +270,14 @@ impl GridRevisionEditor { pub async fn create_row(&self, start_row_id: Option) -> FlowyResult { let field_revs = self.grid_pad.read().await.get_field_revs(None)?; + let field_revs_ref = field_revs + .iter() + .map(|field_rev| field_rev.as_ref()) + .collect::>(); let block_id = self.block_id().await?; // insert empty row below the row whose id is upper_row_id - let row_rev = RowRevisionBuilder::new(&field_revs).build(&block_id); + let row_rev = RowRevisionBuilder::new(&field_revs_ref).build(&block_id); let row_order = RowInfo::from(&row_rev); // insert the row diff --git a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs index fb8c2550e4..6ccb553fc1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs +++ b/frontend/rust-lib/flowy-grid/src/services/row/row_builder.rs @@ -4,19 +4,18 @@ use flowy_error::{FlowyError, FlowyResult}; use flowy_grid_data_model::revision::{gen_row_id, CellRevision, FieldRevision, RowRevision, DEFAULT_ROW_HEIGHT}; use indexmap::IndexMap; use std::collections::HashMap; -use std::sync::Arc; pub struct RowRevisionBuilder<'a> { - field_rev_map: HashMap<&'a String, &'a Arc>, + field_rev_map: HashMap<&'a String, &'a FieldRevision>, payload: CreateRowRevisionPayload, } impl<'a> RowRevisionBuilder<'a> { - pub fn new(fields: &'a [Arc]) -> Self { + pub fn new(fields: &'a [&'a FieldRevision]) -> Self { let field_rev_map = fields .iter() - .map(|field| (&field.id, field)) - .collect::>>(); + .map(|field| (&field.id, *field)) + .collect::>(); let payload = CreateRowRevisionPayload { row_id: gen_row_id(), diff --git a/frontend/rust-lib/flowy-grid/tests/grid/block_test/row_test.rs b/frontend/rust-lib/flowy-grid/tests/grid/block_test/row_test.rs index 0278a40090..02e7ccc050 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/block_test/row_test.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/block_test/row_test.rs @@ -1,6 +1,8 @@ -use crate::grid::block_test::script::GridRowTest; use crate::grid::block_test::script::RowScript::*; +use crate::grid::block_test::script::{CreateRowScriptBuilder, GridRowTest}; +use crate::grid::grid_editor::{COMPLETED, FACEBOOK, GOOGLE, PAUSED, TWITTER}; use flowy_grid::entities::FieldType; +use flowy_grid::services::field::{NO, SELECTION_IDS_SEPARATOR}; use flowy_grid_data_model::revision::RowMetaChangeset; #[tokio::test] @@ -66,50 +68,65 @@ async fn grid_delete_row() { #[tokio::test] async fn grid_row_add_cells_test() { let mut test = GridRowTest::new().await; - let mut builder = test.row_builder(); + let mut builder = CreateRowScriptBuilder::new(&test); + builder.insert(FieldType::RichText, "hello world", "hello world"); + builder.insert(FieldType::DateTime, "1647251762", "2022/03/14"); + builder.insert(FieldType::Number, "18,443", "$18,443.00"); + builder.insert(FieldType::Checkbox, "false", NO); + builder.insert(FieldType::URL, "https://appflowy.io", "https://appflowy.io"); + builder.insert_single_select_cell(|mut options| options.remove(0), COMPLETED); + builder.insert_multi_select_cell( + |options| options, + &vec![GOOGLE, FACEBOOK, TWITTER].join(SELECTION_IDS_SEPARATOR), + ); - 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"); - let url_field_id = builder.insert_url_cell("https://appflowy.io"); - - let row_rev = builder.build(); - 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; + test.run_scripts(builder.build()).await; +} + +#[tokio::test] +async fn grid_row_insert_number_test() { + let mut test = GridRowTest::new().await; + for (val, expected) in &[("1647251762", "2022/03/14"), ("2022/03/14", ""), ("", "")] { + let mut builder = CreateRowScriptBuilder::new(&test); + builder.insert(FieldType::DateTime, val, expected); + test.run_scripts(builder.build()).await; + } +} + +#[tokio::test] +async fn grid_row_insert_date_test() { + let mut test = GridRowTest::new().await; + for (val, expected) in &[ + ("18,443", "$18,443.00"), + ("0", "$0.00"), + ("100000", "$100,000.00"), + ("$100,000.00", "$100,000.00"), + ("", ""), + ] { + let mut builder = CreateRowScriptBuilder::new(&test); + builder.insert(FieldType::Number, val, expected); + test.run_scripts(builder.build()).await; + } +} +#[tokio::test] +async fn grid_row_insert_single_select_test() { + let mut test = GridRowTest::new().await; + let mut builder = CreateRowScriptBuilder::new(&test); + builder.insert_single_select_cell(|mut options| options.pop().unwrap(), PAUSED); + test.run_scripts(builder.build()).await; +} + +#[tokio::test] +async fn grid_row_insert_multi_select_test() { + let mut test = GridRowTest::new().await; + let mut builder = CreateRowScriptBuilder::new(&test); + builder.insert_multi_select_cell( + |mut options| { + options.remove(0); + options + }, + &vec![FACEBOOK, TWITTER].join(SELECTION_IDS_SEPARATOR), + ); + + test.run_scripts(builder.build()).await; } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs b/frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs index 872748fd23..366d1e6c80 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs @@ -1,15 +1,18 @@ +use crate::grid::block_test::script::RowScript::{AssertCell, CreateRow}; use crate::grid::block_test::util::GridRowTestBuilder; use crate::grid::grid_editor::GridEditorTest; use flowy_grid::entities::{CellIdentifier, FieldType, RowInfo}; - use flowy_grid::services::field::{ - DateCellDataParser, NumberCellDataParser, NumberFormat, NumberTypeOption, SelectOptionCellDataParser, - SelectOptionIdsParser, SelectOptionOperation, SingleSelectTypeOption, TextCellDataParser, URLCellDataParser, + CheckboxCellDataParser, DateCellDataParser, MultiSelectTypeOption, NumberCellDataParser, NumberTypeOption, + SelectOption, SelectOptionCellDataParser, SelectOptionIdsParser, SingleSelectTypeOption, TextCellDataParser, + URLCellDataParser, SELECTION_IDS_SEPARATOR, }; use flowy_grid_data_model::revision::{ - GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowMetaChangeset, RowRevision, + FieldRevision, GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowMetaChangeset, RowRevision, }; +use std::collections::HashMap; use std::sync::Arc; +use strum::IntoEnumIterator; pub enum RowScript { CreateEmptyRow, @@ -71,7 +74,19 @@ impl GridRowTest { } pub fn row_builder(&self) -> GridRowTestBuilder { - GridRowTestBuilder::new(self.block_id(), &self.field_revs) + let field_revs_ref = self + .field_revs + .iter() + .map(|field_rev| field_rev.as_ref()) + .collect::>(); + GridRowTestBuilder::new( + self.block_id(), + &self + .field_revs + .iter() + .map(|field_rev| field_rev.as_ref()) + .collect::>(), + ) } pub async fn run_script(&mut self, script: RowScript) { @@ -177,7 +192,7 @@ impl GridRowTest { .get_cell_bytes(&cell_id) .await .unwrap() - .with_parser(NumberCellDataParser(number_type_option.format.clone())) + .with_parser(NumberCellDataParser(number_type_option.format)) .unwrap(); assert_eq!(cell_data.to_string(), expected); } @@ -193,18 +208,45 @@ impl GridRowTest { assert_eq!(cell_data.date, expected); } FieldType::SingleSelect => { - let select_options = self + let cell_data = self .editor .get_cell_bytes(&cell_id) .await .unwrap() .with_parser(SelectOptionCellDataParser()) .unwrap(); - let select_option = select_options.select_options.first().unwrap(); + let select_option = cell_data.select_options.first().unwrap(); assert_eq!(select_option.name, expected); } - FieldType::MultiSelect => {} - FieldType::Checkbox => {} + FieldType::MultiSelect => { + let cell_data = self + .editor + .get_cell_bytes(&cell_id) + .await + .unwrap() + .with_parser(SelectOptionCellDataParser()) + .unwrap(); + + let s = cell_data + .select_options + .into_iter() + .map(|option| option.name) + .collect::>() + .join(SELECTION_IDS_SEPARATOR); + + assert_eq!(s, expected); + } + + FieldType::Checkbox => { + let cell_data = self + .editor + .get_cell_bytes(&cell_id) + .await + .unwrap() + .with_parser(CheckboxCellDataParser()) + .unwrap(); + assert_eq!(cell_data.to_string(), expected); + } FieldType::URL => { let cell_data = self .editor @@ -215,7 +257,7 @@ impl GridRowTest { .unwrap(); assert_eq!(cell_data.content, expected); - assert_eq!(cell_data.url, expected); + // assert_eq!(cell_data.url, expected); } } } @@ -234,3 +276,113 @@ impl std::ops::DerefMut for GridRowTest { &mut self.inner } } + +pub struct CreateRowScriptBuilder<'a> { + builder: GridRowTestBuilder<'a>, + data_by_field_type: HashMap, + output_by_field_type: HashMap, +} + +impl<'a> CreateRowScriptBuilder<'a> { + pub fn new(test: &'a GridRowTest) -> Self { + Self { + builder: test.row_builder(), + data_by_field_type: HashMap::new(), + output_by_field_type: HashMap::new(), + } + } + + pub fn insert(&mut self, field_type: FieldType, input: &str, expected: &str) { + self.data_by_field_type.insert( + field_type, + CellTestData { + input: input.to_string(), + expected: expected.to_owned(), + }, + ); + } + + pub fn insert_single_select_cell(&mut self, f: F, expected: &str) + where + F: Fn(Vec) -> SelectOption, + { + let field_id = self.builder.insert_single_select_cell(f); + self.output_by_field_type.insert( + FieldType::SingleSelect, + CellTestOutput { + field_id, + expected: expected.to_owned(), + }, + ); + } + + pub fn insert_multi_select_cell(&mut self, f: F, expected: &str) + where + F: Fn(Vec) -> Vec, + { + let field_id = self.builder.insert_multi_select_cell(f); + self.output_by_field_type.insert( + FieldType::MultiSelect, + CellTestOutput { + field_id, + expected: expected.to_owned(), + }, + ); + } + + pub fn build(mut self) -> Vec { + let mut scripts = vec![]; + let output_by_field_type = &mut self.output_by_field_type; + + for field_type in FieldType::iter() { + let field_type: FieldType = field_type; + if let Some(data) = self.data_by_field_type.get(&field_type) { + let field_id = match field_type { + FieldType::RichText => self.builder.insert_text_cell(&data.input), + FieldType::Number => self.builder.insert_number_cell(&data.input), + FieldType::DateTime => self.builder.insert_date_cell(&data.input), + FieldType::Checkbox => self.builder.insert_checkbox_cell(&data.input), + FieldType::URL => self.builder.insert_url_cell(&data.input), + _ => "".to_owned(), + }; + + if !field_id.is_empty() { + output_by_field_type.insert( + field_type, + CellTestOutput { + field_id, + expected: data.expected.clone(), + }, + ); + } + } + } + + let row_rev = self.builder.build(); + let row_id = row_rev.id.clone(); + scripts.push(CreateRow { row_rev }); + + for field_type in FieldType::iter() { + if let Some(data) = output_by_field_type.get(&field_type) { + let script = AssertCell { + row_id: row_id.clone(), + field_id: data.field_id.clone(), + field_type, + expected: data.expected.clone(), + }; + scripts.push(script); + } + } + scripts + } +} + +pub struct CellTestData { + pub input: String, + pub expected: String, +} + +struct CellTestOutput { + field_id: String, + expected: String, +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/block_test/util.rs b/frontend/rust-lib/flowy-grid/tests/grid/block_test/util.rs index 397c7100db..ca1e45465e 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/block_test/util.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/block_test/util.rs @@ -1,19 +1,21 @@ use flowy_grid::entities::FieldType; -use flowy_grid::services::field::selection_type_option::{SelectOption, SELECTION_IDS_SEPARATOR}; -use flowy_grid::services::field::{DateCellChangeset, MultiSelectTypeOption, SingleSelectTypeOption}; + +use flowy_grid::services::field::{ + DateCellChangeset, MultiSelectTypeOption, SelectOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, +}; use flowy_grid::services::row::RowRevisionBuilder; use flowy_grid_data_model::revision::{FieldRevision, RowRevision}; -use std::sync::Arc; + use strum::EnumCount; pub struct GridRowTestBuilder<'a> { block_id: String, - field_revs: &'a [Arc], + field_revs: &'a [&'a FieldRevision], inner_builder: RowRevisionBuilder<'a>, } impl<'a> GridRowTestBuilder<'a> { - pub fn new(block_id: &str, field_revs: &'a [Arc]) -> Self { + pub fn new(block_id: &str, field_revs: &'a [&'a FieldRevision]) -> Self { assert_eq!(field_revs.len(), FieldType::COUNT); let inner_builder = RowRevisionBuilder::new(field_revs); Self { @@ -51,11 +53,13 @@ impl<'a> GridRowTestBuilder<'a> { date_field.id.clone() } - pub fn insert_checkbox_cell(&mut self, data: &str) { - let number_field = self.field_rev_with_type(&FieldType::Checkbox); + pub fn insert_checkbox_cell(&mut self, data: &str) -> String { + let checkbox_field = self.field_rev_with_type(&FieldType::Checkbox); self.inner_builder - .insert_cell(&number_field.id, data.to_string()) + .insert_cell(&checkbox_field.id, data.to_string()) .unwrap(); + + checkbox_field.id.clone() } pub fn insert_url_cell(&mut self, data: &str) -> String { @@ -64,6 +68,7 @@ impl<'a> GridRowTestBuilder<'a> { url_field.id.clone() } + #[allow(dead_code)] pub fn insert_single_select_cell(&mut self, f: F) -> String where F: Fn(&Vec) -> &SelectOption, @@ -78,7 +83,7 @@ impl<'a> GridRowTestBuilder<'a> { single_select_field.id.clone() } - pub fn insert_multi_select_cell(&mut self, f: F) + pub fn insert_multi_select_cell(&mut self, f: F) -> String where F: Fn(&Vec) -> &Vec, { @@ -93,6 +98,8 @@ impl<'a> GridRowTestBuilder<'a> { self.inner_builder .insert_select_option_cell(&multi_select_field.id, ops_ids) .unwrap(); + + multi_select_field.id.clone() } pub fn field_rev_with_type(&self, field_type: &FieldType) -> FieldRevision { @@ -111,3 +118,17 @@ impl<'a> GridRowTestBuilder<'a> { self.inner_builder.build(&self.block_id) } } + +impl<'a> std::ops::Deref for GridRowTestBuilder<'a> { + type Target = RowRevisionBuilder<'a>; + + fn deref(&self) -> &Self::Target { + &self.inner_builder + } +} + +impl<'a> std::ops::DerefMut for GridRowTestBuilder<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner_builder + } +} diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs index 3366264936..8d6a2043d0 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs @@ -96,6 +96,14 @@ impl GridEditorTest { } } +pub const GOOGLE: &str = "Google"; +pub const FACEBOOK: &str = "Facebook"; +pub const TWITTER: &str = "Twitter"; + +pub const COMPLETED: &str = "Completed"; +pub const PLANNED: &str = "Planned"; +pub const PAUSED: &str = "Paused"; + // This grid is assumed to contain all the Fields. fn make_test_grid() -> BuildGridContext { let mut grid_builder = GridBuilder::new(); @@ -129,18 +137,18 @@ fn make_test_grid() -> BuildGridContext { FieldType::SingleSelect => { // Single Select let single_select = SingleSelectTypeOptionBuilder::default() - .option(SelectOption::new("Completed")) - .option(SelectOption::new("Planned")) - .option(SelectOption::new("Paused")); + .option(SelectOption::new(COMPLETED)) + .option(SelectOption::new(PLANNED)) + .option(SelectOption::new(PAUSED)); let single_select_field = FieldBuilder::new(single_select).name("Status").visibility(true).build(); grid_builder.add_field(single_select_field); } FieldType::MultiSelect => { // MultiSelect let multi_select = MultiSelectTypeOptionBuilder::default() - .option(SelectOption::new("Google")) - .option(SelectOption::new("Facebook")) - .option(SelectOption::new("Twitter")); + .option(SelectOption::new(GOOGLE)) + .option(SelectOption::new(FACEBOOK)) + .option(SelectOption::new(TWITTER)); let multi_select_field = FieldBuilder::new(multi_select) .name("Platform") .visibility(true) diff --git a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs index 1dffa6c0c6..b0cc2b7bb0 100644 --- a/shared-lib/flowy-sync/src/client_grid/grid_builder.rs +++ b/shared-lib/flowy-sync/src/client_grid/grid_builder.rs @@ -45,6 +45,10 @@ impl GridBuilder { self.add_row(row); } + // pub fn field_revs(&self) -> Vec { + // self.build_context.field_revs + // } + pub fn build(self) -> BuildGridContext { self.build_context }