| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 | 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::{CellPathParams, CreateRowParams, FieldType, GridLayout, RowPB};use flowy_grid::services::field::*;use grid_rev_model::{GridBlockMetaRevision, GridBlockMetaRevisionChangeset, RowChangeset, RowRevision};use std::collections::HashMap;use std::sync::Arc;use strum::IntoEnumIterator;pub enum RowScript {    CreateEmptyRow,    CreateRow {        row_rev: RowRevision,    },    UpdateRow {        changeset: RowChangeset,    },    AssertRow {        expected_row: RowRevision,    },    DeleteRows {        row_ids: Vec<String>,    },    AssertCell {        row_id: String,        field_id: String,        field_type: FieldType,        expected: String,    },    AssertRowCount(usize),    CreateBlock {        block: GridBlockMetaRevision,    },    UpdateBlock {        changeset: GridBlockMetaRevisionChangeset,    },    AssertBlockCount(usize),    AssertBlock {        block_index: usize,        row_count: i32,        start_row_index: i32,    },    AssertBlockEqual {        block_index: usize,        block: GridBlockMetaRevision,    },}pub struct GridRowTest {    inner: GridEditorTest,}impl GridRowTest {    pub async fn new() -> Self {        let editor_test = GridEditorTest::new_table().await;        Self { inner: editor_test }    }    pub fn last_row(&self) -> Option<RowRevision> {        self.row_revs.last().map(|a| a.clone().as_ref().clone())    }    pub async fn run_scripts(&mut self, scripts: Vec<RowScript>) {        for script in scripts {            self.run_script(script).await;        }    }    pub fn row_builder(&self) -> GridRowTestBuilder {        GridRowTestBuilder::new(self.block_id(), &self.field_revs)    }    pub async fn run_script(&mut self, script: RowScript) {        match script {            RowScript::CreateEmptyRow => {                let params = CreateRowParams {                    grid_id: self.editor.grid_id.clone(),                    start_row_id: None,                    group_id: None,                    layout: GridLayout::Table,                };                let row_order = self.editor.create_row(params).await.unwrap();                self.row_order_by_row_id                    .insert(row_order.row_id().to_owned(), row_order);                self.row_revs = self.get_row_revs().await;                self.block_meta_revs = self.editor.get_block_meta_revs().await.unwrap();            }            RowScript::CreateRow { row_rev } => {                let row_orders = self.editor.insert_rows(vec![row_rev]).await.unwrap();                for row_order in row_orders {                    self.row_order_by_row_id                        .insert(row_order.row_id().to_owned(), row_order);                }                self.row_revs = self.get_row_revs().await;                self.block_meta_revs = self.editor.get_block_meta_revs().await.unwrap();            }            RowScript::UpdateRow { changeset: change } => self.editor.update_row(change).await.unwrap(),            RowScript::DeleteRows { row_ids } => {                let row_orders = row_ids                    .into_iter()                    .map(|row_id| self.row_order_by_row_id.get(&row_id).unwrap().clone())                    .collect::<Vec<RowPB>>();                self.editor.delete_rows(row_orders).await.unwrap();                self.row_revs = self.get_row_revs().await;                self.block_meta_revs = self.editor.get_block_meta_revs().await.unwrap();            }            RowScript::AssertCell {                row_id,                field_id,                field_type,                expected,            } => {                let id = CellPathParams {                    grid_id: self.grid_id.clone(),                    field_id,                    row_id,                };                self.compare_cell_content(id, field_type, expected).await;            }            RowScript::AssertRow { expected_row } => {                let row = &*self                    .row_revs                    .iter()                    .find(|row| row.id == expected_row.id)                    .cloned()                    .unwrap();                assert_eq!(&expected_row, row);            }            RowScript::AssertRowCount(expected_row_count) => {                assert_eq!(expected_row_count, self.row_revs.len());            }            RowScript::CreateBlock { block } => {                self.editor.create_block(block).await.unwrap();                self.block_meta_revs = self.editor.get_block_meta_revs().await.unwrap();            }            RowScript::UpdateBlock { changeset: change } => {                self.editor.update_block(change).await.unwrap();            }            RowScript::AssertBlockCount(count) => {                assert_eq!(self.editor.get_block_meta_revs().await.unwrap().len(), count);            }            RowScript::AssertBlock {                block_index,                row_count,                start_row_index,            } => {                assert_eq!(self.block_meta_revs[block_index].row_count, row_count);                assert_eq!(self.block_meta_revs[block_index].start_row_index, start_row_index);            }            RowScript::AssertBlockEqual { block_index, block } => {                let blocks = self.editor.get_block_meta_revs().await.unwrap();                let compared_block = blocks[block_index].clone();                assert_eq!(compared_block, Arc::new(block));            }        }    }    async fn compare_cell_content(&self, cell_id: CellPathParams, field_type: FieldType, expected: String) {        match field_type {            FieldType::RichText => {                let cell_data = self                    .editor                    .get_cell_bytes(&cell_id)                    .await                    .unwrap()                    .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::<NumberTypeOptionPB>(FieldType::Number.into())                    .unwrap();                let cell_data = self                    .editor                    .get_cell_bytes(&cell_id)                    .await                    .unwrap()                    .custom_parser(NumberCellCustomDataParser(number_type_option.format))                    .unwrap();                assert_eq!(cell_data.to_string(), expected);            }            FieldType::DateTime => {                let cell_data = self                    .editor                    .get_cell_bytes(&cell_id)                    .await                    .unwrap()                    .parser::<DateCellDataParser>()                    .unwrap();                assert_eq!(cell_data.date, expected);            }            FieldType::SingleSelect => {                let cell_data = self                    .editor                    .get_cell_bytes(&cell_id)                    .await                    .unwrap()                    .parser::<SelectOptionCellDataParser>()                    .unwrap();                let select_option = cell_data.select_options.first().unwrap();                assert_eq!(select_option.name, expected);            }            FieldType::MultiSelect => {                let cell_data = self                    .editor                    .get_cell_bytes(&cell_id)                    .await                    .unwrap()                    .parser::<SelectOptionCellDataParser>()                    .unwrap();                let s = cell_data                    .select_options                    .into_iter()                    .map(|option| option.name)                    .collect::<Vec<String>>()                    .join(SELECTION_IDS_SEPARATOR);                assert_eq!(s, expected);            }            FieldType::Checklist => {                let cell_data = self                    .editor                    .get_cell_bytes(&cell_id)                    .await                    .unwrap()                    .parser::<SelectOptionCellDataParser>()                    .unwrap();                let s = cell_data                    .select_options                    .into_iter()                    .map(|option| option.name)                    .collect::<Vec<String>>()                    .join(SELECTION_IDS_SEPARATOR);                assert_eq!(s, expected);            }            FieldType::Checkbox => {                let cell_data = self                    .editor                    .get_cell_bytes(&cell_id)                    .await                    .unwrap()                    .parser::<CheckboxCellDataParser>()                    .unwrap();                assert_eq!(cell_data.to_string(), expected);            }            FieldType::URL => {                let cell_data = self                    .editor                    .get_cell_bytes(&cell_id)                    .await                    .unwrap()                    .parser::<URLCellDataParser>()                    .unwrap();                assert_eq!(cell_data.content, expected);                // assert_eq!(cell_data.url, expected);            }        }    }}impl std::ops::Deref for GridRowTest {    type Target = GridEditorTest;    fn deref(&self) -> &Self::Target {        &self.inner    }}impl std::ops::DerefMut for GridRowTest {    fn deref_mut(&mut self) -> &mut Self::Target {        &mut self.inner    }}pub struct CreateRowScriptBuilder<'a> {    builder: GridRowTestBuilder<'a>,    data_by_field_type: HashMap<FieldType, CellTestData>,    output_by_field_type: HashMap<FieldType, CellTestOutput>,}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<F>(&mut self, f: F, expected: &str)    where        F: Fn(Vec<SelectOptionPB>) -> SelectOptionPB,    {        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<F>(&mut self, f: F, expected: &str)    where        F: Fn(Vec<SelectOptionPB>) -> Vec<SelectOptionPB>,    {        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<RowScript> {        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,}
 |