Show More
@@ -1,71 +1,77 b'' | |||||
1 | # Test that certain objects conform to well-defined interfaces. |
|
1 | # Test that certain objects conform to well-defined interfaces. | |
2 |
|
2 | |||
3 | from __future__ import absolute_import, print_function |
|
3 | from __future__ import absolute_import, print_function | |
4 |
|
4 | |||
5 | from mercurial import ( |
|
5 | from mercurial import ( | |
|
6 | bundlerepo, | |||
6 | httppeer, |
|
7 | httppeer, | |
7 | localrepo, |
|
8 | localrepo, | |
8 | sshpeer, |
|
9 | sshpeer, | |
|
10 | statichttprepo, | |||
9 | ui as uimod, |
|
11 | ui as uimod, | |
|
12 | unionrepo, | |||
10 | ) |
|
13 | ) | |
11 |
|
14 | |||
12 | def checkobject(o): |
|
15 | def checkobject(o): | |
13 | """Verify a constructed object conforms to interface rules. |
|
16 | """Verify a constructed object conforms to interface rules. | |
14 |
|
17 | |||
15 | An object must have __abstractmethods__ defined. |
|
18 | An object must have __abstractmethods__ defined. | |
16 |
|
19 | |||
17 | All "public" attributes of the object (attributes not prefixed with |
|
20 | All "public" attributes of the object (attributes not prefixed with | |
18 | an underscore) must be in __abstractmethods__ or appear on a base class |
|
21 | an underscore) must be in __abstractmethods__ or appear on a base class | |
19 | with __abstractmethods__. |
|
22 | with __abstractmethods__. | |
20 | """ |
|
23 | """ | |
21 | name = o.__class__.__name__ |
|
24 | name = o.__class__.__name__ | |
22 |
|
25 | |||
23 | allowed = set() |
|
26 | allowed = set() | |
24 | for cls in o.__class__.__mro__: |
|
27 | for cls in o.__class__.__mro__: | |
25 | if not getattr(cls, '__abstractmethods__', set()): |
|
28 | if not getattr(cls, '__abstractmethods__', set()): | |
26 | continue |
|
29 | continue | |
27 |
|
30 | |||
28 | allowed |= cls.__abstractmethods__ |
|
31 | allowed |= cls.__abstractmethods__ | |
29 | allowed |= {a for a in dir(cls) if not a.startswith('_')} |
|
32 | allowed |= {a for a in dir(cls) if not a.startswith('_')} | |
30 |
|
33 | |||
31 | if not allowed: |
|
34 | if not allowed: | |
32 | print('%s does not have abstract methods' % name) |
|
35 | print('%s does not have abstract methods' % name) | |
33 | return |
|
36 | return | |
34 |
|
37 | |||
35 | public = {a for a in dir(o) if not a.startswith('_')} |
|
38 | public = {a for a in dir(o) if not a.startswith('_')} | |
36 |
|
39 | |||
37 | for attr in sorted(public - allowed): |
|
40 | for attr in sorted(public - allowed): | |
38 | print('public attributes not in abstract interface: %s.%s' % ( |
|
41 | print('public attributes not in abstract interface: %s.%s' % ( | |
39 | name, attr)) |
|
42 | name, attr)) | |
40 |
|
43 | |||
41 | # Facilitates testing localpeer. |
|
44 | # Facilitates testing localpeer. | |
42 | class dummyrepo(object): |
|
45 | class dummyrepo(object): | |
43 | def __init__(self): |
|
46 | def __init__(self): | |
44 | self.ui = uimod.ui() |
|
47 | self.ui = uimod.ui() | |
45 | def filtered(self, name): |
|
48 | def filtered(self, name): | |
46 | pass |
|
49 | pass | |
47 | def _restrictcapabilities(self, caps): |
|
50 | def _restrictcapabilities(self, caps): | |
48 | pass |
|
51 | pass | |
49 |
|
52 | |||
50 | # Facilitates testing sshpeer without requiring an SSH server. |
|
53 | # Facilitates testing sshpeer without requiring an SSH server. | |
51 | class testingsshpeer(sshpeer.sshpeer): |
|
54 | class testingsshpeer(sshpeer.sshpeer): | |
52 | def _validaterepo(self, *args, **kwargs): |
|
55 | def _validaterepo(self, *args, **kwargs): | |
53 | pass |
|
56 | pass | |
54 |
|
57 | |||
55 | class badpeer(httppeer.httppeer): |
|
58 | class badpeer(httppeer.httppeer): | |
56 | def __init__(self): |
|
59 | def __init__(self): | |
57 | super(badpeer, self).__init__(uimod.ui(), 'http://localhost') |
|
60 | super(badpeer, self).__init__(uimod.ui(), 'http://localhost') | |
58 | self.badattribute = True |
|
61 | self.badattribute = True | |
59 |
|
62 | |||
60 | def badmethod(self): |
|
63 | def badmethod(self): | |
61 | pass |
|
64 | pass | |
62 |
|
65 | |||
63 | def main(): |
|
66 | def main(): | |
64 | ui = uimod.ui() |
|
67 | ui = uimod.ui() | |
65 |
|
68 | |||
66 | checkobject(badpeer()) |
|
69 | checkobject(badpeer()) | |
67 | checkobject(httppeer.httppeer(ui, 'http://localhost')) |
|
70 | checkobject(httppeer.httppeer(ui, 'http://localhost')) | |
68 | checkobject(localrepo.localpeer(dummyrepo())) |
|
71 | checkobject(localrepo.localpeer(dummyrepo())) | |
69 | checkobject(testingsshpeer(ui, 'ssh://localhost/foo')) |
|
72 | checkobject(testingsshpeer(ui, 'ssh://localhost/foo')) | |
|
73 | checkobject(bundlerepo.bundlepeer(dummyrepo())) | |||
|
74 | checkobject(statichttprepo.statichttppeer(dummyrepo())) | |||
|
75 | checkobject(unionrepo.unionpeer(dummyrepo())) | |||
70 |
|
76 | |||
71 | main() |
|
77 | main() |
General Comments 0
You need to be logged in to leave comments.
Login now