Merge lp:~jml/pkgme-devportal/backend-tests into lp:pkgme-devportal
- backend-tests
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Jonathan Lange |
Approved revision: | 50 |
Merged at revision: | 31 |
Proposed branch: | lp:~jml/pkgme-devportal/backend-tests |
Merge into: | lp:pkgme-devportal |
Diff against target: |
827 lines (+300/-317) 6 files modified
devportalbinary/metadata.py (+17/-17) devportalbinary/testing.py (+28/-0) devportalbinary/tests/test_binary.py (+69/-14) devportalbinary/tests/test_binary_backend.py (+0/-151) devportalbinary/tests/test_metadata.py (+152/-42) devportalbinary/tests/test_pdf.py (+34/-93) |
To merge this branch: | bzr merge lp:~jml/pkgme-devportal/backend-tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Westby | Approve | ||
Review via email: mp+88365@code.launchpad.net |
Commit message
Refactor backend tests so there's less duplication.
Description of the change
This branch adds direct tests for the metadata backend, and then given that confidence, reconciles the tests for the PDF & binary backends to test the more direct methods. This results in less set up, fewer tests and faster tests.
More specifically:
* Merge test_binary and test_binary_backend
* Merge test_pdf and test_pdf_backend
* Change PDF & binary backend tests to exercise the get_{depends,
* Add tests for get_info, get_extra_files, and dump_json on MetadataBackend
* Remove the extra_files tests from PDF & binary backend suites, since they don't differ in behaviour
* Remove the package name tests from PDF & binary backend suites, since that's all handled by metadata backend
* Change get_desktop_file to take the executable, and made get_extra_files call get_executable
* Group the abstract methods in MetadataBackend
* Combined the desktop tests with the core metadata backend tests
* Extracted a base BackendTests class to reduce duplication
* Removed the HasField matcher, since it's now unused
Future work:
* Use composition instead of inheritance for the abstract backend methods
* Move get_install_file and get_metadata into MetadataBackend
Jonathan Lange (jml) wrote : | # |
On Thu, Jan 12, 2012 at 2:19 PM, James Westby <email address hidden> wrote:
> Review: Approve
>
> Hi,
>
> Great work, I particularly like that this speeds up the tests.
>
> I'm wondering if we want to lose a bit of that improvement for a couple
> of tests that exercise the backend like pkgme will (by executing the scripts)?
> They are simple, but I believe this change means they are untested?
>
> There are the acceptance tests though, so maybe that is sufficient?
>
I think the acceptance tests are sufficient here. Any tests we add
that exercise the backends via pkgme APIs are just duplicating the
acceptance tests and/or verifying that pkgme works or that we've
written our boilerplate scripts correctly.
jml
Preview Diff
1 | === modified file 'devportalbinary/metadata.py' |
2 | --- devportalbinary/metadata.py 2012-01-10 15:23:27 +0000 |
3 | +++ devportalbinary/metadata.py 2012-01-12 13:08:48 +0000 |
4 | @@ -111,21 +111,6 @@ |
5 | """Get the build dependencies of the package.""" |
6 | raise NotImplementedError(self.get_build_depends) |
7 | |
8 | - def get_desktop_file(self, package_name, tagline=None, categories=None): |
9 | - """Get the desktop file for the package. |
10 | - |
11 | - :return: A ``Desktop``. |
12 | - """ |
13 | - executable = self.get_executable(package_name) |
14 | - info = { |
15 | - PackageName.name: package_name, |
16 | - ApplicationName.name: package_name.capitalize(), |
17 | - Executable.name: executable, |
18 | - TagLine.name: tagline, |
19 | - Categories.name: categories, |
20 | - } |
21 | - return Desktop.from_info(DictInfo(info)) |
22 | - |
23 | def get_depends(self, metadata): |
24 | """Get the dependencies for the package.""" |
25 | raise NotImplementedError(self.depends) |
26 | @@ -138,6 +123,21 @@ |
27 | """Return the path to the executable.""" |
28 | raise NotImplementedError(self.get_executable) |
29 | |
30 | + def get_desktop_file(self, package_name, executable, tagline=None, |
31 | + categories=None): |
32 | + """Get the desktop file for the package. |
33 | + |
34 | + :return: A ``Desktop``. |
35 | + """ |
36 | + info = { |
37 | + PackageName.name: package_name, |
38 | + ApplicationName.name: package_name.capitalize(), |
39 | + Executable.name: executable, |
40 | + TagLine.name: tagline, |
41 | + Categories.name: categories, |
42 | + } |
43 | + return Desktop.from_info(DictInfo(info)) |
44 | + |
45 | def get_extra_files(self, package_name, metadata): |
46 | """Get the extra files for the package. |
47 | |
48 | @@ -146,8 +146,10 @@ |
49 | desktop file. |
50 | """ |
51 | install_file = get_install_file(package_name, self.path, True) |
52 | + executable = self.get_executable(package_name) |
53 | desktop_file = self.get_desktop_file( |
54 | package_name, |
55 | + executable, |
56 | tagline=metadata.get(self.TAGLINE, ''), |
57 | categories=metadata.get(self.CATEGORIES, '')) |
58 | return { |
59 | @@ -200,5 +202,3 @@ |
60 | def want(self): |
61 | """How relevant this backend is.""" |
62 | raise NotImplementedError(self.want) |
63 | - |
64 | - |
65 | |
66 | === modified file 'devportalbinary/testing.py' |
67 | --- devportalbinary/testing.py 2012-01-10 12:31:05 +0000 |
68 | +++ devportalbinary/testing.py 2012-01-12 13:08:48 +0000 |
69 | @@ -1,3 +1,6 @@ |
70 | +# Copyright 2011-2012 Canonical Ltd. This software is licensed under the |
71 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
72 | + |
73 | import json |
74 | import os |
75 | |
76 | @@ -6,6 +9,7 @@ |
77 | Fixture, |
78 | TempDir, |
79 | ) |
80 | +from testtools import TestCase |
81 | |
82 | from pkgme.testing import TempdirFixture |
83 | |
84 | @@ -80,3 +84,27 @@ |
85 | def get_test_data_file_path(dirname, filename): |
86 | """Get the path to a file in the test data.""" |
87 | return os.path.join(get_test_data_dir_path(dirname), filename) |
88 | + |
89 | + |
90 | +class BackendTests(TestCase): |
91 | + |
92 | + BACKEND = None |
93 | + |
94 | + def make_metadata(self, package_name=None, description=None, tagline=None, |
95 | + categories=None): |
96 | + if package_name is None: |
97 | + package_name = self.getUniqueString('package-name') |
98 | + metadata = {MetadataBackend.PACKAGE_NAME: package_name} |
99 | + if tagline is None: |
100 | + tagline = self.getUniqueString('tagline') |
101 | + metadata[MetadataBackend.TAGLINE] = tagline |
102 | + if description is not None: |
103 | + metadata[MetadataBackend.DESCRIPTION] = description |
104 | + if categories is not None: |
105 | + metadata[MetadataBackend.CATEGORIES] = categories |
106 | + return metadata |
107 | + |
108 | + def make_backend(self, path=None): |
109 | + if path is None: |
110 | + path = self.useFixture(TempdirFixture()).path |
111 | + return self.BACKEND(path) |
112 | |
113 | === modified file 'devportalbinary/tests/test_binary.py' |
114 | --- devportalbinary/tests/test_binary.py 2012-01-10 13:18:19 +0000 |
115 | +++ devportalbinary/tests/test_binary.py 2012-01-12 13:08:48 +0000 |
116 | @@ -2,6 +2,7 @@ |
117 | # GNU Affero General Public License version 3 (see the file LICENSE). |
118 | |
119 | import os |
120 | +import shutil |
121 | |
122 | from testtools import TestCase |
123 | from testtools.matchers import StartsWith |
124 | @@ -21,10 +22,15 @@ |
125 | NoBinariesFound, |
126 | UnknownDependency, |
127 | ) |
128 | +from devportalbinary.metadata import ( |
129 | + MetadataBackend, |
130 | + ) |
131 | from devportalbinary.testing import ( |
132 | + BackendTests, |
133 | DatabaseFixture, |
134 | get_test_data_dir_path, |
135 | get_test_data_file_path, |
136 | + MetadataFixture, |
137 | ) |
138 | |
139 | |
140 | @@ -34,20 +40,6 @@ |
141 | self.assertRaises(NoBinariesFound, needed_libraries_from_objdump, []) |
142 | |
143 | |
144 | -class BackendTests(TestCase): |
145 | - |
146 | - def test_executable_is_best_guess(self): |
147 | - package_name = self.getUniqueString() |
148 | - tempdir = self.useFixture(TempdirFixture()) |
149 | - tempdir.mkdir('whatever') |
150 | - tempdir.touch('whatever/not-the-best', 0755) |
151 | - tempdir.touch('the-best', 0755) |
152 | - backend = BinaryBackend(tempdir.path) |
153 | - self.assertEqual( |
154 | - '/opt/%s/the-best' % (package_name,), |
155 | - backend.get_executable(package_name)) |
156 | - |
157 | - |
158 | class FindExecutableTests(TestCase): |
159 | |
160 | def test_only_one_file_and_it_is_executable(self): |
161 | @@ -223,3 +215,66 @@ |
162 | e = self.assertRaises(UnknownDependency, |
163 | guess_dependencies, get_test_data_dir_path('hello')) |
164 | self.assertEqual('Can\'t find dependency for "libc.so.6".', str(e)) |
165 | + |
166 | + |
167 | +class BinaryBackendTests(BackendTests): |
168 | + |
169 | + BACKEND = BinaryBackend |
170 | + |
171 | + def test_want_with_metadata(self): |
172 | + # If we detect a binary, then we score 10. The way we determine if |
173 | + # something is a binary is if it has a devportal-metadata.json in its |
174 | + # top-level. |
175 | + path = self.useFixture(MetadataFixture({})).path |
176 | + backend = self.make_backend(path) |
177 | + self.assertEqual(10, backend.want()) |
178 | + |
179 | + def test_want_without_metadata(self): |
180 | + # If we do *not* detect a binary, then we score 0. The way we |
181 | + # determine if something is a binary is if it has a |
182 | + # devportal-metadata.json in its top-level. |
183 | + backend = self.make_backend() |
184 | + self.assertEqual(0, backend.want()) |
185 | + |
186 | + def test_description(self): |
187 | + # The binary backend uses the package description that's in the |
188 | + # metadata. |
189 | + expected_description = self.getUniqueString() |
190 | + backend = self.make_backend() |
191 | + description = backend.get_description( |
192 | + {MetadataBackend.DESCRIPTION: expected_description}) |
193 | + self.assertEqual(expected_description, description) |
194 | + |
195 | + def test_no_description(self): |
196 | + # If no description is provided in the metadata then the description |
197 | + # in the package info is just an empty string. |
198 | + backend = self.make_backend() |
199 | + description = backend.get_description({}) |
200 | + self.assertEqual('', description) |
201 | + |
202 | + def test_build_depends(self): |
203 | + # Make sure there's a database. |
204 | + backend = self.make_backend() |
205 | + shutil.copy( |
206 | + get_test_data_file_path('hello', 'hello'), backend.path) |
207 | + db = self.useFixture(DatabaseFixture()).db |
208 | + db.update_source_package('eglibc', [[('libc.so.6', 'libc6')]]) |
209 | + expected_deps = ', '.join(guess_dependencies(backend.path)) |
210 | + build_deps = backend.get_build_depends(None) |
211 | + self.assertEqual(expected_deps, build_deps) |
212 | + |
213 | + def test_depends(self): |
214 | + backend = self.make_backend() |
215 | + depends = backend.get_depends(None) |
216 | + self.assertEqual('${shlibs:Depends}, ${misc:Depends}', depends) |
217 | + |
218 | + def test_executable_is_best_guess(self): |
219 | + package_name = self.getUniqueString() |
220 | + tempdir = self.useFixture(TempdirFixture()) |
221 | + tempdir.mkdir('whatever') |
222 | + tempdir.touch('whatever/not-the-best', 0755) |
223 | + tempdir.touch('the-best', 0755) |
224 | + backend = self.make_backend(tempdir.path) |
225 | + self.assertEqual( |
226 | + '/opt/%s/the-best' % (package_name,), |
227 | + backend.get_executable(package_name)) |
228 | |
229 | === removed file 'devportalbinary/tests/test_binary_backend.py' |
230 | --- devportalbinary/tests/test_binary_backend.py 2012-01-10 15:23:27 +0000 |
231 | +++ devportalbinary/tests/test_binary_backend.py 1970-01-01 00:00:00 +0000 |
232 | @@ -1,151 +0,0 @@ |
233 | -# Copyright 2011 Canonical Ltd. This software is licensed under the |
234 | -# GNU Affero General Public License version 3 (see the file LICENSE). |
235 | - |
236 | -import shutil |
237 | - |
238 | -from fixtures import TempDir |
239 | -from testtools import TestCase |
240 | -from testtools.matchers import ( |
241 | - Equals, |
242 | - Matcher, |
243 | - ) |
244 | - |
245 | -from pkgme.info_elements import ( |
246 | - BuildDepends, |
247 | - Description, |
248 | - Depends, |
249 | - ExtraFiles, |
250 | - PackageName, |
251 | - ) |
252 | - |
253 | -from devportalbinary.binary import ( |
254 | - BinaryBackend, |
255 | - guess_dependencies, |
256 | - MetadataBackend, |
257 | - ) |
258 | -from devportalbinary.metadata import get_install_file |
259 | -from devportalbinary.testing import ( |
260 | - DatabaseFixture, |
261 | - get_test_data_file_path, |
262 | - MetadataFixture, |
263 | - ) |
264 | - |
265 | - |
266 | -class HasField(Matcher): |
267 | - """Matches if 'info' has a field with the given value.""" |
268 | - |
269 | - def __init__(self, field, field_value): |
270 | - super(HasField, self).__init__() |
271 | - self.field = field |
272 | - self.field_value = field_value |
273 | - |
274 | - def match(self, info): |
275 | - return Equals(self.field_value).match(info[self.field]) |
276 | - |
277 | - |
278 | -class BinaryBackendTests(TestCase): |
279 | - |
280 | - def make_metadata(self, package_name=None, description=None, tagline=None, |
281 | - categories=None): |
282 | - if package_name is None: |
283 | - package_name = self.getUniqueString('package-name') |
284 | - metadata = {MetadataBackend.PACKAGE_NAME: package_name} |
285 | - if description is not None: |
286 | - metadata[MetadataBackend.DESCRIPTION] = description |
287 | - if tagline is not None: |
288 | - metadata[MetadataBackend.TAGLINE] = tagline |
289 | - if categories is not None: |
290 | - metadata[MetadataBackend.CATEGORIES] = categories |
291 | - return metadata |
292 | - |
293 | - def make_backend(self, path=None): |
294 | - if path is None: |
295 | - path = self.useFixture(TempDir()).path |
296 | - backend = BinaryBackend(path) |
297 | - shutil.copy( |
298 | - get_test_data_file_path('hello', 'hello'), path) |
299 | - db = self.useFixture(DatabaseFixture()).db |
300 | - db.update_source_package('eglibc', [[('libc.so.6', 'libc6')]]) |
301 | - return backend |
302 | - |
303 | - def test_want_with_metadata(self): |
304 | - # If we detect a binary, then we score 10. The way we determine if |
305 | - # something is a binary is if it has a devportal-metadata.json in its |
306 | - # top-level. |
307 | - path = self.useFixture(MetadataFixture({})).path |
308 | - backend = self.make_backend(path) |
309 | - self.assertEqual(10, backend.want()) |
310 | - |
311 | - def test_want_without_metadata(self): |
312 | - # If we do *not* detect a binary, then we score 0. The way we |
313 | - # determine if something is a binary is if it has a |
314 | - # devportal-metadata.json in its top-level. |
315 | - backend = self.make_backend() |
316 | - self.assertEqual(0, backend.want()) |
317 | - |
318 | - def test_package_name(self): |
319 | - # The binary backend gets the package name from the metadata file. |
320 | - backend = self.make_backend() |
321 | - metadata = self.make_metadata(package_name='foo') |
322 | - info = backend.get_info(metadata) |
323 | - self.assertThat(info, HasField(PackageName, 'foo')) |
324 | - |
325 | - def test_description(self): |
326 | - # The binary backend uses the package description that's in the |
327 | - # metadata. |
328 | - description = self.getUniqueString() |
329 | - metadata = self.make_metadata(description=description) |
330 | - backend = self.make_backend() |
331 | - info = backend.get_info(metadata) |
332 | - self.assertThat(info, HasField(Description, description)) |
333 | - |
334 | - def test_no_description(self): |
335 | - # If no description is provided in the metadata then the description |
336 | - # in the package info is just an empty string. |
337 | - backend = self.make_backend() |
338 | - metadata = self.make_metadata() |
339 | - info = backend.get_info(metadata) |
340 | - self.assertThat(info, HasField(Description, '')) |
341 | - |
342 | - def test_build_depends(self): |
343 | - # Make sure there's a database. |
344 | - backend = self.make_backend() |
345 | - info = backend.get_info(self.make_metadata()) |
346 | - deps = ', '.join(guess_dependencies(backend.path)) |
347 | - self.assertThat(info, HasField(BuildDepends, deps)) |
348 | - |
349 | - def test_depends(self): |
350 | - backend = self.make_backend() |
351 | - info = backend.get_info(self.make_metadata()) |
352 | - self.assertThat(info, HasField(Depends, BinaryBackend.DEPENDS)) |
353 | - |
354 | - def test_extra_files_install_file(self): |
355 | - # We create an 'install' file that tells debhelper to just copy |
356 | - # everything to opt. |
357 | - package_name = self.getUniqueString() |
358 | - metadata = self.make_metadata(package_name=package_name) |
359 | - backend = self.make_backend() |
360 | - info = backend.get_info(metadata) |
361 | - install_file = info[ExtraFiles]['debian/install'] |
362 | - self.assertEqual( |
363 | - get_install_file(package_name, backend.path, True), |
364 | - install_file) |
365 | - |
366 | - def test_extra_files_desktop_file(self): |
367 | - # We create an 'desktop' file that launches the guessed binary |
368 | - package_name = self.getUniqueString() |
369 | - tagline = self.getUniqueString() |
370 | - categories = self.getUniqueString() |
371 | - metadata = self.make_metadata( |
372 | - package_name=package_name, |
373 | - tagline=tagline, |
374 | - categories=categories, |
375 | - ) |
376 | - backend = self.make_backend() |
377 | - expected_desktop_file = backend.get_desktop_file( |
378 | - package_name, tagline=tagline, |
379 | - categories=categories).get_contents() |
380 | - info = backend.get_info(metadata) |
381 | - extra_files = info[ExtraFiles] |
382 | - desktop = extra_files['debian/%s.desktop' % (package_name,)] |
383 | - self.assertEqual(expected_desktop_file, desktop) |
384 | |
385 | === modified file 'devportalbinary/tests/test_metadata.py' |
386 | --- devportalbinary/tests/test_metadata.py 2012-01-10 13:18:19 +0000 |
387 | +++ devportalbinary/tests/test_metadata.py 2012-01-12 13:08:48 +0000 |
388 | @@ -1,8 +1,18 @@ |
389 | # Copyright 2011-2012 Canonical Ltd. This software is licensed under the |
390 | # GNU Affero General Public License version 3 (see the file LICENSE). |
391 | |
392 | +import json |
393 | +from StringIO import StringIO |
394 | import os |
395 | |
396 | +from pkgme.info_elements import ( |
397 | + Architecture, |
398 | + BuildDepends, |
399 | + Description, |
400 | + Depends, |
401 | + ExtraFiles, |
402 | + PackageName, |
403 | + ) |
404 | from pkgme.package_files import DEBIAN_DIR |
405 | from pkgme.testing import ( |
406 | AreDesktopValuesFor, |
407 | @@ -16,11 +26,14 @@ |
408 | MetadataBackend, |
409 | ) |
410 | from devportalbinary.testing import ( |
411 | + BackendTests, |
412 | MetadataFixture, |
413 | ) |
414 | |
415 | |
416 | -class MetadataTests(TestCase): |
417 | +class MetadataTests(BackendTests): |
418 | + |
419 | + BACKEND = MetadataBackend |
420 | |
421 | def test_metadata_file(self): |
422 | self.assertEqual('devportal-metadata.json', MetadataBackend.METADATA_FILE) |
423 | @@ -76,6 +89,144 @@ |
424 | found_metadata = get_metadata(path=path) |
425 | self.assertEqual(metadata, found_metadata) |
426 | |
427 | + def test_dump_json(self): |
428 | + # dump_json loads metadata, passes it to get_info and then dumps |
429 | + # whatever that returns. This means that get_info(metadata) can be a |
430 | + # relatively pure function, obsessed only with figuring out the right |
431 | + # packaging information. |
432 | + metadata = {'foo': 'bar'} |
433 | + path = self.useFixture(MetadataFixture(metadata)).path |
434 | + backend = MetadataBackend(path) |
435 | + # get_info takes metadata and returns a dict mapping InfoElements to |
436 | + # values. We're using PackageName here arbitrarily. |
437 | + backend.get_info = lambda metadata: {PackageName: metadata} |
438 | + output_buffer = StringIO() |
439 | + backend.dump_json(output_buffer) |
440 | + # The resulting JSON maps the names of the InfoElements to values. |
441 | + self.assertEqual( |
442 | + {PackageName.name: metadata}, |
443 | + json.loads(output_buffer.getvalue())) |
444 | + |
445 | + def test_get_extra_files_install_file(self): |
446 | + # ExtraFiles includes an install file generated by get_install_file. |
447 | + package_name = self.getUniqueString() |
448 | + metadata = {MetadataBackend.PACKAGE_NAME: package_name} |
449 | + backend = self.make_backend() |
450 | + backend.get_executable = lambda x: x |
451 | + extra_files = backend.get_extra_files(package_name, metadata) |
452 | + install_file = extra_files['debian/install'] |
453 | + self.assertEqual( |
454 | + get_install_file(package_name, backend.path, True), |
455 | + install_file) |
456 | + |
457 | + def test_extra_files_desktop_file(self): |
458 | + # ExtraFiles includes a desktop file, named after the package, that is |
459 | + # generated using get_desktop_file on the backend. |
460 | + package_name = self.getUniqueString() |
461 | + tagline = self.getUniqueString() |
462 | + categories = self.getUniqueString() |
463 | + metadata = self.make_metadata( |
464 | + package_name=package_name, |
465 | + tagline=tagline, |
466 | + categories=categories, |
467 | + ) |
468 | + backend = self.make_backend() |
469 | + backend.get_executable = lambda x: 'executable:' + x |
470 | + expected_desktop_file = backend.get_desktop_file( |
471 | + package_name, backend.get_executable(package_name), |
472 | + tagline=tagline, categories=categories).get_contents() |
473 | + extra_files = backend.get_extra_files(package_name, metadata) |
474 | + desktop = extra_files['debian/%s.desktop' % (package_name,)] |
475 | + self.assertEqual(expected_desktop_file, desktop) |
476 | + |
477 | + def test_get_info_with_architecture(self): |
478 | + # get_info consults various methods on the backend class and uses |
479 | + # those to figure out the info to return. |
480 | + class Backend(MetadataBackend): |
481 | + def get_architecture(self): |
482 | + return 'architecture' |
483 | + def get_build_depends(self, metadata): |
484 | + return 'build_depends', metadata |
485 | + def get_depends(self, metadata): |
486 | + return 'depends', metadata |
487 | + def get_description(self, metadata): |
488 | + return 'description', metadata |
489 | + def get_executable(self, package_name): |
490 | + return 'executable:' + package_name |
491 | + |
492 | + package_name = self.getUniqueString('package-name') |
493 | + metadata = self.make_metadata(package_name=package_name) |
494 | + backend = Backend(self.useFixture(TempdirFixture()).path) |
495 | + info = backend.get_info(metadata) |
496 | + self.assertEqual( |
497 | + {Architecture: 'architecture', |
498 | + BuildDepends: ('build_depends', metadata), |
499 | + Depends: ('depends', metadata), |
500 | + Description: ('description', metadata), |
501 | + ExtraFiles: backend.get_extra_files(package_name, metadata), |
502 | + PackageName: package_name}, info) |
503 | + |
504 | + def test_get_info_without_architecture(self): |
505 | + # get_info consults various methods on the backend class and uses |
506 | + # those to figure out the info to return. If get_architecture returns |
507 | + # None, then it is excluded from the info. |
508 | + class Backend(MetadataBackend): |
509 | + def get_architecture(self): |
510 | + return None |
511 | + def get_build_depends(self, metadata): |
512 | + return 'build_depends', metadata |
513 | + def get_depends(self, metadata): |
514 | + return 'depends', metadata |
515 | + def get_description(self, metadata): |
516 | + return 'description', metadata |
517 | + def get_executable(self, package_name): |
518 | + return 'executable:' + package_name |
519 | + |
520 | + package_name = self.getUniqueString('package-name') |
521 | + metadata = self.make_metadata(package_name=package_name) |
522 | + backend = Backend(self.useFixture(TempdirFixture()).path) |
523 | + info = backend.get_info(metadata) |
524 | + self.assertEqual( |
525 | + {BuildDepends: ('build_depends', metadata), |
526 | + Depends: ('depends', metadata), |
527 | + Description: ('description', metadata), |
528 | + ExtraFiles: backend.get_extra_files(package_name, metadata), |
529 | + PackageName: package_name}, info) |
530 | + |
531 | + def test_app_name_is_capitalized_package_name(self): |
532 | + # We don't have any information on the package name, so try to guess |
533 | + # the application name. |
534 | + backend = self.make_backend() |
535 | + package_name = self.getUniqueString() |
536 | + executable = self.getUniqueString() |
537 | + desktop_file = backend.get_desktop_file(package_name, executable) |
538 | + self.assertThat( |
539 | + {'Name': package_name.capitalize()}, |
540 | + AreDesktopValuesFor(desktop_file)) |
541 | + |
542 | + def test_category_and_tagline_are_specified(self): |
543 | + # We just pass the category and comment through. |
544 | + package_name = self.getUniqueString() |
545 | + executable = self.getUniqueString() |
546 | + tagline = self.getUniqueString() |
547 | + categories = self.getUniqueString() |
548 | + backend = self.make_backend() |
549 | + desktop_file = backend.get_desktop_file( |
550 | + package_name, executable, tagline=tagline, categories=categories) |
551 | + self.assertThat( |
552 | + {'Comment': tagline, 'Categories': categories}, |
553 | + AreDesktopValuesFor(desktop_file)) |
554 | + |
555 | + def test_executable(self): |
556 | + # The executable in the desktop file is just whatever get_desktop |
557 | + # returns. |
558 | + package_name = self.getUniqueString() |
559 | + executable = self.getUniqueString() |
560 | + backend = self.make_backend() |
561 | + desktop_file = backend.get_desktop_file(package_name, executable) |
562 | + self.assertThat( |
563 | + {'Exec': executable}, AreDesktopValuesFor(desktop_file)) |
564 | + |
565 | |
566 | class InstallFileTests(TestCase): |
567 | |
568 | @@ -135,44 +286,3 @@ |
569 | "some-file opt/package-name\n" |
570 | "debian/package-name.desktop usr/share/applications\n", |
571 | install_file) |
572 | - |
573 | - |
574 | -class DesktopFileTests(TestCase): |
575 | - |
576 | - def make_backend(self, executable=None): |
577 | - tempdir = self.useFixture(TempdirFixture()) |
578 | - backend = MetadataBackend(tempdir.path) |
579 | - backend.get_executable = lambda package_name: executable |
580 | - return backend |
581 | - |
582 | - def test_app_name_is_capitalized_package_name(self): |
583 | - # We don't have any information on the package name, so try to guess |
584 | - # the application name. |
585 | - backend = self.make_backend() |
586 | - package_name = self.getUniqueString() |
587 | - desktop_file = backend.get_desktop_file(package_name) |
588 | - self.assertThat( |
589 | - {'Name': package_name.capitalize()}, |
590 | - AreDesktopValuesFor(desktop_file)) |
591 | - |
592 | - def test_category_and_tagline_are_specified(self): |
593 | - # We just pass the category and comment through. |
594 | - package_name = self.getUniqueString() |
595 | - tagline = self.getUniqueString() |
596 | - categories = self.getUniqueString() |
597 | - backend = self.make_backend() |
598 | - desktop_file = backend.get_desktop_file( |
599 | - package_name, tagline=tagline, categories=categories) |
600 | - self.assertThat( |
601 | - {'Comment': tagline, 'Categories': categories}, |
602 | - AreDesktopValuesFor(desktop_file)) |
603 | - |
604 | - def test_executable_from_get_executable(self): |
605 | - # The executable in the desktop file is just whatever get_desktop |
606 | - # returns. |
607 | - package_name = self.getUniqueString() |
608 | - executable = self.getUniqueString() |
609 | - backend = self.make_backend(executable) |
610 | - desktop_file = backend.get_desktop_file(package_name) |
611 | - self.assertThat( |
612 | - {'Exec': executable}, AreDesktopValuesFor(desktop_file)) |
613 | |
614 | === removed file 'devportalbinary/tests/test_pdf.py' |
615 | --- devportalbinary/tests/test_pdf.py 2012-01-10 13:18:19 +0000 |
616 | +++ devportalbinary/tests/test_pdf.py 1970-01-01 00:00:00 +0000 |
617 | @@ -1,21 +0,0 @@ |
618 | -# Copyright 2012 Canonical Ltd. This software is licensed under the |
619 | -# GNU Affero General Public License version 3 (see the file LICENSE). |
620 | - |
621 | -from testtools import TestCase |
622 | - |
623 | -from pkgme.testing import TempdirFixture |
624 | - |
625 | -from devportalbinary.pdf import PdfBackend |
626 | - |
627 | - |
628 | -class BackendTests(TestCase): |
629 | - |
630 | - def test_executable_opens_pdf(self): |
631 | - tempdir = self.useFixture(TempdirFixture()) |
632 | - tempdir.touch('foo.pdf') |
633 | - package_name = self.getUniqueString() |
634 | - backend = PdfBackend(tempdir.path) |
635 | - executable = backend.get_executable(package_name) |
636 | - self.assertEqual( |
637 | - '/usr/bin/xdg-open /opt/%s/%s' % (package_name, 'foo.pdf'), |
638 | - executable) |
639 | |
640 | === renamed file 'devportalbinary/tests/test_pdf_backend.py' => 'devportalbinary/tests/test_pdf.py' |
641 | --- devportalbinary/tests/test_pdf_backend.py 2012-01-10 12:50:21 +0000 |
642 | +++ devportalbinary/tests/test_pdf.py 2012-01-12 13:08:48 +0000 |
643 | @@ -1,40 +1,16 @@ |
644 | -# Copyright 2011 Canonical Ltd. This software is licensed under the |
645 | +# Copyright 2011-2012 Canonical Ltd. This software is licensed under the |
646 | # GNU Affero General Public License version 3 (see the file LICENSE). |
647 | |
648 | -from testtools import TestCase |
649 | - |
650 | -from pkgme.backend import ExternalHelpersBackend, get_backend_dir |
651 | -from pkgme.info_elements import ( |
652 | - Architecture, |
653 | - BuildDepends, |
654 | - Depends, |
655 | - Description, |
656 | - ExtraFiles, |
657 | - PackageName, |
658 | - ) |
659 | from pkgme.testing import TempdirFixture |
660 | |
661 | from devportalbinary.binary import MetadataBackend |
662 | from devportalbinary.pdf import PdfBackend |
663 | -from devportalbinary.metadata import get_install_file |
664 | -from devportalbinary.testing import MetadataFixture |
665 | - |
666 | - |
667 | -BACKEND_NAME = 'pdf' |
668 | - |
669 | -backend_dir = get_backend_dir(__file__, BACKEND_NAME) |
670 | - |
671 | - |
672 | -class PdfBackendTests(TestCase): |
673 | - |
674 | - def with_metadata(self, metadata=None): |
675 | - if metadata is None: |
676 | - metadata = {} |
677 | - metadata.setdefault( |
678 | - MetadataBackend.PACKAGE_NAME, self.getUniqueString('package_name')) |
679 | - metadata.setdefault( |
680 | - MetadataBackend.TAGLINE, self.getUniqueString('tagline')) |
681 | - return self.useFixture(MetadataFixture(metadata)) |
682 | +from devportalbinary.testing import BackendTests |
683 | + |
684 | + |
685 | +class PdfBackendTests(BackendTests): |
686 | + |
687 | + BACKEND = PdfBackend |
688 | |
689 | def test_want_with_metadata(self): |
690 | # If we detect the metadata file and a pdf, then we score 20. |
691 | @@ -42,23 +18,23 @@ |
692 | tempdir.touch(MetadataBackend.METADATA_FILE) |
693 | filename = self.getUniqueString() + ".pdf" |
694 | tempdir.touch(filename) |
695 | - backend = ExternalHelpersBackend(BACKEND_NAME, backend_dir) |
696 | - self.assertEqual(20, backend.want(tempdir.path)) |
697 | + backend = PdfBackend(tempdir.path) |
698 | + self.assertEqual(20, backend.want()) |
699 | |
700 | def test_want_with_just_metadata(self): |
701 | # If we detect just the metadata file then we score 0. |
702 | tempdir = self.useFixture(TempdirFixture()) |
703 | tempdir.touch(MetadataBackend.METADATA_FILE) |
704 | - backend = ExternalHelpersBackend(BACKEND_NAME, backend_dir) |
705 | - self.assertEqual(0, backend.want(tempdir.path)) |
706 | + backend = PdfBackend(tempdir.path) |
707 | + self.assertEqual(0, backend.want()) |
708 | |
709 | def test_want_with_just_pdf(self): |
710 | # If we detect just a pdf file then we score 0. |
711 | tempdir = self.useFixture(TempdirFixture()) |
712 | filename = self.getUniqueString() + ".pdf" |
713 | tempdir.touch(filename) |
714 | - backend = ExternalHelpersBackend(BACKEND_NAME, backend_dir) |
715 | - self.assertEqual(0, backend.want(tempdir.path)) |
716 | + backend = PdfBackend(tempdir.path) |
717 | + self.assertEqual(0, backend.want()) |
718 | |
719 | def test_want_with_extra_files(self): |
720 | # If we detect other files then we score 0. This is so that |
721 | @@ -70,8 +46,8 @@ |
722 | tempdir.touch(filename) |
723 | other_filename = self.getUniqueString() + ".foo" |
724 | tempdir.touch(other_filename) |
725 | - backend = ExternalHelpersBackend(BACKEND_NAME, backend_dir) |
726 | - self.assertEqual(0, backend.want(tempdir.path)) |
727 | + backend = PdfBackend(tempdir.path) |
728 | + self.assertEqual(0, backend.want()) |
729 | |
730 | def test_want_with_debian_dir(self): |
731 | # If the other file is a debian dir then we score 20 still. |
732 | @@ -82,76 +58,41 @@ |
733 | tempdir.touch(filename) |
734 | other_filename = "debian" |
735 | tempdir.touch(other_filename) |
736 | - backend = ExternalHelpersBackend(BACKEND_NAME, backend_dir) |
737 | - self.assertEqual(20, backend.want(tempdir.path)) |
738 | - |
739 | - def test_package_name(self): |
740 | - # The pdf backend gets the package name from the metadata file. |
741 | - path = self.with_metadata({MetadataBackend.PACKAGE_NAME: 'foo'}).path |
742 | - package_name = self.get_info_for(BACKEND_NAME, PackageName, path) |
743 | - self.assertEqual("foo", package_name) |
744 | + backend = PdfBackend(tempdir.path) |
745 | + self.assertEqual(20, backend.want()) |
746 | |
747 | def test_architecture(self): |
748 | # The pdf backend set architecture to all |
749 | - path = self.with_metadata().path |
750 | - architecture = self.get_info_for(BACKEND_NAME, Architecture, path) |
751 | - self.assertEqual("all", architecture) |
752 | - |
753 | - def get_info_for(self, backend_name, info_element, path): |
754 | - backend = ExternalHelpersBackend(backend_name, backend_dir) |
755 | - info = backend.get_info(path) |
756 | - return info.get_all([info_element.name])[info_element.name] |
757 | + backend = self.make_backend() |
758 | + architecture = backend.get_architecture() |
759 | + self.assertEqual('all', architecture) |
760 | |
761 | def test_build_depends(self): |
762 | # The pdf backend has simple build dependencies |
763 | - path = self.with_metadata().path |
764 | - build_depends = self.get_info_for(BACKEND_NAME, BuildDepends, path) |
765 | + backend = self.make_backend() |
766 | + build_depends = backend.get_build_depends(None) |
767 | self.assertEqual('debhelper (>=7)', build_depends) |
768 | |
769 | def test_depends(self): |
770 | # The pdf backend depends on xdg-utils |
771 | - path = self.with_metadata().path |
772 | - depends = self.get_info_for(BACKEND_NAME, Depends, path) |
773 | + backend = self.make_backend() |
774 | + depends = backend.get_depends(None) |
775 | self.assertEqual('xdg-utils, ${misc:Depends}', depends) |
776 | |
777 | def test_description(self): |
778 | # The pdf backend gets the description from the metadata file. |
779 | expected_description = 'best pdf evar' |
780 | - path = self.with_metadata( |
781 | - {MetadataBackend.TAGLINE: expected_description}).path |
782 | - description = self.get_info_for(BACKEND_NAME, Description, path) |
783 | + metadata = {MetadataBackend.TAGLINE: expected_description} |
784 | + backend = self.make_backend() |
785 | + description = backend.get_description(metadata) |
786 | self.assertEqual(expected_description, description) |
787 | |
788 | - def test_extra_files_install_file(self): |
789 | - # We create an 'install' file that tells debhelper to copy |
790 | - # the pdf to opt |
791 | + def test_executable_opens_pdf(self): |
792 | + tempdir = self.useFixture(TempdirFixture()) |
793 | + tempdir.touch('foo.pdf') |
794 | package_name = self.getUniqueString() |
795 | - tempdir = self.with_metadata( |
796 | - {MetadataBackend.PACKAGE_NAME: package_name}).tempdir |
797 | - extra_files = self.get_info_for(BACKEND_NAME, ExtraFiles, tempdir.path) |
798 | - install_file = extra_files['debian/install'] |
799 | + backend = PdfBackend(tempdir.path) |
800 | + executable = backend.get_executable(package_name) |
801 | self.assertEqual( |
802 | - get_install_file(package_name, tempdir.path, True), |
803 | - install_file) |
804 | - |
805 | - def test_extra_files_desktop_file(self): |
806 | - # We create an 'desktop' file that uses xdg-open to open the |
807 | - # pdf. |
808 | - package_name = self.getUniqueString() |
809 | - tagline = self.getUniqueString() |
810 | - categories = self.getUniqueString() |
811 | - metadata = { |
812 | - MetadataBackend.PACKAGE_NAME: package_name, |
813 | - MetadataBackend.TAGLINE: tagline, |
814 | - MetadataBackend.CATEGORIES: categories, |
815 | - } |
816 | - tempdir = self.with_metadata(metadata).tempdir |
817 | - # We need to create a pdf file in order to be able to generate a |
818 | - # desktop. |
819 | - tempdir.touch('foo.pdf') |
820 | - expected_desktop_file = PdfBackend(tempdir.path).get_desktop_file( |
821 | - package_name, tagline=tagline, |
822 | - categories=categories).get_contents() |
823 | - extra_files = self.get_info_for(BACKEND_NAME, ExtraFiles, tempdir.path) |
824 | - desktop = extra_files['debian/%s.desktop' % (package_name,)] |
825 | - self.assertEqual(expected_desktop_file, desktop) |
826 | + '/usr/bin/xdg-open /opt/%s/%s' % (package_name, 'foo.pdf'), |
827 | + executable) |
Hi,
Great work, I particularly like that this speeds up the tests.
I'm wondering if we want to lose a bit of that improvement for a couple
of tests that exercise the backend like pkgme will (by executing the scripts)?
They are simple, but I believe this change means they are untested?
There are the acceptance tests though, so maybe that is sufficient?
Thanks,
James