Files
metin2-client/tests/wiki/test_catalogue.py
T

88 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""Contract tests execute the exact parser embedded in CPython 2, under Python 3 too."""
import hashlib
import importlib.util
import json
import tempfile
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
SOURCE = ROOT / 'src/platform/ScriptLib/WikiDataScript.inc'
ns = {}
exec(SOURCE.read_text().split('R"PY(', 1)[1].rsplit(')PY";', 1)[0], ns)
Catalogue = ns['Catalogue']
RAW = (ROOT / 'data/wiki/catalogue.txt').read_bytes()
class CatalogueTests(unittest.TestCase):
def setUp(self):
self.catalogue = Catalogue(RAW)
def test_real_catalogue_manifest_and_unique_ranges(self):
report = json.loads((ROOT / 'data/wiki/manifest.json').read_text())
self.assertEqual(hashlib.sha256(RAW.split(b'\n', 1)[1]).hexdigest(), report['catalogue_sha256'])
self.assertEqual(self.catalogue.version, report['catalogue_sha256'])
self.assertEqual(len(self.catalogue.items), report['items'])
self.assertEqual(len(self.catalogue.mobs), report['monsters'])
self.assertEqual(len(self.catalogue.recipes), report['refine_recipes'])
def test_research_materials_and_chinese_search(self):
for row in json.loads((ROOT / 'tools/server/biolog/catalog.json').read_text()):
for field in ('material', 'stone', 'enhancer', 'skip'):
self.assertIsNotNone(self.catalogue.FindItem(row[field]))
row = self.catalogue.FindItem(300004)
self.assertEqual(row['name'], '榉木树枝')
results, count, page, pages = self.catalogue.Search('items', '榉木')
self.assertIn(300004, [r['id'] for r in results])
self.assertGreater(count, 0)
def test_template_ranges_resolve_without_expansion(self):
row = self.catalogue.FindItem(110050)
self.assertEqual((row['id'], row['end']), (110000, 110099))
results, count, _, _ = self.catalogue.Search('items', '110050')
self.assertIn(110000, [r['id'] for r in results])
self.assertIsNone(self.catalogue.FindItem(4294967295))
self.assertIsNone(self.catalogue.FindItem(0))
def test_pagination_filters_and_unicode_no_results(self):
results, count, page, pages = self.catalogue.Search('mobs', category='STONE', page=999999, page_size=2)
self.assertEqual(page, pages-1)
self.assertTrue(all(r['kind']=='STONE' for r in results))
results, count, page, pages = self.catalogue.Search('items', '不存在的测试物品')
self.assertEqual((results,count,page,pages),([],0,0,1))
results, count, page, pages = self.catalogue.Search('items', page=-20)
self.assertEqual(page,0)
self.assertLessEqual(len(results),6)
for kwargs in ({'mode':'unknown'},{'mode':'items','page_size':99},{'mode':'items','query':'x'*81}):
with self.assertRaises(ValueError):self.catalogue.Search(**kwargs)
def test_refine_links_and_materials_are_integer_data(self):
sword = self.catalogue.FindItem(10)
self.assertEqual(sword['refined'],11)
recipe = self.catalogue.recipes[sword['recipe']]
self.assertEqual((recipe['cost'],recipe['probability']),(600,90))
self.assertEqual(self.catalogue.mobs[101]['hp'],126)
self.assertEqual((self.catalogue.mobs[101]['attack_min'],self.catalogue.mobs[101]['attack_max']),(20,24))
def test_reject_bad_version_truncation_duplicate_and_markup(self):
cases = [RAW.replace(b'MTWIKI\t1',b'MTWIKI\t9',1), RAW+b'I\tbroken\n',
RAW+RAW.splitlines()[1]+b'\n', b'X'*2097153,
RAW.replace(b'ITEM_WEAPON',b'ITEM_|Hlink',1), RAW.replace(b'\t600\t90\t',b'\t600\t101\t',1)]
for raw in cases:
with self.assertRaises((ValueError,UnicodeError)):Catalogue(raw)
def test_generator_deterministic_when_local_snapshot_exists(self):
snapshot=ROOT/'build/wiki-source'
if not (snapshot/'refine.tsv').is_file():self.skipTest('private source snapshot not installed')
spec=importlib.util.spec_from_file_location('build_wiki',ROOT/'tools/wiki/build_catalogue.py')
module=importlib.util.module_from_spec(spec);spec.loader.exec_module(module)
with tempfile.TemporaryDirectory() as folder:
output=Path(folder)
report=module.build(snapshot,output,ROOT/'data/zh_40250')
self.assertEqual((output/'catalogue.txt').read_bytes(),RAW)
self.assertEqual(report['catalogue_sha256'],self.catalogue.version)
if __name__=='__main__':unittest.main()