| import keyword |
| import unittest |
| from test import support |
| import filecmp |
| import os |
| import sys |
| import subprocess |
| import shutil |
| import textwrap |
| |
| KEYWORD_FILE = support.findfile('keyword.py') |
| GRAMMAR_FILE = os.path.join(os.path.split(__file__)[0], |
| '..', '..', 'Python', 'graminit.c') |
| TEST_PY_FILE = 'keyword_test.py' |
| GRAMMAR_TEST_FILE = 'graminit_test.c' |
| PY_FILE_WITHOUT_KEYWORDS = 'minimal_keyword.py' |
| NONEXISTENT_FILE = 'not_here.txt' |
| |
| |
| class Test_iskeyword(unittest.TestCase): |
| def test_true_is_a_keyword(self): |
| self.assertTrue(keyword.iskeyword('True')) |
| |
| def test_uppercase_true_is_not_a_keyword(self): |
| self.assertFalse(keyword.iskeyword('TRUE')) |
| |
| def test_none_value_is_not_a_keyword(self): |
| self.assertFalse(keyword.iskeyword(None)) |
| |
| # This is probably an accident of the current implementation, but should be |
| # preserved for backward compatibility. |
| def test_changing_the_kwlist_does_not_affect_iskeyword(self): |
| oldlist = keyword.kwlist |
| self.addCleanup(setattr, keyword, 'kwlist', oldlist) |
| keyword.kwlist = ['its', 'all', 'eggs', 'beans', 'and', 'a', 'slice'] |
| self.assertFalse(keyword.iskeyword('eggs')) |
| |
| |
| class TestKeywordGeneration(unittest.TestCase): |
| |
| def _copy_file_without_generated_keywords(self, source_file, dest_file): |
| with open(source_file, 'rb') as fp: |
| lines = fp.readlines() |
| nl = lines[0][len(lines[0].strip()):] |
| with open(dest_file, 'wb') as fp: |
| fp.writelines(lines[:lines.index(b"#--start keywords--" + nl) + 1]) |
| fp.writelines(lines[lines.index(b"#--end keywords--" + nl):]) |
| |
| def _generate_keywords(self, grammar_file, target_keyword_py_file): |
| proc = subprocess.Popen([sys.executable, |
| KEYWORD_FILE, |
| grammar_file, |
| target_keyword_py_file], stderr=subprocess.PIPE) |
| stderr = proc.communicate()[1] |
| return proc.returncode, stderr |
| |
| @unittest.skipIf(not os.path.exists(GRAMMAR_FILE), |
| 'test only works from source build directory') |
| def test_real_grammar_and_keyword_file(self): |
| self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE) |
| self.addCleanup(support.unlink, TEST_PY_FILE) |
| self.assertFalse(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE)) |
| self.assertEqual((0, b''), self._generate_keywords(GRAMMAR_FILE, |
| TEST_PY_FILE)) |
| self.assertTrue(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE)) |
| |
| def test_grammar(self): |
| self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE) |
| self.addCleanup(support.unlink, TEST_PY_FILE) |
| with open(GRAMMAR_TEST_FILE, 'w') as fp: |
| # Some of these are probably implementation accidents. |
| fp.writelines(textwrap.dedent("""\ |
| {2, 1}, |
| {11, "encoding_decl", 0, 2, states_79, |
| "\000\000\040\000\000\000\000\000\000\000\000\000" |
| "\000\000\000\000\000\000\000\000\000"}, |
| {1, "jello"}, |
| {326, 0}, |
| {1, "turnip"}, |
| \t{1, "This one is tab indented" |
| {278, 0}, |
| {1, "crazy but legal" |
| "also legal" {1, " |
| {1, "continue"}, |
| {1, "lemon"}, |
| {1, "tomato"}, |
| {1, "wigii"}, |
| {1, 'no good'} |
| {283, 0}, |
| {1, "too many spaces"}""")) |
| self.addCleanup(support.unlink, GRAMMAR_TEST_FILE) |
| self._generate_keywords(GRAMMAR_TEST_FILE, TEST_PY_FILE) |
| expected = [ |
| " 'This one is tab indented',", |
| " 'also legal',", |
| " 'continue',", |
| " 'crazy but legal',", |
| " 'jello',", |
| " 'lemon',", |
| " 'tomato',", |
| " 'turnip',", |
| " 'wigii',", |
| ] |
| with open(TEST_PY_FILE) as fp: |
| lines = fp.read().splitlines() |
| start = lines.index("#--start keywords--") + 1 |
| end = lines.index("#--end keywords--") |
| actual = lines[start:end] |
| self.assertEqual(actual, expected) |
| |
| def test_empty_grammar_results_in_no_keywords(self): |
| self._copy_file_without_generated_keywords(KEYWORD_FILE, |
| PY_FILE_WITHOUT_KEYWORDS) |
| self.addCleanup(support.unlink, PY_FILE_WITHOUT_KEYWORDS) |
| shutil.copyfile(KEYWORD_FILE, TEST_PY_FILE) |
| self.addCleanup(support.unlink, TEST_PY_FILE) |
| self.assertEqual((0, b''), self._generate_keywords(os.devnull, |
| TEST_PY_FILE)) |
| self.assertTrue(filecmp.cmp(TEST_PY_FILE, PY_FILE_WITHOUT_KEYWORDS)) |
| |
| def test_keywords_py_without_markers_produces_error(self): |
| rc, stderr = self._generate_keywords(os.devnull, os.devnull) |
| self.assertNotEqual(rc, 0) |
| self.assertRegex(stderr, b'does not contain format markers') |
| |
| def test_missing_grammar_file_produces_error(self): |
| rc, stderr = self._generate_keywords(NONEXISTENT_FILE, KEYWORD_FILE) |
| self.assertNotEqual(rc, 0) |
| self.assertRegex(stderr, b'(?ms)' + NONEXISTENT_FILE.encode()) |
| |
| def test_missing_keywords_py_file_produces_error(self): |
| rc, stderr = self._generate_keywords(os.devnull, NONEXISTENT_FILE) |
| self.assertNotEqual(rc, 0) |
| self.assertRegex(stderr, b'(?ms)' + NONEXISTENT_FILE.encode()) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |