This is a personal project. Your Mileage May Vary. Mine sure has!
Still thinking about a lot of this, especially the loud ones...
design axioms
*Focus on phase 1, build out a UI in parallel with the development of the data store.*
This software is meant to be used by one person. Someday, maybe, two or four or six. Never more than sixty.
this thing is starting to feel like a thing that could be "real", how do i feel about open source?
All data and metadata should be stored in plaintext where possible. Sqlite DBs should be fungible even if recreating them is a bit time consuming
Personal Software can be Shitty
Personal software can do inefficient things as long as it's only my time i'm wasting. i'm willing and able to throw time and compute and money at my problems. you might not be.
project stuff
i don't want to be an "open source maintainer"
i don't want to this to be a part of any "software supply chain"
THIS BABY NEEDS TO BE KEYBOARD DRIVEN WHILE ALSO PRESENTING A TOUCH INTERFACE. SOMEDAY IT NEEDS TO BE USER-MODDABLE. OH NO.
IDEALISTIC BULLSHIT: SELF-HOSTED ARCOLOGY2GO WHERE YOU EDIT THE MARKDOWN TABLE OF KEYBINDINGS OR SRC EMBEDDED COMPOSABLE AND SAVE THE DOC AND THE BINDINGS UPDATE........
i have more of this sort of stuff in the org-mode projects. lessons learned, design ideas etc. ask if curious.
testing
test coverage should always remain above 50%. check with
./gradlew :koverHtmlReport -x testDebugUnitTest -x testReleaseUnitTestand openbuild/reports/kover/html/index.htmlnever mark test failures as "known issues" and move on. fix the root cause or revert the change that broke them.
run
./gradlew :jvmTestbefore committing. all tests must pass.
Android Unit Tests
For Android-specific tests (in app/src/test/kotlin/), you need to:
Add JUnit dependencies for test files that use JUnit annotations (@Test, @Before, @After):
#+begin_src kotlin // In app/build.gradle.kts dependencies { testImplementation(libs.junit) testImplementation(libs.androidx.test.junit) testImplementation(libs.androidx.test.core) } #+end_src
When testing ViewModels that use AppPreferences, create a test double instead of mocking:
#+begin_src kotlin // Create a test double class in app/src/test/kotlin/.../testutils/AppPreferencesTestDouble.kt class AppPreferencesTestDouble( selectedDirectoryUri: Uri? = null, captureSubdirectory: String = "journals", // ... other parameters with defaults ) : AppPreferencesInterface
// Then in your test: class MyViewModelTest { private lateinit var appPreferences: AppPreferencesInterface
@Before fun setup() { appPreferences = AppPreferencesTestDouble( todoStates = listOf("TODO", "DONE") ) // ... } } #+end_src
See app/src/test/kotlin/computer/whatthefuck/arcology/app/testutils/AppPreferencesTestDouble.kt
for the full implementation and app/src/test/kotlin/computer/whatthefuck/arcology/app/viewmodel/CaptureViewModelTest.kt
for example usage.
Using Instant for Date/Time
When testing code that uses `kotlin.time.Instant` (e.g., for flashcard due dates), add the `@OptIn(ExperimentalTime::class)` annotation to test methods:
#+begin_src kotlin import kotlin.time.ExperimentalTime
@Test @OptIn(ExperimentalTime::class) fun `test with Instant`() = runTest { val dueDate = Instant.fromEpochSeconds(1640995200) // ... } #+end_src
See app/src/test/kotlin/computer/whatthefuck/arcology/app/viewmodel/QuizViewModelTest.kt
for complete examples.
Coverage Targets
The project maintains ~54% line coverage (excluding generated code). The floor is 50%.
Key coverage levels by module:
Parser: 91.9% (well-tested, property-based tests)
Core domain logic: 80%+
ViewModels: Variable (some have 50+ tests, others untested)
Compose UI: 0% (instrumentation tests infrastructure exists but unused)
Remaining Test Work
Modules needing test coverage:
SearchService(0%, 66 lines) — pure class, easy to testOrgDocumentEditor(20%, 416 lines) — hasTestFileSystem, needs operation testsKML export (0%, 54 lines) — needs mock data
EditorViewModel,MapViewModel,GraphViewModel,FilesViewModel— no unit tests (deprecatedOrgDocumentEditorViewModelhas comprehensive tests)
Test Patterns
Property-based tests use Kotest Arb generators (OrgContentGenerators.kt):
Fuzzing with arbitrary strings, generated documents, random property drawers
Invariant checks: ID extraction, link consistency, hash determinism
Edge case tests cover:
BOM, CRLF, Unicode (CJK/Arabic/emoji), malformed properties
Deep hierarchies (10+ levels), outline paths, sibling headings
Tables with formulas, wide tables
Integration tests:
Real org-roam directory parsing (tagged
@Tag("integration"), runs separately)Large file stress tests (500+ nodes)