text_document_test_harness/
lib.rs1use anyhow::Result;
11use common::database::db_context::DbContext;
12use common::entities::InlineContent;
13use common::event::EventHub;
14use common::types::EntityId;
15use common::undo_redo::UndoRedoManager;
16use std::sync::Arc;
17
18pub use common::direct_access::block::block_repository::BlockRelationshipField;
20pub use common::direct_access::document::document_repository::DocumentRelationshipField;
21pub use common::direct_access::frame::frame_repository::FrameRelationshipField;
22pub use common::direct_access::root::root_repository::RootRelationshipField;
23
24pub use common::direct_access::table::table_repository::TableRelationshipField;
25pub use common::direct_access::table_cell::table_cell_repository::TableCellRelationshipField;
26pub use direct_access::block::block_controller;
27pub use direct_access::block::dtos::CreateBlockDto;
28pub use direct_access::document::document_controller;
29pub use direct_access::document::dtos::CreateDocumentDto;
30pub use direct_access::frame::dtos::CreateFrameDto;
31pub use direct_access::frame::frame_controller;
32pub use direct_access::inline_element::dtos::CreateInlineElementDto;
33pub use direct_access::inline_element::inline_element_controller;
34pub use direct_access::root::dtos::CreateRootDto;
35pub use direct_access::root::root_controller;
36pub use direct_access::table::dtos::TableDto;
37pub use direct_access::table::table_controller;
38pub use direct_access::table_cell::dtos::TableCellDto;
39pub use direct_access::table_cell::table_cell_controller;
40
41pub fn setup() -> Result<(DbContext, Arc<EventHub>, UndoRedoManager)> {
45 let db_context = DbContext::new()?;
46 let event_hub = Arc::new(EventHub::new());
47 let mut undo_redo_manager = UndoRedoManager::new();
48
49 let root = root_controller::create_orphan(&db_context, &event_hub, &CreateRootDto::default())?;
50
51 let _doc = document_controller::create(
52 &db_context,
53 &event_hub,
54 &mut undo_redo_manager,
55 None,
56 &CreateDocumentDto::default(),
57 root.id,
58 -1,
59 )?;
60
61 Ok((db_context, event_hub, undo_redo_manager))
62}
63
64pub fn setup_with_text(text: &str) -> Result<(DbContext, Arc<EventHub>, UndoRedoManager)> {
72 let (db_context, event_hub, mut undo_redo_manager) = setup()?;
73
74 let root_rels =
76 root_controller::get_relationship(&db_context, &1, &RootRelationshipField::Document)?;
77 let doc_id = root_rels[0];
78 let frame_ids = document_controller::get_relationship(
79 &db_context,
80 &doc_id,
81 &DocumentRelationshipField::Frames,
82 )?;
83
84 for fid in &frame_ids {
86 frame_controller::remove(&db_context, &event_hub, &mut undo_redo_manager, None, fid)?;
87 }
88
89 let frame = frame_controller::create(
91 &db_context,
92 &event_hub,
93 &mut undo_redo_manager,
94 None,
95 &CreateFrameDto::default(),
96 doc_id,
97 -1,
98 )?;
99
100 let normalized = text.replace("\r\n", "\n").replace('\r', "\n");
102 let lines: Vec<&str> = normalized.split('\n').collect();
103 let mut document_position: i64 = 0;
104 let mut total_chars: i64 = 0;
105
106 for (i, line) in lines.iter().enumerate() {
107 let line_len = line.chars().count() as i64;
108
109 let block_dto = CreateBlockDto {
110 plain_text: line.to_string(),
111 text_length: line_len,
112 document_position,
113 ..Default::default()
114 };
115
116 let block = block_controller::create(
117 &db_context,
118 &event_hub,
119 &mut undo_redo_manager,
120 None,
121 &block_dto,
122 frame.id,
123 i as i32,
124 )?;
125
126 let elem_dto = CreateInlineElementDto {
127 content: InlineContent::Text(line.to_string()),
128 ..Default::default()
129 };
130
131 inline_element_controller::create(
132 &db_context,
133 &event_hub,
134 &mut undo_redo_manager,
135 None,
136 &elem_dto,
137 block.id,
138 0,
139 )?;
140
141 total_chars += line_len;
142 document_position += line_len;
143 if i < lines.len() - 1 {
144 document_position += 1; }
146 }
147
148 let mut doc = document_controller::get(&db_context, &doc_id)?
150 .ok_or_else(|| anyhow::anyhow!("Document not found"))?;
151 doc.character_count = total_chars;
152 doc.block_count = lines.len() as i64;
153 document_controller::update(
154 &db_context,
155 &event_hub,
156 &mut undo_redo_manager,
157 None,
158 &doc.into(),
159 )?;
160
161 undo_redo_manager.clear_all_stacks();
163
164 Ok((db_context, event_hub, undo_redo_manager))
165}
166
167pub fn export_text(db_context: &DbContext, _event_hub: &Arc<EventHub>) -> Result<String> {
170 let block_ids = get_block_ids(db_context)?;
171 let mut blocks = Vec::new();
172 for id in &block_ids {
173 if let Some(b) = block_controller::get(db_context, id)? {
174 blocks.push(b);
175 }
176 }
177 blocks.sort_by_key(|b| b.document_position);
178 let text = blocks
179 .iter()
180 .map(|b| b.plain_text.as_str())
181 .collect::<Vec<&str>>()
182 .join("\n");
183 Ok(text)
184}
185
186pub fn get_block_ids(db_context: &DbContext) -> Result<Vec<EntityId>> {
188 let root_rels =
189 root_controller::get_relationship(db_context, &1, &RootRelationshipField::Document)?;
190 let doc_id = root_rels[0];
191 let frame_ids = document_controller::get_relationship(
192 db_context,
193 &doc_id,
194 &DocumentRelationshipField::Frames,
195 )?;
196 let frame_id = frame_ids[0];
197 frame_controller::get_relationship(db_context, &frame_id, &FrameRelationshipField::Blocks)
198}
199
200pub fn get_element_ids(db_context: &DbContext, block_id: &EntityId) -> Result<Vec<EntityId>> {
202 block_controller::get_relationship(db_context, block_id, &BlockRelationshipField::Elements)
203}
204
205pub fn get_first_block_element_ids(db_context: &DbContext) -> Result<Vec<EntityId>> {
207 let block_ids = get_block_ids(db_context)?;
208 get_element_ids(db_context, &block_ids[0])
209}
210
211pub fn get_frame_id(db_context: &DbContext) -> Result<EntityId> {
213 let root_rels =
214 root_controller::get_relationship(db_context, &1, &RootRelationshipField::Document)?;
215 let doc_id = root_rels[0];
216 let frame_ids = document_controller::get_relationship(
217 db_context,
218 &doc_id,
219 &DocumentRelationshipField::Frames,
220 )?;
221 Ok(frame_ids[0])
222}
223
224pub fn get_table_ids(db_context: &DbContext) -> Result<Vec<EntityId>> {
226 let root_rels =
227 root_controller::get_relationship(db_context, &1, &RootRelationshipField::Document)?;
228 let doc_id = root_rels[0];
229 document_controller::get_relationship(db_context, &doc_id, &DocumentRelationshipField::Tables)
230}
231
232pub fn get_table_cell_ids(db_context: &DbContext, table_id: &EntityId) -> Result<Vec<EntityId>> {
234 table_controller::get_relationship(db_context, table_id, &TableRelationshipField::Cells)
235}
236
237pub fn get_sorted_cells(db_context: &DbContext, table_id: &EntityId) -> Result<Vec<TableCellDto>> {
239 let cell_ids = get_table_cell_ids(db_context, table_id)?;
240 let cells_opt = table_cell_controller::get_multi(db_context, &cell_ids)?;
241 let mut cells: Vec<TableCellDto> = cells_opt.into_iter().flatten().collect();
242 cells.sort_by(|a, b| a.row.cmp(&b.row).then(a.column.cmp(&b.column)));
243 Ok(cells)
244}
245
246pub fn get_all_block_ids(db_context: &DbContext) -> Result<Vec<EntityId>> {
248 let root_rels =
249 root_controller::get_relationship(db_context, &1, &RootRelationshipField::Document)?;
250 let doc_id = root_rels[0];
251 let frame_ids = document_controller::get_relationship(
252 db_context,
253 &doc_id,
254 &DocumentRelationshipField::Frames,
255 )?;
256 let mut all_block_ids = Vec::new();
257 for fid in &frame_ids {
258 let block_ids =
259 frame_controller::get_relationship(db_context, fid, &FrameRelationshipField::Blocks)?;
260 all_block_ids.extend(block_ids);
261 }
262 Ok(all_block_ids)
263}
264
265pub struct BasicStats {
267 pub character_count: i64,
268 pub block_count: i64,
269 pub frame_count: i64,
270}
271
272pub fn get_document_stats(db_context: &DbContext) -> Result<BasicStats> {
274 let root_rels =
275 root_controller::get_relationship(db_context, &1, &RootRelationshipField::Document)?;
276 let doc_id = root_rels[0];
277 let doc = document_controller::get(db_context, &doc_id)?
278 .ok_or_else(|| anyhow::anyhow!("Document not found"))?;
279 let frame_ids = document_controller::get_relationship(
280 db_context,
281 &doc_id,
282 &DocumentRelationshipField::Frames,
283 )?;
284 Ok(BasicStats {
285 character_count: doc.character_count,
286 block_count: doc.block_count,
287 frame_count: frame_ids.len() as i64,
288 })
289}