| … | … | @@ -60,11 +60,20 @@ def _measure(table): |
| 60 | 60 | calls = [] |
| 61 | 61 | |
| 62 | 62 | def measure(ref, srt_in, srt_out): |
| 63 | | calls.append(os.path.basename(srt_in)) |
| 64 | | offset, scale = table[os.path.basename(srt_in)] |
| 65 | | if srt_out: |
| 63 | # Faithful to ffsubsync 0.5.1, measured 2026-10-04: the output format |
| 64 | # comes from the output EXTENSION. Anything but .srt here (".synced", |
| 65 | # /dev/null) logs "unsupported output format", writes NOTHING, exits |
| 66 | # 0 -- after printing the offsets. The first fake wrote any name, which |
| 67 | # is how 32 good tracks got withdrawn in production. |
| 68 | name = os.path.basename(srt_in) |
| 69 | for prefix in ("synced-", "recheck-"): |
| 70 | if name.startswith(prefix): |
| 71 | name = name[len(prefix):] + ".synced" |
| 72 | calls.append(name) |
| 73 | offset, scale = table[name] |
| 74 | if srt_out and srt_out.endswith(".srt"): |
| 66 | 75 | with open(srt_out, "w") as f: |
| 67 | | f.write(f"corrected {os.path.basename(srt_in)}") |
| 76 | f.write(f"corrected {name}") |
| 68 | 77 | return {"offset": offset, "scale": scale, "score": 1.0} |
| 69 | 78 | return measure, calls |
| 70 | 79 | |
| … | … | @@ -222,3 +231,50 @@ def test_parse_reads_ffsubsyncs_own_output(): |
| 222 | 231 | assert addon._parse_subsync(out) == {"offset": -2.25, "scale": 1.001, |
| 223 | 232 | "score": 343738.036} |
| 224 | 233 | assert addon._parse_subsync("garbage") is None |
| 234 | |
| 235 | |
| 236 | def test_a_correction_that_was_not_written_leaves_the_track_alone(lib, monkeypatch): |
| 237 | """The production failure: offsets measured, corrected file never |
| 238 | written. That is "could not repair", not "unfixable".""" |
| 239 | dest, _ = lib |
| 240 | fr = _srt(dest, "fr") |
| 241 | |
| 242 | def measured_but_not_written(ref, srt_in, srt_out): |
| 243 | return {"offset": -8.9, "scale": 1.0, "score": 1.0} |
| 244 | monkeypatch.setattr(addon, "_subsync_measure", measured_but_not_written) |
| 245 | result = addon._sync_subtitles(dest) |
| 246 | assert result["unfixable"] == 0 and result["unmeasured"] == 1 |
| 247 | assert os.path.exists(fr) and open(fr).read().startswith("1\n") |
| 248 | |
| 249 | |
| 250 | def test_a_recheck_that_cannot_run_leaves_the_track_alone(lib, monkeypatch): |
| 251 | dest, _ = lib |
| 252 | fr = _srt(dest, "fr") |
| 253 | calls = [] |
| 254 | |
| 255 | def first_ok_then_none(ref, srt_in, srt_out): |
| 256 | calls.append(srt_in) |
| 257 | if len(calls) == 1: |
| 258 | with open(srt_out, "w") as f: |
| 259 | f.write("corrected") |
| 260 | return {"offset": -8.9, "scale": 1.0, "score": 1.0} |
| 261 | return None |
| 262 | monkeypatch.setattr(addon, "_subsync_measure", first_ok_then_none) |
| 263 | result = addon._sync_subtitles(dest) |
| 264 | assert result["unfixable"] == 0 and result["unmeasured"] == 1 |
| 265 | assert open(fr).read().startswith("1\n") |
| 266 | |
| 267 | |
| 268 | def test_every_output_path_keeps_the_srt_extension(lib, monkeypatch): |
| 269 | dest, _ = lib |
| 270 | _srt(dest, "fr") |
| 271 | outs = [] |
| 272 | |
| 273 | def record(ref, srt_in, srt_out): |
| 274 | outs.append(srt_out) |
| 275 | if srt_out: |
| 276 | open(srt_out, "w").write("x") |
| 277 | return {"offset": -8.9 if len(outs) == 1 else 0.0, "scale": 1.0, "score": 1.0} |
| 278 | monkeypatch.setattr(addon, "_subsync_measure", record) |
| 279 | addon._sync_subtitles(dest) |
| 280 | assert outs and all(o and o.endswith(".srt") for o in outs) |