Four milestones from the survey's remaining gaps
M17 - the mark of a change. A dot on the rows an operation produced, spent by the next read of that folder: in memory, per folder, no timer and no watcher. Copy, move, compress, extract, rename (single and batch) and new folders all mark what they made, so "what did that 4 GB copy do?" has an answer even when the copy went to a folder the user was not looking at. The dot is drawn by MarkOfChange in the list and the grid, with a content description, and `changed` is set by the same state update that announces the folder. M18 - store-only archives. Compressing now asks for the name and whether to compress, because the survey's most enthusiastic review is a bulk copy to a computer and that file is better stored than squeezed. Deflater.NO_COMPRESSION keeps it one pass; a STORED entry would need size and CRC before the header, i.e. reading every file twice. M19 - the trash says what it does. The screen states the 24-hour window, offers Empty trash behind one question, and opening the trash sweeps what has expired - the window used to run only after the next delete, so an old batch could stay on the card indefinitely. Trash.emptyAll leaves anything in that folder that is not one of ours alone. M20 - launcher shortcuts. Images, Recent and Trash as static shortcuts carrying a route extra; core/ShortcutRoute answers null for anything it does not know, so an old shortcut cannot crash a new build. Favourites was dropped from the plan: it is a section of the home screen, not a view, so a shortcut to it would promise something that may not be there. M21 (Android TV) is specified in the roadmap and deliberately not started: its acceptance needs a TV device pass this machine cannot provide. 18 new tests (427 in total). Detekt's baseline was regenerated after two signatures gained a parameter; the diff is three findings with new signatures and their KDoc moved above the annotations so the baseline stays readable. Verified by the gate only so far - the device pass for these four is next, and the terminal here has been losing command output for the last hour.
This commit is contained in:
+40
-15
@@ -2,7 +2,7 @@
|
||||
|
||||
Generated from the source by `tools/make-code-map.py` - do not edit by hand. Regenerate it after a change (`python3 tools/make-code-map.py`); `--check` exits non-zero when this file is stale.
|
||||
|
||||
79 source files, 13481 lines - 35 test files, 409 tests. The behaviour index at the end lists every test name, and in this project a test name is a sentence about what the app does, so it doubles as the specification.
|
||||
80 source files, 13841 lines - 37 test files, 427 tests. The behaviour index at the end lists every test name, and in this project a test name is a sentence about what the app does, so it doubles as the specification.
|
||||
|
||||
Start at `AGENTS.md`. What is done, and why: `docs/ROADMAP.md` and `CHANGELOG.md`. What was verified by hand rather than by a test: `docs/EDGE_CASE_TESTING.md`.
|
||||
|
||||
@@ -23,6 +23,7 @@ Pure Kotlin, **no Android imports**: paths, file names, kinds, sorting, formatti
|
||||
| `MimeTypes.kt` | 110 | Best-effort MIME lookup for the "open with" intent. MimeTypes | `FileEntryTest` (8) |
|
||||
| `NameAllocator.kt` | 30 | Picks a name that is not already in use, in the familiar "name (1)" style. NameAllocator | `NameMatcherTest` (10) |
|
||||
| `NameMatcher.kt` | 63 | The in-folder search matcher. NameMatcher | `NameMatcherTest` (10) |
|
||||
| `ShortcutRoute.kt` | 27 | Where a launcher shortcut asks the app to open. ShortcutRoute | `ShortcutRouteTest` (2) |
|
||||
| `SortSpec.kt` | 82 | A complete, serialisable description of the ordering of a directory listing. SortKey, SortDirection, SortSpec, NaturalOrder | `SortSpecTest` (8) |
|
||||
| `SortedMerge.kt` | 42 | Adds a freshly read batch to an already sorted list, in one pass. SortedMerge | `SortedMergeTest` (4) |
|
||||
| `StoragePath.kt` | 89 | A normalized, absolute, backend-agnostic storage path. StoragePath | `StoragePathTest` (8) |
|
||||
@@ -61,14 +62,14 @@ Operations over a source: copy/move/delete/rename, archives, search walking, dup
|
||||
|
||||
| file | lines | what it holds | tests |
|
||||
|---|---|---|---|
|
||||
| `ArchiveEngine.kt` | 658 | Creates and extracts archives, on top of the storage backends. ArchiveEntry, ArchiveEngine | `ArchiveEngineTest` (30) |
|
||||
| `ArchiveEngine.kt` | 667 | Creates and extracts archives, on top of the storage backends. ArchiveEntry, ArchiveEngine | `ArchiveEngineTest` (31) |
|
||||
| `DuplicateFinder.kt` | 202 | Finds files that hold the same bytes. DuplicateGroup, DuplicateProgress, DuplicateScan, DuplicateFinder | `DuplicateFinderTest` (8) |
|
||||
| `FileOperations.kt` | 272 | Copy, move and delete, assembled from the StorageSource primitives. FileOperations | `FileOperationsTest` (19) |
|
||||
| `FileSearch.kt` | 79 | Recursive name search. FileSearch | `FileSearchTest` (8) |
|
||||
| `OperationModels.kt` | 42 | The kind of long-running operation a progress notification can describe. OperationKind, OperationProgress, OperationFailure, OperationResult | - |
|
||||
| `OperationNotifier.kt` | 25 | Keeps the foreground service in step with a running operation. OperationNotifier | - |
|
||||
| `SearchIndexer.kt` | 173 | Fills a SearchIndex by walking a volume. SearchIndexer | `SearchIndexerTest` (14) |
|
||||
| `Trash.kt` | 338 | A staging folder that makes a delete undoable. TrashedEntry, TrashBatch, Trash | `TrashTest` (19) |
|
||||
| `Trash.kt` | 360 | A staging folder that makes a delete undoable. TrashedEntry, TrashBatch, Trash | `TrashTest` (20) |
|
||||
| `UsageAnalysis.kt` | 95 | Works out where the space went. UsageNode, UsageAnalysis | `UsageAnalysisTest` (6) |
|
||||
|
||||
## service/
|
||||
@@ -95,15 +96,15 @@ The browser screen: view model, state, list and grid, dialogs, selection bar
|
||||
|
||||
| file | lines | what it holds | tests |
|
||||
|---|---|---|---|
|
||||
| `BrowserComponents.kt` | 317 | The thumbnail an entry's leading visual gets in a list row. ListThumbnailSize, GridThumbnailSize, GridCellMinSize, EntryIcon(), FileEntry(), FileEntry(), VIDEO_FRAME_MILLIS, iconFor(), iconFor(), EntryRow(), EntryGridCell(), FileEntry() | - |
|
||||
| `BrowserContent.kt` | 463 | Everything below the app bar: the permission prompt, the roots, or a directory. WIDE_LAYOUT_MIN_WIDTH, MasterPaneWidth, BrowserContent(), LazyListScope(), LIBRARY_SECTION_KEY, LazyListScope(), BOOKMARK_SECTION_KEY, DirectoryView(), FileEntry(), IndexStatusRow(), FileEntry() | - |
|
||||
| `BrowserComponents.kt` | 365 | The thumbnail an entry's leading visual gets in a list row. ListThumbnailSize, GridThumbnailSize, GridCellMinSize, EntryIcon(), FileEntry(), FileEntry(), VIDEO_FRAME_MILLIS, iconFor(), iconFor(), MarkOfChange(), EntryRow(), EntryGridCell(), FileEntry() | `BrowserComponentsTest` (3) |
|
||||
| `BrowserContent.kt` | 465 | Everything below the app bar: the permission prompt, the roots, or a directory. WIDE_LAYOUT_MIN_WIDTH, MasterPaneWidth, BrowserContent(), LazyListScope(), LIBRARY_SECTION_KEY, LazyListScope(), BOOKMARK_SECTION_KEY, DirectoryView(), FileEntry(), IndexStatusRow(), FileEntry() | - |
|
||||
| `BrowserDetailPane.kt` | 131 | The second pane of the wide layout: what is inside the folder the user picked, or a preview and the details of the file they picked. DetailPane(), FolderPreview(), ImagePreview() | - |
|
||||
| `BrowserDialogs.kt` | 385 | The Copy to… / Move to… picker. TransferToDialog(), titleFor(), hereFor(), BatchRenameDialog(), PREVIEW_NAMES, batchRenameNote(), NameDialog(), ConfirmDialog(), ConflictDialog() | `BrowserDialogsTest` (5) |
|
||||
| `BrowserDialogs.kt` | 444 | Compressing something, with the one choice that changes what comes out. CompressDialog(), TransferToDialog(), titleFor(), hereFor(), BatchRenameDialog(), PREVIEW_NAMES, batchRenameNote(), NameDialog(), ConfirmDialog(), ConflictDialog() | `BrowserDialogsTest` (5) |
|
||||
| `BrowserRoots.kt` | 270 | A row on the root screen: a volume, with its free space when the platform reports it. RootRow(), itemCountLabel(), EmptyState(), LibrarySectionHeader(), BookmarkSectionHeader(), SectionHeader(), BookmarkRow(), LibraryRow(), Breadcrumbs() | `BrowserRootsTest` (4) |
|
||||
| `BrowserScreen.kt` | 622 | The text of a snackbar message. BrowserScreen(), messageText() | - |
|
||||
| `BrowserScreen.kt` | 661 | The browser, and everything that can be on top of it. BrowserScreen(), messageText() | - |
|
||||
| `BrowserTopBar.kt` | 238 | The browser's app bar: title, up, the favourite star, and the search / sort / overflow actions. BrowserTopBar(), SEARCH_FIELD_WIDTH | `BrowserTopBarTest` (4) |
|
||||
| `BrowserUiState.kt` | 379 | One immutable description of everything the browser shows. ViewMode, SearchScope, Clipboard, PickerFolder, TransferPicker, MessageAction, UiMessage, ConflictPrompt, RootItem, Bookmark, DetailFocus, Undo, UndoMove, Overlay, BrowserUiState | - |
|
||||
| `BrowserViewModel.kt` | 2430 | Drives the browser screen. BrowserViewModel, ArchivePreview | `BrowserViewModelTest` (102) |
|
||||
| `BrowserUiState.kt` | 391 | One immutable description of everything the browser shows. ViewMode, SearchScope, Clipboard, CompressRequest, PickerFolder, TransferPicker, MessageAction, UiMessage, ConflictPrompt, RootItem, Bookmark, DetailFocus, Undo, UndoMove, Overlay, BrowserUiState | - |
|
||||
| `BrowserViewModel.kt` | 2540 | Drives the browser screen. BrowserViewModel, ArchivePreview | `BrowserViewModelTest` (113) |
|
||||
| `DetailsSheet.kt` | 109 | Name, location, size, type and modified date for one entry. DetailsSheet(), DetailLines(), DetailLine() | - |
|
||||
| `EntryIntents.kt` | 58 | Wraps an entry's path in a content:// URI another app may read. contentUriFor(), viewIntent(), shareIntent() | - |
|
||||
| `IncomingBar.kt` | 60 | The bar shown while another app is waiting on this one. IncomingBar() | - |
|
||||
@@ -139,7 +140,7 @@ The trash screen
|
||||
|
||||
| file | lines | what it holds | tests |
|
||||
|---|---|---|---|
|
||||
| `TrashScreen.kt` | 192 | What the trash still holds, and the way to put it back. TrashScreen(), BatchHeader(), TrashEntryRow() | - |
|
||||
| `TrashScreen.kt` | 220 | What the trash still holds, and the way to put it back. TrashScreen(), BatchHeader(), TrashEntryRow() | - |
|
||||
|
||||
## ui/duplicates/
|
||||
|
||||
@@ -164,7 +165,7 @@ Compose theme, colours, type
|
||||
| file | lines | what it holds | tests |
|
||||
|---|---|---|---|
|
||||
| `FileManagerApplication.kt` | 151 | Application entry point and the app's tiny object graph. FileManagerApplication | - |
|
||||
| `MainActivity.kt` | 65 | MainActivity | - |
|
||||
| `MainActivity.kt` | 69 | MainActivity | - |
|
||||
|
||||
## benchmark/
|
||||
|
||||
@@ -279,6 +280,11 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- treats a dotfile as having no extension
|
||||
- preserves the base of multi-dot names
|
||||
|
||||
### `core/ShortcutRouteTest.kt` (2)
|
||||
|
||||
- each shortcut key maps to its route
|
||||
- anything else is ignored rather than thrown
|
||||
|
||||
### `core/SortSpecTest.kt` (8)
|
||||
|
||||
- directories come first in both directions
|
||||
@@ -427,9 +433,10 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- a volume without a space reading contributes nothing
|
||||
- used bytes never go negative
|
||||
|
||||
### `domain/ArchiveEngineTest.kt` (30)
|
||||
### `domain/ArchiveEngineTest.kt` (31)
|
||||
|
||||
- a zip round-trips folders and files
|
||||
- an uncompressed zip round-trips and is larger than a squeezed one
|
||||
- createZip reports progress over the files it will write
|
||||
- a zip-slip entry cannot escape the destination
|
||||
- a single-file gzip is unwrapped to its inner name
|
||||
@@ -521,8 +528,9 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- the timestamp is stamped from the clock when the pass finishes
|
||||
- a second pass replaces the first rather than doubling it
|
||||
|
||||
### `domain/TrashTest.kt` (19)
|
||||
### `domain/TrashTest.kt` (20)
|
||||
|
||||
- emptying removes every batch and leaves what is not one
|
||||
- staging moves an item aside and records where it came from
|
||||
- restoring puts an item back exactly where it was
|
||||
- a folder comes back whole
|
||||
@@ -559,6 +567,12 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- a determinate operation shows the counter
|
||||
- starting the service puts it in the foreground with that title
|
||||
|
||||
### `ui/browser/BrowserComponentsTest.kt` (3)
|
||||
|
||||
- a row an operation produced carries the mark
|
||||
- an ordinary row carries no mark
|
||||
- a grid cell an operation produced carries the mark too
|
||||
|
||||
### `ui/browser/BrowserDialogsTest.kt` (5)
|
||||
|
||||
- the batch dialog spells the names out before anything moves
|
||||
@@ -581,7 +595,7 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- a library or the root list has nothing to star
|
||||
- the star gives way to the search field
|
||||
|
||||
### `ui/browser/BrowserViewModelTest.kt` (102)
|
||||
### `ui/browser/BrowserViewModelTest.kt` (113)
|
||||
|
||||
- starts on the root list
|
||||
- opening a folder lists it with directories first and natural order
|
||||
@@ -601,6 +615,17 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- a paste into the folder on screen names no destination and offers no action
|
||||
- the message's undo action is the undo
|
||||
- a move to a chosen folder offers undo rather than show
|
||||
- a copy into the folder on screen marks the copy
|
||||
- a copy into another folder marks it there, not here
|
||||
- reading the folder again spends its marks
|
||||
- a rename marks the name it produced
|
||||
- compressing asks for a name and a choice before writing
|
||||
- a confirmed compress writes the name that was typed, and marks it
|
||||
- cancelling the compress dialog writes nothing
|
||||
- opening the trash sweeps what has expired
|
||||
- opening the trash keeps what is still inside the window
|
||||
- emptying the trash removes what is in it
|
||||
- a shortcut opens the view it names
|
||||
- navigating up goes to the parent then to the roots
|
||||
- selection survives toggling and clears on navigation
|
||||
- a file with no preview of its own is handed to the system
|
||||
@@ -698,4 +723,4 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
|
||||
---
|
||||
|
||||
Purpose taken from the first KDoc rather than from a declaration sharing the file's name (15 of 78): `MainActivity.kt`, `ArchiveFormats.kt`, `FileNames.kt`, `ApkInspector.kt`, `OperationModels.kt`, `TextRes.kt`, `BrowserComponents.kt`, `BrowserDetailPane.kt`, `BrowserDialogs.kt`, `BrowserRoots.kt`, `BrowserScreen.kt`, `EntryIntents.kt`, `Color.kt`, `Theme.kt`, `Type.kt`
|
||||
Purpose taken from the first KDoc rather than from a declaration sharing the file's name (14 of 79): `MainActivity.kt`, `ArchiveFormats.kt`, `FileNames.kt`, `ApkInspector.kt`, `OperationModels.kt`, `TextRes.kt`, `BrowserComponents.kt`, `BrowserDetailPane.kt`, `BrowserDialogs.kt`, `BrowserRoots.kt`, `EntryIntents.kt`, `Color.kt`, `Theme.kt`, `Type.kt`
|
||||
|
||||
Reference in New Issue
Block a user