1try:
2    import unittest2 as unittest
3except ImportError:
4    import unittest
5
6
7from rope.base.oi import objectdb, memorydb
8from ropetest import testutils
9
10
11def _do_for_all_dbs(function):
12    def called(self):
13        for db in self.dbs:
14            function(self, db)
15    return called
16
17
18class _MockValidation(object):
19
20    def is_value_valid(self, value):
21        return value != -1
22
23    def is_more_valid(self, new, old):
24        return new != -1
25
26    def is_file_valid(self, path):
27        return path != 'invalid'
28
29    def is_scope_valid(self, path, key):
30        return path != 'invalid' and key != 'invalid'
31
32
33class _MockFileListObserver(object):
34
35    log = ''
36
37    def added(self, path):
38        self.log += 'added %s ' % path
39
40    def removed(self, path):
41        self.log += 'removed %s ' % path
42
43
44class ObjectDBTest(unittest.TestCase):
45
46    def setUp(self):
47        super(ObjectDBTest, self).setUp()
48        self.project = testutils.sample_project()
49        validation = _MockValidation()
50        self.dbs = [
51            objectdb.ObjectDB(memorydb.MemoryDB(self.project), validation)]
52
53    def tearDown(self):
54        for db in self.dbs:
55            db.write()
56        testutils.remove_project(self.project)
57        super(ObjectDBTest, self).tearDown()
58
59    @_do_for_all_dbs
60    def test_simple_per_name(self, db):
61        db.add_pername('file', 'key', 'name', 1)
62        self.assertEqual(1, db.get_pername('file', 'key', 'name'))
63
64    @_do_for_all_dbs
65    def test_simple_per_name_does_not_exist(self, db):
66        self.assertEqual(None, db.get_pername('file', 'key', 'name'))
67
68    @_do_for_all_dbs
69    def test_simple_per_name_after_syncing(self, db):
70        db.add_pername('file', 'key', 'name', 1)
71        db.write()
72        self.assertEqual(1, db.get_pername('file', 'key', 'name'))
73
74    @_do_for_all_dbs
75    def test_getting_returned(self, db):
76        db.add_callinfo('file', 'key', (1, 2), 3)
77        self.assertEqual(3, db.get_returned('file', 'key', (1, 2)))
78
79    @_do_for_all_dbs
80    def test_getting_returned_when_does_not_match(self, db):
81        db.add_callinfo('file', 'key', (1, 2), 3)
82        self.assertEqual(None, db.get_returned('file', 'key', (1, 1)))
83
84    @_do_for_all_dbs
85    def test_getting_call_info(self, db):
86        db.add_callinfo('file', 'key', (1, 2), 3)
87
88        call_infos = list(db.get_callinfos('file', 'key'))
89        self.assertEqual(1, len(call_infos))
90        self.assertEqual((1, 2), call_infos[0].get_parameters())
91        self.assertEqual(3, call_infos[0].get_returned())
92
93    @_do_for_all_dbs
94    def test_invalid_per_name(self, db):
95        db.add_pername('file', 'key', 'name', -1)
96        self.assertEqual(None, db.get_pername('file', 'key', 'name'))
97
98    @_do_for_all_dbs
99    def test_overwriting_per_name(self, db):
100        db.add_pername('file', 'key', 'name', 1)
101        db.add_pername('file', 'key', 'name', 2)
102        self.assertEqual(2, db.get_pername('file', 'key', 'name'))
103
104    @_do_for_all_dbs
105    def test_not_overwriting_with_invalid_per_name(self, db):
106        db.add_pername('file', 'key', 'name', 1)
107        db.add_pername('file', 'key', 'name', -1)
108        self.assertEqual(1, db.get_pername('file', 'key', 'name'))
109
110    @_do_for_all_dbs
111    def test_getting_invalid_returned(self, db):
112        db.add_callinfo('file', 'key', (1, 2), -1)
113        self.assertEqual(None, db.get_returned('file', 'key', (1, 2)))
114
115    @_do_for_all_dbs
116    def test_not_overwriting_with_invalid_returned(self, db):
117        db.add_callinfo('file', 'key', (1, 2), 3)
118        db.add_callinfo('file', 'key', (1, 2), -1)
119        self.assertEqual(3, db.get_returned('file', 'key', (1, 2)))
120
121    @_do_for_all_dbs
122    def test_get_files(self, db):
123        db.add_callinfo('file1', 'key', (1, 2), 3)
124        db.add_callinfo('file2', 'key', (1, 2), 3)
125        self.assertEqual(set(['file1', 'file2']), set(db.get_files()))
126
127    @_do_for_all_dbs
128    def test_validating_files(self, db):
129        db.add_callinfo('invalid', 'key', (1, 2), 3)
130        db.validate_files()
131        self.assertEqual(0, len(db.get_files()))
132
133    @_do_for_all_dbs
134    def test_validating_file_for_scopes(self, db):
135        db.add_callinfo('file', 'invalid', (1, 2), 3)
136        db.validate_file('file')
137        self.assertEqual(1, len(db.get_files()))
138        self.assertEqual(0, len(list(db.get_callinfos('file', 'invalid'))))
139
140    @_do_for_all_dbs
141    def test_validating_file_moved(self, db):
142        db.add_callinfo('file', 'key', (1, 2), 3)
143
144        db.file_moved('file', 'newfile')
145        self.assertEqual(1, len(db.get_files()))
146        self.assertEqual(1, len(list(db.get_callinfos('newfile', 'key'))))
147
148    @_do_for_all_dbs
149    def test_using_file_list_observer(self, db):
150        db.add_callinfo('invalid', 'key', (1, 2), 3)
151        observer = _MockFileListObserver()
152        db.add_file_list_observer(observer)
153        db.validate_files()
154        self.assertEqual('removed invalid ', observer.log)
155
156
157def suite():
158    result = unittest.TestSuite()
159    result.addTests(unittest.makeSuite(ObjectDBTest))
160    return result
161
162
163if __name__ == '__main__':
164    unittest.main()
165