2 # -*- coding: utf-8 -*-
4 from basetest
import BaseTest
, empty_feed
6 from xml
.dom
import minidom
8 from StringIO
import StringIO
10 sys
.path
.insert(0, '..')
11 from zeroinstall
.injector
import model
, qdom
, namespaces
13 mydir
= os
.path
.dirname(__file__
)
15 class TestModel(BaseTest
):
17 assert model
.network_offline
in model
.network_levels
18 assert model
.network_minimal
in model
.network_levels
19 assert model
.network_full
in model
.network_levels
21 def testStabilities(self
):
22 assert 'insecure' in model
.stability_levels
23 assert 'buggy' in model
.stability_levels
24 assert 'developer' in model
.stability_levels
25 assert 'testing' in model
.stability_levels
26 assert 'stable' in model
.stability_levels
27 assert 'preferred' in model
.stability_levels
31 self
.assertEquals("", model
.escape(""))
32 self
.assertEquals("hello", model
.escape("hello"))
33 self
.assertEquals("%20", model
.escape(" "))
35 self
.assertEquals("file%3a%2f%2ffoo%7ebar",
36 model
.escape("file://foo~bar"))
37 self
.assertEquals("file%3a%2f%2ffoo%25bar",
38 model
.escape("file://foo%bar"))
40 self
.assertEquals("file:##foo%7ebar",
41 model
._pretty
_escape
("file://foo~bar"))
42 self
.assertEquals("file:##foo%25bar",
43 model
._pretty
_escape
("file://foo%bar"))
45 def testUnescape(self
):
46 self
.assertEquals("", model
.unescape(""))
47 self
.assertEquals("hello", model
.unescape("hello"))
48 self
.assertEquals(" ", model
.unescape("%20"))
50 self
.assertEquals("file://foo~bar",
51 model
.unescape("file%3a%2f%2ffoo%7ebar"))
52 self
.assertEquals("file://foo%bar",
53 model
.unescape("file%3a%2f%2ffoo%25bar"))
55 self
.assertEquals("file://foo",
56 model
.unescape("file:##foo"))
57 self
.assertEquals("file://foo~bar",
58 model
.unescape("file:##foo%7ebar"))
59 self
.assertEquals("file://foo%bar",
60 model
.unescape("file:##foo%25bar"))
62 def testEscaping(self
):
64 self
.assertEquals(str, model
.unescape(model
.escape(str)))
65 self
.assertEquals(str, model
.unescape(model
._pretty
_escape
(str)))
67 check(u
'http://example.com')
68 check(u
'http://example%46com')
69 check(u
'http:##example#com')
70 check(u
'http://example.com/foo/bar.xml')
71 check(u
'%20%21~&!"£ :@;,./{}$%^&()')
73 def testBadInterface(self
):
75 model
.Interface('foo')
77 except model
.SafeException
:
80 def testInterface(self
):
81 i
= model
.Interface('http://foo')
82 self
.assertEquals('(foo)', i
.get_name())
83 feed
= model
.ZeroInstallFeed(empty_feed
, local_path
= '/foo')
84 self
.assertEquals('Empty', feed
.get_name())
87 def testMetadata(self
):
88 main_feed
= model
.ZeroInstallFeed(empty_feed
, local_path
= '/foo')
89 e
= qdom
.parse(StringIO('<ns:b xmlns:ns="a" foo="bar"/>'))
90 main_feed
.metadata
= [e
]
91 assert main_feed
.get_metadata('a', 'b') == [e
]
92 assert main_feed
.get_metadata('b', 'b') == []
93 assert main_feed
.get_metadata('a', 'a') == []
94 assert e
.getAttribute('foo') == 'bar'
97 local_path
= os
.path
.join(mydir
, 'Local.xml')
98 dom
= qdom
.parse(open(local_path
))
99 feed
= model
.ZeroInstallFeed(dom
, local_path
= local_path
)
100 self
.assertEquals("Local feed", feed
.summary
)
101 self
.assertEquals("English", feed
.description
)
103 self
.assertEquals(4, len(feed
.summaries
))
104 self
.assertEquals(2, len(feed
.descriptions
))
107 basetest
.test_locale
= ('es_ES', 'UTF8')
109 self
.assertEquals("Fuente local", feed
.summary
)
110 self
.assertEquals(u
"Español", feed
.description
)
112 basetest
.test_locale
= ('fr_FR', 'UTF8')
114 self
.assertEquals("Local feed", feed
.summary
)
115 self
.assertEquals("English", feed
.description
)
117 basetest
.test_locale
= (None, None)
119 def testCommand(self
):
120 local_path
= os
.path
.join(mydir
, 'Command.xml')
121 dom
= qdom
.parse(open(local_path
))
122 feed
= model
.ZeroInstallFeed(dom
, local_path
= local_path
)
124 assert feed
.implementations
['a'].main
== 'foo'
125 assert feed
.implementations
['a'].commands
['run'].path
== 'foo'
126 assert feed
.implementations
['a'].commands
['test'].path
== 'test-foo'
128 assert feed
.implementations
['b'].main
== 'bar'
129 assert feed
.implementations
['b'].commands
['run'].path
== 'bar'
130 assert feed
.implementations
['b'].commands
['test'].path
== 'test-foo'
132 assert feed
.implementations
['c'].main
== 'runnable/missing'
133 assert feed
.implementations
['c'].commands
['run'].path
== 'runnable/missing'
134 assert feed
.implementations
['c'].commands
['test'].path
== 'test-baz'
136 def testStabPolicy(self
):
137 i
= model
.Interface('http://foo')
138 self
.assertEquals(None, i
.stability_policy
)
139 i
.set_stability_policy(model
.buggy
)
140 self
.assertEquals(model
.buggy
, i
.stability_policy
)
143 i
= model
.Interface('http://foo')
144 a
= model
.ZeroInstallImplementation(i
, 'foo', None)
146 assert a
.size
== a
.version
== a
.user_stability
== None
147 assert a
.arch
== a
.upstream_stability
== None
148 assert a
.dependencies
== {}
149 assert a
.download_sources
== []
150 assert a
.get_stability() is model
.testing
151 a
.upstream_stability
= model
.stable
152 assert a
.get_stability() is model
.stable
153 a
.user_stability
= model
.buggy
154 assert a
.get_stability() is model
.buggy
155 a
.version
= model
.parse_version('1.2.3')
156 self
.assertEquals('1.2.3', a
.get_version())
157 a
.version
= model
.parse_version('1.2.3-rc2-post')
158 self
.assertEquals('1.2.3-rc2-post', a
.get_version())
159 assert str(a
) == 'foo'
161 b
= model
.ZeroInstallImplementation(i
, 'foo', None)
165 def testDownloadSource(self
):
166 f
= model
.ZeroInstallFeed(empty_feed
, local_path
= '/foo')
167 a
= model
.ZeroInstallImplementation(f
, 'foo', None)
168 a
.add_download_source('ftp://foo', 1024, None)
169 a
.add_download_source('ftp://foo.tgz', 1025, 'foo')
170 assert a
.download_sources
[0].url
== 'ftp://foo'
171 assert a
.download_sources
[0].size
== 1024
172 assert a
.download_sources
[0].extract
== None
175 def testEnvBind(self
):
176 a
= model
.EnvironmentBinding('PYTHONPATH', 'path')
177 assert a
.name
== 'PYTHONPATH'
178 assert a
.insert
== 'path'
181 def testEnvModes(self
):
182 prepend
= model
.EnvironmentBinding('PYTHONPATH', 'lib', None, model
.EnvironmentBinding
.PREPEND
)
183 assert prepend
.name
== 'PYTHONPATH'
184 assert prepend
.insert
== 'lib'
185 assert prepend
.mode
is model
.EnvironmentBinding
.PREPEND
187 self
.assertEquals('/impl/lib:/usr/lib', prepend
.get_value('/impl', '/usr/lib'))
188 self
.assertEquals('/impl/lib', prepend
.get_value('/impl', None))
190 append
= model
.EnvironmentBinding('PYTHONPATH', 'lib', '/opt/lib', model
.EnvironmentBinding
.APPEND
)
191 assert append
.name
== 'PYTHONPATH'
192 assert append
.insert
== 'lib'
193 assert append
.mode
is model
.EnvironmentBinding
.APPEND
195 self
.assertEquals('/usr/lib:/impl/lib', append
.get_value('/impl', '/usr/lib'))
196 self
.assertEquals('/opt/lib:/impl/lib', append
.get_value('/impl', None))
198 append
= model
.EnvironmentBinding('PYTHONPATH', 'lib', None, model
.EnvironmentBinding
.REPLACE
)
199 assert append
.name
== 'PYTHONPATH'
200 assert append
.insert
== 'lib'
201 assert append
.mode
is model
.EnvironmentBinding
.REPLACE
203 self
.assertEquals('/impl/lib', append
.get_value('/impl', '/usr/lib'))
204 self
.assertEquals('/impl/lib', append
.get_value('/impl', None))
206 assert model
.EnvironmentBinding('PYTHONPATH', 'lib').mode
== model
.EnvironmentBinding
.PREPEND
208 def testOverlay(self
):
209 for xml
, expected
in [('<overlay/>', '<overlay . on />'),
210 ('<overlay src="usr"/>', '<overlay usr on />'),
211 ('<overlay src="package" mount-point="/usr/games"/>', '<overlay package on /usr/games>')]:
212 e
= qdom
.parse(StringIO(xml
))
213 ol
= model
.process_binding(e
)
214 self
.assertEquals(expected
, str(ol
))
216 doc
= minidom
.parseString('<doc/>')
217 new_xml
= str(ol
._toxml
(doc
).toxml())
218 new_e
= qdom
.parse(StringIO(new_xml
))
219 new_ol
= model
.process_binding(new_e
)
220 self
.assertEquals(expected
, str(new_ol
))
223 b
= model
.InterfaceDependency('http://foo', element
= qdom
.Element(namespaces
.XMLNS_IFACE
, 'requires', {}))
224 assert not b
.restrictions
225 assert not b
.bindings
229 f
= model
.Feed('http://feed', arch
= None, user_override
= False)
230 assert f
.uri
== 'http://feed'
232 assert f
.machine
== None
233 assert f
.arch
== None
234 assert f
.user_override
== False
236 f
= model
.Feed('http://feed', arch
= 'Linux-*', user_override
= True)
237 assert f
.uri
== 'http://feed'
238 assert f
.os
== 'Linux'
239 assert f
.machine
== None
240 assert f
.arch
== 'Linux-*'
241 assert f
.user_override
== True
243 f
= model
.Feed('http://feed', arch
= '*-i386', user_override
= True)
244 assert f
.uri
== 'http://feed'
246 assert f
.machine
== 'i386'
247 assert f
.arch
== '*-i386'
248 assert f
.user_override
== True
249 assert str(f
).startswith('<Feed from')
252 f
= model
.Feed('http://feed', arch
= 'i386', user_override
= True)
254 except model
.SafeException
, ex
:
255 assert 'Malformed arch' in str(ex
)
257 def testCanonical(self
):
259 model
.canonical_iface_uri('http://foo')
261 except model
.SafeException
, ex
:
262 assert 'Missing /' in str(ex
)
264 self
.assertEquals('http://foo/',
265 model
.canonical_iface_uri('http://foo/'))
267 model
.canonical_iface_uri('bad-name')
269 except model
.SafeException
, ex
:
270 assert 'Bad interface name' in str(ex
)
272 def testVersions(self
):
274 parsed
= model
.parse_version(v
)
275 assert model
.format_version(parsed
) == v
278 assert pv('1.0') > pv('0.9')
279 assert pv('1.0') > pv('1')
280 assert pv('1.0') == pv('1.0')
281 assert pv('0.9.9') < pv('1.0')
282 assert pv('10') > pv('2')
288 except model
.SafeException
:
297 assert pv('1') == [[1], 0]
298 assert pv('1.0') == [[1,0], 0]
299 assert pv('1.0-pre5') == [[1,0], -2, [5], 0]
300 assert pv('1.0-rc5') == [[1,0], -1, [5], 0]
301 assert pv('1.0-5') == [[1,0], 0, [5], 0]
302 assert pv('1.0-post5') == [[1,0], 1, [5], 0]
303 assert pv('1.0-post') == [[1,0], 1]
304 assert pv('1-rc2.0-pre2-post') == [[1], -1, [2,0], -2, [2], 1]
305 assert pv('1-rc2.0-pre-post') == [[1], -1, [2,0], -2, [], 1]
307 assert pv('1.0-0') > pv('1.0')
308 assert pv('1.0-1') > pv('1.0-0')
309 assert pv('1.0-0') < pv('1.0-1')
311 assert pv('1.0-pre99') > pv('1.0-pre1')
312 assert pv('1.0-pre99') < pv('1.0-rc1')
313 assert pv('1.0-rc1') < pv('1.0')
314 assert pv('1.0') < pv('1.0-0')
315 assert pv('1.0-0') < pv('1.0-post')
316 assert pv('2.1.9-pre-1') > pv('2.1.9-pre')
318 assert pv('2-post999') < pv('3-pre1')
320 if __name__
== '__main__':