# -*- coding: utf-8 -*-
'''Chemical Engineering Design Library (ChEDL). Utilities for process modeling.
Copyright (C) 2022, Caleb Bell <Caleb.Andrew.Bell@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.'''

import os
import pytest
from fluids.numerics import assert_close, assert_close1d
from thermo.functional_groups import *
from thermo import Chemical
from chemicals import search_chemical

try:
    import rdkit
    from rdkit import Chem
except:
    rdkit = None
    
    
    
def mol_from_name(name):
    obj = search_chemical(name)
    return Chem.MolFromSmiles(obj.smiles)

mercaptan_chemicals = ['methanethiol', 'Ethanethiol', '1-Propanethiol', '2-Propanethiol',
                       'Allyl mercaptan', 'Butanethiol', 'tert-Butyl mercaptan', 'pentyl mercaptan',
                      'Thiophenol', 'Dimercaptosuccinic acid', 'Thioacetic acid',
                      'Glutathione', 'Cysteine', '2-Mercaptoethanol',
                      'Dithiothreitol', 'Furan-2-ylmethanethiol', '3-Mercaptopropane-1,2-diol',
                      '1-Hexadecanethiol', 'Pentachlorobenzenethiol']

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_mercaptan():
    chemicals = [ '3-Mercapto-1-propanesulfonic acid'] + mercaptan_chemicals
    for c in chemicals:
        assert is_mercaptan(mol_from_name(c))
       
sulfide_chemicals = ['propylene sulfide', 'monochlorodimethyl sulfide', 'Dimethyl sulfide', 'Ethyl methyl sulfide', 'Diethyl sulfide', 'Methyl propyl sulfide', 'Ethyl propyl sulfide', 'Butyl methyl sulfide', 'Butyl ethyl sulfide', 'Methyl pentyl sulfide', 'Dibutyl sulfide', 'Dipentyl sulfide', 'Dihexyl sulfide', 'Diheptyl sulfide', 'Dioctyl sulfide', 'Isopropyl methyl sulfide', 'Tert-butyl methyl sulfide', 'Ethyl isopropyl sulfide', 'Diallyl sulfide', 'Tert-butyl ethyl sulfide', 'Methyl phenyl sulfide', 'Phenyl vinyl sulfide', 'Ethyl phenyl sulfide', 'Di-tert-butyl sulfide', 'Di-sec-butyl sulfide', 'Allyl phenyl sulfide', 'Diphenyl sulfide', 'Dibenzyl sulfide']
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_sulfide():
    not_is_sulfide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene',
    '1-Decanethiol', '3-Pentanethiol', 'Di-phenyl disulfide'] + mercaptan_chemicals + disulfide_chemicals
    for c in not_is_sulfide:
        assert not is_sulfide(mol_from_name(c))

    for c in sulfide_chemicals:
        assert is_sulfide(mol_from_name(c))

disulfide_chemicals = ['Di-phenyl disulfide', "Dimethyl disulfide", "Diethyl disulfide", "Diallyl disulfide", "Diisopropyl disulfide", "Dipentyl disulfide", "Dihexyl disulfide", "Diheptyl disulfide", "Dioctyl disulfide", "Dipropyl disulfide", "Di-tert-butyl disulfide", "Dibutyl disulfide", "Di-phenyl disulfide", "Dicyclohexyl disulfide", "Di-2-naphthyl disulfide"]
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_disulfide():
    not_is_sulfide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene',
    '1-Decanethiol', '3-Pentanethiol'] + sulfide_chemicals
    for c in not_is_sulfide:
        assert not is_disulfide(mol_from_name(c))

    for c in disulfide_chemicals:
        assert is_disulfide(mol_from_name(c))

sulfoxide_chemicals = ['Tetrahydrothiophene 1-oxide', 'Diphenyl sulfoxide', 'Methyl phenyl sulfoxide', 'Dimethyl sulfoxide', 'tert-Butyl methyl sulfoxide', '3-Chloropropyl octyl sulfoxide', 'Alliin', 'Alpha-Amanitin', 'Beta-Amanitin', 'Diethyl sulfoxide', 'Dimethyl sulfoxide', 'Fensulfothion', 'Mesoridazine', 'Methyl phenyl sulfoxide', 'Oxfendazole', 'Oxydemeton-methyl', 'Oxydisulfoton', 'Sulfoxide']
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_sulfoxide():
    not_is_sulfide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene',
    '1-Decanethiol', '3-Pentanethiol'] + sulfide_chemicals + disulfide_chemicals + mercaptan_chemicals
    for c in not_is_sulfide:
        assert not is_sulfoxide(mol_from_name(c))

    for c in sulfoxide_chemicals:
        assert is_sulfoxide(mol_from_name(c))

