TestCmdLine.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import sys
  2. import re
  3. from unittest import TestCase
  4. try:
  5. from StringIO import StringIO
  6. except ImportError:
  7. from io import StringIO # doesn't accept 'str' in Py2
  8. from .. import Options
  9. from ..CmdLine import parse_command_line
  10. def check_global_options(expected_options, white_list=[]):
  11. """
  12. returns error message of "" if check Ok
  13. """
  14. no_value = object()
  15. for name, orig_value in expected_options.items():
  16. if name not in white_list:
  17. if getattr(Options, name, no_value) != orig_value:
  18. return "error in option " + name
  19. return ""
  20. class CmdLineParserTest(TestCase):
  21. def setUp(self):
  22. backup = {}
  23. for name, value in vars(Options).items():
  24. backup[name] = value
  25. self._options_backup = backup
  26. def tearDown(self):
  27. no_value = object()
  28. for name, orig_value in self._options_backup.items():
  29. if getattr(Options, name, no_value) != orig_value:
  30. setattr(Options, name, orig_value)
  31. def check_default_global_options(self, white_list=[]):
  32. self.assertEqual(check_global_options(self._options_backup, white_list), "")
  33. def check_default_options(self, options, white_list=[]):
  34. from ..Main import CompilationOptions, default_options
  35. default_options = CompilationOptions(default_options)
  36. no_value = object()
  37. for name in default_options.__dict__.keys():
  38. if name not in white_list:
  39. self.assertEqual(getattr(options, name, no_value), getattr(default_options, name), msg="error in option " + name)
  40. def test_short_options(self):
  41. options, sources = parse_command_line([
  42. '-V', '-l', '-+', '-t', '-v', '-v', '-v', '-p', '-D', '-a', '-3',
  43. ])
  44. self.assertFalse(sources)
  45. self.assertTrue(options.show_version)
  46. self.assertTrue(options.use_listing_file)
  47. self.assertTrue(options.cplus)
  48. self.assertTrue(options.timestamps)
  49. self.assertTrue(options.verbose >= 3)
  50. self.assertTrue(Options.embed_pos_in_docstring)
  51. self.assertFalse(Options.docstrings)
  52. self.assertTrue(Options.annotate)
  53. self.assertEqual(options.language_level, 3)
  54. options, sources = parse_command_line([
  55. '-f', '-2', 'source.pyx',
  56. ])
  57. self.assertTrue(sources)
  58. self.assertTrue(len(sources) == 1)
  59. self.assertFalse(options.timestamps)
  60. self.assertEqual(options.language_level, 2)
  61. def test_long_options(self):
  62. options, sources = parse_command_line([
  63. '--version', '--create-listing', '--cplus', '--embed', '--timestamps',
  64. '--verbose', '--verbose', '--verbose',
  65. '--embed-positions', '--no-docstrings', '--annotate', '--lenient',
  66. ])
  67. self.assertFalse(sources)
  68. self.assertTrue(options.show_version)
  69. self.assertTrue(options.use_listing_file)
  70. self.assertTrue(options.cplus)
  71. self.assertEqual(Options.embed, 'main')
  72. self.assertTrue(options.timestamps)
  73. self.assertTrue(options.verbose >= 3)
  74. self.assertTrue(Options.embed_pos_in_docstring)
  75. self.assertFalse(Options.docstrings)
  76. self.assertTrue(Options.annotate)
  77. self.assertFalse(Options.error_on_unknown_names)
  78. self.assertFalse(Options.error_on_uninitialized)
  79. options, sources = parse_command_line([
  80. '--force', 'source.pyx',
  81. ])
  82. self.assertTrue(sources)
  83. self.assertTrue(len(sources) == 1)
  84. self.assertFalse(options.timestamps)
  85. def test_options_with_values(self):
  86. options, sources = parse_command_line([
  87. '--embed=huhu',
  88. '-I/test/include/dir1', '--include-dir=/test/include/dir2',
  89. '--include-dir', '/test/include/dir3',
  90. '--working=/work/dir',
  91. 'source.pyx',
  92. '--output-file=/output/dir',
  93. '--pre-import=/pre/import',
  94. '--cleanup=3',
  95. '--annotate-coverage=cov.xml',
  96. '--gdb-outdir=/gdb/outdir',
  97. '--directive=wraparound=false',
  98. ])
  99. self.assertEqual(sources, ['source.pyx'])
  100. self.assertEqual(Options.embed, 'huhu')
  101. self.assertEqual(options.include_path, ['/test/include/dir1', '/test/include/dir2', '/test/include/dir3'])
  102. self.assertEqual(options.working_path, '/work/dir')
  103. self.assertEqual(options.output_file, '/output/dir')
  104. self.assertEqual(Options.pre_import, '/pre/import')
  105. self.assertEqual(Options.generate_cleanup_code, 3)
  106. self.assertTrue(Options.annotate)
  107. self.assertEqual(Options.annotate_coverage_xml, 'cov.xml')
  108. self.assertTrue(options.gdb_debug)
  109. self.assertEqual(options.output_dir, '/gdb/outdir')
  110. def test_module_name(self):
  111. options, sources = parse_command_line([
  112. 'source.pyx'
  113. ])
  114. self.assertEqual(options.module_name, None)
  115. self.check_default_global_options()
  116. self.check_default_options(options)
  117. options, sources = parse_command_line([
  118. '--module-name', 'foo.bar',
  119. 'source.pyx'
  120. ])
  121. self.assertEqual(options.module_name, 'foo.bar')
  122. self.check_default_global_options()
  123. self.check_default_options(options, ['module_name'])
  124. def test_errors(self):
  125. def error(args, regex=None):
  126. old_stderr = sys.stderr
  127. stderr = sys.stderr = StringIO()
  128. try:
  129. self.assertRaises(SystemExit, parse_command_line, list(args))
  130. finally:
  131. sys.stderr = old_stderr
  132. msg = stderr.getvalue().strip()
  133. self.assertTrue(msg)
  134. if regex:
  135. self.assertTrue(re.search(regex, msg),
  136. '"%s" does not match search "%s"' %
  137. (msg, regex))
  138. error(['-1'],
  139. 'Unknown compiler flag: -1')
  140. error(['-I'])
  141. error(['--version=-a'])
  142. error(['--version=--annotate=true'])
  143. error(['--working'])
  144. error(['--verbose=1'])
  145. error(['--cleanup'])
  146. error(['--debug-disposal-code-wrong-name', 'file3.pyx'],
  147. "Unknown debug flag: debug_disposal_code_wrong_name")
  148. error(['--module-name', 'foo.pyx'])
  149. error(['--module-name', 'foo.bar'])
  150. error(['--module-name', 'foo.bar', 'foo.pyx', 'bar.pyx'],
  151. "Only one source file allowed when using --module-name")
  152. error(['--module-name', 'foo.bar', '--timestamps', 'foo.pyx'],
  153. "Cannot use --module-name with --timestamps")