Skip to content

Commit a690a80

Browse files
Add comprehensive tests for GUI, recovery, and TUI modules
- Introduced additional GUI tests covering module structure, logging handlers, and widget operations. - Implemented extensive tests for the recovery module, including Reed-Solomon error correction and recovery record generation/application. - Added TUI tests targeting uncovered code paths, ensuring proper functionality of various modal and pane methods. - Enhanced coverage for constants and edge cases across all modules.
1 parent 679b789 commit a690a80

16 files changed

Lines changed: 5910 additions & 21 deletions

techcompressor/archiver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ def __init__(self, first_volume_path: Path):
432432
Args:
433433
first_volume_path: Path to first volume (.part1/.001) or base archive path
434434
"""
435-
self.first_volume_path = first_volume_path
435+
self.first_volume_path = Path(first_volume_path) if isinstance(first_volume_path, str) else first_volume_path
436436
self.volume_paths = []
437437
self.current_volume_idx = 0
438438
self.current_file = None

techcompressor/cli.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def main():
216216
)
217217
elapsed = time.perf_counter() - start_time
218218

219-
print(f"\n Archive created successfully: {args.archive}")
219+
print(f"\n[OK] Archive created successfully: {args.archive}")
220220
if hasattr(args, 'volume_size') and args.volume_size:
221221
print(f" (Multi-volume archive - check for .001, .002, etc.)")
222222
print(f" Time: {elapsed:.3f}s")
@@ -239,7 +239,7 @@ def main():
239239
)
240240
elapsed = time.perf_counter() - start_time
241241

242-
print(f"\n Archive extracted successfully to: {args.dest}")
242+
print(f"\n[OK] Archive extracted successfully to: {args.dest}")
243243
print(f" Time: {elapsed:.3f}s")
244244

245245
elif args.command in ('list', 'l'):
@@ -255,9 +255,13 @@ def main():
255255
total_compressed = 0
256256

257257
for entry in contents:
258+
# Skip metadata entries (they don't have 'name' key)
259+
if 'metadata' in entry or 'name' not in entry:
260+
continue
261+
258262
name = entry['name']
259-
size = entry['size']
260-
compressed = entry['compressed_size']
263+
size = entry.get('size', 0)
264+
compressed = entry.get('compressed_size', 0)
261265
ratio = (compressed / max(size, 1)) * 100
262266

263267
total_size += size
@@ -272,14 +276,14 @@ def main():
272276

273277
elif args.command == 'compress':
274278
# Compress single file
275-
print(f"Compressing: {args.input} {args.output}")
279+
print(f"Compressing: {args.input} -> {args.output}")
276280
print(f"Algorithm: {args.algo}")
277281
if args.password:
278282
print("Encryption: enabled")
279283

280284
input_path = Path(args.input)
281285
if not input_path.exists():
282-
print(f"❌ Error: Input file not found: {args.input}", file=sys.stderr)
286+
print(f"[ERROR] Input file not found: {args.input}", file=sys.stderr)
283287
return 1
284288

285289
start_time = time.perf_counter()
@@ -292,19 +296,19 @@ def main():
292296

293297
ratio = (len(compressed) / max(len(data), 1)) * 100
294298
speed = (len(data) / (1024 * 1024)) / elapsed if elapsed > 0 else 0
295-
print(f"\n Compressed: {len(data):,} {len(compressed):,} bytes ({ratio:.1f}%)")
299+
print(f"\n[OK] Compressed: {len(data):,} -> {len(compressed):,} bytes ({ratio:.1f}%)")
296300
print(f" Time: {elapsed:.3f}s | Speed: {speed:.2f} MB/s")
297301

298302
elif args.command == 'decompress':
299303
# Decompress single file
300-
print(f"Decompressing: {args.input} {args.output}")
304+
print(f"Decompressing: {args.input} -> {args.output}")
301305
print(f"Algorithm: {args.algo}")
302306
if args.password:
303307
print("Decryption: enabled")
304308

305309
input_path = Path(args.input)
306310
if not input_path.exists():
307-
print(f"❌ Error: Input file not found: {args.input}", file=sys.stderr)
311+
print(f"[ERROR] Input file not found: {args.input}", file=sys.stderr)
308312
return 1
309313

310314
start_time = time.perf_counter()
@@ -315,49 +319,49 @@ def main():
315319
output_path = Path(args.output)
316320
output_path.write_bytes(data)
317321

318-
print(f"\n Decompressed: {len(compressed):,} {len(data):,} bytes in {elapsed:.3f}s")
322+
print(f"\n[OK] Decompressed: {len(compressed):,} -> {len(data):,} bytes in {elapsed:.3f}s")
319323

320324
elif args.command == 'verify':
321325
# Verify archive integrity
322326
print(f"Verifying: {args.archive}")
323327

324328
archive_path = Path(args.archive)
325329
if not archive_path.exists():
326-
print(f"❌ Error: Archive not found: {args.archive}", file=sys.stderr)
330+
print(f"[ERROR] Archive not found: {args.archive}", file=sys.stderr)
327331
return 1
328332

329333
# Check magic header
330334
with open(archive_path, 'rb') as f:
331335
magic = f.read(4)
332336

333337
if magic == b"TCAF":
334-
print(" Valid TCAF archive")
338+
print("[OK] Valid TCAF archive")
335339

336340
# List contents to verify structure
337341
contents = list_contents(str(archive_path))
338-
print(f" Contains {len(contents)} file(s)")
342+
print(f"[OK] Contains {len(contents)} file(s)")
339343

340-
total_size = sum(entry['size'] for entry in contents)
341-
total_compressed = sum(entry['compressed_size'] for entry in contents)
344+
total_size = sum(entry.get('size', 0) for entry in contents if 'name' in entry)
345+
total_compressed = sum(entry.get('compressed_size', 0) for entry in contents if 'name' in entry)
342346
ratio = (total_compressed / max(total_size, 1)) * 100
343347

344348
print(f" Original: {total_size:,} bytes")
345349
print(f" Compressed: {total_compressed:,} bytes ({ratio:.1f}%)")
346-
print("\n Archive verification passed!")
350+
print("\n[OK] Archive verification passed!")
347351
else:
348352
# Check if it's a compressed file
349353
if magic[:4] in [b"TCZ1", b"TCH1", b"TCD1", b"TCE1"]:
350-
print(" Valid compressed file")
354+
print("[OK] Valid compressed file")
351355
print(f" Format: {magic.decode('ascii', errors='replace')}")
352-
print("\n File verification passed!")
356+
print("\n[OK] File verification passed!")
353357
else:
354-
print(f" Unknown format: {magic}")
358+
print(f"[ERROR] Unknown format: {magic}")
355359
return 1
356360

357361
return 0
358362

359363
except Exception as e:
360-
print(f"\n❌ Error: {e}", file=sys.stderr)
364+
print(f"\n[ERROR] {e}", file=sys.stderr)
361365
logger.exception("CLI command failed")
362366
return 1
363367

0 commit comments

Comments
 (0)