def test_merge_sections(self):
        # set up 2 odmls with partially overlapping sections
        doc1 = odml.Document(author='Me')
        doc2 = odml.Document(author='You')

        doc1.extend([odml.Section('MySection'), odml.Section('OurSection')])
        doc2.extend([odml.Section('YourSection'), odml.Section('OurSection')])

        # adding properties to sections, because odml is omitting sections without properties
        for sec in doc1.sections + doc2.sections:
            sec.append(odml.Property('prop'))

        table1 = OdmlTable(load_from=doc1)
        table2 = OdmlTable(load_from=doc2)

        table1.merge(table2, strict=False)

        result = table1.convert2odml()

        expected = ['MySection', 'OurSection', 'YourSection']
        self.assertListEqual([s.name for s in result.sections], expected)
class TestOdmlTable(unittest.TestCase):
    """
    class to test the other functions of the OdmlTable-class
    """

    def setUp(self):
        self.test_table = OdmlTable()

    def test_change_titles(self):
        """
        changing the header_titles
        """
        expected = {"Path": "Pfad",
                    "SectionName": "Section Name",
                    "SectionType": "Section Type",
                    "SectionDefinition": "Section Definition",
                    "PropertyName": "Eigenschaft",
                    "PropertyDefinition": "Property Definition",
                    "Value": "Wert",
                    "ValueDefinition": "Value Definition",
                    "DataUnit": "Einheit",
                    "DataUncertainty": "Data Uncertainty",
                    "odmlDatatype": "Datentyp"}
        self.test_table.change_header_titles(Path="Pfad",
                                             PropertyName="Eigenschaft",
                                             Value="Wert", DataUnit="Einheit",
                                             odmlDatatype="Datentyp")
        self.assertEqual(self.test_table._header_titles, expected)

    # def test_change_allow_free_cols(self):
    #     """
    #     set allow_free_columns
    #     """
    #
    #     # self.test_table.allow_empty_columns = True
    #     # self.assertEqual(self.test_table._allow_empty_columns, True)
    #     # self.test_table.allow_empty_columns = False
    #     # self.assertEqual(self.test_table._allow_empty_columns, False)
    #     # # TODO: Exception
    #     # with self.assertRaises(Exception):
    #     #     self.test_table.allow_empty_columns = 4
    #
    # def test_forbid_free_cols(self):
    #     """
    #     test forbidding free columns while there are already free columns in
    #     the header
    #     """
    #
    #     self.test_table.allow_empty_columns = True
    #     self.test_table.change_header(Path=1, PropertyDefinition=3, Value=4)
    #     # TODO: Exception aendern
    #     with self.assertRaises(Exception):
    #         self.test_table.allow_empty_columns = False

    def test_merge(self):
        doc1 = create_compare_test(sections=2,properties=2,levels=2)

        # generate one additional Value, which is not present in doc2
        doc1.sections[1].properties[0].append(odml.Value(data='testvalue',
                                                         dtype='str'))

        # generate one additional Property, which is not present in doc2
        doc1.sections[0].append(odml.Property(name='Doc1Property2',value=5))

        #generate one additional Section, which is not present in doc2
        new_prop = odml.Property(name='Doc1Property2',value=10)
        new_sec = odml.Section(name='Doc1Section')
        new_sec.append(new_prop)
        doc1.sections[0].append(new_sec)

        self.test_table.load_from_odmldoc(doc1)

        doc2 = create_compare_test(sections=3,properties=3,levels=3)
        table2 = OdmlTable()
        table2.load_from_odmldoc(doc2)

        backup_table = copy.deepcopy(self.test_table)

        self.test_table.merge(doc2,mode='overwrite')
        backup_table.merge(table2,mode='overwrite')

        self.assertListEqual(self.test_table._odmldict,backup_table._odmldict)

        expected = len(table2._odmldict) + 2 # only additional prop and
        # section will be counted; additional value is overwritten

        self.assertEqual(len(self.test_table._odmldict),expected)


    def test_strict_merge_error(self):
        doc1 = create_compare_test(sections=2,properties=2,levels=2)

        # generate one additional Value, which is not present in doc2
        doc1.sections[1].properties[0].append(odml.Value(data='testvalue',
                                                         dtype='str'))

        self.test_table.load_from_odmldoc(doc1)

        doc2 = create_compare_test(sections=3,properties=3,levels=3)
        table2 = OdmlTable()
        table2.load_from_odmldoc(doc2)

        self.assertRaises(ValueError,self.test_table.merge,doc2,mode='strict')

    def test_strict_merge(self):
        doc1 = create_compare_test(sections=0,properties=1,levels=2)
        doc1.sections[0].properties[0].values[0].data = -1
        self.test_table.load_from_odmldoc(doc1)

        doc2 = create_compare_test(sections=0,properties=1,levels=2)
        table2 = OdmlTable()
        table2.load_from_odmldoc(doc2)
        self.test_table.merge(doc2,mode='strict')

        self.assertListEqual(table2._odmldict,self.test_table._odmldict)
