| """Structural checks for the shipped symmetrized scaling tables (data/scaling_factors/). |
| |
| These run on the small CSVs that ship in git, so they need no download. The file is named |
| test_scaling_factors_export.py (not test_scaling_factors.py) on purpose: analysis/code/ already has a |
| test_scaling_factors.py, and pytest's default import mode cannot collect two test modules that share |
| a basename. |
| """ |
| import os |
| import sys |
|
|
| import pandas as pd |
| import pytest |
|
|
| HERE = os.path.dirname(os.path.abspath(__file__)) |
| sys.path.insert(0, HERE) |
|
|
| import scaling_factors_reader as R |
|
|
|
|
| def test_both_tables_load_with_expected_shape_and_columns(): |
| tables = R.load_symmetrized_tables() |
| assert set(tables) == {"H", "C"} |
| for nucleus, df in tables.items(): |
| assert df.shape == (12, 3), nucleus |
| assert list(df.columns) == ["intercept", "stationary", "pcm"], nucleus |
| assert "chloroform" in df.index |
| assert df.notnull().all().all(), nucleus |
|
|
|
|
| def test_slopes_are_negative_and_intercepts_in_range(): |
| tables = R.load_symmetrized_tables() |
| |
| for nucleus, df in tables.items(): |
| assert (df["stationary"] < 0).all(), nucleus |
| |
| assert 25 < tables["H"]["intercept"].mean() < 35 |
| assert 150 < tables["C"]["intercept"].mean() < 200 |
|
|
|
|
| def test_predict_shift_uses_the_documented_linear_formula(): |
| |
| |
| |
| |
| table = pd.DataFrame({"intercept": [10.0], "stationary": [-1.0], "pcm": [2.0]}, index=["x"]) |
| table.index.name = "solvent" |
| assert R.predict_shift(table, "x", shielding=5.0, correction=3.0) == pytest.approx(11.0) |
|
|
|
|
| def test_reader_rejects_unknown_nucleus(): |
| with pytest.raises(ValueError): |
| R._csv_path("X") |
|
|