From 7c3f8b431cf21650492629d13205ea88266a5396 Mon Sep 17 00:00:00 2001 From: Warsame Date: Sat, 27 Sep 2025 17:11:10 -0400 Subject: [PATCH] V3 --- requirements.txt | Bin 47 -> 106 bytes ...st_hf_handler.cpython-312-pytest-8.4.2.pyc | Bin 2952 -> 0 bytes ...ic_heuristics.cpython-312-pytest-8.4.2.pyc | Bin 2254 -> 0 bytes ...rics_contract.cpython-313-pytest-8.4.2.pyc | Bin 3326 -> 0 bytes ...porter_schema.cpython-313-pytest-8.4.2.pyc | Bin 2003 -> 0 bytes tests/test_bus_factor_metric.py | 16 ++++++++++++++++ tests/test_cli.py | 18 ++++++++++++++++++ tests/test_code_quality_metric.py | 16 ++++++++++++++++ tests/test_dataset_and_code_metric.py | 16 ++++++++++++++++ tests/test_dataset_quality_metric.py | 16 ++++++++++++++++ tests/test_hf_handler.py | 9 --------- tests/test_logging_env.py | 13 +++++++++++++ tests/test_metric_heuristics.py | 7 ------- tests/test_metrics_contract.py | 11 ----------- tests/test_parallel_metrics.py | 11 +++++++++++ tests/test_performance_claims_metric.py | 16 ++++++++++++++++ tests/test_ramp_up_metric.py | 16 ++++++++++++++++ tests/test_reporter_schema.py | 16 ---------------- tests/test_size_metric.py | 16 ++++++++++++++++ 19 files changed, 154 insertions(+), 43 deletions(-) delete mode 100644 tests/__pycache__/test_hf_handler.cpython-312-pytest-8.4.2.pyc delete mode 100644 tests/__pycache__/test_metric_heuristics.cpython-312-pytest-8.4.2.pyc delete mode 100644 tests/__pycache__/test_metrics_contract.cpython-313-pytest-8.4.2.pyc delete mode 100644 tests/__pycache__/test_reporter_schema.cpython-313-pytest-8.4.2.pyc create mode 100644 tests/test_bus_factor_metric.py create mode 100644 tests/test_cli.py create mode 100644 tests/test_code_quality_metric.py create mode 100644 tests/test_dataset_and_code_metric.py create mode 100644 tests/test_dataset_quality_metric.py delete mode 100644 tests/test_hf_handler.py create mode 100644 tests/test_logging_env.py delete mode 100644 tests/test_metric_heuristics.py delete mode 100644 tests/test_metrics_contract.py create mode 100644 tests/test_parallel_metrics.py create mode 100644 tests/test_performance_claims_metric.py create mode 100644 tests/test_ramp_up_metric.py delete mode 100644 tests/test_reporter_schema.py create mode 100644 tests/test_size_metric.py diff --git a/requirements.txt b/requirements.txt index 6dcda410bb422255737d3a5fae8e40301cf499a8..78c2af88257cd7a61985587dd833ec3c2cb33869 100644 GIT binary patch literal 106 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 J%EGg*?cY|;g#`cr diff --git a/tests/__pycache__/test_reporter_schema.cpython-313-pytest-8.4.2.pyc b/tests/__pycache__/test_reporter_schema.cpython-313-pytest-8.4.2.pyc deleted file mode 100644 index f2d1c7740ee1ccca076793052a6120b33f8f568f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2003 zcmah}TW=dh6rS;}@0Y}mb8To{he8(`<6NAeVgpqY38l1^vWkS1NUP0ylB`(oZfDj6 z2O;%=2Y5n4s>CyI`~_b50~DwbBP3Mu#M?sNcw%POvv#0@m3_{4zVpqQGZ)Q8v6utw z`|9-D(=QSL{KfW;P39g09q8~bz)<+au0j$uu&d%^jb{>fQ@d%LW>{GOICBCu z^>;q_z6NP_5BVMr_PjGo)Ek;K^9uW4wAn{aTYvr6&xiE4s>TQcp3P)-%jz z1|Z$KC9gFU%)*%I?E)K%~L ze&Y5!0C;ORhnem-034`NwwID<11rCAD>wLGe`u3N($l)afVmqwNTd(;ESdK#_d`D!TV_+Mp0D)q&Nvds3yRrMG2 ztNUsbiYR$dmi>&?sz`3+*~*f#mh^~S!VYv{2l}fgK&#!Ss%!QTRlBI?(TrsV=)}VV zn!NX5d*@x6bx~jt%fskI)}`f`GaM#&tpVnTP7B!V`9|M20-F`Ajz>~Rb4Pt*9Gh0) zVOkmCIA8G*KK5|WbS-39j%oJ@UHCT_>(h>HA(tRJF$8fYN9=PHwN5J|9Oq}cW?&Mw zI@9eMme-ZqtIy}-aT7BCux~ncFrc&lAYx@fRF$&ocqBC%{43GvXz;vwSHL7FgOi>f26WyM(43k0}V9Gsvmece+AqoH*W* z=@{bTWDQ~-BVK`)?uf~4&)vb89q^PPjxsRNhrVOFX23F93NP|5@_d@8*_H8NeLPr; zf~d;Ic)y^GUnUWj_st$sgxQTaMLo0O z4`^NNLX=>eX`Gsb$sYD?jJn3LjhrsQ{Qc%zN8VyD#3S%aZt72v&!>JaPK65hS8oXa ztTG)YS^P|UMfg8bU}io{Glrq&N`x|?IvZv=mjSnyBa{P+*TOvKa-iLbPyv*yVUcqM z@Y2f>DuL=uIKjCRc=c9wHYnw0g*L>_#x~5s5B0KPr5k rn-y+e= 0 + +def test_bus_factor_edge_case_zero_contrib(): + metric = BusFactorMetric() + mv = metric.score({"contributors": 0}) + assert mv.value == 0.0 \ No newline at end of file diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..367d204 --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,18 @@ +import subprocess + +def test_run_install(): + result = subprocess.run(["./run", "install"], capture_output=True) + assert result.returncode == 0 + +def test_run_test(): + result = subprocess.run(["./run", "test"], capture_output=True) + assert b"test cases passed" in result.stdout + +def test_run_score_valid_url(): + result = subprocess.run(["./run", "score", "urls.txt"], capture_output=True) + assert result.stdout.decode().strip().startswith("{") + assert result.returncode == 0 + +def test_run_score_invalid_url(): + result = subprocess.run(["./run", "score", "bad_urls.txt"], capture_output=True) + assert result.returncode == 1 or "error" in result.stderr.decode().lower() \ No newline at end of file diff --git a/tests/test_code_quality_metric.py b/tests/test_code_quality_metric.py new file mode 100644 index 0000000..e3f2389 --- /dev/null +++ b/tests/test_code_quality_metric.py @@ -0,0 +1,16 @@ +from acmecli.metrics.code_quality_metric import CodeQualityMetric + +def test_code_quality_range(): + metric = CodeQualityMetric() + mv = metric.score({"lint_score": 0.9}) + assert 0.0 <= mv.value <= 1.0 + +def test_code_quality_latency(): + metric = CodeQualityMetric() + mv = metric.score({"lint_score": 0.9}) + assert mv.latency_ms >= 0 + +def test_code_quality_missing(): + metric = CodeQualityMetric() + mv = metric.score({}) + assert mv.value == 0.0 \ No newline at end of file diff --git a/tests/test_dataset_and_code_metric.py b/tests/test_dataset_and_code_metric.py new file mode 100644 index 0000000..a65ef12 --- /dev/null +++ b/tests/test_dataset_and_code_metric.py @@ -0,0 +1,16 @@ +from acmecli.metrics.dataset_and_code_metric import DatasetAndCodeMetric + +def test_dataset_and_code_range(): + metric = DatasetAndCodeMetric() + mv = metric.score({"linked": True}) + assert 0.0 <= mv.value <= 1.0 + +def test_dataset_and_code_latency(): + metric = DatasetAndCodeMetric() + mv = metric.score({"linked": True}) + assert mv.latency_ms >= 0 + +def test_dataset_and_code_missing(): + metric = DatasetAndCodeMetric() + mv = metric.score({}) + assert mv.value == 0.0 \ No newline at end of file diff --git a/tests/test_dataset_quality_metric.py b/tests/test_dataset_quality_metric.py new file mode 100644 index 0000000..706c080 --- /dev/null +++ b/tests/test_dataset_quality_metric.py @@ -0,0 +1,16 @@ +from acmecli.metrics.dataset_quality_metric import DatasetQualityMetric + +def test_dataset_quality_range(): + metric = DatasetQualityMetric() + mv = metric.score({"quality_score": 0.8}) + assert 0.0 <= mv.value <= 1.0 + +def test_dataset_quality_latency(): + metric = DatasetQualityMetric() + mv = metric.score({"quality_score": 0.8}) + assert mv.latency_ms >= 0 + +def test_dataset_quality_missing(): + metric = DatasetQualityMetric() + mv = metric.score({}) + assert mv.value == 0.0 \ No newline at end of file diff --git a/tests/test_hf_handler.py b/tests/test_hf_handler.py deleted file mode 100644 index a4bbfaf..0000000 --- a/tests/test_hf_handler.py +++ /dev/null @@ -1,9 +0,0 @@ -from src.acmecli.hf_handler import HFHandler - -def test_hf_fetch_meta(monkeypatch): - h = HFHandler() - meta = h.fetch_meta("https://huggingface.co/google/gemma-3-270m") - assert isinstance(meta, dict) - assert "modelId" in meta - assert "downloads" in meta - assert "license" in meta \ No newline at end of file diff --git a/tests/test_logging_env.py b/tests/test_logging_env.py new file mode 100644 index 0000000..5577fc9 --- /dev/null +++ b/tests/test_logging_env.py @@ -0,0 +1,13 @@ +import os +import tempfile + +def test_logging_env(monkeypatch): + with tempfile.NamedTemporaryFile() as log_file: + monkeypatch.setenv("LOG_FILE", log_file.name) + monkeypatch.setenv("LOG_LEVEL", "DEBUG") + # You should call your project's logging function here if available + from acmecli import main_logger + main_logger.debug("test message") + log_file.seek(0) + contents = log_file.read().decode() + assert "test message" in contents \ No newline at end of file diff --git a/tests/test_metric_heuristics.py b/tests/test_metric_heuristics.py deleted file mode 100644 index bf80dd7..0000000 --- a/tests/test_metric_heuristics.py +++ /dev/null @@ -1,7 +0,0 @@ -from src.acmecli.metrics.hf_downloads_metric import HFDownloadsMetric - -def test_hf_downloads_metric(): - m = HFDownloadsMetric() - mv = m.score({"downloads": 5000}) - assert 0.0 <= mv.value <= 1.0 - assert mv.value == 0.5 \ No newline at end of file diff --git a/tests/test_metrics_contract.py b/tests/test_metrics_contract.py deleted file mode 100644 index 51199a7..0000000 --- a/tests/test_metrics_contract.py +++ /dev/null @@ -1,11 +0,0 @@ -from acmecli.metrics.base import REGISTRY -from acmecli.metrics.license_metric import LicenseMetric - -def test_registry_has_license_metric(): - assert any(m.name == "license" for m in REGISTRY) - -def test_metric_value_range(): - m = LicenseMetric() - mv = m.score({}) - assert 0.0 <= mv.value <= 1.0 - assert mv.latency_ms >= 0 diff --git a/tests/test_parallel_metrics.py b/tests/test_parallel_metrics.py new file mode 100644 index 0000000..b611bb4 --- /dev/null +++ b/tests/test_parallel_metrics.py @@ -0,0 +1,11 @@ +import time +from acmecli.cli import score_all_metrics_parallel + +def test_metrics_run_parallel(): + start = time.time() + # Simulate input that runs several metrics + report = score_all_metrics_parallel({"contributors": 10, "size_kb": 100, "linked": True}) + duration = time.time() - start + # For parallel, duration should be less than sum of all metric durations + assert isinstance(report, dict) + assert duration < 2.0 # Example threshold, adjust to your actual metric timings \ No newline at end of file diff --git a/tests/test_performance_claims_metric.py b/tests/test_performance_claims_metric.py new file mode 100644 index 0000000..33f2f02 --- /dev/null +++ b/tests/test_performance_claims_metric.py @@ -0,0 +1,16 @@ +from acmecli.metrics.performance_claims_metric import PerformanceClaimsMetric + +def test_performance_claims_range(): + metric = PerformanceClaimsMetric() + mv = metric.score({"claims": 5}) + assert 0.0 <= mv.value <= 1.0 + +def test_performance_claims_latency(): + metric = PerformanceClaimsMetric() + mv = metric.score({"claims": 5}) + assert mv.latency_ms >= 0 + +def test_performance_claims_missing(): + metric = PerformanceClaimsMetric() + mv = metric.score({}) + assert mv.value == 0.0 \ No newline at end of file diff --git a/tests/test_ramp_up_metric.py b/tests/test_ramp_up_metric.py new file mode 100644 index 0000000..53b2e9e --- /dev/null +++ b/tests/test_ramp_up_metric.py @@ -0,0 +1,16 @@ +from acmecli.metrics.ramp_up_metric import RampUpMetric + +def test_ramp_up_range(): + metric = RampUpMetric() + mv = metric.score({"readme_size": 1000}) + assert 0.0 <= mv.value <= 1.0 + +def test_ramp_up_latency(): + metric = RampUpMetric() + mv = metric.score({"readme_size": 1000}) + assert mv.latency_ms >= 0 + +def test_ramp_up_missing_readme(): + metric = RampUpMetric() + mv = metric.score({}) + assert mv.value == 0.0 \ No newline at end of file diff --git a/tests/test_reporter_schema.py b/tests/test_reporter_schema.py deleted file mode 100644 index ba0dbcd..0000000 --- a/tests/test_reporter_schema.py +++ /dev/null @@ -1,16 +0,0 @@ -from acmecli.types import ReportRow - -def test_reportrow_has_required_fields(): - row = ReportRow( - name="demo", category="MODEL", - net_score=0.0, net_score_latency=0, - ramp_up_time=0.0, ramp_up_time_latency=0, - bus_factor=0.0, bus_factor_latency=0, - performance_claims=0.0, performance_claims_latency=0, - license=0.0, license_latency=0, - size_score={}, size_score_latency=0, - dataset_and_code_score=0.0, dataset_and_code_score_latency=0, - dataset_quality=0.0, dataset_quality_latency=0, - code_quality=0.0, code_quality_latency=0 - ) - assert row.category == "MODEL" diff --git a/tests/test_size_metric.py b/tests/test_size_metric.py new file mode 100644 index 0000000..50bb85a --- /dev/null +++ b/tests/test_size_metric.py @@ -0,0 +1,16 @@ +from acmecli.metrics.size_metric import SizeMetric + +def test_size_range(): + metric = SizeMetric() + mv = metric.score({"size_kb": 100}) + assert 0.0 <= mv.value <= 1.0 + +def test_size_latency(): + metric = SizeMetric() + mv = metric.score({"size_kb": 100}) + assert mv.latency_ms >= 0 + +def test_size_edge_case_zero(): + metric = SizeMetric() + mv = metric.score({"size_kb": 0}) + assert mv.value == 0.0 \ No newline at end of file