makepad/tools/nigig_compat/check.py

87 lines
3.8 KiB
Python

#!/usr/bin/env python3
"""Static nigig compatibility sentinels, not build/runtime tests.
Run with Python 3.11+: python3 tools/nigig_compat/check.py [--root CHECKOUT]
File moves are allowed for the platform and widget implementations. These
checks catch accidentally omitted interfaces; they do not prove semantics.
"""
import argparse
from pathlib import Path
import re
import tomllib
import unittest
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--root', type=Path, default=Path(__file__).resolve().parents[2])
args, rest = parser.parse_known_args()
ROOT = args.root.resolve()
def read(path):
return (ROOT / path).read_text(encoding='utf-8')
def rust_under(*directories):
return '\n'.join(p.read_text(encoding='utf-8') for directory in directories
for p in (ROOT / directory).rglob('*.rs')
if 'target' not in p.parts)
class NigigCompatibility(unittest.TestCase):
def test_optional_sibling_exports(self):
cargo = tomllib.loads(read('widgets/Cargo.toml'))
source = read('widgets/src/lib.rs')
for feature, crate in [('test', 'makepad-test'), ('gltf', 'makepad-gltf'), ('csg', 'makepad-csg')]:
with self.subTest(feature=feature):
self.assertIn('dep:' + crate, cargo['features'][feature])
self.assertTrue(cargo['dependencies'][crate]['optional'])
self.assertIn('pub use ' + crate.replace('-', '_') + ';', source)
def test_isolate_host_entry_points(self):
source = rust_under('widgets/core/src', 'widgets/src')
for symbol in ['enter_isolate', 'leave_isolate']:
self.assertRegex(source, r'pub\s+fn\s+' + symbol + r'\s*\(')
def test_android_test_mode_forwarding(self):
source = rust_under('platform/src/os/linux/android', 'platform/hal/src/backend/android')
self.assertIn('makepad.NIGIG_TEST_MODE', source)
self.assertIn('"NIGIG_TEST_MODE"', source)
def test_startup_and_touch_protocol(self):
source = rust_under('platform/studio/src')
for symbol in ['BeforeStartup', 'AfterStartup', 'RemoteTouchUpdate', 'RemoteLongPress', 'RemoteTextPaste', 'RemoteIMEComposition']:
with self.subTest(symbol=symbol):
self.assertTrue(symbol in source, 'Missing nigig protocol symbol: ' + symbol)
def test_secondary_dex_and_custom_manifest(self):
source = read('tools/cargo_makepad/src/android/compile.rs')
self.assertGreaterEqual(source.count('bundle_crate_secondary_dex('), 2,
'secondary dex bundler must be defined and invoked')
self.assertIn('resources/android/AndroidManifest.xml.template', source)
self.assertIn('generate_android_wrapper_manifest', source)
def test_game_packages(self):
expected = {
'libs/sim/Cargo.toml': 'makepad-game-sim',
'libs/sim/math/Cargo.toml': 'makepad-game-math',
'libs/game/blocks/Cargo.toml': 'makepad-game-blocks',
'libs/game/render/Cargo.toml': 'makepad-game-render',
}
for path, name in expected.items():
with self.subTest(package=name):
self.assertEqual(tomllib.loads(read(path))['package']['name'], name)
def test_quest_packaging_remains_available(self):
source = read('tools/cargo_makepad/src/android/mod.rs')
enum = re.search(r'pub enum AndroidVariant\s*\{([^}]+)\}', source)
self.assertIsNotNone(enum)
self.assertRegex(enum.group(1), r'\bQuest\b')
def test_cef_widget_remains_available(self):
cargo = tomllib.loads(read('widgets/Cargo.toml'))
self.assertIn('cef', cargo['features'])
self.assertTrue((ROOT / 'widgets/families/cef/Cargo.toml').is_file())
if __name__ == '__main__':
unittest.main(argv=['check.py', *rest])