Added 'shell-command' attribute to validator
[0publish.git] / tests / testlocal.py
blob5922e33754acd94e14e9cb205fbf88ee59c46226
1 #!/usr/bin/env python
2 import sys, os, tempfile, StringIO
3 from zeroinstall.injector.namespaces import XMLNS_IFACE
4 from zeroinstall.injector.reader import InvalidInterface
5 from zeroinstall.injector import model, reader, qdom
6 import unittest
7 from xml.dom import minidom
9 sys.path.insert(0, '..')
11 import create, merge, release
13 header = """<?xml version="1.0" ?>
14 <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface"
15 uri='http://test/hello.xml'>
16 <name>test</name>
17 <summary>for testing</summary>
18 <description>This is for testing.</description>
19 """
20 footer = """
21 </interface>
22 """
24 def parse(xml):
25 dom = minidom.parseString(xml)
26 uri = dom.documentElement.getAttribute('uri')
27 assert uri
29 tmp = tempfile.NamedTemporaryFile(prefix = 'test-')
30 try:
31 tmp.write(xml)
32 tmp.flush()
33 iface = model.Interface(uri)
34 reader.update(iface, tmp.name, local = True)
35 return iface
36 finally:
37 tmp.close()
39 local_file = os.path.join(os.path.dirname(__file__), 'local.xml')
40 local_file_req = os.path.join(os.path.dirname(__file__), 'local-req.xml')
41 local_file_command = os.path.join(os.path.dirname(__file__), 'local-command.xml')
43 def tap(s):
44 #print s
45 return s
47 class TestLocal(unittest.TestCase):
48 def testCreate(self):
49 master = parse(create.create_from_local(local_file))
50 assert master.uri == 'http://test/hello.xml', master
51 assert len(master.implementations) == 1
53 def testMergeFirst(self):
54 master = parse(merge.merge(header + footer, local_file))
55 assert master.uri == 'http://test/hello.xml', master
56 assert len(master.implementations) == 1
58 def testMergeSecond(self):
59 master = parse(merge.merge(header + "<implementation id='sha1=123' version='1'/>" + footer, local_file))
60 assert master.uri == 'http://test/hello.xml', master
61 assert len(master.implementations) == 2
63 def testMergeGroup(self):
64 master = parse(merge.merge(header + "<group>\n <implementation id='sha1=123' version='1'/>\n </group>" + footer, local_file))
65 assert master.uri == 'http://test/hello.xml', master
66 assert len(master.implementations) == 2
67 assert master.implementations['sha1=002'].requires == []
69 def testMergeLocalReq(self):
70 master = parse(tap(merge.merge(header + "<group x='x'>\n <implementation id='sha1=123' version='1'/>\n </group>" + footer, local_file_req)))
71 assert master.uri == 'http://test/hello.xml', master
72 assert len(master.implementations) == 2
73 deps = master.implementations['sha1=003'].requires
74 assert len(deps) == 1
75 assert deps[0].interface == 'http://foo', deps[0]
77 assert master.implementations['sha1=003'].metadata['http://mynamespace/foo bob'] == 'bob'
79 def testNotSubset(self):
80 master = parse(merge.merge(header + "<group a='a'>\n <implementation id='sha1=123' version='1'/>\n </group>" + footer, local_file))
81 assert master.uri == 'http://test/hello.xml', master
82 assert len(master.implementations) == 2
83 assert master.implementations['sha1=123'].metadata.get('a', None) == 'a'
84 assert master.implementations['sha1=002'].metadata.get('a', None) == None
86 master = parse(merge.merge(header + """\n
87 <group>
88 <requires interface='http://foo' meta='foo'/>
89 <implementation id='sha1=004' version='1'/>
90 </group>
91 <group>
92 <requires interface='http://foo'>
93 <version before='1'/>
94 </requires>
95 <implementation id='sha1=001' version='1'/>
96 </group>""" + footer, local_file_req))
97 assert len(master.implementations['sha1=001'].requires[0].restrictions) == 1
98 assert len(master.implementations['sha1=003'].requires[0].restrictions) == 0
100 assert master.implementations['sha1=004'].requires[0].metadata.get('meta', None) == 'foo'
101 assert master.implementations['sha1=003'].requires[0].metadata.get('meta', None) == None
103 assert master.implementations['sha1=003'].main == 'hello'
105 def testMergeBest(self):
106 master_xml = merge.merge(header + """\n
107 <group>
108 <implementation id='sha1=123' version='1'/>
109 </group>
110 <group>
111 <requires interface='http://foo'/>
112 <implementation id='sha1=002' version='2'/>
113 </group>""" + footer, local_file_req)
114 master = parse(master_xml)
115 assert master.uri == 'http://test/hello.xml', master
116 assert len(master.implementations) == 3
117 deps = master.implementations['sha1=003'].requires
118 assert len(deps) == 1
119 assert deps[0].interface == 'http://foo', deps[0]
121 assert len(minidom.parseString(master_xml).documentElement.getElementsByTagNameNS(XMLNS_IFACE, 'group')) == 2
123 # Again, but with the groups the other way around
124 master_xml = merge.merge(header + """\n
125 <group>
126 <requires interface='http://foo'/>
127 <implementation id='sha1=002' version='2'/>
128 </group>
129 <group>
130 <implementation id='sha1=123' version='1'/>
131 </group>""" + footer, local_file_req)
132 master = parse(master_xml)
133 assert master.uri == 'http://test/hello.xml', master
134 assert len(master.implementations) == 3
135 deps = master.implementations['sha1=003'].requires
136 assert len(deps) == 1
137 assert deps[0].interface == 'http://foo', deps[0]
139 assert len(minidom.parseString(master_xml).documentElement.getElementsByTagNameNS(XMLNS_IFACE, 'group')) == 2
141 def testMergeCommand(self):
142 # We create a new group inside this one, sharing the <requires> and adding the <command>
143 master_xml = merge.merge(header + """
144 <group>
145 <requires interface='http://foo'>
146 <environment name='TESTING' value='true' mode='replace'/>
147 </requires>
148 <implementation id='sha1=002' version='2'/>
149 </group>""" + footer, local_file_command)
150 master = parse(master_xml)
151 assert master.uri == 'http://test/hello.xml', master
152 assert len(master.implementations) == 2
153 commands = master.implementations['sha1=003'].commands
154 assert len(commands) == 1
155 assert commands['run'].path == 'run.sh', commands['run'].path
157 new_root = minidom.parseString(master_xml).documentElement
158 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'group')) == 2
159 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'requires')) == 1
160 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'command')) == 1
162 # We create a new top-level group inside this one, as we can't share the test command
163 master_xml = merge.merge(header + """
164 <group>
165 <requires interface='http://foo'>
166 <environment name='TESTING' value='true' mode='replace'/>
167 </requires>
168 <command name='test' path='test.sh'/>
169 <implementation id='sha1=002' version='2'/>
170 </group>""" + footer, local_file_command)
171 master = parse(master_xml)
172 assert master.uri == 'http://test/hello.xml', master
173 assert len(master.implementations) == 2
174 commands = master.implementations['sha1=003'].commands
175 assert len(commands) == 1
176 assert commands['run'].path == 'run.sh', commands['run'].path
178 new_root = minidom.parseString(master_xml).documentElement
179 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'group')) == 2
180 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'requires')) == 2
181 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'command')) == 2
183 # We share the <requires> and override the <command>
184 master_xml = merge.merge(header + """
185 <group>
186 <requires interface='http://foo'>
187 <environment name='TESTING' value='true' mode='replace'/>
188 </requires>
189 <command name='run' path='old-run.sh'/>
190 <implementation id='sha1=002' version='2'/>
191 </group>""" + footer, local_file_command)
192 master = parse(master_xml)
193 assert master.uri == 'http://test/hello.xml', master
194 assert len(master.implementations) == 2
195 commands = master.implementations['sha1=003'].commands
196 assert len(commands) == 1
197 assert commands['run'].path == 'run.sh', commands['run'].path
199 new_root = minidom.parseString(master_xml).documentElement
200 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'group')) == 2
201 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'requires')) == 1
202 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'command')) == 2
204 # We share the <requires> and the <command>
205 master_xml = merge.merge(header + """
206 <group>
207 <requires interface='http://foo'>
208 <environment name='TESTING' value='true' mode='replace'/>
209 </requires>
210 <command name='run' path='run.sh'/>
211 <implementation id='sha1=002' version='2'/>
212 </group>""" + footer, local_file_command)
213 master = parse(master_xml)
214 assert master.uri == 'http://test/hello.xml', master
215 assert len(master.implementations) == 2
216 commands = master.implementations['sha1=003'].commands
217 assert len(commands) == 1
218 assert commands['run'].path == 'run.sh', commands['run'].path
220 new_root = minidom.parseString(master_xml).documentElement
221 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'group')) == 1
222 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'requires')) == 1
223 assert len(new_root.getElementsByTagNameNS(XMLNS_IFACE, 'command')) == 1
225 def testLocalContext(self):
226 def get_context(xml_frag):
227 doc = minidom.parseString(header + xml_frag + footer)
228 impls = list(doc.getElementsByTagNameNS(XMLNS_IFACE, 'implementation'))
229 assert len(impls) == 1
230 return merge.Context(impls[0])
232 ctx = get_context("<implementation id='sha1=001' version='1'/>")
233 assert ctx.attribs[(None, 'id')] == 'sha1=001'
234 assert ctx.attribs[(None, 'version')] == '1'
236 ctx = get_context("<group t='t' x='1' y:z='2' xmlns:y='yns'><implementation id='sha1=001' version='1' t='r'/></group>")
237 assert ctx.attribs[(None, 'id')] == 'sha1=001'
238 assert ctx.attribs[(None, 'version')] == '1'
239 assert ctx.attribs[(None, 't')] == 'r'
240 assert ctx.attribs[(None, 'x')] == '1'
241 assert ctx.attribs[('yns', 'z')] == '2'
243 def testSetAtttibs(self):
244 local_data = open(local_file).read()
245 result = release.set_attributes(local_data, '0.2', id = 'sha1=98765', version='3.7', main = None)
246 feed = model.ZeroInstallFeed(qdom.parse(StringIO.StringIO(str(result))), "local.xml")
247 assert len(feed.implementations) == 1
248 assert feed.implementations['sha1=98765'].get_version() == '3.7'
250 try:
251 result = release.set_attributes(local_data, '0.3', id = 'sha1=98765', version='3.7', main = None)
252 assert 0
253 except Exception, ex:
254 assert str(ex) == 'No implementations with version=0.3'
256 suite = unittest.makeSuite(TestLocal)
257 if __name__ == '__main__':
258 unittest.main()