Add a test suite and fix 7 bugs it found - #76
Closed
Xehanort88 wants to merge 2 commits into
Closed
Xehanort88 wants to merge 2 commits into
Xehanort88 wants to merge 2 commits into
Conversation
Tests generate their own audio: an intro followed by a repeated 8-note pattern, so the correct loop points are known in advance and loop detection can be checked for correctness, not just for running. Covers audio loading, loop detection and scoring, zero-crossing snapping, split/extend/tag/txt exports, the interactive picker, batch file discovery and every CLI command. Known bugs are marked as strict xfail, so each fix is flagged until its marker is removed. Also adds pytest as a dev dependency and a CI workflow running the tests on Ubuntu and Windows with Python 3.10 and 3.13.
- Mono tracks were played and exported louder than the original: the analysis-only normalization was applied in place to the audio array that is also used for playback, since to_mono returns its input as-is for mono audio. - Longer loops were never preferred among near-identical scores: _prioritize_duration ran before loop_start/loop_end were set, so every duration it compared was 0. - Loops starting in the first seconds of a track were underscored: the truncated look-behind window was zero-padded on the side nearest the loop point, where the weights are heaviest. - Interactive mode discarded the choice made after 'more', 'all' or 'reset' and prompted again. - extend with fade_length=0 crashed (x[-0:] selects the whole array). - export_tags() without output_dir used the file path as the directory. - The txt export message named loop.txt instead of loops.txt.
This was referenced Sep 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds a pytest suite (the project currently has none) and fixes the bugs it uncovered. It's split into two commits so the fixes can be reviewed against the tests that demonstrate them.
1. Test suite
The tests generate their own audio: a short intro followed by the same 8-note pattern repeated several times. Since any loop spanning a whole number of patterns is seamless, the correct loop points are known in advance, so loop detection is checked for correctness, not just for running without errors.
tests/test_audio.pytests/test_analysis.pytests/test_core.pytests/test_handler.pytests/test_cli.pyThe whole suite runs in about 5–10 seconds (
uv run pytest). pytest is added as a dev dependency (theuv.lockdiff is only pytest and its dependencies), and aTestsworkflow runs the suite on Ubuntu and Windows with Python 3.10 and 3.13.In the first commit, each bug below has a test marked
xfail(strict=True); the second commit fixes them and removes the markers.2. Bug fixes
librosa.to_monoreturns its input unchanged, so the in-place normalization meant for analysis (mono_signal /= ...) also rescaledplayback_audio.play,split-audioandextendwere affected; stereo files were not._prioritize_durationran beforeloop_start/loop_endwere set, so every duration it compared was0 - 0. It now runs after the loop positions are set._calculate_subseq_beat_similarityis truncated, it was zero-padded at the end, i.e. next to the loop point, where the weights are heaviest. It's now padded on the side farthest from the loop point.more/all/resetdiscarded the choice made afterwards and prompted again, because the redrawn table's result wasn't returned.extend --fade-length 0crashed:x[-0:]selects the whole array, which then fails to broadcast.MusicLooper.export_tags()withoutoutput_dirused the file path instead of its directory (the CLI always passes one, so only API use was affected).loop.txtwhile the file written isloops.txt;export_txtnow returns the path it wrote.Test plan
uv run pyteston the first commit: 45 passed, 7 xfailed (the bugs above)uv run pyteston the second commit: 52 passed