tests/test_performer_name_variant_link.py
Rama master · réplica de lectura del repositorio original.
# -*- coding: utf-8 -*-
"""同一位出演者的另一个艺名,从复核候选里认出来的判据。"""
from __future__ import annotations
import json
import sqlite3
import sys
import unittest
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
import link_performer_name_variants as link # noqa: E402
SCHEMA = (
"CREATE TABLE asset(id INTEGER PRIMARY KEY, code TEXT)",
"CREATE TABLE entity(id INTEGER PRIMARY KEY, kind TEXT, canonical_name TEXT,"
" normalized_name TEXT)",
"CREATE TABLE entity_alias(entity_id INTEGER, alias TEXT, normalized_alias TEXT,"
" source TEXT, confidence REAL DEFAULT 1.0,"
" PRIMARY KEY(entity_id, normalized_alias, source))",
)
def row(code: str, *candidates: tuple[str, str]) -> dict:
"""一行出演者候选。每个 `(来源, 顿号分隔的名字)` 是一条候选。"""
return {"field": "performers", "code": code, "query": code,
"candidates_json": json.dumps(
[{"source": source, "display_value": names} for source, names in candidates],
ensure_ascii=False)}
class LinkPerformerNameVariantTests(unittest.TestCase):
def setUp(self):
self.connection = sqlite3.connect(":memory:")
self.connection.row_factory = sqlite3.Row
for statement in SCHEMA:
self.connection.execute(statement)
self.connection.executemany(
"INSERT INTO entity(id,kind,canonical_name,normalized_name) VALUES(?,'performer',?,?)",
[(1, "美空彩香", "美空彩香"), (2, "森泽佳奈", "森泽佳奈"), (3, "白咲碧", "白咲碧")])
self.connection.execute(
"INSERT INTO entity_alias(entity_id,alias,normalized_alias,source) "
"VALUES(1,'美空あやか','美空あやか','peach:canonicalization')")
self.connection.executemany(
"INSERT INTO asset(id,code) VALUES(?,?)",
[(1, "n0762"), (2, "259LUXU-811"), (3, "LUXU-688")])
self.addCleanup(self.connection.close)
def collect(self, *rows):
return link.collect(self.connection, list(rows))
def test_one_anchored_name_makes_the_other_an_alias_of_that_person(self):
"""两家在同一部片上只差一个写法,其中一个有账本锚点,另一个就是同一位。"""
found, contested = self.collect(
row("n0762", ("javbus", "藤原遼子"), ("javdb", "森泽佳奈")))
self.assertEqual(contested, [])
self.assertEqual([(item["keep_id"], item["alias"]) for item in found],
[(2, "藤原遼子")])
def test_the_anchor_may_be_a_registered_alias_rather_than_the_canonical_name(self):
"""锚点算的是身份不是规范名:`美空あやか` 是别名,同样指得到实体 1。"""
found, _ = self.collect(row("n0646", ("javbus", "一ノ瀬アメリ"), ("javdb", "美空あやか")))
self.assertEqual([(item["keep_id"], item["alias"], item["keep_name"]) for item in found],
[(1, "一ノ瀬アメリ", "美空彩香")])
def test_a_shared_cast_member_leaves_the_single_differing_name_pairable(self):
"""两家各给两个人、其中一个逐字相同:剩下那一处才是同一位的另一个写法。"""
found, _ = self.collect(
row("n1032", ("javbus", "山本玲奈、本村紗枝"), ("javdb", "本村紗枝、白咲碧")))
self.assertEqual([(item["keep_id"], item["alias"]) for item in found],
[(3, "山本玲奈")])
def test_two_names_changing_at_once_is_a_real_disagreement(self):
"""整组换掉说明两家说的是两拨人,不是写法不同。"""
found, _ = self.collect(
row("n9999", ("javbus", "山本玲奈、佐藤花"), ("javdb", "白咲碧、鈴木葵")))
self.assertEqual(found, [])
def test_a_name_neither_side_of_the_ledger_knows_has_no_anchor(self):
"""两边都不认识就没有锚点,谁当规范名都是猜。"""
found, _ = self.collect(row("122919-001", ("javbus", "新城由衣"), ("javdb", "吉澤ひかり")))
self.assertEqual(found, [])
def test_both_names_already_being_separate_people_is_left_to_merge_entity(self):
"""两侧都认识说明账本已经当成两个人,合不合并是另一件事。"""
found, _ = self.collect(row("n8888", ("javbus", "白咲碧"), ("javdb", "森泽佳奈")))
self.assertEqual(found, [])
def test_the_amateur_planning_name_never_becomes_an_alias(self):
"""素人企划的商品页给的是这部片给她起的一次性称呼,不是她的艺名。"""
found, _ = self.collect(row("259LUXU-811", ("avbase", "白咲碧"), ("javdb", "ひなた唯")))
self.assertEqual(found, [])
def test_the_same_planning_label_without_the_numeric_prefix_is_skipped_too(self):
"""同一个企划既有 `259LUXU-811` 也有 `LUXU-688`,字母段一样就整段算进去。"""
self.assertIn("luxu", link.amateur_stems(self.connection))
found, _ = self.collect(row("LUXU-688", ("avbase", "白咲碧"), ("javdb", "松永さな")))
self.assertEqual(found, [])
def test_promo_copy_is_not_a_name_so_the_whole_candidate_drops_out(self):
"""剪不出艺名边界的是企划文案,整条候选作废。"""
found, _ = self.collect(row("n7777", ("mgstage", "佐倉井さん 28歳 某企業広報担当"),
("javdb", "白咲碧")))
self.assertEqual(found, [])
def test_one_spelling_claimed_by_two_people_is_written_for_neither(self):
"""同一个写法被两条实体同时认领时一条都不写:指错人比没指更难发现。"""
found, contested = self.collect(
row("n0762", ("javbus", "藤原遼子"), ("javdb", "森泽佳奈")),
row("n0763", ("javbus", "藤原遼子"), ("javdb", "白咲碧")))
self.assertEqual(found, [])
self.assertEqual(sorted(item["keep_id"] for item in contested), [2, 3])
def test_applying_writes_each_alias_once(self):
found, _ = self.collect(row("n0762", ("javbus", "藤原遼子"), ("javdb", "森泽佳奈")))
self.assertEqual(link.apply_rows(self.connection, found), 1)
self.assertEqual(link.apply_rows(self.connection, found), 0)
self.assertEqual(
[tuple(item) for item in self.connection.execute(
"SELECT entity_id,alias,source FROM entity_alias WHERE source=?",
(link.ALIAS_SOURCE,))],
[(2, "藤原遼子", link.ALIAS_SOURCE)])
if __name__ == "__main__":
unittest.main()