Mercurial > repos > melissacline > ucsc_xena_platform
comparison python-daemon-2.0.5/test_version.py @ 33:7ceb967147c3
start xena with no gui
add library files
| author | jingchunzhu <jingchunzhu@gmail.com> |
|---|---|
| date | Wed, 22 Jul 2015 13:24:44 -0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 32:63b1ba1e3424 | 33:7ceb967147c3 |
|---|---|
| 1 # -*- coding: utf-8 -*- | |
| 2 # | |
| 3 # test_version.py | |
| 4 # Part of ‘python-daemon’, an implementation of PEP 3143. | |
| 5 # | |
| 6 # Copyright © 2008–2015 Ben Finney <ben+python@benfinney.id.au> | |
| 7 # | |
| 8 # This is free software: you may copy, modify, and/or distribute this work | |
| 9 # under the terms of the GNU General Public License as published by the | |
| 10 # Free Software Foundation; version 3 of that license or any later version. | |
| 11 # No warranty expressed or implied. See the file ‘LICENSE.GPL-3’ for details. | |
| 12 | |
| 13 """ Unit test for ‘version’ packaging module. """ | |
| 14 | |
| 15 from __future__ import (absolute_import, unicode_literals) | |
| 16 | |
| 17 import os | |
| 18 import os.path | |
| 19 import io | |
| 20 import errno | |
| 21 import functools | |
| 22 import collections | |
| 23 import textwrap | |
| 24 import json | |
| 25 import tempfile | |
| 26 import distutils.dist | |
| 27 import distutils.cmd | |
| 28 import distutils.errors | |
| 29 import distutils.fancy_getopt | |
| 30 try: | |
| 31 # Standard library of Python 2.7 and later. | |
| 32 from io import StringIO | |
| 33 except ImportError: | |
| 34 # Standard library of Python 2.6 and earlier. | |
| 35 from StringIO import StringIO | |
| 36 | |
| 37 import mock | |
| 38 import testtools | |
| 39 import testscenarios | |
| 40 import docutils | |
| 41 import docutils.writers | |
| 42 import docutils.nodes | |
| 43 import setuptools | |
| 44 import setuptools.command | |
| 45 | |
| 46 import version | |
| 47 | |
| 48 version.ensure_class_bases_begin_with( | |
| 49 version.__dict__, str('VersionInfoWriter'), docutils.writers.Writer) | |
| 50 version.ensure_class_bases_begin_with( | |
| 51 version.__dict__, str('VersionInfoTranslator'), | |
| 52 docutils.nodes.SparseNodeVisitor) | |
| 53 | |
| 54 | |
| 55 def make_test_classes_for_ensure_class_bases_begin_with(): | |
| 56 """ Make test classes for use with ‘ensure_class_bases_begin_with’. | |
| 57 | |
| 58 :return: Mapping {`name`: `type`} of the custom types created. | |
| 59 | |
| 60 """ | |
| 61 | |
| 62 class quux_metaclass(type): | |
| 63 def __new__(metaclass, name, bases, namespace): | |
| 64 return super(quux_metaclass, metaclass).__new__( | |
| 65 metaclass, name, bases, namespace) | |
| 66 | |
| 67 class Foo(object): | |
| 68 __metaclass__ = type | |
| 69 | |
| 70 class Bar(object): | |
| 71 pass | |
| 72 | |
| 73 class FooInheritingBar(Bar): | |
| 74 __metaclass__ = type | |
| 75 | |
| 76 class FooWithCustomMetaclass(object): | |
| 77 __metaclass__ = quux_metaclass | |
| 78 | |
| 79 result = dict( | |
| 80 (name, value) for (name, value) in locals().items() | |
| 81 if isinstance(value, type)) | |
| 82 | |
| 83 return result | |
| 84 | |
| 85 class ensure_class_bases_begin_with_TestCase( | |
| 86 testscenarios.WithScenarios, testtools.TestCase): | |
| 87 """ Test cases for ‘ensure_class_bases_begin_with’ function. """ | |
| 88 | |
| 89 test_classes = make_test_classes_for_ensure_class_bases_begin_with() | |
| 90 | |
| 91 scenarios = [ | |
| 92 ('simple', { | |
| 93 'test_class': test_classes['Foo'], | |
| 94 'base_class': test_classes['Bar'], | |
| 95 }), | |
| 96 ('custom metaclass', { | |
| 97 'test_class': test_classes['FooWithCustomMetaclass'], | |
| 98 'base_class': test_classes['Bar'], | |
| 99 'expected_metaclass': test_classes['quux_metaclass'], | |
| 100 }), | |
| 101 ] | |
| 102 | |
| 103 def setUp(self): | |
| 104 """ Set up test fixtures. """ | |
| 105 super(ensure_class_bases_begin_with_TestCase, self).setUp() | |
| 106 | |
| 107 self.class_name = self.test_class.__name__ | |
| 108 self.test_module_namespace = {self.class_name: self.test_class} | |
| 109 | |
| 110 if not hasattr(self, 'expected_metaclass'): | |
| 111 self.expected_metaclass = type | |
| 112 | |
| 113 patcher_metaclass = mock.patch.object( | |
| 114 self.test_class, '__metaclass__') | |
| 115 patcher_metaclass.start() | |
| 116 self.addCleanup(patcher_metaclass.stop) | |
| 117 | |
| 118 self.fake_new_class = type(object) | |
| 119 self.test_class.__metaclass__.return_value = ( | |
| 120 self.fake_new_class) | |
| 121 | |
| 122 def test_module_namespace_contains_new_class(self): | |
| 123 """ Specified module namespace should have new class. """ | |
| 124 version.ensure_class_bases_begin_with( | |
| 125 self.test_module_namespace, self.class_name, self.base_class) | |
| 126 self.assertIn(self.fake_new_class, self.test_module_namespace.values()) | |
| 127 | |
| 128 def test_calls_metaclass_with_expected_class_name(self): | |
| 129 """ Should call the metaclass with the expected class name. """ | |
| 130 version.ensure_class_bases_begin_with( | |
| 131 self.test_module_namespace, self.class_name, self.base_class) | |
| 132 expected_class_name = self.class_name | |
| 133 self.test_class.__metaclass__.assert_called_with( | |
| 134 expected_class_name, mock.ANY, mock.ANY) | |
| 135 | |
| 136 def test_calls_metaclass_with_expected_bases(self): | |
| 137 """ Should call the metaclass with the expected bases. """ | |
| 138 version.ensure_class_bases_begin_with( | |
| 139 self.test_module_namespace, self.class_name, self.base_class) | |
| 140 expected_bases = tuple( | |
| 141 [self.base_class] | |
| 142 + list(self.test_class.__bases__)) | |
| 143 self.test_class.__metaclass__.assert_called_with( | |
| 144 mock.ANY, expected_bases, mock.ANY) | |
| 145 | |
| 146 def test_calls_metaclass_with_expected_namespace(self): | |
| 147 """ Should call the metaclass with the expected class namespace. """ | |
| 148 version.ensure_class_bases_begin_with( | |
| 149 self.test_module_namespace, self.class_name, self.base_class) | |
| 150 expected_namespace = self.test_class.__dict__.copy() | |
| 151 del expected_namespace['__dict__'] | |
| 152 self.test_class.__metaclass__.assert_called_with( | |
| 153 mock.ANY, mock.ANY, expected_namespace) | |
| 154 | |
| 155 | |
| 156 class ensure_class_bases_begin_with_AlreadyHasBase_TestCase( | |
| 157 testscenarios.WithScenarios, testtools.TestCase): | |
| 158 """ Test cases for ‘ensure_class_bases_begin_with’ function. | |
| 159 | |
| 160 These test cases test the conditions where the class's base is | |
| 161 already the specified base class. | |
| 162 | |
| 163 """ | |
| 164 | |
| 165 test_classes = make_test_classes_for_ensure_class_bases_begin_with() | |
| 166 | |
| 167 scenarios = [ | |
| 168 ('already Bar subclass', { | |
| 169 'test_class': test_classes['FooInheritingBar'], | |
| 170 'base_class': test_classes['Bar'], | |
| 171 }), | |
| 172 ] | |
| 173 | |
| 174 def setUp(self): | |
| 175 """ Set up test fixtures. """ | |
| 176 super( | |
| 177 ensure_class_bases_begin_with_AlreadyHasBase_TestCase, | |
| 178 self).setUp() | |
| 179 | |
| 180 self.class_name = self.test_class.__name__ | |
| 181 self.test_module_namespace = {self.class_name: self.test_class} | |
| 182 | |
| 183 patcher_metaclass = mock.patch.object( | |
| 184 self.test_class, '__metaclass__') | |
| 185 patcher_metaclass.start() | |
| 186 self.addCleanup(patcher_metaclass.stop) | |
| 187 | |
| 188 def test_metaclass_not_called(self): | |
| 189 """ Should not call metaclass to create a new type. """ | |
| 190 version.ensure_class_bases_begin_with( | |
| 191 self.test_module_namespace, self.class_name, self.base_class) | |
| 192 self.assertFalse(self.test_class.__metaclass__.called) | |
| 193 | |
| 194 | |
| 195 class VersionInfoWriter_TestCase(testtools.TestCase): | |
| 196 """ Test cases for ‘VersionInfoWriter’ class. """ | |
| 197 | |
| 198 def setUp(self): | |
| 199 """ Set up test fixtures. """ | |
| 200 super(VersionInfoWriter_TestCase, self).setUp() | |
| 201 | |
| 202 self.test_instance = version.VersionInfoWriter() | |
| 203 | |
| 204 def test_declares_version_info_support(self): | |
| 205 """ Should declare support for ‘version_info’. """ | |
| 206 instance = self.test_instance | |
| 207 expected_support = "version_info" | |
| 208 result = instance.supports(expected_support) | |
| 209 self.assertTrue(result) | |
| 210 | |
| 211 | |
| 212 class VersionInfoWriter_translate_TestCase(testtools.TestCase): | |
| 213 """ Test cases for ‘VersionInfoWriter.translate’ method. """ | |
| 214 | |
| 215 def setUp(self): | |
| 216 """ Set up test fixtures. """ | |
| 217 super(VersionInfoWriter_translate_TestCase, self).setUp() | |
| 218 | |
| 219 patcher_translator = mock.patch.object( | |
| 220 version, 'VersionInfoTranslator') | |
| 221 self.mock_class_translator = patcher_translator.start() | |
| 222 self.addCleanup(patcher_translator.stop) | |
| 223 self.mock_translator = self.mock_class_translator.return_value | |
| 224 | |
| 225 self.test_instance = version.VersionInfoWriter() | |
| 226 patcher_document = mock.patch.object( | |
| 227 self.test_instance, 'document') | |
| 228 patcher_document.start() | |
| 229 self.addCleanup(patcher_document.stop) | |
| 230 | |
| 231 def test_creates_translator_with_document(self): | |
| 232 """ Should create a translator with the writer's document. """ | |
| 233 instance = self.test_instance | |
| 234 expected_document = self.test_instance.document | |
| 235 instance.translate() | |
| 236 self.mock_class_translator.assert_called_with(expected_document) | |
| 237 | |
| 238 def test_calls_document_walkabout_with_translator(self): | |
| 239 """ Should call document.walkabout with the translator. """ | |
| 240 instance = self.test_instance | |
| 241 instance.translate() | |
| 242 instance.document.walkabout.assert_called_with(self.mock_translator) | |
| 243 | |
| 244 def test_output_from_translator_astext(self): | |
| 245 """ Should have output from translator.astext(). """ | |
| 246 instance = self.test_instance | |
| 247 instance.translate() | |
| 248 expected_output = self.mock_translator.astext.return_value | |
| 249 self.assertEqual(expected_output, instance.output) | |
| 250 | |
| 251 | |
| 252 class ChangeLogEntry_TestCase(testtools.TestCase): | |
| 253 """ Test cases for ‘ChangeLogEntry’ class. """ | |
| 254 | |
| 255 def setUp(self): | |
| 256 """ Set up test fixtures. """ | |
| 257 super(ChangeLogEntry_TestCase, self).setUp() | |
| 258 | |
| 259 self.test_instance = version.ChangeLogEntry() | |
| 260 | |
| 261 def test_instantiate(self): | |
| 262 """ New instance of ‘ChangeLogEntry’ should be created. """ | |
| 263 self.assertIsInstance( | |
| 264 self.test_instance, version.ChangeLogEntry) | |
| 265 | |
| 266 def test_minimum_zero_arguments(self): | |
| 267 """ Initialiser should not require any arguments. """ | |
| 268 instance = version.ChangeLogEntry() | |
| 269 self.assertIsNot(instance, None) | |
| 270 | |
| 271 | |
| 272 class ChangeLogEntry_release_date_TestCase( | |
| 273 testscenarios.WithScenarios, testtools.TestCase): | |
| 274 """ Test cases for ‘ChangeLogEntry.release_date’ attribute. """ | |
| 275 | |
| 276 scenarios = [ | |
| 277 ('default', { | |
| 278 'test_args': {}, | |
| 279 'expected_release_date': | |
| 280 version.ChangeLogEntry.default_release_date, | |
| 281 }), | |
| 282 ('unknown token', { | |
| 283 'test_args': {'release_date': "UNKNOWN"}, | |
| 284 'expected_release_date': "UNKNOWN", | |
| 285 }), | |
| 286 ('future token', { | |
| 287 'test_args': {'release_date': "FUTURE"}, | |
| 288 'expected_release_date': "FUTURE", | |
| 289 }), | |
| 290 ('2001-01-01', { | |
| 291 'test_args': {'release_date': "2001-01-01"}, | |
| 292 'expected_release_date': "2001-01-01", | |
| 293 }), | |
| 294 ('bogus', { | |
| 295 'test_args': {'release_date': "b0gUs"}, | |
| 296 'expected_error': ValueError, | |
| 297 }), | |
| 298 ] | |
| 299 | |
| 300 def test_has_expected_release_date(self): | |
| 301 """ Should have default `release_date` attribute. """ | |
| 302 if hasattr(self, 'expected_error'): | |
| 303 self.assertRaises( | |
| 304 self.expected_error, | |
| 305 version.ChangeLogEntry, **self.test_args) | |
| 306 else: | |
| 307 instance = version.ChangeLogEntry(**self.test_args) | |
| 308 self.assertEqual(self.expected_release_date, instance.release_date) | |
| 309 | |
| 310 | |
| 311 class ChangeLogEntry_version_TestCase( | |
| 312 testscenarios.WithScenarios, testtools.TestCase): | |
| 313 """ Test cases for ‘ChangeLogEntry.version’ attribute. """ | |
| 314 | |
| 315 scenarios = [ | |
| 316 ('default', { | |
| 317 'test_args': {}, | |
| 318 'expected_version': | |
| 319 version.ChangeLogEntry.default_version, | |
| 320 }), | |
| 321 ('unknown token', { | |
| 322 'test_args': {'version': "UNKNOWN"}, | |
| 323 'expected_version': "UNKNOWN", | |
| 324 }), | |
| 325 ('0.0', { | |
| 326 'test_args': {'version': "0.0"}, | |
| 327 'expected_version': "0.0", | |
| 328 }), | |
| 329 ] | |
| 330 | |
| 331 def test_has_expected_version(self): | |
| 332 """ Should have default `version` attribute. """ | |
| 333 instance = version.ChangeLogEntry(**self.test_args) | |
| 334 self.assertEqual(self.expected_version, instance.version) | |
| 335 | |
| 336 | |
| 337 class ChangeLogEntry_maintainer_TestCase( | |
| 338 testscenarios.WithScenarios, testtools.TestCase): | |
| 339 """ Test cases for ‘ChangeLogEntry.maintainer’ attribute. """ | |
| 340 | |
| 341 scenarios = [ | |
| 342 ('default', { | |
| 343 'test_args': {}, | |
| 344 'expected_maintainer': None, | |
| 345 }), | |
| 346 ('person', { | |
| 347 'test_args': {'maintainer': "Foo Bar <foo.bar@example.org>"}, | |
| 348 'expected_maintainer': "Foo Bar <foo.bar@example.org>", | |
| 349 }), | |
| 350 ('bogus', { | |
| 351 'test_args': {'maintainer': "b0gUs"}, | |
| 352 'expected_error': ValueError, | |
| 353 }), | |
| 354 ] | |
| 355 | |
| 356 def test_has_expected_maintainer(self): | |
| 357 """ Should have default `maintainer` attribute. """ | |
| 358 if hasattr(self, 'expected_error'): | |
| 359 self.assertRaises( | |
| 360 self.expected_error, | |
| 361 version.ChangeLogEntry, **self.test_args) | |
| 362 else: | |
| 363 instance = version.ChangeLogEntry(**self.test_args) | |
| 364 self.assertEqual(self.expected_maintainer, instance.maintainer) | |
| 365 | |
| 366 | |
| 367 class ChangeLogEntry_body_TestCase( | |
| 368 testscenarios.WithScenarios, testtools.TestCase): | |
| 369 """ Test cases for ‘ChangeLogEntry.body’ attribute. """ | |
| 370 | |
| 371 scenarios = [ | |
| 372 ('default', { | |
| 373 'test_args': {}, | |
| 374 'expected_body': None, | |
| 375 }), | |
| 376 ('simple', { | |
| 377 'test_args': {'body': "Foo bar baz."}, | |
| 378 'expected_body': "Foo bar baz.", | |
| 379 }), | |
| 380 ] | |
| 381 | |
| 382 def test_has_expected_body(self): | |
| 383 """ Should have default `body` attribute. """ | |
| 384 instance = version.ChangeLogEntry(**self.test_args) | |
| 385 self.assertEqual(self.expected_body, instance.body) | |
| 386 | |
| 387 | |
| 388 class ChangeLogEntry_as_version_info_entry_TestCase( | |
| 389 testscenarios.WithScenarios, testtools.TestCase): | |
| 390 """ Test cases for ‘ChangeLogEntry.as_version_info_entry’ attribute. """ | |
| 391 | |
| 392 scenarios = [ | |
| 393 ('default', { | |
| 394 'test_args': {}, | |
| 395 'expected_result': collections.OrderedDict([ | |
| 396 ('release_date', version.ChangeLogEntry.default_release_date), | |
| 397 ('version', version.ChangeLogEntry.default_version), | |
| 398 ('maintainer', None), | |
| 399 ('body', None), | |
| 400 ]), | |
| 401 }), | |
| 402 ] | |
| 403 | |
| 404 def setUp(self): | |
| 405 """ Set up test fixtures. """ | |
| 406 super(ChangeLogEntry_as_version_info_entry_TestCase, self).setUp() | |
| 407 | |
| 408 self.test_instance = version.ChangeLogEntry(**self.test_args) | |
| 409 | |
| 410 def test_returns_result(self): | |
| 411 """ Should return expected result. """ | |
| 412 result = self.test_instance.as_version_info_entry() | |
| 413 self.assertEqual(self.expected_result, result) | |
| 414 | |
| 415 | |
| 416 def make_mock_field_node(field_name, field_body): | |
| 417 """ Make a mock Docutils field node for tests. """ | |
| 418 | |
| 419 mock_field_node = mock.MagicMock( | |
| 420 name='field', spec=docutils.nodes.field) | |
| 421 | |
| 422 mock_field_name_node = mock.MagicMock( | |
| 423 name='field_name', spec=docutils.nodes.field_name) | |
| 424 mock_field_name_node.parent = mock_field_node | |
| 425 mock_field_name_node.children = [field_name] | |
| 426 | |
| 427 mock_field_body_node = mock.MagicMock( | |
| 428 name='field_body', spec=docutils.nodes.field_body) | |
| 429 mock_field_body_node.parent = mock_field_node | |
| 430 mock_field_body_node.children = [field_body] | |
| 431 | |
| 432 mock_field_node.children = [mock_field_name_node, mock_field_body_node] | |
| 433 | |
| 434 def fake_func_first_child_matching_class(node_class): | |
| 435 result = None | |
| 436 node_class_name = node_class.__name__ | |
| 437 for (index, node) in enumerate(mock_field_node.children): | |
| 438 if node._mock_name == node_class_name: | |
| 439 result = index | |
| 440 break | |
| 441 return result | |
| 442 | |
| 443 mock_field_node.first_child_matching_class.side_effect = ( | |
| 444 fake_func_first_child_matching_class) | |
| 445 | |
| 446 return mock_field_node | |
| 447 | |
| 448 | |
| 449 class JsonEqual(testtools.matchers.Matcher): | |
| 450 """ A matcher to compare the value of JSON streams. """ | |
| 451 | |
| 452 def __init__(self, expected): | |
| 453 self.expected_value = expected | |
| 454 | |
| 455 def match(self, content): | |
| 456 """ Assert the JSON `content` matches the `expected_content`. """ | |
| 457 result = None | |
| 458 actual_value = json.loads(content.decode('utf-8')) | |
| 459 if actual_value != self.expected_value: | |
| 460 result = JsonValueMismatch(self.expected_value, actual_value) | |
| 461 return result | |
| 462 | |
| 463 | |
| 464 class JsonValueMismatch(testtools.matchers.Mismatch): | |
| 465 """ The specified JSON stream does not evaluate to the expected value. """ | |
| 466 | |
| 467 def __init__(self, expected, actual): | |
| 468 self.expected_value = expected | |
| 469 self.actual_value = actual | |
| 470 | |
| 471 def describe(self): | |
| 472 """ Emit a text description of this mismatch. """ | |
| 473 expected_json_text = json.dumps(self.expected_value, indent=4) | |
| 474 actual_json_text = json.dumps(self.actual_value, indent=4) | |
| 475 text = ( | |
| 476 "\n" | |
| 477 "reference: {expected}\n" | |
| 478 "actual: {actual}\n").format( | |
| 479 expected=expected_json_text, actual=actual_json_text) | |
| 480 return text | |
| 481 | |
| 482 | |
| 483 class changelog_to_version_info_collection_TestCase( | |
| 484 testscenarios.WithScenarios, testtools.TestCase): | |
| 485 """ Test cases for ‘changelog_to_version_info_collection’ function. """ | |
| 486 | |
| 487 scenarios = [ | |
| 488 ('single entry', { | |
| 489 'test_input': textwrap.dedent("""\ | |
| 490 Version 1.0 | |
| 491 =========== | |
| 492 | |
| 493 :Released: 2009-01-01 | |
| 494 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 495 | |
| 496 * Lorem ipsum dolor sit amet. | |
| 497 """), | |
| 498 'expected_version_info': [ | |
| 499 { | |
| 500 'release_date': "2009-01-01", | |
| 501 'version': "1.0", | |
| 502 'maintainer': "Foo Bar <foo.bar@example.org>", | |
| 503 'body': "* Lorem ipsum dolor sit amet.\n", | |
| 504 }, | |
| 505 ], | |
| 506 }), | |
| 507 ('multiple entries', { | |
| 508 'test_input': textwrap.dedent("""\ | |
| 509 Version 1.0 | |
| 510 =========== | |
| 511 | |
| 512 :Released: 2009-01-01 | |
| 513 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 514 | |
| 515 * Lorem ipsum dolor sit amet. | |
| 516 | |
| 517 | |
| 518 Version 0.8 | |
| 519 =========== | |
| 520 | |
| 521 :Released: 2004-01-01 | |
| 522 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 523 | |
| 524 * Donec venenatis nisl aliquam ipsum. | |
| 525 | |
| 526 | |
| 527 Version 0.7.2 | |
| 528 ============= | |
| 529 | |
| 530 :Released: 2001-01-01 | |
| 531 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 532 | |
| 533 * Pellentesque elementum mollis finibus. | |
| 534 """), | |
| 535 'expected_version_info': [ | |
| 536 { | |
| 537 'release_date': "2009-01-01", | |
| 538 'version': "1.0", | |
| 539 'maintainer': "Foo Bar <foo.bar@example.org>", | |
| 540 'body': "* Lorem ipsum dolor sit amet.\n", | |
| 541 }, | |
| 542 { | |
| 543 'release_date': "2004-01-01", | |
| 544 'version': "0.8", | |
| 545 'maintainer': "Foo Bar <foo.bar@example.org>", | |
| 546 'body': "* Donec venenatis nisl aliquam ipsum.\n", | |
| 547 }, | |
| 548 { | |
| 549 'release_date': "2001-01-01", | |
| 550 'version': "0.7.2", | |
| 551 'maintainer': "Foo Bar <foo.bar@example.org>", | |
| 552 'body': "* Pellentesque elementum mollis finibus.\n", | |
| 553 }, | |
| 554 ], | |
| 555 }), | |
| 556 ('trailing comment', { | |
| 557 'test_input': textwrap.dedent("""\ | |
| 558 Version NEXT | |
| 559 ============ | |
| 560 | |
| 561 :Released: FUTURE | |
| 562 :Maintainer: | |
| 563 | |
| 564 * Lorem ipsum dolor sit amet. | |
| 565 | |
| 566 .. | |
| 567 Vivamus aliquam felis rutrum rutrum dictum. | |
| 568 """), | |
| 569 'expected_version_info': [ | |
| 570 { | |
| 571 'release_date': "FUTURE", | |
| 572 'version': "NEXT", | |
| 573 'maintainer': "", | |
| 574 'body': "* Lorem ipsum dolor sit amet.\n", | |
| 575 }, | |
| 576 ], | |
| 577 }), | |
| 578 ('inline comment', { | |
| 579 'test_input': textwrap.dedent("""\ | |
| 580 Version NEXT | |
| 581 ============ | |
| 582 | |
| 583 :Released: FUTURE | |
| 584 :Maintainer: | |
| 585 | |
| 586 .. | |
| 587 Vivamus aliquam felis rutrum rutrum dictum. | |
| 588 | |
| 589 * Lorem ipsum dolor sit amet. | |
| 590 """), | |
| 591 'expected_version_info': [ | |
| 592 { | |
| 593 'release_date': "FUTURE", | |
| 594 'version': "NEXT", | |
| 595 'maintainer': "", | |
| 596 'body': "* Lorem ipsum dolor sit amet.\n", | |
| 597 }, | |
| 598 ], | |
| 599 }), | |
| 600 ('unreleased entry', { | |
| 601 'test_input': textwrap.dedent("""\ | |
| 602 Version NEXT | |
| 603 ============ | |
| 604 | |
| 605 :Released: FUTURE | |
| 606 :Maintainer: | |
| 607 | |
| 608 * Lorem ipsum dolor sit amet. | |
| 609 | |
| 610 | |
| 611 Version 0.8 | |
| 612 =========== | |
| 613 | |
| 614 :Released: 2001-01-01 | |
| 615 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 616 | |
| 617 * Donec venenatis nisl aliquam ipsum. | |
| 618 """), | |
| 619 'expected_version_info': [ | |
| 620 { | |
| 621 'release_date': "FUTURE", | |
| 622 'version': "NEXT", | |
| 623 'maintainer': "", | |
| 624 'body': "* Lorem ipsum dolor sit amet.\n", | |
| 625 }, | |
| 626 { | |
| 627 'release_date': "2001-01-01", | |
| 628 'version': "0.8", | |
| 629 'maintainer': "Foo Bar <foo.bar@example.org>", | |
| 630 'body': "* Donec venenatis nisl aliquam ipsum.\n", | |
| 631 }, | |
| 632 ], | |
| 633 }), | |
| 634 ('no section', { | |
| 635 'test_input': textwrap.dedent("""\ | |
| 636 :Released: 2009-01-01 | |
| 637 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 638 | |
| 639 * Lorem ipsum dolor sit amet. | |
| 640 """), | |
| 641 'expected_error': version.InvalidFormatError, | |
| 642 }), | |
| 643 ('subsection', { | |
| 644 'test_input': textwrap.dedent("""\ | |
| 645 Version 1.0 | |
| 646 =========== | |
| 647 | |
| 648 :Released: 2009-01-01 | |
| 649 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 650 | |
| 651 * Lorem ipsum dolor sit amet. | |
| 652 | |
| 653 Ut ultricies fermentum quam | |
| 654 --------------------------- | |
| 655 | |
| 656 * In commodo magna facilisis in. | |
| 657 """), | |
| 658 'expected_error': version.InvalidFormatError, | |
| 659 'subsection': True, | |
| 660 }), | |
| 661 ('unknown field', { | |
| 662 'test_input': textwrap.dedent("""\ | |
| 663 Version 1.0 | |
| 664 =========== | |
| 665 | |
| 666 :Released: 2009-01-01 | |
| 667 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 668 :Favourite: Spam | |
| 669 | |
| 670 * Lorem ipsum dolor sit amet. | |
| 671 """), | |
| 672 'expected_error': version.InvalidFormatError, | |
| 673 }), | |
| 674 ('invalid version word', { | |
| 675 'test_input': textwrap.dedent("""\ | |
| 676 BoGuS 1.0 | |
| 677 ========= | |
| 678 | |
| 679 :Released: 2009-01-01 | |
| 680 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 681 | |
| 682 * Lorem ipsum dolor sit amet. | |
| 683 """), | |
| 684 'expected_error': version.InvalidFormatError, | |
| 685 }), | |
| 686 ('invalid section title', { | |
| 687 'test_input': textwrap.dedent("""\ | |
| 688 Lorem Ipsum 1.0 | |
| 689 =============== | |
| 690 | |
| 691 :Released: 2009-01-01 | |
| 692 :Maintainer: Foo Bar <foo.bar@example.org> | |
| 693 | |
| 694 * Lorem ipsum dolor sit amet. | |
| 695 """), | |
| 696 'expected_error': version.InvalidFormatError, | |
| 697 }), | |
| 698 ] | |
| 699 | |
| 700 def test_returns_expected_version_info(self): | |
| 701 """ Should return expected version info mapping. """ | |
| 702 infile = StringIO(self.test_input) | |
| 703 if hasattr(self, 'expected_error'): | |
| 704 self.assertRaises( | |
| 705 self.expected_error, | |
| 706 version.changelog_to_version_info_collection, infile) | |
| 707 else: | |
| 708 result = version.changelog_to_version_info_collection(infile) | |
| 709 self.assertThat(result, JsonEqual(self.expected_version_info)) | |
| 710 | |
| 711 | |
| 712 try: | |
| 713 FileNotFoundError | |
| 714 PermissionError | |
| 715 except NameError: | |
| 716 # Python 2 uses OSError. | |
| 717 FileNotFoundError = functools.partial(IOError, errno.ENOENT) | |
| 718 PermissionError = functools.partial(IOError, errno.EPERM) | |
| 719 | |
| 720 fake_version_info = { | |
| 721 'release_date': "2001-01-01", 'version': "2.0", | |
| 722 'maintainer': None, 'body': None, | |
| 723 } | |
| 724 | |
| 725 @mock.patch.object( | |
| 726 version, "get_latest_version", return_value=fake_version_info) | |
| 727 class generate_version_info_from_changelog_TestCase( | |
| 728 testscenarios.WithScenarios, testtools.TestCase): | |
| 729 """ Test cases for ‘generate_version_info_from_changelog’ function. """ | |
| 730 | |
| 731 fake_open_side_effects = { | |
| 732 'success': ( | |
| 733 lambda *args, **kwargs: StringIO()), | |
| 734 'file not found': FileNotFoundError(), | |
| 735 'permission denied': PermissionError(), | |
| 736 } | |
| 737 | |
| 738 scenarios = [ | |
| 739 ('simple', { | |
| 740 'open_scenario': 'success', | |
| 741 'fake_versions_json': json.dumps([fake_version_info]), | |
| 742 'expected_result': fake_version_info, | |
| 743 }), | |
| 744 ('file not found', { | |
| 745 'open_scenario': 'file not found', | |
| 746 'expected_result': {}, | |
| 747 }), | |
| 748 ('permission denied', { | |
| 749 'open_scenario': 'permission denied', | |
| 750 'expected_result': {}, | |
| 751 }), | |
| 752 ] | |
| 753 | |
| 754 def setUp(self): | |
| 755 """ Set up test fixtures. """ | |
| 756 super(generate_version_info_from_changelog_TestCase, self).setUp() | |
| 757 | |
| 758 self.fake_changelog_file_path = tempfile.mktemp() | |
| 759 | |
| 760 def fake_open(filespec, *args, **kwargs): | |
| 761 if filespec == self.fake_changelog_file_path: | |
| 762 side_effect = self.fake_open_side_effects[self.open_scenario] | |
| 763 if callable(side_effect): | |
| 764 result = side_effect() | |
| 765 else: | |
| 766 raise side_effect | |
| 767 else: | |
| 768 result = StringIO() | |
| 769 return result | |
| 770 | |
| 771 func_patcher_io_open = mock.patch.object( | |
| 772 io, "open") | |
| 773 func_patcher_io_open.start() | |
| 774 self.addCleanup(func_patcher_io_open.stop) | |
| 775 io.open.side_effect = fake_open | |
| 776 | |
| 777 self.file_encoding = "utf-8" | |
| 778 | |
| 779 func_patcher_changelog_to_version_info_collection = mock.patch.object( | |
| 780 version, "changelog_to_version_info_collection") | |
| 781 func_patcher_changelog_to_version_info_collection.start() | |
| 782 self.addCleanup(func_patcher_changelog_to_version_info_collection.stop) | |
| 783 if hasattr(self, 'fake_versions_json'): | |
| 784 version.changelog_to_version_info_collection.return_value = ( | |
| 785 self.fake_versions_json.encode(self.file_encoding)) | |
| 786 | |
| 787 def test_returns_empty_collection_on_read_error( | |
| 788 self, | |
| 789 mock_func_get_latest_version): | |
| 790 """ Should return empty collection on error reading changelog. """ | |
| 791 test_error = PermissionError("Not for you") | |
| 792 version.changelog_to_version_info_collection.side_effect = test_error | |
| 793 result = version.generate_version_info_from_changelog( | |
| 794 self.fake_changelog_file_path) | |
| 795 expected_result = {} | |
| 796 self.assertDictEqual(expected_result, result) | |
| 797 | |
| 798 def test_opens_file_with_expected_encoding( | |
| 799 self, | |
| 800 mock_func_get_latest_version): | |
| 801 """ Should open changelog file in text mode with expected encoding. """ | |
| 802 result = version.generate_version_info_from_changelog( | |
| 803 self.fake_changelog_file_path) | |
| 804 expected_file_path = self.fake_changelog_file_path | |
| 805 expected_open_mode = 'rt' | |
| 806 expected_encoding = self.file_encoding | |
| 807 (open_args_positional, open_args_kwargs) = io.open.call_args | |
| 808 (open_args_filespec, open_args_mode) = open_args_positional[:2] | |
| 809 open_args_encoding = open_args_kwargs['encoding'] | |
| 810 self.assertEqual(expected_file_path, open_args_filespec) | |
| 811 self.assertEqual(expected_open_mode, open_args_mode) | |
| 812 self.assertEqual(expected_encoding, open_args_encoding) | |
| 813 | |
| 814 def test_returns_expected_result( | |
| 815 self, | |
| 816 mock_func_get_latest_version): | |
| 817 """ Should return expected result. """ | |
| 818 result = version.generate_version_info_from_changelog( | |
| 819 self.fake_changelog_file_path) | |
| 820 self.assertEqual(self.expected_result, result) | |
| 821 | |
| 822 | |
| 823 DefaultNoneDict = functools.partial(collections.defaultdict, lambda: None) | |
| 824 | |
| 825 class get_latest_version_TestCase( | |
| 826 testscenarios.WithScenarios, testtools.TestCase): | |
| 827 """ Test cases for ‘get_latest_version’ function. """ | |
| 828 | |
| 829 scenarios = [ | |
| 830 ('simple', { | |
| 831 'test_versions': [ | |
| 832 DefaultNoneDict({'release_date': "LATEST"}), | |
| 833 ], | |
| 834 'expected_result': version.ChangeLogEntry.make_ordered_dict( | |
| 835 DefaultNoneDict({'release_date': "LATEST"})), | |
| 836 }), | |
| 837 ('no versions', { | |
| 838 'test_versions': [], | |
| 839 'expected_result': collections.OrderedDict(), | |
| 840 }), | |
| 841 ('ordered versions', { | |
| 842 'test_versions': [ | |
| 843 DefaultNoneDict({'release_date': "1"}), | |
| 844 DefaultNoneDict({'release_date': "2"}), | |
| 845 DefaultNoneDict({'release_date': "LATEST"}), | |
| 846 ], | |
| 847 'expected_result': version.ChangeLogEntry.make_ordered_dict( | |
| 848 DefaultNoneDict({'release_date': "LATEST"})), | |
| 849 }), | |
| 850 ('un-ordered versions', { | |
| 851 'test_versions': [ | |
| 852 DefaultNoneDict({'release_date': "2"}), | |
| 853 DefaultNoneDict({'release_date': "LATEST"}), | |
| 854 DefaultNoneDict({'release_date': "1"}), | |
| 855 ], | |
| 856 'expected_result': version.ChangeLogEntry.make_ordered_dict( | |
| 857 DefaultNoneDict({'release_date': "LATEST"})), | |
| 858 }), | |
| 859 ] | |
| 860 | |
| 861 def test_returns_expected_result(self): | |
| 862 """ Should return expected result. """ | |
| 863 result = version.get_latest_version(self.test_versions) | |
| 864 self.assertDictEqual(self.expected_result, result) | |
| 865 | |
| 866 | |
| 867 @mock.patch.object(json, "dumps", side_effect=json.dumps) | |
| 868 class serialise_version_info_from_mapping_TestCase( | |
| 869 testscenarios.WithScenarios, testtools.TestCase): | |
| 870 """ Test cases for ‘get_latest_version’ function. """ | |
| 871 | |
| 872 scenarios = [ | |
| 873 ('simple', { | |
| 874 'test_version_info': {'foo': "spam"}, | |
| 875 }), | |
| 876 ] | |
| 877 | |
| 878 for (name, scenario) in scenarios: | |
| 879 scenario['fake_json_dump'] = json.dumps(scenario['test_version_info']) | |
| 880 scenario['expected_value'] = scenario['test_version_info'] | |
| 881 | |
| 882 def test_passes_specified_object(self, mock_func_json_dumps): | |
| 883 """ Should pass the specified object to `json.dumps`. """ | |
| 884 result = version.serialise_version_info_from_mapping( | |
| 885 self.test_version_info) | |
| 886 mock_func_json_dumps.assert_called_with( | |
| 887 self.test_version_info, indent=mock.ANY) | |
| 888 | |
| 889 def test_returns_expected_result(self, mock_func_json_dumps): | |
| 890 """ Should return expected result. """ | |
| 891 mock_func_json_dumps.return_value = self.fake_json_dump | |
| 892 result = version.serialise_version_info_from_mapping( | |
| 893 self.test_version_info) | |
| 894 value = json.loads(result) | |
| 895 self.assertEqual(self.expected_value, value) | |
| 896 | |
| 897 | |
| 898 DistributionMetadata_defaults = { | |
| 899 name: None | |
| 900 for name in list(collections.OrderedDict.fromkeys( | |
| 901 distutils.dist.DistributionMetadata._METHOD_BASENAMES))} | |
| 902 FakeDistributionMetadata = collections.namedtuple( | |
| 903 'FakeDistributionMetadata', DistributionMetadata_defaults.keys()) | |
| 904 | |
| 905 Distribution_defaults = { | |
| 906 'metadata': None, | |
| 907 'version': None, | |
| 908 'release_date': None, | |
| 909 'maintainer': None, | |
| 910 'maintainer_email': None, | |
| 911 } | |
| 912 FakeDistribution = collections.namedtuple( | |
| 913 'FakeDistribution', Distribution_defaults.keys()) | |
| 914 | |
| 915 def make_fake_distribution( | |
| 916 fields_override=None, metadata_fields_override=None): | |
| 917 metadata_fields = DistributionMetadata_defaults.copy() | |
| 918 if metadata_fields_override is not None: | |
| 919 metadata_fields.update(metadata_fields_override) | |
| 920 metadata = FakeDistributionMetadata(**metadata_fields) | |
| 921 | |
| 922 fields = Distribution_defaults.copy() | |
| 923 fields['metadata'] = metadata | |
| 924 if fields_override is not None: | |
| 925 fields.update(fields_override) | |
| 926 distribution = FakeDistribution(**fields) | |
| 927 | |
| 928 return distribution | |
| 929 | |
| 930 | |
| 931 class get_changelog_path_TestCase( | |
| 932 testscenarios.WithScenarios, testtools.TestCase): | |
| 933 """ Test cases for ‘get_changelog_path’ function. """ | |
| 934 | |
| 935 default_path = "." | |
| 936 default_script_filename = "setup.py" | |
| 937 | |
| 938 scenarios = [ | |
| 939 ('simple', {}), | |
| 940 ('unusual script name', { | |
| 941 'script_filename': "lorem_ipsum", | |
| 942 }), | |
| 943 ('relative script path', { | |
| 944 'script_directory': "dolor/sit/amet", | |
| 945 }), | |
| 946 ('absolute script path', { | |
| 947 'script_directory': "/dolor/sit/amet", | |
| 948 }), | |
| 949 ('specify filename', { | |
| 950 'changelog_filename': "adipiscing", | |
| 951 }), | |
| 952 ] | |
| 953 | |
| 954 def setUp(self): | |
| 955 """ Set up test fixtures. """ | |
| 956 super(get_changelog_path_TestCase, self).setUp() | |
| 957 | |
| 958 self.test_distribution = mock.MagicMock(distutils.dist.Distribution) | |
| 959 | |
| 960 if not hasattr(self, 'script_directory'): | |
| 961 self.script_directory = self.default_path | |
| 962 if not hasattr(self, 'script_filename'): | |
| 963 self.script_filename = self.default_script_filename | |
| 964 self.test_distribution.script_name = os.path.join( | |
| 965 self.script_directory, self.script_filename) | |
| 966 | |
| 967 changelog_filename = version.changelog_filename | |
| 968 if hasattr(self, 'changelog_filename'): | |
| 969 changelog_filename = self.changelog_filename | |
| 970 | |
| 971 self.expected_result = os.path.join( | |
| 972 self.script_directory, changelog_filename) | |
| 973 | |
| 974 def test_returns_expected_result(self): | |
| 975 """ Should return expected result. """ | |
| 976 args = { | |
| 977 'distribution': self.test_distribution, | |
| 978 } | |
| 979 if hasattr(self, 'changelog_filename'): | |
| 980 args.update({'filename': self.changelog_filename}) | |
| 981 result = version.get_changelog_path(**args) | |
| 982 self.assertEqual(self.expected_result, result) | |
| 983 | |
| 984 | |
| 985 class WriteVersionInfoCommand_BaseTestCase( | |
| 986 testscenarios.WithScenarios, testtools.TestCase): | |
| 987 """ Base class for ‘WriteVersionInfoCommand’ test case classes. """ | |
| 988 | |
| 989 def setUp(self): | |
| 990 """ Set up test fixtures. """ | |
| 991 super(WriteVersionInfoCommand_BaseTestCase, self).setUp() | |
| 992 | |
| 993 fake_distribution_name = self.getUniqueString() | |
| 994 | |
| 995 self.test_distribution = distutils.dist.Distribution() | |
| 996 self.test_distribution.metadata.name = fake_distribution_name | |
| 997 | |
| 998 | |
| 999 class WriteVersionInfoCommand_TestCase(WriteVersionInfoCommand_BaseTestCase): | |
| 1000 """ Test cases for ‘WriteVersionInfoCommand’ class. """ | |
| 1001 | |
| 1002 def test_subclass_of_distutils_command(self): | |
| 1003 """ Should be a subclass of ‘distutils.cmd.Command’. """ | |
| 1004 instance = version.WriteVersionInfoCommand(self.test_distribution) | |
| 1005 self.assertIsInstance(instance, distutils.cmd.Command) | |
| 1006 | |
| 1007 | |
| 1008 class WriteVersionInfoCommand_user_options_TestCase( | |
| 1009 WriteVersionInfoCommand_BaseTestCase): | |
| 1010 """ Test cases for ‘WriteVersionInfoCommand.user_options’ attribute. """ | |
| 1011 | |
| 1012 def setUp(self): | |
| 1013 """ Set up test fixtures. """ | |
| 1014 super(WriteVersionInfoCommand_user_options_TestCase, self).setUp() | |
| 1015 | |
| 1016 self.test_instance = version.WriteVersionInfoCommand( | |
| 1017 self.test_distribution) | |
| 1018 self.commandline_parser = distutils.fancy_getopt.FancyGetopt( | |
| 1019 self.test_instance.user_options) | |
| 1020 | |
| 1021 def test_parses_correctly_as_fancy_getopt(self): | |
| 1022 """ Should parse correctly in ‘FancyGetopt’. """ | |
| 1023 self.assertIsInstance( | |
| 1024 self.commandline_parser, distutils.fancy_getopt.FancyGetopt) | |
| 1025 | |
| 1026 def test_includes_base_class_user_options(self): | |
| 1027 """ Should include base class's user_options. """ | |
| 1028 base_command = setuptools.command.egg_info.egg_info | |
| 1029 expected_user_options = base_command.user_options | |
| 1030 self.assertThat( | |
| 1031 set(expected_user_options), | |
| 1032 IsSubset(set(self.test_instance.user_options))) | |
| 1033 | |
| 1034 def test_has_option_changelog_path(self): | |
| 1035 """ Should have a ‘changelog-path’ option. """ | |
| 1036 expected_option_name = "changelog-path=" | |
| 1037 result = self.commandline_parser.has_option(expected_option_name) | |
| 1038 self.assertTrue(result) | |
| 1039 | |
| 1040 def test_has_option_outfile_path(self): | |
| 1041 """ Should have a ‘outfile-path’ option. """ | |
| 1042 expected_option_name = "outfile-path=" | |
| 1043 result = self.commandline_parser.has_option(expected_option_name) | |
| 1044 self.assertTrue(result) | |
| 1045 | |
| 1046 | |
| 1047 class WriteVersionInfoCommand_initialize_options_TestCase( | |
| 1048 WriteVersionInfoCommand_BaseTestCase): | |
| 1049 """ Test cases for ‘WriteVersionInfoCommand.initialize_options’ method. """ | |
| 1050 | |
| 1051 def setUp(self): | |
| 1052 """ Set up test fixtures. """ | |
| 1053 super( | |
| 1054 WriteVersionInfoCommand_initialize_options_TestCase, self | |
| 1055 ).setUp() | |
| 1056 | |
| 1057 patcher_func_egg_info_initialize_options = mock.patch.object( | |
| 1058 setuptools.command.egg_info.egg_info, "initialize_options") | |
| 1059 patcher_func_egg_info_initialize_options.start() | |
| 1060 self.addCleanup(patcher_func_egg_info_initialize_options.stop) | |
| 1061 | |
| 1062 def test_calls_base_class_method(self): | |
| 1063 """ Should call base class's ‘initialize_options’ method. """ | |
| 1064 instance = version.WriteVersionInfoCommand(self.test_distribution) | |
| 1065 base_command_class = setuptools.command.egg_info.egg_info | |
| 1066 base_command_class.initialize_options.assert_called_with() | |
| 1067 | |
| 1068 def test_sets_changelog_path_to_none(self): | |
| 1069 """ Should set ‘changelog_path’ attribute to ``None``. """ | |
| 1070 instance = version.WriteVersionInfoCommand(self.test_distribution) | |
| 1071 self.assertIs(instance.changelog_path, None) | |
| 1072 | |
| 1073 def test_sets_outfile_path_to_none(self): | |
| 1074 """ Should set ‘outfile_path’ attribute to ``None``. """ | |
| 1075 instance = version.WriteVersionInfoCommand(self.test_distribution) | |
| 1076 self.assertIs(instance.outfile_path, None) | |
| 1077 | |
| 1078 | |
| 1079 class WriteVersionInfoCommand_finalize_options_TestCase( | |
| 1080 WriteVersionInfoCommand_BaseTestCase): | |
| 1081 """ Test cases for ‘WriteVersionInfoCommand.finalize_options’ method. """ | |
| 1082 | |
| 1083 def setUp(self): | |
| 1084 """ Set up test fixtures. """ | |
| 1085 super(WriteVersionInfoCommand_finalize_options_TestCase, self).setUp() | |
| 1086 | |
| 1087 self.test_instance = version.WriteVersionInfoCommand(self.test_distribution) | |
| 1088 | |
| 1089 patcher_func_egg_info_finalize_options = mock.patch.object( | |
| 1090 setuptools.command.egg_info.egg_info, "finalize_options") | |
| 1091 patcher_func_egg_info_finalize_options.start() | |
| 1092 self.addCleanup(patcher_func_egg_info_finalize_options.stop) | |
| 1093 | |
| 1094 self.fake_script_dir = self.getUniqueString() | |
| 1095 self.test_distribution.script_name = os.path.join( | |
| 1096 self.fake_script_dir, self.getUniqueString()) | |
| 1097 | |
| 1098 self.fake_egg_dir = self.getUniqueString() | |
| 1099 self.test_instance.egg_info = self.fake_egg_dir | |
| 1100 | |
| 1101 patcher_func_get_changelog_path = mock.patch.object( | |
| 1102 version, "get_changelog_path") | |
| 1103 patcher_func_get_changelog_path.start() | |
| 1104 self.addCleanup(patcher_func_get_changelog_path.stop) | |
| 1105 | |
| 1106 self.fake_changelog_path = self.getUniqueString() | |
| 1107 version.get_changelog_path.return_value = self.fake_changelog_path | |
| 1108 | |
| 1109 def test_calls_base_class_method(self): | |
| 1110 """ Should call base class's ‘finalize_options’ method. """ | |
| 1111 base_command_class = setuptools.command.egg_info.egg_info | |
| 1112 self.test_instance.finalize_options() | |
| 1113 base_command_class.finalize_options.assert_called_with() | |
| 1114 | |
| 1115 def test_sets_force_to_none(self): | |
| 1116 """ Should set ‘force’ attribute to ``None``. """ | |
| 1117 self.test_instance.finalize_options() | |
| 1118 self.assertIs(self.test_instance.force, None) | |
| 1119 | |
| 1120 def test_sets_changelog_path_using_get_changelog_path(self): | |
| 1121 """ Should set ‘changelog_path’ attribute if it was ``None``. """ | |
| 1122 self.test_instance.changelog_path = None | |
| 1123 self.test_instance.finalize_options() | |
| 1124 expected_changelog_path = self.fake_changelog_path | |
| 1125 self.assertEqual(expected_changelog_path, self.test_instance.changelog_path) | |
| 1126 | |
| 1127 def test_leaves_changelog_path_if_already_set(self): | |
| 1128 """ Should leave ‘changelog_path’ attribute set. """ | |
| 1129 prior_changelog_path = self.getUniqueString() | |
| 1130 self.test_instance.changelog_path = prior_changelog_path | |
| 1131 self.test_instance.finalize_options() | |
| 1132 expected_changelog_path = prior_changelog_path | |
| 1133 self.assertEqual(expected_changelog_path, self.test_instance.changelog_path) | |
| 1134 | |
| 1135 def test_sets_outfile_path_to_default(self): | |
| 1136 """ Should set ‘outfile_path’ attribute to default value. """ | |
| 1137 fake_version_info_filename = self.getUniqueString() | |
| 1138 with mock.patch.object( | |
| 1139 version, "version_info_filename", | |
| 1140 new=fake_version_info_filename): | |
| 1141 self.test_instance.finalize_options() | |
| 1142 expected_outfile_path = os.path.join( | |
| 1143 self.fake_egg_dir, fake_version_info_filename) | |
| 1144 self.assertEqual(expected_outfile_path, self.test_instance.outfile_path) | |
| 1145 | |
| 1146 def test_leaves_outfile_path_if_already_set(self): | |
| 1147 """ Should leave ‘outfile_path’ attribute set. """ | |
| 1148 prior_outfile_path = self.getUniqueString() | |
| 1149 self.test_instance.outfile_path = prior_outfile_path | |
| 1150 self.test_instance.finalize_options() | |
| 1151 expected_outfile_path = prior_outfile_path | |
| 1152 self.assertEqual(expected_outfile_path, self.test_instance.outfile_path) | |
| 1153 | |
| 1154 | |
| 1155 class has_changelog_TestCase( | |
| 1156 testscenarios.WithScenarios, testtools.TestCase): | |
| 1157 """ Test cases for ‘has_changelog’ function. """ | |
| 1158 | |
| 1159 fake_os_path_exists_side_effects = { | |
| 1160 'true': (lambda path: True), | |
| 1161 'false': (lambda path: False), | |
| 1162 } | |
| 1163 | |
| 1164 scenarios = [ | |
| 1165 ('no changelog path', { | |
| 1166 'changelog_path': None, | |
| 1167 'expected_result': False, | |
| 1168 }), | |
| 1169 ('changelog exists', { | |
| 1170 'os_path_exists_scenario': 'true', | |
| 1171 'expected_result': True, | |
| 1172 }), | |
| 1173 ('changelog not found', { | |
| 1174 'os_path_exists_scenario': 'false', | |
| 1175 'expected_result': False, | |
| 1176 }), | |
| 1177 ] | |
| 1178 | |
| 1179 def setUp(self): | |
| 1180 """ Set up test fixtures. """ | |
| 1181 super(has_changelog_TestCase, self).setUp() | |
| 1182 | |
| 1183 self.test_distribution = distutils.dist.Distribution() | |
| 1184 self.test_command = version.EggInfoCommand( | |
| 1185 self.test_distribution) | |
| 1186 | |
| 1187 patcher_func_get_changelog_path = mock.patch.object( | |
| 1188 version, "get_changelog_path") | |
| 1189 patcher_func_get_changelog_path.start() | |
| 1190 self.addCleanup(patcher_func_get_changelog_path.stop) | |
| 1191 | |
| 1192 self.fake_changelog_file_path = self.getUniqueString() | |
| 1193 if hasattr(self, 'changelog_path'): | |
| 1194 self.fake_changelog_file_path = self.changelog_path | |
| 1195 version.get_changelog_path.return_value = self.fake_changelog_file_path | |
| 1196 self.fake_changelog_file = StringIO() | |
| 1197 | |
| 1198 def fake_os_path_exists(path): | |
| 1199 if path == self.fake_changelog_file_path: | |
| 1200 side_effect = self.fake_os_path_exists_side_effects[ | |
| 1201 self.os_path_exists_scenario] | |
| 1202 if callable(side_effect): | |
| 1203 result = side_effect(path) | |
| 1204 else: | |
| 1205 raise side_effect | |
| 1206 else: | |
| 1207 result = False | |
| 1208 return result | |
| 1209 | |
| 1210 func_patcher_os_path_exists = mock.patch.object( | |
| 1211 os.path, "exists") | |
| 1212 func_patcher_os_path_exists.start() | |
| 1213 self.addCleanup(func_patcher_os_path_exists.stop) | |
| 1214 os.path.exists.side_effect = fake_os_path_exists | |
| 1215 | |
| 1216 def test_gets_changelog_path_from_distribution(self): | |
| 1217 """ Should call ‘get_changelog_path’ with distribution. """ | |
| 1218 result = version.has_changelog(self.test_command) | |
| 1219 version.get_changelog_path.assert_called_with( | |
| 1220 self.test_distribution) | |
| 1221 | |
| 1222 def test_returns_expected_result(self): | |
| 1223 """ Should be a subclass of ‘distutils.cmd.Command’. """ | |
| 1224 result = version.has_changelog(self.test_command) | |
| 1225 self.assertEqual(self.expected_result, result) | |
| 1226 | |
| 1227 | |
| 1228 @mock.patch.object(version, 'generate_version_info_from_changelog') | |
| 1229 @mock.patch.object(version, 'serialise_version_info_from_mapping') | |
| 1230 @mock.patch.object(version.EggInfoCommand, "write_file") | |
| 1231 class WriteVersionInfoCommand_run_TestCase( | |
| 1232 WriteVersionInfoCommand_BaseTestCase): | |
| 1233 """ Test cases for ‘WriteVersionInfoCommand.run’ method. """ | |
| 1234 | |
| 1235 def setUp(self): | |
| 1236 """ Set up test fixtures. """ | |
| 1237 super(WriteVersionInfoCommand_run_TestCase, self).setUp() | |
| 1238 | |
| 1239 self.test_instance = version.WriteVersionInfoCommand( | |
| 1240 self.test_distribution) | |
| 1241 | |
| 1242 self.fake_changelog_path = self.getUniqueString() | |
| 1243 self.test_instance.changelog_path = self.fake_changelog_path | |
| 1244 | |
| 1245 self.fake_outfile_path = self.getUniqueString() | |
| 1246 self.test_instance.outfile_path = self.fake_outfile_path | |
| 1247 | |
| 1248 def test_returns_none( | |
| 1249 self, | |
| 1250 mock_func_egg_info_write_file, | |
| 1251 mock_func_serialise_version_info, | |
| 1252 mock_func_generate_version_info): | |
| 1253 """ Should return ``None``. """ | |
| 1254 result = self.test_instance.run() | |
| 1255 self.assertIs(result, None) | |
| 1256 | |
| 1257 def test_generates_version_info_from_changelog( | |
| 1258 self, | |
| 1259 mock_func_egg_info_write_file, | |
| 1260 mock_func_serialise_version_info, | |
| 1261 mock_func_generate_version_info): | |
| 1262 """ Should generate version info from specified changelog. """ | |
| 1263 self.test_instance.run() | |
| 1264 expected_changelog_path = self.test_instance.changelog_path | |
| 1265 mock_func_generate_version_info.assert_called_with( | |
| 1266 expected_changelog_path) | |
| 1267 | |
| 1268 def test_serialises_version_info_from_mapping( | |
| 1269 self, | |
| 1270 mock_func_egg_info_write_file, | |
| 1271 mock_func_serialise_version_info, | |
| 1272 mock_func_generate_version_info): | |
| 1273 """ Should serialise version info from specified mapping. """ | |
| 1274 self.test_instance.run() | |
| 1275 expected_version_info = mock_func_generate_version_info.return_value | |
| 1276 mock_func_serialise_version_info.assert_called_with( | |
| 1277 expected_version_info) | |
| 1278 | |
| 1279 def test_writes_file_using_command_context( | |
| 1280 self, | |
| 1281 mock_func_egg_info_write_file, | |
| 1282 mock_func_serialise_version_info, | |
| 1283 mock_func_generate_version_info): | |
| 1284 """ Should write the metadata file using the command context. """ | |
| 1285 self.test_instance.run() | |
| 1286 expected_content = mock_func_serialise_version_info.return_value | |
| 1287 mock_func_egg_info_write_file.assert_called_with( | |
| 1288 "version info", self.fake_outfile_path, expected_content) | |
| 1289 | |
| 1290 | |
| 1291 IsSubset = testtools.matchers.MatchesPredicateWithParams( | |
| 1292 set.issubset, "{0} should be a subset of {1}") | |
| 1293 | |
| 1294 class EggInfoCommand_TestCase(testtools.TestCase): | |
| 1295 """ Test cases for ‘EggInfoCommand’ class. """ | |
| 1296 | |
| 1297 def setUp(self): | |
| 1298 """ Set up test fixtures. """ | |
| 1299 super(EggInfoCommand_TestCase, self).setUp() | |
| 1300 | |
| 1301 self.test_distribution = distutils.dist.Distribution() | |
| 1302 self.test_instance = version.EggInfoCommand(self.test_distribution) | |
| 1303 | |
| 1304 def test_subclass_of_setuptools_egg_info(self): | |
| 1305 """ Should be a subclass of Setuptools ‘egg_info’. """ | |
| 1306 self.assertIsInstance( | |
| 1307 self.test_instance, setuptools.command.egg_info.egg_info) | |
| 1308 | |
| 1309 def test_sub_commands_include_base_class_sub_commands(self): | |
| 1310 """ Should include base class's sub-commands in this sub_commands. """ | |
| 1311 base_command = setuptools.command.egg_info.egg_info | |
| 1312 expected_sub_commands = base_command.sub_commands | |
| 1313 self.assertThat( | |
| 1314 set(expected_sub_commands), | |
| 1315 IsSubset(set(self.test_instance.sub_commands))) | |
| 1316 | |
| 1317 def test_sub_commands_includes_write_version_info_command(self): | |
| 1318 """ Should include sub-command named ‘write_version_info’. """ | |
| 1319 commands_by_name = dict(self.test_instance.sub_commands) | |
| 1320 expected_predicate = version.has_changelog | |
| 1321 expected_item = ('write_version_info', expected_predicate) | |
| 1322 self.assertIn(expected_item, commands_by_name.items()) | |
| 1323 | |
| 1324 | |
| 1325 @mock.patch.object(setuptools.command.egg_info.egg_info, "run") | |
| 1326 class EggInfoCommand_run_TestCase(testtools.TestCase): | |
| 1327 """ Test cases for ‘EggInfoCommand.run’ method. """ | |
| 1328 | |
| 1329 def setUp(self): | |
| 1330 """ Set up test fixtures. """ | |
| 1331 super(EggInfoCommand_run_TestCase, self).setUp() | |
| 1332 | |
| 1333 self.test_distribution = distutils.dist.Distribution() | |
| 1334 self.test_instance = version.EggInfoCommand(self.test_distribution) | |
| 1335 | |
| 1336 base_command = setuptools.command.egg_info.egg_info | |
| 1337 patcher_func_egg_info_get_sub_commands = mock.patch.object( | |
| 1338 base_command, "get_sub_commands") | |
| 1339 patcher_func_egg_info_get_sub_commands.start() | |
| 1340 self.addCleanup(patcher_func_egg_info_get_sub_commands.stop) | |
| 1341 | |
| 1342 patcher_func_egg_info_run_command = mock.patch.object( | |
| 1343 base_command, "run_command") | |
| 1344 patcher_func_egg_info_run_command.start() | |
| 1345 self.addCleanup(patcher_func_egg_info_run_command.stop) | |
| 1346 | |
| 1347 self.fake_sub_commands = ["spam", "eggs", "beans"] | |
| 1348 base_command.get_sub_commands.return_value = self.fake_sub_commands | |
| 1349 | |
| 1350 def test_returns_none(self, mock_func_egg_info_run): | |
| 1351 """ Should return ``None``. """ | |
| 1352 result = self.test_instance.run() | |
| 1353 self.assertIs(result, None) | |
| 1354 | |
| 1355 def test_runs_each_command_in_sub_commands( | |
| 1356 self, mock_func_egg_info_run): | |
| 1357 """ Should run each command in ‘self.get_sub_commands()’. """ | |
| 1358 base_command = setuptools.command.egg_info.egg_info | |
| 1359 self.test_instance.run() | |
| 1360 expected_calls = [mock.call(name) for name in self.fake_sub_commands] | |
| 1361 base_command.run_command.assert_has_calls(expected_calls) | |
| 1362 | |
| 1363 def test_calls_base_class_run(self, mock_func_egg_info_run): | |
| 1364 """ Should call base class's ‘run’ method. """ | |
| 1365 result = self.test_instance.run() | |
| 1366 mock_func_egg_info_run.assert_called_with() | |
| 1367 | |
| 1368 | |
| 1369 # Local variables: | |
| 1370 # coding: utf-8 | |
| 1371 # mode: python | |
| 1372 # End: | |
| 1373 # vim: fileencoding=utf-8 filetype=python : |
