1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
//!
//! This file is part of Ri.
//! The Ri project belongs to the Dunimd Team.
//!
//! Licensed under the Apache License, Version 2.0 (the "License");
//! You may not use this file except in compliance with the License.
//! You may obtain a copy of the License at
//!
//! http://www.apache.org/licenses/LICENSE-2.0
//!
//! Unless required by applicable law or agreed to in writing, software
//! distributed under the License is distributed on an "AS IS" BASIS,
//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//! See the License for the specific language governing permissions and
//! limitations under the License.
//! # FileSystem Module Tests
//!
//! This module contains comprehensive tests for the Ri filesystem abstraction layer,
//! covering filesystem initialization, safe directory operations, atomic file operations,
//! JSON serialization/deserialization, and category-based path management.
//!
//! ## Test Coverage
//!
//! - **RiFileSystem Initialization**: Tests for filesystem root setup including explicit
//! root path configuration and automatic root detection based on system conventions
//! - **Directory Operations**: Tests for safe directory creation, parent directory
//! enforcement, and recursive directory handling
//! - **File Operations**: Tests for atomic text and binary writes that prevent partial
//! file corruption, file reading, existence checking, and file removal
//! - **JSON Serialization**: Tests for structured data storage with automatic JSON
//! parsing and type-safe deserialization using Serde
//! - **Directory Management**: Tests for recursive directory removal and file copying
//! operations
//! - **Category Path Management**: Tests for standardized directory categories including
//! app data, logs, cache, reports, observability data, and temporary files
//!
//! ## Design Principles
//!
//! The RiFileSystem abstraction provides a safe, consistent interface for filesystem
//! operations with the following principles:
//! - **Path Safety**: All paths are normalized and validated to prevent path traversal
//! attacks and ensure operations stay within the project root
//! - **Atomic Operations**: Write operations use temporary files with atomic rename
//! to prevent data corruption from crashes or interruptions
//! - **Category Organization**: Files are organized into standard categories (logs,
//! cache, reports, etc.) for consistent structure and easy management
//! - **Error Handling**: Operations return proper error types with context rather
//! than panicking on common filesystem issues
//!
//! ## Category Directory Structure
//!
//! The filesystem maintains a standard category directory layout:
//! - **app/**: Application-specific data and configuration
//! - **logs/**: Log files and logging-related data
//! - **cache/**: Temporary cached data that can be evicted
//! - **reports/**: Generated reports and output files
//! - **observability/**: Metrics, traces, and observability data
//! - **temp/**: Temporary files with automatic cleanup semantics
//!
//! ## Path Normalization
//!
//! The filesystem provides several path normalization mechanisms:
//! - `ensure_parent_dir()`: Ensures the parent directory exists before file operations
//! - `normalize_under_category()`: Validates and normalizes paths to ensure they
//! remain within the specified category directory
//! - Category path helpers: Each category directory has a dedicated helper method
//! (app_dir(), logs_dir(), cache_dir(), etc.) that returns the category root path
//!
//! ## Atomic Write Pattern
//!
//! The atomic write pattern ensures data integrity:
//! 1. Content is written to a temporary file in the same directory (e.g., filename.tmp)
//! 2. On successful write, the temporary file is renamed to the target filename
//! 3. If a crash occurs during write, the temporary file can be cleaned up on restart
//! 4. The rename operation is atomic on most filesystems, ensuring either complete
//! old or complete new content is visible
use RiFileSystem;
use PathBuf;
use tempdir;
/// Tests RiFileSystem creation with explicit root path.
///
/// Verifies that a filesystem can be created with a specific root directory
/// using the new_with_root() constructor. The filesystem should use this
/// root as the base for all file operations.
///
/// ## Expected Behavior
///
/// - Filesystem is created with the specified root path
/// - The project_root() method returns the configured root
/// - The root path exists (it's the temp directory)
/// Tests RiFileSystem automatic root detection.
///
/// Verifies that the filesystem can automatically detect and use an
/// appropriate project root based on system conventions. The auto-detected
/// root should exist and be usable for file operations.
///
/// ## Expected Behavior
///
/// - Filesystem is created with an auto-detected root
/// - The project_root() returns a valid, existing path
/// - The root is suitable for file operations
/// Tests safe directory creation with safe_mkdir().
///
/// Verifies that the safe_mkdir() method creates directories safely,
/// returning the path of the created directory and ensuring it exists.
///
/// ## Directory Creation Behavior
///
/// - Creates the specified directory if it doesn't exist
/// - Returns the path to the created directory
/// - Does not error if the directory already exists
/// - Parent directories are not automatically created
///
/// ## Expected Behavior
///
/// - The returned path matches the requested directory
/// - The directory exists after the operation
/// Tests parent directory creation with ensure_parent_dir().
///
/// Verifies that the ensure_parent_dir() method creates parent directories
/// as needed before file operations, ensuring the path is ready for use.
///
/// ## Parent Directory Behavior
///
/// - Creates all missing parent directories recursively
/// - Returns the parent directory path
/// - Does not create the final file or directory
///
/// ## Expected Behavior
///
/// - Parent directory is created if missing
/// - The returned path is the parent directory
/// - The parent directory exists after the operation
/// Tests atomic text file writing with atomic_write_text().
///
/// Verifies that text content can be written atomically to files,
/// preventing data corruption from crashes or interruptions.
///
/// ## Atomic Write Pattern
///
/// 1. Content is written to a temporary file (filename.tmp)
/// 2. On success, the temporary file is renamed to the target
/// 3. This ensures either old or new content is visible, never partial
///
/// ## Expected Behavior
///
/// - Text content is written to the file
/// - The written content can be read back correctly
/// - The atomic write completes without errors
/// Tests atomic binary file writing with atomic_write_bytes().
///
/// Verifies that binary content can be written atomically to files,
/// ensuring data integrity for non-text data.
///
/// ## Expected Behavior
///
/// - Binary content is written to the file
/// - The written content can be read back correctly
/// - Binary data is preserved without modification
/// Tests JSON file reading with read_json().
///
/// Verifies that JSON data can be read from files and automatically
/// deserialized into typed structures using Serde.
///
/// ## Type Safety
///
/// - The target type must implement Deserialize
/// - Type mismatches result in deserialization errors
/// - Complex nested structures are supported
///
/// ## Expected Behavior
///
/// - JSON content is read from the file
/// - The data is deserialized into the target type
/// - The deserialized data matches the original
/// Tests file existence checking with exists().
///
/// Verifies that the exists() method correctly reports whether
/// a file or directory exists at the specified path.
///
/// ## Expected Behavior
///
/// - Non-existent paths return false
/// - Existing files return true
/// - The check is accurate and immediate
/// Tests file removal with remove_file().
///
/// Verifies that files can be safely removed from the filesystem,
/// and that existence checks reflect the removal.
///
/// ## Expected Behavior
///
/// - remove_file() deletes the specified file
/// - The file no longer exists after removal
/// - Attempting to remove non-existent files may error
/// Tests recursive directory removal with remove_dir_all().
///
/// Verifies that directories and their contents can be removed
/// recursively, including all files and subdirectories.
///
/// ## Expected Behavior
///
/// - The directory and all contents are removed
/// - No files remain in or under the directory
/// - The operation is recursive (handles nested structures)
/// Tests file copying with copy_file().
///
/// Verifies that files can be copied from a source path to a
/// destination path, preserving the content.
///
/// ## Copy Behavior
///
/// - Creates the destination file with the same content
/// - Does not modify the source file
/// - Overwrites destination if it exists
///
/// ## Expected Behavior
///
/// - The destination file is created
/// - The destination content matches the source
/// Tests text appending with append_text().
///
/// Verifies that text can be appended to existing files,
/// adding content at the end without overwriting.
///
/// ## Append Behavior
///
/// - Creates the file if it doesn't exist
/// - Adds content at the end of existing content
/// - Does not modify existing content
///
/// ## Expected Behavior
///
/// - The file contains the original content
/// - The appended content follows the original
/// Tests JSON file writing with write_json().
///
/// Verifies that typed data can be serialized to JSON and
/// written to files in a single operation.
///
/// ## Serialization
///
/// - The data is serialized to JSON format
/// - The JSON is written atomically to the file
/// - Complex types are supported through Serde
///
/// ## Expected Behavior
///
/// - The data is serialized and written
/// - The file contains valid JSON
/// - The data can be read back correctly
/// Tests category directory creation and access.
///
/// Verifies that standard category directories (app, logs, cache,
/// reports, observability, temp) are automatically created and
/// accessible through dedicated methods.
///
/// ## Category Directories
///
/// - app/: Application-specific data
/// - logs/: Log files
/// - cache/: Cached data
/// - reports/: Generated reports
/// - observability/: Metrics and traces
/// - temp/: Temporary files
///
/// ## Expected Behavior
///
/// - All category directories exist
/// - Each directory is under the project root
/// - Directories can be used for file operations
/// Tests category path validation with ensure_category_path().
///
/// Verifies that paths can be created within category directories
/// with proper validation and parent directory creation.
///
/// ## Expected Behavior
///
/// - The path is created within the category
/// - Parent directories are created as needed
/// - The path starts with the category directory
/// Tests category path normalization with normalize_under_category().
///
/// Verifies that paths are validated and normalized to ensure
/// they remain within the specified category directory.
///
/// ## Path Safety
///
/// - Validates the path is within the category
/// - Normalizes path separators
/// - Prevents path traversal attacks
///
/// ## Expected Behavior
///
/// - The normalized path is within the category
/// - The filename is preserved
/// - Invalid paths are rejected or normalized