summaryrefslogtreecommitdiff
path: root/tests/test_cmdline.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_cmdline.py')
-rw-r--r--tests/test_cmdline.py495
1 files changed, 250 insertions, 245 deletions
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
index 11b53896..d56e2ae5 100644
--- a/tests/test_cmdline.py
+++ b/tests/test_cmdline.py
@@ -3,7 +3,7 @@
Command line test
~~~~~~~~~~~~~~~~~
- :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
+ :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@@ -14,9 +14,10 @@ import os
import re
import sys
import tempfile
-import unittest
from os import path
+from pytest import raises
+
from pygments import cmdline, highlight
from pygments.util import BytesIO, StringIO
@@ -66,249 +67,253 @@ def run_cmdline(*args, **kwds):
return (ret, _decode_output(out), _decode_output(err))
-class CmdLineTest(unittest.TestCase):
-
- def check_success(self, *cmdline, **kwds):
- code, out, err = run_cmdline(*cmdline, **kwds)
- self.assertEqual(code, 0)
- self.assertEqual(err, '')
- return out
-
- def check_failure(self, *cmdline, **kwds):
- expected_code = kwds.pop('code', 1)
- code, out, err = run_cmdline(*cmdline, **kwds)
- self.assertEqual(code, expected_code)
- self.assertEqual(out, '')
- return err
-
- def test_normal(self):
- # test that cmdline gives the same output as library api
- from pygments.lexers import PythonLexer
- from pygments.formatters import HtmlFormatter
- filename = TESTFILE
- with open(filename, 'rb') as fp:
- code = fp.read()
-
- output = highlight(code, PythonLexer(), HtmlFormatter())
-
- o = self.check_success('-lpython', '-fhtml', filename)
- self.assertEqual(o, output)
-
- def test_stdin(self):
- o = self.check_success('-lpython', '-fhtml', stdin=TESTCODE)
- o = re.sub('<[^>]*>', '', o)
- # rstrip is necessary since HTML inserts a \n after the last </div>
- self.assertEqual(o.rstrip(), TESTCODE.rstrip())
-
- # guess if no lexer given
- o = self.check_success('-fhtml', stdin=TESTCODE)
- o = re.sub('<[^>]*>', '', o)
- # rstrip is necessary since HTML inserts a \n after the last </div>
- self.assertEqual(o.rstrip(), TESTCODE.rstrip())
-
- def test_outfile(self):
- # test that output file works with and without encoding
- fd, name = tempfile.mkstemp()
- os.close(fd)
- for opts in [['-fhtml', '-o', name, TESTFILE],
- ['-flatex', '-o', name, TESTFILE],
- ['-fhtml', '-o', name, '-O', 'encoding=utf-8', TESTFILE]]:
- try:
- self.check_success(*opts)
- finally:
- os.unlink(name)
-
- def test_load_from_file(self):
- lexer_file = os.path.join(TESTDIR, 'support', 'python_lexer.py')
- formatter_file = os.path.join(TESTDIR, 'support', 'html_formatter.py')
-
- # By default, use CustomLexer
- o = self.check_success('-l', lexer_file, '-f', 'html',
- '-x', stdin=TESTCODE)
- o = re.sub('<[^>]*>', '', o)
- # rstrip is necessary since HTML inserts a \n after the last </div>
- self.assertEqual(o.rstrip(), TESTCODE.rstrip())
-
- # If user specifies a name, use it
- o = self.check_success('-f', 'html', '-x', '-l',
- lexer_file + ':LexerWrapper', stdin=TESTCODE)
- o = re.sub('<[^>]*>', '', o)
- # rstrip is necessary since HTML inserts a \n after the last </div>
- self.assertEqual(o.rstrip(), TESTCODE.rstrip())
-
- # Should also work for formatters
- o = self.check_success('-lpython', '-f',
- formatter_file + ':HtmlFormatterWrapper',
- '-x', stdin=TESTCODE)
- o = re.sub('<[^>]*>', '', o)
- # rstrip is necessary since HTML inserts a \n after the last </div>
- self.assertEqual(o.rstrip(), TESTCODE.rstrip())
-
- def test_stream_opt(self):
- o = self.check_success('-lpython', '-s', '-fterminal', stdin=TESTCODE)
- o = re.sub(r'\x1b\[.*?m', '', o)
- self.assertEqual(o.replace('\r\n', '\n'), TESTCODE)
-
- def test_h_opt(self):
- o = self.check_success('-h')
- self.assertTrue('Usage:' in o)
-
- def test_L_opt(self):
- o = self.check_success('-L')
- self.assertTrue('Lexers' in o and 'Formatters' in o and
- 'Filters' in o and 'Styles' in o)
- o = self.check_success('-L', 'lexer')
- self.assertTrue('Lexers' in o and 'Formatters' not in o)
- self.check_success('-L', 'lexers')
-
- def test_O_opt(self):
- filename = TESTFILE
- o = self.check_success('-Ofull=1,linenos=true,foo=bar',
- '-fhtml', filename)
- self.assertTrue('<html' in o)
- self.assertTrue('class="linenos"' in o)
-
- # "foobar" is invalid for a bool option
- e = self.check_failure('-Ostripnl=foobar', TESTFILE)
- self.assertTrue('Error: Invalid value' in e)
- e = self.check_failure('-Ostripnl=foobar', '-lpy')
- self.assertTrue('Error: Invalid value' in e)
-
- def test_P_opt(self):
- filename = TESTFILE
- o = self.check_success('-Pfull', '-Ptitle=foo, bar=baz=,',
- '-fhtml', filename)
- self.assertTrue('<title>foo, bar=baz=,</title>' in o)
-
- def test_F_opt(self):
- filename = TESTFILE
- o = self.check_success('-Fhighlight:tokentype=Name.Blubb,'
- 'names=TESTFILE filename',
- '-fhtml', filename)
- self.assertTrue('<span class="n n-Blubb' in o)
-
- def test_H_opt(self):
- o = self.check_success('-H', 'formatter', 'html')
- self.assertTrue('HTML' in o)
- o = self.check_success('-H', 'lexer', 'python')
- self.assertTrue('Python' in o)
- o = self.check_success('-H', 'filter', 'raiseonerror')
- self.assertTrue('raiseonerror', o)
- e = self.check_failure('-H', 'lexer', 'foobar')
- self.assertTrue('not found' in e)
-
- def test_S_opt(self):
- o = self.check_success('-S', 'default', '-f', 'html', '-O', 'linenos=1')
- lines = o.splitlines()
- for line in lines:
- # every line is for a token class
- parts = line.split()
- self.assertTrue(parts[0].startswith('.'))
- self.assertTrue(parts[1] == '{')
- if parts[0] != '.hll':
- self.assertTrue(parts[-4] == '}')
- self.assertTrue(parts[-3] == '/*')
- self.assertTrue(parts[-1] == '*/')
- self.check_failure('-S', 'default', '-f', 'foobar')
-
- def test_N_opt(self):
- o = self.check_success('-N', 'test.py')
- self.assertEqual('python', o.strip())
- o = self.check_success('-N', 'test.unknown')
- self.assertEqual('text', o.strip())
-
- def test_invalid_opts(self):
- for opts in [
- ('-X',),
- ('-L', '-lpy'),
- ('-L', '-fhtml'),
- ('-L', '-Ox'),
- ('-S', 'default', '-l', 'py', '-f', 'html'),
- ('-S', 'default'),
- ('-a', 'arg'),
- ('-H',),
- (TESTFILE, TESTFILE),
- ('-H', 'formatter'),
- ('-H', 'foo', 'bar'),
- ('-s',),
- ('-s', TESTFILE),
- ]:
- self.check_failure(*opts, code=2)
-
- def test_errors(self):
- # input file not found
- e = self.check_failure('-lpython', 'nonexistent.py')
- self.assertTrue('Error: cannot read infile' in e)
- self.assertTrue('nonexistent.py' in e)
-
- # lexer not found
- e = self.check_failure('-lfooo', TESTFILE)
- self.assertTrue('Error: no lexer for alias' in e)
-
- # cannot load .py file without load_from_file flag
- e = self.check_failure('-l', 'nonexistent.py', TESTFILE)
- self.assertTrue('Error: no lexer for alias' in e)
-
- # lexer file is missing/unreadable
- e = self.check_failure('-l', 'nonexistent.py',
- '-x', TESTFILE)
- self.assertTrue('Error: cannot read' in e)
-
- # lexer file is malformed
- e = self.check_failure('-l', path.join(TESTDIR, 'support', 'empty.py'),
- '-x', TESTFILE)
- self.assertTrue('Error: no valid CustomLexer class found' in e)
-
- # formatter not found
- e = self.check_failure('-lpython', '-ffoo', TESTFILE)
- self.assertTrue('Error: no formatter found for name' in e)
-
- # formatter for outfile not found
- e = self.check_failure('-ofoo.foo', TESTFILE)
- self.assertTrue('Error: no formatter found for file name' in e)
-
- # cannot load .py file without load_from_file flag
- e = self.check_failure('-f', 'nonexistent.py', TESTFILE)
- self.assertTrue('Error: no formatter found for name' in e)
-
- # formatter file is missing/unreadable
- e = self.check_failure('-f', 'nonexistent.py',
- '-x', TESTFILE)
- self.assertTrue('Error: cannot read' in e)
-
- # formatter file is malformed
- e = self.check_failure('-f', path.join(TESTDIR, 'support', 'empty.py'),
- '-x', TESTFILE)
- self.assertTrue('Error: no valid CustomFormatter class found' in e)
-
- # output file not writable
- e = self.check_failure('-o', os.path.join('nonexistent', 'dir', 'out.html'),
- '-lpython', TESTFILE)
- self.assertTrue('Error: cannot open outfile' in e)
- self.assertTrue('out.html' in e)
-
- # unknown filter
- e = self.check_failure('-F', 'foo', TESTFILE)
- self.assertTrue('Error: filter \'foo\' not found' in e)
-
- def test_exception(self):
- cmdline.highlight = None # override callable to provoke TypeError
+def check_success(*cmdline, **kwds):
+ code, out, err = run_cmdline(*cmdline, **kwds)
+ assert code == 0
+ assert err == ''
+ return out
+
+
+def check_failure(*cmdline, **kwds):
+ expected_code = kwds.pop('code', 1)
+ code, out, err = run_cmdline(*cmdline, **kwds)
+ assert code == expected_code
+ assert out == ''
+ return err
+
+
+def test_normal():
+ # test that cmdline gives the same output as library api
+ from pygments.lexers import PythonLexer
+ from pygments.formatters import HtmlFormatter
+ filename = TESTFILE
+ with open(filename, 'rb') as fp:
+ code = fp.read()
+
+ output = highlight(code, PythonLexer(), HtmlFormatter())
+
+ o = check_success('-lpython', '-fhtml', filename)
+ assert o == output
+
+
+def test_stdin():
+ o = check_success('-lpython', '-fhtml', stdin=TESTCODE)
+ o = re.sub('<[^>]*>', '', o)
+ # rstrip is necessary since HTML inserts a \n after the last </div>
+ assert o.rstrip() == TESTCODE.rstrip()
+
+ # guess if no lexer given
+ o = check_success('-fhtml', stdin=TESTCODE)
+ o = re.sub('<[^>]*>', '', o)
+ # rstrip is necessary since HTML inserts a \n after the last </div>
+ assert o.rstrip() == TESTCODE.rstrip()
+
+
+def test_outfile():
+ # test that output file works with and without encoding
+ fd, name = tempfile.mkstemp()
+ os.close(fd)
+ for opts in [['-fhtml', '-o', name, TESTFILE],
+ ['-flatex', '-o', name, TESTFILE],
+ ['-fhtml', '-o', name, '-O', 'encoding=utf-8', TESTFILE]]:
try:
- # unexpected exception while highlighting
- e = self.check_failure('-lpython', TESTFILE)
- self.assertTrue('*** Error while highlighting:' in e)
- self.assertTrue('TypeError' in e)
-
- # same with -v: should reraise the exception
- try:
- self.check_failure('-lpython', '-v', TESTFILE)
- except Exception:
- pass
- else:
- self.fail('exception not reraised')
+ check_success(*opts)
finally:
- cmdline.highlight = highlight
+ os.unlink(name)
+
+
+def test_load_from_file():
+ lexer_file = os.path.join(TESTDIR, 'support', 'python_lexer.py')
+ formatter_file = os.path.join(TESTDIR, 'support', 'html_formatter.py')
+
+ # By default, use CustomLexer
+ o = check_success('-l', lexer_file, '-f', 'html', '-x', stdin=TESTCODE)
+ o = re.sub('<[^>]*>', '', o)
+ # rstrip is necessary since HTML inserts a \n after the last </div>
+ assert o.rstrip() == TESTCODE.rstrip()
+
+ # If user specifies a name, use it
+ o = check_success('-f', 'html', '-x', '-l',
+ lexer_file + ':LexerWrapper', stdin=TESTCODE)
+ o = re.sub('<[^>]*>', '', o)
+ # rstrip is necessary since HTML inserts a \n after the last </div>
+ assert o.rstrip() == TESTCODE.rstrip()
+
+ # Should also work for formatters
+ o = check_success('-lpython', '-f',
+ formatter_file + ':HtmlFormatterWrapper',
+ '-x', stdin=TESTCODE)
+ o = re.sub('<[^>]*>', '', o)
+ # rstrip is necessary since HTML inserts a \n after the last </div>
+ assert o.rstrip() == TESTCODE.rstrip()
+
+
+def test_stream_opt():
+ o = check_success('-lpython', '-s', '-fterminal', stdin=TESTCODE)
+ o = re.sub(r'\x1b\[.*?m', '', o)
+ assert o.replace('\r\n', '\n') == TESTCODE
+
+
+def test_h_opt():
+ o = check_success('-h')
+ assert 'Usage:' in o
+
+
+def test_L_opt():
+ o = check_success('-L')
+ assert 'Lexers' in o and 'Formatters' in o and 'Filters' in o and 'Styles' in o
+ o = check_success('-L', 'lexer')
+ assert 'Lexers' in o and 'Formatters' not in o
+ check_success('-L', 'lexers')
+
+
+def test_O_opt():
+ filename = TESTFILE
+ o = check_success('-Ofull=1,linenos=true,foo=bar', '-fhtml', filename)
+ assert '<html' in o
+ assert 'class="linenos"' in o
+
+ # "foobar" is invalid for a bool option
+ e = check_failure('-Ostripnl=foobar', TESTFILE)
+ assert 'Error: Invalid value' in e
+ e = check_failure('-Ostripnl=foobar', '-lpy')
+ assert 'Error: Invalid value' in e
+
+
+def test_P_opt():
+ filename = TESTFILE
+ o = check_success('-Pfull', '-Ptitle=foo, bar=baz=,', '-fhtml', filename)
+ assert '<title>foo, bar=baz=,</title>' in o
+
+
+def test_F_opt():
+ filename = TESTFILE
+ o = check_success('-Fhighlight:tokentype=Name.Blubb,'
+ 'names=TESTFILE filename', '-fhtml', filename)
+ assert '<span class="n n-Blubb' in o
+
+
+def test_H_opt():
+ o = check_success('-H', 'formatter', 'html')
+ assert 'HTML' in o
+ o = check_success('-H', 'lexer', 'python')
+ assert 'Python' in o
+ o = check_success('-H', 'filter', 'raiseonerror')
+ assert 'raiseonerror' in o
+ e = check_failure('-H', 'lexer', 'foobar')
+ assert 'not found' in e
+
+
+def test_S_opt():
+ o = check_success('-S', 'default', '-f', 'html', '-O', 'linenos=1')
+ lines = o.splitlines()
+ for line in lines:
+ # every line is for a token class
+ parts = line.split()
+ assert parts[0].startswith('.')
+ assert parts[1] == '{'
+ if parts[0] != '.hll':
+ assert parts[-4] == '}'
+ assert parts[-3] == '/*'
+ assert parts[-1] == '*/'
+ check_failure('-S', 'default', '-f', 'foobar')
+
+
+def test_N_opt():
+ o = check_success('-N', 'test.py')
+ assert 'python' == o.strip()
+ o = check_success('-N', 'test.unknown')
+ assert 'text' == o.strip()
+
+
+def test_invalid_opts():
+ for opts in [
+ ('-X',),
+ ('-L', '-lpy'),
+ ('-L', '-fhtml'),
+ ('-L', '-Ox'),
+ ('-S', 'default', '-l', 'py', '-f', 'html'),
+ ('-S', 'default'),
+ ('-a', 'arg'),
+ ('-H',),
+ (TESTFILE, TESTFILE),
+ ('-H', 'formatter'),
+ ('-H', 'foo', 'bar'),
+ ('-s',),
+ ('-s', TESTFILE),
+ ]:
+ check_failure(*opts, code=2)
+
+
+def test_errors():
+ # input file not found
+ e = check_failure('-lpython', 'nonexistent.py')
+ assert 'Error: cannot read infile' in e
+ assert 'nonexistent.py' in e
+
+ # lexer not found
+ e = check_failure('-lfooo', TESTFILE)
+ assert 'Error: no lexer for alias' in e
+
+ # cannot load .py file without load_from_file flag
+ e = check_failure('-l', 'nonexistent.py', TESTFILE)
+ assert 'Error: no lexer for alias' in e
+
+ # lexer file is missing/unreadable
+ e = check_failure('-l', 'nonexistent.py', '-x', TESTFILE)
+ assert 'Error: cannot read' in e
+
+ # lexer file is malformed
+ e = check_failure('-l', path.join(TESTDIR, 'support', 'empty.py'),
+ '-x', TESTFILE)
+ assert 'Error: no valid CustomLexer class found' in e
+
+ # formatter not found
+ e = check_failure('-lpython', '-ffoo', TESTFILE)
+ assert 'Error: no formatter found for name' in e
+
+ # formatter for outfile not found
+ e = check_failure('-ofoo.foo', TESTFILE)
+ assert 'Error: no formatter found for file name' in e
+
+ # cannot load .py file without load_from_file flag
+ e = check_failure('-f', 'nonexistent.py', TESTFILE)
+ assert 'Error: no formatter found for name' in e
+
+ # formatter file is missing/unreadable
+ e = check_failure('-f', 'nonexistent.py', '-x', TESTFILE)
+ assert 'Error: cannot read' in e
+
+ # formatter file is malformed
+ e = check_failure('-f', path.join(TESTDIR, 'support', 'empty.py'),
+ '-x', TESTFILE)
+ assert 'Error: no valid CustomFormatter class found' in e
+
+ # output file not writable
+ e = check_failure('-o', os.path.join('nonexistent', 'dir', 'out.html'),
+ '-lpython', TESTFILE)
+ assert 'Error: cannot open outfile' in e
+ assert 'out.html' in e
+
+ # unknown filter
+ e = check_failure('-F', 'foo', TESTFILE)
+ assert 'Error: filter \'foo\' not found' in e
+
+
+def test_exception():
+ cmdline.highlight = None # override callable to provoke TypeError
+ try:
+ # unexpected exception while highlighting
+ e = check_failure('-lpython', TESTFILE)
+ assert '*** Error while highlighting:' in e
+ assert 'TypeError' in e
+
+ # same with -v: should reraise the exception
+ assert raises(Exception, check_failure, '-lpython', '-v', TESTFILE)
+ finally:
+ cmdline.highlight = highlight
+
- def test_parse_opts(self):
- self.assertEqual(cmdline._parse_options([' ', 'keyonly,key = value ']),
- {'keyonly': True, 'key': 'value'})
+def test_parse_opts():
+ assert cmdline._parse_options([' ', 'keyonly,key = value ']) == \
+ {'keyonly': True, 'key': 'value'}