diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c811dafff0..075638913b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -262,16 +262,19 @@ dependencies { // Tests testImplementation(libs.junit) - testImplementation(libs.assertj.core) - testImplementation(libs.mockito.core) - - testImplementation(libs.bundles.robolectric) // For detecting memory leaks; see https://square.github.io/leakcanary/ // debugImplementation(libs.leakcanary.android) } tasks { + withType { + useJUnitPlatform() + testLogging { + events("passed", "skipped", "failed") + } + } + // See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers) withType { kotlinOptions.freeCompilerArgs += listOf( diff --git a/app/src/main/java/eu/kanade/domain/DomainModule.kt b/app/src/main/java/eu/kanade/domain/DomainModule.kt index 71e1dcef2d..2f6da5f7f7 100644 --- a/app/src/main/java/eu/kanade/domain/DomainModule.kt +++ b/app/src/main/java/eu/kanade/domain/DomainModule.kt @@ -21,12 +21,14 @@ import uy.kohesive.injekt.api.get class DomainModule : InjektModule { override fun InjektRegistrar.registerInjectables() { + addFactory { GetNextChapterForManga(get()) } + addSingletonFactory { HistoryRepositoryImpl(get()) } addFactory { DeleteHistoryTable(get()) } addFactory { GetHistory(get()) } - addFactory { GetNextChapterForManga(get()) } addFactory { RemoveHistoryById(get()) } addFactory { RemoveHistoryByMangaId(get()) } + addSingletonFactory { SourceRepositoryImpl(get()) } addFactory { GetEnabledSources(get(), get()) } addFactory { DisableSource(get()) } diff --git a/app/src/test/java/eu/kanade/tachiyomi/CustomRobolectricGradleTestRunner.kt b/app/src/test/java/eu/kanade/tachiyomi/CustomRobolectricGradleTestRunner.kt deleted file mode 100644 index 3b334be41b..0000000000 --- a/app/src/test/java/eu/kanade/tachiyomi/CustomRobolectricGradleTestRunner.kt +++ /dev/null @@ -1,12 +0,0 @@ -package eu.kanade.tachiyomi - -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import org.robolectric.manifest.AndroidManifest - -class CustomRobolectricGradleTestRunner(klass: Class<*>) : RobolectricTestRunner(klass) { - - override fun getAppManifest(config: Config): AndroidManifest { - return super.getAppManifest(config).apply { packageName = "eu.kanade.tachiyomi" } - } -} diff --git a/app/src/test/java/eu/kanade/tachiyomi/TestApp.kt b/app/src/test/java/eu/kanade/tachiyomi/TestApp.kt deleted file mode 100644 index 35a74ceb22..0000000000 --- a/app/src/test/java/eu/kanade/tachiyomi/TestApp.kt +++ /dev/null @@ -1,8 +0,0 @@ -package eu.kanade.tachiyomi - -open class TestApp : App() { - - override fun setupAcra() { - // Do nothing - } -} diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt b/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt deleted file mode 100644 index 8815334045..0000000000 --- a/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt +++ /dev/null @@ -1,377 +0,0 @@ -package eu.kanade.tachiyomi.data.backup - -import android.app.Application -import android.content.Context -import android.os.Build -import eu.kanade.tachiyomi.BuildConfig -import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner -import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupManager -import eu.kanade.tachiyomi.data.backup.legacy.models.Backup -import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory -import eu.kanade.tachiyomi.data.database.DatabaseHelper -import eu.kanade.tachiyomi.data.database.models.Category -import eu.kanade.tachiyomi.data.database.models.Chapter -import eu.kanade.tachiyomi.data.database.models.ChapterImpl -import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.database.models.MangaImpl -import eu.kanade.tachiyomi.data.database.models.Track -import eu.kanade.tachiyomi.data.database.models.TrackImpl -import eu.kanade.tachiyomi.source.SourceManager -import eu.kanade.tachiyomi.source.online.HttpSource -import eu.kanade.tachiyomi.ui.reader.setting.OrientationType -import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType -import kotlinx.coroutines.runBlocking -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.buildJsonObject -import org.assertj.core.api.Assertions.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.RETURNS_DEEP_STUBS -import org.mockito.Mockito.anyLong -import org.mockito.Mockito.mock -import org.mockito.Mockito.`when` -import org.robolectric.RuntimeEnvironment -import org.robolectric.annotation.Config -import rx.Observable -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.InjektModule -import uy.kohesive.injekt.api.InjektRegistrar -import uy.kohesive.injekt.api.addSingleton - -/** - * Test class for the [LegacyBackupManager]. - * Note that this does not include the backup create/restore services. - */ -@Config(constants = BuildConfig::class, sdk = [Build.VERSION_CODES.M]) -@RunWith(CustomRobolectricGradleTestRunner::class) -class BackupTest { - // Create root object - var root = Backup() - - // Create information object - var information = buildJsonObject {} - - lateinit var app: Application - lateinit var context: Context - lateinit var source: HttpSource - - lateinit var legacyBackupManager: LegacyBackupManager - - lateinit var db: DatabaseHelper - - @Before - fun setup() { - app = RuntimeEnvironment.application - context = app.applicationContext - legacyBackupManager = LegacyBackupManager(context, 2) - db = legacyBackupManager.databaseHelper - - // Mock the source manager - val module = object : InjektModule { - override fun InjektRegistrar.registerInjectables() { - addSingleton(mock(SourceManager::class.java, RETURNS_DEEP_STUBS)) - } - } - Injekt.importModule(module) - - source = mock(HttpSource::class.java) - `when`(legacyBackupManager.sourceManager.get(anyLong())).thenReturn(source) - } - - /** - * Test that checks if no crashes when no categories in library. - */ - @Test - fun testRestoreEmptyCategory() { - // Restore Json - legacyBackupManager.restoreCategories(root.categories ?: emptyList()) - - // Check if empty - val dbCats = db.getCategories().executeAsBlocking() - assertThat(dbCats).isEmpty() - } - - /** - * Test to check if single category gets restored - */ - @Test - fun testRestoreSingleCategory() { - // Create category and add to json - val category = addSingleCategory("category") - - // Restore Json - legacyBackupManager.restoreCategories(root.categories ?: emptyList()) - - // Check if successful - val dbCats = legacyBackupManager.databaseHelper.getCategories().executeAsBlocking() - assertThat(dbCats).hasSize(1) - assertThat(dbCats[0].name).isEqualTo(category.name) - } - - /** - * Test to check if multiple categories get restored. - */ - @Test - fun testRestoreMultipleCategories() { - // Create category and add to json - val category = addSingleCategory("category") - val category2 = addSingleCategory("category2") - val category3 = addSingleCategory("category3") - val category4 = addSingleCategory("category4") - val category5 = addSingleCategory("category5") - - // Insert category to test if no duplicates on restore. - db.insertCategory(category).executeAsBlocking() - - // Restore Json - legacyBackupManager.restoreCategories(root.categories ?: emptyList()) - - // Check if successful - val dbCats = legacyBackupManager.databaseHelper.getCategories().executeAsBlocking() - assertThat(dbCats).hasSize(5) - assertThat(dbCats[0].name).isEqualTo(category.name) - assertThat(dbCats[1].name).isEqualTo(category2.name) - assertThat(dbCats[2].name).isEqualTo(category3.name) - assertThat(dbCats[3].name).isEqualTo(category4.name) - assertThat(dbCats[4].name).isEqualTo(category5.name) - } - - /** - * Test if restore of manga is successful - */ - @Test - fun testRestoreManga() { - // Add manga to database - val manga = getSingleManga("One Piece") - manga.readingModeType = ReadingModeType.VERTICAL.flagValue - manga.orientationType = OrientationType.PORTRAIT.flagValue - manga.id = db.insertManga(manga).executeAsBlocking().insertedId() - - var favoriteManga = legacyBackupManager.databaseHelper.getFavoriteMangas().executeAsBlocking() - assertThat(favoriteManga).hasSize(1) - assertThat(favoriteManga[0].readingModeType).isEqualTo(ReadingModeType.VERTICAL.flagValue) - assertThat(favoriteManga[0].orientationType).isEqualTo(OrientationType.PORTRAIT.flagValue) - - // Change manga in database to default values - val dbManga = getSingleManga("One Piece") - dbManga.id = manga.id - db.insertManga(dbManga).executeAsBlocking() - - favoriteManga = legacyBackupManager.databaseHelper.getFavoriteMangas().executeAsBlocking() - assertThat(favoriteManga).hasSize(1) - assertThat(favoriteManga[0].readingModeType).isEqualTo(ReadingModeType.DEFAULT.flagValue) - assertThat(favoriteManga[0].orientationType).isEqualTo(OrientationType.DEFAULT.flagValue) - - // Restore local manga - legacyBackupManager.restoreMangaNoFetch(manga, dbManga) - - // Test if restore successful - favoriteManga = legacyBackupManager.databaseHelper.getFavoriteMangas().executeAsBlocking() - assertThat(favoriteManga).hasSize(1) - assertThat(favoriteManga[0].readingModeType).isEqualTo(ReadingModeType.VERTICAL.flagValue) - assertThat(favoriteManga[0].orientationType).isEqualTo(OrientationType.PORTRAIT.flagValue) - - // Clear database to test manga fetch - clearDatabase() - - // Test if successful - favoriteManga = legacyBackupManager.databaseHelper.getFavoriteMangas().executeAsBlocking() - assertThat(favoriteManga).hasSize(0) - - // Restore Json - // Create JSON from manga to test parser - val json = legacyBackupManager.parser.encodeToString(manga) - // Restore JSON from manga to test parser - val jsonManga = legacyBackupManager.parser.decodeFromString(json) - - // Restore manga with fetch observable - val networkManga = getSingleManga("One Piece") - networkManga.description = "This is a description" - `when`(source.fetchMangaDetails(jsonManga)).thenReturn(Observable.just(networkManga)) - - runBlocking { - legacyBackupManager.fetchManga(source, jsonManga) - - // Check if restore successful - val dbCats = legacyBackupManager.databaseHelper.getFavoriteMangas().executeAsBlocking() - assertThat(dbCats).hasSize(1) - assertThat(dbCats[0].readingModeType).isEqualTo(ReadingModeType.VERTICAL.flagValue) - assertThat(dbCats[0].orientationType).isEqualTo(OrientationType.PORTRAIT.flagValue) - assertThat(dbCats[0].description).isEqualTo("This is a description") - } - } - - /** - * Test if chapter restore is successful - */ - @Test - fun testRestoreChapters() { - // Insert manga - val manga = getSingleManga("One Piece") - manga.id = legacyBackupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId() - - // Create restore list - val chapters = mutableListOf() - for (i in 1..8) { - val chapter = getSingleChapter("Chapter $i") - chapter.read = true - chapters.add(chapter) - } - - // Check parser - val chaptersJson = legacyBackupManager.parser.encodeToString(chapters) - val restoredChapters = legacyBackupManager.parser.decodeFromString>(chaptersJson) - - // Fetch chapters from upstream - // Create list - val chaptersRemote = mutableListOf() - (1..10).mapTo(chaptersRemote) { getSingleChapter("Chapter $it") } - `when`(source.fetchChapterList(manga)).thenReturn(Observable.just(chaptersRemote)) - - runBlocking { - legacyBackupManager.restoreChapters(source, manga, restoredChapters) - - val dbCats = legacyBackupManager.databaseHelper.getChapters(manga).executeAsBlocking() - assertThat(dbCats).hasSize(10) - assertThat(dbCats[0].read).isEqualTo(true) - } - } - - /** - * Test to check if history restore works - */ - @Test - fun restoreHistoryForManga() { - val manga = getSingleManga("One Piece") - manga.id = legacyBackupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId() - - // Create chapter - val chapter = getSingleChapter("Chapter 1") - chapter.manga_id = manga.id - chapter.read = true - chapter.id = legacyBackupManager.databaseHelper.insertChapter(chapter).executeAsBlocking().insertedId() - - val historyJson = getSingleHistory(chapter) - - val historyList = mutableListOf() - historyList.add(historyJson) - - // Check parser - val historyListJson = legacyBackupManager.parser.encodeToString(historyList) - val history = legacyBackupManager.parser.decodeFromString>(historyListJson) - - // Restore categories - legacyBackupManager.restoreHistoryForManga(history) - - val historyDB = legacyBackupManager.databaseHelper.getHistoryByMangaId(manga.id!!).executeAsBlocking() - assertThat(historyDB).hasSize(1) - assertThat(historyDB[0].last_read).isEqualTo(1000) - } - - /** - * Test to check if tracking restore works - */ - @Test - fun restoreTrackForManga() { - // Create mangas - val manga = getSingleManga("One Piece") - val manga2 = getSingleManga("Bleach") - manga.id = legacyBackupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId() - manga2.id = legacyBackupManager.databaseHelper.insertManga(manga2).executeAsBlocking().insertedId() - - // Create track and add it to database - // This tests duplicate errors. - val track = getSingleTrack(manga) - track.last_chapter_read = 5F - legacyBackupManager.databaseHelper.insertTrack(track).executeAsBlocking() - var trackDB = legacyBackupManager.databaseHelper.getTracks(manga).executeAsBlocking() - assertThat(trackDB).hasSize(1) - assertThat(trackDB[0].last_chapter_read).isEqualTo(5) - track.last_chapter_read = 7F - - // Create track for different manga to test track not in database - val track2 = getSingleTrack(manga2) - track2.last_chapter_read = 10F - - // Check parser and restore already in database - var trackList = listOf(track) - // Check parser - var trackListJson = legacyBackupManager.parser.encodeToString(trackList) - var trackListRestore = legacyBackupManager.parser.decodeFromString>(trackListJson) - legacyBackupManager.restoreTrackForManga(manga, trackListRestore) - - // Assert if restore works. - trackDB = legacyBackupManager.databaseHelper.getTracks(manga).executeAsBlocking() - assertThat(trackDB).hasSize(1) - assertThat(trackDB[0].last_chapter_read).isEqualTo(7) - - // Check parser and restore already in database with lower chapter_read - track.last_chapter_read = 5F - trackList = listOf(track) - legacyBackupManager.restoreTrackForManga(manga, trackList) - - // Assert if restore works. - trackDB = legacyBackupManager.databaseHelper.getTracks(manga).executeAsBlocking() - assertThat(trackDB).hasSize(1) - assertThat(trackDB[0].last_chapter_read).isEqualTo(7) - - // Check parser and restore, track not in database - trackList = listOf(track2) - - // Check parser - trackListJson = legacyBackupManager.parser.encodeToString(trackList) - trackListRestore = legacyBackupManager.parser.decodeFromString>(trackListJson) - legacyBackupManager.restoreTrackForManga(manga2, trackListRestore) - - // Assert if restore works. - trackDB = legacyBackupManager.databaseHelper.getTracks(manga2).executeAsBlocking() - assertThat(trackDB).hasSize(1) - assertThat(trackDB[0].last_chapter_read).isEqualTo(10) - } - - private fun clearJson() { - root = Backup() - information = buildJsonObject {} - } - - private fun addSingleCategory(name: String): Category { - val category = Category.create(name) - root.categories = listOf(category) - return category - } - - private fun clearDatabase() { - db.deleteMangas().executeAsBlocking() - db.dropHistoryTable().executeAsBlocking() - } - - private fun getSingleHistory(chapter: Chapter): DHistory { - return DHistory(chapter.url, 1000) - } - - private fun getSingleTrack(manga: Manga): TrackImpl { - val track = TrackImpl() - track.title = manga.title - track.manga_id = manga.id!! - track.sync_id = 1 - return track - } - - private fun getSingleManga(title: String): MangaImpl { - val manga = MangaImpl() - manga.source = 1 - manga.title = title - manga.url = "/manga/$title" - manga.favorite = true - return manga - } - - private fun getSingleChapter(name: String): ChapterImpl { - val chapter = ChapterImpl() - chapter.name = name - chapter.url = "/read-online/$name-page-1.html" - return chapter - } -} diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/database/CategoryTest.kt b/app/src/test/java/eu/kanade/tachiyomi/data/database/CategoryTest.kt deleted file mode 100644 index c24baa1c63..0000000000 --- a/app/src/test/java/eu/kanade/tachiyomi/data/database/CategoryTest.kt +++ /dev/null @@ -1,109 +0,0 @@ -package eu.kanade.tachiyomi.data.database - -import android.os.Build -import eu.kanade.tachiyomi.BuildConfig -import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner -import eu.kanade.tachiyomi.data.database.models.CategoryImpl -import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.database.models.MangaCategory -import org.assertj.core.api.Assertions.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RuntimeEnvironment -import org.robolectric.annotation.Config - -@Config(constants = BuildConfig::class, sdk = [Build.VERSION_CODES.M]) -@RunWith(CustomRobolectricGradleTestRunner::class) -class CategoryTest { - - lateinit var db: DatabaseHelper - - @Before - fun setup() { - val app = RuntimeEnvironment.application - db = DatabaseHelper(app) - - // Create 5 manga - createManga("a") - createManga("b") - createManga("c") - createManga("d") - createManga("e") - } - - @Test - fun testHasCategories() { - // Create 2 categories - createCategory("Reading") - createCategory("Hold") - - val categories = db.getCategories().executeAsBlocking() - assertThat(categories).hasSize(2) - } - - @Test - fun testHasLibraryMangas() { - val mangas = db.getLibraryMangas().executeAsBlocking() - assertThat(mangas).hasSize(5) - } - - @Test - fun testHasCorrectFavorites() { - val m = Manga.create(0) - m.title = "title" - m.author = "" - m.artist = "" - m.thumbnail_url = "" - m.genre = "a list of genres" - m.description = "long description" - m.url = "url to manga" - m.favorite = false - db.insertManga(m).executeAsBlocking() - val mangas = db.getLibraryMangas().executeAsBlocking() - assertThat(mangas).hasSize(5) - } - - @Test - fun testMangaInCategory() { - // Create 2 categories - createCategory("Reading") - createCategory("Hold") - - // It should not have 0 as id - val c = db.getCategories().executeAsBlocking()[0] - assertThat(c.id).isNotZero - - // Add a manga to a category - val m = db.getLibraryMangas().executeAsBlocking()[0] - val mc = MangaCategory.create(m, c) - db.insertMangaCategory(mc).executeAsBlocking() - - // Get mangas from library and assert manga category is the same - val mangas = db.getLibraryMangas().executeAsBlocking() - for (manga in mangas) { - if (manga.id == m.id) { - assertThat(manga.category).isEqualTo(c.id) - } - } - } - - private fun createManga(title: String) { - val m = Manga.create(0) - m.title = title - m.author = "" - m.artist = "" - m.thumbnail_url = "" - m.genre = "a list of genres" - m.description = "long description" - m.url = "url to manga" - m.favorite = true - db.insertManga(m).executeAsBlocking() - } - - private fun createCategory(name: String) { - val c = CategoryImpl() - c.name = name - db.insertCategory(c).executeAsBlocking() - } -} diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt b/app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt index 33a0f2d176..640c0a2437 100644 --- a/app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt +++ b/app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt @@ -3,46 +3,27 @@ package eu.kanade.tachiyomi.data.database import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.util.chapter.ChapterRecognition -import org.assertj.core.api.Assertions.assertThat -import org.junit.Before -import org.junit.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test class ChapterRecognitionTest { - /** - * The manga containing manga title - */ - lateinit var manga: Manga - /** - * The chapter containing chapter name - */ - lateinit var chapter: Chapter + private lateinit var manga: Manga + private lateinit var chapter: Chapter - /** - * Set chapter title - * @param name name of chapter - * @return chapter object - */ private fun createChapter(name: String): Chapter { chapter = Chapter.create() chapter.name = name return chapter } - /** - * Set manga title - * @param title title of manga - * @return manga object - */ private fun createManga(title: String): Manga { manga.title = title return manga } - /** - * Called before test - */ - @Before + @BeforeEach fun setup() { manga = Manga.create(0).apply { title = "random" } chapter = Chapter.create() @@ -52,12 +33,12 @@ class ChapterRecognitionTest { * Ch.xx base case */ @Test - fun ChCaseBase() { + fun `ChCaseBase`() { createManga("Mokushiroku Alice") createChapter("Mokushiroku Alice Vol.1 Ch.4: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(4f) + assertEquals(4f, chapter.chapter_number) } /** @@ -69,7 +50,7 @@ class ChapterRecognitionTest { createChapter("Mokushiroku Alice Vol. 1 Ch. 4: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(4f) + assertEquals(4f, chapter.chapter_number) } /** @@ -81,11 +62,11 @@ class ChapterRecognitionTest { createChapter("Mokushiroku Alice Vol.1 Ch.4.1: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(4.1f) + assertEquals(4.1f, chapter.chapter_number) createChapter("Mokushiroku Alice Vol.1 Ch.4.4: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(4.4f) + assertEquals(4.4f, chapter.chapter_number) } /** @@ -97,15 +78,15 @@ class ChapterRecognitionTest { createChapter("Mokushiroku Alice Vol.1 Ch.4.a: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(4.1f) + assertEquals(4.1f, chapter.chapter_number) createChapter("Mokushiroku Alice Vol.1 Ch.4.b: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(4.2f) + assertEquals(4.2f, chapter.chapter_number) createChapter("Mokushiroku Alice Vol.1 Ch.4.extra: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(4.99f) + assertEquals(4.99f, chapter.chapter_number) } /** @@ -117,7 +98,7 @@ class ChapterRecognitionTest { createChapter("Bleach 567 Down With Snowwhite") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(567f) + assertEquals(567f, chapter.chapter_number) } /** @@ -129,11 +110,11 @@ class ChapterRecognitionTest { createChapter("Bleach 567.1 Down With Snowwhite") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(567.1f) + assertEquals(567.1f, chapter.chapter_number) createChapter("Bleach 567.4 Down With Snowwhite") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(567.4f) + assertEquals(567.4f, chapter.chapter_number) } /** @@ -145,15 +126,15 @@ class ChapterRecognitionTest { createChapter("Bleach 567.a Down With Snowwhite") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(567.1f) + assertEquals(567.1f, chapter.chapter_number) createChapter("Bleach 567.b Down With Snowwhite") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(567.2f) + assertEquals(567.2f, chapter.chapter_number) createChapter("Bleach 567.extra Down With Snowwhite") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(567.99f) + assertEquals(567.99f, chapter.chapter_number) } /** @@ -165,7 +146,7 @@ class ChapterRecognitionTest { createChapter("Solanin 028 Vol. 2") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28f) + assertEquals(28f, chapter.chapter_number) } /** @@ -177,11 +158,11 @@ class ChapterRecognitionTest { createChapter("Solanin 028.1 Vol. 2") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.1f) + assertEquals(28.1f, chapter.chapter_number) createChapter("Solanin 028.4 Vol. 2") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.4f) + assertEquals(28.4f, chapter.chapter_number) } /** @@ -193,15 +174,15 @@ class ChapterRecognitionTest { createChapter("Solanin 028.a Vol. 2") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.1f) + assertEquals(28.1f, chapter.chapter_number) createChapter("Solanin 028.b Vol. 2") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.2f) + assertEquals(28.2f, chapter.chapter_number) createChapter("Solanin 028.extra Vol. 2") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.99f) + assertEquals(28.99f, chapter.chapter_number) } /** @@ -213,7 +194,7 @@ class ChapterRecognitionTest { createChapter("Onepunch-Man Punch Ver002 028") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28f) + assertEquals(28f, chapter.chapter_number) } /** @@ -225,11 +206,11 @@ class ChapterRecognitionTest { createChapter("Onepunch-Man Punch Ver002 028.1") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.1f) + assertEquals(28.1f, chapter.chapter_number) createChapter("Onepunch-Man Punch Ver002 028.4") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.4f) + assertEquals(28.4f, chapter.chapter_number) } /** @@ -241,15 +222,15 @@ class ChapterRecognitionTest { createChapter("Onepunch-Man Punch Ver002 028.a") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.1f) + assertEquals(28.1f, chapter.chapter_number) createChapter("Onepunch-Man Punch Ver002 028.b") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.2f) + assertEquals(28.2f, chapter.chapter_number) createChapter("Onepunch-Man Punch Ver002 028.extra") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(28.99f) + assertEquals(28.99f, chapter.chapter_number) } /** @@ -259,7 +240,7 @@ class ChapterRecognitionTest { fun dotV2Case() { createChapter("Vol.1 Ch.5v.2: Alones") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(5f) + assertEquals(5f, chapter.chapter_number) } /** @@ -270,7 +251,7 @@ class ChapterRecognitionTest { createManga("Ayame 14") createChapter("Ayame 14 1 - The summer of 14") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(1f) + assertEquals(1f, chapter.chapter_number) } /** @@ -281,7 +262,7 @@ class ChapterRecognitionTest { createManga("Mokushiroku Alice") createChapter("Mokushiroku Alice Vol.1 Ch. 4: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(4f) + assertEquals(4f, chapter.chapter_number) } /** @@ -292,7 +273,7 @@ class ChapterRecognitionTest { createManga("Ayame 14") createChapter("Vol.1 Ch.1: March 25 (First Day Cohabiting)") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(1f) + assertEquals(1f, chapter.chapter_number) } /** @@ -302,7 +283,7 @@ class ChapterRecognitionTest { fun rangeInChapterCase() { createChapter("Ch.191-200 Read Online") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(191f) + assertEquals(191f, chapter.chapter_number) } /** @@ -312,7 +293,7 @@ class ChapterRecognitionTest { fun multipleZerosCase() { createChapter("Vol.001 Ch.003: Kaguya Doesn't Know Much") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(3f) + assertEquals(3f, chapter.chapter_number) } /** @@ -323,7 +304,7 @@ class ChapterRecognitionTest { createManga("Onepunch-Man") createChapter("Onepunch-Man Punch Ver002 086 : Creeping Darkness [3]") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(86f) + assertEquals(86f, chapter.chapter_number) } /** @@ -334,7 +315,7 @@ class ChapterRecognitionTest { createManga("Ansatsu Kyoushitsu") createChapter("Ansatsu Kyoushitsu 011v002: Assembly Time") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(11f) + assertEquals(11f, chapter.chapter_number) } /** @@ -346,7 +327,7 @@ class ChapterRecognitionTest { createChapter("Tokyo ESP 027: Part 002: Chapter 001") createManga("Tokyo ESP") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(027f) + assertEquals(027f, chapter.chapter_number) } /** @@ -356,7 +337,7 @@ class ChapterRecognitionTest { fun unParsableCase() { createChapter("Foo") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(-1f) + assertEquals(-1f, chapter.chapter_number) } /** @@ -366,7 +347,7 @@ class ChapterRecognitionTest { fun timeChapterCase() { createChapter("Fairy Tail 404: 00:00") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404f) + assertEquals(404f, chapter.chapter_number) } /** @@ -376,7 +357,7 @@ class ChapterRecognitionTest { fun alphaWithoutDotCase() { createChapter("Asu No Yoichi 19a") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(19.1f) + assertEquals(19.1f, chapter.chapter_number) } /** @@ -388,15 +369,15 @@ class ChapterRecognitionTest { createChapter("Fairy Tail 404.extravol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.99f) + assertEquals(404.99f, chapter.chapter_number) createChapter("Fairy Tail 404 extravol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.99f) + assertEquals(404.99f, chapter.chapter_number) createChapter("Fairy Tail 404.evol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.5f) + assertEquals(404.5f, chapter.chapter_number) } /** @@ -408,15 +389,15 @@ class ChapterRecognitionTest { createChapter("Fairy Tail 404.omakevol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.98f) + assertEquals(404.98f, chapter.chapter_number) createChapter("Fairy Tail 404 omakevol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.98f) + assertEquals(404.98f, chapter.chapter_number) createChapter("Fairy Tail 404.ovol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.15f) + assertEquals(404.15f, chapter.chapter_number) } /** @@ -428,15 +409,15 @@ class ChapterRecognitionTest { createChapter("Fairy Tail 404.specialvol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.97f) + assertEquals(404.97f, chapter.chapter_number) createChapter("Fairy Tail 404 specialvol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.97f) + assertEquals(404.97f, chapter.chapter_number) createChapter("Fairy Tail 404.svol002") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(404.19f) + assertEquals(404.19f, chapter.chapter_number) } /** @@ -448,15 +429,15 @@ class ChapterRecognitionTest { createChapter("One Piece 300,a") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(300.1f) + assertEquals(300.1f, chapter.chapter_number) createChapter("One Piece Ch,123,extra") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(123.99f) + assertEquals(123.99f, chapter.chapter_number) createChapter("One Piece the sunny, goes swimming 024,005") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(24.005f) + assertEquals(24.005f, chapter.chapter_number) } /** @@ -468,7 +449,7 @@ class ChapterRecognitionTest { createChapter("D.I.C.E[Season 001] Ep. 007") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(7f) + assertEquals(7f, chapter.chapter_number) } /** @@ -480,7 +461,7 @@ class ChapterRecognitionTest { createChapter("S3 - Chapter 20") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(20f) + assertEquals(20f, chapter.chapter_number) } /** @@ -492,6 +473,6 @@ class ChapterRecognitionTest { createChapter("One Outs 001") ChapterRecognition.parseChapterNumber(chapter, manga) - assertThat(chapter.chapter_number).isEqualTo(1f) + assertEquals(1f, chapter.chapter_number) } } diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateServiceTest.kt b/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateServiceTest.kt deleted file mode 100644 index bd96644c41..0000000000 --- a/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateServiceTest.kt +++ /dev/null @@ -1,136 +0,0 @@ -package eu.kanade.tachiyomi.data.library - -import android.app.Application -import android.content.Context -import android.content.Intent -import android.os.Build -import eu.kanade.tachiyomi.BuildConfig -import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner -import eu.kanade.tachiyomi.data.database.models.Chapter -import eu.kanade.tachiyomi.data.database.models.LibraryManga -import eu.kanade.tachiyomi.source.SourceManager -import eu.kanade.tachiyomi.source.online.HttpSource -import kotlinx.coroutines.runBlocking -import org.assertj.core.api.Assertions.assertThat -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Matchers.anyLong -import org.mockito.Mockito.RETURNS_DEEP_STUBS -import org.mockito.Mockito.mock -import org.mockito.Mockito.`when` -import org.robolectric.Robolectric -import org.robolectric.RuntimeEnvironment -import org.robolectric.annotation.Config -import rx.Observable -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.InjektModule -import uy.kohesive.injekt.api.InjektRegistrar -import uy.kohesive.injekt.api.addSingleton - -@Config(constants = BuildConfig::class, sdk = [Build.VERSION_CODES.M]) -@RunWith(CustomRobolectricGradleTestRunner::class) -class LibraryUpdateServiceTest { - - lateinit var app: Application - lateinit var context: Context - lateinit var service: LibraryUpdateService - lateinit var source: HttpSource - - @Before - fun setup() { - app = RuntimeEnvironment.application - context = app.applicationContext - - // Mock the source manager - val module = object : InjektModule { - override fun InjektRegistrar.registerInjectables() { - addSingleton(mock(SourceManager::class.java, RETURNS_DEEP_STUBS)) - } - } - Injekt.importModule(module) - - service = Robolectric.setupService(LibraryUpdateService::class.java) - source = mock(HttpSource::class.java) - `when`(service.sourceManager.get(anyLong())).thenReturn(source) - } - - @Test - fun testLifecycle() { - // Smoke test - Robolectric.buildService(LibraryUpdateService::class.java) - .attach() - .create() - .startCommand(0, 0) - .destroy() - .get() - } - - @Test - fun testUpdateManga() { - val manga = createManga("/manga1")[0] - manga.id = 1L - service.db.insertManga(manga).executeAsBlocking() - - val sourceChapters = createChapters("/chapter1", "/chapter2") - - `when`(source.fetchChapterList(manga)).thenReturn(Observable.just(sourceChapters)) - - runBlocking { - service.updateManga(manga) - - assertThat(service.db.getChapters(manga).executeAsBlocking()).hasSize(2) - } - } - - @Test - fun testContinuesUpdatingWhenAMangaFails() { - var favManga = createManga("/manga1", "/manga2", "/manga3") - service.db.insertMangas(favManga).executeAsBlocking() - favManga = service.db.getLibraryMangas().executeAsBlocking() - - val chapters = createChapters("/chapter1", "/chapter2") - val chapters3 = createChapters("/achapter1", "/achapter2") - - // One of the updates will fail - `when`(source.fetchChapterList(favManga[0])).thenReturn(Observable.just(chapters)) - `when`(source.fetchChapterList(favManga[1])).thenReturn(Observable.error(Exception())) - `when`(source.fetchChapterList(favManga[2])).thenReturn(Observable.just(chapters3)) - - val intent = Intent() - val categoryId = intent.getIntExtra(LibraryUpdateService.KEY_CATEGORY, -1) - val target = LibraryUpdateService.Target.CHAPTERS - runBlocking { - service.addMangaToQueue(categoryId, target) - service.updateChapterList() - - // There are 3 network attempts and 2 insertions (1 request failed) - assertThat(service.db.getChapters(favManga[0]).executeAsBlocking()).hasSize(2) - assertThat(service.db.getChapters(favManga[1]).executeAsBlocking()).hasSize(0) - assertThat(service.db.getChapters(favManga[2]).executeAsBlocking()).hasSize(2) - } - } - - private fun createChapters(vararg urls: String): List { - val list = mutableListOf() - for (url in urls) { - val c = Chapter.create() - c.url = url - c.name = url.substring(1) - list.add(c) - } - return list - } - - private fun createManga(vararg urls: String): List { - val list = mutableListOf() - for (url in urls) { - val m = LibraryManga() - m.url = url - m.title = url.substring(1) - m.favorite = true - list.add(m) - } - return list - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1726326a19..27938a0a27 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,6 @@ coil_version = "2.0.0-rc03" conductor_version = "3.1.2" flowbinding_version = "1.2.0" shizuku_version = "12.1.0" -robolectric_version = "3.1.4" sqldelight = "1.5.3" [libraries] @@ -89,19 +88,14 @@ aboutLibraries-compose = { module = "com.mikepenz:aboutlibraries-compose", versi shizuku-api = { module = "dev.rikka.shizuku:api", version.ref = "shizuku_version" } shizuku-provider = { module = "dev.rikka.shizuku:provider", version.ref = "shizuku_version" } -junit = "junit:junit:4.13.2" -assertj-core = "org.assertj:assertj-core:3.16.1" -mockito-core = "org.mockito:mockito-core:1.10.19" - -robolectric-core = { module = "org.robolectric:robolectric", version.ref = "robolectric_version" } -robolectric-playservices = { module = "org.robolectric:shadows-play-services", version.ref = "robolectric_version" } - leakcanary-android = "com.squareup.leakcanary:leakcanary-android:2.7" sqldelight-android-driver = { module = "com.squareup.sqldelight:android-driver", version.ref ="sqldelight" } sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extensions-jvm", version.ref ="sqldelight" } sqldelight-android-paging = { module = "com.squareup.sqldelight:android-paging3-extensions", version.ref ="sqldelight" } +junit = "org.junit.jupiter:junit-jupiter:5.8.2" + [bundles] reactivex = ["rxandroid","rxjava","rxrelay"] okhttp = ["okhttp-core","okhttp-logging","okhttp-dnsoverhttps"] @@ -112,7 +106,6 @@ coil = ["coil-core","coil-gif","coil-compose"] flowbinding = ["flowbinding-android","flowbinding-appcompat","flowbinding-recyclerview","flowbinding-swiperefreshlayout","flowbinding-viewpager"] conductor = ["conductor-core","conductor-viewpager","conductor-support-preference"] shizuku = ["shizuku-api","shizuku-provider"] -robolectric = ["robolectric-core","robolectric-playservices"] [plugins] kotlinter = { id = "org.jmailen.kotlinter", version = "3.6.0"}