mirror of
https://github.com/unclebob/mutator.git
synced 2026-11-07 10:43:49 +00:00
Stop shelling generated test commands and fail closed on git and coverage.
A package path is one argument. Git status uses NUL records and returns git's status. A failed coverage command leaves reports unread, coverage keeps the longest path match, and site walks no longer recurse.
This commit is contained in:
+94
-28
@@ -6,6 +6,7 @@ alone when no input can tell the operators apart.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
from pathlib import Path
|
||||
@@ -13,6 +14,7 @@ from pathlib import Path
|
||||
import pytest
|
||||
|
||||
from mutator.cli import (
|
||||
GitStatusError,
|
||||
_changed_files,
|
||||
_is_source,
|
||||
_prepare_coverage,
|
||||
@@ -21,7 +23,7 @@ from mutator.cli import (
|
||||
run,
|
||||
select_files,
|
||||
)
|
||||
from mutator.coverage import _candidates, _jacoco_index, _suffix_hit, covered_lines
|
||||
from mutator.coverage import _candidates, _jacoco_index, covered_lines
|
||||
from mutator.crapper_link import ensure_crapper
|
||||
from mutator.edn import loads
|
||||
from mutator.engine import (
|
||||
@@ -246,7 +248,6 @@ def test_grammar_guards_and_non_head_clojure_symbols(tmp_path):
|
||||
def test_coverage_indexes_use_package_names_form_counts_and_exact_paths(tmp_path):
|
||||
assert _candidates(lambda value: value, "") == []
|
||||
assert _candidates(lambda _value: "same", "src/app.py") == ["same"]
|
||||
assert _suffix_hit("demo/Board.java", ["Other.java"], lambda left, right: left.endswith(right)) is False
|
||||
|
||||
report = tmp_path / "target" / "site" / "jacoco" / "jacoco.xml"
|
||||
report.parent.mkdir(parents=True)
|
||||
@@ -288,7 +289,7 @@ def test_commands_follow_the_nearest_project_and_a_killed_process(tmp_path):
|
||||
both.mkdir()
|
||||
(both / "bb.edn").write_text("{:tasks {test (clojure)}}\n", encoding="utf-8")
|
||||
(both / "deps.edn").write_text("{:deps {}}\n", encoding="utf-8")
|
||||
assert _clojure_command(both) == "clj -M:test"
|
||||
assert _clojure_command(both) == ["clj", "-M:test"]
|
||||
|
||||
root = tmp_path / "proj"
|
||||
sub = root / "svc"
|
||||
@@ -299,28 +300,28 @@ def test_commands_follow_the_nearest_project_and_a_killed_process(tmp_path):
|
||||
clojure.write_text("(defn place [] 1)\n", encoding="utf-8")
|
||||
command, directory = command_for(root, clojure, "clojure", None)
|
||||
assert directory == sub
|
||||
assert command == "bb test"
|
||||
assert command == ["bb", "test"]
|
||||
|
||||
(sub / "pom.xml").write_text("<project/>\n", encoding="utf-8")
|
||||
java = sub / "src" / "A.java"
|
||||
java.write_text("class A { int place(){ return 1; } }\n", encoding="utf-8")
|
||||
command, directory = command_for(root, java, "java", None)
|
||||
assert directory == sub
|
||||
assert command == "mvn -q test -DexcludeTags=no-mutate"
|
||||
assert command == ["mvn", "-q", "test", "-DexcludeTags=no-mutate"]
|
||||
|
||||
(sub / "package.json").write_text("{}\n", encoding="utf-8")
|
||||
typescript = sub / "src" / "a.ts"
|
||||
typescript.write_text("export function place(){ return 1; }\n", encoding="utf-8")
|
||||
command, directory = command_for(root, typescript, "typescript", None)
|
||||
assert directory == sub
|
||||
assert command == "npm test"
|
||||
assert command == ["npm", "test"]
|
||||
|
||||
(sub / "Cargo.toml").write_text("[package]\nname='demo'\n", encoding="utf-8")
|
||||
rust = sub / "src" / "lib.rs"
|
||||
rust.write_text("fn place() -> i32 { 1 }\n", encoding="utf-8")
|
||||
command, directory = command_for(root, rust, "rust", None)
|
||||
assert directory == sub
|
||||
assert command == "cargo test"
|
||||
assert command == ["cargo", "test"]
|
||||
|
||||
(sub / "go.mod").write_text("module example.com/demo\n", encoding="utf-8")
|
||||
go = sub / "pkg" / "widget.go"
|
||||
@@ -328,14 +329,14 @@ def test_commands_follow_the_nearest_project_and_a_killed_process(tmp_path):
|
||||
go.write_text("package pkg\nfunc Run() int { return 1 }\n", encoding="utf-8")
|
||||
command, directory = command_for(root, go, "go", None)
|
||||
assert directory == sub
|
||||
assert command == "go test -count=1 ./pkg"
|
||||
assert command == ["go", "test", "-count=1", "./pkg"]
|
||||
|
||||
(sub / "pyproject.toml").write_text("[project]\ndependencies=['pytest']\n", encoding="utf-8")
|
||||
python = sub / "app.py"
|
||||
python.write_text("def place():\n return 1\n", encoding="utf-8")
|
||||
command, directory = command_for(root, python, "python", None)
|
||||
assert directory == sub
|
||||
assert command.endswith("-m pytest")
|
||||
assert command[-2:] == ["-m", "pytest"]
|
||||
|
||||
result = CommandRunner().run(f"{sys.executable} -c 'import time; time.sleep(30)'", tmp_path, 0.4)
|
||||
assert result.timed_out is True
|
||||
@@ -398,28 +399,93 @@ def test_help_and_conflicts_use_different_streams(capsys):
|
||||
assert captured.out == ""
|
||||
|
||||
|
||||
def test_git_status_keeps_short_names_renames_and_the_failure_text(monkeypatch, tmp_path, capsys):
|
||||
class Result:
|
||||
def __init__(self, code, out="", err=""):
|
||||
self.returncode = code
|
||||
self.stdout = out
|
||||
self.stderr = err
|
||||
def _init_repo(path: Path) -> None:
|
||||
subprocess.run(["git", "init"], cwd=path, check=True, capture_output=True)
|
||||
subprocess.run(["git", "config", "user.email", "[email protected]"], cwd=path, check=True)
|
||||
subprocess.run(["git", "config", "user.name", "Dev"], cwd=path, check=True)
|
||||
|
||||
def fail(*args, **kwargs):
|
||||
return Result(1, err="boom\n")
|
||||
|
||||
def _commit(path: Path, message: str) -> None:
|
||||
subprocess.run(["git", "add", "-A"], cwd=path, check=True, capture_output=True)
|
||||
subprocess.run(["git", "commit", "-m", message], cwd=path, check=True, capture_output=True)
|
||||
|
||||
|
||||
def test_git_status_keeps_real_names_and_fails_closed(tmp_path, capsys):
|
||||
outside = tmp_path / "outside"
|
||||
outside.mkdir()
|
||||
code = run(["--changed", "--root", str(outside)])
|
||||
captured = capsys.readouterr()
|
||||
assert code == 128
|
||||
assert "not a git repository" in captured.err
|
||||
assert "No source files" not in captured.out
|
||||
|
||||
repo = tmp_path / "repo"
|
||||
repo.mkdir()
|
||||
_init_repo(repo)
|
||||
source = "def place(x):\n return x > 0\n"
|
||||
keep = repo / "src" / "café.py"
|
||||
keep.parent.mkdir()
|
||||
keep.write_text(source, encoding="utf-8")
|
||||
nested = repo / "fresh" / "nested" / "new.py"
|
||||
nested.parent.mkdir(parents=True)
|
||||
nested.write_text(source, encoding="utf-8")
|
||||
spaced = repo / "src" / "my file.py"
|
||||
spaced.write_text(source, encoding="utf-8")
|
||||
gone = repo / "gone.py"
|
||||
gone.write_text(source, encoding="utf-8")
|
||||
old = repo / "src" / "old.py"
|
||||
old.write_text(source, encoding="utf-8")
|
||||
_commit(repo, "base")
|
||||
keep.write_text(source + "\n", encoding="utf-8")
|
||||
nested.write_text(source + "\n", encoding="utf-8")
|
||||
spaced.write_text(source + "\n", encoding="utf-8")
|
||||
gone.unlink()
|
||||
subprocess.run(
|
||||
["git", "mv", "src/old.py", "src/new.py"], cwd=repo, check=True, capture_output=True
|
||||
)
|
||||
skipped = repo / "target" / "skip.py"
|
||||
skipped.parent.mkdir()
|
||||
skipped.write_text(source, encoding="utf-8")
|
||||
|
||||
found = set(_changed_files(repo))
|
||||
assert keep.resolve() in found
|
||||
assert nested.resolve() in found
|
||||
assert spaced.resolve() in found
|
||||
assert (repo / "src" / "new.py").resolve() in found
|
||||
assert gone.resolve() not in found
|
||||
assert old.resolve() not in found
|
||||
|
||||
chosen = select_files(parse_args(["--root", str(repo), "--changed"]))
|
||||
assert skipped.resolve() not in chosen
|
||||
assert keep.resolve() in chosen
|
||||
code = run(["--scan", "--no-coverage", "--root", str(repo), "--changed"])
|
||||
assert code == 0
|
||||
assert "café.py" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_changed_from_a_subdirectory_stays_inside_it(tmp_path):
|
||||
repo = tmp_path / "repo"
|
||||
sub = repo / "sub"
|
||||
(sub / "src").mkdir(parents=True)
|
||||
(repo / "src").mkdir()
|
||||
_init_repo(repo)
|
||||
below = sub / "src" / "below.py"
|
||||
above = repo / "src" / "above.py"
|
||||
body = "def place(x):\n return x > 0\n"
|
||||
below.write_text(body, encoding="utf-8")
|
||||
above.write_text(body, encoding="utf-8")
|
||||
chosen = select_files(parse_args(["--root", str(sub), "--changed"]))
|
||||
assert chosen == [below.resolve()]
|
||||
|
||||
|
||||
def test_an_empty_git_error_uses_the_fallback_text(monkeypatch, tmp_path):
|
||||
def fail(args, **kwargs):
|
||||
return subprocess.CompletedProcess(args, 128, b"", b" \n")
|
||||
|
||||
monkeypatch.setattr("mutator.cli.subprocess.run", fail)
|
||||
assert _changed_files(tmp_path) == []
|
||||
assert capsys.readouterr().err.strip() == "boom"
|
||||
|
||||
def status(*args, **kwargs):
|
||||
return Result(0, out="?? a\nR src/old.py -> src/new.py\n")
|
||||
|
||||
monkeypatch.setattr("mutator.cli.subprocess.run", status)
|
||||
found = _changed_files(tmp_path)
|
||||
assert (tmp_path / "a").resolve() in found
|
||||
assert (tmp_path / "src" / "new.py").resolve() in found
|
||||
assert (tmp_path / "src" / "old.py").resolve() not in found
|
||||
with pytest.raises(GitStatusError, match="git status failed") as caught:
|
||||
_changed_files(tmp_path)
|
||||
assert caught.value.code == 128
|
||||
|
||||
|
||||
def test_selection_joins_the_root_and_skips_unknown_files(tmp_path, capsys):
|
||||
|
||||
@@ -42,6 +42,8 @@ def test_help_and_conflicting_flags():
|
||||
help_options = parse_args(["--help"])
|
||||
assert help_options.exit_code == 0
|
||||
assert "uml-viewer" in help_options.message
|
||||
assert "__pycache__" in help_options.message
|
||||
assert "testdata" in help_options.message
|
||||
conflict = parse_args(["--mutate-all", "--since-last-run", "src/demo.py"])
|
||||
assert conflict.exit_code == 1
|
||||
assert run(["--help"]) == 0
|
||||
@@ -92,3 +94,28 @@ def test_real_python_mutants_update_the_snapshot(tmp_path, capsys):
|
||||
assert ":namespace \"demo\"" in text
|
||||
assert ":id \"defn/add\"" in text
|
||||
assert path.read_text(encoding="utf-8").startswith("def add")
|
||||
|
||||
|
||||
def test_a_failed_coverage_command_does_not_read_the_report(tmp_path, capsys):
|
||||
path = tmp_path / "src" / "app.py"
|
||||
path.parent.mkdir()
|
||||
path.write_text("def place(x):\n return x > 0\n", encoding="utf-8")
|
||||
report = tmp_path / "target" / "coverage" / "python" / "lcov.info"
|
||||
report.parent.mkdir(parents=True)
|
||||
report.write_text("SF:src/app.py\nDA:1,1\nDA:2,1\nend_of_record\n", encoding="utf-8")
|
||||
code = run(
|
||||
[
|
||||
"--root",
|
||||
str(tmp_path),
|
||||
"--coverage-command",
|
||||
"exit 3",
|
||||
"--test-command",
|
||||
"false",
|
||||
"src/app.py",
|
||||
]
|
||||
)
|
||||
captured = capsys.readouterr()
|
||||
assert code == 3
|
||||
assert "will not be read" in captured.err
|
||||
assert "Baseline failed" not in captured.err
|
||||
assert path.read_text(encoding="utf-8").startswith("def place")
|
||||
|
||||
@@ -55,3 +55,44 @@ def test_lcov_marks_executed_lines(tmp_path):
|
||||
source.write_text("def place():\n return 1\n", encoding="utf-8")
|
||||
assert covered_lines(tmp_path, source, "python") == {1}
|
||||
assert covered_lines(tmp_path, source, "clojure") == {1}
|
||||
|
||||
|
||||
def test_lcov_does_not_let_a_shorter_path_steal_hits(tmp_path):
|
||||
report = tmp_path / "target" / "coverage" / "python" / "lcov.info"
|
||||
report.parent.mkdir(parents=True)
|
||||
report.write_text(
|
||||
"SF:b/app.py\nDA:2,1\nend_of_record\n"
|
||||
"SF:a/b/app.py\nDA:1,1\nend_of_record\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
short = tmp_path / "b" / "app.py"
|
||||
long = tmp_path / "a" / "b" / "app.py"
|
||||
short.parent.mkdir(parents=True)
|
||||
long.parent.mkdir(parents=True)
|
||||
short.write_text("def place():\n return 1\n", encoding="utf-8")
|
||||
long.write_text("def place():\n return 1\n", encoding="utf-8")
|
||||
assert covered_lines(tmp_path, long, "python") == {1}
|
||||
assert covered_lines(tmp_path, short, "python") == {2}
|
||||
|
||||
|
||||
def test_go_profile_does_not_cross_files(tmp_path):
|
||||
profile = tmp_path / "target" / "coverage" / "go" / "coverage.out"
|
||||
profile.parent.mkdir(parents=True)
|
||||
profile.write_text(
|
||||
"mode: set\n"
|
||||
"b/widget.go:2.1,2.2 1 1\n"
|
||||
"a/b/widget.go:3.1,3.2 1 0\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
short = tmp_path / "b" / "widget.go"
|
||||
long = tmp_path / "a" / "b" / "widget.go"
|
||||
short.parent.mkdir(parents=True)
|
||||
long.parent.mkdir(parents=True)
|
||||
short.write_text("package b\nfunc Run() {}\n", encoding="utf-8")
|
||||
long.write_text("package b\nfunc Run() {}\n", encoding="utf-8")
|
||||
assert covered_lines(tmp_path, short, "go") == {2}
|
||||
assert covered_lines(tmp_path, long, "go") == set()
|
||||
|
||||
profile.write_text("mode: set\na/b/widget.go:2.1,2.2 1 1\n", encoding="utf-8")
|
||||
assert covered_lines(tmp_path, short, "go") is None
|
||||
assert covered_lines(tmp_path, long, "go") == {2}
|
||||
|
||||
+46
-16
@@ -1,6 +1,7 @@
|
||||
import sys
|
||||
|
||||
from mutator.runner import CommandRunner, _clojure_command, _python_command, nearest
|
||||
from mutator.runner import test_plan as plan_command
|
||||
|
||||
|
||||
def test_nearest_walks_up_to_the_marker(tmp_path):
|
||||
@@ -19,29 +20,29 @@ def test_clojure_commands(tmp_path):
|
||||
bb = tmp_path / "bb-spec"
|
||||
bb.mkdir()
|
||||
(bb / "bb.edn").write_text('{:tasks {spec "spec"}}', encoding="utf-8")
|
||||
assert _clojure_command(bb) == "bb spec --tag ~no-mutate"
|
||||
assert _clojure_command(bb) == ["bb", "spec", "--tag", "~no-mutate"]
|
||||
|
||||
bb_test = tmp_path / "bb-test"
|
||||
bb_test.mkdir()
|
||||
(bb_test / "bb.edn").write_text("{:tasks {test (clojure \"-M:test\")}}", encoding="utf-8")
|
||||
assert _clojure_command(bb_test) == "bb test"
|
||||
assert _clojure_command(bb_test) == ["bb", "test"]
|
||||
|
||||
spec = tmp_path / "spec"
|
||||
spec.mkdir()
|
||||
(spec / "deps.edn").write_text(
|
||||
"{:aliases {:spec {:extra-deps {speclj/speclj {}}}}}", encoding="utf-8"
|
||||
)
|
||||
assert _clojure_command(spec) == "clj -M:spec --tag ~no-mutate"
|
||||
assert _clojure_command(spec) == ["clj", "-M:spec", "--tag", "~no-mutate"]
|
||||
|
||||
spec_only = tmp_path / "spec-only"
|
||||
spec_only.mkdir()
|
||||
(spec_only / "deps.edn").write_text("{:aliases {:spec {}}}", encoding="utf-8")
|
||||
assert _clojure_command(spec_only) == "clj -M:spec"
|
||||
assert _clojure_command(spec_only) == ["clj", "-M:spec"]
|
||||
|
||||
plain = tmp_path / "plain"
|
||||
plain.mkdir()
|
||||
(plain / "deps.edn").write_text("{:deps {}}", encoding="utf-8")
|
||||
assert _clojure_command(plain) == "clj -M:test"
|
||||
assert _clojure_command(plain) == ["clj", "-M:test"]
|
||||
|
||||
|
||||
def _executable(path):
|
||||
@@ -55,15 +56,20 @@ def test_python_command_uses_an_absolute_project_interpreter(tmp_path):
|
||||
dot = project / ".venv" / "bin" / "python"
|
||||
_executable(dot)
|
||||
(project / "pytest.ini").write_text("[pytest]\n", encoding="utf-8")
|
||||
assert _python_command(project) == f"{dot.absolute()} -m pytest"
|
||||
assert _python_command(project) == [str(dot.absolute()), "-m", "pytest"]
|
||||
|
||||
other = tmp_path / "other"
|
||||
plain = other / "venv" / "bin" / "python"
|
||||
_executable(plain)
|
||||
assert _python_command(other) == f"{plain.absolute()} -m unittest discover"
|
||||
assert _python_command(other) == [str(plain.absolute()), "-m", "unittest", "discover"]
|
||||
|
||||
_executable(other / ".venv" / "bin" / "python")
|
||||
assert _python_command(other) == f"{(other / '.venv' / 'bin' / 'python').absolute()} -m unittest discover"
|
||||
assert _python_command(other) == [
|
||||
str((other / ".venv" / "bin" / "python").absolute()),
|
||||
"-m",
|
||||
"unittest",
|
||||
"discover",
|
||||
]
|
||||
|
||||
|
||||
def test_python_command_keeps_the_virtualenv_symlink(tmp_path):
|
||||
@@ -74,7 +80,7 @@ def test_python_command_keeps_the_virtualenv_symlink(tmp_path):
|
||||
link.parent.mkdir(parents=True)
|
||||
link.symlink_to(target)
|
||||
(project / "pytest.ini").write_text("[pytest]\n", encoding="utf-8")
|
||||
assert _python_command(project) == f"{link.absolute()} -m pytest"
|
||||
assert _python_command(project) == [str(link.absolute()), "-m", "pytest"]
|
||||
|
||||
|
||||
def test_python_command_falls_back_when_the_virtualenv_cannot_run(tmp_path):
|
||||
@@ -82,37 +88,61 @@ def test_python_command_falls_back_when_the_virtualenv_cannot_run(tmp_path):
|
||||
binary = project / ".venv" / "bin" / "python"
|
||||
binary.parent.mkdir(parents=True)
|
||||
binary.write_text("", encoding="utf-8")
|
||||
assert _python_command(project) == f"{sys.executable} -m unittest discover"
|
||||
assert _python_command(project) == [sys.executable, "-m", "unittest", "discover"]
|
||||
|
||||
missing = tmp_path / "missing"
|
||||
missing.mkdir()
|
||||
assert _python_command(missing) == f"{sys.executable} -m unittest discover"
|
||||
assert _python_command(missing) == [sys.executable, "-m", "unittest", "discover"]
|
||||
|
||||
|
||||
def test_python_commands(tmp_path):
|
||||
pytest_dir = tmp_path / "py"
|
||||
pytest_dir.mkdir()
|
||||
(pytest_dir / "pytest.ini").write_text("[pytest]\n", encoding="utf-8")
|
||||
assert _python_command(pytest_dir).endswith("-m pytest")
|
||||
assert _python_command(pytest_dir)[-2:] == ["-m", "pytest"]
|
||||
|
||||
unit = tmp_path / "unit"
|
||||
unit.mkdir()
|
||||
assert _python_command(unit).endswith("-m unittest discover")
|
||||
assert _python_command(unit)[-3:] == ["-m", "unittest", "discover"]
|
||||
|
||||
cfg = tmp_path / "cfg"
|
||||
cfg.mkdir()
|
||||
(cfg / "setup.cfg").write_text("[tool:pytest]\n", encoding="utf-8")
|
||||
assert _python_command(cfg).endswith("-m pytest")
|
||||
assert _python_command(cfg)[-2:] == ["-m", "pytest"]
|
||||
|
||||
project = tmp_path / "proj"
|
||||
project.mkdir()
|
||||
(project / "pyproject.toml").write_text("[project]\ndependencies=['pytest']\n", encoding="utf-8")
|
||||
assert _python_command(project).endswith("-m pytest")
|
||||
assert _python_command(project)[-2:] == ["-m", "pytest"]
|
||||
|
||||
conf = tmp_path / "conf"
|
||||
conf.mkdir()
|
||||
(conf / "conftest.py").write_text("", encoding="utf-8")
|
||||
assert _python_command(conf).endswith("-m pytest")
|
||||
assert _python_command(conf)[-2:] == ["-m", "pytest"]
|
||||
|
||||
|
||||
def test_a_go_package_path_is_one_argument(tmp_path):
|
||||
root = tmp_path / "proj"
|
||||
package = root / "a;echo no"
|
||||
package.mkdir(parents=True)
|
||||
(root / "go.mod").write_text("module example.com/demo\n", encoding="utf-8")
|
||||
source = package / "widget.go"
|
||||
source.write_text("package main\nfunc Run() int { return 1 }\n", encoding="utf-8")
|
||||
command, directory = plan_command(root, source, "go", None)
|
||||
assert command == ["go", "test", "-count=1", "./a;echo no"]
|
||||
assert directory == root
|
||||
echoed = CommandRunner().run(["/bin/echo", command[-1]], directory, None)
|
||||
assert echoed.code == 0
|
||||
assert echoed.output.strip() == "./a;echo no"
|
||||
|
||||
spaced = root / "my dir" / "widget.go"
|
||||
spaced.parent.mkdir()
|
||||
spaced.write_text("package main\nfunc Run() int { return 1 }\n", encoding="utf-8")
|
||||
command, _directory = plan_command(root, spaced, "go", None)
|
||||
assert command == ["go", "test", "-count=1", "./my dir"]
|
||||
override, override_dir = plan_command(root, source, "go", "go test ./...")
|
||||
assert override == "go test ./..."
|
||||
assert override_dir == root.resolve()
|
||||
|
||||
|
||||
def test_a_worker_overlay_is_imported_ahead_of_the_environment(tmp_path):
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
from mutator.functions import form_id, is_private, project_functions, sites_in_file
|
||||
from mutator.sites import discover_raw
|
||||
|
||||
|
||||
def _sites(tmp_path: Path, relative: str, source: str):
|
||||
@@ -194,3 +195,11 @@ export function mount(app) {
|
||||
def test_a_quoted_nullish_operator_is_not_a_site(tmp_path):
|
||||
source = 'export function place() {\n return "a ?? b?.c";\n}\n'
|
||||
assert _sites(tmp_path, "src/demo/app.ts", source) == []
|
||||
|
||||
|
||||
def test_a_deep_expression_is_walked(tmp_path):
|
||||
expr = " + ".join(["1"] * 1200)
|
||||
python = f"def place():\n return {expr}\n"
|
||||
assert discover_raw(python, "python", "app.py")
|
||||
go = f"package p\nfunc place() int {{ return {expr} }}\n"
|
||||
assert discover_raw(go, "go", "app.go")
|
||||
|
||||
Reference in New Issue
Block a user