Skip to content

Commit 3258540

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

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed

Lib/test/test_filecmp.py

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import filecmp
2+
import getopt
23
import os
34
import re
45
import shutil
6+
import sys
57
import tempfile
68
import unittest
79

@@ -21,7 +23,9 @@ def _create_file_shallow_equal(template_path, new_path):
2123
assert os.stat(new_path).st_size == os.stat(template_path).st_size
2224
assert os.stat(new_path).st_mtime == os.stat(template_path).st_mtime
2325

26+
2427
class FileCompareTestCase(unittest.TestCase):
28+
2529
def setUp(self):
2630
self.name = os_helper.TESTFN
2731
self.name_same = os_helper.TESTFN + '-same'
@@ -367,5 +371,198 @@ def _assert_report(self, dircmp_report, expected_report_lines):
367371
self.assertEqual(report_lines, expected_report_lines)
368372

369373

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

0 commit comments

Comments
 (0)