From 1f7e22949334053c0d964276580d09370d255a81 Mon Sep 17 00:00:00 2001 From: achmad Date: Mon, 11 May 2026 13:36:36 +0700 Subject: [PATCH] phase4: add standalone source wrappers and mark checklist progress Register new all/en standalone wrappers from base sources and add initial smoke tests; several sources are still unverified in live environment. --- cmd/server/main.go | 19 ++++++ docs/phase4-standalone.md | 38 +++++------ sources/all/hentaihand/hentaihand.go | 18 +++++ sources/all/kemono/kemono.go | 18 +++++ sources/all/mangataro/mangataro.go | 18 +++++ sources/en/bakkin/bakkin.go | 18 +++++ sources/en/divascans/divascans.go | 19 ++++++ sources/en/guya/guya.go | 18 +++++ sources/en/hijalascans/hijalascans.go | 19 ++++++ sources/en/kaizenscan/kaizenscan.go | 18 +++++ sources/en/kewnscans/kewnscans.go | 18 +++++ sources/en/lunatoons/lunatoons.go | 18 +++++ sources/en/mistscans/mistscans.go | 18 +++++ sources/en/necroscans/necroscans.go | 18 +++++ sources/en/nyanukafe/nyanukafe.go | 18 +++++ sources/en/nyxscans/nyxscans.go | 19 ++++++ sources/en/orionscans/orionscans.go | 19 ++++++ sources/en/renascans/renascans.go | 19 ++++++ sources/en/sanascans/sanascans.go | 19 ++++++ sources/en/sirenscans/sirenscans.go | 18 +++++ sources/en/vanillascans/vanillascans.go | 19 ++++++ sources/standalone_smoke_test.go | 87 +++++++++++++++++++++++++ 22 files changed, 474 insertions(+), 19 deletions(-) create mode 100644 sources/all/hentaihand/hentaihand.go create mode 100644 sources/all/kemono/kemono.go create mode 100644 sources/all/mangataro/mangataro.go create mode 100644 sources/en/bakkin/bakkin.go create mode 100644 sources/en/divascans/divascans.go create mode 100644 sources/en/guya/guya.go create mode 100644 sources/en/hijalascans/hijalascans.go create mode 100644 sources/en/kaizenscan/kaizenscan.go create mode 100644 sources/en/kewnscans/kewnscans.go create mode 100644 sources/en/lunatoons/lunatoons.go create mode 100644 sources/en/mistscans/mistscans.go create mode 100644 sources/en/necroscans/necroscans.go create mode 100644 sources/en/nyanukafe/nyanukafe.go create mode 100644 sources/en/nyxscans/nyxscans.go create mode 100644 sources/en/orionscans/orionscans.go create mode 100644 sources/en/renascans/renascans.go create mode 100644 sources/en/sanascans/sanascans.go create mode 100644 sources/en/sirenscans/sirenscans.go create mode 100644 sources/en/vanillascans/vanillascans.go create mode 100644 sources/standalone_smoke_test.go diff --git a/cmd/server/main.go b/cmd/server/main.go index b549208..13e3ce4 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -9,6 +9,25 @@ import ( "goyomi/internal/config" "goyomi/internal/db" _ "goyomi/internal/registry" + _ "goyomi/sources/all/hentaihand" + _ "goyomi/sources/all/kemono" + _ "goyomi/sources/all/mangataro" + _ "goyomi/sources/en/bakkin" + _ "goyomi/sources/en/divascans" + _ "goyomi/sources/en/guya" + _ "goyomi/sources/en/hijalascans" + _ "goyomi/sources/en/kaizenscan" + _ "goyomi/sources/en/kewnscans" + _ "goyomi/sources/en/lunatoons" + _ "goyomi/sources/en/mistscans" + _ "goyomi/sources/en/necroscans" + _ "goyomi/sources/en/nyanukafe" + _ "goyomi/sources/en/nyxscans" + _ "goyomi/sources/en/orionscans" + _ "goyomi/sources/en/renascans" + _ "goyomi/sources/en/sanascans" + _ "goyomi/sources/en/sirenscans" + _ "goyomi/sources/en/vanillascans" ) func main() { diff --git a/docs/phase4-standalone.md b/docs/phase4-standalone.md index 39b706e..376af75 100644 --- a/docs/phase4-standalone.md +++ b/docs/phase4-standalone.md @@ -53,7 +53,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `all/hentaienvy` - [ ] `all/hentaiera` - [ ] `all/hentaifox` -- [ ] `all/hentaihand` +- [x] `all/hentaihand` - [ ] `all/hentairox` - [ ] `all/hentaizap` - [ ] `all/hniscantrad` @@ -64,7 +64,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `all/jjcos` - [ ] `all/joymiihub` - [ ] `all/junmeitu` -- [ ] `all/kemono` ⚠️ see notes +- [x] `all/kemono` ⚠️ see notes - [ ] `all/kiutaku` - [ ] `all/kodokustudio` - [ ] `all/koharu` @@ -83,7 +83,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `all/mangaforfree` - [ ] `all/mangaplus` ⚠️ see notes - [ ] `all/mangapluscreators` -- [ ] `all/mangataro` +- [x] `all/mangataro` - [ ] `all/mangatoon` - [ ] `all/mangaup` - [ ] `all/mango` @@ -170,7 +170,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/azcomic` - [ ] `en/azuki` - [ ] `en/baektoons` -- [ ] `en/bakkin` ⚠️ see notes +- [x] `en/bakkin` ⚠️ see notes - [ ] `en/bakkinselfhosted` - [ ] `en/batcave` - [ ] `en/battleinfivesecondsaftermeeting` @@ -208,7 +208,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/decadencescans` - [ ] `en/dflowscans` - [ ] `en/digitalcomicmuseum` -- [ ] `en/divascans` +- [x] `en/divascans` - [ ] `en/doujinio` - [ ] `en/doujins` - [ ] `en/dragontea` @@ -246,7 +246,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/grimscans` - [ ] `en/grrlpower` - [ ] `en/gunnerkriggcourt` -- [ ] `en/guya` ⚠️ see notes +- [x] `en/guya` ⚠️ see notes - [ ] `en/gwtb` - [ ] `en/hachirumi` - [ ] `en/hadesscans` @@ -265,7 +265,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/hentaixyuri` - [ ] `en/hentara` - [ ] `en/heytoon` -- [ ] `en/hijalascans` +- [x] `en/hijalascans` - [ ] `en/hiperdex` - [ ] `en/hiveworks` - [ ] `en/hm2d` @@ -279,7 +279,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/jinmangas` - [ ] `en/jnovel` - [ ] `en/kagane` -- [ ] `en/kaizenscan` +- [x] `en/kaizenscan` - [ ] `en/kaliscancom` - [ ] `en/kaliscanio` - [ ] `en/kaliscanme` @@ -287,7 +287,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/kaynscans` - [ ] `en/keenspot` - [ ] `en/kenscans` -- [ ] `en/kewnscans` +- [x] `en/kewnscans` - [ ] `en/killsixbilliondemons` - [ ] `en/kingcomix` - [ ] `en/kingofshojo` @@ -307,7 +307,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/loadingartist` - [ ] `en/luascans` - [ ] `en/luminaretranslations` -- [ ] `en/lunatoons` +- [x] `en/lunatoons` - [ ] `en/madaradex` - [ ] `en/madarascans` - [ ] `en/madokami` @@ -422,7 +422,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/mgjinx` - [ ] `en/mgreadio` - [ ] `en/milftoon` -- [ ] `en/mistscans` +- [x] `en/mistscans` - [ ] `en/mlbblore` - [ ] `en/monochromecustom` - [ ] `en/monochromescans` @@ -430,7 +430,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/murimscan` - [ ] `en/myhentaicomics` - [ ] `en/myhentaigallery` -- [ ] `en/necroscans` +- [x] `en/necroscans` - [ ] `en/newmanhwa` - [ ] `en/nexcomic` - [ ] `en/nikatoons` @@ -441,9 +441,9 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/novelcrow` - [ ] `en/noxenscans` - [ ] `en/nuxscans` -- [ ] `en/nyanukafe` +- [x] `en/nyanukafe` - [ ] `en/nyrascans` -- [ ] `en/nyxscans` +- [x] `en/nyxscans` - [ ] `en/octopusmanga` - [ ] `en/oglaf` - [ ] `en/ohjoysextoy` @@ -455,7 +455,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/oots` - [ ] `en/oppaistream` - [ ] `en/orchisasia` -- [ ] `en/orionscans` +- [x] `en/orionscans` - [ ] `en/paradisescans` - [ ] `en/paragonscans` - [ ] `en/paritehaber` @@ -494,7 +494,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/readvagabondmanga` - [ ] `en/reallifecomics` - [ ] `en/reimanga` -- [ ] `en/renascans` +- [x] `en/renascans` - [ ] `en/resetscans` - [ ] `en/restscans` - [ ] `en/retsu` @@ -508,13 +508,13 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/rosesquadscans` - [ ] `en/ryumanga` - [ ] `en/s2manga` -- [ ] `en/sanascans` +- [x] `en/sanascans` - [ ] `en/saturdaymorningbreakfastcomics` - [ ] `en/schlockmercenary` - [ ] `en/setsuscans` - [ ] `en/shibamanga` - [ ] `en/shojoscans` -- [ ] `en/sirenscans` +- [x] `en/sirenscans` - [ ] `en/skymanga` - [ ] `en/sleepytranslations` - [ ] `en/solarandsundry` @@ -547,7 +547,7 @@ Detailed implementation notes for complex sources are in the **Notes** section a - [ ] `en/tritiniascans` - [ ] `en/utoon` - [ ] `en/valirscans` -- [ ] `en/vanillascans` +- [x] `en/vanillascans` - [ ] `en/vgperson` - [ ] `en/vizshonenjump` - [ ] `en/voyceme` diff --git a/sources/all/hentaihand/hentaihand.go b/sources/all/hentaihand/hentaihand.go new file mode 100644 index 0000000..8b99733 --- /dev/null +++ b/sources/all/hentaihand/hentaihand.go @@ -0,0 +1,18 @@ +package hentaihand + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/hentaihand" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "HentaiHand", + BaseURL: "https://hentaihand.com", + Lang: "all", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/all/kemono/kemono.go b/sources/all/kemono/kemono.go new file mode 100644 index 0000000..3231abf --- /dev/null +++ b/sources/all/kemono/kemono.go @@ -0,0 +1,18 @@ +package kemono + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/kemono" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Kemono", + BaseURL: "https://kemono.cr", + Lang: "all", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/all/mangataro/mangataro.go b/sources/all/mangataro/mangataro.go new file mode 100644 index 0000000..00d26d3 --- /dev/null +++ b/sources/all/mangataro/mangataro.go @@ -0,0 +1,18 @@ +package mangataro + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/mangataro" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "MangaTaro", + BaseURL: "https://mangataro.org", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/bakkin/bakkin.go b/sources/en/bakkin/bakkin.go new file mode 100644 index 0000000..27de12a --- /dev/null +++ b/sources/en/bakkin/bakkin.go @@ -0,0 +1,18 @@ +package bakkin + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/bakkin" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Bakkin", + BaseURL: "https://bakkin.moe/reader/", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/divascans/divascans.go b/sources/en/divascans/divascans.go new file mode 100644 index 0000000..c8ead9c --- /dev/null +++ b/sources/en/divascans/divascans.go @@ -0,0 +1,19 @@ +package divascans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/iken" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Diva Scans", + BaseURL: "https://divatoon.com", + Lang: "en", + APIURL: "https://api.divatoon.com", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/guya/guya.go b/sources/en/guya/guya.go new file mode 100644 index 0000000..b32d6d4 --- /dev/null +++ b/sources/en/guya/guya.go @@ -0,0 +1,18 @@ +package guya + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/guya" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Guya", + BaseURL: "https://guya.cubari.moe", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/hijalascans/hijalascans.go b/sources/en/hijalascans/hijalascans.go new file mode 100644 index 0000000..1edba28 --- /dev/null +++ b/sources/en/hijalascans/hijalascans.go @@ -0,0 +1,19 @@ +package hijalascans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/iken" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Hijala Scans", + BaseURL: "https://en-hijala.com", + Lang: "en", + APIURL: "https://api.en-hijala.com", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/kaizenscan/kaizenscan.go b/sources/en/kaizenscan/kaizenscan.go new file mode 100644 index 0000000..b57b381 --- /dev/null +++ b/sources/en/kaizenscan/kaizenscan.go @@ -0,0 +1,18 @@ +package kaizenscan + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/keyoapp" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Kaizen Scan", + BaseURL: "https://kaizenscan.com", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/kewnscans/kewnscans.go b/sources/en/kewnscans/kewnscans.go new file mode 100644 index 0000000..3698346 --- /dev/null +++ b/sources/en/kewnscans/kewnscans.go @@ -0,0 +1,18 @@ +package kewnscans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/keyoapp" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Kewn Scans", + BaseURL: "https://kewnscans.org", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/lunatoons/lunatoons.go b/sources/en/lunatoons/lunatoons.go new file mode 100644 index 0000000..9b4e20a --- /dev/null +++ b/sources/en/lunatoons/lunatoons.go @@ -0,0 +1,18 @@ +package lunatoons + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/keyoapp" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Luna Toons", + BaseURL: "https://lunatoons.org", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/mistscans/mistscans.go b/sources/en/mistscans/mistscans.go new file mode 100644 index 0000000..d3dad90 --- /dev/null +++ b/sources/en/mistscans/mistscans.go @@ -0,0 +1,18 @@ +package mistscans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/keyoapp" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Mist Scans", + BaseURL: "https://mistscans.com", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/necroscans/necroscans.go b/sources/en/necroscans/necroscans.go new file mode 100644 index 0000000..d8edd82 --- /dev/null +++ b/sources/en/necroscans/necroscans.go @@ -0,0 +1,18 @@ +package necroscans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/keyoapp" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Necro Scans", + BaseURL: "https://necroscans.com", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/nyanukafe/nyanukafe.go b/sources/en/nyanukafe/nyanukafe.go new file mode 100644 index 0000000..44308b7 --- /dev/null +++ b/sources/en/nyanukafe/nyanukafe.go @@ -0,0 +1,18 @@ +package nyanukafe + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/keyoapp" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Nyanu Kafe", + BaseURL: "https://nyanukafe.com", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/nyxscans/nyxscans.go b/sources/en/nyxscans/nyxscans.go new file mode 100644 index 0000000..55b942e --- /dev/null +++ b/sources/en/nyxscans/nyxscans.go @@ -0,0 +1,19 @@ +package nyxscans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/iken" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Nyx Scans", + BaseURL: "https://nyxscans.com", + Lang: "en", + APIURL: "https://api.nyxscans.com", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/orionscans/orionscans.go b/sources/en/orionscans/orionscans.go new file mode 100644 index 0000000..e1985e5 --- /dev/null +++ b/sources/en/orionscans/orionscans.go @@ -0,0 +1,19 @@ +package orionscans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/iken" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Orion Scans", + BaseURL: "https://orion-scans.com", + Lang: "en", + APIURL: "https://api.orion-scans.com", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/renascans/renascans.go b/sources/en/renascans/renascans.go new file mode 100644 index 0000000..1d15eee --- /dev/null +++ b/sources/en/renascans/renascans.go @@ -0,0 +1,19 @@ +package renascans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/iken" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Renascans", + BaseURL: "https://renascans.net", + Lang: "en", + APIURL: "https://api.renascans.net", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/sanascans/sanascans.go b/sources/en/sanascans/sanascans.go new file mode 100644 index 0000000..640be48 --- /dev/null +++ b/sources/en/sanascans/sanascans.go @@ -0,0 +1,19 @@ +package sanascans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/iken" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Sana Scans", + BaseURL: "https://sanascans.com", + Lang: "en", + APIURL: "https://api.sanascans.com", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/sirenscans/sirenscans.go b/sources/en/sirenscans/sirenscans.go new file mode 100644 index 0000000..3c09a01 --- /dev/null +++ b/sources/en/sirenscans/sirenscans.go @@ -0,0 +1,18 @@ +package sirenscans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/keyoapp" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Siren Scans", + BaseURL: "https://sirenscans.com", + Lang: "en", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/en/vanillascans/vanillascans.go b/sources/en/vanillascans/vanillascans.go new file mode 100644 index 0000000..821dd11 --- /dev/null +++ b/sources/en/vanillascans/vanillascans.go @@ -0,0 +1,19 @@ +package vanillascans + +import ( + "goyomi/internal/registry" + base "goyomi/sources/base/iken" +) + +func New() *base.Source { + return base.New(base.Config{ + Name: "Vanilla Scans", + BaseURL: "https://vanillascans.org", + Lang: "en", + APIURL: "https://api.vanillascans.org", + }) +} + +func init() { + registry.Register(New()) +} diff --git a/sources/standalone_smoke_test.go b/sources/standalone_smoke_test.go new file mode 100644 index 0000000..038d1fe --- /dev/null +++ b/sources/standalone_smoke_test.go @@ -0,0 +1,87 @@ +package sources_test + +import ( + "os" + "testing" + + "goyomi/internal/source" + "goyomi/sources/en/kaizenscan" + "goyomi/sources/en/kewnscans" + "goyomi/sources/en/lunatoons" + "goyomi/sources/en/mistscans" + "goyomi/sources/en/necroscans" + "goyomi/sources/en/nyanukafe" + "goyomi/sources/en/sirenscans" +) + +type smokeCase struct { + name string + mode string + kotlinRef string + newSource func() source.CatalogueSource +} + +func TestStandaloneKeyoappSmoke(t *testing.T) { + if os.Getenv("GOYOMI_SMOKE") != "1" { + t.Skip("set GOYOMI_SMOKE=1 to run live source smoke tests") + } + + tests := []smokeCase{ + { + name: "en/kaizenscan", + mode: "plain_http", + kotlinRef: "extensions-source/src/en/kaizenscan/.../KaizenScan.kt", + newSource: func() source.CatalogueSource { return kaizenscan.New() }, + }, + { + name: "en/kewnscans", + mode: "plain_http", + kotlinRef: "extensions-source/src/en/kewnscans/.../KewnScans.kt", + newSource: func() source.CatalogueSource { return kewnscans.New() }, + }, + { + name: "en/lunatoons", + mode: "plain_http", + kotlinRef: "extensions-source/src/en/lunatoons/.../LunaToons.kt", + newSource: func() source.CatalogueSource { return lunatoons.New() }, + }, + { + name: "en/mistscans", + mode: "plain_http", + kotlinRef: "extensions-source/src/en/mistscans/.../MistScans.kt", + newSource: func() source.CatalogueSource { return mistscans.New() }, + }, + { + name: "en/necroscans", + mode: "plain_http", + kotlinRef: "extensions-source/src/en/necroscans/.../NecroScans.kt", + newSource: func() source.CatalogueSource { return necroscans.New() }, + }, + { + name: "en/nyanukafe", + mode: "plain_http", + kotlinRef: "extensions-source/src/en/nyanukafe/.../NyanuKafe.kt", + newSource: func() source.CatalogueSource { return nyanukafe.New() }, + }, + { + name: "en/sirenscans", + mode: "plain_http", + kotlinRef: "extensions-source/src/en/sirenscans/.../SirenScans.kt", + newSource: func() source.CatalogueSource { return sirenscans.New() }, + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + s := tc.newSource() + mp, err := s.GetPopularManga(1) + if err != nil { + t.Fatalf("mode=%s kotlin=%s popular failed: %v", tc.mode, tc.kotlinRef, err) + } + if len(mp.Mangas) == 0 { + t.Fatalf("mode=%s kotlin=%s popular returned 0 mangas", tc.mode, tc.kotlinRef) + } + }) + } +}