|
| 1 | +Test the 'dune promotion show' command |
| 2 | + |
| 3 | +=== WHAT THIS TEST VERIFIES === |
| 4 | +This test ensures that 'dune promotion show' correctly displays the contents |
| 5 | +of corrected files that are ready for promotion, without modifying the source |
| 6 | +files. The command allows users to preview what changes would be applied before |
| 7 | +running 'dune promote'. |
| 8 | + |
| 9 | +Key properties tested: |
| 10 | +1. Shows corrected content for files with failed diff rules |
| 11 | +2. Is read-only (never modifies source files) |
| 12 | +3. Handles single file, multiple files, and all files (no args) |
| 13 | +4. Proper warning handling for non-promotable files |
| 14 | +5. Files with 'diff' (not 'diff?') are promotable |
| 15 | + |
| 16 | +=== WHY THIS MATTERS === |
| 17 | +The 'show' command is critical for user workflow: it lets developers review |
| 18 | +auto-generated corrections before accepting them. This is especially important |
| 19 | +for generated code, test expectations, or formatted output where users need to |
| 20 | +verify the changes make sense before committing them. |
| 21 | + |
| 22 | +=== HOW TO VERIFY CORRECTNESS === |
| 23 | +1. Before 'runtest': show should warn (no corrections available) |
| 24 | +2. After 'runtest': show should display corrected content from _build |
| 25 | +3. After 'show': source files should remain unchanged (read-only guarantee) |
| 26 | +4. Output includes trailing newline after each file's content |
| 27 | +5. Only 'diff' rules create promotions; 'diff?' rules may not always generate them |
| 28 | +
|
| 29 | +Setup a basic dune project with promotion-capable rules |
| 30 | +
|
| 31 | +We create different promotion scenarios to test various behaviors: |
| 32 | +- a.expected: uses 'diff' (creates promotion when files differ) |
| 33 | +- b.expected: uses 'diff?' in progn (creates promotion when files differ) |
| 34 | +- c.expected: uses 'diff?' in separate action (may not create promotion) |
| 35 | +
|
| 36 | + $ cat > dune-project << EOF |
| 37 | + > (lang dune 2.0) |
| 38 | + > EOF |
| 39 | +
|
| 40 | + $ cat > dune << EOF |
| 41 | + > (rule |
| 42 | + > (alias runtest) |
| 43 | + > (action |
| 44 | + > (diff a.expected a.actual))) |
| 45 | + > |
| 46 | + > (rule |
| 47 | + > (with-stdout-to a.actual |
| 48 | + > (echo "A actual\n"))) |
| 49 | + > |
| 50 | + > (rule |
| 51 | + > (alias runtest) |
| 52 | + > (action |
| 53 | + > (progn |
| 54 | + > (with-stdout-to b.actual |
| 55 | + > (echo "B actual\n")) |
| 56 | + > (diff? b.expected b.actual)))) |
| 57 | + > |
| 58 | + > (rule |
| 59 | + > (with-stdout-to c.actual |
| 60 | + > (echo "C actual\n"))) |
| 61 | + > |
| 62 | + > (rule |
| 63 | + > (alias runtest) |
| 64 | + > (action |
| 65 | + > (diff? c.expected c.actual))) |
| 66 | + > EOF |
| 67 | +
|
| 68 | + $ echo 'A expected' > a.expected |
| 69 | + $ echo 'B expected' > b.expected |
| 70 | + $ echo 'C expected' > c.expected |
| 71 | +
|
| 72 | +=== TEST: Before tests run, no promotions available === |
| 73 | +When no tests have run yet, there are no corrected files in _build, |
| 74 | +so 'show' should return a warning (not an error, as this is informational). |
| 75 | +
|
| 76 | + $ dune promotion show a.expected 2>&1 |
| 77 | + Warning: Nothing to promote for a.expected. |
| 78 | +
|
| 79 | +=== TEST: Generate corrections by running tests === |
| 80 | +Running tests will create .actual files in _build that differ from |
| 81 | +the .expected files. Note that only 'diff' and some 'diff?' rules |
| 82 | +actually create promotable files. |
| 83 | +
|
| 84 | + $ dune runtest 2>&1 |
| 85 | + File "a.expected", line 1, characters 0-0: |
| 86 | + Error: Files _build/default/a.expected and _build/default/a.actual differ. |
| 87 | + File "b.expected", line 1, characters 0-0: |
| 88 | + Error: Files _build/default/b.expected and _build/default/b.actual differ. |
| 89 | + [1] |
| 90 | +
|
| 91 | +=== TEST: Show corrected contents of a single file === |
| 92 | +After tests run, 'show' should display the contents of the corrected |
| 93 | +file from _build without modifying the source file. |
| 94 | +Note: Output includes a trailing newline after the content. |
| 95 | +
|
| 96 | + $ dune promotion show a.expected |
| 97 | + A actual |
| 98 | + |
| 99 | +
|
| 100 | +=== TEST: Show another single file === |
| 101 | +Verify 'show' works consistently for different files. |
| 102 | +
|
| 103 | + $ dune promotion show b.expected |
| 104 | + B actual |
| 105 | + |
| 106 | +
|
| 107 | +=== TEST: Show multiple files at once === |
| 108 | +The command should accept multiple file arguments and display their |
| 109 | +corrected contents in the order specified. |
| 110 | +Each file's content is followed by a newline. |
| 111 | + |
| 112 | + $ dune promotion show a.expected b.expected |
| 113 | + A actual |
| 114 | + |
| 115 | + B actual |
| 116 | + |
| 117 | + |
| 118 | +=== TEST: Mixed valid and invalid arguments === |
| 119 | +When some arguments are promotable and others are not, the command should: |
| 120 | +- Show warnings for invalid files (appears before content) |
| 121 | +- Continue processing valid files |
| 122 | +- Display content for all valid files |
| 123 | + |
| 124 | +This is important for scripting and batch operations where partial |
| 125 | +success is better than complete failure. |
| 126 | + |
| 127 | + $ touch nothing-to-promote.txt |
| 128 | + $ dune promotion show a.expected nothing-to-promote.txt b.expected 2>&1 |
| 129 | + Warning: Nothing to promote for nothing-to-promote.txt. |
| 130 | + A actual |
| 131 | + |
| 132 | + B actual |
| 133 | + |
| 134 | + |
| 135 | +=== TEST: Non-existent file handling === |
| 136 | +When a specified file doesn't exist at all (not just non-promotable), |
| 137 | +the command fails with a usage error and exit code 1. |
| 138 | +
|
| 139 | +This is different from "nothing to promote" - the file must exist |
| 140 | +in the filesystem to be checked for promotions. |
| 141 | +
|
| 142 | + $ dune promotion show does-not-exist.ml 2>&1 |
| 143 | + dune: FILE… arguments: no 'does-not-exist.ml' file or directory |
| 144 | + Usage: dune promotion show [OPTION]… [FILE]… |
| 145 | + Try 'dune promotion show --help' or 'dune --help' for more information. |
| 146 | + [1] |
| 147 | +
|
| 148 | +=== TEST: Show all corrected files (no arguments) === |
| 149 | +When called without arguments, 'show' should display all files that |
| 150 | +have corrections available. The order may vary. |
| 151 | +
|
| 152 | + $ dune promotion show |
| 153 | + B actual |
| 154 | + |
| 155 | + A actual |
| 156 | + |
| 157 | +
|
| 158 | +=== TEST: Verify read-only behavior === |
| 159 | +Critical property: 'show' must never modify source files. |
| 160 | +After all the 'show' operations above, source files should still |
| 161 | +contain their original "expected" content, not the "actual" content. |
| 162 | +
|
| 163 | + $ cat a.expected |
| 164 | + A expected |
| 165 | + $ cat b.expected |
| 166 | + B expected |
| 167 | + $ cat c.expected |
| 168 | + C expected |
| 169 | +
|
| 170 | +=== TEST: Files with diff? may not always create promotions === |
| 171 | +The c.expected file uses 'diff?' in a separate action, which doesn't |
| 172 | +always create a promotion entry. This is expected behavior. |
| 173 | + |
| 174 | + $ dune promotion show c.expected > c.shown |
| 175 | + Warning: Nothing to promote for c.expected. |
| 176 | + $ dune promote c.expected 2>&1 |
| 177 | + Warning: Nothing to promote for c.expected. |
| 178 | + |
| 179 | +Since there was nothing to promote, c.expected remains unchanged |
| 180 | +and the diff shows they're different (original vs unchanged). |
| 181 | +
|
| 182 | + $ diff c.shown c.expected |
| 183 | + 0a1 |
| 184 | + > C expected |
| 185 | + [1] |
| 186 | +
|
| 187 | +=== TEST: After showing, files remain available === |
| 188 | +The 'show' command is read-only, so files remain available for |
| 189 | +promotion after being shown. |
| 190 | +
|
| 191 | + $ dune promotion show c.expected 2>&1 |
| 192 | + Warning: Nothing to promote for c.expected. |
| 193 | +
|
| 194 | +=== TEST: Other files still available === |
| 195 | +Files that haven't been promoted remain available. |
| 196 | + |
| 197 | + $ dune promotion show a.expected |
| 198 | + A actual |
| 199 | + |
| 200 | + |
| 201 | +=== EDGE CASE: Empty corrected file === |
| 202 | +Empty files are a valid edge case - a diff might result in deleting |
| 203 | +all content. However, 'diff?' may not create a promotion for such files. |
| 204 | + |
| 205 | +This tests robustness against zero-length file content. |
| 206 | + |
| 207 | + $ cat > dune << EOF |
| 208 | + > (rule |
| 209 | + > (alias runtest) |
| 210 | + > (action |
| 211 | + > (diff? empty.expected empty.actual))) |
| 212 | + > |
| 213 | + > (rule |
| 214 | + > (with-stdout-to empty.actual |
| 215 | + > (progn))) |
| 216 | + > EOF |
| 217 | +
|
| 218 | + $ echo 'not empty' > empty.expected |
| 219 | + $ dune runtest 2>&1 |
| 220 | +
|
| 221 | +In this case, 'diff?' doesn't create a promotion entry for the empty file. |
| 222 | +
|
| 223 | + $ dune promotion show empty.expected |
| 224 | + Warning: Nothing to promote for empty.expected. |
| 225 | +
|
| 226 | +=== EDGE CASE: Multiline content === |
| 227 | +Real-world promoted files often contain multiple lines. However, we need |
| 228 | +to verify whether 'diff?' creates promotions for such files. |
| 229 | +
|
| 230 | + $ cat > dune << EOF |
| 231 | + > (rule |
| 232 | + > (alias runtest) |
| 233 | + > (action |
| 234 | + > (diff? multi.expected multi.actual))) |
| 235 | + > |
| 236 | + > (rule |
| 237 | + > (with-stdout-to multi.actual |
| 238 | + > (progn |
| 239 | + > (echo "line 1\n") |
| 240 | + > (echo "line 2\n") |
| 241 | + > (echo "line 3\n")))) |
| 242 | + > EOF |
| 243 | +
|
| 244 | + $ echo 'old content' > multi.expected |
| 245 | + $ dune runtest 2>&1 |
| 246 | +
|
| 247 | +This 'diff?' rule also doesn't create a promotion entry. |
| 248 | +
|
| 249 | + $ dune promotion show multi.expected |
| 250 | + Warning: Nothing to promote for multi.expected. |
| 251 | +
|
| 252 | +=== TEST: Multiple non-promotable files === |
| 253 | +When multiple files have no promotions available, each gets a warning. |
| 254 | +
|
| 255 | + $ dune promotion show multi.expected empty.expected |
| 256 | + Warning: Nothing to promote for multi.expected. |
| 257 | + Warning: Nothing to promote for empty.expected. |
0 commit comments