def test_run_default_format_output_in_tty(self): path = os.path.join(self.wd, 'a.yaml') # Create a pseudo-TTY and redirect stdout to it master, slave = pty.openpty() sys.stdout = sys.stderr = os.fdopen(slave, 'w') with self.assertRaises(SystemExit) as ctx: cli.run((path, )) sys.stdout.flush() self.assertEqual(ctx.exception.code, 1) # Read output from TTY output = os.fdopen(master, 'r') flag = fcntl.fcntl(master, fcntl.F_GETFD) fcntl.fcntl(master, fcntl.F_SETFL, flag | os.O_NONBLOCK) out = output.read().replace('\r\n', '\n') sys.stdout.close() sys.stderr.close() output.close() self.assertEqual(out, ('\033[4m%s\033[0m\n' ' \033[2m2:4\033[0m \033[31merror\033[0m ' 'trailing spaces \033[2m(trailing-spaces)\033[0m\n' ' \033[2m3:4\033[0m \033[31merror\033[0m ' 'no new line character at the end of file ' '\033[2m(new-line-at-end-of-file)\033[0m\n' '\n' % path))
def test_run_no_warnings(self): file = os.path.join(self.wd, 'a.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run((file, '--no-warnings', '-f', 'auto')) self.assertEqual(ctx.exception.code, 1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, ( '%s\n' ' 2:4 error trailing spaces (trailing-spaces)\n' ' 3:4 error no new line character at the end of file ' '(new-line-at-end-of-file)\n' '\n' % file)) self.assertEqual(err, '') file = os.path.join(self.wd, 'warn.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run((file, '--no-warnings', '-f', 'auto')) self.assertEqual(ctx.exception.code, 0)
def test_run_with_user_global_config_file(self): home = os.path.join(self.wd, 'fake-home') os.mkdir(home) dir = os.path.join(home, '.config') os.mkdir(dir) dir = os.path.join(dir, 'yamllint') os.mkdir(dir) config = os.path.join(dir, 'config') temp = os.environ['HOME'] os.environ['HOME'] = home with open(config, 'w') as f: f.write('rules: {trailing-spaces: disable}') with self.assertRaises(SystemExit) as ctx: cli.run((os.path.join(self.wd, 'a.yaml'), )) self.assertEqual(ctx.exception.code, 0) with open(config, 'w') as f: f.write('rules: {trailing-spaces: enable}') with self.assertRaises(SystemExit) as ctx: cli.run((os.path.join(self.wd, 'a.yaml'), )) self.assertEqual(ctx.exception.code, 1) os.environ['HOME'] = temp
def test_colcon_mixins(): any_error = False mixins_dir = pkg_resources.resource_filename('ros_cross_compile', 'mixins') for name in sorted(os.listdir(mixins_dir)): if name != 'index.yaml' and not name.endswith('.mixin'): continue try: run([ '--config-data', '{' 'extends: default, ' 'rules: {' 'document-start: {present: false}, ' 'empty-lines: {max: 0}, ' 'key-ordering: {}, ' 'line-length: {max: 999}' '}' '}', '--strict', os.path.join(mixins_dir, name), ]) except SystemExit as e: any_error |= bool(e.code) continue assert not any_error, 'Should not have seen any errors'
def test_run_colored_output(self): file = os.path.join(self.wd, 'a.yaml') # Create a pseudo-TTY and redirect stdout to it master, slave = pty.openpty() sys.stdout = sys.stderr = os.fdopen(slave, 'w') with self.assertRaises(SystemExit) as ctx: cli.run((file, )) sys.stdout.flush() self.assertEqual(ctx.exception.code, 1) # Read output from TTY output = os.fdopen(master, 'r') flag = fcntl.fcntl(master, fcntl.F_GETFD) fcntl.fcntl(master, fcntl.F_SETFL, flag | os.O_NONBLOCK) out = output.read().replace('\r\n', '\n') sys.stdout.close() sys.stderr.close() output.close() self.assertEqual(out, ( '\033[4m%s\033[0m\n' ' \033[2m2:4\033[0m \033[31merror\033[0m ' 'trailing spaces \033[2m(trailing-spaces)\033[0m\n' ' \033[2m3:4\033[0m \033[31merror\033[0m ' 'no new line character at the end of file ' '\033[2m(new-line-at-end-of-file)\033[0m\n' '\n' % file))
def test_json_output(self): path = os.path.join(self.wd, 'a.yaml') with RunContext(self) as ctx: cli.run(('-f', 'json', path)) print (ctx.stdout) self.assertTrue(json.loads(ctx.stdout))
def test_run_non_existing_file(self): path = os.path.join(self.wd, 'i-do-not-exist.yaml') with RunContext(self) as ctx: cli.run(('-f', 'parsable', path)) self.assertEqual(ctx.returncode, -1) self.assertEqual(ctx.stdout, '') self.assertRegexpMatches(ctx.stderr, r'No such file or directory')
def test_run_warning_in_strict_mode(self): file = os.path.join(self.wd, 'warn.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('-f', 'parsable', '--strict', file)) self.assertEqual(ctx.exception.code, 2)
def test_run_non_ascii_file(self): locale.setlocale(locale.LC_ALL, 'C.UTF-8') self.addCleanup(locale.setlocale, locale.LC_ALL, (None, None)) path = os.path.join(self.wd, 'non-ascii', 'éçäγλνπ¥', 'utf-8') with RunContext(self) as ctx: cli.run(('-f', 'parsable', path)) self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (0, '', ''))
def test_run_no_warnings_and_strict(self): file = os.path.join(self.wd, 'warn.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run((file, '--no-warnings', '-s')) self.assertEqual(ctx.exception.code, 2)
def test_run_version(self): sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('--version', )) self.assertEqual(ctx.exception.code, 0) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertRegexpMatches(out + err, r'yamllint \d+\.\d+')
def test_run_with_empty_config(self): sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('-d', '', 'file')) self.assertEqual(ctx.exception.code, -1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, '') self.assertRegexpMatches(err, r'^invalid config: not a dict')
def test_run_multiple_files(self): items = [os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's')] path = items[1] + '/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml' with RunContext(self) as ctx: cli.run(['-f', 'parsable'] + items) self.assertEqual((ctx.returncode, ctx.stderr), (1, '')) self.assertEqual(ctx.stdout, ( '%s:3:1: [error] duplication of key "key" in mapping ' '(key-duplicates)\n') % path)
def test_run_one_problem_file(self): path = os.path.join(self.wd, 'a.yaml') with RunContext(self) as ctx: cli.run(('-f', 'parsable', path)) self.assertEqual(ctx.returncode, 1) self.assertEqual(ctx.stdout, ( '%s:2:4: [error] trailing spaces (trailing-spaces)\n' '%s:3:4: [error] no new line character at the end of file ' '(new-line-at-end-of-file)\n' % (path, path))) self.assertEqual(ctx.stderr, '')
def test_run_non_existing_file(self): file = os.path.join(self.wd, 'i-do-not-exist.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('-f', 'parsable', file)) self.assertEqual(ctx.exception.code, -1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, '') self.assertRegexpMatches(err, r'No such file or directory')
def test_run_read_from_stdin(self): # prepares stdin with an invalid yaml string so that we can check # for its specific error, and be assured that stdin was read self.addCleanup(setattr, sys, 'stdin', sys.__stdin__) sys.stdin = StringIO('I am a string\n' 'therefore: I am an error\n') with RunContext(self) as ctx: cli.run(('-', '-f', 'parsable')) expected_out = ('stdin:2:10: [error] syntax error: ' 'mapping values are not allowed here (syntax)\n') self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, ''))
def test_run_format_github(self): path = os.path.join(self.wd, 'a.yaml') with RunContext(self) as ctx: cli.run((path, '--format', 'github')) expected_out = ( '::error file=%s,line=2,col=4::[trailing-spaces] trailing' ' spaces\n' '::error file=%s,line=3,col=4::[new-line-at-end-of-file] no' ' new line character at the end of file\n' % (path, path)) self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, ''))
def test_run_empty_file(self): file = os.path.join(self.wd, 'empty.yml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('-f', 'parsable', file)) self.assertEqual(ctx.exception.code, 0) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, '') self.assertEqual(err, '')
def test_run_piped_output_nocolor(self): path = os.path.join(self.wd, 'a.yaml') with RunContext(self) as ctx: cli.run((path, )) self.assertEqual((ctx.returncode, ctx.stderr), (1, '')) self.assertEqual(ctx.stdout, ( '%s\n' ' 2:4 error trailing spaces (trailing-spaces)\n' ' 3:4 error no new line character at the end of file ' '(new-line-at-end-of-file)\n' '\n' % path))
def test_run_auto_output_without_tty_output(self): path = os.path.join(self.wd, 'a.yaml') with RunContext(self) as ctx: cli.run((path, '--format', 'auto')) expected_out = ( '%s\n' ' 2:4 error trailing spaces (trailing-spaces)\n' ' 3:4 error no new line character at the end of file ' '(new-line-at-end-of-file)\n' '\n' % path) self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, ''))
def test_run_with_config_file(self): with open(os.path.join(self.wd, 'config'), 'w') as f: f.write('rules: {trailing-spaces: disable}') with RunContext(self) as ctx: cli.run(('-c', f.name, os.path.join(self.wd, 'a.yaml'))) self.assertEqual(ctx.returncode, 0) with open(os.path.join(self.wd, 'config'), 'w') as f: f.write('rules: {trailing-spaces: enable}') with RunContext(self) as ctx: cli.run(('-c', f.name, os.path.join(self.wd, 'a.yaml'))) self.assertEqual(ctx.returncode, 1)
def test_run_with_bad_arguments(self): with RunContext(self) as ctx: cli.run(()) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') self.assertRegexpMatches(ctx.stderr, r'^usage') with RunContext(self) as ctx: cli.run(('--unknown-arg', )) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') self.assertRegexpMatches(ctx.stderr, r'^usage') with RunContext(self) as ctx: cli.run(('-c', './conf.yaml', '-d', 'relaxed', 'file')) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') self.assertRegexpMatches( ctx.stderr.splitlines()[-1], r'^yamllint: error: argument -d\/--config-data: ' r'not allowed with argument -c\/--config-file$') # checks if reading from stdin and files are mutually exclusive with RunContext(self) as ctx: cli.run(('-', 'file')) self.assertNotEqual(ctx.returncode, 0) self.assertEqual(ctx.stdout, '') self.assertRegexpMatches(ctx.stderr, r'^usage')
def test_run_format_colored(self): path = os.path.join(self.wd, 'a.yaml') with RunContext(self) as ctx: cli.run((path, '--format', 'colored')) expected_out = ('\033[4m%s\033[0m\n' ' \033[2m2:4\033[0m \033[31merror\033[0m ' 'trailing spaces \033[2m(trailing-spaces)\033[0m\n' ' \033[2m3:4\033[0m \033[31merror\033[0m ' 'no new line character at the end of file ' '\033[2m(new-line-at-end-of-file)\033[0m\n' '\n' % path) self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, ''))
def test_run_with_config_file(self): with open(os.path.join(self.wd, 'config'), 'w') as f: f.write('rules: {trailing-spaces: disable}') with self.assertRaises(SystemExit) as ctx: cli.run(('-c', f.name, os.path.join(self.wd, 'a.yaml'))) self.assertEqual(ctx.exception.code, 0) with open(os.path.join(self.wd, 'config'), 'w') as f: f.write('rules: {trailing-spaces: enable}') with self.assertRaises(SystemExit) as ctx: cli.run(('-c', f.name, os.path.join(self.wd, 'a.yaml'))) self.assertEqual(ctx.exception.code, 1)
def test_run_one_problem_file(self): file = os.path.join(self.wd, 'a.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('-f', 'parsable', file)) self.assertEqual(ctx.exception.code, 1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, ( '%s:2:4: [error] trailing spaces (trailing-spaces)\n' '%s:3:4: [error] no new line character at the end of file ' '(new-line-at-end-of-file)\n') % (file, file)) self.assertEqual(err, '')
def test_run_one_problem_file(self): file = os.path.join(self.wd, 'a.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('-f', 'parsable', file)) self.assertEqual(ctx.exception.code, 1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual( out, ('%s:2:4: [error] trailing spaces (trailing-spaces)\n' '%s:3:4: [error] no new line character at the end of file ' '(new-line-at-end-of-file)\n') % (file, file)) self.assertEqual(err, '')
def test_run_read_from_stdin(self): # prepares stdin with an invalid yaml string so that we can check # for its specific error, and be assured that stdin was read sys.stdout, sys.stderr = StringIO(), StringIO() sys.stdin = StringIO('I am a string\n' 'therefore: I am an error\n') with self.assertRaises(SystemExit) as ctx: cli.run(('-', '-f', 'parsable')) self.assertNotEqual(ctx.exception.code, 0) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, ('stdin:2:10: [error] syntax error: ' 'mapping values are not allowed here\n')) self.assertEqual(err, '')
def test_run_non_ascii_file(self): path = os.path.join(self.wd, 'non-ascii', 'éçäγλνπ¥', 'utf-8') # Make sure the default localization conditions on this "system" # support UTF-8 encoding. loc = locale.getlocale() try: locale.setlocale(locale.LC_ALL, 'C.UTF-8') except locale.Error: locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') self.addCleanup(locale.setlocale, locale.LC_ALL, loc) with RunContext(self) as ctx: cli.run(('-f', 'parsable', path)) self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (0, '', ''))
def test_github_actions_detection(self): path = os.path.join(self.wd, 'a.yaml') self.addCleanup(os.environ.__delitem__, 'GITHUB_ACTIONS') self.addCleanup(os.environ.__delitem__, 'GITHUB_WORKFLOW') with RunContext(self) as ctx: os.environ['GITHUB_ACTIONS'] = 'something' os.environ['GITHUB_WORKFLOW'] = 'something' cli.run((path, )) expected_out = ( '::error file=%s,line=2,col=4::[trailing-spaces] trailing' ' spaces\n' '::error file=%s,line=3,col=4::[new-line-at-end-of-file] no' ' new line character at the end of file\n' % (path, path)) self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, ''))
def test_run_multiple_files(self): items = [os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's')] file = items[1] + '/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml' sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(['-f', 'parsable'] + items) self.assertEqual(ctx.exception.code, 1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, ( '%s:3:1: [error] duplication of key "key" in mapping ' '(key-duplicates)\n') % file) self.assertEqual(err, '')
def test_run_non_universal_newline(self): path = os.path.join(self.wd, 'dos.yml') with RunContext(self) as ctx: cli.run(('-d', 'rules:\n new-lines:\n type: dos', path)) self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (0, '', '')) with RunContext(self) as ctx: cli.run(('-d', 'rules:\n new-lines:\n type: unix', path)) expected_out = ( '%s\n' ' 1:4 error wrong new line character: expected \\n' ' (new-lines)\n' '\n' % path) self.assertEqual((ctx.returncode, ctx.stdout, ctx.stderr), (1, expected_out, ''))
def test_run_default_format_output_without_tty(self): file = os.path.join(self.wd, 'a.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run((file, )) self.assertEqual(ctx.exception.code, 1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, ( '%s\n' ' 2:4 error trailing spaces (trailing-spaces)\n' ' 3:4 error no new line character at the end of file ' '(new-line-at-end-of-file)\n' '\n' % file)) self.assertEqual(err, '')
def test_run_piped_output_nocolor(self): file = os.path.join(self.wd, 'a.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run((file, )) self.assertEqual(ctx.exception.code, 1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, ( '%s\n' ' 2:4 error trailing spaces (trailing-spaces)\n' ' 3:4 error no new line character at the end of file ' '(new-line-at-end-of-file)\n' '\n' % file)) self.assertEqual(err, '')
def test_run_non_ascii_file(self): file = os.path.join(self.wd, 'non-ascii', 'utf-8') # Make sure the default localization conditions on this "system" # support UTF-8 encoding. loc = locale.getlocale() locale.setlocale(locale.LC_ALL, 'C.UTF-8') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('-f', 'parsable', file)) locale.setlocale(locale.LC_ALL, loc) self.assertEqual(ctx.exception.code, 0) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, '') self.assertEqual(err, '')
def test_run_colored_output(self): file = os.path.join(self.wd, 'a.yaml') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run((file, )) self.assertEqual(ctx.exception.code, 1) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, ( '\033[4m%s\033[0m\n' ' \033[2m2:4\033[0m \033[31merror\033[0m ' 'trailing spaces \033[2m(trailing-spaces)\033[0m\n' ' \033[2m3:4\033[0m \033[31merror\033[0m ' 'no new line character at the end of file ' '\033[2m(new-line-at-end-of-file)\033[0m\n' '\n' % file)) self.assertEqual(err, '')
def test_run_with_bad_arguments(self): sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(()) self.assertNotEqual(ctx.exception.code, 0) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, '') self.assertRegexpMatches(err, r'^usage') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('--unknown-arg', )) self.assertNotEqual(ctx.exception.code, 0) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, '') self.assertRegexpMatches(err, r'^usage') sys.stdout, sys.stderr = StringIO(), StringIO() with self.assertRaises(SystemExit) as ctx: cli.run(('-c', './conf.yaml', '-d', 'relaxed', 'file')) self.assertNotEqual(ctx.exception.code, 0) out, err = sys.stdout.getvalue(), sys.stderr.getvalue() self.assertEqual(out, '') self.assertRegexpMatches(err, r'^Options --config-file and ' r'--config-data cannot be used')