source: orange/Orange/testing/unit/tests/test_table.py @ 11048:782c9d850e72

Revision 11048:782c9d850e72, 6.5 KB checked in by Ales Erjavec <ales.erjavec@…>, 16 months ago (diff)

Fixed 'TExampleTable.clone' method (erroneous copy constructor for TExampleTable).

The 'clone' method calls the C++ copy constructor to copy the table,
but the default copy constructor fails to properly copy the instances
(both tables end up claiming ownership of the same memory space).

Fixed by implementing a copy constructor to make a deep copy of
the instances.

Fixes #1260

Line 
1# -*- coding: utf-8 -*-
2""" Orange.data.Table related unit-tests
3"""
4
5
6try:
7    import unittest2 as unittest
8except:
9    import unittest
10from Orange.testing import testing
11
12import Orange
13import cPickle
14import tempfile
15import gc
16
17
18def native(table):
19    table = table.native()
20    for i in range(len(table)):
21        table[i] = [v.native() for v in table[i].native()]
22    return table
23
24
25def names_iter():
26    for name in testing.ALL_DATASETS:
27        yield name.replace(" ", "_").replace("-", "_"), (name,)
28
29
30@testing.data_driven(data_iter=names_iter())
31class TestLoading(unittest.TestCase):
32
33    @testing.test_on_data
34    def test_load_on(self, name):
35        """ Test the loading of the data set
36        """
37        table = Orange.data.Table(name)
38        self.assertIsNotNone(getattr(table, "attributeLoadStatus"),
39                             "No attributeLoadStatus")
40
41    @testing.test_on_data
42    def test_pickling_on(self, name):
43        """ Test data table pickling.
44        """
45        table = Orange.data.Table(name)
46        s = cPickle.dumps(table)
47        table_clone = cPickle.loads(s)
48#        self.assertEqual(table.domain, table_clone.domain)
49#        self.assertEqual(table.domain.class_var, table_clone.domain.class_var)
50        self.assertEqual(native(table), native(table_clone),
51                         "Native representation is not equal!")
52
53
54@testing.datasets_driven
55class TestSaving(unittest.TestCase):
56    @testing.test_on_data
57    def test_R_on(self, name):
58        data = Orange.data.Table(name)
59        with tempfile.NamedTemporaryFile(suffix=".R") as f:
60            data.save(f.name)
61
62#    @testing.test_on_data
63#    def test_toC50(self, name):
64#        data = Orange.data.Table(name)
65
66    @testing.test_on_datasets(datasets=testing.CLASSIFICATION_DATASETS + \
67                              testing.REGRESSION_DATASETS)
68    def test_arff_on(self, data):
69        with tempfile.NamedTemporaryFile(suffix=".arff") as f:
70            data.save(f.name)
71            f.flush()
72            data_arff = Orange.data.Table(f.name)
73
74    @testing.test_on_datasets(datasets=testing.CLASSIFICATION_DATASETS + \
75                              testing.REGRESSION_DATASETS)
76    def test_svm_on(self, data):
77        with tempfile.NamedTemporaryFile(suffix=".svm") as f:
78            data.save(f.name)
79            f.flush()
80            data_svm = Orange.data.Table(f.name)
81
82    @testing.test_on_datasets
83    def test_csv_on(self, data):
84        with tempfile.NamedTemporaryFile(suffix=".csv") as f:
85            Orange.data.io.save_csv(f, data, dialect="excel-tab")
86            f.flush()
87            f.seek(0)
88            Orange.data.io.load_csv(f, has_header=True,
89                                    has_types=True, has_annotations=True)
90
91
92@testing.datasets_driven
93class TestUnicodeFilenames(unittest.TestCase):
94
95    @testing.test_on_data
96    def test_tab_on(self, name):
97        """ Test the loading and saving to/from unicode (utf-8) filenames.
98        """
99        table = Orange.data.Table(name)
100        with tempfile.NamedTemporaryFile(suffix=u"ü-š-ç.tab") as f:
101            table.save(f.name)
102            f.flush()
103            table1 = Orange.data.Table(f.name)
104
105    @testing.test_on_datasets(datasets=testing.CLASSIFICATION_DATASETS + \
106                              testing.REGRESSION_DATASETS)
107    def test_txt_on(self, name):
108        """ Test the loading and saving to/from unicode (utf-8) filenames.
109        """
110        table = Orange.data.Table(name)
111        with tempfile.NamedTemporaryFile(suffix=u"ü-š-ç.txt") as f:
112            table.save(f.name)
113            f.flush()
114            table1 = Orange.data.Table(f.name)
115
116    @testing.test_on_datasets(datasets=testing.CLASSIFICATION_DATASETS + \
117                              testing.REGRESSION_DATASETS)
118    def test_arff_on(self, name):
119        """ Test the loading and saving to/from unicode (utf-8) filenames.
120        """
121        table = Orange.data.Table(name)
122        with tempfile.NamedTemporaryFile(suffix=u"ü-š-ç.arff") as f:
123            table.save(f.name)
124            f.flush()
125            table1 = Orange.data.Table(f.name)
126
127    def test_basket(self):
128        """ Test the loading and saving to/from unicode (utf-8) filenames.
129        """
130        table = Orange.data.Table("inquisition.basket")
131        with tempfile.NamedTemporaryFile(suffix=u"ü-š-ç.basket") as f:
132            table.save(f.name)
133            f.flush()
134            table1 = Orange.data.Table(f.name)
135
136
137@testing.datasets_driven
138class TestHashing(unittest.TestCase):
139
140    @testing.test_on_data
141    def test_uniqueness(self, name):
142        """ Test the uniqueness of hashes. This is probabilistic,
143        but if we hit a collision in one of documentation datasets,
144        then it's time to open a bottle of Champagne ...
145        """
146        table = Orange.data.Table(name)
147        self.assertEquals(len(set(table)), len(set(hash(i) for i in table)))
148
149    @testing.test_on_data
150    def test_repetitiveness(self, name):
151        """ Test whether a data instance gets the same hash twice.
152        """
153        table = Orange.data.Table(name)
154        a = [hash(i) for i in table]
155        # Copy and reverse the table prior to hashing - just to hopefully
156        # make more bugs stand out.
157        b = list(reversed([hash(i) for i in
158                           reversed(Orange.data.Table(table))]))
159
160        self.assertEquals(a, b)
161
162
163class TestDataOwnership(unittest.TestCase):
164    def test_clone(self):
165        """Test that `clone` method returns a table with it's own copy
166        of the data.
167
168        """
169        iris = Orange.data.Table("iris")
170        clone = iris.clone()
171
172        self.assertTrue(iris.owns_instances and clone.owns_instances)
173        self.assertTrue(all(e1.reference() != e2.reference()
174                            for e1, e2 in zip(iris, clone)))
175
176        clone[0][0] = -1
177        self.assertTrue(iris[0][0] != clone[0][0])
178
179        del clone
180        gc.collect()
181
182    def test_reference(self):
183        iris = Orange.data.Table("iris")
184
185        ref = Orange.data.Table(iris, True)
186
187        self.assertTrue(iris.owns_instances)
188        self.assertFalse(ref.owns_instances)
189
190        self.assertTrue(all(e1.reference() == e2.reference()
191                            for e1, e2 in zip(iris, ref)))
192
193        ref[0][0] = -1
194        self.assertEqual(iris[0][0], -1)
195
196        with self.assertRaises(TypeError):
197            ref.append(
198                Orange.data.Instance(ref.domain,
199                                     [0, 0, 0, 0, "Iris-setosa"])
200            )
201
202        del ref
203        gc.collect()
204
205
206if __name__ == "__main__":
207    unittest.main()
Note: See TracBrowser for help on using the repository browser.