|
| 1 | +# Protocol YAML Roundtrip Testing |
| 2 | + |
| 3 | +Validates that YAML protocol files generated by the **web experiment designer** (`experiment_designer.html`) are fully compatible with the **MATLAB experiment runner** (`ProtocolParser` + `ProtocolRunner`). |
| 4 | + |
| 5 | +## Architecture |
| 6 | + |
| 7 | +``` |
| 8 | +Web (JavaScript) MATLAB |
| 9 | +───────────────── ────────────────────── |
| 10 | +experiment_designer.html ProtocolParser.m |
| 11 | + └─ generateYAML() └─ parse() |
| 12 | + │ │ |
| 13 | + ▼ ▼ |
| 14 | + V1 Protocol YAML ───────────────> Parsed protocol struct |
| 15 | + │ │ |
| 16 | + │ ▼ |
| 17 | + │ ProtocolRunner constructor |
| 18 | + │ (validates structure) |
| 19 | + ▼ |
| 20 | + simpleYAMLParse() |
| 21 | + (web-side parse-back) |
| 22 | +``` |
| 23 | + |
| 24 | +### Test Coverage |
| 25 | + |
| 26 | +| Layer | Test | Runs in CI? | |
| 27 | +|-------|------|-------------| |
| 28 | +| Web YAML generation + parse | `test-protocol-roundtrip.js` | Yes (Node.js) | |
| 29 | +| Web YAML → file generation | `generate-roundtrip-protocol.js` | Yes (Node.js) | |
| 30 | +| MATLAB parse + validate | `validate_web_protocol_roundtrip.m` | No (needs MATLAB license) | |
| 31 | +| MATLAB ProtocolRunner construction | `validate_web_protocol_roundtrip.m` | No (needs MATLAB license) | |
| 32 | + |
| 33 | +## Running Tests |
| 34 | + |
| 35 | +### Web-side CI test (no dependencies) |
| 36 | + |
| 37 | +```bash |
| 38 | +cd webDisplayTools |
| 39 | +node tests/test-protocol-roundtrip.js |
| 40 | +``` |
| 41 | + |
| 42 | +Tests 49 checks across 5 suites: |
| 43 | +1. **V1 Generate → Parse Roundtrip** — full field-by-field comparison |
| 44 | +2. **Comment-Handling Regression** — comments between conditions (bug fix validation) |
| 45 | +3. **Excluded Phases** — pretrial/intertrial/posttrial with `include: false` |
| 46 | +4. **Numeric Type Preservation** — ints, floats, booleans parse correctly |
| 47 | +5. **Inline Comments** — comments don't interfere with parsing |
| 48 | + |
| 49 | +Exit code 0 = all passed, 1 = failures. |
| 50 | + |
| 51 | +### Re-generate test YAML for MATLAB |
| 52 | + |
| 53 | +```bash |
| 54 | +cd webDisplayTools |
| 55 | +node tests/generate-roundtrip-protocol.js --outdir ../maDisplayTools/tests/web_generated_patterns |
| 56 | +``` |
| 57 | + |
| 58 | +Generates: |
| 59 | +- `test_protocol_v1.yaml` — V1 protocol with 3 conditions |
| 60 | +- `test_protocol_manifest.json` — expected values for MATLAB validation |
| 61 | + |
| 62 | +The generator also runs 27 self-verification checks. |
| 63 | + |
| 64 | +### MATLAB validation (requires MATLAB license) |
| 65 | + |
| 66 | +```matlab |
| 67 | +cd maDisplayTools |
| 68 | +results = validate_web_protocol_roundtrip('v1'); |
| 69 | +``` |
| 70 | + |
| 71 | +Tests 28 checks: |
| 72 | +1. ProtocolParser can parse the YAML |
| 73 | +2. Version = 1 |
| 74 | +3. Experiment info (name) |
| 75 | +4. Arena config (generation, rows, cols) |
| 76 | +5. Experiment structure (repetitions) |
| 77 | +6. Number of conditions = 3 |
| 78 | +7. Per-condition: id, pattern, duration, frame_rate, mode (x3 conditions) |
| 79 | +8. Phase includes (pretrial, intertrial, posttrial) |
| 80 | +9. Pretrial command count = 4 |
| 81 | +10. ProtocolRunner construction (validates full pipeline) |
| 82 | + |
| 83 | +V2 test available but stubbed: `validate_web_protocol_roundtrip('v2')` returns early until V2 format is finalized. |
| 84 | + |
| 85 | +## Files |
| 86 | + |
| 87 | +### Web side (`webDisplayTools/`) |
| 88 | + |
| 89 | +| File | Purpose | |
| 90 | +|------|---------| |
| 91 | +| `tests/test-protocol-roundtrip.js` | CI-ready regression test (49 checks) | |
| 92 | +| `tests/generate-roundtrip-protocol.js` | YAML + manifest generator for MATLAB validation | |
| 93 | + |
| 94 | +### MATLAB side (`maDisplayTools/`) |
| 95 | + |
| 96 | +| File | Purpose | |
| 97 | +|------|---------| |
| 98 | +| `tests/validate_web_protocol_roundtrip.m` | MATLAB validation (28 checks, parameterized V1/V2) | |
| 99 | +| `tests/web_generated_patterns/test_protocol_v1.yaml` | Generated test YAML | |
| 100 | +| `tests/web_generated_patterns/test_protocol_manifest.json` | Expected values manifest | |
| 101 | + |
| 102 | +## What to Update When Changing YAML Format |
| 103 | + |
| 104 | +### Adding new fields to V1 |
| 105 | + |
| 106 | +1. Update `generateV1Protocol()` in both: |
| 107 | + - `generate-roundtrip-protocol.js` (generates files) |
| 108 | + - `test-protocol-roundtrip.js` (in-memory test) |
| 109 | +2. Add expected values to the `testProtocol` definition |
| 110 | +3. Add check assertions |
| 111 | +4. Re-generate: `node tests/generate-roundtrip-protocol.js --outdir ...` |
| 112 | +5. Update `validate_web_protocol_roundtrip.m` with new field checks |
| 113 | +6. Update manifest expected values count |
| 114 | + |
| 115 | +### Adding V2 support |
| 116 | + |
| 117 | +1. Add `generateV2Protocol()` to generator and test scripts |
| 118 | +2. Remove the `skip` return from `validate_web_protocol_roundtrip('v2')` |
| 119 | +3. Add V2-specific checks (rig config, plugins, etc.) |
| 120 | +4. Generate V2 test YAML: update generator's `--version 2` support |
| 121 | + |
| 122 | +### Changing `experiment_designer.html` YAML output |
| 123 | + |
| 124 | +After modifying `generateYAML()` or `simpleYAMLParse()`: |
| 125 | + |
| 126 | +1. Run `node tests/test-protocol-roundtrip.js` — catches web-side regressions |
| 127 | +2. Re-generate: `node tests/generate-roundtrip-protocol.js --outdir ...` |
| 128 | +3. Run MATLAB: `validate_web_protocol_roundtrip('v1')` — catches cross-tool regressions |
| 129 | + |
| 130 | +## Known Constraints |
| 131 | + |
| 132 | +- **ProtocolRunner dry run** tries to initialize hardware (PanelsController). The MATLAB test validates construction only (parse + validate), not `run()`. |
| 133 | +- **`ProtocolParser.m` and `CommandExecutor.m`** are Lisa's code — flagged as DO NOT MODIFY. Any incompatibilities found should be discussed before changing. |
| 134 | +- **simpleYAMLParse** is a minimal YAML parser. It handles the subset of YAML used by the experiment designer but is not a full YAML 1.2 parser. |
0 commit comments