-- Tests anime_sort.lua end to end (stubbing the `naut` host API) and verifies -- its embedded parser still matches examples/anitomy.lua. -- Run: lua examples/test_anime_sort.lua local dir = arg[0]:match("^(.*/)") or "./" package.path = dir .. "?.lua;" .. package.path local ref = require("anitomy") -- stub the host API the script calls, and silence its prints local captured -- Per-torrent label stub: torrent 1 is labelled "anime"; others are unlabelled. local LABELS = { [1] = { "anime" } } -- Optional per-key setting overrides; nil falls back to the script's defaults. local SETTINGS = {} _G.naut = { move_file = function(tid, idx, dest) captured = dest end, get_labels = function(tid) return LABELS[tid] or {} end, define_settings = function(_) end, -- schema declaration: no-op here get_setting = function(key) return SETTINGS[key] end, } local realprint = print _G.print = function() end dofile(dir .. "anime_sort.lua") -- defines on_file_complete + _G.anime_sort _G.print = realprint local configured_root = _G.anime_sort.destination({ title = "__ROOT_PROBE__", file_name = "__ROOT_PROBE__.mkv", extension = "mkv", }):match("^(.*)/__ROOT_PROBE__/__ROOT_PROBE__%.mkv$") assert(configured_root, "could not derive SORTED_ROOT from anime_sort.lua") local fails = 0 local function fire(path, torrent_id) captured = nil on_file_complete({ torrent_id = torrent_id or 1, index = 0, path = path }) return captured end local function expect(path, want_dest) local got = fire(path) if got ~= want_dest then fails = fails + 1 realprint("FAIL " .. path) realprint(" got: " .. tostring(got)) realprint(" want: " .. tostring(want_dest)) else realprint("ok " .. path) end end -- episodes expect("/downloads/1/[HorribleSubs] Boku no Hero Academia - 12 [1080p].mkv", configured_root .. "/Boku no Hero Academia/Season 01/Boku no Hero Academia - S01E12.mkv") expect("/downloads/2/[Group] Attack on Titan S04E28 [BD 1080p HEVC].mkv", configured_root .. "/Attack on Titan/Season 04/Attack on Titan - S04E28.mkv") expect("/dl/[Commie] Steins;Gate 0 - 12 [BD 1080p].mkv", configured_root .. "/Steins;Gate 0/Season 01/Steins;Gate 0 - S01E12.mkv") expect("Demon.Slayer.Kimetsu.no.Yaiba.S03E11.1080p.mkv", configured_root .. "/Demon Slayer Kimetsu no Yaiba/Season 03/Demon Slayer Kimetsu no Yaiba - S03E11.mkv") expect("/x/[Erai-raws] Jujutsu Kaisen 2nd Season - 17 [1080p].mkv", configured_root .. "/Jujutsu Kaisen/Season 02/Jujutsu Kaisen - S02E17.mkv") -- movies (no episode) expect("/m/[Group] A Silent Voice [BD 1080p FLAC].mkv", configured_root .. "/A Silent Voice/A Silent Voice.mkv") expect("/m/Spirited.Away.2001.1080p.BluRay.x264.mkv", configured_root .. "/Spirited Away/Spirited Away (2001).mkv") -- non-video file must be skipped (no move queued) do local got = fire("/d/[Group] Some Show - 01 [1080p].ass") if got ~= nil then fails = fails + 1 realprint("FAIL non-video should be skipped, got: " .. tostring(got)) else realprint("ok non-video skipped") end end -- label gate: a torrent without the "anime" label is left alone (no move), -- while an "anime"-labelled torrent is still sorted. do local episode = "/downloads/[HorribleSubs] Boku no Hero Academia - 12 [1080p].mkv" local unlabelled = fire(episode, 2) -- torrent 2 has no labels if unlabelled ~= nil then fails = fails + 1 realprint("FAIL unlabelled torrent should be skipped, got: " .. tostring(unlabelled)) else realprint("ok unlabelled torrent skipped") end local labelled = fire(episode, 1) -- torrent 1 is labelled "anime" if labelled == nil then fails = fails + 1 realprint("FAIL anime-labelled torrent should be sorted") else realprint("ok anime-labelled torrent sorted") end end -- settings: a value configured in the UI (delivered via naut.get_setting) takes -- effect live, without editing the script. do SETTINGS.sorted_root = "/custom/lib" local got = fire("/downloads/[HorribleSubs] Boku no Hero Academia - 12 [1080p].mkv", 1) SETTINGS.sorted_root = nil local want = "/custom/lib/Boku no Hero Academia/Season 01/Boku no Hero Academia - S01E12.mkv" if got ~= want then fails = fails + 1 realprint("FAIL sorted_root override not applied, got: " .. tostring(got)) else realprint("ok sorted_root setting override applied") end end -- drift guard: embedded parser must agree with anitomy.lua local embedded = _G.anime_sort.anitomy local drift = 0 for _, name in ipairs({ "[HorribleSubs] Boku no Hero Academia - 12 [1080p].mkv", "[Group] Attack on Titan S04E28 [BD 1080p HEVC].mkv", "One.Piece.S01E1071.1080p.WEB.x264.mkv", "Spirited.Away.2001.1080p.BluRay.x264.mkv", "[Commie] Steins;Gate 0 - 12 [BD 1080p].mkv", }) do local a, b = ref.parse(name), embedded.parse(name) for _, k in ipairs({ "title", "season", "episode", "year", "episode_end" }) do if a[k] ~= b[k] then drift = drift + 1 realprint(("DRIFT %s field %s: anitomy=%s embedded=%s") :format(name, k, tostring(a[k]), tostring(b[k]))) end end end if drift == 0 then realprint("ok embedded parser matches anitomy.lua") else fails = fails + drift end if fails == 0 then realprint("\nALL PASS"); os.exit(0) else realprint("\n" .. fails .. " FAILED"); os.exit(1) end