class TestOdmlTable(unittest.TestCase):
    """
    class to test the other functions of the OdmlTable-class
    """
    def setUp(self):
        self.test_table = OdmlTable()

    def test_change_titles(self):
        """
        changing the header_titles
        """
        expected = {
            "Path": "Pfad",
            "SectionName": "Section Name",
            "SectionType": "Section Type",
            "SectionDefinition": "Section Definition",
            "PropertyName": "Eigenschaft",
            "PropertyDefinition": "Property Definition",
            "Value": "Wert",
            "DataUnit": "Einheit",
            "DataUncertainty": "Data Uncertainty",
            "odmlDatatype": "Datentyp"
        }
        self.test_table.change_header_titles(Path="Pfad",
                                             PropertyName="Eigenschaft",
                                             Value="Wert",
                                             DataUnit="Einheit",
                                             odmlDatatype="Datentyp")
        self.assertEqual(self.test_table._header_titles, expected)

    def test_merge_sections(self):
        # set up 2 odmls with partially overlapping sections
        doc1 = odml.Document(author='Me')
        doc2 = odml.Document(author='You')

        doc1.extend([odml.Section('MySection'), odml.Section('OurSection')])
        doc2.extend([odml.Section('YourSection'), odml.Section('OurSection')])

        # adding properties to sections, because odml is omitting sections without properties
        for sec in doc1.sections + doc2.sections:
            sec.append(odml.Property('prop'))

        table1 = OdmlTable(load_from=doc1)
        table2 = OdmlTable(load_from=doc2)

        table1.merge(table2, strict=False)

        result = table1.convert2odml()

        expected = ['MySection', 'OurSection', 'YourSection']
        self.assertListEqual([s.name for s in result.sections], expected)

    def test_merge_append_identical_value(self):
        doc1 = odml.Document()
        doc1.append(odml.Section('first sec'))
        doc1.sections[0].append(
            odml.Property('first prop', values=['value 1', 'value 2']))

        doc2 = odml.Document()
        doc2.append(odml.Section('first sec'))
        doc2.sections[0].append(
            odml.Property('first prop', values=['value 2', 'value 3']))

        self.test_table.load_from_odmldoc(doc1)
        self.test_table.merge(doc2, overwrite_values=False)

        self.assertEqual(len(self.test_table._odmldict[0]['Value']), 3)
        expected = doc1.sections[0].properties[0].values + doc2.sections[
            0].properties[0].values
        expected = list(set(expected))
        # comparing as set to disregard item order
        self.assertEqual(set(self.test_table._odmldict[0]['Value']),
                         set(expected))

    def test_merge_overwrite_values_false(self):
        doc1 = odml.Document()
        doc1.append(odml.Section('first sec'))
        doc1.sections[0].append(
            odml.Property('first prop', values='first value'))

        doc2 = odml.Document()
        doc2.append(odml.Section('first sec'))
        doc2.sections[0].append(
            odml.Property('first prop', values='second value'))

        self.test_table.load_from_odmldoc(doc1)
        self.test_table.merge(doc2, overwrite_values=False)

        self.assertEqual(len(self.test_table._odmldict[0]['Value']), 2)
        self.assertEqual(
            self.test_table._odmldict[0]['Value'],
            doc1.sections[0].properties[0].values +
            doc2.sections[0].properties[0].values)

    def test_merge_overwrite_values_true(self):
        doc1 = odml.Document()
        doc1.append(odml.Section('first sec'))
        doc1.sections[0].append(
            odml.Property('first prop', values='first value'))

        doc2 = odml.Document()
        doc2.append(odml.Section('first sec'))
        doc2.sections[0].append(
            odml.Property('first prop', values='second value'))

        self.test_table.load_from_odmldoc(doc1)
        self.test_table.merge(doc2, overwrite_values=True)

        self.assertEqual(len(self.test_table._odmldict[0]['Value']), 1)
        self.assertEqual(self.test_table._odmldict[0]['Value'][0],
                         doc2.sections[0].properties[0].values[0])

    def test_merge_update_docprops(self):
        doc1 = odml.Document(author='me',
                             repository='somewhere',
                             version=1.1,
                             date=None)
        doc2 = odml.Document(author='',
                             repository='anywhere',
                             version=1.1,
                             date=datetime.date.today())
        self.test_table.load_from_odmldoc(doc1)
        self.test_table.merge(doc2)

        self.assertEqual(self.test_table._docdict['author'], doc1.author)
        self.assertEqual(self.test_table._docdict['repository'],
                         doc1.repository)
        self.assertEqual(self.test_table._docdict['version'], doc1.version)
        self.assertEqual(self.test_table._docdict['date'], doc2.date)