# Path: chemdataextractor/model.py
# class Compound(BaseModel):
#     names = ListType(StringType())
#     labels = ListType(StringType())
#     roles = ListType(StringType())
#     nmr_spectra = ListType(ModelType(NmrSpectrum))
#     ir_spectra = ListType(ModelType(IrSpectrum))
#     uvvis_spectra = ListType(ModelType(UvvisSpectrum))
#     melting_points = ListType(ModelType(MeltingPoint))
#     glass_transitions = ListType(ModelType(GlassTransition))
#     quantum_yields = ListType(ModelType(QuantumYield))
#     fluorescence_lifetimes = ListType(ModelType(FluorescenceLifetime))
#     electrochemical_potentials = ListType(ModelType(ElectrochemicalPotential))
# 
#     def merge(self, other):
#         """Merge data from another Compound into this Compound."""
#         log.debug('Merging: %s and %s' % (self.serialize(), other.serialize()))
#         for k in self.keys():
#             for new_item in other[k]:
#                 if new_item not in self[k]:
#                     self[k].append(new_item)
#         log.debug('Result: %s' % self.serialize())
#         return self
# 
#     def merge_contextual(self, other):
#         """Merge in contextual info from a template Compound."""
#         # TODO: This is currently dependent on our data model? Make more robust to schema changes
#         # Currently we assume all lists at Compound level, with 1 further potential nested level of lists
#         for k in self.keys():
#             # print('key: %s' % k)
#             for item in self[k]:
#                 # print('item: %s' % item)
#                 for other_item in other.get(k, []):
#                     # Skip text properties (don't merge names, labels, roles)
#                     if isinstance(other_item, six.text_type):
#                         continue
#                     for otherk in other_item.keys():
#                         if isinstance(other_item[otherk], list):
#                             if len(other_item[otherk]) > 0 and len(item[otherk]) > 0:
#                                 other_nested_item = other_item[otherk][0]
#                                 for othernestedk in other_nested_item.keys():
#                                     for nested_item in item[otherk]:
#                                         if not nested_item[othernestedk]:
#                                             nested_item[othernestedk] = other_nested_item[othernestedk]
#                         elif not item[otherk]:
#                             item[otherk] = other_item[otherk]
#         log.debug('Result: %s' % self.serialize())
#         return self
# 
#     @property
#     def is_unidentified(self):
#         if not self.names and not self.labels:
#             return True
#         return False
# 
#     # @property
#     # def is_contextual(self):
#     #     for k in self:
#     #         # Not contextual if we have any names or labels
#     #         if k in {'names', 'labels'}:
#     #             return False
#     #     return super(Compound, self).is_contextual
# 
# 
#     @property
#     def is_id_only(self):
#         """Return True if identifier information only."""
#         for key, value in self.items():
#             if key not in {'names', 'labels', 'roles'} and value:
#                 return False
#         if self.names or self.labels:
#             return True
#         return False
# 
# class MeltingPoint(BaseModel):
#     """A melting point measurement."""
#     value = StringType()
#     units = StringType(contextual=True)
#     solvent = StringType(contextual=True)
#     concentration = StringType(contextual=True)
#     concentration_units = StringType(contextual=True)
#     apparatus = StringType(contextual=True)
# 
# class UvvisSpectrum(BaseModel):
#     solvent = StringType(contextual=True)
#     temperature = StringType(contextual=True)
#     temperature_units = StringType(contextual=True)
#     concentration = StringType(contextual=True)
#     concentration_units = StringType(contextual=True)
#     apparatus = StringType(contextual=True)
#     peaks = ListType(ModelType(UvvisPeak))
# 
# class UvvisPeak(BaseModel):
#     #: Peak value, i.e. wavelength
#     value = StringType()
#     #: Peak value units
#     units = StringType(contextual=True)
#     # Extinction value
#     extinction = StringType()
#     # Extinction units
#     extinction_units = StringType(contextual=True)
#     # Peak shape information (e.g. shoulder, broad)
#     shape = StringType()


import logging
import unittest
from chemdataextractor.model import Compound, MeltingPoint, UvvisSpectrum, UvvisPeak
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals



logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger(__name__)


class TestModel(unittest.TestCase):

    maxDiff = None

    def test_serialize(self):
        """Test model serializes as expected."""
        self.assertEqual(Compound(names=['Coumarin 343']).serialize(), {'names': ['Coumarin 343']})

    def test_is_unidentified(self):
        """Test is_unidentified method returns expected result."""
        self.assertEqual(Compound().is_unidentified, True)
        self.assertEqual(Compound(names=['Coumarin 343']).is_unidentified, False)
        self.assertEqual(Compound(labels=['3a']).is_unidentified, False)
        self.assertEqual(Compound(names=['Coumarin 343'], labels=['3a']).is_unidentified, False)
        self.assertEqual(Compound(melting_points=[MeltingPoint(value='250')]).is_unidentified, True)

    def test_is_contextual(self):
        """Test is_contextual method returns expected result."""
        self.assertEqual(Compound(names=['Coumarin 343']).is_contextual, False)
        self.assertEqual(Compound(melting_points=[MeltingPoint(value='240')]).is_contextual, False)

