Skip to content

Commit

Permalink
Merge pull request #183 from Steinbeck-Lab/dev-kohulan
Browse files Browse the repository at this point in the history
feat: Add tests for chem router #181
  • Loading branch information
NishaSharma14 authored Jun 7, 2023
2 parents eb7ffc8 + f41e9f7 commit 21bd7f4
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 0 deletions.
165 changes: 165 additions & 0 deletions tests/test_chem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import pytest
from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)


@pytest.fixture
def test_smiles():
return "CN1C=NC2=C1C(=O)N(C(=O)N2C)C"


def test_chem_index():
response = client.get("/v1/chem/")
assert response.status_code == 200
assert response.json() == {"module": "chem", "message": "Successful", "status": 200}


def test_smiles_to_stereo_isomers(test_smiles):
response = client.get(f"/v1/chem/stereoisomers?smiles={test_smiles}")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text == '["Cn1c(=O)c2c(ncn2C)n(C)c1=O"]'


def test_SMILES_Descriptors_returns_descriptors(test_smiles):
response = client.get(f"/v1/chem/descriptors?smiles={test_smiles}")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert (
response.text
== '{"atom_count":24,"heavy_atom_count":14,"molecular_weight":194.19,"exactmolecular_weight":194.08038,"alogp":-1.03,"rotatable_bond_count":0,"topological_polar_surface_area":61.82,"hydrogen_bond_acceptors":6,"hydrogen_bond_donors":0,"hydrogen_bond_acceptors_lipinski":6,"hydrogen_bond_donors_lipinski":0,"lipinski_rule_of_five_violations":0,"aromatic_rings_count":2,"qed_drug_likeliness":0.54,"formal_charge":0,"fractioncsp3":0.375,"number_of_minimal_rings":2,"linear_sugars":false,"circular_sugars":false,"murko_framework":"N1=C[N]C2=C1NCNC2","nplikeliness":-1.09}'
)

response = client.get(f"/v1/chem/descriptors?smiles={test_smiles}&format=html")
assert response.status_code == 200
assert response.headers["content-type"] == "text/html; charset=utf-8"

response = client.get("/v1/chem/descriptors")
assert response.status_code == 422 # Missing required parameter

response = client.get(f"/v1/chem/descriptors?smiles={test_smiles}&toolkit=unknown")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text == '"Error Calculating Descriptors"'


@pytest.mark.parametrize(
"smiles, expected_score",
[
("CN1C=NC2=C1C(=O)N(C(=O)N2C)C", "-1.09"),
("CC=O", "0.96"),
],
)
def test_NPlikeliness_Score(smiles, expected_score):
response = client.get(f"/v1/chem/npscore?smiles={smiles}")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.json() == expected_score


def test_ClassyFire_Classify(test_smiles):
response = client.get(f"/v1/chem/classyfire/classify?smiles={test_smiles}")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"


@pytest.mark.parametrize(
"smiles, expected",
[("invalid_smiles", '"Error reading SMILES string, check again."')],
)
def test_cdk2d_coordinates(smiles, expected):
response = client.get(f"/v1/chem/cdk2d?smiles={smiles}")
assert response.status_code == 200
assert response.text == expected


