summaryrefslogtreecommitdiffstats
path: root/tests/languages
diff options
context:
space:
mode:
Diffstat (limited to 'tests/languages')
-rw-r--r--tests/languages/conda_test.py36
-rw-r--r--tests/languages/coursier_test.py45
-rw-r--r--tests/languages/dart_test.py62
-rw-r--r--tests/languages/golang_test.py57
-rw-r--r--tests/languages/helpers_test.py28
-rw-r--r--tests/languages/lua_test.py58
-rw-r--r--tests/languages/perl_test.py69
-rw-r--r--tests/languages/r_test.py263
-rw-r--r--tests/languages/ruby_test.py4
-rw-r--r--tests/languages/rust_test.py7
-rw-r--r--tests/languages/swift_test.py31
11 files changed, 530 insertions, 130 deletions
diff --git a/tests/languages/conda_test.py b/tests/languages/conda_test.py
index 5023b2a..83aaebe 100644
--- a/tests/languages/conda_test.py
+++ b/tests/languages/conda_test.py
@@ -1,9 +1,13 @@
from __future__ import annotations
+import os.path
+
import pytest
from pre_commit import envcontext
-from pre_commit.languages.conda import _conda_exe
+from pre_commit.languages import conda
+from pre_commit.store import _make_local_repo
+from testing.language_helpers import run_language
@pytest.mark.parametrize(
@@ -37,4 +41,32 @@ from pre_commit.languages.conda import _conda_exe
)
def test_conda_exe(ctx, expected):
with envcontext.envcontext(ctx):
- assert _conda_exe() == expected
+ assert conda._conda_exe() == expected
+
+
+def test_conda_language(tmp_path):
+ environment_yml = '''\
+channels: [conda-forge, defaults]
+dependencies: [python, pip]
+'''
+ tmp_path.joinpath('environment.yml').write_text(environment_yml)
+
+ ret, out = run_language(
+ tmp_path,
+ conda,
+ 'python -c "import sys; print(sys.prefix)"',
+ )
+ assert ret == 0
+ assert os.path.basename(out.strip()) == b'conda-default'
+
+
+def test_conda_additional_deps(tmp_path):
+ _make_local_repo(tmp_path)
+
+ ret = run_language(
+ tmp_path,
+ conda,
+ 'python -c "import botocore; print(1)"',
+ deps=('botocore',),
+ )
+ assert ret == (0, b'1\n')
diff --git a/tests/languages/coursier_test.py b/tests/languages/coursier_test.py
new file mode 100644
index 0000000..dbb746c
--- /dev/null
+++ b/tests/languages/coursier_test.py
@@ -0,0 +1,45 @@
+from __future__ import annotations
+
+import pytest
+
+from pre_commit.errors import FatalError
+from pre_commit.languages import coursier
+from testing.language_helpers import run_language
+
+
+def test_coursier_hook(tmp_path):
+ echo_java_json = '''\
+{
+ "repositories": ["central"],
+ "dependencies": ["io.get-coursier:echo:latest.stable"]
+}
+'''
+
+ channel_dir = tmp_path.joinpath('.pre-commit-channel')
+ channel_dir.mkdir()
+ channel_dir.joinpath('echo-java.json').write_text(echo_java_json)
+
+ ret = run_language(
+ tmp_path,
+ coursier,
+ 'echo-java',
+ args=('Hello', 'World', 'from', 'coursier'),
+ )
+ assert ret == (0, b'Hello World from coursier\n')
+
+
+def test_coursier_hook_additional_dependencies(tmp_path):
+ ret = run_language(
+ tmp_path,
+ coursier,
+ 'scalafmt --version',
+ deps=('scalafmt:3.6.1',),
+ )
+ assert ret == (0, b'scalafmt 3.6.1\n')
+
+
+def test_error_if_no_deps_or_channel(tmp_path):
+ with pytest.raises(FatalError) as excinfo:
+ run_language(tmp_path, coursier, 'dne')
+ msg, = excinfo.value.args
+ assert msg == 'expected .pre-commit-channel dir or additional_dependencies'
diff --git a/tests/languages/dart_test.py b/tests/languages/dart_test.py
new file mode 100644
index 0000000..5bb5aa6
--- /dev/null
+++ b/tests/languages/dart_test.py
@@ -0,0 +1,62 @@
+from __future__ import annotations
+
+import re_assert
+
+from pre_commit.languages import dart
+from pre_commit.store import _make_local_repo
+from testing.language_helpers import run_language
+
+
+def test_dart(tmp_path):
+ pubspec_yaml = '''\
+environment:
+ sdk: '>=2.10.0 <3.0.0'
+
+name: hello_world_dart
+
+executables:
+ hello-world-dart:
+
+dependencies:
+ ansicolor: ^2.0.1
+'''
+ hello_world_dart_dart = '''\
+import 'package:ansicolor/ansicolor.dart';
+
+void main() {
+ AnsiPen pen = new AnsiPen()..red();
+ print("hello hello " + pen("world"));
+}
+'''
+ tmp_path.joinpath('pubspec.yaml').write_text(pubspec_yaml)
+ bin_dir = tmp_path.joinpath('bin')
+ bin_dir.mkdir()
+ bin_dir.joinpath('hello-world-dart.dart').write_text(hello_world_dart_dart)
+
+ expected = (0, b'hello hello world\n')
+ assert run_language(tmp_path, dart, 'hello-world-dart') == expected
+
+
+def test_dart_additional_deps(tmp_path):
+ _make_local_repo(str(tmp_path))
+
+ ret = run_language(
+ tmp_path,
+ dart,
+ 'hello-world-dart',
+ deps=('hello_world_dart',),
+ )
+ assert ret == (0, b'hello hello world\n')
+
+
+def test_dart_additional_deps_versioned(tmp_path):
+ _make_local_repo(str(tmp_path))
+
+ ret, out = run_language(
+ tmp_path,
+ dart,
+ 'secure-random -l 4 -b 16',
+ deps=('encrypt:5.0.0',),
+ )
+ assert ret == 0
+ re_assert.Matches('^[a-f0-9]{8}\n$').assert_matches(out.decode())
diff --git a/tests/languages/golang_test.py b/tests/languages/golang_test.py
index 9e393cb..0219261 100644
--- a/tests/languages/golang_test.py
+++ b/tests/languages/golang_test.py
@@ -1,22 +1,43 @@
from __future__ import annotations
+import re
+from unittest import mock
+
import pytest
-from pre_commit.languages.golang import guess_go_dir
-
-
-@pytest.mark.parametrize(
- ('url', 'expected'),
- (
- ('/im/a/path/on/disk', 'unknown_src_dir'),
- ('file:///im/a/path/on/disk', 'unknown_src_dir'),
- ('git@github.com:golang/lint', 'github.com/golang/lint'),
- ('git://github.com/golang/lint', 'github.com/golang/lint'),
- ('http://github.com/golang/lint', 'github.com/golang/lint'),
- ('https://github.com/golang/lint', 'github.com/golang/lint'),
- ('ssh://git@github.com/golang/lint', 'github.com/golang/lint'),
- ('git@github.com:golang/lint.git', 'github.com/golang/lint'),
- ),
-)
-def test_guess_go_dir(url, expected):
- assert guess_go_dir(url) == expected
+import pre_commit.constants as C
+from pre_commit.languages import golang
+from pre_commit.languages import helpers
+
+
+ACTUAL_GET_DEFAULT_VERSION = golang.get_default_version.__wrapped__
+
+
+@pytest.fixture
+def exe_exists_mck():
+ with mock.patch.object(helpers, 'exe_exists') as mck:
+ yield mck
+
+
+def test_golang_default_version_system_available(exe_exists_mck):
+ exe_exists_mck.return_value = True
+ assert ACTUAL_GET_DEFAULT_VERSION() == 'system'
+
+
+def test_golang_default_version_system_not_available(exe_exists_mck):
+ exe_exists_mck.return_value = False
+ assert ACTUAL_GET_DEFAULT_VERSION() == C.DEFAULT
+
+
+ACTUAL_INFER_GO_VERSION = golang._infer_go_version.__wrapped__
+
+
+def test_golang_infer_go_version_not_default():
+ assert ACTUAL_INFER_GO_VERSION('1.19.4') == '1.19.4'
+
+
+def test_golang_infer_go_version_default():
+ version = ACTUAL_INFER_GO_VERSION(C.DEFAULT)
+
+ assert version != C.DEFAULT
+ assert re.match(r'^\d+\.\d+\.\d+$', version)
diff --git a/tests/languages/helpers_test.py b/tests/languages/helpers_test.py
index f333e79..c209e7e 100644
--- a/tests/languages/helpers_test.py
+++ b/tests/languages/helpers_test.py
@@ -12,7 +12,6 @@ from pre_commit import parse_shebang
from pre_commit.languages import helpers
from pre_commit.prefix import Prefix
from pre_commit.util import CalledProcessError
-from testing.auto_namedtuple import auto_namedtuple
@pytest.fixture
@@ -94,31 +93,22 @@ def test_assert_no_additional_deps():
)
-SERIAL_FALSE = auto_namedtuple(require_serial=False)
-SERIAL_TRUE = auto_namedtuple(require_serial=True)
-
-
def test_target_concurrency_normal():
with mock.patch.object(multiprocessing, 'cpu_count', return_value=123):
with mock.patch.dict(os.environ, {}, clear=True):
- assert helpers.target_concurrency(SERIAL_FALSE) == 123
-
-
-def test_target_concurrency_cpu_count_require_serial_true():
- with mock.patch.dict(os.environ, {}, clear=True):
- assert helpers.target_concurrency(SERIAL_TRUE) == 1
+ assert helpers.target_concurrency() == 123
def test_target_concurrency_testing_env_var():
with mock.patch.dict(
os.environ, {'PRE_COMMIT_NO_CONCURRENCY': '1'}, clear=True,
):
- assert helpers.target_concurrency(SERIAL_FALSE) == 1
+ assert helpers.target_concurrency() == 1
def test_target_concurrency_on_travis():
with mock.patch.dict(os.environ, {'TRAVIS': '1'}, clear=True):
- assert helpers.target_concurrency(SERIAL_FALSE) == 2
+ assert helpers.target_concurrency() == 2
def test_target_concurrency_cpu_count_not_implemented():
@@ -126,10 +116,20 @@ def test_target_concurrency_cpu_count_not_implemented():
multiprocessing, 'cpu_count', side_effect=NotImplementedError,
):
with mock.patch.dict(os.environ, {}, clear=True):
- assert helpers.target_concurrency(SERIAL_FALSE) == 1
+ assert helpers.target_concurrency() == 1
def test_shuffled_is_deterministic():
seq = [str(i) for i in range(10)]
expected = ['4', '0', '5', '1', '8', '6', '2', '3', '7', '9']
assert helpers._shuffled(seq) == expected
+
+
+def test_xargs_require_serial_is_not_shuffled():
+ ret, out = helpers.run_xargs(
+ ('echo',), [str(i) for i in range(10)],
+ require_serial=True,
+ color=False,
+ )
+ assert ret == 0
+ assert out.strip() == b'0 1 2 3 4 5 6 7 8 9'
diff --git a/tests/languages/lua_test.py b/tests/languages/lua_test.py
new file mode 100644
index 0000000..b2767b7
--- /dev/null
+++ b/tests/languages/lua_test.py
@@ -0,0 +1,58 @@
+from __future__ import annotations
+
+import sys
+
+import pytest
+
+from pre_commit.languages import lua
+from pre_commit.util import make_executable
+from testing.language_helpers import run_language
+
+pytestmark = pytest.mark.skipif(
+ sys.platform == 'win32',
+ reason='lua is not supported on windows',
+)
+
+
+def test_lua(tmp_path): # pragma: win32 no cover
+ rockspec = '''\
+package = "hello"
+version = "dev-1"
+
+source = {
+ url = "git+ssh://git@github.com/pre-commit/pre-commit.git"
+}
+description = {}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {},
+ install = {
+ bin = {"bin/hello-world-lua"}
+ },
+}
+'''
+ hello_world_lua = '''\
+#!/usr/bin/env lua
+print('hello world')
+'''
+ tmp_path.joinpath('hello-dev-1.rockspec').write_text(rockspec)
+ bin_dir = tmp_path.joinpath('bin')
+ bin_dir.mkdir()
+ bin_file = bin_dir.joinpath('hello-world-lua')
+ bin_file.write_text(hello_world_lua)
+ make_executable(bin_file)
+
+ expected = (0, b'hello world\n')
+ assert run_language(tmp_path, lua, 'hello-world-lua') == expected
+
+
+def test_lua_additional_dependencies(tmp_path): # pragma: win32 no cover
+ ret, out = run_language(
+ tmp_path,
+ lua,
+ 'luacheck --version',
+ deps=('luacheck',),
+ )
+ assert ret == 0
+ assert out.startswith(b'Luacheck: ')
diff --git a/tests/languages/perl_test.py b/tests/languages/perl_test.py
new file mode 100644
index 0000000..042478d
--- /dev/null
+++ b/tests/languages/perl_test.py
@@ -0,0 +1,69 @@
+from __future__ import annotations
+
+from pre_commit.languages import perl
+from pre_commit.store import _make_local_repo
+from pre_commit.util import make_executable
+from testing.language_helpers import run_language
+
+
+def test_perl_install(tmp_path):
+ makefile_pl = '''\
+use strict;
+use warnings;
+
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+ NAME => "PreCommitHello",
+ VERSION_FROM => "lib/PreCommitHello.pm",
+ EXE_FILES => [qw(bin/pre-commit-perl-hello)],
+);
+'''
+ bin_perl_hello = '''\
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use PreCommitHello;
+
+PreCommitHello::hello();
+'''
+ lib_hello_pm = '''\
+package PreCommitHello;
+
+use strict;
+use warnings;
+
+our $VERSION = "0.1.0";
+
+sub hello {
+ print "Hello from perl-commit Perl!\n";
+}
+
+1;
+'''
+ tmp_path.joinpath('Makefile.PL').write_text(makefile_pl)
+ bin_dir = tmp_path.joinpath('bin')
+ bin_dir.mkdir()
+ exe = bin_dir.joinpath('pre-commit-perl-hello')
+ exe.write_text(bin_perl_hello)
+ make_executable(exe)
+ lib_dir = tmp_path.joinpath('lib')
+ lib_dir.mkdir()
+ lib_dir.joinpath('PreCommitHello.pm').write_text(lib_hello_pm)
+
+ ret = run_language(tmp_path, perl, 'pre-commit-perl-hello')
+ assert ret == (0, b'Hello from perl-commit Perl!\n')
+
+
+def test_perl_additional_dependencies(tmp_path):
+ _make_local_repo(str(tmp_path))
+
+ ret, out = run_language(
+ tmp_path,
+ perl,
+ 'perltidy --version',
+ deps=('SHANCOCK/Perl-Tidy-20211029.tar.gz',),
+ )
+ assert ret == 0
+ assert out.startswith(b'This is perltidy, v20211029')
diff --git a/tests/languages/r_test.py b/tests/languages/r_test.py
index c52d5ac..02c559c 100644
--- a/tests/languages/r_test.py
+++ b/tests/languages/r_test.py
@@ -1,136 +1,119 @@
from __future__ import annotations
import os.path
+import shutil
import pytest
from pre_commit import envcontext
from pre_commit.languages import r
+from pre_commit.prefix import Prefix
+from pre_commit.store import _make_local_repo
from pre_commit.util import win_exe
-from testing.fixtures import make_config_from_repo
-from testing.fixtures import make_repo
-from tests.repository_test import _get_hook_no_install
-
-
-def _test_r_parsing(
- tempdir_factory,
- store,
- hook_id,
- expected_hook_expr={},
- expected_args={},
- config={},
- expect_path_prefix=True,
-):
- repo_path = 'r_hooks_repo'
- path = make_repo(tempdir_factory, repo_path)
- config = config or make_config_from_repo(path)
- hook = _get_hook_no_install(config, store, hook_id)
- ret = r._cmd_from_hook(hook)
- expected_cmd = 'Rscript'
- expected_opts = (
- '--no-save', '--no-restore', '--no-site-file', '--no-environ',
- )
- expected_path = os.path.join(
- hook.prefix.prefix_dir if expect_path_prefix else '',
- f'{hook_id}.R',
- )
- expected = (
- expected_cmd,
- *expected_opts,
- *(expected_hook_expr or (expected_path,)),
- *expected_args,
- )
- assert ret == expected
+from testing.language_helpers import run_language
-def test_r_parsing_file_no_opts_no_args(tempdir_factory, store):
- hook_id = 'parse-file-no-opts-no-args'
- _test_r_parsing(tempdir_factory, store, hook_id)
+def test_r_parsing_file_no_opts_no_args(tmp_path):
+ cmd = r._cmd_from_hook(
+ Prefix(str(tmp_path)),
+ 'Rscript some-script.R',
+ (),
+ is_local=False,
+ )
+ assert cmd == (
+ 'Rscript',
+ '--no-save', '--no-restore', '--no-site-file', '--no-environ',
+ str(tmp_path.joinpath('some-script.R')),
+ )
-def test_r_parsing_file_opts_no_args(tempdir_factory, store):
+def test_r_parsing_file_opts_no_args():
with pytest.raises(ValueError) as excinfo:
r._entry_validate(['Rscript', '--no-init', '/path/to/file'])
- msg = excinfo.value.args
+ msg, = excinfo.value.args
assert msg == (
- 'The only valid syntax is `Rscript -e {expr}`',
- 'or `Rscript path/to/hook/script`',
+ 'The only valid syntax is `Rscript -e {expr}`'
+ 'or `Rscript path/to/hook/script`'
+ )
+
+
+def test_r_parsing_file_no_opts_args(tmp_path):
+ cmd = r._cmd_from_hook(
+ Prefix(str(tmp_path)),
+ 'Rscript some-script.R',
+ ('--no-cache',),
+ is_local=False,
+ )
+ assert cmd == (
+ 'Rscript',
+ '--no-save', '--no-restore', '--no-site-file', '--no-environ',
+ str(tmp_path.joinpath('some-script.R')),
+ '--no-cache',
)
-def test_r_parsing_file_no_opts_args(tempdir_factory, store):
- hook_id = 'parse-file-no-opts-args'
- expected_args = ['--no-cache']
- _test_r_parsing(
- tempdir_factory, store, hook_id, expected_args=expected_args,
+def test_r_parsing_expr_no_opts_no_args1(tmp_path):
+ cmd = r._cmd_from_hook(
+ Prefix(str(tmp_path)),
+ "Rscript -e '1+1'",
+ (),
+ is_local=False,
+ )
+ assert cmd == (
+ 'Rscript',
+ '--no-save', '--no-restore', '--no-site-file', '--no-environ',
+ '-e', '1+1',
)
-def test_r_parsing_expr_no_opts_no_args1(tempdir_factory, store):
- hook_id = 'parse-expr-no-opts-no-args-1'
- _test_r_parsing(
- tempdir_factory, store, hook_id, expected_hook_expr=('-e', '1+1'),
+def test_r_parsing_local_hook_path_is_not_expanded(tmp_path):
+ cmd = r._cmd_from_hook(
+ Prefix(str(tmp_path)),
+ 'Rscript path/to/thing.R',
+ (),
+ is_local=True,
+ )
+ assert cmd == (
+ 'Rscript',
+ '--no-save', '--no-restore', '--no-site-file', '--no-environ',
+ 'path/to/thing.R',
)
-def test_r_parsing_expr_no_opts_no_args2(tempdir_factory, store):
- with pytest.raises(ValueError) as execinfo:
+def test_r_parsing_expr_no_opts_no_args2():
+ with pytest.raises(ValueError) as excinfo:
r._entry_validate(['Rscript', '-e', '1+1', '-e', 'letters'])
- msg = execinfo.value.args
- assert msg == ('You can supply at most one expression.',)
+ msg, = excinfo.value.args
+ assert msg == 'You can supply at most one expression.'
-def test_r_parsing_expr_opts_no_args2(tempdir_factory, store):
- with pytest.raises(ValueError) as execinfo:
+def test_r_parsing_expr_opts_no_args2():
+ with pytest.raises(ValueError) as excinfo:
r._entry_validate(
- [
- 'Rscript', '--vanilla', '-e', '1+1', '-e', 'letters',
- ],
+ ['Rscript', '--vanilla', '-e', '1+1', '-e', 'letters'],
)
- msg = execinfo.value.args
+ msg, = excinfo.value.args
assert msg == (
- 'The only valid syntax is `Rscript -e {expr}`',
- 'or `Rscript path/to/hook/script`',
+ 'The only valid syntax is `Rscript -e {expr}`'
+ 'or `Rscript path/to/hook/script`'
)
-def test_r_parsing_expr_args_in_entry2(tempdir_factory, store):
- with pytest.raises(ValueError) as execinfo:
+def test_r_parsing_expr_args_in_entry2():
+ with pytest.raises(ValueError) as excinfo:
r._entry_validate(['Rscript', '-e', 'expr1', '--another-arg'])
- msg = execinfo.value.args
- assert msg == ('You can supply at most one expression.',)
+ msg, = excinfo.value.args
+ assert msg == 'You can supply at most one expression.'
-def test_r_parsing_expr_non_Rscirpt(tempdir_factory, store):
- with pytest.raises(ValueError) as execinfo:
+def test_r_parsing_expr_non_Rscirpt():
+ with pytest.raises(ValueError) as excinfo:
r._entry_validate(['AnotherScript', '-e', '{{}}'])
- msg = execinfo.value.args
- assert msg == ('entry must start with `Rscript`.',)
-
-
-def test_r_parsing_file_local(tempdir_factory, store):
- path = 'path/to/script.R'
- hook_id = 'local-r'
- config = {
- 'repo': 'local',
- 'hooks': [{
- 'id': hook_id,
- 'name': 'local-r',
- 'entry': f'Rscript {path}',
- 'language': 'r',
- }],
- }
- _test_r_parsing(
- tempdir_factory,
- store,
- hook_id=hook_id,
- expected_hook_expr=(path,),
- config=config,
- expect_path_prefix=False,
- )
+ msg, = excinfo.value.args
+ assert msg == 'entry must start with `Rscript`.'
def test_rscript_exec_relative_to_r_home():
@@ -142,3 +125,99 @@ def test_rscript_exec_relative_to_r_home():
def test_path_rscript_exec_no_r_home_set():
with envcontext.envcontext((('R_HOME', envcontext.UNSET),)):
assert r._rscript_exec() == 'Rscript'
+
+
+def test_r_hook(tmp_path):
+ renv_lock = '''\
+{
+ "R": {
+ "Version": "4.0.3",
+ "Repositories": [
+ {
+ "Name": "CRAN",
+ "URL": "https://cloud.r-project.org"
+ }
+ ]
+ },
+ "Packages": {
+ "renv": {
+ "Package": "renv",
+ "Version": "0.12.5",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "5c0cdb37f063c58cdab3c7e9fbb8bd2c"
+ },
+ "rprojroot": {
+ "Package": "rprojroot",
+ "Version": "1.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "86704667fe0860e4fec35afdfec137f3"
+ }
+ }
+}
+'''
+ description = '''\
+Package: gli.clu
+Title: What the Package Does (One Line, Title Case)
+Type: Package
+Version: 0.0.0.9000
+Authors@R:
+ person(given = "First",
+ family = "Last",
+ role = c("aut", "cre"),
+ email = "first.last@example.com",
+ comment = c(ORCID = "YOUR-ORCID-ID"))
+Description: What the package does (one paragraph).
+License: `use_mit_license()`, `use_gpl3_license()` or friends to
+ pick a license
+Encoding: UTF-8
+LazyData: true
+Roxygen: list(markdown = TRUE)
+RoxygenNote: 7.1.1
+Imports:
+ rprojroot
+'''
+ hello_world_r = '''\
+stopifnot(
+ packageVersion('rprojroot') == '1.0',
+ packageVersion('gli.clu') == '0.0.0.9000'
+)
+cat("Hello, World, from R!\n")
+'''
+
+ tmp_path.joinpath('renv.lock').write_text(renv_lock)
+ tmp_path.joinpath('DESCRIPTION').write_text(description)
+ tmp_path.joinpath('hello-world.R').write_text(hello_world_r)
+ renv_dir = tmp_path.joinpath('renv')
+ renv_dir.mkdir()
+ shutil.copy(
+ os.path.join(
+ os.path.dirname(__file__),
+ '../../pre_commit/resources/empty_template_activate.R',
+ ),
+ renv_dir.joinpath('activate.R'),
+ )
+
+ expected = (0, b'Hello, World, from R!\n')
+ assert run_language(tmp_path, r, 'Rscript hello-world.R') == expected
+
+
+def test_r_inline(tmp_path):
+ _make_local_repo(str(tmp_path))
+
+ cmd = '''\
+Rscript -e '
+ stopifnot(packageVersion("rprojroot") == "1.0")
+ cat(commandArgs(trailingOnly = TRUE), "from R!\n", sep=", ")
+'
+'''
+
+ ret = run_language(
+ tmp_path,
+ r,
+ cmd,
+ deps=('rprojroot@1.0',),
+ args=('hi', 'hello'),
+ )
+ assert ret == (0, b'hi, hello, from R!\n')
diff --git a/tests/languages/ruby_test.py b/tests/languages/ruby_test.py
index 29f3c80..63a16eb 100644
--- a/tests/languages/ruby_test.py
+++ b/tests/languages/ruby_test.py
@@ -71,10 +71,10 @@ def test_install_ruby_default(fake_gem_prefix):
@xfailif_windows # pragma: win32 no cover
def test_install_ruby_with_version(fake_gem_prefix):
- ruby.install_environment(fake_gem_prefix, '3.1.0', ())
+ ruby.install_environment(fake_gem_prefix, '3.2.0', ())
# Should be able to activate and use rbenv install
- with ruby.in_env(fake_gem_prefix, '3.1.0'):
+ with ruby.in_env(fake_gem_prefix, '3.2.0'):
cmd_output('rbenv', 'install', '--help')
diff --git a/tests/languages/rust_test.py b/tests/languages/rust_test.py
index f011e71..b8167a9 100644
--- a/tests/languages/rust_test.py
+++ b/tests/languages/rust_test.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+from typing import Mapping
from unittest import mock
import pytest
@@ -48,7 +49,9 @@ def test_installs_with_bootstrapped_rustup(tmpdir, language_version):
original_find_executable = parse_shebang.find_executable
- def mocked_find_executable(exe: str) -> str | None:
+ def mocked_find_executable(
+ exe: str, *, env: Mapping[str, str] | None = None,
+ ) -> str | None:
"""
Return `None` the first time `find_executable` is called to ensure
that the bootstrapping code is executed, then just let the function
@@ -59,7 +62,7 @@ def test_installs_with_bootstrapped_rustup(tmpdir, language_version):
find_executable_exes.append(exe)
if len(find_executable_exes) == 1:
return None
- return original_find_executable(exe)
+ return original_find_executable(exe, env=env)
with mock.patch.object(parse_shebang, 'find_executable') as find_exe_mck:
find_exe_mck.side_effect = mocked_find_executable
diff --git a/tests/languages/swift_test.py b/tests/languages/swift_test.py
new file mode 100644
index 0000000..e0a8ea4
--- /dev/null
+++ b/tests/languages/swift_test.py
@@ -0,0 +1,31 @@
+from __future__ import annotations
+
+import sys
+
+import pytest
+
+from pre_commit.languages import swift
+from testing.language_helpers import run_language
+
+
+@pytest.mark.skipif(
+ sys.platform == 'win32',
+ reason='swift is not supported on windows',
+)
+def test_swift_language(tmp_path): # pragma: win32 no cover
+ package_swift = '''\
+// swift-tools-version:5.0
+import PackageDescription
+
+let package = Package(
+ name: "swift_hooks_repo",
+ targets: [.target(name: "swift_hooks_repo")]
+)
+'''
+ tmp_path.joinpath('Package.swift').write_text(package_swift)
+ src_dir = tmp_path.joinpath('Sources/swift_hooks_repo')
+ src_dir.mkdir(parents=True)
+ src_dir.joinpath('main.swift').write_text('print("Hello, world!")\n')
+
+ expected = (0, b'Hello, world!\n')
+ assert run_language(tmp_path, swift, 'swift_hooks_repo') == expected