Files
navidrome/core/external/provider_matching_internal_test.go
T
Deluan Quintão 772d1f359b feat: add similar songs functionality in agents, and Instant Mix (song-based) to UI (#4919)
* refactor: rename ArtistRadio to SimilarSongs for clarity and consistency

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: implement GetSimilarSongsByTrack and related functionality for song similarity retrieval

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: enhance GetSimilarSongsByTrack to include artist and album details and update tests

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: enhance song matching by implementing title and artist filtering in loadTracksByTitleAndArtist

Signed-off-by: Deluan <deluan@navidrome.org>

* test: add unit tests for song matching functionality in provider

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: extract song matching functionality into its own file

Signed-off-by: Deluan <deluan@navidrome.org>

* docs: clarify similarSongsFallback function description in provider.go

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: initialize result slice for songs with capacity based on response length

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: simplify agent method calls for retrieving images and similar songs

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: simplify agent method calls for retrieving images and similar songs

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: remove outdated comments in GetSimilarSongs methods

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: use composite key for song matches to handle duplicates by title and artist

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: consolidate expectations setup for similar songs tests

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: add instant mix action to song context menu and update translations

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(provider): handle unknown entity types in GetSimilarSongs

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: move playSimilar action to playbackActions and streamline song processing

Signed-off-by: Deluan <deluan@navidrome.org>

* format

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: enhance instant mix functionality with loading notification and shuffle option

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: implement fuzzy matching for similar songs based on configurable threshold

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: implement track matching with multiple specificity levels

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: enhance track matching by implementing unified scoring with specificity levels

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: enhance deezer top tracks result with album

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: enhance track matching with fuzzy album similarity for improved scoring

Signed-off-by: Deluan <deluan@navidrome.org>

* docs: document multi-phase song matching algorithm with detailed scoring and prioritization

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2026-01-25 16:16:43 -05:00

58 lines
1.8 KiB
Go

package external
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("similarityRatio", func() {
It("returns 1.0 for identical strings", func() {
Expect(similarityRatio("hello", "hello")).To(BeNumerically("==", 1.0))
})
It("returns 0.0 for empty strings", func() {
Expect(similarityRatio("", "test")).To(BeNumerically("==", 0.0))
Expect(similarityRatio("test", "")).To(BeNumerically("==", 0.0))
})
It("returns high similarity for remastered suffix", func() {
// Jaro-Winkler gives ~0.92 for this case
ratio := similarityRatio("paranoid android", "paranoid android remastered")
Expect(ratio).To(BeNumerically(">=", 0.85))
})
It("returns high similarity for suffix additions like (Live)", func() {
// Jaro-Winkler gives ~0.96 for this case
ratio := similarityRatio("bohemian rhapsody", "bohemian rhapsody live")
Expect(ratio).To(BeNumerically(">=", 0.90))
})
It("returns high similarity for 'yesterday' variants (common prefix)", func() {
// Jaro-Winkler gives ~0.90 because of common prefix
ratio := similarityRatio("yesterday", "yesterday once more")
Expect(ratio).To(BeNumerically(">=", 0.85))
})
It("returns low similarity for same suffix", func() {
// Jaro-Winkler gives ~0.70 for this case
ratio := similarityRatio("postman (live)", "taxman (live)")
Expect(ratio).To(BeNumerically("<", 0.85))
})
It("handles unicode characters", func() {
ratio := similarityRatio("dont stop believin", "don't stop believin'")
Expect(ratio).To(BeNumerically(">=", 0.85))
})
It("returns low similarity for completely different strings", func() {
ratio := similarityRatio("abc", "xyz")
Expect(ratio).To(BeNumerically("<", 0.5))
})
It("is symmetric", func() {
ratio1 := similarityRatio("hello world", "hello")
ratio2 := similarityRatio("hello", "hello world")
Expect(ratio1).To(Equal(ratio2))
})
})