diff --git a/tests/test_cli.py b/tests/test_cli.py index f8550c9..a477061 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -14,10 +14,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO import os import shutil import tempfile import unittest +import sys from yamllint import cli @@ -27,14 +32,17 @@ class CommandLineTestCase(unittest.TestCase): self.wd = tempfile.mkdtemp(prefix='yamllint-tests-') # .yaml file at root - open(os.path.join(self.wd, 'a.yaml'), 'w').close() + with open(os.path.join(self.wd, 'a.yaml'), 'w') as f: + f.write('---\n' + '- 1 \n' + '- 2') # .yml file at root - open(os.path.join(self.wd, 'b.yml'), 'w').close() + open(os.path.join(self.wd, 'empty.yml'), 'w').close() # file in dir os.mkdir(os.path.join(self.wd, 'sub')) - with open(os.path.join(self.wd, 'sub', 'file.yaml'), 'w') as f: + with open(os.path.join(self.wd, 'sub', 'ok.yaml'), 'w') as f: f.write('---\n' 'key: value\n') @@ -45,10 +53,11 @@ class CommandLineTestCase(unittest.TestCase): os.mkdir(dir) with open(os.path.join(dir, 'file.yaml'), 'w') as f: f.write('---\n' - 'key: value\n') + 'key: value\n' + 'key: other value\n') # empty dir - os.mkdir(os.path.join(self.wd, 'empty')) + os.mkdir(os.path.join(self.wd, 'empty-dir')) # non-YAML file with open(os.path.join(self.wd, 'no-yaml.json'), 'w') as f: @@ -62,23 +71,23 @@ class CommandLineTestCase(unittest.TestCase): self.assertEqual( sorted(cli.find_files_recursively([self.wd])), [os.path.join(self.wd, 'a.yaml'), - os.path.join(self.wd, 'b.yml'), + os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), - os.path.join(self.wd, 'sub/file.yaml')], + os.path.join(self.wd, 'sub/ok.yaml')], ) - items = [os.path.join(self.wd, 'sub/file.yaml'), - os.path.join(self.wd, 'empty')] + items = [os.path.join(self.wd, 'sub/ok.yaml'), + os.path.join(self.wd, 'empty-dir')] self.assertEqual( sorted(cli.find_files_recursively(items)), - [os.path.join(self.wd, 'sub/file.yaml')], + [os.path.join(self.wd, 'sub/ok.yaml')], ) - items = [os.path.join(self.wd, 'b.yml'), + items = [os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's')] self.assertEqual( sorted(cli.find_files_recursively(items)), - [os.path.join(self.wd, 'b.yml'), + [os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml')], ) @@ -87,5 +96,149 @@ class CommandLineTestCase(unittest.TestCase): self.assertEqual( sorted(cli.find_files_recursively(items)), [os.path.join(self.wd, '/etc/another/file'), - os.path.join(self.wd, 'sub/file.yaml')], + os.path.join(self.wd, 'sub/ok.yaml')], ) + + 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') + + def test_run_with_bad_config(self): + sys.stdout, sys.stderr = StringIO(), StringIO() + with self.assertRaises(SystemExit) as ctx: + cli.run(('-d', 'rules: {a: b}', 'file')) + + self.assertEqual(ctx.exception.code, -1) + + out, err = sys.stdout.getvalue(), sys.stderr.getvalue() + self.assertRegexpMatches(out + err, r'^invalid config') + + 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_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_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_ok_file(self): + file = os.path.join(self.wd, 'sub', 'ok.yaml') + + 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_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_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_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, '')