Throw out old unit tests

Considering we never run or update them, they're not providing any value right now.
Kept the chapter recognition tests and bumped to JUnit 5.
This commit is contained in:
arkon 2022-04-24 16:16:05 -04:00
parent f6fdb12db2
commit 4d23f35b9d
9 changed files with 71 additions and 734 deletions

View file

@ -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<Test> {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
}
// See https://kotlinlang.org/docs/reference/experimental.html#experimental-status-of-experimental-api(-markers)
withType<KotlinCompile> {
kotlinOptions.freeCompilerArgs += listOf(

View file

@ -21,12 +21,14 @@ import uy.kohesive.injekt.api.get
class DomainModule : InjektModule {
override fun InjektRegistrar.registerInjectables() {
addFactory { GetNextChapterForManga(get()) }
addSingletonFactory<HistoryRepository> { HistoryRepositoryImpl(get()) }
addFactory { DeleteHistoryTable(get()) }
addFactory { GetHistory(get()) }
addFactory { GetNextChapterForManga(get()) }
addFactory { RemoveHistoryById(get()) }
addFactory { RemoveHistoryByMangaId(get()) }
addSingletonFactory<SourceRepository> { SourceRepositoryImpl(get()) }
addFactory { GetEnabledSources(get(), get()) }
addFactory { DisableSource(get()) }

View file

@ -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" }
}
}

View file

@ -1,8 +0,0 @@
package eu.kanade.tachiyomi
open class TestApp : App() {
override fun setupAcra() {
// Do nothing
}
}

View file

@ -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<Manga>(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<Chapter>()
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<List<Chapter>>(chaptersJson)
// Fetch chapters from upstream
// Create list
val chaptersRemote = mutableListOf<Chapter>()
(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<DHistory>()
historyList.add(historyJson)
// Check parser
val historyListJson = legacyBackupManager.parser.encodeToString(historyList)
val history = legacyBackupManager.parser.decodeFromString<List<DHistory>>(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<List<Track>>(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<List<Track>>(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
}
}

View file

@ -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()
}
}

View file

@ -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)
}
}

View file

@ -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<Chapter> {
val list = mutableListOf<Chapter>()
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<LibraryManga> {
val list = mutableListOf<LibraryManga>()
for (url in urls) {
val m = LibraryManga()
m.url = url
m.title = url.substring(1)
m.favorite = true
list.add(m)
}
return list
}
}

View file

@ -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"}