Home | History | Annotate | Download | only in test
      1 import keyword
      2 import unittest
      3 from test import support
      4 import filecmp
      5 import os
      6 import sys
      7 import subprocess
      8 import shutil
      9 import textwrap
     10 
     11 KEYWORD_FILE             = support.findfile('keyword.py')
     12 GRAMMAR_FILE             = os.path.join(os.path.split(__file__)[0],
     13                                         '..', '..', 'Python', 'graminit.c')
     14 TEST_PY_FILE             = 'keyword_test.py'
     15 GRAMMAR_TEST_FILE        = 'graminit_test.c'
     16 PY_FILE_WITHOUT_KEYWORDS = 'minimal_keyword.py'
     17 NONEXISTENT_FILE         = 'not_here.txt'
     18 
     19 
     20 class Test_iskeyword(unittest.TestCase):
     21     def test_true_is_a_keyword(self):
     22         self.assertTrue(keyword.iskeyword('True'))
     23 
     24     def test_uppercase_true_is_not_a_keyword(self):
     25         self.assertFalse(keyword.iskeyword('TRUE'))
     26 
     27     def test_none_value_is_not_a_keyword(self):
     28         self.assertFalse(keyword.iskeyword(None))
     29 
     30     # This is probably an accident of the current implementation, but should be
     31     # preserved for backward compatibility.
     32     def test_changing_the_kwlist_does_not_affect_iskeyword(self):
     33         oldlist = keyword.kwlist
     34         self.addCleanup(setattr, keyword, 'kwlist', oldlist)
     35         keyword.kwlist = ['its', 'all', 'eggs', 'beans', 'and', 'a', 'slice']
     36         self.assertFalse(keyword.iskeyword('eggs'))
     37 
     38 
     39 class TestKeywordGeneration(unittest.TestCase):
     40 
     41     def _copy_file_without_generated_keywords(self, source_file, dest_file):
     42         with open(source_file, 'rb') as fp:
     43             lines = fp.readlines()
     44         nl = lines[0][len(lines[0].strip()):]
     45         with open(dest_file, 'wb') as fp:
     46             fp.writelines(lines[:lines.index(b"#--start keywords--" + nl) + 1])
     47             fp.writelines(lines[lines.index(b"#--end keywords--" + nl):])
     48 
     49     def _generate_keywords(self, grammar_file, target_keyword_py_file):
     50         proc = subprocess.Popen([sys.executable,
     51                                  KEYWORD_FILE,
     52                                  grammar_file,
     53                                  target_keyword_py_file], stderr=subprocess.PIPE)
     54         stderr = proc.communicate()[1]
     55         return proc.returncode, stderr
     56 
     57     @unittest.skipIf(not os.path.exists(GRAMMAR_FILE),
     58                      'test only works from source build directory')
     59     def test_real_grammar_and_keyword_file(self):
     60         self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE)
     61         self.addCleanup(support.unlink, TEST_PY_FILE)
     62         self.assertFalse(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE))
     63         self.assertEqual((0, b''), self._generate_keywords(GRAMMAR_FILE,
     64                                                            TEST_PY_FILE))
     65         self.assertTrue(filecmp.cmp(KEYWORD_FILE, TEST_PY_FILE))
     66 
     67     def test_grammar(self):
     68         self._copy_file_without_generated_keywords(KEYWORD_FILE, TEST_PY_FILE)
     69         self.addCleanup(support.unlink, TEST_PY_FILE)
     70         with open(GRAMMAR_TEST_FILE, 'w') as fp:
     71             # Some of these are probably implementation accidents.
     72             fp.writelines(textwrap.dedent("""\
     73                 {2, 1},
     74                     {11, "encoding_decl", 0, 2, states_79,
     75                      "\000\000\040\000\000\000\000\000\000\000\000\000"
     76                      "\000\000\000\000\000\000\000\000\000"},
     77                     {1, "jello"},
     78                     {326, 0},
     79                     {1, "turnip"},
     80                 \t{1, "This one is tab indented"
     81                     {278, 0},
     82                     {1, "crazy but legal"
     83                 "also legal" {1, "
     84                     {1, "continue"},
     85                    {1, "lemon"},
     86                      {1, "tomato"},
     87                 {1, "wigii"},
     88                     {1, 'no good'}
     89                     {283, 0},
     90                     {1,  "too many spaces"}"""))
     91         self.addCleanup(support.unlink, GRAMMAR_TEST_FILE)
     92         self._generate_keywords(GRAMMAR_TEST_FILE, TEST_PY_FILE)
     93         expected = [
     94             "        'This one is tab indented',",
     95             "        'also legal',",
     96             "        'continue',",
     97             "        'crazy but legal',",
     98             "        'jello',",
     99             "        'lemon',",
    100             "        'tomato',",
    101             "        'turnip',",
    102             "        'wigii',",
    103             ]
    104         with open(TEST_PY_FILE) as fp:
    105             lines = fp.read().splitlines()
    106         start = lines.index("#--start keywords--") + 1
    107         end = lines.index("#--end keywords--")
    108         actual = lines[start:end]
    109         self.assertEqual(actual, expected)
    110 
    111     def test_empty_grammar_results_in_no_keywords(self):
    112         self._copy_file_without_generated_keywords(KEYWORD_FILE,
    113                                                    PY_FILE_WITHOUT_KEYWORDS)
    114         self.addCleanup(support.unlink, PY_FILE_WITHOUT_KEYWORDS)
    115         shutil.copyfile(KEYWORD_FILE, TEST_PY_FILE)
    116         self.addCleanup(support.unlink, TEST_PY_FILE)
    117         self.assertEqual((0, b''), self._generate_keywords(os.devnull,
    118                                                            TEST_PY_FILE))
    119         self.assertTrue(filecmp.cmp(TEST_PY_FILE, PY_FILE_WITHOUT_KEYWORDS))
    120 
    121     def test_keywords_py_without_markers_produces_error(self):
    122         rc, stderr = self._generate_keywords(os.devnull, os.devnull)
    123         self.assertNotEqual(rc, 0)
    124         self.assertRegex(stderr, b'does not contain format markers')
    125 
    126     def test_missing_grammar_file_produces_error(self):
    127         rc, stderr = self._generate_keywords(NONEXISTENT_FILE, KEYWORD_FILE)
    128         self.assertNotEqual(rc, 0)
    129         self.assertRegex(stderr, b'(?ms)' + NONEXISTENT_FILE.encode())
    130 
    131     def test_missing_keywords_py_file_produces_error(self):
    132         rc, stderr = self._generate_keywords(os.devnull, NONEXISTENT_FILE)
    133         self.assertNotEqual(rc, 0)
    134         self.assertRegex(stderr, b'(?ms)' + NONEXISTENT_FILE.encode())
    135 
    136 
    137 if __name__ == "__main__":
    138     unittest.main()
    139