BirdNet-goMikrofon/Arduino-audio-tools-main/arduino-audio-tools-main/tests-cmake/etc/strview-matches/strview-matches.cpp
2026-09-26 01:20:55 +02:00

89 lines
3.3 KiB
C++

/// Regression test for StrView::matches() (glob-style '*'/'?' matching,
/// plus ','/';'/'|' separated alternatives).
///
/// Covers a bug where a pattern ending in '*' (e.g. the "Track*" style
/// filters used by AudioSourceSDMMC/AudioSourceSTD/AudioSourceVFS file
/// filters, or OSC address patterns) failed to match a string that matches
/// the literal prefix exactly with nothing left over, e.g.
/// StrView("a").matches("a*") used to return false instead of true.
///
/// Also covers the alternatives syntax added to let a single file filter
/// select multiple extensions, e.g. "*.mp3;*.MP3;*.wav" - the exact style
/// of pattern a user tried (and which previously failed outright, since
/// the whole string was treated as one literal glob) when wiring up
/// AudioSourceSDMMC::setFileFilter() for a multi-format player.
#include <assert.h>
#include "AudioTools.h"
#include "AudioTools/CoreAudio/AudioBasic/StrView.h"
using namespace audio_tools;
static bool m(const char* line, const char* pattern) {
return StrView(line).matches(pattern);
}
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning);
// plain literal match / mismatch
assert(m("abc", "abc") == true);
assert(m("abc", "abd") == false);
// '?' wildcard
assert(m("abc", "a?c") == true);
assert(m("abc", "a?d") == false);
assert(m("ab", "a?c") == false); // '?' needs a char, string too short
// leading '*' (suffix match) - always worked
assert(m("test.mp3", "*.mp3") == true);
assert(m("test.wav", "*.mp3") == false);
assert(m("anything", "*") == true);
assert(m("", "*") == true);
// trailing '*' (prefix match) - this was the broken case
assert(m("a", "a*") == true);
assert(m("ab", "a*") == true);
assert(m("ab", "ab*") == true);
assert(m("Track", "Track*") == true);
assert(m("Track01.mp3", "Track*") == true);
assert(m("Tra", "Track*") == false);
// multiple '*' wildcards, including one immediately at the end
assert(m("abc", "*a*b*c*") == true);
assert(m("aXbXc", "*a*b*c*") == true);
assert(m("xaXbc", "*a*b*c*") == true);
assert(m("xyz", "*a*b*c*") == false);
// empty pattern / empty string edge cases
assert(m("", "") == true);
assert(m("a", "") == false);
assert(m("", "a") == false);
assert(m("", "**") == true);
// alternatives separated by ',', ';' or '|'
assert(m("x.wav", "*.mp3,*.wav") == true);
assert(m("x.wav", "*.mp3|*.wav") == true);
assert(m("x.wav", "*.mp3;*.wav") == true);
assert(m("x.flac", "*.mp3;*.wav") == false);
// whitespace around a separator is trimmed
assert(m("x.wav", "*.mp3; *.wav") == true);
assert(m("x.wav", "*.mp3 ; *.wav") == true);
// mixed separators, and the real-world multi-extension filter from the
// "using MultiDecoder for SD card" report (github discussion #2411)
const char* multi_ext = "*.mp3;*.MP3;*.aac;*.AAC;*.wav;*.WAV;*.flac;*.FLAC";
assert(m("09 - Track.MP3", multi_ext) == true);
assert(m("Britney Spears - If U Seek Amy.flac", multi_ext) == true);
assert(m("11.wav", multi_ext) == true);
assert(m("WPSettings.dat", multi_ext) == false);
assert(m("IndexerVolumeGuid", multi_ext) == false);
// pattern made up only of separators has no real alternative
assert(m("x", ",;|") == false);
Serial.println("All StrView::matches() tests passed");
exit(0);
}
void loop() {}