# Path: chemdataextractor/model.py
# class Compound(BaseModel):
#     names = ListType(StringType())
#     labels = ListType(StringType())
#     roles = ListType(StringType())
#     nmr_spectra = ListType(ModelType(NmrSpectrum))
#     ir_spectra = ListType(ModelType(IrSpectrum))
#     uvvis_spectra = ListType(ModelType(UvvisSpectrum))
#     melting_points = ListType(ModelType(MeltingPoint))
#     glass_transitions = ListType(ModelType(GlassTransition))
#     quantum_yields = ListType(ModelType(QuantumYield))
#     fluorescence_lifetimes = ListType(ModelType(FluorescenceLifetime))
#     electrochemical_potentials = ListType(ModelType(ElectrochemicalPotential))
# 
#     def merge(self, other):
#         """Merge data from another Compound into this Compound."""
#         log.debug('Merging: %s and %s' % (self.serialize(), other.serialize()))
#         for k in self.keys():
#             for new_item in other[k]:
#                 if new_item not in self[k]:
#                     self[k].append(new_item)
#         log.debug('Result: %s' % self.serialize())
#         return self
# 
#     def merge_contextual(self, other):
#         """Merge in contextual info from a template Compound."""
#         # TODO: This is currently dependent on our data model? Make more robust to schema changes
#         # Currently we assume all lists at Compound level, with 1 further potential nested level of lists
#         for k in self.keys():
#             # print('key: %s' % k)
#             for item in self[k]:
#                 # print('item: %s' % item)
#                 for other_item in other.get(k, []):
#                     # Skip text properties (don't merge names, labels, roles)
#                     if isinstance(other_item, six.text_type):
#                         continue
#                     for otherk in other_item.keys():
#                         if isinstance(other_item[otherk], list):
#                             if len(other_item[otherk]) > 0 and len(item[otherk]) > 0:
#                                 other_nested_item = other_item[otherk][0]
#                                 for othernestedk in other_nested_item.keys():
#                                     for nested_item in item[otherk]:
#                                         if not nested_item[othernestedk]:
#                                             nested_item[othernestedk] = other_nested_item[othernestedk]
#                         elif not item[otherk]:
#                             item[otherk] = other_item[otherk]
#         log.debug('Result: %s' % self.serialize())
#         return self
# 
#     @property
#     def is_unidentified(self):
#         if not self.names and not self.labels:
#             return True
#         return False
# 
#     # @property
#     # def is_contextual(self):
#     #     for k in self:
#     #         # Not contextual if we have any names or labels
#     #         if k in {'names', 'labels'}:
#     #             return False
#     #     return super(Compound, self).is_contextual
# 
# 
#     @property
#     def is_id_only(self):
#         """Return True if identifier information only."""
#         for key, value in self.items():
#             if key not in {'names', 'labels', 'roles'} and value:
#                 return False
#         if self.names or self.labels:
#             return True
#         return False
# 
# class MeltingPoint(BaseModel):
#     """A melting point measurement."""
#     value = StringType()
#     units = StringType(contextual=True)
#     solvent = StringType(contextual=True)
#     concentration = StringType(contextual=True)
#     concentration_units = StringType(contextual=True)
#     apparatus = StringType(contextual=True)
# 
# class UvvisSpectrum(BaseModel):
#     solvent = StringType(contextual=True)
#     temperature = StringType(contextual=True)
#     temperature_units = StringType(contextual=True)
#     concentration = StringType(contextual=True)
#     concentration_units = StringType(contextual=True)
#     apparatus = StringType(contextual=True)
#     peaks = ListType(ModelType(UvvisPeak))
# 
# class UvvisPeak(BaseModel):
#     #: Peak value, i.e. wavelength
#     value = StringType()
#     #: Peak value units
#     units = StringType(contextual=True)
#     # Extinction value
#     extinction = StringType()
#     # Extinction units
#     extinction_units = StringType(contextual=True)
#     # Peak shape information (e.g. shoulder, broad)
#     shape = StringType()


# Path: tests/test_model.py
import logging
import unittest
from chemdataextractor.model import Compound, MeltingPoint, UvvisSpectrum, UvvisPeak

from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals



logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger(__name__)


class TestModel(unittest.TestCase):

    maxDiff = None

    def test_serialize(self):
        """Test model serializes as expected."""
        self.assertEqual(Compound(names=['Coumarin 343']).serialize(), {'names': ['Coumarin 343']})

    def test_is_unidentified(self):
        """Test is_unidentified method returns expected result."""
        self.assertEqual(Compound().is_unidentified, True)
        self.assertEqual(Compound(names=['Coumarin 343']).is_unidentified, False)
        self.assertEqual(Compound(labels=['3a']).is_unidentified, False)
        self.assertEqual(Compound(names=['Coumarin 343'], labels=['3a']).is_unidentified, False)
        self.assertEqual(Compound(melting_points=[MeltingPoint(value='250')]).is_unidentified, True)

    def test_is_contextual(self):
        """Test is_contextual method returns expected result."""
        self.assertEqual(Compound(names=['Coumarin 343']).is_contextual, False)
        self.assertEqual(Compound(melting_points=[MeltingPoint(value='240')]).is_contextual, False)

        self.assertEqual(Compound(melting_points=[MeltingPoint(units='K')]).is_contextual, True)