Compare commits
6 Commits
231908da78
...
14e1d3fc53
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14e1d3fc53 | ||
|
|
d7802d89d6 | ||
|
|
325afe0335 | ||
|
|
f3ebd18def | ||
|
|
7cab6e2ecc | ||
|
|
1b1b1abf92 |
@@ -139,7 +139,7 @@ end
|
|||||||
---@param positions neotest.Tree
|
---@param positions neotest.Tree
|
||||||
---@param root string
|
---@param root string
|
||||||
local function discover_params(python, script, path, positions, root)
|
local function discover_params(python, script, path, positions, root)
|
||||||
local cmd = vim.tbl_flatten({ python, script, "--pytest-collect", path })
|
local cmd = vim.iter({ python, script, "--pytest-collect", path }):flatten():totable()
|
||||||
logger.debug("Running test instance discovery:", cmd)
|
logger.debug("Running test instance discovery:", cmd)
|
||||||
|
|
||||||
local test_params = {}
|
local test_params = {}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
import unittest
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from types import TracebackType
|
from types import TracebackType
|
||||||
@@ -33,12 +31,26 @@ class CaseUtilsMixin:
|
|||||||
|
|
||||||
|
|
||||||
class DjangoNeotestAdapter(CaseUtilsMixin, NeotestAdapter):
|
class DjangoNeotestAdapter(CaseUtilsMixin, NeotestAdapter):
|
||||||
|
def get_django_root(self, path: str) -> Path:
|
||||||
|
"""
|
||||||
|
Traverse the file system to locate the nearest manage.py parent
|
||||||
|
from the location of a given path.
|
||||||
|
|
||||||
|
This is the location of the django project
|
||||||
|
"""
|
||||||
|
test_file_path = Path(path).resolve()
|
||||||
|
for parent in [test_file_path] + list(test_file_path.parents):
|
||||||
|
if (parent / "manage.py").exists():
|
||||||
|
return parent
|
||||||
|
raise FileNotFoundError("manage.py not found")
|
||||||
|
|
||||||
def convert_args(self, case_id: str, args: List[str]) -> List[str]:
|
def convert_args(self, case_id: str, args: List[str]) -> List[str]:
|
||||||
"""Converts a neotest ID into test specifier for unittest"""
|
"""Converts a neotest ID into test specifier for unittest"""
|
||||||
path, *child_ids = case_id.split("::")
|
path, *child_ids = case_id.split("::")
|
||||||
if not child_ids:
|
if not child_ids:
|
||||||
child_ids = []
|
child_ids = []
|
||||||
relative_file = os.path.relpath(path, os.getcwd())
|
django_root = self.get_django_root(path)
|
||||||
|
relative_file = os.path.relpath(path, django_root)
|
||||||
relative_stem = os.path.splitext(relative_file)[0]
|
relative_stem = os.path.splitext(relative_file)[0]
|
||||||
relative_dotted = relative_stem.replace(os.sep, ".")
|
relative_dotted = relative_stem.replace(os.sep, ".")
|
||||||
return [*args, ".".join([relative_dotted, *child_ids])]
|
return [*args, ".".join([relative_dotted, *child_ids])]
|
||||||
@@ -117,10 +129,16 @@ class DjangoNeotestAdapter(CaseUtilsMixin, NeotestAdapter):
|
|||||||
+ len(suite_results.unexpectedSuccesses)
|
+ len(suite_results.unexpectedSuccesses)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Make sure we can import relative to current path
|
# Add the location of the django project to system path
|
||||||
sys.path.insert(0, os.getcwd())
|
# to ensure we have the same import paths as if the tests were ran
|
||||||
|
# by manage.py
|
||||||
|
case_id = args[-1]
|
||||||
|
path, *_ = case_id.split("::")
|
||||||
|
manage_py_location = self.get_django_root(path)
|
||||||
|
sys.path.insert(0, str(manage_py_location))
|
||||||
|
|
||||||
# Prepend an executable name which is just used in output
|
# Prepend an executable name which is just used in output
|
||||||
argv = ["neotest-python"] + self.convert_args(args[-1], args[:-1])
|
argv = ["neotest-python"] + self.convert_args(case_id, args[:-1])
|
||||||
# parse args
|
# parse args
|
||||||
parser = ArgumentParser()
|
parser = ArgumentParser()
|
||||||
DjangoUnittestRunner.add_arguments(parser)
|
DjangoUnittestRunner.add_arguments(parser)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from io import StringIO
|
from io import StringIO
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import re
|
||||||
from typing import Callable, Dict, List, Optional, Union
|
from typing import Callable, Dict, List, Optional, Union
|
||||||
from . import params_getter
|
from . import params_getter
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ from _pytest.fixtures import FixtureLookupErrorRepr
|
|||||||
|
|
||||||
from .base import NeotestAdapter, NeotestError, NeotestResult, NeotestResultStatus
|
from .base import NeotestAdapter, NeotestError, NeotestResult, NeotestResultStatus
|
||||||
|
|
||||||
|
ANSI_ESCAPE = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
|
||||||
|
|
||||||
class PytestNeotestAdapter(NeotestAdapter):
|
class PytestNeotestAdapter(NeotestAdapter):
|
||||||
def __init__(self, emit_parameterized_ids: bool):
|
def __init__(self, emit_parameterized_ids: bool):
|
||||||
@@ -132,7 +134,7 @@ class NeotestResultCollector:
|
|||||||
errors.append({"message": msg_prefix + exc_repr, "line": None})
|
errors.append({"message": msg_prefix + exc_repr, "line": None})
|
||||||
# Test failed internally
|
# Test failed internally
|
||||||
elif isinstance(exc_repr, ExceptionRepr):
|
elif isinstance(exc_repr, ExceptionRepr):
|
||||||
error_message = exc_repr.reprcrash.message # type: ignore
|
error_message = ANSI_ESCAPE.sub('', exc_repr.reprcrash.message) # type: ignore
|
||||||
error_line = None
|
error_line = None
|
||||||
for traceback_entry in reversed(call.excinfo.traceback):
|
for traceback_entry in reversed(call.excinfo.traceback):
|
||||||
if str(traceback_entry.path) == abs_path:
|
if str(traceback_entry.path) == abs_path:
|
||||||
|
|||||||
Reference in New Issue
Block a user