diff options
author | Michal Gorny <mgorny@gentoo.org> | 2018-11-10 11:41:36 +0000 |
---|---|---|
committer | Michal Gorny <mgorny@gentoo.org> | 2018-11-10 11:41:36 +0000 |
commit | 8d3c930260730d83b6a8979800135df8ccb27148 (patch) | |
tree | 53238cc43e350cd879f5977bc52763dfa9ab72e2 /bindings/python/tests | |
parent | 4e24035ea29d2d9b4a210765a94d0615d9dd2674 (diff) |
[python] Support PathLike filenames and directories
Python 3.6 introduced a file system path protocol (PEP 519[1]).
The standard library APIs accepting file system paths now accept path
objects too. It could be useful to add this here as well
for convenience.
[1] https://www.python.org/dev/peps/pep-0519
Authored by: jstasiak (Jakub Stasiak)
Differential Revision: https://reviews.llvm.org/D54120
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@346586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'bindings/python/tests')
-rw-r--r-- | bindings/python/tests/cindex/test_cdb.py | 9 | ||||
-rw-r--r-- | bindings/python/tests/cindex/test_code_completion.py | 28 | ||||
-rw-r--r-- | bindings/python/tests/cindex/test_translation_unit.py | 68 | ||||
-rw-r--r-- | bindings/python/tests/cindex/util.py | 15 |
4 files changed, 120 insertions, 0 deletions
diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py index 5908239c46..589fc72856 100644 --- a/bindings/python/tests/cindex/test_cdb.py +++ b/bindings/python/tests/cindex/test_cdb.py @@ -11,6 +11,8 @@ import os import gc import unittest import sys +from .util import skip_if_no_fspath +from .util import str_to_path kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') @@ -37,6 +39,13 @@ class TestCDB(unittest.TestCase): cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') self.assertNotEqual(len(cmds), 0) + @skip_if_no_fspath + def test_lookup_succeed_pathlike(self): + """Same as test_lookup_succeed, but with PathLikes""" + cdb = CompilationDatabase.fromDirectory(str_to_path(kInputsDir)) + cmds = cdb.getCompileCommands(str_to_path('/home/john.doe/MyProject/project.cpp')) + self.assertNotEqual(len(cmds), 0) + def test_all_compilecommand(self): """Check we get all results from the db""" cdb = CompilationDatabase.fromDirectory(kInputsDir) diff --git a/bindings/python/tests/cindex/test_code_completion.py b/bindings/python/tests/cindex/test_code_completion.py index 9cd5a5ff62..e0b41577ae 100644 --- a/bindings/python/tests/cindex/test_code_completion.py +++ b/bindings/python/tests/cindex/test_code_completion.py @@ -6,6 +6,8 @@ if 'CLANG_LIBRARY_PATH' in os.environ: from clang.cindex import TranslationUnit import unittest +from .util import skip_if_no_fspath +from .util import str_to_path class TestCodeCompletion(unittest.TestCase): @@ -43,6 +45,32 @@ void f() { ] self.check_completion_results(cr, expected) + @skip_if_no_fspath + def test_code_complete_pathlike(self): + files = [(str_to_path('fake.c'), """ +/// Aaa. +int test1; + +/// Bbb. +void test2(void); + +void f() { + +} +""")] + + tu = TranslationUnit.from_source(str_to_path('fake.c'), ['-std=c99'], unsaved_files=files, + options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION) + + cr = tu.codeComplete(str_to_path('fake.c'), 9, 1, unsaved_files=files, include_brief_comments=True) + + expected = [ + "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.", + "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.", + "{'return', TypedText} || Priority: 40 || Availability: Available || Brief comment: None" + ] + self.check_completion_results(cr, expected) + def test_code_complete_availability(self): files = [('fake.cpp', """ class P { diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py index 0abfda8cea..b3075eb85d 100644 --- a/bindings/python/tests/cindex/test_translation_unit.py +++ b/bindings/python/tests/cindex/test_translation_unit.py @@ -20,6 +20,8 @@ from clang.cindex import TranslationUnitLoadError from clang.cindex import TranslationUnit from .util import get_cursor from .util import get_tu +from .util import skip_if_no_fspath +from .util import str_to_path kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') @@ -36,6 +38,17 @@ def save_tu(tu): yield t.name +@contextmanager +def save_tu_pathlike(tu): + """Convenience API to save a TranslationUnit to a file. + + Returns the filename it was saved to. + """ + with tempfile.NamedTemporaryFile() as t: + tu.save(str_to_path(t.name)) + yield t.name + + class TestTranslationUnit(unittest.TestCase): def test_spelling(self): path = os.path.join(kInputsDir, 'hello.cpp') @@ -89,6 +102,22 @@ int SOME_DEFINE; spellings = [c.spelling for c in tu.cursor.get_children()] self.assertEqual(spellings[-1], 'x') + @skip_if_no_fspath + def test_from_source_accepts_pathlike(self): + tu = TranslationUnit.from_source(str_to_path('fake.c'), ['-Iincludes'], unsaved_files = [ + (str_to_path('fake.c'), """ +#include "fake.h" + int x; + int SOME_DEFINE; + """), + (str_to_path('includes/fake.h'), """ +#define SOME_DEFINE y + """) + ]) + spellings = [c.spelling for c in tu.cursor.get_children()] + self.assertEqual(spellings[-2], 'x') + self.assertEqual(spellings[-1], 'y') + def assert_normpaths_equal(self, path1, path2): """ Compares two paths for equality after normalizing them with os.path.normpath @@ -135,6 +164,16 @@ int SOME_DEFINE; self.assertTrue(os.path.exists(path)) self.assertGreater(os.path.getsize(path), 0) + @skip_if_no_fspath + def test_save_pathlike(self): + """Ensure TranslationUnit.save() works with PathLike filename.""" + + tu = get_tu('int foo();') + + with save_tu_pathlike(tu) as path: + self.assertTrue(os.path.exists(path)) + self.assertGreater(os.path.getsize(path), 0) + def test_save_translation_errors(self): """Ensure that saving to an invalid directory raises.""" @@ -167,6 +206,22 @@ int SOME_DEFINE; # Just in case there is an open file descriptor somewhere. del tu2 + @skip_if_no_fspath + def test_load_pathlike(self): + """Ensure TranslationUnits can be constructed from saved files - + PathLike variant.""" + tu = get_tu('int foo();') + self.assertEqual(len(tu.diagnostics), 0) + with save_tu(tu) as path: + tu2 = TranslationUnit.from_ast_file(filename=str_to_path(path)) + self.assertEqual(len(tu2.diagnostics), 0) + + foo = get_cursor(tu2, 'foo') + self.assertIsNotNone(foo) + + # Just in case there is an open file descriptor somewhere. + del tu2 + def test_index_parse(self): path = os.path.join(kInputsDir, 'hello.cpp') index = Index.create() @@ -185,6 +240,19 @@ int SOME_DEFINE; with self.assertRaises(Exception): f = tu.get_file('foobar.cpp') + @skip_if_no_fspath + def test_get_file_pathlike(self): + """Ensure tu.get_file() works appropriately with PathLike filenames.""" + + tu = get_tu('int foo();') + + f = tu.get_file(str_to_path('t.c')) + self.assertIsInstance(f, File) + self.assertEqual(f.name, 't.c') + + with self.assertRaises(Exception): + f = tu.get_file(str_to_path('foobar.cpp')) + def test_get_source_location(self): """Ensure tu.get_source_location() works.""" diff --git a/bindings/python/tests/cindex/util.py b/bindings/python/tests/cindex/util.py index c53ba7c81b..57e17941c5 100644 --- a/bindings/python/tests/cindex/util.py +++ b/bindings/python/tests/cindex/util.py @@ -1,5 +1,15 @@ # This file provides common utility functions for the test suite. +import os +HAS_FSPATH = hasattr(os, 'fspath') + +if HAS_FSPATH: + from pathlib import Path as str_to_path +else: + str_to_path = None + +import unittest + from clang.cindex import Cursor from clang.cindex import TranslationUnit @@ -68,8 +78,13 @@ def get_cursors(source, spelling): return cursors +skip_if_no_fspath = unittest.skipUnless(HAS_FSPATH, + "Requires file system path protocol / Python 3.6+") + __all__ = [ 'get_cursor', 'get_cursors', 'get_tu', + 'skip_if_no_fspath', + 'str_to_path', ] |