Compare commits

..

6 Commits

Author SHA1 Message Date
Itai Bohadana
14e1d3fc53 fix(lua): add wait to socket connect 2025-10-06 11:47:36 +03:00
Itai Bohadana
d7802d89d6 fix(params_getter): try to bind even if socket exists 2025-10-06 11:47:36 +03:00
Itai Bohadana
325afe0335 fix(params_getter): try to bind even if socket exists 2025-10-06 11:47:36 +03:00
Itai Bohadana
f3ebd18def feat(pytest): use socket instead of a shitton of processes 2025-10-06 11:47:34 +03:00
Daniel Ebrahimian
7cab6e2ecc feat: improve Django unit test execution pathing (#103) 2025-09-27 11:36:59 +01:00
Rónán Carrigan
1b1b1abf92 feat(pytest): strip ansi codes from errors 2025-09-19 12:16:58 +01:00
3 changed files with 28 additions and 8 deletions

View File

@@ -139,7 +139,7 @@ end
---@param positions neotest.Tree
---@param root string
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)
local test_params = {}

View File

@@ -1,9 +1,7 @@
import inspect
import os
import subprocess
import sys
import traceback
import unittest
from argparse import ArgumentParser
from pathlib import Path
from types import TracebackType
@@ -33,12 +31,26 @@ class CaseUtilsMixin:
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]:
"""Converts a neotest ID into test specifier for unittest"""
path, *child_ids = case_id.split("::")
if not 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_dotted = relative_stem.replace(os.sep, ".")
return [*args, ".".join([relative_dotted, *child_ids])]
@@ -117,10 +129,16 @@ class DjangoNeotestAdapter(CaseUtilsMixin, NeotestAdapter):
+ len(suite_results.unexpectedSuccesses)
)
# Make sure we can import relative to current path
sys.path.insert(0, os.getcwd())
# Add the location of the django project to system path
# 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
argv = ["neotest-python"] + self.convert_args(args[-1], args[:-1])
argv = ["neotest-python"] + self.convert_args(case_id, args[:-1])
# parse args
parser = ArgumentParser()
DjangoUnittestRunner.add_arguments(parser)

View File

@@ -1,6 +1,7 @@
from io import StringIO
import json
from pathlib import Path
import re
from typing import Callable, Dict, List, Optional, Union
from . import params_getter
@@ -11,6 +12,7 @@ from _pytest.fixtures import FixtureLookupErrorRepr
from .base import NeotestAdapter, NeotestError, NeotestResult, NeotestResultStatus
ANSI_ESCAPE = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
class PytestNeotestAdapter(NeotestAdapter):
def __init__(self, emit_parameterized_ids: bool):
@@ -132,7 +134,7 @@ class NeotestResultCollector:
errors.append({"message": msg_prefix + exc_repr, "line": None})
# Test failed internally
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
for traceback_entry in reversed(call.excinfo.traceback):
if str(traceback_entry.path) == abs_path: