music: add uid and raw tests

Add tests for the relatively simple Music.UID and Raw data classes
(excluding Song.Raw).

This should make sure most of the grouping code works, making the
library tests theoretically much simpler.
This commit is contained in:
Alexander Capehart 2023-01-08 10:31:28 -07:00
parent 0199d2f343
commit 9bd78bc855
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
2 changed files with 245 additions and 30 deletions

View file

@ -21,6 +21,7 @@ package org.oxycblt.auxio.music
import android.content.Context
import android.os.Parcelable
import androidx.annotation.VisibleForTesting
import java.security.MessageDigest
import java.text.CollationKey
import java.text.Collator
@ -763,16 +764,15 @@ class Album constructor(raw: Raw, override val songs: List<Song>) : MusicParent(
override fun hashCode() = hashCode
override fun equals(other: Any?): Boolean {
if (other !is Raw) return false
if (musicBrainzId != null &&
other.musicBrainzId != null &&
musicBrainzId == other.musicBrainzId) {
return true
}
return name.equals(other.name, true) && rawArtists == other.rawArtists
}
override fun equals(other: Any?) =
other is Raw &&
when {
musicBrainzId != null && other.musicBrainzId != null ->
musicBrainzId == other.musicBrainzId
musicBrainzId == null && other.musicBrainzId == null ->
name.equals(other.name, true) && rawArtists == other.rawArtists
else -> false
}
}
}
@ -916,21 +916,19 @@ class Artist constructor(private val raw: Raw, songAlbums: List<Music>) : MusicP
override fun hashCode() = hashCode
override fun equals(other: Any?): Boolean {
if (other !is Raw) return false
if (musicBrainzId != null &&
other.musicBrainzId != null &&
musicBrainzId == other.musicBrainzId) {
return true
}
return when {
name != null && other.name != null -> name.equals(other.name, true)
name == null && other.name == null -> true
else -> false
}
}
override fun equals(other: Any?) =
other is Raw &&
when {
musicBrainzId != null && other.musicBrainzId != null ->
musicBrainzId == other.musicBrainzId
musicBrainzId == null && other.musicBrainzId == null ->
when {
name != null && other.name != null -> name.equals(other.name, true)
name == null && other.name == null -> true
else -> false
}
else -> false
}
}
}
@ -1025,7 +1023,7 @@ class Genre constructor(private val raw: Raw, override val songs: List<Song>) :
* @return A [UUID] converted from the [String] value, or null if the value was not valid.
* @see UUID.fromString
*/
fun String.toUuidOrNull(): UUID? =
private fun String.toUuidOrNull(): UUID? =
try {
UUID.fromString(this)
} catch (e: IllegalArgumentException) {
@ -1036,7 +1034,8 @@ fun String.toUuidOrNull(): UUID? =
* Update a [MessageDigest] with a lowercase [String].
* @param string The [String] to hash. If null, it will not be hashed.
*/
private fun MessageDigest.update(string: String?) {
@VisibleForTesting
fun MessageDigest.update(string: String?) {
if (string != null) {
update(string.lowercase().toByteArray())
} else {
@ -1048,7 +1047,8 @@ private fun MessageDigest.update(string: String?) {
* Update a [MessageDigest] with the string representation of a [Date].
* @param date The [Date] to hash. If null, nothing will be done.
*/
private fun MessageDigest.update(date: Date?) {
@VisibleForTesting
fun MessageDigest.update(date: Date?) {
if (date != null) {
update(date.toString().toByteArray())
} else {
@ -1060,7 +1060,8 @@ private fun MessageDigest.update(date: Date?) {
* Update a [MessageDigest] with the lowercase versions of all of the input [String]s.
* @param strings The [String]s to hash. If a [String] is null, it will not be hashed.
*/
private fun MessageDigest.update(strings: List<String?>) {
@VisibleForTesting
fun MessageDigest.update(strings: List<String?>) {
strings.forEach(::update)
}
@ -1068,7 +1069,8 @@ private fun MessageDigest.update(strings: List<String?>) {
* Update a [MessageDigest] with the little-endian bytes of a [Int].
* @param n The [Int] to write. If null, nothing will be done.
*/
private fun MessageDigest.update(n: Int?) {
@VisibleForTesting
fun MessageDigest.update(n: Int?) {
if (n != null) {
update(byteArrayOf(n.toByte(), n.shr(8).toByte(), n.shr(16).toByte(), n.shr(24).toByte()))
} else {

View file

@ -0,0 +1,213 @@
/*
* Copyright (c) 2023 Auxio Project
*
* 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 java.util.*
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.oxycblt.auxio.music.tags.Date
class MusicTest {
@Test
fun musicUid_auxio() {
val uid =
Music.UID.auxio(MusicMode.SONGS) {
update("Wheel")
update(listOf("Parannoul", "Asian Glow"))
update("Paraglow")
update(null as String?)
update(Date.from(2022))
update(4 as Int?)
update(null as Int?)
}
assertEquals("org.oxycblt.auxio:a10b-3d29c202-cd52-fbe0-4714-47cd07f07a59", uid.toString())
}
@Test
fun musicUid_musicBrainz() {
val uid =
Music.UID.musicBrainz(
MusicMode.ALBUMS, UUID.fromString("9b3b0695-0cdc-4560-8486-8deadee136cb"))
assertEquals("org.musicbrainz:a10a-9b3b0695-0cdc-4560-8486-8deadee136cb", uid.toString())
}
@Test
fun albumRaw_equals_inconsistentCase() {
val a =
Album.Raw(
mediaStoreId = -1,
musicBrainzId = null,
name = "Paraglow",
sortName = null,
releaseType = null,
rawArtists =
listOf(Artist.Raw(name = "Parannoul"), Artist.Raw(name = "Asian Glow")))
val b =
Album.Raw(
mediaStoreId = -1,
musicBrainzId = null,
name = "paraglow",
sortName = null,
releaseType = null,
rawArtists =
listOf(Artist.Raw(name = "Parannoul"), Artist.Raw(name = "Asian glow")))
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun albumRaw_equals_withMbids() {
val a =
Album.Raw(
mediaStoreId = -1,
musicBrainzId = UUID.fromString("c7b245c9-8099-32ea-af95-893acedde2cf"),
name = "Weezer",
sortName = "Blue Album",
releaseType = null,
rawArtists = listOf(Artist.Raw(name = "Weezer")))
val b =
Album.Raw(
mediaStoreId = -1,
musicBrainzId = UUID.fromString("923d5ba6-7eee-3bce-bcb2-c913b2bd69d4"),
name = "Weezer",
sortName = "Green Album",
releaseType = null,
rawArtists = listOf(Artist.Raw(name = "Weezer")))
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun albumRaw_equals_inconsistentMbids() {
val a =
Album.Raw(
mediaStoreId = -1,
musicBrainzId = UUID.fromString("c7b245c9-8099-32ea-af95-893acedde2cf"),
name = "Weezer",
sortName = "Blue Album",
releaseType = null,
rawArtists = listOf(Artist.Raw(name = "Weezer")))
val b =
Album.Raw(
mediaStoreId = -1,
musicBrainzId = null,
name = "Weezer",
sortName = "Green Album",
releaseType = null,
rawArtists = listOf(Artist.Raw(name = "Weezer")))
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun albumRaw_equals_withArtists() {
val a =
Album.Raw(
mediaStoreId = -1,
musicBrainzId = null,
name = "Album",
sortName = null,
releaseType = null,
rawArtists = listOf(Artist.Raw(name = "Artist A")))
val b =
Album.Raw(
mediaStoreId = -1,
musicBrainzId = null,
name = "Album",
sortName = null,
releaseType = null,
rawArtists = listOf(Artist.Raw(name = "Artist B")))
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun artistRaw_equals_inconsistentCase() {
val a = Artist.Raw(musicBrainzId = null, name = "Parannoul")
val b = Artist.Raw(musicBrainzId = null, name = "parannoul")
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun artistRaw_equals_withMbids() {
val a =
Artist.Raw(
musicBrainzId = UUID.fromString("677325ef-d850-44bb-8258-0d69bbc0b3f7"),
name = "Artist")
val b =
Artist.Raw(
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 =
Artist.Raw(
musicBrainzId = UUID.fromString("677325ef-d850-44bb-8258-0d69bbc0b3f7"),
name = "Artist")
val b = Artist.Raw(musicBrainzId = null, name = "Artist")
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun artistRaw_equals_missingNames() {
val a = Artist.Raw(name = null)
val b = Artist.Raw(name = null)
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun artistRaw_equals_inconsistentNames() {
val a = Artist.Raw(name = null)
val b = Artist.Raw(name = "Parannoul")
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
@Test
fun genreRaw_equals_inconsistentCase() {
val a = Genre.Raw("Future Garage")
val b = Genre.Raw("future garage")
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun genreRaw_equals_missingNames() {
val a = Genre.Raw(name = null)
val b = Genre.Raw(name = null)
assertTrue(a == b)
assertTrue(a.hashCode() == b.hashCode())
}
@Test
fun genreRaw_equals_inconsistentNames() {
val a = Genre.Raw(name = null)
val b = Genre.Raw(name = "Future Garage")
assertTrue(a != b)
assertTrue(a.hashCode() != b.hashCode())
}
}