File: test_compound.py

package info (click to toggle)
python-pubchempy 1.0.4-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 388 kB
  • sloc: python: 1,377; makefile: 147
file content (170 lines) | stat: -rw-r--r-- 5,113 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# -*- coding: utf-8 -*-
"""
test_compound
~~~~~~~~~~~~~

Test compound object.

"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import re

import pytest

from pubchempy import *


@pytest.fixture(scope='module')
def c1():
    """Compound CID 241."""
    return Compound.from_cid(241)


@pytest.fixture(scope='module')
def c2():
    """Compound CID 175."""
    return Compound.from_cid(175)


def test_basic(c1):
    """Test Compound is retrieved and has a record and correct CID."""
    assert c1.cid == 241
    assert repr(c1) == 'Compound(241)'
    assert c1.record


def test_atoms(c1):
    assert len(c1.atoms) == 12
    assert set(a.element for a in c1.atoms) == {'C', 'H'}
    assert set(c1.elements) == {'C', 'H'}


def test_atoms_deprecated(c1):
    with warnings.catch_warnings(record=True) as w:
        assert set(a['element'] for a in c1.atoms) == {'C', 'H'}
        assert len(w) == 1
        assert w[0].category == PubChemPyDeprecationWarning
        assert str(w[0].message) == 'Dictionary style access to Atom attributes is deprecated'


def test_single_atom():
    """Test Compound when there is a single atom and no bonds."""
    c = Compound.from_cid(259)
    assert c.atoms == [Atom(aid=1, number=35, x=2, y=0, charge=-1)]
    assert c.bonds == []


def test_bonds(c1):
    assert len(c1.bonds) == 12
    assert set(b.order for b in c1.bonds) == {BondType.SINGLE, BondType.DOUBLE}


def test_bonds_deprecated(c1):
    with warnings.catch_warnings(record=True) as w:
        assert set(b['order'] for b in c1.bonds) == {BondType.SINGLE, BondType.DOUBLE}
        assert len(w) == 1
        assert w[0].category == PubChemPyDeprecationWarning
        assert str(w[0].message) == 'Dictionary style access to Bond attributes is deprecated'


def test_charge(c1):
    assert c1.charge == 0


def test_coordinates(c1):
    for a in c1.atoms:
        assert isinstance(a.x, (float, int))
        assert isinstance(a.y, (float, int))
        assert a.z is None


def test_coordinates_deprecated(c1):
    with warnings.catch_warnings(record=True) as w:
        assert isinstance(c1.atoms[0]['x'], (float, int))
        assert isinstance(c1.atoms[0]['y'], (float, int))
        assert 'z' not in c1.atoms[0]
        assert len(w) == 3
        assert w[0].category == PubChemPyDeprecationWarning
        assert str(w[0].message) == 'Dictionary style access to Atom attributes is deprecated'


def test_identifiers(c1):
    assert len(c1.canonical_smiles) > 10
    assert len(c1.isomeric_smiles) > 10
    assert c1.inchi.startswith('InChI=')
    assert re.match(r'^[A-Z]{14}-[A-Z]{10}-[A-Z\d]$', c1.inchikey)
    # TODO: c1.molecular_formula


def test_properties_types(c1):
    assert isinstance(c1.molecular_weight, float)
    assert isinstance(c1.iupac_name, text_types)
    assert isinstance(c1.xlogp, float)
    assert isinstance(c1.exact_mass, float)
    assert isinstance(c1.monoisotopic_mass, float)
    assert isinstance(c1.tpsa, (int, float))
    assert isinstance(c1.complexity, float)
    assert isinstance(c1.h_bond_donor_count, int)
    assert isinstance(c1.h_bond_acceptor_count, int)
    assert isinstance(c1.rotatable_bond_count, int)
    assert isinstance(c1.heavy_atom_count, int)
    assert isinstance(c1.isotope_atom_count, int)
    assert isinstance(c1.atom_stereo_count, int)
    assert isinstance(c1.defined_atom_stereo_count, int)
    assert isinstance(c1.undefined_atom_stereo_count, int)
    assert isinstance(c1.bond_stereo_count, int)
    assert isinstance(c1.defined_bond_stereo_count, int)
    assert isinstance(c1.undefined_bond_stereo_count, int)
    assert isinstance(c1.covalent_unit_count, int)
    assert isinstance(c1.fingerprint, text_types)


def test_coordinate_type(c1):
    assert c1.coordinate_type == '2d'


def test_compound_equality():
    assert Compound.from_cid(241) == Compound.from_cid(241)
    assert get_compounds('Benzene', 'name')[0], get_compounds('c1ccccc1' == 'smiles')[0]


def test_synonyms(c1):
    assert len(c1.synonyms) > 5
    assert len(c1.synonyms) > 5


def test_related_records(c1):
    assert len(c1.sids) > 20
    assert len(c1.aids) > 20


def test_compound_dict(c1):
    assert isinstance(c1.to_dict(), dict)
    assert c1.to_dict()
    assert 'atoms' in c1.to_dict()
    assert 'bonds' in c1.to_dict()
    assert 'element' in c1.to_dict()['atoms'][0]


def test_charged_compound(c2):
    assert len(c2.atoms) == 7
    assert c2.atoms[0].charge == -1


def test_charged_compound_deprecated(c2):
    with warnings.catch_warnings(record=True) as w:
        assert c2.atoms[0]['charge'] == -1
        assert len(w) == 1
        assert w[0].category == PubChemPyDeprecationWarning
        assert str(w[0].message) == 'Dictionary style access to Atom attributes is deprecated'


def test_fingerprint(c1):
    # CACTVS fingerprint is 881 bits
    assert len(c1.cactvs_fingerprint) == 881
    # Raw fingerprint has 4 byte prefix, 7 bit suffix, and is hex encoded (/4) = 230
    assert len(c1.fingerprint) == (881 + (4 * 8) + 7) / 4