test: re-implement tests

Reimplement the tests of music modeling, and re-enable the automatic
test workflow in GH actions.

I'm actually going to work on reimplementing these.
This commit is contained in:
Alexander Capehart 2023-08-18 11:51:09 -06:00
parent 2c2bd79ae2
commit 59e42acad9
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
16 changed files with 567 additions and 790 deletions

View file

@ -23,8 +23,8 @@ jobs:
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
# - name: Test app with Gradle
# run: ./gradlew app:testDebug
- name: Test app with Gradle
run: ./gradlew app:testDebug
- name: Build debug APK with Gradle
run: ./gradlew app:packageDebug
- name: Upload debug APK artifact

View file

@ -145,8 +145,10 @@ dependencies {
// Testing
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
testImplementation "junit:junit:4.13.2"
testImplementation "io.mockk:mockk:1.13.7"
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
spotless {

View file

@ -20,6 +20,7 @@ package org.oxycblt.auxio.music.info
import android.content.Context
import androidx.annotation.StringRes
import androidx.annotation.VisibleForTesting
import java.text.CollationKey
import java.text.Collator
import org.oxycblt.auxio.music.MusicSettings
@ -54,10 +55,11 @@ sealed interface Name : Comparable<Name> {
abstract val sort: String?
/** A tokenized version of the name that will be compared. */
protected abstract val sortTokens: List<SortToken>
@VisibleForTesting(VisibleForTesting.PROTECTED) abstract val sortTokens: List<SortToken>
/** An individual part of a name string that can be compared intelligently. */
protected data class SortToken(val collationKey: CollationKey, val type: Type) :
@VisibleForTesting(VisibleForTesting.PROTECTED)
data class SortToken(val collationKey: CollationKey, val type: Type) :
Comparable<SortToken> {
override fun compareTo(other: SortToken): Int {
// Numeric tokens should always be lower than lexicographic tokens.

View file

@ -1,143 +0,0 @@
/*
* Copyright (c) 2023 Auxio Project
* FakeMusic.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music
import android.net.Uri
import org.oxycblt.auxio.music.fs.MimeType
import org.oxycblt.auxio.music.fs.Path
import org.oxycblt.auxio.music.info.Date
import org.oxycblt.auxio.music.info.Disc
import org.oxycblt.auxio.music.info.Name
import org.oxycblt.auxio.music.info.ReleaseType
open class FakeSong : Song {
override val name: Name
get() = throw NotImplementedError()
override val date: Date?
get() = throw NotImplementedError()
override val dateAdded: Long
get() = throw NotImplementedError()
override val disc: Disc?
get() = throw NotImplementedError()
override val genres: List<Genre>
get() = throw NotImplementedError()
override val mimeType: MimeType
get() = throw NotImplementedError()
override val track: Int?
get() = throw NotImplementedError()
override val path: Path
get() = throw NotImplementedError()
override val size: Long
get() = throw NotImplementedError()
override val uri: Uri
get() = throw NotImplementedError()
override val album: Album
get() = throw NotImplementedError()
override val artists: List<Artist>
get() = throw NotImplementedError()
override val durationMs: Long
get() = throw NotImplementedError()
override val uid: Music.UID
get() = throw NotImplementedError()
}
open class FakeAlbum : Album {
override val name: Name
get() = throw NotImplementedError()
override val coverUri: Uri
get() = throw NotImplementedError()
override val dateAdded: Long
get() = throw NotImplementedError()
override val dates: Date.Range?
get() = throw NotImplementedError()
override val releaseType: ReleaseType
get() = throw NotImplementedError()
override val artists: List<Artist>
get() = throw NotImplementedError()
override val durationMs: Long
get() = throw NotImplementedError()
override val songs: List<Song>
get() = throw NotImplementedError()
override val uid: Music.UID
get() = throw NotImplementedError()
}
open class FakeArtist : Artist {
override val name: Name
get() = throw NotImplementedError()
override val albums: List<Album>
get() = throw NotImplementedError()
override val explicitAlbums: List<Album>
get() = throw NotImplementedError()
override val implicitAlbums: List<Album>
get() = throw NotImplementedError()
override val genres: List<Genre>
get() = throw NotImplementedError()
override val durationMs: Long
get() = throw NotImplementedError()
override val songs: List<Song>
get() = throw NotImplementedError()
override val uid: Music.UID
get() = throw NotImplementedError()
}
open class FakeGenre : Genre {
override val name: Name
get() = throw NotImplementedError()
override val artists: List<Artist>
get() = throw NotImplementedError()
override val durationMs: Long
get() = throw NotImplementedError()
override val songs: List<Song>
get() = throw NotImplementedError()
override val uid: Music.UID
get() = throw NotImplementedError()
}

View file

@ -1,90 +0,0 @@
/*
* Copyright (c) 2023 Auxio Project
* FakeMusicRepository.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music
import kotlinx.coroutines.Job
import org.oxycblt.auxio.music.device.DeviceLibrary
import org.oxycblt.auxio.music.user.UserLibrary
open class FakeMusicRepository : MusicRepository {
override val indexingState: IndexingState?
get() = throw NotImplementedError()
override val deviceLibrary: DeviceLibrary?
get() = throw NotImplementedError()
override val userLibrary: UserLibrary?
get() = throw NotImplementedError()
override fun addUpdateListener(listener: MusicRepository.UpdateListener) {
throw NotImplementedError()
}
override fun removeUpdateListener(listener: MusicRepository.UpdateListener) {
throw NotImplementedError()
}
override fun addIndexingListener(listener: MusicRepository.IndexingListener) {
throw NotImplementedError()
}
override fun removeIndexingListener(listener: MusicRepository.IndexingListener) {
throw NotImplementedError()
}
override fun registerWorker(worker: MusicRepository.IndexingWorker) {
throw NotImplementedError()
}
override fun unregisterWorker(worker: MusicRepository.IndexingWorker) {
throw NotImplementedError()
}
override fun find(uid: Music.UID): Music? {
throw NotImplementedError()
}
override suspend fun createPlaylist(name: String, songs: List<Song>) {
throw NotImplementedError()
}
override suspend fun renamePlaylist(playlist: Playlist, name: String) {
throw NotImplementedError()
}
override suspend fun deletePlaylist(playlist: Playlist) {
throw NotImplementedError()
}
override suspend fun addToPlaylist(songs: List<Song>, playlist: Playlist) {
throw NotImplementedError()
}
override suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>) {
throw NotImplementedError()
}
override fun requestIndex(withCache: Boolean) {
throw NotImplementedError()
}
override fun index(worker: MusicRepository.IndexingWorker, withCache: Boolean): Job {
throw NotImplementedError()
}
}

View file

@ -1,77 +0,0 @@
/*
* Copyright (c) 2023 Auxio Project
* FakeMusicSettings.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music
import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.music.fs.MusicDirectories
open class FakeMusicSettings : MusicSettings {
override fun registerListener(listener: MusicSettings.Listener) = throw NotImplementedError()
override fun unregisterListener(listener: MusicSettings.Listener) = throw NotImplementedError()
override var musicDirs: MusicDirectories
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override val excludeNonMusic: Boolean
get() = throw NotImplementedError()
override val shouldBeObserving: Boolean
get() = throw NotImplementedError()
override var multiValueSeparators: String
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override val intelligentSorting: Boolean
get() = throw NotImplementedError()
override var songSort: Sort
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override var albumSort: Sort
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override var artistSort: Sort
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override var genreSort: Sort
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override var playlistSort: Sort
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override var albumSongSort: Sort
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override var artistSongSort: Sort
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
override var genreSongSort: Sort
get() = throw NotImplementedError()
set(_) = throw NotImplementedError()
}

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2023 Auxio Project
* MusicModeTest.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music
import org.junit.Assert.assertEquals
import org.junit.Test
class MusicModeTest {
@Test
fun intCode() {
assertEquals(MusicType.SONGS, MusicType.fromIntCode(MusicType.SONGS.intCode))
assertEquals(MusicType.ALBUMS, MusicType.fromIntCode(MusicType.ALBUMS.intCode))
assertEquals(MusicType.ARTISTS, MusicType.fromIntCode(MusicType.ARTISTS.intCode))
assertEquals(MusicType.GENRES, MusicType.fromIntCode(MusicType.GENRES.intCode))
}
}

View file

@ -1,133 +0,0 @@
/*
* Copyright (c) 2023 Auxio Project
* MusicViewModelTest.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.oxycblt.auxio.music.device.DeviceLibrary
import org.oxycblt.auxio.music.device.FakeDeviceLibrary
import org.oxycblt.auxio.util.forceClear
class MusicViewModelTest {
@Test
fun indexerState() {
val indexer =
TestMusicRepository().apply {
indexingState = IndexingState.Indexing(IndexingProgress.Indeterminate)
}
val musicViewModel = MusicViewModel(indexer, FakeMusicSettings())
assertTrue(indexer.updateListener is MusicViewModel)
assertTrue(indexer.indexingListener is MusicViewModel)
assertEquals(
IndexingProgress.Indeterminate,
(musicViewModel.indexingState.value as IndexingState.Indexing).progress)
indexer.indexingState = null
assertEquals(null, musicViewModel.indexingState.value)
musicViewModel.forceClear()
assertTrue(indexer.indexingListener == null)
}
@Test
fun statistics() {
val musicRepository = TestMusicRepository()
val musicViewModel = MusicViewModel(musicRepository, FakeMusicSettings())
assertEquals(null, musicViewModel.statistics.value)
musicRepository.deviceLibrary = TestDeviceLibrary()
assertEquals(
MusicViewModel.Statistics(
2,
3,
4,
1,
161616 * 2,
),
musicViewModel.statistics.value)
}
@Test
fun requests() {
val indexer = TestMusicRepository()
val musicViewModel = MusicViewModel(indexer, FakeMusicSettings())
musicViewModel.refresh()
musicViewModel.rescan()
assertEquals(listOf(true, false), indexer.requests)
}
private class TestMusicRepository : FakeMusicRepository() {
override var deviceLibrary: DeviceLibrary? = null
set(value) {
field = value
updateListener?.onMusicChanges(
MusicRepository.Changes(deviceLibrary = true, userLibrary = false))
}
override var indexingState: IndexingState? = null
set(value) {
field = value
indexingListener?.onIndexingStateChanged()
}
var updateListener: MusicRepository.UpdateListener? = null
var indexingListener: MusicRepository.IndexingListener? = null
val requests = mutableListOf<Boolean>()
override fun addUpdateListener(listener: MusicRepository.UpdateListener) {
listener.onMusicChanges(
MusicRepository.Changes(deviceLibrary = true, userLibrary = false))
this.updateListener = listener
}
override fun removeUpdateListener(listener: MusicRepository.UpdateListener) {
this.updateListener = null
}
override fun addIndexingListener(listener: MusicRepository.IndexingListener) {
listener.onIndexingStateChanged()
this.indexingListener = listener
}
override fun removeIndexingListener(listener: MusicRepository.IndexingListener) {
this.indexingListener = null
}
override fun requestIndex(withCache: Boolean) {
requests.add(withCache)
}
}
private class TestDeviceLibrary : FakeDeviceLibrary() {
override val songs: List<Song>
get() = listOf(TestSong(), TestSong())
override val albums: List<Album>
get() = listOf(FakeAlbum(), FakeAlbum(), FakeAlbum())
override val artists: List<Artist>
get() = listOf(FakeArtist(), FakeArtist(), FakeArtist(), FakeArtist())
override val genres: List<Genre>
get() = listOf(FakeGenre())
}
private class TestSong : FakeSong() {
override val durationMs: Long
get() = 161616
}
}

View file

@ -1,186 +0,0 @@
/*
* Copyright (c) 2023 Auxio Project
* DeviceMusicImplTest.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music.device
import java.util.UUID
import org.junit.Assert.assertTrue
import org.junit.Test
class DeviceMusicImplTest {
@Test
fun albumRaw_equals_inconsistentCase() {
val a =
RawAlbum(
mediaStoreId = -1,
musicBrainzId = null,
name = "Paraglow",
sortName = null,
releaseType = null,
rawArtists = listOf(RawArtist(name = "Parannoul"), RawArtist(name = "Asian Glow")))
val b =
RawAlbum(
mediaStoreId = -1,
musicBrainzId = null,
name = "paraglow",
sortName = null,
releaseType = null,
rawArtists = listOf(RawArtist(name = "Parannoul"), RawArtist(name = "Asian glow")))
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun albumRaw_equals_withMbids() {
val a =
RawAlbum(
mediaStoreId = -1,
musicBrainzId = UUID.fromString("c7b245c9-8099-32ea-af95-893acedde2cf"),
name = "Weezer",
sortName = "Blue Album",
releaseType = null,
rawArtists = listOf(RawArtist(name = "Weezer")))
val b =
RawAlbum(
mediaStoreId = -1,
musicBrainzId = UUID.fromString("923d5ba6-7eee-3bce-bcb2-c913b2bd69d4"),
name = "Weezer",
sortName = "Green Album",
releaseType = null,
rawArtists = listOf(RawArtist(name = "Weezer")))
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun albumRaw_equals_inconsistentMbids() {
val a =
RawAlbum(
mediaStoreId = -1,
musicBrainzId = UUID.fromString("c7b245c9-8099-32ea-af95-893acedde2cf"),
name = "Weezer",
sortName = "Blue Album",
releaseType = null,
rawArtists = listOf(RawArtist(name = "Weezer")))
val b =
RawAlbum(
mediaStoreId = -1,
musicBrainzId = null,
name = "Weezer",
sortName = "Green Album",
releaseType = null,
rawArtists = listOf(RawArtist(name = "Weezer")))
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun albumRaw_equals_withArtists() {
val a =
RawAlbum(
mediaStoreId = -1,
musicBrainzId = null,
name = "Album",
sortName = null,
releaseType = null,
rawArtists = listOf(RawArtist(name = "Artist A")))
val b =
RawAlbum(
mediaStoreId = -1,
musicBrainzId = null,
name = "Album",
sortName = null,
releaseType = null,
rawArtists = listOf(RawArtist(name = "Artist B")))
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun artistRaw_equals_inconsistentCase() {
val a = RawArtist(musicBrainzId = null, name = "Parannoul")
val b = RawArtist(musicBrainzId = null, name = "parannoul")
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun artistRaw_equals_withMbids() {
val a =
RawArtist(
musicBrainzId = UUID.fromString("677325ef-d850-44bb-8258-0d69bbc0b3f7"),
name = "Artist")
val b =
RawArtist(
musicBrainzId = UUID.fromString("6b625592-d88d-48c8-ac1a-c5b476d78bcc"),
name = "Artist")
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun artistRaw_equals_inconsistentMbids() {
val a =
RawArtist(
musicBrainzId = UUID.fromString("677325ef-d850-44bb-8258-0d69bbc0b3f7"),
name = "Artist")
val b = RawArtist(musicBrainzId = null, name = "Artist")
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun artistRaw_equals_missingNames() {
val a = RawArtist(name = null)
val b = RawArtist(name = null)
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun artistRaw_equals_inconsistentNames() {
val a = RawArtist(name = null)
val b = RawArtist(name = "Parannoul")
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun genreRaw_equals_inconsistentCase() {
val a = RawGenre("Future Garage")
val b = RawGenre("future garage")
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun genreRaw_equals_missingNames() {
val a = RawGenre(name = null)
val b = RawGenre(name = null)
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun genreRaw_equals_inconsistentNames() {
val a = RawGenre(name = null)
val b = RawGenre(name = "Future Garage")
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
}

View file

@ -1,61 +0,0 @@
/*
* Copyright (c) 2023 Auxio Project
* FakeDeviceLibrary.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music.device
import android.content.Context
import android.net.Uri
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Song
open class FakeDeviceLibrary : DeviceLibrary {
override val songs: List<Song>
get() = throw NotImplementedError()
override val albums: List<Album>
get() = throw NotImplementedError()
override val artists: List<Artist>
get() = throw NotImplementedError()
override val genres: List<Genre>
get() = throw NotImplementedError()
override fun findSong(uid: Music.UID): Song? {
throw NotImplementedError()
}
override fun findSongForUri(context: Context, uri: Uri): Song? {
throw NotImplementedError()
}
override fun findAlbum(uid: Music.UID): Album? {
throw NotImplementedError()
}
override fun findArtist(uid: Music.UID): Artist? {
throw NotImplementedError()
}
override fun findGenre(uid: Music.UID): Genre? {
throw NotImplementedError()
}
}

View file

@ -1,4 +1,91 @@
/*
* Copyright (c) 2023 Auxio Project
* DateTest.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music.info
class NameTest {
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
class DateTest {
@Test
fun date_equals_varyingPrecision() {
assertTrue(
requireNotNull(Date.from("2016-08-16T00:01:02")) !=
requireNotNull(Date.from("2016-08-16")))
}
@Test
fun date_compareTo_dates() {
val a = requireNotNull(Date.from("2016-08-16T00:01:02"))
val b = requireNotNull(Date.from("2016-09-16T00:01:02"))
assertEquals(-1, a.compareTo(b))
}
@Test
fun date_compareTo_times() {
val a = requireNotNull(Date.from("2016-08-16T00:02:02"))
val b = requireNotNull(Date.from("2016-08-16T00:01:02"))
assertEquals(1, a.compareTo(b))
}
@Test
fun date_compareTo_varyingPrecision() {
val a = requireNotNull(Date.from("2016-08-16T00:01:02"))
val b = requireNotNull(Date.from("2016-08-16"))
assertEquals(
1,
a.compareTo(b),
)
}
@Test
fun date_from_values() {
assertEquals("2016", Date.from(2016).toString())
assertEquals("2016-08-16", Date.from(2016, 8, 16).toString())
assertEquals("2016-08-16T00:01Z", Date.from(2016, 8, 16, 0, 1).toString())
}
@Test
fun date_from_yearDate() {
assertEquals("2016-08-16", Date.from(20160816).toString())
assertEquals("2016-08-16", Date.from("20160816").toString())
}
@Test
fun date_from_timestamp() {
assertEquals("2016-08-16T00:01:02Z", Date.from("2016-08-16T00:01:02").toString())
assertEquals("2016-08-16T00:01:02Z", Date.from("2016-08-16 00:01:02").toString())
}
@Test
fun date_from_lesserPrecision() {
assertEquals("2016", Date.from("2016").toString())
assertEquals("2016-08", Date.from("2016-08").toString())
assertEquals("2016-08-16", Date.from("2016-08-16").toString())
assertEquals("2016-08-16T00:01Z", Date.from("2016-08-16T00:01").toString())
}
@Test
fun date_from_wack() {
assertEquals(null, Date.from(0))
assertEquals(null, Date.from(""))
assertEquals(null, Date.from("2016-08-16:00:01:02"))
assertEquals("2016-11", Date.from("2016-11-32 25:43:01").toString())
}
}

View file

@ -19,30 +19,36 @@
package org.oxycblt.auxio.music.info
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
class DiscTest {
@Test
fun disc_compare() {
val a = Disc(1, "Part I")
val b = Disc(2, "Part II")
fun disc_equals_byNum() {
val a = Disc(0, null)
val b = Disc(0, null)
assertEquals(a, b)
assertEquals(a.hashCode(), b.hashCode())
}
@Test
fun disc_equals_bySubtitle() {
val a = Disc(0, "z subtitle")
val b = Disc(0, "a subtitle")
assertEquals(a, b)
assertEquals(a.hashCode(), b.hashCode())
}
@Test
fun disc_compareTo_byNum() {
val a = Disc(0, null)
val b = Disc(1, null)
assertEquals(-1, a.compareTo(b))
}
@Test
fun disc_equals_correct() {
val a = Disc(1, "Part I")
val b = Disc(1, "Part I")
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun disc_equals_inconsistentNames() {
val a = Disc(1, "Part I")
val b = Disc(1, null)
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
fun disc_compareTo_bySubtitle() {
val a = Disc(0, "z subtitle")
val b = Disc(1, "a subtitle")
assertEquals(-1, a.compareTo(b))
}
}

View file

@ -1,4 +1,430 @@
/*
* Copyright (c) 2023 Auxio Project
* NameTest.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.music.info
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Test
import org.oxycblt.auxio.music.MusicSettings
class NameTest {
private fun mockIntelligentSorting(enabled: Boolean) =
mockk<MusicSettings>().apply { every { intelligentSorting } returns enabled }
@Test
fun name_from_simple_withoutPunct() {
val name = Name.Known.from("Loveless", null, mockIntelligentSorting(false))
assertEquals("Loveless", name.raw)
assertEquals(null, name.sort)
assertEquals("L", name.thumb)
val only = name.sortTokens.single()
assertEquals("Loveless", only.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, only.type)
}
@Test
fun name_from_simple_withPunct() {
val name = Name.Known.from("alt-J", null, mockIntelligentSorting(false))
assertEquals("alt-J", name.raw)
assertEquals(null, name.sort)
assertEquals("A", name.thumb)
val only = name.sortTokens.single()
assertEquals("altJ", only.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, only.type)
}
@Test
fun name_from_simple_oopsAllPunct() {
val name = Name.Known.from("!!!", null, mockIntelligentSorting(false))
assertEquals("!!!", name.raw)
assertEquals(null, name.sort)
assertEquals("!", name.thumb)
val only = name.sortTokens.single()
assertEquals("!!!", only.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, only.type)
}
@Test
fun name_from_simple_spacedPunct() {
val name = Name.Known.from("& Yet & Yet", null, mockIntelligentSorting(false))
assertEquals("& Yet & Yet", name.raw)
assertEquals(null, name.sort)
assertEquals("Y", name.thumb)
val first = name.sortTokens[0]
assertEquals("Yet Yet", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
}
@Test
fun name_from_simple_withSort() {
val name = Name.Known.from("The Smile", "Smile", mockIntelligentSorting(false))
assertEquals("The Smile", name.raw)
assertEquals("Smile", name.sort)
assertEquals("S", name.thumb)
val only = name.sortTokens.single()
assertEquals("Smile", only.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, only.type)
}
@Test
fun name_from_intelligent_withoutPunct_withoutArticle_withoutNumerics() {
val name = Name.Known.from("Loveless", null, mockIntelligentSorting(true))
assertEquals("Loveless", name.raw)
assertEquals(null, name.sort)
assertEquals("L", name.thumb)
val only = name.sortTokens.single()
assertEquals("Loveless", only.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, only.type)
}
@Test
fun name_from_intelligent_withoutPunct_withoutArticle_withSpacedStartNumerics() {
val name = Name.Known.from("15 Step", null, mockIntelligentSorting(true))
assertEquals("15 Step", name.raw)
assertEquals(null, name.sort)
assertEquals("#", name.thumb)
val first = name.sortTokens[0]
assertEquals("15", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, first.type)
val second = name.sortTokens[1]
assertEquals("Step", second.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, second.type)
}
@Test
fun name_from_intelligent_withoutPunct_withoutArticle_withPackedStartNumerics() {
val name = Name.Known.from("23Kid", null, mockIntelligentSorting(true))
assertEquals("23Kid", name.raw)
assertEquals(null, name.sort)
assertEquals("#", name.thumb)
val first = name.sortTokens[0]
assertEquals("23", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, first.type)
val second = name.sortTokens[1]
assertEquals("Kid", second.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, second.type)
}
@Test
fun name_from_intelligent_withoutPunct_withoutArticle_withSpacedMiddleNumerics() {
val name = Name.Known.from("Foo 1 2 Bar", null, mockIntelligentSorting(true))
assertEquals("Foo 1 2 Bar", name.raw)
assertEquals(null, name.sort)
assertEquals("F", name.thumb)
val first = name.sortTokens[0]
assertEquals("Foo", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
val second = name.sortTokens[1]
assertEquals("1", second.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, second.type)
val third = name.sortTokens[2]
assertEquals(" ", third.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, third.type)
val fourth = name.sortTokens[3]
assertEquals("2", fourth.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, fourth.type)
val fifth = name.sortTokens[4]
assertEquals("Bar", fifth.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, fifth.type)
}
@Test
fun name_from_intelligent_withoutPunct_withoutArticle_withPackedMiddleNumerics() {
val name = Name.Known.from("Foo12Bar", null, mockIntelligentSorting(true))
assertEquals("Foo12Bar", name.raw)
assertEquals(null, name.sort)
assertEquals("F", name.thumb)
val first = name.sortTokens[0]
assertEquals("Foo", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
val second = name.sortTokens[1]
assertEquals("12", second.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, second.type)
val third = name.sortTokens[2]
assertEquals("Bar", third.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, third.type)
}
@Test
fun name_from_intelligent_withoutPunct_withoutArticle_withSpacedEndNumerics() {
val name = Name.Known.from("Foo 1", null, mockIntelligentSorting(true))
assertEquals("Foo 1", name.raw)
assertEquals(null, name.sort)
assertEquals("F", name.thumb)
val first = name.sortTokens[0]
assertEquals("Foo", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
val second = name.sortTokens[1]
assertEquals("1", second.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, second.type)
}
@Test
fun name_from_intelligent_withoutPunct_withoutArticle_withPackedEndNumerics() {
val name = Name.Known.from("Error404", null, mockIntelligentSorting(true))
assertEquals("Error404", name.raw)
assertEquals(null, name.sort)
assertEquals("E", name.thumb)
val first = name.sortTokens[0]
assertEquals("Error", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
val second = name.sortTokens[1]
assertEquals("404", second.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, second.type)
}
@Test
fun name_from_intelligent_withoutPunct_withThe_withoutNumerics() {
val name = Name.Known.from("The National Anthem", null, mockIntelligentSorting(true))
assertEquals("The National Anthem", name.raw)
assertEquals(null, name.sort)
assertEquals("N", name.thumb)
val first = name.sortTokens[0]
assertEquals("National Anthem", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
}
@Test
fun name_from_intelligent_withoutPunct_withAn_withoutNumerics() {
val name = Name.Known.from("An Eagle in Your Mind", null, mockIntelligentSorting(true))
assertEquals("An Eagle in Your Mind", name.raw)
assertEquals(null, name.sort)
assertEquals("E", name.thumb)
val first = name.sortTokens[0]
assertEquals("Eagle in Your Mind", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
}
@Test
fun name_from_intelligent_withoutPunct_withA_withoutNumerics() {
val name = Name.Known.from("A Song For Our Fathers", null, mockIntelligentSorting(true))
assertEquals("A Song For Our Fathers", name.raw)
assertEquals(null, name.sort)
assertEquals("S", name.thumb)
val first = name.sortTokens[0]
assertEquals("Song For Our Fathers", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
}
@Test
fun name_from_intelligent_withPunct_withoutArticle_withoutNumerics() {
val name = Name.Known.from("alt-J", null, mockIntelligentSorting(true))
assertEquals("alt-J", name.raw)
assertEquals(null, name.sort)
assertEquals("A", name.thumb)
val only = name.sortTokens.single()
assertEquals("altJ", only.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, only.type)
}
@Test
fun name_from_intelligent_oopsAllPunct_withoutArticle_withoutNumerics() {
val name = Name.Known.from("!!!", null, mockIntelligentSorting(true))
assertEquals("!!!", name.raw)
assertEquals(null, name.sort)
assertEquals("!", name.thumb)
val only = name.sortTokens.single()
assertEquals("!!!", only.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, only.type)
}
@Test
fun name_from_intelligent_withoutPunct_shortArticle_withNumerics() {
val name = Name.Known.from("the 1", null, mockIntelligentSorting(true))
assertEquals("the 1", name.raw)
assertEquals(null, name.sort)
assertEquals("#", name.thumb)
val first = name.sortTokens[0]
assertEquals("1", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, first.type)
}
@Test
fun name_from_intelligent_spacedPunct_withoutArticle_withoutNumerics() {
val name = Name.Known.from("& Yet & Yet", null, mockIntelligentSorting(true))
assertEquals("& Yet & Yet", name.raw)
assertEquals(null, name.sort)
assertEquals("Y", name.thumb)
val first = name.sortTokens[0]
assertEquals("Yet Yet", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
}
@Test
fun name_from_intelligent_withPunct_withoutArticle_withNumerics() {
val name = Name.Known.from("Design : 2 : 3", null, mockIntelligentSorting(true))
assertEquals("Design : 2 : 3", name.raw)
assertEquals(null, name.sort)
assertEquals("D", name.thumb)
val first = name.sortTokens[0]
assertEquals("Design", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, first.type)
val second = name.sortTokens[1]
assertEquals("2", second.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, second.type)
val third = name.sortTokens[2]
assertEquals(" ", third.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, third.type)
val fourth = name.sortTokens[3]
assertEquals("3", fourth.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, fourth.type)
}
@Test
fun name_from_intelligent_oopsAllPunct_withoutArticle_oopsAllNumerics() {
val name = Name.Known.from("2 + 2 = 5", null, mockIntelligentSorting(true))
assertEquals("2 + 2 = 5", name.raw)
assertEquals(null, name.sort)
assertEquals("#", name.thumb)
val first = name.sortTokens[0]
assertEquals("2", first.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, first.type)
val second = name.sortTokens[1]
assertEquals(" ", second.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, second.type)
val third = name.sortTokens[2]
assertEquals("2", third.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, third.type)
val fourth = name.sortTokens[3]
assertEquals(" ", fourth.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, fourth.type)
val fifth = name.sortTokens[4]
assertEquals("5", fifth.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.NUMERIC, fifth.type)
}
@Test
fun name_from_intelligent_withSort() {
val name = Name.Known.from("The Smile", "Smile", mockIntelligentSorting(true))
assertEquals("The Smile", name.raw)
assertEquals("Smile", name.sort)
assertEquals("S", name.thumb)
val only = name.sortTokens.single()
assertEquals("Smile", only.collationKey.sourceString)
assertEquals(Name.Known.SortToken.Type.LEXICOGRAPHIC, only.type)
}
@Test
fun name_equals_simple() {
val a = Name.Known.from("The Same", "Same", mockIntelligentSorting(false))
val b = Name.Known.from("The Same", "Same", mockIntelligentSorting(false))
assertEquals(a, b)
}
@Test
fun name_equals_differentSort() {
val a = Name.Known.from("The Same", "Same", mockIntelligentSorting(false))
val b = Name.Known.from("The Same", null, mockIntelligentSorting(false))
assertNotEquals(a, b)
assertNotEquals(a.hashCode(), b.hashCode())
}
@Test
fun name_equals_intelligent_differentTokens() {
val a = Name.Known.from("The Same", "Same", mockIntelligentSorting(true))
val b = Name.Known.from("Same", "Same", mockIntelligentSorting(true))
assertNotEquals(a, b)
assertNotEquals(a.hashCode(), b.hashCode())
}
@Test
fun name_compareTo_simple_withoutSort_withoutArticle_withoutNumeric() {
val a = Name.Known.from("A", null, mockIntelligentSorting(false))
val b = Name.Known.from("B", null, mockIntelligentSorting(false))
assertEquals(-1, a.compareTo(b))
}
@Test
fun name_compareTo_simple_withoutSort_withArticle_withoutNumeric() {
val a = Name.Known.from("A Brain in a Bottle", null, mockIntelligentSorting(false))
val b = Name.Known.from("Acid Rain", null, mockIntelligentSorting(false))
val c = Name.Known.from("Boralis / Contrastellar", null, mockIntelligentSorting(false))
val d = Name.Known.from("Breathe In", null, mockIntelligentSorting(false))
assertEquals(-1, a.compareTo(b))
assertEquals(-1, a.compareTo(c))
assertEquals(-1, a.compareTo(d))
}
@Test
fun name_compareTo_simple_withSort_withoutArticle_withNumeric() {
val a = Name.Known.from("15 Step", null, mockIntelligentSorting(false))
val b = Name.Known.from("128 Harps", null, mockIntelligentSorting(false))
val c = Name.Known.from("1969", null, mockIntelligentSorting(false))
assertEquals(1, a.compareTo(b))
assertEquals(-1, a.compareTo(c))
}
@Test
fun name_compareTo_simple_withPartialSort() {
val a = Name.Known.from("A", "C", mockIntelligentSorting(false))
val b = Name.Known.from("B", null, mockIntelligentSorting(false))
assertEquals(1, a.compareTo(b))
}
@Test
fun name_compareTo_simple_withSort() {
val a = Name.Known.from("D", "A", mockIntelligentSorting(false))
val b = Name.Known.from("C", "B", mockIntelligentSorting(false))
assertEquals(-1, a.compareTo(b))
}
@Test
fun name_compareTo_intelligent_withoutSort_withoutArticle_withoutNumeric() {
val a = Name.Known.from("A", null, mockIntelligentSorting(true))
val b = Name.Known.from("B", null, mockIntelligentSorting(true))
assertEquals(-1, a.compareTo(b))
}
@Test
fun name_compareTo_intelligent_withoutSort_withArticle_withoutNumeric() {
val a = Name.Known.from("A Brain in a Bottle", null, mockIntelligentSorting(true))
val b = Name.Known.from("Acid Rain", null, mockIntelligentSorting(true))
val c = Name.Known.from("Boralis / Contrastellar", null, mockIntelligentSorting(true))
val d = Name.Known.from("Breathe In", null, mockIntelligentSorting(true))
assertEquals(1, a.compareTo(b))
assertEquals(1, a.compareTo(c))
assertEquals(-1, a.compareTo(d))
}
@Test
fun name_compareTo_intelligent_withoutSort_withoutArticle_withNumeric() {
val a = Name.Known.from("15 Step", null, mockIntelligentSorting(true))
val b = Name.Known.from("128 Harps", null, mockIntelligentSorting(true))
val c = Name.Known.from("1969", null, mockIntelligentSorting(true))
assertEquals(-1, a.compareTo(b))
assertEquals(-1, b.compareTo(c))
assertEquals(-2, a.compareTo(c))
}
@Test
fun name_compareTo_intelligent_withPartialSort_withoutArticle_withoutNumeric() {
val a = Name.Known.from("A", "C", mockIntelligentSorting(false))
val b = Name.Known.from("B", null, mockIntelligentSorting(false))
assertEquals(1, a.compareTo(b))
}
@Test
fun name_compareTo_intelligent_withSort_withoutArticle_withoutNumeric() {
val a = Name.Known.from("D", "A", mockIntelligentSorting(true))
val b = Name.Known.from("C", "B", mockIntelligentSorting(true))
assertEquals(-1, a.compareTo(b))
}
}

View file

@ -18,27 +18,32 @@
package org.oxycblt.auxio.music.metadata
import io.mockk.every
import io.mockk.mockk
import org.junit.Assert.assertEquals
import org.junit.Test
import org.oxycblt.auxio.music.FakeMusicSettings
import org.oxycblt.auxio.music.MusicSettings
class TagUtilTest {
private fun mockSeparators(separators: String) =
mockk<MusicSettings>().apply { every { multiValueSeparators } returns separators }
@Test
fun parseMultiValue_single() {
assertEquals(listOf("a", "b", "c"), listOf("a,b,c").parseMultiValue(TestMusicSettings(",")))
assertEquals(listOf("a", "b", "c"), listOf("a,b,c").parseMultiValue(mockSeparators(",")))
}
@Test
fun parseMultiValue_many() {
assertEquals(
listOf("a", "b", "c"), listOf("a", "b", "c").parseMultiValue(TestMusicSettings(",")))
listOf("a", "b", "c"), listOf("a", "b", "c").parseMultiValue(mockSeparators(",")))
}
@Test
fun parseMultiValue_several() {
assertEquals(
listOf("a", "b", "c", "d", "e", "f"),
listOf("a,b;c/d+e&f").parseMultiValue(TestMusicSettings(",;/+&")))
listOf("a,b;c/d+e&f").parseMultiValue(mockSeparators(",;/+&")))
}
@Test
@ -131,43 +136,37 @@ class TagUtilTest {
fun parseId3v2Genre_multi() {
assertEquals(
listOf("Post-Rock", "Shoegaze", "Glitch"),
listOf("Post-Rock", "Shoegaze", "Glitch").parseId3GenreNames(TestMusicSettings(",")))
listOf("Post-Rock", "Shoegaze", "Glitch").parseId3GenreNames(mockSeparators(",")))
}
@Test
fun parseId3v2Genre_multiId3v1() {
assertEquals(
listOf("Post-Rock", "Shoegaze", "Glitch"),
listOf("176", "178", "Glitch").parseId3GenreNames(TestMusicSettings(",")))
listOf("176", "178", "Glitch").parseId3GenreNames(mockSeparators(",")))
}
@Test
fun parseId3v2Genre_wackId3() {
assertEquals(listOf("2941"), listOf("2941").parseId3GenreNames(TestMusicSettings(",")))
assertEquals(listOf("2941"), listOf("2941").parseId3GenreNames(mockSeparators(",")))
}
@Test
fun parseId3v2Genre_singleId3v23() {
assertEquals(
listOf("Post-Rock", "Shoegaze", "Remix", "Cover", "Glitch"),
listOf("(176)(178)(RX)(CR)Glitch").parseId3GenreNames(TestMusicSettings(",")))
listOf("(176)(178)(RX)(CR)Glitch").parseId3GenreNames(mockSeparators(",")))
}
@Test
fun parseId3v2Genre_singleSeparated() {
assertEquals(
listOf("Post-Rock", "Shoegaze", "Glitch"),
listOf("Post-Rock, Shoegaze, Glitch").parseId3GenreNames(TestMusicSettings(",")))
listOf("Post-Rock, Shoegaze, Glitch").parseId3GenreNames(mockSeparators(",")))
}
@Test
fun parsId3v2Genre_singleId3v1() {
assertEquals(listOf("Post-Rock"), listOf("176").parseId3GenreNames(TestMusicSettings(",")))
}
class TestMusicSettings(private val separators: String) : FakeMusicSettings() {
override var multiValueSeparators: String
get() = separators
set(_) = throw NotImplementedError()
assertEquals(listOf("Post-Rock"), listOf("176").parseId3GenreNames(mockSeparators(",")))
}
}

View file

@ -39,6 +39,7 @@ class TextTagsTest {
assertEquals(listOf("2022"), textTags.vorbis["date"])
assertEquals(listOf("ep"), textTags.vorbis["releasetype"])
assertEquals(listOf("+2 dB"), textTags.vorbis["replaygain_track_gain"])
assertEquals(null, textTags.id3v2["APIC"])
}
@Test
@ -51,6 +52,7 @@ class TextTagsTest {
assertEquals(listOf("2022"), textTags.id3v2["TDRC"])
assertEquals(listOf("ep"), textTags.id3v2["TXXX:musicbrainz album type"])
assertEquals(listOf("+2 dB"), textTags.id3v2["TXXX:replaygain_track_gain"])
assertEquals(null, textTags.id3v2["metadata_block_picture"])
}
@Test
@ -62,10 +64,13 @@ class TextTagsTest {
assertEquals(listOf("2022"), textTags.vorbis["date"])
assertEquals(listOf("ep"), textTags.vorbis["releasetype"])
assertEquals(listOf("+2 dB"), textTags.vorbis["replaygain_track_gain"])
assertEquals(null, textTags.id3v2["metadata_block_picture"])
assertEquals(listOf("Wheel"), textTags.id3v2["TIT2"])
assertEquals(listOf("Paraglow"), textTags.id3v2["TALB"])
assertEquals(listOf("Parannoul", "Asian Glow"), textTags.id3v2["TPE1"])
assertEquals(listOf("2022"), textTags.id3v2["TDRC"])
assertEquals(null, textTags.id3v2["APIC"])
assertEquals(listOf("ep"), textTags.id3v2["TXXX:musicbrainz album type"])
assertEquals(listOf("+2 dB"), textTags.id3v2["TXXX:replaygain_track_gain"])
}

View file

@ -1,28 +0,0 @@
/*
* Copyright (c) 2023 Auxio Project
* TestingUtil.kt is part of Auxio.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.oxycblt.auxio.util
import androidx.lifecycle.ViewModel
private val VM_CLEAR_METHOD =
ViewModel::class.java.getDeclaredMethod("clear").apply { isAccessible = true }
fun ViewModel.forceClear() {
VM_CLEAR_METHOD.invoke(this)
}