CodeReviewAgent / tests /test_language_detector.py
c1r3x's picture
Review Agent: first commit
88d205f
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Unit tests for the Language Detector
"""
import unittest
from unittest.mock import patch, MagicMock, mock_open
import os
import sys
from pathlib import Path
# Add the project root directory to the Python path
project_root = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(project_root))
from src.core.language_detector import LanguageDetector
class TestLanguageDetector(unittest.TestCase):
"""Test cases for the LanguageDetector class"""
def setUp(self):
"""Set up test fixtures"""
self.detector = LanguageDetector()
# Create a mock repository structure
self.repo_path = "/test/repo"
self.mock_files = [
"/test/repo/main.py",
"/test/repo/utils.py",
"/test/repo/static/script.js",
"/test/repo/static/style.css",
"/test/repo/src/app.js",
"/test/repo/src/components/Button.jsx",
"/test/repo/src/components/Form.tsx",
"/test/repo/docs/index.html",
"/test/repo/README.md",
"/test/repo/package.json",
"/test/repo/Dockerfile",
"/test/repo/.gitignore"
]
def test_get_language_from_extension(self):
"""Test _get_language_from_extension method"""
# Test common extensions
self.assertEqual(self.detector._get_language_from_extension(".py"), "Python")
self.assertEqual(self.detector._get_language_from_extension(".js"), "JavaScript")
self.assertEqual(self.detector._get_language_from_extension(".jsx"), "JavaScript")
self.assertEqual(self.detector._get_language_from_extension(".ts"), "TypeScript")
self.assertEqual(self.detector._get_language_from_extension(".tsx"), "TypeScript")
self.assertEqual(self.detector._get_language_from_extension(".java"), "Java")
self.assertEqual(self.detector._get_language_from_extension(".go"), "Go")
self.assertEqual(self.detector._get_language_from_extension(".rs"), "Rust")
self.assertEqual(self.detector._get_language_from_extension(".html"), "HTML")
self.assertEqual(self.detector._get_language_from_extension(".css"), "CSS")
self.assertEqual(self.detector._get_language_from_extension(".md"), "Markdown")
# Test unknown extension
self.assertEqual(self.detector._get_language_from_extension(".unknown"), "Other")
def test_get_language_from_filename(self):
"""Test _get_language_from_filename method"""
# Test common filenames
self.assertEqual(self.detector._get_language_from_filename("Dockerfile"), "Dockerfile")
self.assertEqual(self.detector._get_language_from_filename(".gitignore"), "Git")
self.assertEqual(self.detector._get_language_from_filename("package.json"), "JSON")
self.assertEqual(self.detector._get_language_from_filename("README.md"), "Markdown")
# Test unknown filename
self.assertEqual(self.detector._get_language_from_filename("unknown"), None)
@patch('os.walk')
def test_detect_languages(self, mock_walk):
"""Test detect_languages method"""
# Mock os.walk to return our mock files
mock_walk.return_value = [
("/test/repo", ["static", "src", "docs"], ["main.py", "utils.py", "README.md", "package.json", ".gitignore"]),
("/test/repo/static", [], ["script.js", "style.css"]),
("/test/repo/src", ["components"], ["app.js"]),
("/test/repo/src/components", [], ["Button.jsx", "Form.tsx"]),
("/test/repo/docs", [], ["index.html"]),
]
# Test the method
languages = self.detector.detect_languages(self.repo_path)
# Verify the result
self.assertIn("Python", languages)
self.assertIn("JavaScript", languages)
self.assertIn("TypeScript", languages)
self.assertIn("HTML", languages)
self.assertIn("CSS", languages)
self.assertIn("Markdown", languages)
self.assertIn("JSON", languages)
self.assertIn("Git", languages)
@patch('os.walk')
@patch('builtins.open', new_callable=mock_open, read_data="line1\nline2\nline3\n")
def test_get_language_breakdown(self, mock_file, mock_walk):
"""Test get_language_breakdown method"""
# Mock os.walk to return our mock files
mock_walk.return_value = [
("/test/repo", ["static", "src"], ["main.py", "utils.py", "README.md"]),
("/test/repo/static", [], ["script.js"]),
("/test/repo/src", [], ["app.js"]),
]
# Test the method
breakdown = self.detector.get_language_breakdown(self.repo_path)
# Verify the result
self.assertIn("Python", breakdown)
self.assertIn("JavaScript", breakdown)
self.assertIn("Markdown", breakdown)
# Each file has 4 lines (including the newline at the end)
self.assertEqual(breakdown["Python"]["files"], 2)
self.assertEqual(breakdown["Python"]["lines"], 8) # 2 files * 4 lines
self.assertEqual(breakdown["JavaScript"]["files"], 2)
self.assertEqual(breakdown["JavaScript"]["lines"], 8) # 2 files * 4 lines
self.assertEqual(breakdown["Markdown"]["files"], 1)
self.assertEqual(breakdown["Markdown"]["lines"], 4) # 1 file * 4 lines
# Check percentages
total_lines = 20 # 5 files * 4 lines
self.assertEqual(breakdown["Python"]["percentage"], 40) # 8/20 * 100
self.assertEqual(breakdown["JavaScript"]["percentage"], 40) # 8/20 * 100
self.assertEqual(breakdown["Markdown"]["percentage"], 20) # 4/20 * 100
@patch('os.path.isfile')
def test_is_binary_file(self, mock_isfile):
"""Test _is_binary_file method"""
# Mock isfile to always return True
mock_isfile.return_value = True
# Test with text file extensions
self.assertFalse(self.detector._is_binary_file("test.py"))
self.assertFalse(self.detector._is_binary_file("test.js"))
self.assertFalse(self.detector._is_binary_file("test.html"))
self.assertFalse(self.detector._is_binary_file("test.css"))
self.assertFalse(self.detector._is_binary_file("test.md"))
# Test with binary file extensions
self.assertTrue(self.detector._is_binary_file("test.png"))
self.assertTrue(self.detector._is_binary_file("test.jpg"))
self.assertTrue(self.detector._is_binary_file("test.gif"))
self.assertTrue(self.detector._is_binary_file("test.pdf"))
self.assertTrue(self.detector._is_binary_file("test.zip"))
# Test with non-existent file
mock_isfile.return_value = False
self.assertFalse(self.detector._is_binary_file("nonexistent.py"))
@patch('os.path.isdir')
def test_should_ignore_directory(self, mock_isdir):
"""Test _should_ignore_directory method"""
# Mock isdir to always return True
mock_isdir.return_value = True
# Test with common directories to ignore
self.assertTrue(self.detector._should_ignore_directory("/test/repo/node_modules"))
self.assertTrue(self.detector._should_ignore_directory("/test/repo/.git"))
self.assertTrue(self.detector._should_ignore_directory("/test/repo/__pycache__"))
self.assertTrue(self.detector._should_ignore_directory("/test/repo/venv"))
self.assertTrue(self.detector._should_ignore_directory("/test/repo/.vscode"))
# Test with directories not to ignore
self.assertFalse(self.detector._should_ignore_directory("/test/repo/src"))
self.assertFalse(self.detector._should_ignore_directory("/test/repo/app"))
self.assertFalse(self.detector._should_ignore_directory("/test/repo/docs"))
# Test with non-existent directory
mock_isdir.return_value = False
self.assertFalse(self.detector._should_ignore_directory("/test/repo/nonexistent"))
def test_should_ignore_file(self):
"""Test _should_ignore_file method"""
# Test with common files to ignore
self.assertTrue(self.detector._should_ignore_file("/test/repo/.DS_Store"))
self.assertTrue(self.detector._should_ignore_file("/test/repo/Thumbs.db"))
self.assertTrue(self.detector._should_ignore_file("/test/repo/.env"))
# Test with files not to ignore
self.assertFalse(self.detector._should_ignore_file("/test/repo/main.py"))
self.assertFalse(self.detector._should_ignore_file("/test/repo/app.js"))
self.assertFalse(self.detector._should_ignore_file("/test/repo/README.md"))
if __name__ == "__main__":
unittest.main()