python3Packages.beets: add single-plugin passthru tests

Add a positive `beet --help` check for every functional built-in plugin,
with only that plugin enabled.

Assisted-by: Codex (GPT-5)
Co-Authored-By: Doron Behar <doron.behar@gmail.com>
This commit is contained in:
staticdev
2026-07-16 17:43:18 +03:00
committed by Doron Behar
co-authored by Doron Behar
parent eb808e50be
commit 79835e4005
@@ -278,7 +278,9 @@ buildPythonPackage (finalAttrs: {
bench.testPaths = [ ];
bpd = { };
bpm.testPaths = [ ];
bpsync.testPaths = [ ];
bpsync = {
testPaths = [ ];
};
bucket = { };
chroma = {
propagatedBuildInputs = [ pyacoustid ];
@@ -291,10 +293,15 @@ buildPythonPackage (finalAttrs: {
propagatedBuildInputs = [ requests ];
testPaths = [ ];
};
discogs.propagatedBuildInputs = [
discogs-client
requests
];
discogs = {
propagatedBuildInputs = [
discogs-client
requests
];
singlePluginTest.config = {
user_token = "test";
};
};
duplicates.testPaths = [ ];
edit = { };
embedart = {
@@ -337,7 +344,10 @@ buildPythonPackage (finalAttrs: {
testPaths = [ ];
};
limit = { };
listenbrainz = { };
listenbrainz.singlePluginTest.config = {
token = "test";
username = "test";
};
loadext = {
propagatedBuildInputs = [ requests ];
testPaths = [ ];
@@ -366,11 +376,14 @@ buildPythonPackage (finalAttrs: {
plexupdate = { };
random = { };
replace = { };
replaygain.wrapperBins = [
aacgain
ffmpeg
mp3gain
];
replaygain = {
singlePluginTest.config.backend = "gstreamer";
wrapperBins = [
aacgain
ffmpeg
mp3gain
];
};
rewrite.testPaths = [ ];
scrub.testPaths = [ ];
smartplaylist = { };
@@ -378,7 +391,10 @@ buildPythonPackage (finalAttrs: {
propagatedBuildInputs = [ soco ];
testPaths = [ ];
};
spotify = { };
spotify.singlePluginTest.setup = ''
mkdir -p $HOME/.config/beets
echo '{"access_token":"test"}' > $HOME/.config/beets/spotify_token.json
'';
subsonicplaylist = {
propagatedBuildInputs = [ requests ];
testPaths = [ ];
@@ -428,6 +444,10 @@ buildPythonPackage (finalAttrs: {
enable = !disableAllPlugins;
builtin = false;
propagatedBuildInputs = [ ];
singlePluginTest = {
config = { };
setup = "";
};
testPaths = [ "test/plugins/test_${n}.py" ];
wrapperBins = [ ];
} a
@@ -497,7 +517,66 @@ buildPythonPackage (finalAttrs: {
-c $out/config.yaml \
mpdstats --help 2> $out/mpdstats-help-stderr || true
'';
};
}
# Build and start beets once for each supported built-in plugin. Keeping the
# plugins isolated makes missing optional dependencies visible.
// lib.pipe finalAttrs.finalPackage.passthru.plugins.all [
# Deprecated plugins are not useful regression targets.
(lib.filterAttrs (_: pluginAttrs: !(pluginAttrs.deprecated or false)))
(lib.concatMapAttrs (
pluginName: pluginAttrs:
let
testConfig = {
plugins = [ pluginName ];
}
# Some plugins do not accept an empty attribute set as config.
// lib.optionalAttrs (pluginAttrs.singlePluginTest.config != { }) {
${pluginName} = pluginAttrs.singlePluginTest.config;
};
beetsWithSinglePlugin = beets.override {
disableAllPlugins = true;
pluginOverrides = {
${pluginName}.enable = true;
};
# The runCommand below is the relevant check; avoid running
# the full upstream test suite once per plugin. NOTE that
# testing whether any plugin's `testPaths` is incorrect, is
# done for all plugins via the `beets-minimal` derivation.
doCheck = false;
};
in
{
"with-single-plugin-${pluginName}" = beetsWithSinglePlugin;
"single-plugin-${pluginName}" = runCommand "beets-single-plugin-${pluginName}-test" { } ''
set -euo pipefail
export HOME=$(mktemp -d)
${pluginAttrs.singlePluginTest.setup}
mkdir $out
cat <<'EOF' > $out/config.yaml
${lib.generators.toYAML { } testConfig}
EOF
status=0
${lib.getExe beetsWithSinglePlugin} \
-c "$out/config.yaml" \
--help > "$out/stdout" 2> "$out/stderr" || status=$?
# beet exits successfully when a plugin fails to load, so its
# stderr must also be checked for the diagnostic.
if (( status != 0 )) || grep -Fq "error loading plugin" "$out/stderr"; then
{
printf '%s\n' '----- stdout -----'
cat "$out/stdout"
printf '%s\n' '----- stderr -----'
cat "$out/stderr"
} >&2
exit 1
fi
'';
}
))
];
};
meta = {