Skip to content

Commit 04af1c8

Browse files
committed
chore: filecmp add unittest
1 parent d4e5802 commit 04af1c8

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed

Lib/test/test_filecmp.py

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import re
44
import shutil
5+
import sys
56
import tempfile
67
import unittest
78

@@ -367,5 +368,212 @@ def _assert_report(self, dircmp_report, expected_report_lines):
367368
self.assertEqual(report_lines, expected_report_lines)
368369

369370

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

0 commit comments

Comments
 (0)