@pytest.mark.parametrize(
"smiles, expected",
[
(
"CC",
""" RDKit 3D\n'\n '\n'\n ' 8 7 0 0 0 0 0 0 0 0999 V2000\n'\n ' 0.7480 -0.0676 0.0869 C 0 0 0 0 0 0 0 0 0 0 0 0\n'\n ' -0.7480 0.0676 -0.0869 C 0 0 0 0 0 0 0 0 0 0 0 0\n'\n ' 1.2303 -0.2658 -0.8749 H 0 0 0 0 0 0 0 0 0 0 0 0\n'\n ' 1.1714 0.8520 0.5016 H 0 0 0 0 0 0 0 0 0 0 0 0\n'\n ' 0.9830 -0.8922 0.7665 H 0 0 0 0 0 0 0 0 0 0 0 0\n'\n ' -0.9830 0.8922 -0.7665 H 0 0 0 0 0 0 0 0 0 0 0 0\n'\n ' -1.2303 0.2658 0.8749 H 0 0 0 0 0 0 0 0 0 0 0 0\n'\n ' -1.1714 -0.8520 -0.5016 H 0 0 0 0 0 0 0 0 0 0 0 0\n'\n ' 1 2 1 0\n'\n ' 1 3 1 0\n'\n ' 1 4 1 0\n'\n ' 1 5 1 0\n'\n ' 2 6 1 0\n'\n ' 2 7 1 0\n'\n ' 2 8 1 0\n'\n 'M END""",
),
("invalid_smiles", '"Error reading SMILES string, check again."'),
],
)
def test_rdkit3d_mol(smiles, expected):
response = client.get(f"/v1/chem/rdkit3d?smiles={smiles}")
assert response.status_code == 200
# assert response.text == expected


@pytest.mark.parametrize(
"smiles, toolkit, expected",
[
("CC,CC", "cdk", '"1.00000"'),
("CC,CC", "rdkit", "1.0"),
(
"CC,CC,CC",
"cdk",
"<table><tr><th></th><th>0</th><th>1</th><th>2</th></tr><tr><td>0</td><td>1.00000</td><td>1.00000</td><td>1.00000</td></tr><tr><td>1</td><td>1.00000</td><td>1.00000</td><td>1.00000</td></tr><tr><td>2</td><td>1.00000</td><td>1.00000</td><td>1.00000</td></tr></table>",
),
],
)
def test_tanimoto_similarity(smiles, toolkit, expected):
response = client.get(f"/v1/chem/tanimoto?smiles={smiles}&toolkit={toolkit}")
assert response.status_code == 200
assert response.text == expected


@pytest.mark.parametrize(
"smiles, generator, width, height, rotate, CIP, unicolor",
[
("CCO", "cdksdg", 512, 512, 0, False, False),
("CCO", "rdkit", 512, 512, 0, False, False),
],
)
def test_depict2D_molecule(smiles, generator, width, height, rotate, CIP, unicolor):
response = client.get(
f"/v1/chem/depict?smiles={smiles}&generator={generator}&width={width}&height={height}&rotate={rotate}&CIP={CIP}&unicolor={unicolor}"
)
assert response.status_code == 200
assert response.headers["content-type"] == "image/svg+xml"


@pytest.mark.parametrize(
"smiles, fix, expected",
[
("CCO", False, '"No Errors Found"'),
("CCO", True, '"No Errors Found"'),
],
)
def test_check_errors(smiles, fix, expected):
response = client.get(f"/v1/chem/checkerrors?smiles={smiles}&fix={fix}")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text == expected


def test_depict3D_molecule(test_smiles):
response = client.get(f"/v1/chem/depict3D?smiles={test_smiles}")
assert response.status_code == 200
assert response.headers["content-type"] == "text/html; charset=utf-8"


"""
def test_hose_codes(test_smiles):
response = client.get(f"/v1/chem/hosecode?framework=cdk&smiles={test_smiles}")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text ==
# Add more assertions for the expected response data
"""


def test_coconut_preprocessing(test_smiles):
response = client.get(f"/v1/chem/coconutpreprocessing?smiles={test_smiles}")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"


# Run the tests
if __name__ == "__main__":
pytest.main()
15 changes: 15 additions & 0 deletions tests/test_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,40 @@ def test_SMILES_Canonicalise():
)
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text == '"Cn1c(=O)c2c(ncn2C)n(C)c1=O"'


def test_SMILES_to_InChI():
response = client.get("/v1/convert/inchi?smiles=CN1C=NC2=C1C(=O)N(C(=O)N2C)C")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert (
response.text
== '"InChI=1S/C8H10N4O2/c1-10-4-9-6-5(10)7(13)12(3)8(14)11(6)2/h4H,1-3H3"'
)


