Files
LihonT/tests/test_avatar_patch.py
cheb0chik e63ca75eac LihonT 2 Luna pre-release
Avatar shapes (circle, flower, rounded square, hexagon, heart, triangle): the own shape everywhere and, through
the members service, the shapes other members published after proving the account with the code in the bio.
Own accent colour and AMOLED, compact bottom bar, Material 3 profile and plus button, save menu (quality, audio
only, photo posts without the watermark), fixed comment cards, "Luna (pre-release)" in the mod screen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-23 19:03:48 +03:00

81 lines
3.0 KiB
Python

import unittest
from pathlib import Path
from lihont import avatar_patch
ROOT = Path(__file__).resolve().parents[1]
REAL = ROOT / "work" / "dl" / "avatar" / "X" / "1Bem.smali"
VIEW = """\
.class public LX/1Bem;
.super Lcom/bytedance/lighten/loader/SmartImageView;
.method public final onDetachedFromWindow()V
.registers 1
return-void
.end method
.method public onDraw(Landroid/graphics/Canvas;)V
.registers 3
:try_start_0
invoke-virtual {p0, p1}, LX/1Bem;->LJIIIIZZ(Landroid/graphics/Canvas;)V
goto :goto_9
:catch_4
move-exception v0
throw v0
:goto_9
return-void
.end method
"""
class AvatarRewriteTest(unittest.TestCase):
def test_the_hand_over_is_bracketed(self):
patched = avatar_patch.rewrite_avatar(VIEW)
begin = patched.index(avatar_patch.BEGIN)
end = patched.index(avatar_patch.END)
self.assertLess(begin, patched.index("invoke-virtual {p0, p1}, LX/1Bem;->LJIIIIZZ"))
self.assertLess(patched.index("invoke-virtual {p0, p1}, LX/1Bem;->LJIIIIZZ"), end)
self.assertLess(end, patched.index(" return-void\n.end method", end))
self.assertIn(" .registers 3\n\n" + avatar_patch.BEGIN_CALL, patched)
def test_only_the_draw_method_changes(self):
patched = avatar_patch.rewrite_avatar(VIEW)
self.assertEqual(1, patched.count(avatar_patch.BEGIN))
self.assertEqual(1, patched.count(avatar_patch.END))
self.assertEqual(VIEW.count(".method "), patched.count(".method "))
self.assertTrue(patched.startswith(VIEW.split(".method public onDraw")[0]))
# the calls use the parameter registers only, so no register is added to a method with three
for register in ("v0", "v1", "v2"):
self.assertNotIn(register, avatar_patch.BEGIN_CALL + avatar_patch.END_CALL)
def test_second_passes_and_foreign_classes_are_refused(self):
with self.assertRaises(ValueError):
avatar_patch.rewrite_avatar(avatar_patch.rewrite_avatar(VIEW))
with self.assertRaises(ValueError):
avatar_patch.rewrite_avatar(".class public Lx;\n.super Ljava/lang/Object;\n")
with self.assertRaises(ValueError):
avatar_patch.rewrite_avatar(VIEW.replace("invoke-virtual", "invoke-direct"))
with self.assertRaises(ValueError):
avatar_patch.rewrite_avatar(VIEW.replace(" goto :goto_9", " return-void"))
def test_runtime_targets_are_what_the_rewrite_calls(self):
patched = avatar_patch.rewrite_avatar(VIEW)
for target in avatar_patch.runtime_targets():
self.assertIn(target, patched)
@unittest.skipUnless(REAL.exists(), "the disassembled X.1Bem is not in work/")
def test_the_real_class_is_rewritten(self):
text = REAL.read_text(encoding="utf-8").replace(chr(13) + chr(10), chr(10))
patched = avatar_patch.rewrite_avatar(text)
self.assertEqual(text.count(".method "), patched.count(".method "))
self.assertEqual(1, patched.count(avatar_patch.BEGIN))
if __name__ == "__main__":
unittest.main()