2
2
import os
3
3
import re
4
4
import shutil
5
+ import sys
5
6
import tempfile
6
7
import unittest
7
8
@@ -21,7 +22,9 @@ def _create_file_shallow_equal(template_path, new_path):
21
22
assert os .stat (new_path ).st_size == os .stat (template_path ).st_size
22
23
assert os .stat (new_path ).st_mtime == os .stat (template_path ).st_mtime
23
24
25
+
24
26
class FileCompareTestCase (unittest .TestCase ):
27
+
25
28
def setUp (self ):
26
29
self .name = os_helper .TESTFN
27
30
self .name_same = os_helper .TESTFN + '-same'
@@ -367,5 +370,212 @@ def _assert_report(self, dircmp_report, expected_report_lines):
367
370
self .assertEqual (report_lines , expected_report_lines )
368
371
369
372
373
+ class TestFilecmpCLI (unittest .TestCase ):
374
+ """Test the command line interface of filecmp module"""
375
+
376
+ def setUp (self ):
377
+ self .temp_dir = tempfile .mkdtemp ()
378
+ self .addCleanup (shutil .rmtree , self .temp_dir )
379
+
380
+ # Create test directories and files
381
+ self .dir1 = os .path .join (self .temp_dir , 'dir1' )
382
+ self .dir2 = os .path .join (self .temp_dir , 'dir2' )
383
+ os .makedirs (self .dir1 )
384
+ os .makedirs (self .dir2 )
385
+
386
+ # Create identical files
387
+ with open (os .path .join (self .dir1 , 'same.txt' ), 'w' ) as f :
388
+ f .write ('same content' )
389
+ with open (os .path .join (self .dir2 , 'same.txt' ), 'w' ) as f :
390
+ f .write ('same content' )
391
+
392
+ # Create different files
393
+ with open (os .path .join (self .dir1 , 'different.txt' ), 'w' ) as f :
394
+ f .write ('content in dir1' )
395
+ with open (os .path .join (self .dir2 , 'different.txt' ), 'w' ) as f :
396
+ f .write ('content in dir2' )
397
+
398
+ # Create file only in dir1
399
+ with open (os .path .join (self .dir1 , 'only_in_dir1.txt' ), 'w' ) as f :
400
+ f .write ('unique to dir1' )
401
+
402
+ # Create file only in dir2
403
+ with open (os .path .join (self .dir2 , 'only_in_dir2.txt' ), 'w' ) as f :
404
+ f .write ('unique to dir2' )
405
+
406
+ # Create subdirectories for recursive testing
407
+ self .subdir1 = os .path .join (self .dir1 , 'subdir' )
408
+ self .subdir2 = os .path .join (self .dir2 , 'subdir' )
409
+ os .makedirs (self .subdir1 )
410
+ os .makedirs (self .subdir2 )
411
+
412
+ with open (os .path .join (self .subdir1 , 'subfile.txt' ), 'w' ) as f :
413
+ f .write ('sub content' )
414
+ with open (os .path .join (self .subdir2 , 'subfile.txt' ), 'w' ) as f :
415
+ f .write ('different sub content' )
416
+
417
+ def test_demo_basic_comparison (self ):
418
+ """Test basic directory comparison via demo()"""
419
+ import sys
420
+ old_argv = sys .argv
421
+ try :
422
+ sys .argv = ['filecmp' , self .dir1 , self .dir2 ]
423
+ with support .captured_stdout () as stdout :
424
+ filecmp .__dict__ ['demo' ]()
425
+ output = stdout .getvalue ()
426
+
427
+ # Check that output contains expected comparison results
428
+ self .assertIn ('diff' , output )
429
+ self .assertIn ('same.txt' , output )
430
+ self .assertIn ('different.txt' , output )
431
+ self .assertIn ('only_in_dir1.txt' , output )
432
+ self .assertIn ('only_in_dir2.txt' , output )
433
+ finally :
434
+ sys .argv = old_argv
435
+
436
+ def test_demo_recursive_comparison (self ):
437
+ """Test recursive directory comparison via demo() with -r flag"""
438
+ import sys
439
+ old_argv = sys .argv
440
+ try :
441
+ sys .argv = ['filecmp' , '-r' , self .dir1 , self .dir2 ]
442
+ with support .captured_stdout () as stdout :
443
+ filecmp .__dict__ ['demo' ]()
444
+ output = stdout .getvalue ()
445
+
446
+ # Check that output contains subdirectory comparison
447
+ self .assertIn ('subdir' , output )
448
+ self .assertIn ('subfile.txt' , output )
449
+ finally :
450
+ sys .argv = old_argv
451
+
452
+ def test_demo_long_flag (self ):
453
+ """Test demo with long --recursive flag (should fail as only -r is supported)"""
454
+ import sys
455
+ import getopt
456
+ old_argv = sys .argv
457
+ try :
458
+ sys .argv = ['filecmp' , '--recursive' , self .dir1 , self .dir2 ]
459
+ with self .assertRaises (getopt .GetoptError ):
460
+ filecmp .__dict__ ['demo' ]()
461
+ finally :
462
+ sys .argv = old_argv
463
+
464
+ def test_demo_no_arguments (self ):
465
+ """Test demo with no arguments (should raise GetoptError)"""
466
+ import sys
467
+ import getopt
468
+ old_argv = sys .argv
469
+ try :
470
+ sys .argv = ['filecmp' ]
471
+ with self .assertRaises (getopt .GetoptError ) as cm :
472
+ filecmp .__dict__ ['demo' ]()
473
+ self .assertIn ('need exactly two args' , str (cm .exception ))
474
+ finally :
475
+ sys .argv = old_argv
476
+
477
+ def test_demo_one_argument (self ):
478
+ """Test demo with only one directory argument (should raise GetoptError)"""
479
+ import sys
480
+ import getopt
481
+ old_argv = sys .argv
482
+ try :
483
+ sys .argv = ['filecmp' , self .dir1 ]
484
+ with self .assertRaises (getopt .GetoptError ) as cm :
485
+ filecmp .__dict__ ['demo' ]()
486
+ self .assertIn ('need exactly two args' , str (cm .exception ))
487
+ finally :
488
+ sys .argv = old_argv
489
+
490
+ def test_demo_three_arguments (self ):
491
+ """Test demo with three arguments (should raise GetoptError)"""
492
+ import sys
493
+ import getopt
494
+ old_argv = sys .argv
495
+ try :
496
+ sys .argv = ['filecmp' , self .dir1 , self .dir2 , 'extra' ]
497
+ with self .assertRaises (getopt .GetoptError ) as cm :
498
+ filecmp .__dict__ ['demo' ]()
499
+ self .assertIn ('need exactly two args' , str (cm .exception ))
500
+ finally :
501
+ sys .argv = old_argv
502
+
503
+ def test_demo_nonexistent_directory (self ):
504
+ """Test demo with nonexistent directory"""
505
+ import sys
506
+ old_argv = sys .argv
507
+ try :
508
+ sys .argv = ['filecmp' , self .dir1 , '/nonexistent/path' ]
509
+ # This should raise an exception during comparison
510
+ with self .assertRaises ((FileNotFoundError , OSError )):
511
+ filecmp .__dict__ ['demo' ]()
512
+ finally :
513
+ sys .argv = old_argv
514
+
515
+ def test_demo_identical_directories (self ):
516
+ """Test demo with identical directories"""
517
+ import sys
518
+
519
+ dir3 = os .path .join (self .temp_dir , 'dir3' )
520
+ dir4 = os .path .join (self .temp_dir , 'dir4' )
521
+ os .makedirs (dir3 )
522
+ os .makedirs (dir4 )
523
+
524
+ with open (os .path .join (dir3 , 'file1.txt' ), 'w' ) as f :
525
+ f .write ('same content' )
526
+ with open (os .path .join (dir4 , 'file1.txt' ), 'w' ) as f :
527
+ f .write ('same content' )
528
+
529
+ old_argv = sys .argv
530
+ try :
531
+ sys .argv = ['filecmp' , dir3 , dir4 ]
532
+ with support .captured_stdout () as stdout :
533
+ filecmp .__dict__ ['demo' ]()
534
+ output = stdout .getvalue ()
535
+
536
+ # Should indicate identical files
537
+ self .assertIn ('Identical files' , output )
538
+ self .assertIn ('file1.txt' , output )
539
+ finally :
540
+ sys .argv = old_argv
541
+
542
+ def test_demo_empty_directories (self ):
543
+ """Test demo with empty directories"""
544
+ import sys
545
+
546
+ dir3 = os .path .join (self .temp_dir , 'empty1' )
547
+ dir4 = os .path .join (self .temp_dir , 'empty2' )
548
+ os .makedirs (dir3 )
549
+ os .makedirs (dir4 )
550
+
551
+ old_argv = sys .argv
552
+ try :
553
+ sys .argv = ['filecmp' , dir3 , dir4 ]
554
+ with support .captured_stdout () as stdout :
555
+ filecmp .__dict__ ['demo' ]()
556
+ output = stdout .getvalue ()
557
+
558
+ # Should handle empty directories gracefully
559
+ self .assertTrue (len (output ) > 0 )
560
+ finally :
561
+ sys .argv = old_argv
562
+
563
+ def test_demo_with_files_instead_of_directories (self ):
564
+ """Test demo when file paths are given instead of directories"""
565
+ import sys
566
+
567
+ file1 = os .path .join (self .dir1 , 'same.txt' )
568
+ file2 = os .path .join (self .dir2 , 'same.txt' )
569
+
570
+ old_argv = sys .argv
571
+ try :
572
+ sys .argv = ['filecmp' , file1 , file2 ]
573
+ # This should raise an exception as files are not directories
574
+ with self .assertRaises ((NotADirectoryError , OSError )):
575
+ filecmp .__dict__ ['demo' ]()
576
+ finally :
577
+ sys .argv = old_argv
578
+
579
+
370
580
if __name__ == "__main__" :
371
581
unittest .main ()
0 commit comments