def test_SMILES_to_InChIKey():
response = client.get("/v1/convert/inchikey?smiles=CN1C=NC2=C1C(=O)N(C(=O)N2C)C")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text == '"RYYVLZVUVIJVGH-UHFFFAOYSA-N"'


def test_SMILES_to_CXSMILES():
response = client.get("/v1/convert/cxsmiles?smiles=CN1C=NC2=C1C(=O)N(C(=O)N2C)C")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert (
response.text
== '"CN1C=NC2=C1C(=O)N(C)C(=O)N2C |(2.68,2.45,;2.22,1.02,;3.1,-0.19,;2.22,-1.4,;0.8,-0.94,;0.8,0.56,;-0.5,1.31,;-0.5,2.81,;-1.8,0.56,;-3.1,1.31,;-1.8,-0.94,;-3.1,-1.69,;-0.5,-1.69,;-0.5,-3.19,)|"'
)


def test_SMILES_convert_to_Formats():
response = client.get("/v1/convert/formats?smiles=CN1C=NC2=C1C(=O)N(C(=O)N2C)C")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.json() == {
"mol": "\n RDKit 2D\n\n 14 15 0 0 0 0 0 0 0 0999 V2000\n 2.7760 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1.2760 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\n 0.3943 1.2135 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -1.0323 0.7500 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\n -1.0323 -0.7500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.3943 -1.2135 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 0.7062 -2.6807 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 2.1328 -3.1443 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n -0.4086 -3.6844 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\n -1.8351 -3.2209 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -2.9499 -4.2246 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n -2.1470 -1.7537 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\n -3.5736 -1.2902 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n -0.0967 -5.1517 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n 1 2 1 0\n 2 3 1 0\n 3 4 2 0\n 4 5 1 0\n 5 6 2 0\n 6 7 1 0\n 7 8 2 0\n 7 9 1 0\n 9 10 1 0\n 10 11 2 0\n 10 12 1 0\n 12 13 1 0\n 9 14 1 0\n 6 2 1 0\n 12 5 1 0\nM END\n",
"cannonicalsmiles": "CN1C(=O)C2=C(N=CN2C)N(C)C1=O",
Expand All @@ -68,6 +79,7 @@ def test_SMILES_convert_to_Formats():
def test_SMILES_to_IUPACname():
response = client.get("/v1/convert/iupac?smiles=CN1C=NC2=C1C(=O)N(C(=O)N2C)C")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text == '"1,3,7-trimethylpurine-2,6-dione"'


Expand All @@ -76,18 +88,21 @@ def test_IUPACname_or_SELFIES_to_SMILES():
"/v1/convert/smiles?input_text=1,3,7-trimethylpurine-2,6-dione&representation=iupac"
)
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text == '"CN1C=NC2=C1C(=O)N(C)C(=O)N2C"'

response = client.get(
"/v1/convert/smiles?input_text=[C][N][C][=N][C][=C][Ring1][Branch1][C][=Branch1][C][=O][N][Branch1][=Branch2][C][=Branch1][C][=O][N][Ring1][Branch2][C][C]&representation=selfies"
)
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert response.text == '"CN1C=NC2=C1C(=O)N(C(=O)N2C)C"'


def test_encode_SELFIES():
response = client.get("/v1/convert/selfies?smiles=CN1C=NC2=C1C(=O)N(C(=O)N2C)C")
assert response.status_code == 200
assert response.headers["content-type"] == "application/json"
assert (
response.text
== '"[C][N][C][=N][C][=C][Ring1][Branch1][C][=Branch1][C][=O][N][Branch1][=Branch2][C][=Branch1][C][=O][N][Ring1][Branch2][C][C]"'
Expand Down

0 comments on commit 21bd7f4

Please sign in to comment.