diff --git a/test/batch_test.dart b/test/batch_test.dart index 102da61..12159f7 100644 --- a/test/batch_test.dart +++ b/test/batch_test.dart @@ -298,6 +298,14 @@ void main() { return true; } + // 관리자 지적 (10/18): 전체 시험 중 PC 가 바쁘면 정해진 횟수 안에 오지 않아 30초 한도에 걸렸다 (240) - 239 처럼 될 때까지 기다린다 + Future until(bool Function() ok, {Duration max = const Duration(seconds: 90)}) async { + final end = DateTime.now().add(max); + while (!ok() && DateTime.now().isBefore(end)) { + await Future.delayed(const Duration(milliseconds: 20)); + } + } + File out(int i) => File(outputMkvPath(files[i])); void writeOld(int i) => (out(i)..createSync(recursive: true)).writeAsStringSync('OLD COMPLETE MKV'); List parts() => [ @@ -310,16 +318,14 @@ void main() { final v1 = c.videos.first; writeOld(0); final building = c.buildVideos([v1], onExisting: 'overwrite'); - for (var i = 0; i < 400 && !(v1.status == JobStatus.running && v1.progress > 0.02); i++) { - await Future.delayed(const Duration(milliseconds: 25)); - } + await until(() => v1.status == JobStatus.running && v1.progress > 0.02); expect(out(0).readAsStringSync(), 'OLD COMPLETE MKV', reason: '만드는 동안에도 예전 것은 그대로 (임시 이름에 씀)'); c.cancel(); await building; expect(v1.status, JobStatus.cancelled); expect(out(0).readAsStringSync(), 'OLD COMPLETE MKV', reason: '취소해도 예전 완성본은 남는다'); expect(parts(), isEmpty, reason: '만들다 만 임시 파일은 지움'); - }); + }, timeout: const Timeout(Duration(minutes: 4))); test('덮어쓰기 · 건너뛰기 · 다른 이름', () async { if (!await prepare()) return markTestSkipped('FFmpeg 없음'); @@ -337,7 +343,7 @@ void main() { expect(File(p.join(p.dirname(out(2).path), 'b3 (2).mkv')).lengthSync(), greaterThan(100)); expect(v3.outputPath, endsWith('b3 (2).mkv')); expect(parts(), isEmpty); - }); + }, timeout: const Timeout(Duration(minutes: 4))); test('240 집계: 다시 만들다 [남은 것 모두 취소] - 앞 실행의 ✓ 가 섞이지 않고 시작 못 한 것은 취소 (성공 1 · 취소 2)', () async { if (!await prepare(seconds: [1, 60, 1])) return markTestSkipped('FFmpeg 없음'); @@ -346,14 +352,13 @@ void main() { v2.status = JobStatus.done; // 앞 실행에서 ✓ 였던 것 v3.status = JobStatus.done; final building = c.buildVideos([v1, v2, v3], onExisting: 'overwrite'); - for (var i = 0; i < 800 && !(v2.status == JobStatus.running && v2.progress > 0.01); i++) { - await Future.delayed(const Duration(milliseconds: 25)); - } + await until(() => v2.status == JobStatus.running && v2.progress > 0.01); + expect(v2.status, JobStatus.running, reason: '기다린 끝에도 v2 가 시작하지 않음'); c.cancel(); await building; expect([v1.status, v2.status, v3.status], [JobStatus.done, JobStatus.cancelled, JobStatus.cancelled]); expect(c.logs.last, contains('성공 1 · 취소 2 · 실패 0 / 전체 3')); - }); + }, timeout: const Timeout(Duration(minutes: 4))); }); test('239: 취소 창을 연 뒤 그 동영상이 끝나고 다음 것이 시작했으면 [지금 것만 취소] 는 다음 것을 취소하지 않는다', () async {