172 lines
6.5 KiB
Python
172 lines
6.5 KiB
Python
"""
|
|
Test per verificare che il differ non duplichi l'analisi dei file.
|
|
Verifica che countings e metrics vengano calcolati una sola volta.
|
|
"""
|
|
import os
|
|
import tempfile
|
|
import shutil
|
|
from pathlib import Path
|
|
from unittest.mock import patch, MagicMock
|
|
import pytest
|
|
|
|
from pyucc.core.differ import BaselineManager, Differ
|
|
|
|
|
|
def test_differ_no_duplicate_analysis(tmp_path):
|
|
"""Verifica che countings e metrics vengano calcolati solo una volta per file."""
|
|
|
|
# Crea una directory temporanea con alcuni file Python
|
|
project_dir = tmp_path / "project"
|
|
project_dir.mkdir()
|
|
|
|
# Crea file di test
|
|
file1 = project_dir / "test1.py"
|
|
file1.write_text("def foo():\n return 42\n")
|
|
|
|
file2 = project_dir / "test2.py"
|
|
file2.write_text("def bar():\n x = 1\n return x\n")
|
|
|
|
# Crea baseline manager con baselines_root temporanea
|
|
baseline_dir = tmp_path / "baselines"
|
|
baseline_dir.mkdir()
|
|
bm = BaselineManager(str(project_dir), baselines_root=str(baseline_dir))
|
|
baseline_id = bm.create_baseline_from_dir(
|
|
str(project_dir),
|
|
baseline_id="test_baseline",
|
|
snapshot=True,
|
|
compute_sha1=True
|
|
)
|
|
|
|
# Carica metadata
|
|
metadata = bm.load_metadata(baseline_id)
|
|
|
|
# Verifica che la baseline abbia countings e metrics
|
|
assert len(metadata.files) == 2
|
|
for fm in metadata.files:
|
|
# Baseline deve avere countings e metrics già calcolati
|
|
assert fm.countings is not None, f"File {fm.path} dovrebbe avere countings"
|
|
assert fm.metrics is not None, f"File {fm.path} dovrebbe avere metrics"
|
|
|
|
# Modifica un file
|
|
file1.write_text("def foo():\n # nuovo commento\n return 42\n")
|
|
|
|
# Crea differ con mock per contare quante volte vengono chiamate le funzioni di analisi
|
|
# Le funzioni sono importate dentro build_current_file_list, quindi devo mockare i moduli originali
|
|
with patch('pyucc.core.countings_impl.analyze_file_counts') as mock_counts, \
|
|
patch('pyucc.core.metrics.analyze_file_metrics') as mock_metrics:
|
|
|
|
# Configura i mock per restituire valori realistici
|
|
mock_counts.return_value = {
|
|
'physical_lines': 3,
|
|
'code_lines': 2,
|
|
'comment_lines': 1,
|
|
'blank_lines': 0
|
|
}
|
|
mock_metrics.return_value = {
|
|
'avg_cc': 1.0,
|
|
'max_cc': 1,
|
|
'func_count': 1,
|
|
'mi': 100.0
|
|
}
|
|
|
|
# Esegui differ
|
|
differ = Differ(metadata, str(project_dir))
|
|
current_files = differ.build_current_file_list()
|
|
|
|
# Verifica che build_current_file_list abbia chiamato le funzioni di analisi
|
|
# Dovrebbe essere chiamato una volta per ogni file (2 file)
|
|
assert mock_counts.call_count == 2, \
|
|
f"analyze_file_counts dovrebbe essere chiamato 2 volte, invece: {mock_counts.call_count}"
|
|
assert mock_metrics.call_count == 2, \
|
|
f"analyze_file_metrics dovrebbe essere chiamato 2 volte, invece: {mock_metrics.call_count}"
|
|
|
|
# Verifica che i file correnti abbiano countings e metrics
|
|
for fm in current_files:
|
|
assert fm.countings is not None, f"File {fm.path} dovrebbe avere countings"
|
|
assert fm.metrics is not None, f"File {fm.path} dovrebbe avere metrics"
|
|
|
|
# Reset dei mock per verificare che diff() non richiami le funzioni
|
|
mock_counts.reset_mock()
|
|
mock_metrics.reset_mock()
|
|
|
|
# Esegui diff
|
|
result = differ.diff()
|
|
|
|
# VERIFICA CRITICA: diff() non dovrebbe richiamare analyze_file_counts o analyze_file_metrics
|
|
# perché i dati sono già presenti nei FileMeta objects
|
|
assert mock_counts.call_count == 0, \
|
|
f"diff() NON dovrebbe chiamare analyze_file_counts, invece chiamato {mock_counts.call_count} volte"
|
|
assert mock_metrics.call_count == 0, \
|
|
f"diff() NON dovrebbe chiamare analyze_file_metrics, invece chiamato {mock_metrics.call_count} volte"
|
|
|
|
# Verifica che il risultato contenga i dati corretti
|
|
assert 'pairs' in result
|
|
assert len(result['pairs']) == 2
|
|
|
|
for pair in result['pairs']:
|
|
# Ogni pair dovrebbe avere countings e metrics delta
|
|
assert 'baseline_countings' in pair
|
|
assert 'current_countings' in pair
|
|
assert 'baseline_metrics' in pair
|
|
assert 'current_metrics' in pair
|
|
|
|
|
|
def test_differ_uses_precomputed_data():
|
|
"""Verifica che il differ usi i dati pre-calcolati invece di ricalcolarli."""
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
project_dir = Path(tmpdir) / "project"
|
|
project_dir.mkdir()
|
|
|
|
# Crea file
|
|
test_file = project_dir / "example.py"
|
|
test_file.write_text("def test():\n pass\n")
|
|
|
|
# Crea baseline
|
|
bm = BaselineManager(str(project_dir))
|
|
baseline_id = bm.create_baseline_from_dir(str(project_dir))
|
|
metadata = bm.load_metadata(baseline_id)
|
|
|
|
# Verifica struttura baseline
|
|
assert len(metadata.files) == 1
|
|
baseline_file = metadata.files[0]
|
|
assert baseline_file.countings is not None
|
|
assert baseline_file.metrics is not None
|
|
|
|
# Salva i valori originali
|
|
original_countings = baseline_file.countings.copy()
|
|
original_metrics = baseline_file.metrics.copy()
|
|
|
|
# Modifica il file
|
|
test_file.write_text("def test():\n # comment\n pass\n")
|
|
|
|
# Crea differ e ottieni file correnti
|
|
differ = Differ(metadata, str(project_dir))
|
|
current_files = differ.build_current_file_list()
|
|
|
|
# Verifica che il file corrente abbia countings e metrics
|
|
assert len(current_files) == 1
|
|
current_file = current_files[0]
|
|
assert current_file.countings is not None
|
|
assert current_file.metrics is not None
|
|
|
|
# Esegui diff
|
|
result = differ.diff()
|
|
|
|
# Verifica che il risultato contenga i delta
|
|
assert len(result['pairs']) == 1
|
|
pair = result['pairs'][0]
|
|
|
|
# Verifica che abbia sia baseline che current data
|
|
assert pair['baseline_countings'] == original_countings
|
|
assert pair['current_countings'] == current_file.countings
|
|
|
|
# Verifica che i delta siano calcolati
|
|
assert pair['countings_delta'] is not None
|
|
assert 'code_lines' in pair['countings_delta']
|
|
assert 'comment_lines' in pair['countings_delta']
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pytest.main([__file__, '-v'])
|