sulfone_chemicals = ['trifluoromethanesulfonyl fluoride',
'4-(methylsulfonyl)benzonitrile',
'2-chloro-4-(methylsulfonyl)aniline',
'3-chloro-1-benzothiophene 1,1-dioxide',
'diethyl sulfone',
'picryl sulfone',
'1,2,2,2-tetrafluoroethanesulfonyl fluoride',
'isopropylsulfamoyl chloride',
'bis(3-nitrophenyl)sulfone',
'sulfone, hexyl vinyl',
'3-chloropropanesulfonyl chloride',
'5-chloro-2-((p-tolyl)sulphonyl)aniline',
'5-bromo-2-methoxybenzenesulfonyl chloride',
'1,4-butane sultone',
'2,4,5-trichlorobenzenesulfonyl chloride',
'dimethyl sulfate',
'2,4-dimethylsulfolane',
'3-sulfolene',
'2-(phenylsulfonyl)ethanol',
'pyrogallol sulfonphthalein',
'2-methyl-5-nitrobenzenesulfonyl chloride',
'peraktivin',
"4,4'-sulfonyldibenzoic acid",
'quinoline-8-sulfonyl chloride',
'3-methylsulfolene',
'methyl p-tolyl sulfone',
'di-p-tolyl sulfone',
'ethyl phenyl sulfone',
'3-amino-4-chlorobenzenesulfonyl fluoride',
'methanesulfonyl chloride',
'2-chloroethanesulfonyl chloride',
'(propylsulfonyl)benzene',
'thiete sulfone',
'2-(3-nitrophenylsulfonyl)ethanol',
'phenyl t-butyl sulfone',
'sulfolane',
'3-bromo-1-benzothiophene 1,1-dioxide',
'phenyl tribromomethyl sulfone',
'2-thiophenesulfonyl chloride',
'pentamethylene sulfone',
'3,5-dichloro-2-hydroxybenzenesulfonyl chloride',
'sulfone, phenyl p-tolyl',
'tetradifon',
'2-tosylethanol',
'o-toluenesulfonyl chloride',
'sulfone, p-tolyl 2,5-xylyl',
'4-chloro-2-nitrophenyl methyl sulfone',
'2,4-dimethyldiphenylsulfone',
'3-(trifluoromethyl)benzenesulfonyl chloride',
'monoacetyldapsone',
'methyl 4-methanesulfonylbenzoate',
'acedapsone',
'4-(methylsulfonyl)-2-nitroaniline',
"2,4'-dihydroxydiphenyl sulfone",
'4-(methylsulfonyl)phenol',
'n,n-bis(trifluoromethylsulfonyl)aniline',
'2-(ethylsulfonyl)ethanol',
'3-nitrobenzenesulfonyl chloride',
'disyston sulfone',
'2,5-dichlorothiophene-3-sulfonyl chloride',
'phenyl styryl sulfone',
'2-chloro-5-nitrobenzenesulfonyl chloride',
'p-toluenesulfonhydrazide',
'3-amino-4-methoxybenzenesulfonyl fluoride',
'2,5-xylyl sulfone',
'di-tert-butyl sulfone',
'4-(trifluoromethoxy)benzenesulfonyl chloride',
'benzyl phenyl sulfone',
'benzyl methyl sulfone',
'albendazole sulfone',
'2,5-dichlorobenzenesulfonyl chloride',
'tetrabromophenol blue',
'2-(trifluoromethyl)benzenesulfonyl chloride',
'2-(phenylsulfonyl)thiophene',
'benzenesulfonyl chloride',
'5-fluoro-2-methylbenzenesulfonyl chloride',
'2,4,6-trimethyldiphenylsulphone',
'2-naphthalenesulfonyl chloride',
'mesityl sulfone',
'4-(trifluoromethylsulfonyl)aniline',
'cresol red',
'benzenesulfonyl fluoride',
'sulfonyl diamine',
'trifluoromethanesulfonyl chloride',
'2-(phenylsulfonyl)aniline',
'2-nitrobenzenesulfonyl chloride',
'sulfonyldiethanol',
'2-bromobenzothiophene sulfone',
'phenyl benzenesulfinyl sulfone',
'4-(methylsulfonyl)benzaldehyde',
'metanilyl fluoride, hydrochloride',
'2-amino-4-(methylsulfonyl)phenol',
'1-butanesulfonyl chloride',
'1-(methylsulfonyl)-4-nitrobenzene',
'3,4-dichlorobenzenesulfonyl chloride',
'diallyl sulfone',
'3-chloro-2-methylbenzenesulfonyl chloride',
'di-n-octyl sulfone',
'tinidazole',
'sulfone, butyl ethyl',
'sulfamoyldapsone',
'4,5-dibromothiophene-2-sulfonyl chloride',
'2-chloro-4-fluorobenzenesulfonyl chloride',
'chlordetal',
'2,4,5-trichlorobenzenesulfonohydrazide',
'sulfonyldiacetic acid',
'bromophenol blue',
'2,4-dimethylbenzenesulfonyl chloride',
'methyl phenyl sulfone',
'octyl disulfone',
'2-methyl-2-propenyl p-tolyl sulphone',
'4-chloro-3-nitrobenzenesulfonyl chloride',
'tosyl fluoride',
'phorate sulfone',
'4-chlorophenyl methyl sulfone',
'4-bromobenzenesulfonyl chloride',
'p-chlorophenyl 2-chloro-1,1,2-trifluoroethyl sulfone',
'tosyl chloride',
'divinyl sulfone',
'4-chlorobenzenesulfonyl chloride',
'bromocresol purple',
'disulfone, dihexyl',
'allyl methyl sulfone',
'pipsyl chloride',
'4-methoxybenzenesulfonyl chloride',
'oxycarboxin',
'bromothymol blue',
'4-nitrobenzenesulfonyl chloride',
'1-nitro-4-(phenylsulfonyl)benzene',
'didecyl sulfone',
'thietane 1,1-dioxide',
'dapsone',
'chlorophenol red',
"disodium 4,4'-sulfonyldiphenolate",
'demeton-s-methylsulphon',
'4-(methylsulfonyl)aniline',
'bromocresol green',
'1-naphthalenesulfonyl chloride',
'dimethyl sulfone',
'4-fluorophenyl methyl sulfone',
"dimethyl 4,4'-sulfonyldibenzoate",
"n,n'-dimethylsulfamide",
'methanesulfonyl fluoride',
'2-bromobenzenesulfonyl chloride',
'1-propanesulfonyl chloride',
'methiocarb sulfone',
'2-(methylsulphonyl)-2-methylpropane',
'phenylmethylsulfonyl fluoride',
'allyl phenyl sulfone',
'thymol blue',
'ethyl methyl sulfone',
'diisobutyl sulfone',
'2,4,6-triisopropylbenzenesulfonyl chloride',
'2,3,4-trichlorobenzenesulfonyl chloride',
'diphenyl disulfone',
'4-fluorobenzenesulfonyl chloride',
'tosylmethyl isocyanide',
'p-(p-nitrophenylsulfonyl)aniline',
'sulfonmethane',
'phenol red',
'dibutyl sulfone',
'methyl vinyl sulfone',
'benzenesulfonyl isocyanate',
'1,3-dithiane 1,1,3,3-tetraoxide',
'2-methylsulfonylethenylbenzene',
'2,4-dixylylsulfone',
'methyl pentyl sulfone',
'dl-methionine sulfone',
'methyl propyl sulfone',
'sulfone, 3-butynyl p-tolyl',
'2-(p-methoxyphenyl)vinylmethylsulfone',
'sulfone, bis(2-bromoethyl)',
'sulfone, 2-butynyl phenyl',
'amical 48',
'4-tert-butylbenzenesulfonyl chloride',
'benzenesulfonyl hydrazide',
'p-tolyl allyl sulfone',
'3-chloro-4-fluorobenzenesulfonyl chloride',
'2-(p-methylphenyl)vinylmethylsulfone',
'ethyl isobutyl sulfone',
'3-chlorobenzenesulfonyl chloride',
'2,2-dichlorocyclopropyl phenyl sulfone',
'2,3-dichlorothiophene-5-sulfonyl chloride',
'4-hydroxy-3-nitrobenzenesulfonyl chloride',
'dansyl chloride',
'p-cyanophenyl sulfone',
'2-(methylsulfonyl)ethanol',
'dimethylsulfamoyl chloride',
'2-nitro-4-(ethylsulfonyl)aniline',
'2,5-dimethoxybenzenesulfonyl chloride',
'fluoresone',
'4-bromophenyl sulfone',
'diiodomethyl m-tolyl sulfone',
'3-nitrobenzenesulfonyl fluoride',
'diiodomethyl o-tolyl sulfone',
'pentafluorobenzenesulfonyl chloride',
'phenylmethanesulfonyl chloride',
'2-chlorobenzothiophene sulfone',
'diiodomethyl benzyl sulfone',
'ethyl isopropyl sulfone',
'bis(phenylsulfonyl)methane',
'phenyl propargyl sulfone',
'amsacrine hydrochloride',
'2-mesitylenesulfonyl chloride',
'2-fluorobenzenesulfonyl chloride',
'sulfone, butyl methyl',
'ethyl vinyl sulfone',
'2-(methylsulfonyl)benzenesulfonyl chloride',
'thioxane sulfone',
"4,4'-biphenyldisulfonyl chloride",
'3-bromobenzenesulfonyl chloride',
'isopropyl methyl sulfone',
'dibenzyl sulfone',
'bis(2-chloroethyl) sulfone',
'2-chloroethyl phenyl sulfone',
'benzene, dimethyl((methylphenyl)sulfonyl)-',
"3,3'-sulfonyldianiline",
'4-chlorophenyl phenyl sulfone',
'fenthione sulfone',
'2,2,2-trifluoroethanesulfonyl chloride',
'ethanesulfonyl chloride',
'sulfacetamide',
'2,3,5,6-tetrachloro-4-(methylsulfonyl)pyridine',
'chlorosulfona',
'benzyl 2-chloroethyl sulfone',
'2,4,6-trichlorobenzenesulfonyl chloride',
'bis(4-chlorophenyl) sulfone',
'4-(bromomethyl)benzenesulfonyl chloride',
'propyl sulfone',
"4,4'-sulfonyldiphenol",
"2,2'-sulfonyldiphenol",
'1-octanesulfonyl chloride',
'4726-22-1',
'sulfuryl chloride fluoride',
"2,2'-sulphonylbisethyl diacetate",
'2-(benzenesulfonyl)acetamide',
'sulfonethylmethane',
'3,4-epoxysulfolane',
'2,4-dinitrobenzenesulfonyl chloride',
'2-methoxy-5-methylbenzenesulfonyl chloride',
'thiazosulfone',
'promin',
'demeton-sulfone',
'3-amino-4-[(4-methylphenyl)sulfonyl]benzenesulfonic acid',
'diphenyl sulfone',
'cheirolin',
'1-dodecanesulfonyl chloride',
'benzenesulphonylacetone',
'bis[4-chlorobenzyl]sulfone',
'2-chlorobenzenesulfonyl chloride',
'chloromethanesulfonyl chloride',
'diisopropyl sulfone',
'p-sulfanilylphenol',
'dipyrone',
'diformyldapsone',
'propane, 2-[(2-chloroethyl)sulfonyl]-2-methyl-',
'aldoxycarb',
'3,5-dichlorobenzenesulfonyl chloride',
'4-bromobenzenesulfonohydrazide',
'2,4-dichlorobenzenesulfonyl chloride',
'2,5-dimethylbenzenesulfonyl chloride',
'3-iodosulfolane',
'2,3,5,6-tetramethylbenzenesulfonyl chloride',
'phenyl vinyl sulfone',
'5-chlorothiophene-2-sulfonyl chloride',
'4-fluorophenyl sulfone',
'p-tosylethylene',
'4-(n-butoxy)benzenesulfonyl chloride',
'3-methyl-1-benzothiophene 1,1-dioxide',
'dibenzothiophene sulfone',
'4-fluorophenyl phenyl sulfone',
'2,6-dichlorobenzenesulfonyl chloride']
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_sulfone():
    not_is_sulfone = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene',
    '1-Decanethiol', '3-Pentanethiol']+ sulfide_chemicals + disulfide_chemicals + mercaptan_chemicals + sulfoxide_chemicals
    for c in not_is_sulfone:
        assert not is_sulfone(mol_from_name(c))
    chemicals = sulfone_chemicals + ['Chlormezanone', 'Davicil', 'Methylsulfonylmethane', 'Nifurtimox', 'Oxycarboxin', 'Sulfolane', 'Sulfolene', 'Sulfonmethane', 'Tinidazole', 'Trional', 'Vinyl sulfone']

    for c in chemicals:
        assert is_sulfone(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_siloxane():
    not_siloxanes = ['CO2', 'water', 'toluene', 'methane','butane', 'cyclopentane', 'benzene']
    for c in not_siloxanes:
        assert not is_siloxane(mol_from_name(c))
    
    is_siloxanes = ['dodecasiloxane, hexacosamethyl-',
                    'tetradecamethylhexasiloxane',
                    'decamethylcyclopentasiloxane',
                    'hexamethylcyclotrisiloxane',
                    'hexamethyldisiloxane',
                    'decamethyltetrasiloxane',
                    'dodecamethylpentasiloxane',
                    'octamethylcyclotetrasiloxane',
                    'cyclooctasiloxane, hexadecamethyl-',
                    'octasiloxane, octadecamethyl-',
                    'octamethyltrisiloxane',
                    'icosamethylnonasiloxane',
                    'dodecamethylcyclohexasiloxane',
                    'heptasiloxane, hexadecamethyl-']
    
    for c in is_siloxanes:
        assert is_siloxane(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_alkane():
    for i in range(2, 50):
        mol = mol_from_name('C%d' %(i))
        assert is_alkane(mol)
    
    not_alkanes = ['CO2', 'water', 'toluene']
    for c in not_alkanes + mercaptan_chemicals:
        assert not is_alkane(mol_from_name(c))
    is_alkanes = ['cyclopentane', 'cyclopropane', 'cyclobutane', 'neopentane']
    for c in is_alkanes:
        assert is_alkane(mol_from_name(c))


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_cycloalkane():
    non_cycloalkanes =  ['CO2', 'water', 'toluene'] + ['C%d' %(i) for i in range(2, 20)]
    for c in non_cycloalkanes:
        assert not is_cycloalkane(mol_from_name(c))
    
    is_cycloalkanes = ['cyclopentane', 'cyclopropane', 'cyclobutane', 'Cyclopropane', 'Cyclobutane',
                       'Cyclopentane', 'Cyclohexane', 'Cycloheptane', 'Cyclooctane', 'Cyclononane',
                       'Cyclodecane']
    for c in is_cycloalkanes:
        assert is_cycloalkane(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_alkene():
    not_alkenes = ['CO2', 'water', 'toluene', 'methane','butane', 'cyclopentane', 'benzene']
    for c in not_alkenes:
        assert not is_alkene(mol_from_name(c))
        
    is_alkenes = ['ethylene', 'propylene', '1-butene', '2-butene', 'isobutylene', '1-pentene', '2-pentene', '2-methyl-1-butene', '3-methyl-1-butene', '2-methyl-2-butene', '1-hexene', '2-hexene', '3-hexene', 
                 'cyclopentadiene']
    for c in is_alkenes:
        assert is_alkene(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_alkyne():
    not_alkynes = ['CO2', 'water', 'toluene', 'methane','butane', 'cyclopentane', 'benzene']
    for c in not_alkynes:
        assert not is_alkyne(mol_from_name(c))
    
    is_alkynes = ['Ethyne', 'Propyne', '1-Butyne', '2-Butyne', '1-Pentyne', '2-Pentyne',
                 '1-hexyne', '2-hexyne', '3-hexyne', 'heptyne', '2-octyne', '4-octyne',
                  'nonyne', '1-decyne', '5-decyne']
    
    for c in is_alkynes:
        assert is_alkyne(mol_from_name(c))


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_aromatic():
    not_aromatic = ['CO2', 'water', 'methane','butane', 'cyclopentane']
    for c in not_aromatic:
        assert not is_aromatic(mol_from_name(c))
    
    is_aromatics = ['benzene', 'toluene']
    
    for c in is_aromatics:
        assert is_aromatic(mol_from_name(c))


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_alcohol():
    not_alcohol = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_alcohol:
        assert not is_alcohol(mol_from_name(c))
    
    is_alcohols = ['ethanol', 'methanol', 'cyclopentanol', '1-nonanol', 'triphenylmethanol',
                  ' 1-decanol', 'glycerol',
                  '1-propanol', '2-propanol', '1-butanol', '2-butanol', '2-methyl-1-propanol', '2-methyl-2-propanol', '1-pentanol', '3-methyl-1-butanol', '2,2-dimethyl-1-propanol', 'cyclopentanol', '1-hexanol', 'cyclohexanol', '1-heptanol', '1-octanol', '1-nonanol', '1-decanol', '2-propen-1-ol', 'phenylmethanol', 'diphenylmethanol', 'triphenylmethanol', 'methanol', 'ethanol', '1-propanol', '2-propanol', '1-butanol', '2-butanol', '2-methyl-1-propanol', '2-methyl-2-propanol', '1-pentanol', '3-methyl-1-butanol', '2,2-dimethyl-1-propanol', 'cyclopentanol', '1-hexanol', 'cyclohexanol', '1-heptanol', '1-octanol', '1-nonanol', '1-decanol', '2-propen-1-ol', 'phenylmethanol', 'diphenylmethanol', 'triphenylmethanol']
    
    for c in is_alcohols:
        assert is_alcohol(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_polyol():
    not_polyol = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene',
                  'ethanol', 'methanol', 'cyclopentanol']
    for c in not_polyol:
        assert not is_polyol(mol_from_name(c))
    
    # missing 'Erythritol', HSHs, Isomalt 'Threitol', Fucitol, Volemitol, Maltotriitol, Maltotetraitol Polyglycitol
    is_polyols = ['sorbitol', 'ethylene glycol', 'glycerol', 'trimethylolpropane', 'pentaerythritol',
                 'PEG', 'Arabitol',  'Glycerol', 'Lactitol', 'Maltitol', 'Mannitol', 'Sorbitol', 'Xylitol', 'Ethylene glycol', 'Glycerol', 'Arabitol', 'Xylitol', 'Ribitol', 'Mannitol', 'Sorbitol', 'Galactitol', 'Iditol', 'Inositol', 
                  'Maltitol', 'Lactitol']
    for c in is_polyols:
        assert is_polyol(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_acid():
    not_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_acid:
        assert not is_acid(mol_from_name(c))
    
    is_acids = [#organics
        'formic acid', 'acetic acid', 'acrylic acid', 'propionic acid', 'n-butyric acid', 'adipic acid', 'Oxalic acid',
                # inorganics
               'nitric acid', 'hydrogen chloride', 'hydrogen fluoride', 'hydrogen iodide', 'sulfuric acid', 'phosphoric acid',
    ]
    
    for c in is_acids:
        assert is_acid(mol_from_name(c))
        
        
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_ketone():
    not_ketone = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_ketone:
        assert not is_ketone(mol_from_name(c))
    
    # missing cyclopropanetrione
    is_ketones = ['acetone', 'diethyl ketone', 'cyclohexanone', 'methyl isobutyl ketone',
                 '2,3-butanedione', '2,3-pentanedione', '2,3-hexanedione', 
                  '1,2-cyclohexanedione']
    
    for c in is_ketones:
        assert is_ketone(mol_from_name(c))


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_aldehyde():
    not_aldehyde = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_aldehyde:
        assert not is_aldehyde(mol_from_name(c))
    
    #missing: Tolualdehyde
    is_aldehydes = ['acetaldehyde', 'n-propionaldehyde', 'n-butyraldehyde', 'isobutyraldehyde',
                   'Formaldehyde',
                    'Acetaldehyde', 'Propionaldehyde', 'Butyraldehyde', 'Isovaleraldehyde', 
                    'Benzaldehyde', 'Cinnamaldehyde', 'Vanillin', 'Furfural', 'Retinaldehyde', 
                    'Glycolaldehyde', 'Glyoxal', 'Malondialdehyde', 'Succindialdehyde', 'Glutaraldehyde', 
                    'Phthalaldehyde']
    
    for c in is_aldehydes:
        assert is_aldehyde(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_anhydride():
    not_anhydride = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_anhydride:
        assert not is_anhydride(mol_from_name(c))
    
    is_anhydrides = ['acetic anhydride', 'maleic anhydride', 'phthalic anhydride']
    
    for c in is_anhydrides:
        assert is_anhydride(mol_from_name(c))
        
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_ether():
    not_ether = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_ether:
        assert not is_ether(mol_from_name(c))
    
    is_ethers = ['diethyl ether', 'methyl t-butyl ether', 'isopropyl ether',
                'Ethylene oxide ', 'Dimethyl ether', 'Diethyl ether', 
                 'Dimethoxyethane', 'Dioxane', 'Tetrahydrofuran', 'Anisole',
                 '12-Crown-4', '15-Crown-5', '18-Crown-6', 'Dibenzo-18-crown-6']
    
    for c in is_ethers:
        assert is_ether(mol_from_name(c))
        
        
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_phenol():
    not_phenols = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_phenols:
        assert not is_phenol(mol_from_name(c))
    
    # missing amoxicillin
    phenol_chemicals = ['Acetaminophen', 'phenol', 'Bisphenol A', 'butylated hydroxytoluene', 
                        '4-Nonylphenol', 'Orthophenyl phenol', 'Picric acid', 'Phenolphthalein', 
                        '2,6-Xylenol','2,5-Xylenol', '2,4-Xylenol', '2,3-Xylenol', '3,4-Xylenol', '3,5-Xylenol',
                       'tyrosine', 'propofol', 'levothyroxine', 'estradiol']
    for c in phenol_chemicals:
        assert is_phenol(mol_from_name(c))
        
        
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_nitrile():
    not_nitrile = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_nitrile:
        assert not is_nitrile(mol_from_name(c))
    
    # something weird in the smiles for 'Tosylmethyl isocyanide'
    
    nitrile_chemicals = ['butanedinitrile', '2-methoxybenzonitrile', 'ethanenitrile', 'propanenitrile',
                         'butanenitrile', 'pentanenitrile', 'hexanenitrile', 'heptanenitrile', 'octanenitrile', 'nonanenitrile',
                         'decanenitrile',
                         'Dicyandiamide', 'Acetonitrile ', 'Malononitrile', '4-Chlorobenzyl cyanide', '2-Chloro-5-nitrobenzonitrile', 
                         '3-Trifluoromethylbenzylcyanide', 'Benzeneacetonitrile', 'Adiponitrile', '1,3-Dicyanobenzene',
                         '2-Chloro-4-nitrobenzonitrile', 
                          '1,2-Phenylenediacetonitrile', 'Cyanocyclobutane', 
                         'HEXANENITRILE', 'BUTYRONITRILE', 'Dimethylaminopropionitrile', 
                         'Glycolonitrile', 'Acrylonitrile', 'ETHYL 2-CYANOACRYLATE', 'Propionitrile']
    for c in nitrile_chemicals:
        assert is_nitrile(mol_from_name(c))

is_isonitriles =  [  'isocyanoethane', '1-isocyanopropane', 'trifluoromethylisocyanide',
 'ethyl isocyanoacetate', '1-isocyanonaphthalene',
 'tosylmethyl isocyanide', 'isocyanobenzene', 'isocyanomethane',
 '1-adamantyl isocyanide',
 'sodium fulminate',
 '2-isocyanobutane',
 'n-butyl isocyanide',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_isonitrile():
    not_isonitrile = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_isonitrile:
        assert not is_isonitrile(mol_from_name(c))
    
    
    for c in is_isonitriles:
        assert is_isonitrile(mol_from_name(c))

    smiles_hits = ['[*][N+]#[C-]']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_isonitrile(mol)


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carboxylic_acid():
    not_carboxylic_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_carboxylic_acid:
        assert not is_carboxylic_acid(mol_from_name(c))
    
    # 'docosahexaenoic acid', 'eicosapentaenoic acid',  'α-Hydroxypropionic acid', 'β-Hydroxypropionic acid', 
    # 'β-Hydroxybutyric acid', 'β-Hydroxy β-methylbutyric acid', 'Enanthic acid', 'Margaric acid', 
    carboxylic_acid_chemicals= ['acrylic acid',  'Glycine', 'Alanine',
                                'Valine', 'Leucine', 'Isoleucine', 'Proline', 'Serine', 'Threonine', 'Asparagine',
                                'Glutamine', 'acetoacetic acid', 'pyruvic acid', 'benzoic acid', 'salicylic acid',
                                'adipic acid', 'citric acid', 'glyceric acid', 'glycolic acid', 'lactic acid',
                                'Propanoic acid',
                                'Formic acid', 'Acetic acid', 'Propionic acid', 'Butyric acid', 'Valeric acid', 'Caproic acid',
                                'Caprylic acid', 'Pelargonic acid', 'Capric acid', 'Undecylic acid', 'Lauric acid', 
                                'Tridecylic acid', 'Myristic acid', 'Pentadecylic acid', 'Palmitic acid', 
                                'Stearic acid', 'Nonadecylic acid', 'Arachidic acid']
    for c in carboxylic_acid_chemicals:
        assert is_carboxylic_acid(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_haloalkane():
    not_is_haloalkane = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_is_haloalkane:
        assert not is_haloalkane(mol_from_name(c))
    
    #  '(Dibromomethyl)cyclohexane',  'Equatorial (Dibromomethyl)cyclohexane',  1,6-Dichloro-2,5-dimethylhexane', '1,1-Dichloro-3-methylcyclobutane'
    haloalkane_chemicals = ['Fluoromethane', 'Chloromethane', 'Bromomethane', 'Iodomethane', 'Difluoromethane', 
                            'Dichloromethane', 'Chlorofluoromethane', 'Bromochlorofluoromethane', 'Trichloromethane',
                            'Tetrachloromethane', '1,1-Dichloroethane',
                            ]
    for c in haloalkane_chemicals:
        assert is_haloalkane(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_nitro():
    not_is_nitro = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_is_nitro:
        assert not is_nitro(mol_from_name(c))
    
    nitro_chemicals = ['Nitromethane',
                       '1-Nitropyrene', '2,4-Dinitroaniline', '2-Nitrofluorene', '3-Nitrobenzanthrone', 
                       '4-Nitropyridine-N-oxide', '4-Nitroquinoline 1-oxide', '5-Nitro-2-propoxyaniline',
                       '7-Nitroindazole', 'Acifluorfen', 'Aclonifen', 'Aristolochic acid', 'Benfluralin',
                       'Beta-Nitropropionic acid', 'Beta-Nitrostyrene', 'Bifenox', 'Bronidox', 'Bronopol',
                       'Chloropicrin', 'CNQX', 'DMDNB', 'DNQX', 'Fluazinam', 'NBQX', 'Nitrocyclohexane', 
                       'Nitroethylene', 'Nitrofen', 'Nitrotyrosine', 'Nitroxinil', 'Nitroxoline', 
                       'Oxamniquine', 'Sivifene', 'Trinitroethylorthocarbonate']
    for c in nitro_chemicals:
        assert is_nitro(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_amine():
    not_is_amine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_is_amine:
        assert not is_amine(mol_from_name(c))
    
    chemicals = ['tetramethylthiuram disulfide'] + amine_chemicals
    # chemicals = amine_chemicals
    for c in chemicals:
        assert is_amine(mol_from_name(c))

primary_amine_chemicals = ['methylamine', 'ethylamine', 'propylamine', 'butylamine', 'pentylamine', 
                   'hexylamine', 'heptylamine', 'octylamine', 'nonylamine', 'decylamine', 
                   'Ethanolamine', 'Aniline', 'o-Phenylenediamine', 'm-phenylenediamine',
                   'p-phenylenediamine', 'o-toluidine ', 'm-toluidine ', 'p-toluidine ',
                   '2,4-Diaminotoluene', '2,6-Diaminotoluene', '2,5-Diaminotoluene',
                   '1-Naphthylamine', '2-Naphthylamine',
                   '2-Aminopyridine', '3-Aminopyridine', '4-Aminopyridine','Cytosine',
                   '4-Aminoquinoline', '8-Aminoquinoline', 'Primaquine',
                   '2-Aminopurine', 'Guanine',
                   '2-Aminoacridine', '3-Aminoacridine', '4-Aminoacridine', '9-Aminoacridine',
                   ]
secondary_amine_chemicals = ['dimethylamine', 'diethylamine', 'Diethanolamine',]
tertiary_amine_chemicals = ['trimethylamine', 'triethylamine', 'Methyl diethanolamine', "Wurster's blue",
                            #"Prodan" not in database
                            ]
amine_chemicals = ['methylamine', 'ethylamine', 'propylamine', 'butylamine', 'pentylamine', 
                   'hexylamine', 'heptylamine', 'octylamine', 'nonylamine', 'decylamine', 
                   'Ethanolamine',
                   
                   'dimethylamine', 'diethylamine',    'Diethanolamine','Aniline',
                   
                   'trimethylamine', 'triethylamine', 'Methyl diethanolamine']
amine_chemicals = amine_chemicals + primary_amine_chemicals + secondary_amine_chemicals + tertiary_amine_chemicals
# test_is_amine()

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_primary_amine():
    not_is_primary_amine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] + secondary_amine_chemicals + tertiary_amine_chemicals
    for c in not_is_primary_amine:
        assert not is_primary_amine(mol_from_name(c))
    chemicals = primary_amine_chemicals + ['Dimethyl-4-phenylenediamine', 'Congo red']
    for c in chemicals:
        assert is_primary_amine(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_secondary_amine():
    not_is_secondary_amine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] + tertiary_amine_chemicals + primary_amine_chemicals
    for c in not_is_secondary_amine:
        assert not is_secondary_amine(mol_from_name(c))
    
    for c in secondary_amine_chemicals:
        assert is_secondary_amine(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_tertiary_amine():
    not_is_tertiary_amine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] + primary_amine_chemicals + secondary_amine_chemicals

    for c in not_is_tertiary_amine:
        assert not is_tertiary_amine(mol_from_name(c))
    
    chemicals = tertiary_amine_chemicals + ['tetramethylthiuram disulfide']
    for c in chemicals:
        assert is_tertiary_amine(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_ester():
    not_ester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_ester:
        assert not is_ester(mol_from_name(c))
    
    is_esters_inorganic = ['triphenylphosphate', 'dimethylsulfate', 'methyl nitrate', 'trimethylborate', 'ethylene carbonate']
    
    # missing: 'Ethyl cinnamate','Geranyl butyrate', 'Geranyl pentanoate','Nonyl caprylate', 'Terpenyl butyrate'
    is_esters = ['Allyl hexanoate', 'Benzyl acetate', 'Bornyl acetate', 'Butyl acetate', 'Butyl butyrate', 'Butyl propanoate', 'Ethyl acetate', 'Ethyl benzoate', 'Ethyl butyrate', 'Ethyl hexanoate',  'Ethyl formate', 'Ethyl heptanoate', 'Ethyl isovalerate', 'Ethyl lactate', 'Ethyl nonanoate', 'Ethyl pentanoate', 'Geranyl acetate',  'Isobutyl acetate', 'Isobutyl formate', 'Isoamyl acetate', 'Isopropyl acetate', 'Linalyl acetate', 'Linalyl butyrate', 'Linalyl formate', 'Methyl acetate', 'Methyl anthranilate', 'Methyl benzoate', 'Methyl butyrate', 'Methyl cinnamate', 'Methyl pentanoate', 'Methyl phenylacetate', 'Methyl salicylate', 'Octyl acetate', 'Octyl butyrate', 'Amyl acetate', 'Pentyl butyrate', 'Pentyl hexanoate', 'Pentyl pentanoate', 'Propyl acetate', 'Propyl hexanoate', 'Propyl isobutyrate']
    for c in is_esters:
        assert is_ester(mol_from_name(c))

branched_alkanes = ["2-Methylpentane", "3-Methylpentane", "2,2-Dimethylbutane", "2,3-Dimethylbutane", "2-Methylhexane", "3-Methylhexane", "2,2-Dimethylpentane",
    "2,3-Dimethylpentane", "2,4-Dimethylpentane", "3,3-Dimethylpentane", "3-Ethylpentane", "2,2,3-Trimethylbutane", "2-Methylheptane", "3-Methylheptane",
    "4-Methylheptane", "2,2-Dimethylhexane", "2,3-Dimethylhexane", "2,4-Dimethylhexane", "2,5-Dimethylhexane", "3,3-Dimethylhexane", "3,4-Dimethylhexane",
    "3-Ethylhexane", "2,2,3-Trimethylpentane", "2,2,4-Trimethylpentane", "2,3,3-Trimethylpentane", "2,3,4-Trimethylpentane", "3-Ethyl-2-methylpentane",
    "3-Ethyl-3-methylpentane", "2,2,3,3-Tetramethylbutane", "2-Methyloctane", "3-Methyloctane", "4-Methyloctane", "2,2-Dimethylheptane",
    "2,3-Dimethylheptane", "2,4-Dimethylheptane", "2,5-Dimethylheptane", "2,6-Dimethylheptane", "3,3-Dimethylheptane", "3,4-Dimethylheptane",
    "3,5-Dimethylheptane", "4,4-Dimethylheptane", "3-Ethylheptane", "4-Ethylheptane", "2,2,3-Trimethylhexane", "2,2,4-Trimethylhexane",
    "2,2,5-Trimethylhexane", "2,3,3-Trimethylhexane", "2-Methyldodecane", "3-Methyldodecane", "4-Methyldodecane", "5-Methyldodecane",
    "2,2-Dimethylundecane", "2,3-Dimethylundecane", "2,4-Dimethylundecane", "2,5-Dimethylundecane", "2,6-Dimethylundecane", "2,7-Dimethylundecane",
    "2,8-Dimethylundecane", "2,9-Dimethylundecane", "3,3-Dimethylundecane", "3,4-Dimethylundecane", "3,5-Dimethylundecane", "3,6-Dimethylundecane",
    "3,7-Dimethylundecane", "3,8-Dimethylundecane", "3,9-Dimethylundecane", "4,4-Dimethylundecane", "4,5-Dimethylundecane", "4,6-Dimethylundecane",
    "4,7-Dimethylundecane", "4,8-Dimethylundecane", "5,5-Dimethylundecane", "5,6-Dimethylundecane", "5,7-Dimethylundecane", "6,6-Dimethylundecane",
    "3-Ethylundecane", "2,2,3-Trimethyldecane", "2,2,8-Trimethyldecane", "2,5,9-Trimethyldecane", "4-Propyldecane", "5-Propyldecane",
    "4,4,6,6-Tetramethylnonane", "3-Methyl-5-propylnonane", "5-Butylnonane", "3,5-Diethyl-3,5-dimethylheptane", "4,4-Dipropylheptane", "2-Methyldodecane",
    "3-Methyldodecane", "4-Methyldodecane", "5-Methyldodecane", "2,2-Dimethylundecane", "2,3-Dimethylundecane", "2,4-Dimethylundecane",
    "2,5-Dimethylundecane", "2,6-Dimethylundecane", "2,7-Dimethylundecane", "2,8-Dimethylundecane", "2,9-Dimethylundecane", "3,3-Dimethylundecane",
    "3,4-Dimethylundecane", "3,5-Dimethylundecane", "3,6-Dimethylundecane", "3,7-Dimethylundecane", "3,8-Dimethylundecane", "3,9-Dimethylundecane",
    "4,4-Dimethylundecane", "4,5-Dimethylundecane", "4,6-Dimethylundecane", "4,7-Dimethylundecane", "4,8-Dimethylundecane", "5,5-Dimethylundecane",
    "5,6-Dimethylundecane", "5,7-Dimethylundecane", "6,6-Dimethylundecane", "3-Ethylundecane", "2,2,3-Trimethyldecane", "2,2,8-Trimethyldecane",
    "2,5,9-Trimethyldecane", "4-Propyldecane", "5-Propyldecane", "4,4,6,6-Tetramethylnonane", "3-Methyl-5-propylnonane", "5-Butylnonane",
    "3,5-Diethyl-3,5-dimethylheptane", "4,4-Dipropylheptane", "2,3,4-Trimethylhexane", "2,3,5-Trimethylhexane", "2,4,4-Trimethylhexane",
    "3,3,4-Trimethylhexane", "3-Ethyl-2-methylhexane", "3-Ethyl-3-methylhexane", "3-Ethyl-4-methylhexane", "4-Ethyl-2-methylhexane",
    "2,2,3,3-Tetramethylpentane", "2,2,3,4-Tetramethylpentane", "2,2,4,4-Tetramethylpentane", "2,3,3,4-Tetramethylpentane", "3-Ethyl-2,2-dimethylpentane",
    "3-Ethyl-2,3-dimethylpentane", "3-Ethyl-2,4-dimethylpentane", "3,3-Diethylpentane", "2-Methylnonane", "3-Methylnonane", "4-Methylnonane",
    "5-Methylnonane", "2,2-Dimethyloctane", "2,3-Dimethyloctane", "2,4-Dimethyloctane", "2,5-Dimethyloctane", "2,6-Dimethyloctane", "2,7-Dimethyloctane",
    "3,3-Dimethyloctane", "3,4-Dimethyloctane", "3,5-Dimethyloctane", "3,6-Dimethyloctane", "4,4-Dimethyloctane", "4,5-Dimethyloctane", "3-Ethyloctane",
    "4-Ethyloctane", "2,2,3-Trimethylheptane", "2,2,4-Trimethylheptane", "2,2,5-Trimethylheptane", "2,2,6-Trimethylheptane", "2,3,3-Trimethylheptane",
    "2,3,4-Trimethylheptane", "2,3,5-Trimethylheptane", "2,3,6-Trimethylheptane", "2,4,4-Trimethylheptane", "2,4,5-Trimethylheptane",
    "2,4,6-Trimethylheptane", "2,5,5-Trimethylheptane", "3,3,4-Trimethylheptane", "3,3,5-Trimethylheptane", "3,4,4-Trimethylheptane",
    "3,4,5-Trimethylheptane", "3-Ethyl-2-methylheptane", "3-Ethyl-3-methylheptane", "3-Ethyl-4-methylheptane", "4-Ethyl-2-methylheptane",
    "4-Ethyl-3-methylheptane", "4-Ethyl-4-methylheptane", "5-Ethyl-2-methylheptane", "4-Propylheptane", "2,2,3,3-Tetramethylhexane",
    "2,2,3,4-Tetramethylhexane", "2,2,3,5-Tetramethylhexane", "2,2,4,4-Tetramethylhexane", "2,2,4,5-Tetramethylhexane", "2,2,5,5-Tetramethylhexane",
    "2,3,3,4-Tetramethylhexane", "2,3,3,5-Tetramethylhexane", "2,3,4,4-Tetramethylhexane", "2,3,4,5-Tetramethylhexane", "3,3,4,4-Tetramethylhexane",
    "3-Ethyl-2,2-dimethylhexane", "3-Ethyl-2,3-dimethylhexane", "3-Ethyl-2,4-dimethylhexane", "3-Ethyl-2,5-dimethylhexane", "3-Ethyl-3,4-dimethylhexane",
    "4-Ethyl-2,2-dimethylhexane", "4-Ethyl-2,3-dimethylhexane", "4-Ethyl-2,4-dimethylhexane", "4-Ethyl-3,3-dimethylhexane", "3,3-Diethylhexane",
    "3,4-Diethylhexane", "2,2,3,3,4-Pentamethylpentane", "2,2,3,4,4-Pentamethylpentane", "3-Ethyl-2,2,3-trimethylpentane", "3-Ethyl-2,2,4-trimethylpentane",
    "3-Ethyl-2,3,4-trimethylpentane", "3,3-Diethyl-2-methylpentane", "2-Methyldecane", "3-Methyldecane", "4-Methyldecane", "5-Methyldecane",
    "2,2-Dimethylnonane", "2,3-Dimethylnonane", "2,4-Dimethylnonane", "2,5-Dimethylnonane", "2,6-Dimethylnonane", "2,7-Dimethylnonane",
    "2,8-Dimethylnonane", "3,3-Dimethylnonane", "3,4-Dimethylnonane", "3,5-Dimethylnonane", "3,6-Dimethylnonane", "3,7-Dimethylnonane",
    "4,4-Dimethylnonane", "4,5-Dimethylnonane", "4,6-Dimethylnonane", "5,5-Dimethylnonane", "3-Ethylnonane", "4-Ethylnonane", "5-Ethylnonane",
    "2,2,3-Trimethyloctane", "2,2,4-Trimethyloctane", "2,2,5-Trimethyloctane", "2,2,6-Trimethyloctane", "2,2,7-Trimethyloctane", "2,3,3-Trimethyloctane",
    "2,3,4-Trimethyloctane", "2,3,5-Trimethyloctane", "2,3,6-Trimethyloctane", "2,3,7-Trimethyloctane", "2,4,4-Trimethyloctane", "2,4,5-Trimethyloctane",
    "2,4,6-Trimethyloctane", "2,4,7-Trimethyloctane", "2,5,5-Trimethyloctane", "2,5,6-Trimethyloctane", "3,3,4-Trimethyloctane", "3,3,5-Trimethyloctane",
    "3,3,6-Trimethyloctane", "3,4,4-Trimethyloctane", "3,4,5-Trimethyloctane", "3,4,6-Trimethyloctane", "3,5,5-Trimethyloctane", "4,4,5-Trimethyloctane",
    "3-Ethyl-4-methyloctane", "3-Ethyl-5-methyloctane", "3-Ethyl-6-methyloctane", "4-Ethyl-3-methyloctane", "4-Ethyl-4-methyloctane",
    "4-Ethyl-5-methyloctane", "4-Propyloctane", "2,2,3,3-Tetramethylheptane", "2,2,3,4-Tetramethylheptane", "2,2,3,5-Tetramethylheptane",
    "2,2,3,6-Tetramethylheptane", "2,2,4,4-Tetramethylheptane", "2,2,4,5-Tetramethylheptane", "2,2,4,6-Tetramethylheptane", "2,2,5,5-Tetramethylheptane",
    "2,2,5,6-Tetramethylheptane", "2,2,6,6-Tetramethylheptane", "2,3,3,4-Tetramethylheptane", "2,3,3,5-Tetramethylheptane", "2,3,3,6-Tetramethylheptane",
    "2,3,4,4-Tetramethylheptane", "2,3,4,5-Tetramethylheptane", "2,3,4,6-Tetramethylheptane", "2,3,5,5-Tetramethylheptane", "2,3,5,6-Tetramethylheptane",
    "2,4,4,5-Tetramethylheptane", "2,4,4,6-Tetramethylheptane", "2,4,5,5-Tetramethylheptane", "3,3,4,4-Tetramethylheptane", "3,3,4,5-Tetramethylheptane",
    "3,3,5,5-Tetramethylheptane", "3,4,4,5-Tetramethylheptane", "3-Ethyl-2,2-dimethylheptane", "3-Ethyl-2,5-dimethylheptane", "3-Ethyl-3,4-dimethylheptane",
    "3-Ethyl-3,5-dimethylheptane", "4-Ethyl-2,2-dimethylheptane", "4-Ethyl-2,5-dimethylheptane", "4-Ethyl-3,5-dimethylheptane", "3,3-Diethylheptane",
    "3,4-Diethylheptane", "3,5-Diethylheptane", "4,4-Diethylheptane", "2-Methyl-4-propylheptane", "3-Methyl-4-propylheptane", "4-Methyl-4-propylheptane",
    "2,2,3,3,4-Pentamethylhexane", "2,2,3,3,5-Pentamethylhexane", "2,2,3,4,4-Pentamethylhexane", "2,2,3,4,5-Pentamethylhexane",
    "2,2,3,5,5-Pentamethylhexane", "2,2,4,4,5-Pentamethylhexane", "2,3,3,4,4-Pentamethylhexane", "2,3,3,4,5-Pentamethylhexane",
    "3-Ethyl-2,2,5-trimethylhexane", "3-Ethyl-2,4,4-trimethylhexane", "3-Ethyl-2,4,5-trimethylhexane", "4-Ethyl-2,2,4-trimethylhexane",
    "3,3-Diethyl-2-methylhexane", "3,3-Diethyl-4-methylhexane", "3,4-Diethyl-3-methylhexane", "2,2,3,3,4,4-Hexamethylpentane",
    "3-Ethyl-2,2,3,4-tetramethylpentane", "3,3-Diethyl-2,2-dimethylpentane", "3,3-Diethyl-2,4-dimethylpentane", "2-Methylundecane", "3-Methylundecane",
    "4-Methylundecane", "5-Methylundecane", "6-Methylundecane", "2,2-Dimethyldecane", "2,3-Dimethyldecane", "2,4-Dimethyldecane", "2,5-Dimethyldecane",
    "2,6-Dimethyldecane", "2,7-Dimethyldecane", "2,8-Dimethyldecane", "2,9-Dimethyldecane", "3,3-Dimethyldecane", "3,4-Dimethyldecane",
    "3,5-Dimethyldecane", "3,6-Dimethyldecane", "3,7-Dimethyldecane", "3,8-Dimethyldecane", "4,4-Dimethyldecane", "4,5-Dimethyldecane",
    "4,6-Dimethyldecane", "4,7-Dimethyldecane", "5,5-Dimethyldecane", "5,6-Dimethyldecane", "3-Ethyldecane", "4-Ethyldecane", "2,2,3-Trimethylnonane",
    "2,2,4-Trimethylnonane", "2,2,5-Trimethylnonane", "2,2,6-Trimethylnonane", "2,2,7-Trimethylnonane", "2,2,8-Trimethylnonane", "2,3,3-Trimethylnonane",
    "2,3,4-Trimethylnonane", "2,3,5-Trimethylnonane", "2,3,6-Trimethylnonane", "2,3,7-Trimethylnonane", "2,3,8-Trimethylnonane", "2,4,4-Trimethylnonane",
    "2,4,5-Trimethylnonane", "2,4,6-Trimethylnonane", "2,4,7-Trimethylnonane", "2,4,8-Trimethylnonane", "2,5,5-Trimethylnonane", "2,5,6-Trimethylnonane",
    "2,5,7-Trimethylnonane", "2,5,8-Trimethylnonane", "2,6,6-Trimethylnonane", "2,6,7-Trimethylnonane", "2,7,7-Trimethylnonane", "3,3,4-Trimethylnonane",
    "3,3,5-Trimethylnonane", "3,3,6-Trimethylnonane", "3,3,7-Trimethylnonane", "3,4,4-Trimethylnonane", "3,4,5-Trimethylnonane", "3,4,6-Trimethylnonane",
    "3,4,7-Trimethylnonane", "3,5,5-Trimethylnonane", "3,5,6-Trimethylnonane", "3,5,7-Trimethylnonane", "3,6,6-Trimethylnonane", "4,4,5-Trimethylnonane",
    "4,4,6-Trimethylnonane", "4,5,5-Trimethylnonane", "4,5,6-Trimethylnonane", "3-Ethyl-3-methylnonane", "3-Ethyl-6-methylnonane", "3-Ethyl-7-methylnonane",
    "4-Ethyl-3-methylnonane", "4-Ethyl-5-methylnonane", "5-Ethyl-5-methylnonane", "4-Propylnonane", "5-Propylnonane", "2,2,3,3-Tetramethyloctane",
    "2,2,3,4-Tetramethyloctane", "2,2,3,5-Tetramethyloctane", "2,2,3,6-Tetramethyloctane", "2,2,3,7-Tetramethyloctane", "2,2,4,4-Tetramethyloctane",
    "2,2,4,5-Tetramethyloctane", "2,2,4,6-Tetramethyloctane", "2,2,4,7-Tetramethyloctane", "2,2,5,5-Tetramethyloctane", "2,2,5,6-Tetramethyloctane",
    "2,2,5,7-Tetramethyloctane", "2,2,6,6-Tetramethyloctane", "2,2,6,7-Tetramethyloctane", "2,2,7,7-Tetramethyloctane", "2,3,3,4-Tetramethyloctane",
    "2,3,3,5-Tetramethyloctane", "2,3,3,6-Tetramethyloctane", "2,3,3,7-Tetramethyloctane", "2,3,4,4-Tetramethyloctane", "2,3,4,5-Tetramethyloctane",
    "2,3,4,6-Tetramethyloctane", "2,3,4,7-Tetramethyloctane", "2,3,5,5-Tetramethyloctane", "2,3,5,6-Tetramethyloctane", "2,3,5,7-Tetramethyloctane",
    "2,3,6,6-Tetramethyloctane", "2,4,4,5-Tetramethyloctane", "2,4,4,6-Tetramethyloctane", "2,4,4,7-Tetramethyloctane", "2,4,5,5-Tetramethyloctane",
    "2,4,5,6-Tetramethyloctane", "2,4,5,7-Tetramethyloctane", "2,4,6,6-Tetramethyloctane", "2,5,5,6-Tetramethyloctane", "2,5,6,6-Tetramethyloctane",
    "3,3,4,4-Tetramethyloctane", "3,3,4,5-Tetramethyloctane", "3,3,4,6-Tetramethyloctane", "3,3,5,5-Tetramethyloctane", "3,3,5,6-Tetramethyloctane",
    "3,3,6,6-Tetramethyloctane", "3,4,4,5-Tetramethyloctane", "3,4,4,6-Tetramethyloctane", "3,4,5,5-Tetramethyloctane", "3,4,5,6-Tetramethyloctane",
    "4,4,5,5-Tetramethyloctane", "3-Ethyl-2,6-dimethyloctane", "3-Ethyl-2,7-dimethyloctane", "3-Ethyl-3,4-dimethyloctane", "3-Ethyl-3,6-dimethyloctane",
    "4-Ethyl-2,2-dimethyloctane", "4-Ethyl-2,4-dimethyloctane", "4-Ethyl-2,6-dimethyloctane", "5-Ethyl-3,3-dimethyloctane", "6-Ethyl-3,4-dimethyloctane",
    "3,3-Diethyloctane", "3,4-Diethyloctane", "3,5-Diethyloctane", "3,6-Diethyloctane", "4,4-Diethyloctane", "4,5-Diethyloctane", "2-Methyl-4-propyloctane",
    "3-Methyl-4-propyloctane", "4-Methyl-4-propyloctane", "2-Methyl-5-propyloctane", "3-Methyl-5-propyloctane", "2,2,3,3,4-Pentamethylheptane",
    "2,2,3,3,5-Pentamethylheptane", "2,2,3,3,6-Pentamethylheptane", "2,2,3,4,4-Pentamethylheptane", "2,2,3,4,5-Pentamethylheptane",
    "2,2,3,4,6-Pentamethylheptane", "2,2,3,5,5-Pentamethylheptane", "2,2,3,5,6-Pentamethylheptane", "2,2,3,6,6-Pentamethylheptane",
    "2,2,4,4,5-Pentamethylheptane", "2,2,4,4,6-Pentamethylheptane", "2,2,4,5,5-Pentamethylheptane", "2,2,4,5,6-Pentamethylheptane",
    "2,2,4,6,6-Pentamethylheptane", "2,2,5,5,6-Pentamethylheptane", "2,3,3,4,4-Pentamethylheptane", "2,3,3,4,5-Pentamethylheptane",
    "2,3,3,4,6-Pentamethylheptane", "2,3,3,5,5-Pentamethylheptane", "2,3,3,5,6-Pentamethylheptane", "2,3,4,4,5-Pentamethylheptane",
    "2,3,4,4,6-Pentamethylheptane", "2,3,4,5,5-Pentamethylheptane", "2,3,4,5,6-Pentamethylheptane", "2,4,4,5,5-Pentamethylheptane",
    "3,3,4,4,5-Pentamethylheptane", "3,3,4,5,5-Pentamethylheptane", "3-Ethyl-2,2,3-trimethylheptane", "3-Ethyl-2,5,5-trimethylheptane",
    "3-Ethyl-3,4,5-trimethylheptane", "5-Ethyl-2,2,3-trimethylheptane", "5-Ethyl-2,2,4-trimethylheptane", "5-Ethyl-2,3,3-trimethylheptane",
    "3,3-Diethyl-2-methylheptane", "3,5-Diethyl-3-methylheptane", "2,3-Dimethyl-4-propylheptane", "2,4-Dimethyl-4-propylheptane",
    "2,5-Dimethyl-4-propylheptane", "2,6-Dimethyl-4-propylheptane", "3,3-Dimethyl-4-propylheptane", "3,4-Dimethyl-4-propylheptane",
    "3,5-Dimethyl-4-propylheptane", "2,2,3,3,4,4-Hexamethylhexane", "2,2,3,3,4,5-Hexamethylhexane", "2,2,3,3,5,5-Hexamethylhexane",
    "2,2,3,4,4,5-Hexamethylhexane", "2,2,3,4,5,5-Hexamethylhexane", "2,3,3,4,4,5-Hexamethylhexane", "3-Ethyl-2,2,5,5-tetramethylhexane",
    "3,3-Diethyl-2,4-dimethylhexane", "3,4-Diethyl-3,4-dimethylhexane", "3,3,4-Triethylhexane", "3-Ethyl-2,2,3,4,4-pentamethylpentane",
    "3,3-Diethyl-2,2,4-trimethylpentane", "2-Methyldodecane", "3-Methyldodecane", "4-Methyldodecane", "5-Methyldodecane", "2,2-Dimethylundecane",
    "2,3-Dimethylundecane", "2,4-Dimethylundecane", "2,5-Dimethylundecane", "2,6-Dimethylundecane", "2,7-Dimethylundecane", "2,8-Dimethylundecane",
    "2,9-Dimethylundecane", "3,3-Dimethylundecane", "3,4-Dimethylundecane", "3,5-Dimethylundecane", "3,6-Dimethylundecane", "3,7-Dimethylundecane",
    "3,8-Dimethylundecane", "3,9-Dimethylundecane", "4,4-Dimethylundecane", "4,5-Dimethylundecane", "4,6-Dimethylundecane", "4,7-Dimethylundecane",
    "4,8-Dimethylundecane", "5,5-Dimethylundecane", "5,6-Dimethylundecane", "5,7-Dimethylundecane", "6,6-Dimethylundecane", "3-Ethylundecane",
    "2,2,3-Trimethyldecane", "2,2,8-Trimethyldecane", "2,5,9-Trimethyldecane", "4-Propyldecane", "5-Propyldecane", "4,4,6,6-Tetramethylnonane",
    "3-Methyl-5-propylnonane", "5-Butylnonane", "3,5-Diethyl-3,5-dimethylheptane", "4,4-Dipropylheptane"
]
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_branched_alkane():
    not_branched_alkane = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] + ['C%d' %(i) for i in range(2, 20)]
    for c in not_branched_alkane:
        assert not is_branched_alkane(mol_from_name(c))
    
    is_branched_alkanes = ['Isobutane', '2,3,4-Trimethylpentane', '2-Methylpropane', '2-Methylbutane', '2,2-Dimethylpropane'] + branched_alkanes
    for c in is_branched_alkanes:
        mol = mol_from_name(c)
        assert is_branched_alkane(mol)
        assert is_alkane(mol)


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_amide():
    not_amides = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_amides:
        assert not is_amide(mol_from_name(c))
    
    # 'DMPU' may or may not be amide?
    amide_chemicals = ['Dimethylformamide', 'benzamide', 'acetamide',
                       'Chloracyzine', 
                       'Methanamide', 'Propanamide', 'N-methylacetamide', 'N-ethylpropionamide', 'benzamide',
                       'formamide', 'ethanamide', 'propanamide', 'butanamide', 'pentanamide', 'hexanamide', 'heptanamide', 'octanamide', 'nonanamide', 'decanamide',
                       '3-Methoxybenzamide', 'Acetamide', 'Acetaminophen', 'Acetyl sulfisoxazole', 'Aminohippuric acid', 'Ampicillin', 'Aztreonam', 'Bacampicillin', 'Benorilate', 'Benzylpenicillin', 'Bromopride', 'Bufexamac', 'Bupivacaine', 'Butanilicaine', 'Capsaicin', 'Carboxin', 'Carfecillin', 'Cefacetrile', 'Cefaloridine', 'Cefalotin', 'Cefamandole', 'Cefamandole nafate', 'Cefapirin', 'Cefatrizine', 'Cefmenoxime', 'Cefmetazole', 'Cefotaxime', 'Cefoxitin', 'Cefprozil', 'Cefradine', 'Cefsulodin', 'Ceftriaxone', 'Cefuroxime', 'Cephalexin', 'Cerulenin', 'Chlorthalidone', 'Cinchocaine', 'Cisapride', 'Cloxacillin', 'Cyclacillin', 'Cyclohexylformamide', 'Diethyltoluamide', 'Etamivan', 'Ethenzamide', 'Etidocaine', 'Flucloxacillin', 'Flutamide', 'Geldanamycin', 'Indapamide', 'Iobenzamic acid', 'Levobupivacaine', 'Metoclopramide', 'Metolazone', 'Mezlocillin', 'Moclobemide', 'Mosapride', 'N,N-dimethylformamide', 'N-Benzylformamide', 'Nafcillin', 'Niclosamide', 'Oxacillin', 'Penimepicycline', 'Phenacemide', 'Phenacetin', 'Phenoxymethylpenicillin', 'Phthalylsulfathiazole', 'Piperacillin', 'Piperine', 'Piracetam', 'Practolol', 'Prilocaine', 'Rifampicin', 'Rifamycin', 'Rifapentine', 'Salicylamide', 'Salicylamide O-acetic acid', 'Salicylhydroxamic Acid', 'Succinylsulfathiazole', 'Sulfabenzamide', 'Sulfacetamide', 'Sulfanitran', 'Sulopenem', 'Sulpiride', 'Sultopride']
    for c in amide_chemicals:
        mol = mol_from_name(c)
        assert is_amide(mol)

# list off of wikipedia
inorganic_compounds = ["Actinium(III) oxide", "Ag", "Al", "Al2O3", "Aluminium arsenide", "Aluminium boride", "Aluminium Bromide", "Aluminium bromide",
    "Aluminium chloride", "Aluminium fluoride", "Aluminium iodide", "Aluminium nitride", "Aluminium oxide", "Aluminium phosphide", "Aluminium sulfate",
    "Am", "Americium dioxide", "Ammonia", "Ammonium bicarbonate", "Ammonium bisulfate", "Ammonium bromide", "Ammonium chlorate", "Ammonium chloride",
    "Ammonium chromate", "Ammonium cyanide", "Ammonium dichromate", "Ammonium dihydrogen phosphate", "Ammonium hexachloroplatinate", "Ammonium hydroxide",
    "Ammonium nitrate", "Ammonium perchlorate", "Ammonium permanganate", "Ammonium persulfate", "Ammonium sulfamate", "Ammonium sulfate",
    "Ammonium sulfide", "Ammonium sulfite", "Ammonium thiocyanate", "Ammonium triiodide", "Antimony pentachloride", "Antimony pentafluoride",
    "Antimony sulfate", "Antimony trifluoride", "Ar", "Arsenic acid", "Arsenic pentafluoride", "Arsenic trifluoride", "Arsenic(V) oxide", "Arsenous acid",
    "Arsine", "As", "As2O3", "Au", "Au2O3", "B", "Ba", "BaO", "Barium bromide", "Barium carbonate", "Barium chlorate", "Barium chloride", "Barium chromate",
    "Barium iodide", "Barium manganate", "Barium nitrate", "Barium oxalate", "Barium oxide", "Barium permanganate", "Barium peroxide", "Barium sulfate",
    "Barium sulfide", "Be", "BeO", "Beryllium bromide", "Beryllium carbonate", "Beryllium chloride", "Beryllium nitrate", "Beryllium oxide",
    "Beryllium sulfate", "Beryllium telluride", "Bi", "Bi2O3", "Bismuth oxychloride", "Bismuth pentafluoride", "Bismuth tribromide", "Borazine",
    "Boric acid", "Boron nitride", "Boron trichloride", "Boron trifluoride", "Boroxine", "Br", "Bromic acid", "Bromine monochloride",
    "Bromine monofluoride", "C", "Ca", "Cadmium arsenide", "Cadmium chloride", "Cadmium iodide", "Cadmium nitrate", "Cadmium oxide", "Cadmium selenide",
    "Cadmium sulfate", "Cadmium sulfide", "Cadmium telluride", "Caesium carbonate", "Caesium chloride", "Caesium chromate", "Caesium fluoride",
    "Caesium hydride", "Caesium iodide", "Caesium sulfate", "Calcium carbonate (Precipitated Chalk)", "Calcium chlorate", "Calcium chloride",
    "Calcium chromate", "Calcium cyanamide", "Calcium fluoride", "Calcium hydride", "Calcium hydroxide", "Calcium oxalate", "Calcium oxychloride",
    "Calcium perchlorate", "Calcium permanganate", "Calcium sulfate (gypsum)", "Carbon dioxide", "Carbon disulfide", "Carbonic acid", "Carbon monoxide",
    "Carbon tetrabromide", "Carbon tetrachloride", "Carbon tetrafluoride", "Carbon tetraiodide", "Carbonyl chloride", "Carbonyl fluoride",
    "Carbonyl sulfide", "Cd", "Ce", "CeO2", "Cerium(III) bromide", "Cerium(III) carbonate", "Cerium(III) chloride", "Cerium(III) iodide",
    "Cerium(III) nitrate", "Cerium(III) sulfate", "Cerium(IV) oxide", "Cerium(IV) sulfate", "Cf", "Chloric acid", "Chlorine azide", "Chlorine dioxide",
    "Chlorine monofluoride", "Chlorine monoxide", "Chlorine perchlorate", "Chloroplatinic acid", "Chromic acid", "Chromium(II) chloride",
    "Chromium(III) chloride", "Chromium(III) nitrate", "Chromium(III) oxide", "Chromium(III) sulfate", "Chromium(II) sulfate", "Chromium(IV) oxide", "Cl",
    "Cl2O", "Cl2O7", "ClO2", "Cm", "Co", "CO2", "Cobalt(II) bromide", "Cobalt(II) carbonate", "Cobalt(III) fluoride", "Cobalt(II) nitrate",
    "Cobalt(II) sulfate", "CoO", "Copper(I) bromide", "Copper(I) chloride", "Copper(I) fluoride", "Copper(II) azide", "Copper(II) bromide",
    "Copper(II) carbonate", "Copper(II) chloride", "Copper(II) nitrate", "Copper(II) oxide", "Copper(II) sulfate", "Copper(II) sulfide", "Copper(I) oxide",
    "Copper(I) sulfate", "Copper(I) sulfide", "Copper oxychloride", "Cr", "Cr2O3", "CrO2", "CrO3", "Cs", "Cu", "Cu2O", "CuO", "Curium(III) oxide",
    "Cyanogen", "Cyanogen bromide", "Cyanogen chloride", "Cyanogen iodide", "Diammonium phosphate", "Diborane", "Diboron tetrafluoride",
    "Dichlorine heptoxide", "Dichlorine monoxide", "Dichlorine tetroxide (chlorine perchlorate)", "Dichlorosilane", "Dimagnesium phosphate",
    "Dinitrogen pentoxide (nitronium nitrate)", "Dinitrogen tetrafluoride", "Dinitrogen tetroxide", "Dinitrogen trioxide", "Diphosphorus tetrafluoride",
    "Diphosphorus tetraiodide", "Disilane", "Disulfur decafluoride", "Dy", "Dy2O3", "Dysprosium(III) chloride", "Er", "Er2O3", "Erbium(III) chloride", "Es",
    "Eu", "Eu2O3", "Europium(II) chloride", "Europium(III) chloride", "F", "Fe", "Fe2O3", "FeO", "Fr", "Ga", "Ga2O3", "Gadolinium(III) chloride",
    "Gadolinium(III) fluoride", "Gadolinium(III) sulfate", "Gallium antimonide", "Gallium arsenide", "Gallium nitride", "Gallium phosphide",
    "Gallium trichloride", "Gd", "Gd2O3", "Ge", "GeO2", "Germane", "Germanium dioxide", "Germanium(II) chloride", "Germanium(II) iodide",
    "Germanium(IV) bromide", "Germanium(IV) chloride", "Germanium(IV) fluoride", "Germanium(IV) iodide", "Germanium(IV) oxide", "Germanium(IV) selenide",
    "Germanium telluride", "Germanium tetrachloride", "Germanium tetrafluoride", "Gold(III) bromide", "Gold(III) chloride", "Gold(III) oxide",
    "Gold(I) iodide", "Gold(I) sulfide", "H", "Hafnium(IV) bromide", "Hafnium(IV) carbide", "Hafnium(IV) chloride", "Hafnium(IV) iodide",
    "Hafnium(IV) oxide", "He", "Hexachlorophosphazene", "Hf", "HfO2", "Hg", "Ho", "Holmium(III) chloride", "Hydrazine", "Hydrazoic acid",
    "Hydrobromic acid", "Hydrogen bromide", "Hydrogen chloride", "Hydrogen cyanide", "Hydrogen fluoride", "Hydrogen peroxide", "Hydrogen selenide",
    "Hydrogen sulfide", "Hydrogen sulfide (sulfane)", "Hydrogen telluride", "Hydroiodic acid", "Hydroxylamine", "Hypobromous acid", "Hypochlorous acid",
    "Hypophosphorous acid", "I", "I2O5", "In", "In2O3", "Indium antimonide", "Indium arsenide", "Indium(III) bromide", "Indium(III) chloride",
    "Indium(III) nitrate", "Indium(III) oxide", "Indium(III) sulfate", "Indium(I) iodide", "Indium nitride", "Indium phosphide", "Iodic acid",
    "Iodine monobromide", "Iodine monochloride", "Iodine pentafluoride", "Iodine trichloride", "Ir", "Iridium(IV) chloride", "IrO2", "Iron disulfide",
    "Iron(II) chloride", "Iron(III) chloride", "Iron(III) fluoride", "Iron(II) iodide", "Iron(III) phosphate", "Iron(III) sulfate", "Iron(II) oxalate",
    "Iron(II) oxide", "Iron(II) sulfamate", "Iron(II) sulfate", "Iron(II) sulfide", "K", "K2O", "Kr", "Krypton difluoride", "La", "Lanthanum boride",
    "Lanthanum(III) chloride", "Lanthanum(III) sulfate", "Lanthanum trifluoride", "Lead hydrogen arsenate", "Lead(II) azide", "Lead(II) bromide",
    "Lead(II) carbonate", "Lead(II) chloride", "Lead(II) fluoride", "Lead(II) iodide", "Lead(II) nitrate", "Lead(II) oxide", "Lead(II) selenide",
    "Lead(II) sulfate", "Lead(II) sulfide", "Lead(II) telluride", "Lead(II) thiocyanate", "Lead(IV) oxide", "Lead telluride", "Lead tetrachloride",
    "Lead titanate", "Lead zirconate titanate", "Li", "Li2O", "Lithium aluminium hydride", "Lithium borohydride", "Lithium bromide", "Lithium chlorate",
    "Lithium chloride", "Lithium hexafluorophosphate", "Lithium hydroxide", "Lithium hypochlorite", "Lithium iodide", "Lithium nitrate",
    "Lithium perchlorate", "Lithium sulfate", "Lithium sulfide", "Lithium tetrachloroaluminate", "Magnesium boride", "Magnesium carbonate",
    "Magnesium hydroxide", "Magnesium iodide", "Magnesium nitrate", "Magnesium oxide", "Magnesium perchlorate", "Magnesium peroxide", "Magnesium sulfate",
    "Magnesium sulfide", "Magnesium titanate", "Magnesium tungstate", "Manganese dioxide", "Manganese(II) bromide", "Manganese(III) oxide",
    "Manganese(II) oxide", "Manganese(II) sulfate", "Manganese(II) sulfate monohydrate", "Mercury(I) chloride", "Mercury(II) bromide",
    "Mercury(II) chloride", "Mercury(II) sulfate", "Mercury(II) sulfide", "Mercury(II) telluride", "Mercury(I) sulfate", "Mercury telluride",
    "Metaphosphoric acid", "Mg", "MgO", "Mn", "Mo", "Molybdenum disulfide", "Molybdenum hexacarbonyl", "Molybdenum hexafluoride", "Molybdenum(III) bromide",
    "Molybdenum(III) chloride", "Molybdenum(IV) chloride", "Molybdenum(IV) fluoride", "Molybdenum tetrachloride", "Molybdenum trioxide",
    "Molybdenum(V) chloride", "Molybdenum(V) fluoride", "Molybdic acid", "N", "Na", "Na2O", "Nb", "Nd", "Neodymium(III) chloride", "Ni",
    "Nickel(II) carbonate", "Nickel(II) chloride", "Nickel(II) nitrate", "Nickel(II) oxide", "Nickel(II) sulfamate", "Nickel(II) sulfide",
    "Niobium pentachloride", "Niobium(V) fluoride", "Nitric acid", "Nitrogen dioxide", "Nitrogen triiodide", "Nitrosonium tetrafluoroborate",
    "Nitrosyl bromide", "Nitrosylsulfuric acid", "Nitrous acid", "Nitrous oxide", "NO", "Np", "O", "O2F2", "OF2", "Os", "Osmium hexafluoride",
    "Osmium tetroxide", "Oxygen difluoride", "Ozone", "P", "Palladium(II) chloride", "Palladium(II) nitrate", "Palladium sulfate", "Pb", "PbO", "PbO2",
    "Pd", "Pentaborane", "Perbromic acid", "Perchloric acid", "Periodic acid", "Phosphine", "Phosphoric acid", "Phosphorous acid",
    "Phosphorus pentabromide", "Phosphorus pentafluoride", "Phosphorus pentasulfide", "Phosphorus pentoxide", "Phosphorus sesquisulfide",
    "Phosphorus tribromide", "Phosphorus trichloride", "Phosphorus trifluoride", "Phosphorus triiodide", "Platinum(II) chloride", "Platinum(IV) chloride",
    "Platinum tetrafluoride", "Plutonium dioxide", "Plutonium hexafluoride", "Plutonium hydride", "Plutonium(III) chloride", "Plutonium(III) fluoride",
    "Plutonium(IV) oxide", "Pm", "Po", "Potash Alum", "Potassium amide", "Potassium azide", "Potassium bicarbonate", "Potassium bisulfite",
    "Potassium borate", "Potassium bromate", "Potassium bromide", "Potassium carbonate", "Potassium chlorate", "Potassium chloride", "Potassium chromate",
    "Potassium cyanide", "Potassium dichromate", "Potassium dithionite", "Potassium ferricyanide", "Potassium heptafluorotantalate",
    "Potassium hexafluorophosphate", "Potassium hydrogen carbonate", "Potassium hydroxide", "Potassium iodate", "Potassium iodide", "Potassium manganate",
    "Potassium nitrate", "Potassium perchlorate", "Potassium periodate", "Potassium permanganate", "Potassium sulfate", "Potassium sulfide",
    "Potassium sulfite", "Potassium tetraiodomercurate(II)", "", "Potassium thiocyanate", "Potassium titanyl phosphate", "Potassium vanadate", "Pr",
    "Praseodymium(III) chloride", "Praseodymium(III) phosphate", "Praseodymium(III) sulfate", "Prussian blue", "Pt", "Pu", "Pyrosulfuric acid", "Ra", "Rb",
    "Rb2O", "Re", "Rh", "Rhenium heptafluoride", "Rhenium hexafluoride", "Rhenium(IV) oxide", "Rhenium(VII) oxide", "Rhodium hexafluoride",
    "Rhodium(III) chloride", "Rhodium(III) nitrate", "Rhodium(III) sulfate", "Rhodium(IV) oxide", "Rn", "Ru", "Rubidium bromide", "Rubidium chloride",
    "Rubidium fluoride", "Rubidium hydroxide", "Rubidium iodide", "Rubidium nitrate", "Ruthenium hexafluoride", "Ruthenium(IV) oxide",
    "Ruthenium(VIII) oxide", "S", "Samarium(III) bromide", "Samarium(III) chloride", "Samarium(III) iodide", "Samarium(III) oxide", "Samarium(III) sulfide",
    "Sb", "Sb2O3", "Sb2O5", "Sc", "Scandium(III) nitrate", "Se", "Selenic acid", "Selenious acid", "Selenium dibromide", "Selenium dioxide",
    "Selenium disulfide", "Selenium hexafluoride", "Selenium oxybromide", "Selenium oxydichloride", "Selenium tetrachloride", "Selenium tetrafluoride",
    "Selenium trioxide", "Si", "Silane", "Silica gel", "Silicic acid", "Silicon carbide", "Silicon dioxide", "Silicon monoxide", "Silicon nitride",
    "Silicon tetrabromide", "Silicon tetrachloride", "Silicon tetrafluoride", "Silicon tetraiodide", "Silver bromide", "Silver chlorate", "Silver chloride",
    "Silver chromate", "Silver fluoroborate", "Silver fulminate", "Silver nitrate", "Silver oxide", "Silver perchlorate", "Silver permanganate",
    "Silver sulfate", "Silver sulfide", "Silver telluride", "Sm", "Sn", "SO", "Sodamide", "Sodium aluminate", "Sodium azide", "Sodium bicarbonate",
    "Sodium bisulfate", "Sodium bisulfite", "Sodium borohydride", "Sodium bromate", "Sodium bromide", "Sodium bromite", "Sodium carbonate",
    "Sodium chlorate", "Sodium chloride", "Sodium chlorite", "Sodium cyanate", "Sodium cyanide", "Sodium dichromate", "Sodium dioxide", "Sodium dithionite",
    "Sodium fluoride", "Sodium hydride", "Sodium hydrosulfide", "Sodium hydroxide", "Sodium hypochlorite", "Sodium hypoiodite", "Sodium hypophosphite",
    "Sodium iodate", "Sodium iodide", "Sodium molybdate", "Sodium monofluorophosphate", "Sodium nitrate", "Sodium nitrite", "Sodium perborate",
    "Sodium perbromate", "Sodium percarbonate", "Sodium perchlorate", "Sodium periodate", "Sodium permanganate", "Sodium peroxide", "Sodium perrhenate",
    "Sodium persulfate", "Sodium phosphate", "Sodium selenate", "Sodium selenide", "Sodium selenite", "Sodium silicate", "Sodium sulfate", "Sodium sulfide",
    "Sodium sulfite", "Sodium tellurite", "Sodium tetrafluoroborate", "Sodium thiocyanate", "Sodium tungstate", "Sr", "SrO", "Strontium boride",
    "Strontium carbonate", "Strontium fluoride", "Strontium hydroxide", "Strontium nitrate", "Strontium oxalate", "Strontium peroxide",
    "Strontium silicate", "Strontium sulfate", "Strontium sulfide", "Strontium titanate", "Strontium zirconate", "Sulfamic acid", "Sulfur dibromide",
    "Sulfur dioxide", "Sulfur hexafluoride", "Sulfuric acid", "Sulfurous acid", "Sulfur tetrafluoride", "Sulfuryl chloride", "Ta", "Tantalum(V) oxide",
    "Tb", "Tc", "Te", "Tellurium dioxide", "Tellurium hexafluoride", "Tellurium tetrabromide", "Tellurium tetrachloride", "Tellurium tetraiodide",
    "Tellurous acid", "TeO2", "Terbium(III) chloride", "Terbium(III) oxide", "Tetrachloroauric acid", "Tetrafluorohydrazine", "Th", "Thallium arsenide",
    "Thallium(I) bromide", "Thallium(I) carbonate", "Thallium(III) bromide", "Thallium(III) nitrate", "Thallium(III) sulfate", "Thallium(III) sulfide",
    "Thallium(I) iodide", "Thallium(I) sulfate", "Thionyl bromide", "Thionyl chloride", "Thiophosgene", "Thiophosphoryl chloride", "Thorium dioxide",
    "Thorium(IV) nitrate", "Thorium tetrafluoride", "Thulium(III) chloride", "Ti", "Tin(II) bromide", "Tin(II) chloride", "Tin(II) fluoride",
    "Tin(II) iodide", "Tin(II) oxide", "Tin(II) sulfate", "Tin(II) sulfide", "Tin(IV) bromide", "Tin(IV) chloride", "Tin(IV) iodide", "Tin(IV) oxide",
    "TiO", "Titanium diboride", "Titanium dioxide", "Titanium diselenide", "Titanium disilicide", "Titanium disulfide", "Titanium(II) chloride",
    "Titanium(III) chloride", "Titanium(III) phosphide", "Titanium(IV) chloride", "titanium(IV) oxide", "Titanium nitride", "Tl", "Tm", "Tribromosilane",
    "Trioxidane", "Tripotassium phosphate", "Trisodium phosphate", "trisodium phosphate", "Tungsten boride", "Tungsten(VI) chloride",
    "Tungsten(VI) fluoride", "Tungstic acid", "U", "UCl3", "UCl4", "UF4", "UF6", "UO2", "Uranium hexafluoride", "Uranium tetrachloride",
    "Uranium tetrafluoride", "Uranyl chloride", "Uranyl nitrate", "Uranyl sulfate", "V", "Vanadium(II) chloride", "Vanadium(III) fluoride",
    "Vanadium(III) oxide", "Vanadium(II) oxide", "Vanadium(IV) chloride", "Vanadium(IV) fluoride", "Vanadium(IV) oxide", "Vanadium oxytrichloride",
    "Vanadium pentafluoride", "Vanadium tetrachloride", "Vanadium(V) oxide", "W", "Water", "Xe", "Xenon difluoride", "Xenon hexafluoride",
    "Xenon tetrafluoride", "Y", "Yb", "Ytterbium(III) chloride", "Ytterbium(III) sulfate", "Yttrium(III) bromide", "Yttrium(III) nitrate",
    "Yttrium(III) sulfide", "Yttrium iron garnet", "Yttrium phosphide", "Zinc arsenide", "Zinc carbonate", "Zinc chloride", "Zinc iodide", "Zinc nitrate",
    "Zinc oxide", "Zinc pyrophosphate", "Zinc selenate", "Zinc selenite", "Zinc sulfate", "Zinc sulfide", "Zinc sulfite", "Zinc telluride",
    "Zirconium boride", "Zirconium dioxide", "Zirconium hydroxide", "Zirconium(IV) bromide", "Zirconium(IV) chloride", "Zirconium(IV) oxide",
    "Zirconium(IV) silicate", "Zirconium nitride", "Zirconium orthosilicate", "Zirconium tetrachloride", "Zirconium tetrahydroxide", "Zirconyl chloride",
    "Zirconyl nitrate", "Zn", "Zr"
]
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_organic():
    # https://old.reddit.com/r/chemistry/comments/pvsobb/what_are_the_clear_boundaries_between_conditions/
    from chemicals.miscdata import CRC_inorganic_data, CRC_organic_data
    from rdkit import Chem
    # from rdkit import RDLogger
    # RDLogger.DisableLog('rdApp.*')
    
    definitely_organic = ['methane', 'methanol',
                          'Trifluoroacetic anhydride', # not a hydrogen in it
                          'buckminsterfullerene', # not a hydrogen in it
                          'Acetylenedicarboxylic acid', # no C_H bond
                          # 'urea', # definitely organic for historical reason
                          ]
    for name in definitely_organic:
        mol = mol_from_name(name)
        assert is_organic(mol)
        
    definitely_organic_smiles = [
        'N(=[N+]=[N-])C1=NN=NN1N=C(N=[N+]=[N-])N=[N+]=[N-]', # azidoazide azide
        ]
    for smiles in definitely_organic_smiles:
        mol = Chem.MolFromSmiles(smiles)
        assert is_organic(mol)
    
    not_organic = ['Carbon dioxide', 'carbon monoxide', 'iron', 'gold', 'hydrogen',
                   # carbonic acids are not organic
                   'carbonic acid',
                   ]
    for name in not_organic + inorganic_compounds:
        mol = mol_from_name(name)
        assert not is_organic(mol)
        
    definitely_inorganic_smiles = [
        ]
        
    for smiles in definitely_inorganic_smiles:
        mol = Chem.MolFromSmiles(smiles)
        assert not is_organic(mol)
        
    
    # CRC_inconsistent_CASs = set(CRC_inorganic_data.index).intersection(CRC_organic_data.index)
    
    # some molecules like CO appear in both lists. It is interesting to look at the
    # results, but their lists definitely aren't definitive.
    
    
    # not_really_inorganic = frozenset([])
    # for CAS in CRC_inorganic_data.index:
    #     if CAS in not_really_inorganic:
    #         continue
    #     if CAS in CRC_inconsistent_CASs:
    #         continue
    #     try:
    #         c = Chemical(CAS)
    #         mol = c.rdkitmol
    #         if mol is None:
    #             continue
    #     except:
    #         continue
    #     try:
    #         assert is_inorganic(mol)
    #     except:
    #         print(CAS, c.name, c.smiles)

    # not_really_organic = frozenset([])#frozenset(['50-01-1', '56-03-1'])
    # for CAS in CRC_organic_data.index:
    #     if CAS in not_really_organic:
    #         continue
    #     if CAS in CRC_inconsistent_CASs:
    #         continue
    #     try:
    #         c = Chemical(CAS)
    #         mol = c.rdkitmol_Hs
    #         if mol is None:
    #             continue
    #     except:
    #         continue
    #     try:
    #         assert is_organic(mol)
    #     except:
    #         print(CAS,c.name, c.smiles)
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_count_ring_ring_attatchments():
    mol = mol_from_name('Dibenz[a,h]anthracene')
    assert 4 == count_ring_ring_attatchments(mol)
    
    mol = mol_from_name('Pyrene')
    assert 5 == count_ring_ring_attatchments(mol)
    
    mol = mol_from_name('Benzo[a]pyrene')
    assert 6 == count_ring_ring_attatchments(mol)
    
    mol = mol_from_name('Porphine')
    assert 4 == count_ring_ring_attatchments(mol)
    
    
    mol = mol_from_name('cubane')
    assert 12 == count_ring_ring_attatchments(mol)
    
    no_shared_rings = ['[18]annulene', 'pyridine', 'Methyl 2-pyridyl ketone',
                      ' 2-Methoxy-5-methylpyrazine', 'Pyrimidine', 'Imidazole', 'Furan', 'Thiophene',
                       'Pyrrole']
    for name in no_shared_rings:
        mol = mol_from_name(name)
    #     print(name)
        assert 0 == count_ring_ring_attatchments(mol)
    

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_count_rings_attatched_to_rings():
    mol = mol_from_name('Dibenz[a,h]anthracene')
    assert 5 == count_rings_attatched_to_rings(mol)
    
    mol = mol_from_name('Pyrene')
    assert 4 == count_rings_attatched_to_rings(mol)
    
    mol = mol_from_name('Benzo[a]pyrene')
    assert 5 == count_rings_attatched_to_rings(mol)
    
    mol = mol_from_name('cubane')
    assert 6 == count_rings_attatched_to_rings(mol)
    assert 6 == count_rings_attatched_to_rings(mol, allow_neighbors=False)
    
    mol = mol_from_name('biphenyl')
    assert 2 == count_rings_attatched_to_rings(mol)
    assert 0 == count_rings_attatched_to_rings(mol, allow_neighbors=False)
    
    


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_phosphine():
    not_phosphine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_phosphine:
        assert not is_phosphine(mol_from_name(c))
    
    phosphines = ['diphosphorous tetrafluoride', 'difluoroiodophosphine', 'difluorophosphine', 'phenylphosphine', 'Methyl diphenylphosphinite']
    
    for c in phosphines:
        assert is_phosphine(mol_from_name(c))

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_phosphonic_acid():
    not_phosphonic_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene',
                           'calcium metaphosphate', 'barium metaphosphate']
    for c in not_phosphonic_acid:
        assert not is_phosphonic_acid(mol_from_name(c))
    
    phosphonic_acids = ['Benzylphosphonic acid', 'phosphonoacetic acid', '3-phosphonopropanoic acid',
                        'medronic acid', 'hypophosphoric acid', 'phosphonic acid']
    
    for c in phosphonic_acids:
        assert is_phosphonic_acid(mol_from_name(c))
        
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_phosphodiester():
    not_phosphodiester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene', 'calcium metaphosphate', 'difluorophosphine']
    for c in not_phosphodiester:
        assert not is_phosphodiester(mol_from_name(c))
    
    phosphodiesters = ['dipropyl hydrogen phosphate', 'didecyl phosphate', 'diicosoxyphosphinic acid', 'diadenosine tetraphosphate', 'citicoline', 'dioctyl phosphate', 'ditetradecyl phosphate', 'diphosphoric acid, trioctyl ester', 'adenosine triphosphate']
    
    for c in phosphodiesters:
        assert is_phosphodiester(mol_from_name(c))

phosphates = ['monotridecyl phosphate', 'phosphoglycolic acid',
              'phosphoglycolic acid', 'glucose-1-phosphate', 'isoamyl ammonium phosphate', 'cytidylic acid', 'thuringiensin',
                'synadenylic acid',
                'cytidine triphosphate',
                'propyl phosphate', 'octacosyl dihydrogen phosphate',
                'hexacosyl dihydrogen phosphate',
                'tetracosyl dihydrogen phosphate', 'uridylic acid',
                'triethyl lead phosphate',]
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_phosphate():
    not_phosphate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_phosphate:
        assert not is_phosphate(mol_from_name(c))
    
    for c in phosphates:
        assert is_phosphate(mol_from_name(c))

boronic_acids = ['4-ethylphenylboronic acid',
 '2-fluorophenylboronic acid',
 '4-borono-dl-phenylalanine',
 '3-formylphenylboronic acid',
 '3-hydroxyphenylboronic acid',
 'oleyl borate',
 '3,5-bis(trifluoromethyl)phenylboronic acid',
 '3-iodophenylboronic acid',
 '1-naphthaleneboronic acid',
 'formaldehyde, polymer with phenol, borate',
 '3-methoxyphenylboronic acid',
 '1,4-benzenediboronic acid',
 '3-methylphenylboronic acid',
 '4-phenoxyphenylboronic acid',
 'quinoline-8-boronic acid',
 'methylboronic acid',
 'isooctyl borate',
 'thianthrene-1-boronic acid',
 '3-(trifluoromethoxy)phenylboronic acid',
 '3-carboxyphenylboronic acid',
 '3-(trifluoromethyl)phenylboronic acid',
 '2-methoxyphenylboronic acid',
 '4-vinylphenylboronic acid',
 '4-(methylthio)phenylboronic acid',
 '3-aminophenylboronic acid monohydrate',
 '4-fluorophenylboronic acid',
 'thiophene-2-boronic acid',
 '4-chlorophenylboronic acid',
 '2-methylphenylboronic acid',
 'isobutaneboronic acid',
 'thiophene-3-boronic acid',
 '5-methyl-2-(propan-2-yl)cyclohexyl dihydrogen borate',
 'nonylboronic acid',
 '4-bromophenylboronic acid',
 '3-fluorophenylboronic acid',
 '1-propanol, 3-((3-(boronooxy)propyl)amino)-',
 'ethylboronic acid',
 '3-benzyloxybenzeneboronic acid',
 'octadecylboronic acid',
 '4-benzyloxyphenylboronic acid',
 '4-methoxyphenylboronic acid',
 'biphenyl-3-boronic acid',
 '4-tolylboronic acid',
 '2,6-dimethylphenylboronic acid',
 '3-bromophenylboronic acid',
 '5-bromothiophene-2-boronic acid',
 '3-nitrophenylboronic acid',
 '3-chlorophenylboronic acid',
 '5-chlorothiophene-2-boronic acid',
 '3-cyanophenylboronic acid',
 '4-cyanophenylboronic acid',
 '3,4-dichlorophenylboronic acid',
 '2,3-difluorophenylboronic acid',
 'phenylboronic acid',
 '2,4-difluorophenylboronic acid',
 '2-aminoethyl dihydrogen borate',
 '2,5-difluorophenylboronic acid',
 '4-iodophenylboronic acid',
 '2,6-difluorophenylboronic acid',
 'isoquinolin-1-ylboronic acid',
 '3,4-difluorophenylboronic acid',
 '2-acetylphenylboronic acid',
 '2,5-dimethoxyphenylboronic acid',
 '2,6-dimethoxyphenylboronic acid',
 'ethyl borate',
 'propylboronic acid',
 '4-(dimethylamino)phenylboronic acid',
 '3-acetylphenylboronic acid',
 'styrylboronic acid',
 '1-butaneboronic acid',
 '3,4-dimethylphenylboronic acid',
 '4-carboxyphenylboronic acid',
 '3,5-dimethylphenylboronic acid',
 '4-ethoxyphenylboronic acid']
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_boronic_acids():
    not_boronic_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']
    for c in not_boronic_acid:
        assert not is_boronic_acid(mol_from_name(c))
    
    
    for c in boronic_acids:
        assert is_boronic_acid(mol_from_name(c))
boronic_esters =[ 'Diisopropoxymethylborane',
                     'difluoroboroxin',
 'fluoroboroxin', 'trichloroboroxin',
 'trifluoroboroxine', 'fluorodimethoxyborane', 'chloro(diethoxy)borane',
 'chlorodimethoxyborane',
 'butyldiisopropoxyborane',
 'ethyldimethoxyborane',
 'diisopropoxymethylborane',
 '2-bromo-1,3,2-benzodioxaborole',
 'trimethylboroxine',]
@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_boronic_ester():
    not_boronic_ester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] + boronic_acids + borinic_acids
    for c in not_boronic_ester:
        assert not is_boronic_ester(mol_from_name(c))
    
    
    for c in boronic_esters:
        assert is_boronic_ester(mol_from_name(c))

borinic_acids =  ['diphenylborinic acid', 'difluorohydroxyborane']

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_borinic_acid():
    not_borinic_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] + boronic_esters + boronic_acids + borinic_esters
    for c in not_borinic_acid:
        assert not is_borinic_acid(mol_from_name(c))
    
    
    for c in borinic_acids:
        assert is_borinic_acid(mol_from_name(c))

    smiles_hits = ['BO', 'B(C1=CC=C(C=C1)Cl)(C2=CC=C(C=C2)Cl)O']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_borinic_acid(mol)


borinic_esters = [ 'methoxydichloroborane',
 'methoxydiethylborane',
 'methoxychlorofluoroborane',
 'methoxybromofluoroborane',
 'methoxybromochloroborane', 'methoxydifluoroborane', 'dichloro-(ethoxy)borane',
 'dichloro-(n-propoxy)borane', 'methoxydiiodoborane',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_borinic_ester():
    not_borinic_ester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] + boronic_esters + boronic_acids + borinic_acids
    for c in not_borinic_ester:
        assert not is_borinic_ester(mol_from_name(c))
    
    
    for c in borinic_esters:
        assert is_borinic_ester(mol_from_name(c))

    smiles_hits = []
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_borinic_ester(mol)


alkyllithiums = [ 'methyllithium', 'tert-butyllithium', 'n-butyllithium', 'lithium cyanide', 'lithium cyclopentadienide', 'isopropyllithium',
 'ethyllithium',
 'n-hexyllithium', 'sec-butyllithium',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_alkyllithium():
    not_alkyllithium = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_alkyllithium:
        assert not is_alkyllithium(mol_from_name(c))
    
    
    for c in alkyllithiums:
        assert is_alkyllithium(mol_from_name(c))

    smiles_hits = []
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_alkyllithium(mol)

alkylmagnesium_halides = [ 'bromopentylmagnesium', 'ethylmagnesiumbromide', 'bromophenylmagnesium', 'chloroethylmagnesium',
 'chloromethylmagnesium', 'methyl magnesium bromide',
 'benzylmagnesium chloride','cyclohexylmagnesium chloride', '4-methylphenylmagnesium bromide',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_alkylmagnesium_halide():
    not_alkylmagnesium_halide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_alkylmagnesium_halide:
        assert not is_alkylmagnesium_halide(mol_from_name(c))
    
    
    for c in alkylmagnesium_halides:
        assert is_alkylmagnesium_halide(mol_from_name(c))

    smiles_hits = ['C1=CC=[C-]C=C1.[Mg+2].[Br-]', 'Br[Mg]c1ccccc1', '[Cl-].[Mg+]C']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_alkylmagnesium_halide(mol)



alkylaluminiums = ['trimethylaluminium', 'Triethylaluminium', 'diethylaluminum ethoxide', 'tris(triacontyl)aluminium', '(e)-didecyl(dodec-1-enyl)aluminium', 'trineopentylaluminium',
                   'tripropylaluminum', 'triisobutylaluminum', 'dimethylaluminum chloride', 'diisobutylaluminum chloride', 'isobutylaluminum dichloride', 'chlorodioctylaluminium']


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_alkylaluminium():
    not_alkylaluminium = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_alkylaluminium:
        assert not is_alkylaluminium(mol_from_name(c))
    
    
    for c in alkylaluminiums:
        assert is_alkylaluminium(mol_from_name(c))

    smiles_hits = []
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_alkylaluminium(mol)
        

silyl_ethers = [  'methyltriethoxysilane', '3-cyanopropyltriethoxysilane', 'tris(trimethylsiloxy)silane', '2-(3-cyclohexenyl)ethyltrimethoxysilane',
 'diisobutyldimethoxysilane',
 'octamethyltetrasiloxane-1,7-diol', '3-isocyanatopropyltrimethoxysilane', 'trimethoxy(octyl)silane',
 'octadecyltrimethoxysilane', 'diethyldiethoxysilane', 'methyldodecyldiethoxysilane', '1-phenoxysilatrane', 'phenylsilatrane', 'hexaphenyldisiloxane',
 '1,3-dibenzyltetramethyldisiloxane',
 'methyltris(trimethylsiloxy)silane',
 'isopropenyloxytrimethylsilane',
 'pentamethylphenylcyclotrisiloxane', 'tris(trimethylsilyloxy)ethylene', 'octadecyltriethoxysilane',
 '1,1-dimethoxysiletane', 'ethoxysilatrane',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_silyl_ether():
    not_silyl_ether = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene']  + alkylaluminiums+ alkylmagnesium_halides+alkyllithiums
    for c in not_silyl_ether:
        assert not is_silyl_ether(mol_from_name(c))
    
    
    for c in silyl_ethers:
        assert is_silyl_ether(mol_from_name(c))

    smiles_hits = ['C[Si](C)(C)OS(=O)(=O)C(F)(F)F']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_silyl_ether(mol)

sulfinic_acids = [ 'bisulfite',
 'thiourea dioxide', 'methanesulfinic acid', 'p-toluenesulfinic acid',
 'sodium bisulfite', 'calcium bisulfite', 'choline bisulfite',
 'potassium hydrogen sulfite',
 'benzenesulfinic acid',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_sulfinic_acid():
    not_sulfinic_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_sulfinic_acid:
        assert not is_sulfinic_acid(mol_from_name(c))
    
    
    for c in sulfinic_acids:
        assert is_sulfinic_acid(mol_from_name(c))

    smiles_hits = ['O=S(O)CCN']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_sulfinic_acid(mol)

sulfonic_acids = ['Benzenesulfonic acid',
                  'n-acetylsulfanilic acid', 'guabenxane', 'diphenyl epsilon acid',
 'chromotropic acid', 'ergocristinine methanesulfonate',
 'ergocorninine methanesulfonate',
 'ergocryptinine methanesulfonate',
 'ergotaminine methanesulfonate', 'persilic acid', '4-amino-2-methylbenzenesulfonic acid',
 '4-sulfophthalic anhydride', 'peroxydisulfuric acid', 'fluorosulfonic acid',
 'chlorosulfuric acid',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_sulfonic_acid():
    not_sulfonic_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_sulfonic_acid:
        assert not is_sulfonic_acid(mol_from_name(c))
    
    
    for c in sulfonic_acids:
        assert is_sulfonic_acid(mol_from_name(c))

    smiles_hits = ['OS(=O)(=O)c1ccccc1']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_sulfonic_acid(mol)

sulfonate_esters = [ 'phenyl methanesulfonate', 'propylene dimethanesulfonate',
 'isopropyl methanesulfonate', 'multergan', 'allyl methanesulfonate',
 'potassium persulfate', 'magnesium tetradecyl sulfate',
 'magnesium decyl sulfate', 'dipropyl sulfate', 'potassium pyrosulfate', 'ammonium persulfate',
 'sodium persulfate',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_sulfonate_ester():
    not_sulfonate_ester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_sulfonate_ester:
        assert not is_sulfonate_ester(mol_from_name(c))
    
    
    for c in sulfonate_esters:
        assert is_sulfonate_ester(mol_from_name(c))

    smiles_hits = ['COS(=O)(=O)C(F)(F)F']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_sulfonate_ester(mol)


thiocyanates = ['heptyl thiocyanate',
 'bornate',
 'methyl thiocyanate',
 'iodine thiocyanate', 'ethyl thiocyanate',
 '4-methyl-2-nitrophenylthiocyanate',
 '4-nitrobenzyl thiocyanate', 'chlorine thiocyanate', 'methylene dithiocyanate',
 'sulfur dicyanide', 'lauryl thiocyanate', 'octyl thiocyanate', '4-fluorobutyl thiocyanate',
 'chloromethyl thiocyanate', 'trimethyltin thiocyanate',
 'benzyl thiocyanate', 'phenyl thiocyanate', 'trichloromethyl thiocyanate',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_thiocyanate():
    not_thiocyanate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_thiocyanate:
        assert not is_thiocyanate(mol_from_name(c))
    
    
    for c in thiocyanates:
        assert is_thiocyanate(mol_from_name(c))

    smiles_hits = ['C1=CC=C(C=C1)SC#N']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_thiocyanate(mol)


isothiocyanates =  ['crotonyl isothiocyanate',
 '4-isopropylphenyl isothiocyanate', '2-chlorobenzoyl isothiocyanate',
 '3-chlorobenzoyl isothiocyanate',
 'octadecyl isothiocyanate',
 'ethyl 4-isothiocyanatobutanoate', 'trityl isothiocyanate', 'methyl isothiocyanate',
 'cyanogen isothiocyanate', 'allyl isothiocyanate', 'ethyl isothiocyanate', 'benzoyl isothiocyanate',
 'phenyl isothiocyanate', '3-bromopropyl isothiocyanate', 'dodecyl isothiocyanate',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_isothiocyanate():
    not_isothiocyanate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_isothiocyanate:
        assert not is_isothiocyanate(mol_from_name(c))
    
    
    for c in isothiocyanates:
        assert is_isothiocyanate(mol_from_name(c))

    smiles_hits = ['C=CCN=C=S']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_isothiocyanate(mol)


is_thioketones =  ['Diphenylmethanethione',
 'thioacetamide', 'nickel dibutyldithiocarbamate', 'dimethylthiocarbamoyl chloride', 'propyl dipropyldithiocarbamate', 'sodium ethylxanthate', 'diethyl xanthate', 'thioisonicotinamide', 'thiourea', 'potassium butylxanthate', '2-phenethyl-3-thiosemicarbazide', 'ammonium thiocarbamate', 'zinc isopropylxanthate', 'thiadiazinthion', '3-anilinorhodanine', 'thiuram disulfide', '2-bornanethione',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_thioketone():
    not_thioketone = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_thioketone:
        assert not is_thioketone(mol_from_name(c))
    
    
    for c in is_thioketones:
        assert is_thioketone(mol_from_name(c))

    smiles_hits = ['C1=CC=C(C=C1)C(=S)C2=CC=CC=C2']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_thioketone(mol)


is_thials =  ['ethanethial',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_thial():
    not_thial = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_thial:
        assert not is_thial(mol_from_name(c))
    
    
    for c in is_thials:
        assert is_thial(mol_from_name(c))

    smiles_hits = ['CC=S', 'CN(C)C=S', 'C(=S)N', 'C(=S)C#N']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_thial(mol)


is_carbothioic_s_acids =  ['Thiobenzoic acid', 'thioacetic acid', 'trifluorothiolacetic acid','dithioterephthalic acid',
 'aminothioacetic acid',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carbothioic_s_acid():
    not_carbothioic_s_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_carbothioic_s_acid:
        assert not is_carbothioic_s_acid(mol_from_name(c))
    
    
    for c in is_carbothioic_s_acids:
        assert is_carbothioic_s_acid(mol_from_name(c))

    smiles_hits = ['C1=CC=C(C=C1)C(=O)S']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_carbothioic_s_acid(mol)



is_carbothioic_o_acids =  []
# Literally nothing in the database

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carbothioic_o_acid():
    not_carbothioic_o_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_carbothioic_o_acid:
        assert not is_carbothioic_o_acid(mol_from_name(c))
    
    
    for c in is_carbothioic_o_acids:
        assert is_carbothioic_o_acid(mol_from_name(c))

    smiles_hits = ['OC(=S)c1ccccc1O']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_carbothioic_o_acid(mol)


is_thiolesters =  [ '2-benzothiophene-1,3-dione', 's-phenyl carbonochloridothioate',
 's-tert-butyl thioacetate', 'ecadotril', 'tibenzate', 's-ethyl thiopropionate',
 's-propyl propanethioate',
 's-methyl hexanethioate',
 's-propyl chlorothioformate', '2-methyl-3-(acetylthio)propionyl chloride', 'tiocarbazil',
 'cycloate', 'fenothiocarb', 'prosulfocarb', 'previcur',
 'molinate', 'acetylthiocholine iodide',
 'butyrylthiocholine iodide', 's-phenyl thioacetate',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_thiolester():
    not_thiolester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_thiolester:
        assert not is_thiolester(mol_from_name(c))
    
    
    for c in is_thiolesters:
        assert is_thiolester(mol_from_name(c))

    smiles_hits = ['CSC(=O)C=C']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_thiolester(mol)


is_thionoesters =  [ 'allyl thiopropionate',
 'o-ethyl ethanethioate', 'potassium butylxanthate',
 'dibutylxanthogen', 'potassium amylxanthate', 'o-phenyl chlorothioformate', 'o-ethyl thiocarbamate', 'potassium isopentyl dithiocarbonate',
 'pentafluorophenyl chlorothionoformate',
 'trichloromethyl methyl perthioxanthate', 'sodium ethylxanthate',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_thionoester():
    not_thionoester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_thionoester:
        assert not is_thionoester(mol_from_name(c))
    
    
    for c in is_thionoesters:
        assert is_thionoester(mol_from_name(c))

    smiles_hits = ['CCOC(=S)S']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_thionoester(mol)


is_carbodithioic_acids =  [ 'Dithiobenzoic acid', 'xanthate', '4-morpholinecarbodithioic acid', 'bis(2-methylpropyl)carbamodithioic acid', 'ammonium diethyldithiocarbamate', 'azepanium azepane-1-carbodithioate',
 'dipropyldithiocarbamic acid',
 'pyrrolidine dithiocarbamate',
 'ethane(dithioic) acid',
 'benzenecarbodithioic acid', 'ditiocarb',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carbodithioic_acid():
    not_carbodithioic_acid = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_carbodithioic_acid:
        assert not is_carbodithioic_acid(mol_from_name(c))
    
    
    for c in is_carbodithioic_acids:
        assert is_carbodithioic_acid(mol_from_name(c))

    smiles_hits = ['C1=CC=C(C=C1)C(=S)S']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_carbodithioic_acid(mol)


is_carbodithios =  [  '1,3-dithiolane-2-thione', 'tetrabutylthiuram disulfide', 'chlorothioformylsulfenylchloride',
 'dimorpholinethiuram disulfide', 'allyl dimethyldithiocarbamate',
 'phenyl chlorodithioformate', 'thiadiazinthion',
 'dimethyl trithiocarbonate',
 'ethyl dithioacetate', '3-allylrhodanine',
 '3-anilinorhodanine', 'dixanthogen', 'cystogon', 'monosulfiram',
 'sulfallate',
 '2-benzothiazolyl diethyldithiocarbamate', 'dipentamethylenethiuram disulfide',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carbodithio():
    not_carbodithio = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_carbodithio:
        assert not is_carbodithio(mol_from_name(c))
    
    
    for c in is_carbodithios:
        assert is_carbodithio(mol_from_name(c))

    smiles_hits = ['C(=S)(N)SSC(=S)N']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_carbodithio(mol)


is_acyl_halides =  ['4-bromobenzoyl chloride', 'isophthaloyl dichloride',
 'terephthaloyl chloride', 'heptanoyl chloride', '4-methylvaleryl chloride',
 '2-chloroisobutyryl chloride', 'acetyl bromide',
 'acetyl iodide',
 'benzoyl iodide', '2-furoyl chloride', '4-ethoxybenzoyl chloride',
 '5-bromovaleryl chloride',
 'propionyl chloride', 'isovaleryl chloride',
 '2,3,3-trifluoroacryloyl fluoride',
 '3-nitrobenzoyl chloride',
 '4-chlorobenzoyl chloride',
 '4-nitrobenzoyl chloride', 'perfluoroglutaryl chloride',
 'perfluoroglutaryl fluoride', 'chlorodifluoroacetyl chloride',
 'chlorodifluoroacetyl fluoride',
 'trifluoroacetyl fluoride',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_acyl_halide():
    not_acyl_halide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_acyl_halide:
        assert not is_acyl_halide(mol_from_name(c))
    
    
    for c in is_acyl_halides:
        assert is_acyl_halide(mol_from_name(c))

    smiles_hits = ['C(CCC(=O)Cl)CC(=O)Cl']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_acyl_halide(mol)


is_carbonates =  [ 'Triphosgene', 'dihexyl carbonate', 'triphosgene',
 'isobutyl carbonate', 'dibutyl carbonate',
 '4-formylphenyl methyl carbonate',
 'ethyl phenyl carbonate',
 'ethyl methyl carbonate', 'ethylene carbonate', 'dimethyl carbonate',
 'clorethate', 'decachlorodiphenyl carbonate', 'dipropyl carbonate',
 'bis(2-chloroethyl) carbonate', 'diallyl carbonate', 'diethyl pyrocarbonate', 'bismuth subcarbonate',
 'diamyl carbonate',
 'diethyl carbonate',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carbonate():
    not_carbonate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_carbonate:
        assert not is_carbonate(mol_from_name(c))
    
    
    for c in is_carbonates:
        assert is_carbonate(mol_from_name(c))

    smiles_hits = ['C(=O)(OC(Cl)(Cl)Cl)OC(Cl)(Cl)Cl']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_carbonate(mol)

is_carboxylates =  [ 'Sodium acetate', 'ammonium acetate', 'potassium acetate',
 'sodium acetate', 'praseodymium oxalate', 'bismuth oxalate', 'iron oleate', 'zinc octanoate',
 'calcium valproate', 'cefodizime sodium',
 'cadmium lactate','stannous tartrate',
 'pentolonium tartrate',
 'indium citrate',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carboxylate():
    not_carboxylate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_carboxylate:
        assert not is_carboxylate(mol_from_name(c))
    
    
    for c in is_carboxylates:
        assert is_carboxylate(mol_from_name(c))

    smiles_hits = [ 'CC(=O)[O-].[Na+]']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_carboxylate(mol)

is_hydroperoxides =  [  'octadecaneperoxoic acid',
 'tetradecaneperoxoic acid', '1-methylcyclohexyl hydroperoxide', 'n-butylhydroperoxide', 'peroxytridecanoic acid', 'trifluoromethyl peroxyacetate', 'hydroperoxymethanol', 'pentyl hydroperoxide', 'dodecaneperoxoic acid', 'tert-butyl hydroperoxide', 'methyl hydroperoxide',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_hydroperoxide():
    not_hydroperoxide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_hydroperoxide:
        assert not is_hydroperoxide(mol_from_name(c))
    
    
    for c in is_hydroperoxides:
        assert is_hydroperoxide(mol_from_name(c))

    smiles_hits = ['CC(C)(C)OO']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_hydroperoxide(mol)



is_peroxides =  [ 'hydrogen peroxide', '1,2-dioxane', 'tert-butyl octaneperoxoate', '2,2-di(tert-butylperoxy)butane', 'butyl peroxide', 'bis(1-oxononyl) peroxide',
 'dioctanoyl peroxide', 'acetyl benzoyl peroxide', 'octyl peroxide', 'benzoyl peroxide', 'fluorine dioxide', 'peroxydisulfuric acid', '1,2-dioxocane',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_peroxide():
    not_peroxide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_peroxide:
        assert not is_peroxide(mol_from_name(c))
    
    
    for c in is_peroxides:
        assert is_peroxide(mol_from_name(c))

    smiles_hits = [ 'CC(C)(C)OOC(C)(C)C']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_peroxide(mol)

is_orthoesters =  ['Triethyl orthoacetate', 'tetraethyl orthocarbonate',
 'triethyl orthoacetate', 'trimethyl orthoacetate', 'trimethyl orthobenzoate', 'trimethyl orthopropionate', 'trimethyl orthobutyrate',
 'triethyl orthopropionate', 'trimethyl orthovalerate',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_orthoester():
    not_orthoester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_orthoester:
        assert not is_orthoester(mol_from_name(c))
    
    
    for c in is_orthoesters:
        assert is_orthoester(mol_from_name(c))

    smiles_hits = ['CCOC(C)(OCC)OCC']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_orthoester(mol)


is_methylenedioxys =  [ '4,4-dimethyl-1,3-dioxane', 'narcotine', 'piperic acid', 'cubebin', '1,3,5-trioxane', 'homarylamine',
 'oxolinic acid', '1-piperonylpiperazine', 'sesamol',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_methylenedioxy():
    not_methylenedioxy = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_methylenedioxy:
        assert not is_methylenedioxy(mol_from_name(c))
    
    
    for c in is_methylenedioxys:
        assert is_methylenedioxy(mol_from_name(c))

    smiles_hits = ['C1OC2=CC=CC=C2O1']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_methylenedioxy(mol)

is_orthocarbonate_esters =  [ 'Tetramethoxymethane' ,'tetraethyl orthocarbonate',
 'tetrapropoxymethane',
 'tetramethoxymethane',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_orthocarbonate_ester():
    not_orthocarbonate_ester = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_orthocarbonate_ester:
        assert not is_orthocarbonate_ester(mol_from_name(c))
    
    
    for c in is_orthocarbonate_esters:
        assert is_orthocarbonate_ester(mol_from_name(c))

    smiles_hits = ['COC(OC)(OC)OC']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_orthocarbonate_ester(mol)

is_carboxylic_anhydrides =  [ 'Butyric anhydride', 'pivalic anhydride',
 'hexadecylsuccinic anhydride', '4-nitrobenzoic anhydride', '3-methylphthalic anhydride', 'dibromomaleic anhydride',
 'dichloromaleic anhydride', 'oxacycloundecane-2,11-dione', '2-methylphenyl anhydride',
 'iodine monoacetate', 'homophthalic anhydride',
 'difluoromaleic anhydride', 'citraconic anhydride', 'heptafluorobutyric anhydride',
 'hexafluoroglutaric anhydride',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carboxylic_anhydride():
    not_carboxylic_anhydride = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_carboxylic_anhydride:
        assert not is_carboxylic_anhydride(mol_from_name(c))
    
    
    for c in is_carboxylic_anhydrides:
        assert is_carboxylic_anhydride(mol_from_name(c))

    smiles_hits = ['CCCC(=O)OC(=O)CCC']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_carboxylic_anhydride(mol)


is_amidines =  [ 'acetamidine', 'DBU', 'Pentamidine']


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_amidine():
    not_amidine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_amidine:
        assert not is_amidine(mol_from_name(c))
    
    
    for c in is_amidines:
        assert is_amidine(mol_from_name(c))

    smiles_hits = ['C1=CC(=CC=C1C(=N)N)OCCCCCOC2=CC=C(C=C2)C(=N)N',
                   'C1=CC(=CC=C1C(=N)N)N/N=N/C2=CC=C(C=C2)C(=N)N',
                   '[NH]=C(N)c1ccccc1',
                   'C1=CC=C2C(=C1)C3=CC=CC=C3C2=CC4=CC=C(C=C4)C(=N)N']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_amidine(mol)
is_primary_ketimines =  [ 'benzophenone imine']


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_primary_ketimine():
    not_primary_ketimine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_primary_ketimine:
        assert not is_primary_ketimine(mol_from_name(c))
    
    
    for c in is_primary_ketimines:
        assert is_primary_ketimine(mol_from_name(c))

    smiles_hits = ['C1=CC=C(C=C1)C(=N)C2=CC=CC=C2']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_primary_ketimine(mol)


is_secondary_ketimines =  [ '54688-30-1']


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_secondary_ketimine():
    not_secondary_ketimine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_secondary_ketimine:
        assert not is_secondary_ketimine(mol_from_name(c))
    
    
    for c in is_secondary_ketimines:
        assert is_secondary_ketimine(mol_from_name(c))

    smiles_hits = [ 'CC(C)CC(=NC1=CC=C(C=C1)CC2=CC=C(C=C2)N=C(C)CC(C)C)C']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_secondary_ketimine(mol)
is_primary_aldimines =  [ 'Ethanimine', 'phenylmethanimine']


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_primary_aldimine():
    not_primary_aldimine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_primary_aldimine:
        assert not is_primary_aldimine(mol_from_name(c))
    
    
    for c in is_primary_aldimines:
        assert is_primary_aldimine(mol_from_name(c))

    smiles_hits = ['CC=N', 'C1=CC=C(C=C1)C=N', 'CN1C(C2=CC=CC=C2SC1=O)C=N',]
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_primary_aldimine(mol)

is_secondary_aldimines =  [ 'benzaldoxime',  'hydrobenzamide', 'nifuradene', '2-nitrobenzaldoxime', 'amfecloral', '2-furaldehyde oxime', 'covidarabine', 'chlordimeform hydrochloride', 'furapyrimidone', 'nitrofurazone',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_secondary_aldimine():
    not_secondary_aldimine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_secondary_aldimine:
        assert not is_secondary_aldimine(mol_from_name(c))
    
    
    for c in is_secondary_aldimines:
        assert is_secondary_aldimine(mol_from_name(c))

    smiles_hits = [ 'C1=CC=C(C=C1)/C=N\\O']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_secondary_aldimine(mol)


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_imine():
    not_secondary_aldimine = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in is_primary_aldimines + is_secondary_ketimines + is_primary_ketimines + is_secondary_aldimines:
        assert is_imine(mol_from_name(c))


is_imides =  [ 'Succinimide', 'Maleimide', 'Glutarimide', 'Phthalimide',
 'cefoperazone sodium', 'barbituric acid', 'aprobarbital', 'dichloromaleimide', 'acetylpheneturide', 'dioxatrine',
 'benzetimide',
 'methetoin', 'butabarbital', 'tetrabromophthalimide',
 'benzobarbital', 'dibenzamide', 'heptabarbital', 'captafol',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_imide():
    not_imide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_imide:
        assert not is_imide(mol_from_name(c))
    
    
    for c in is_imides:
        assert is_imide(mol_from_name(c))

    smiles_hits = ['C1=CC=C2C(=C1)C(=O)NC2=O']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_imide(mol)


is_azides =  [ 'Phenyl azide','azidosilane',
 'aziprotryne', 'chlorine azide', 'benzenesulfonyl azide', 'azidomethane', 'cyclohexyl azide', 'benzoyl azide', 'trityl azide', '1,2-diazidoethane', 'azidobenzene', '1-azidohexane', 'pentanedioyl azide', 'azidoacetic acid', 'triethylazidosilane', 'azidocodeine',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_azide():
    not_azide = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_azide:
        assert not is_azide(mol_from_name(c))
    
    
    for c in is_azides:
        assert is_azide(mol_from_name(c))

    smiles_hits = ['C1=CC=C(C=C1)N=[N+]=[N-]']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_azide(mol)

is_azos =  [ 'Azobenzene', '4-aminoazobenzene', 'cis-3-azonoradamantane', 'azodicarboxamide', '2,2-azopyridine',]


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_azo():
    not_azo = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_azo:
        assert not is_azo(mol_from_name(c))
    
    
    for c in is_azos:
        assert is_azo(mol_from_name(c))

    smiles_hits = ['C1=CC=C(C=C1)N=NC2=CC=CC=C2']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_azo(mol)


is_cyanates =  [ 'Methyl cyanate',
 'ethyl cyanate', 'cyanatotributylstannane',
 'trimethyltin cyanate', 'phenyl cyanate',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_cyanate():
    not_cyanate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_cyanate:
        assert not is_cyanate(mol_from_name(c))
    
    for c in is_cyanates:
        assert is_cyanate(mol_from_name(c))

    smiles_hits = [ 'COC#N']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_cyanate(mol)


is_isocyanates =  [ 'Methyl isocyanate', '1,8-diisocyanatooctane', '2-chlorobenzyl isocyanate', '2-methylbenzyl isocyanate',
 '3-methylbenzyl isocyanate', '2-chloroethyl isocyanate', 'undecyl isocyanate', 'phenyl isocyanatoformate', 'methyl isocyanate', 'isocyanatoethene', 'tert-octyl isocyanate',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_isocyanate():
    not_isocyanate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_isocyanate:
        assert not is_isocyanate(mol_from_name(c))
    
    
    for c in is_isocyanates:
        assert is_isocyanate(mol_from_name(c))

    smiles_hits = ['CN=C=O']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_isocyanate(mol)


is_nitrates =  [ 'mannitol hexanitrate',
 'ethyl nitrate',
 'uranyl nitrate', 'sulconazole nitrate', 'hydrazine dinitrate', 'metriol trinitrate', 'fuchsin nitrate', 'benzoyl nitrate', 'octyl nitrate', 'butyl nitrate', 'nitroglycerin', 'nitric acid', 'amyl nitrate', 'isopropyl nitrate',
 'methyl nitrate', 'miconazole nitrate',
 'methylamine nitrate', 'tetranitrin',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_nitrate():
    not_nitrate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_nitrate:
        assert not is_nitrate(mol_from_name(c))
    
    
    for c in is_nitrates:
        assert is_nitrate(mol_from_name(c))

    smiles_hits = ['CCCCCO[N+](=O)[O-]']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_nitrate(mol)


is_nitrites =  ['Isoamyl nitrite', 'amyl nitrite',
 'methyl nitrite', 'peroxynitrite', 'fluoro nitrite',
 'nitrous acid',
 'hexyl nitrite', 'ethyl nitrite',
 'isoamyl nitrite',
 'tert-butyl nitrite',
 'isopropyl nitrite',
 'isobutyl nitrite', 'propyl nitrite',
 'butyl nitrite',
 'benzyl nitrite', 'octyl nitrite',
 'decyl nitrite',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_nitrite():
    not_nitrite = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_nitrite:
        assert not is_nitrite(mol_from_name(c))
    
    
    for c in is_nitrites:
        assert is_nitrite(mol_from_name(c))

    smiles_hits = [ 'CC(C)CCON=O']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_nitrite(mol)

is_nitrosos =  ['Nitrosobenzene',  '1-nitro-2-nitrosobenzene', '1,2-dinitrosobenzene', 'pentafluoronitrosobenzene', 'p-chloronitrosobenzene', '1,3-dimethyl-2-nitrosobenzene',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_nitroso():
    not_nitroso = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_nitroso:
        assert not is_nitroso(mol_from_name(c))
    
    
    for c in is_nitrosos:
        assert is_nitroso(mol_from_name(c))

    smiles_hits = ['C1=CC=C(C=C1)N=O']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_nitroso(mol)


is_oximes =  [ 'cycloheptanone oxime', '2-octanone oxime',
 'pinacolone oxime', 'acetophenone oxime', 'diacetyl monoxime', 'benzophenone oxime',
 '2-pentanone oxime', 'cyclohexanone oxime',
 'cyclododecanone oxime', 'norethindrone oxime', '2-butanone oxime', '2-bornanone oxime', '9-fluorenone oxime',
 '2-indanone oxime',
 'hexan-2-one oxime', 'cyclopentanone oxime', 'cyclopropylmethylketone oxime',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_oxime():
    not_oxime = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_oxime:
        assert not is_oxime(mol_from_name(c))
    
    
    for c in is_oximes:
        assert is_oxime(mol_from_name(c))

    smiles_hits = [ 'CC(=NO)C']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_oxime(mol)

is_pyridyls =  [  'pyridine-3-thiol', '2,5-dichloropyridine', '1-(phenylmethyl)pyridinium', '4-ethynylpyridine',
 '3-amino-6-bromopyridine', '4-phenylpyridine', 'pyridine', '2-ethynylpyridine', '2-propylpyridine', '2-(octyloxy)pyridine', '2-hexylpyridine',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_pyridyl():
    not_pyridyl = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_pyridyl:
        assert not is_pyridyl(mol_from_name(c))
    
    
    for c in is_pyridyls:
        assert is_pyridyl(mol_from_name(c))

    smiles_hits = [ 'CN1CCC[C@H]1C1=CC=CN=C1']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_pyridyl(mol)

is_carbamates =  [  'Chlorpropham',  'ethyl ethylcarbamate', 'allyl carbamate',
 '2-chloroethyl carbamate', 'ethyl phenethylcarbamate', 'benzimidazole carbamate', 'methyl dimethylolcarbamate', 'hexyl phenylcarbamate', 'ethyl cyanomethylcarbamate', '2-methoxyethyl dimethylcarbamate', 'ethyl 2-methylphenylcarbamate', 'm-cumenyl methylcarbamate', 'isopropyl(hydroxymethyl)carbamate',
 'methyl methylcarbamate', 'phenyl carbamate', 'ethyl benzylcarbamate',
 'ethyl methylphenylcarbamate',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_carbamate():
    not_carbamate = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_carbamate:
        assert not is_carbamate(mol_from_name(c))
    
    
    for c in is_carbamates:
        assert is_carbamate(mol_from_name(c))

    smiles_hits = [ 'CC(C)OC(=O)NC1=CC(=CC=C1)Cl']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_carbamate(mol)

is_quats =  [   'penthonium', 'decamethonium bromide', 'pentamethazene', 'tetrabutylammonium tetraphenylborate', 'furamon', 'monodral bromide', 'acetylcholine chloride',]

@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_is_quat():
    not_quat = ['CO2', 'water', 'methane','butane', 'cyclopentane', 'benzene', 'toluene'] 
    for c in not_quat:
        assert not is_quat(mol_from_name(c))
    
    
    for c in is_quats:
        assert is_quat(mol_from_name(c))

    smiles_hits = ['CCCCCCCCCCCCCCCCCC[N+](C)(C)CCCCCCCCCCCCCCCCCC.[Cl-]']
    for smiles in smiles_hits:
        mol = Chem.MolFromSmiles(smiles)
        assert is_quat(mol)


@pytest.mark.rdkit
@pytest.mark.skipif(rdkit is None, reason="requires rdkit")
def test_BVirial_Tsonopoulos_extended_ab():
    res = BVirial_Tsonopoulos_extended_ab(Tc=405.65, Pc=11.28e6, dipole=1.469, smiles='N')
    assert_close1d(res, (-0.03213165965970815, 0.0))
    
    
    res = BVirial_Tsonopoulos_extended_ab(Tc=512.5, Pc=8084000.0, dipole=1.7, smiles="CO")
    assert_close1d(res, (0.0878, 0.0525))
    res = BVirial_Tsonopoulos_extended_ab(Tc=647.14, Pc=22048320.0, dipole=1.85, smiles="O")
    assert_close1d(res, (-0.0109, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=536.7, Pc=4207000.0, dipole=2.78, smiles="CCC(=O)C")
    assert_close1d(res, (-0.023941613881302313, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=408.0, Pc=6586125.0, dipole=2.33, smiles="C=O")
    assert_close1d(res, (-0.06293245357806315, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=466.7, Pc=3644000.0, dipole=1.15, smiles="CCOCC")
    assert_close1d(res, (-0.0046729983628324544, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=615.0, Pc=5674200.0, dipole=1.4599896871365, smiles="C=CC(=O)O")
    assert_close1d(res, (-0.006753850104414003, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=514.0, Pc=6137000.0, dipole=1.44, smiles="CCO")
    assert_close1d(res, (0.0878, 0.04215198485694609))
    res = BVirial_Tsonopoulos_extended_ab(Tc=536.8, Pc=5169000.0, dipole=1.55, smiles="CCCO")
    assert_close1d(res, (0.0878, 0.038670363833023684))
    res = BVirial_Tsonopoulos_extended_ab(Tc=562.05, Pc=4895000.0, dipole=0.0, smiles="C1=CC=CC=C1")
    assert_close1d(res, (0.0, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=405.6, Pc=11277472.5, dipole=1.47, smiles="N")
    assert_close1d(res, (-0.032184806598961786, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=373.2, Pc=8936865.0, dipole=0.97, smiles="S")
    assert_close1d(res, (-0.012751634807714006, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=457.0, Pc=5400000.0, dipole=2.98, smiles="C#N")
    assert_close1d(res, (-0.07845103454306249, 0.0))
    res = BVirial_Tsonopoulos_extended_ab(Tc=317.4, Pc=5870000.0, dipole=1.85, smiles="CF")
    assert_close1d(res, (-328285.5327580192, 0.0))