""" Command line test ~~~~~~~~~~~~~~~~~ :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS. :license: BSD, see LICENSE for details. """ import io import os import re import sys import tempfile from io import BytesIO from os import path import pytest from pytest import raises from pygments import cmdline, highlight TESTDIR = path.dirname(path.abspath(__file__)) TESTFILE = path.join(TESTDIR, 'test_cmdline.py') TESTCODE = '''\ def func(args): pass ''' def _decode_output(text): try: return text.decode('utf-8') except UnicodeEncodeError: # implicit encode on Python 2 with data loss return text def run_cmdline(*args, **kwds): saved_stdin = sys.stdin saved_stdout = sys.stdout saved_stderr = sys.stderr stdin_buffer = BytesIO() stdout_buffer = BytesIO() stderr_buffer = BytesIO() new_stdin = sys.stdin = io.TextIOWrapper(stdin_buffer, 'utf-8') new_stdout = sys.stdout = io.TextIOWrapper(stdout_buffer, 'utf-8') new_stderr = sys.stderr = io.TextIOWrapper(stderr_buffer, 'utf-8') new_stdin.write(kwds.get('stdin', '')) new_stdin.seek(0, 0) try: ret = cmdline.main(['pygmentize'] + list(args)) finally: sys.stdin = saved_stdin sys.stdout = saved_stdout sys.stderr = saved_stderr new_stdout.flush() new_stderr.flush() out, err = stdout_buffer.getvalue(), \ stderr_buffer.getvalue() return (ret, _decode_output(out), _decode_output(err)) 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) try: code, out, err = run_cmdline(*cmdline, **kwds) except SystemExit as err: assert err.args[0] == expected_code else: 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 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 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: check_success(*opts) finally: 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 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 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 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 'foo, bar=baz=,' in o def test_F_opt(): filename = TESTFILE o = check_success('-Fhighlight:tokentype=Name.Blubb,' 'names=TESTFILE filename', '-fhtml', filename) assert '