EXPECT FILES - Behavioral Expectation Documentation =================================================== OVERVIEW Expect files (.expect) are pseudo-test documents that define behavioral expectations for code without implementing actual test execution. They serve as living documentation that will eventually become automated test cases. Philosophy: Document expectations incrementally during development. Convert to executable tests later. The .expect file captures intent; the test runner executes verification. FILE NAMING Expect files are named after the file they document with .expect extension: Rsx_Time.js → Rsx_Time.js.expect Rsx_Time.php → Rsx_Time.php.expect routing.txt → routing.txt.expect For man pages, a .expect file tests the concepts described rather than the file itself. Example: time.txt.expect would verify that the datetime system behaves as documented. FILE LOCATION Expect files live alongside the files they document: /system/app/RSpade/Core/Time/ Rsx_Time.php Rsx_Time.php.expect Rsx_Date.php Rsx_Date.php.expect /system/app/RSpade/Core/Js/ Rsx_Time.js Rsx_Time.js.expect Rsx_Date.js Rsx_Date.js.expect /system/app/RSpade/man/ time.txt time.txt.expect FORMAT Expect files use a simple, human-readable format designed for eventual automated parsing: EXPECT: GIVEN: WHEN: THEN: --- Each expectation block is separated by three dashes (---). EXAMPLE EXPECT: UTC storage for timestamps GIVEN: A datetime value in any timezone WHEN: Stored to database via Rsx_Time THEN: Value is stored as UTC --- EXPECT: User timezone conversion on display GIVEN: UTC timestamp from database WHEN: Formatted for display via format_datetime() THEN: Output is in user's configured timezone --- EXPECT: Null handling GIVEN: A null datetime value WHEN: Passed to format_datetime() THEN: Returns empty string without error --- WRITING EXPECTATIONS Good expectations are: - Atomic: One behavior per block - Specific: Clear about inputs and outputs - Testable: Could be converted to executable code - Independent: No dependencies between blocks Avoid: - Implementation details (how, not what) - Vague outcomes ("works correctly") - Multiple behaviors in one block LANGUAGE CONVENTIONS Use present tense for behaviors: THEN: Returns ISO 8601 format Use imperative for actions: WHEN: Call now_iso() with no arguments Reference exact method/function names: WHEN: Rsx_Time::format_datetime($timestamp) CATEGORIES Optional category prefix groups related expectations: ## Input Validation EXPECT: Reject non-ISO strings GIVEN: A malformed date string "not-a-date" WHEN: Passed to parse() THEN: Throws exception --- ## Timezone Handling EXPECT: Honor user timezone preference ... TODO EXPECTATIONS Use TODO: prefix for planned functionality that doesn't exist yet: TODO: Batch timezone conversion GIVEN: Array of timestamps WHEN: Passed to convert_batch() THEN: All timestamps converted in single operation --- TODO: Timezone autodetection from browser GIVEN: No user timezone preference set WHEN: User visits page for first time THEN: Browser timezone is detected and stored --- TODO expectations document future requirements without implying the feature exists. The test runner will skip these until converted to EXPECT blocks. CHANGE TIMESTAMPS All additions and modifications to .expect files must include a timestamp to track when expectations were documented. This creates a timeline of behavioral requirements as the codebase evolves. Format: # Added: YYYY-MM-DD or # Modified: YYYY-MM-DD Place timestamp as the last line within an expectation block: EXPECT: Parse ISO 8601 with milliseconds GIVEN: String "2024-12-24T15:30:45.123Z" WHEN: Passed to parse() THEN: Returns Carbon instance with millisecond precision # Added: 2024-12-24 --- When modifying an existing expectation, add the modification date: EXPECT: Parse ISO 8601 with milliseconds GIVEN: String "2024-12-24T15:30:45.123Z" WHEN: Passed to parse() THEN: Returns Carbon instance with millisecond precision # Added: 2024-12-24 # Modified: 2024-12-26 - Changed from DateTime to Carbon --- For file-level metadata, use a header comment: # Rsx_Time.php.expect # Created: 2024-12-24 # Last modified: 2024-12-26 ## Parsing EXPECT: Parse ISO 8601 format ... This timeline helps: - Track when specific behaviors were defined - Identify recently added/changed expectations during code review - Correlate behavioral expectations with git commits - Understand the evolution of requirements over time COMMENTS AND NOTES Expect files can include freeform comments and explanations. These help when eventually writing tests by capturing context, edge cases, and implementation hints. Use # for inline comments within blocks: EXPECT: Parse Unix timestamps GIVEN: Integer 1703432400 WHEN: Passed to parse() THEN: Returns correct datetime # Note: Must detect seconds vs milliseconds automatically # Threshold: values > 10 billion are milliseconds --- Use plain text between blocks for extended notes: ## Edge Cases The following expectations cover boundary conditions. When implementing tests, pay special attention to timezone transitions (DST changes) and leap seconds. The framework deliberately ignores leap seconds. EXPECT: Handle DST transition ... These comments are preserved in the file but ignored by the test runner. They serve as institutional knowledge for future test authors. FUTURE: AUTOMATED TEST RUNNER The planned test runner will: 1. Parse .expect files to extract test definitions 2. Generate executable test stubs in appropriate language (PHP/JS) 3. Map GIVEN/WHEN/THEN to test setup/action/assertion 4. Report coverage: which expectations have passing tests 5. Flag expectations without corresponding tests The runner will NOT modify .expect files. They remain human-maintained documentation. Tests are generated separately. Workflow: 1. Developer writes .expect file during feature development 2. Test runner audits .expect files periodically 3. Runner generates test stubs for new expectations 4. Developer completes test implementations 5. CI runs tests, reports against .expect coverage MAN PAGE EXPECTATIONS Man pages document concepts, not just APIs. A man page .expect file tests that the documented behavior actually works: # time.txt.expect - Tests for datetime system as documented EXPECT: Server time sync on page load GIVEN: Fresh page load WHEN: rsxapp object is available THEN: window.rsxapp.server_time contains ISO timestamp --- EXPECT: Ajax response time sync GIVEN: Any successful Ajax request WHEN: Response is processed THEN: Rsx_Time._server_offset is updated --- This ensures documentation stays accurate as code evolves. DISTRIBUTION Expect files are: - NOT published with bin/publish (development-only) - NOT shown in rsx:man listings - Committed to git (they are documentation) SEE ALSO testing, time, routing