You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
351 lines
9.0 KiB
Python
351 lines
9.0 KiB
Python
class MockSharedPreferences:
|
|
"""Mock SharedPreferences for testing."""
|
|
|
|
_all_data = {} # Class-level storage
|
|
|
|
def __init__(self, app_id, filename=None):
|
|
self.app_id = app_id
|
|
self.filename = filename
|
|
if app_id not in MockSharedPreferences._all_data:
|
|
MockSharedPreferences._all_data[app_id] = {}
|
|
|
|
def _get_value(self, key, default):
|
|
return MockSharedPreferences._all_data.get(self.app_id, {}).get(key, default)
|
|
|
|
def get_dict(self, key):
|
|
return self._get_value(key, {})
|
|
|
|
def get_list(self, key, default=None):
|
|
return self._get_value(key, default)
|
|
|
|
def get_bool(self, key, default=False):
|
|
value = self._get_value(key, default)
|
|
return bool(value)
|
|
|
|
def get_string(self, key, default=""):
|
|
value = self._get_value(key, default)
|
|
return value if value is not None else default
|
|
|
|
def get_int(self, key, default=0):
|
|
value = self._get_value(key, default)
|
|
try:
|
|
return int(value)
|
|
except (TypeError, ValueError):
|
|
return default
|
|
|
|
def edit(self):
|
|
return MockEditor(self)
|
|
|
|
@classmethod
|
|
def reset_all(cls):
|
|
cls._all_data = {}
|
|
|
|
|
|
class MockEditor:
|
|
"""Mock editor for SharedPreferences."""
|
|
|
|
def __init__(self, prefs):
|
|
self.prefs = prefs
|
|
self.pending = {}
|
|
|
|
def put_dict(self, key, value):
|
|
self.pending[key] = value
|
|
|
|
def put_list(self, key, value):
|
|
self.pending[key] = value
|
|
|
|
def put_bool(self, key, value):
|
|
self.pending[key] = bool(value)
|
|
|
|
def put_string(self, key, value):
|
|
self.pending[key] = value
|
|
|
|
def put_int(self, key, value):
|
|
self.pending[key] = int(value)
|
|
|
|
def commit(self):
|
|
if self.prefs.app_id not in MockSharedPreferences._all_data:
|
|
MockSharedPreferences._all_data[self.prefs.app_id] = {}
|
|
MockSharedPreferences._all_data[self.prefs.app_id].update(self.pending)
|
|
|
|
|
|
class MockMpos:
|
|
"""Mock mpos module with config and time."""
|
|
|
|
class config:
|
|
@staticmethod
|
|
def SharedPreferences(app_id):
|
|
return MockSharedPreferences(app_id)
|
|
|
|
class time:
|
|
@staticmethod
|
|
def sync_time():
|
|
pass # No-op for testing
|
|
|
|
|
|
class HotspotMockNetwork:
|
|
"""Mock network module with AP/STA support for hotspot tests."""
|
|
|
|
STA_IF = 0
|
|
AP_IF = 1
|
|
|
|
AUTH_OPEN = 0
|
|
AUTH_WPA_PSK = 1
|
|
AUTH_WPA2_PSK = 2
|
|
AUTH_WPA_WPA2_PSK = 3
|
|
|
|
class MockWLAN:
|
|
def __init__(self, interface):
|
|
self.interface = interface
|
|
self._active = False
|
|
self._connected = False
|
|
self._config = {}
|
|
self._scan_results = []
|
|
self._ifconfig = ("0.0.0.0", "0.0.0.0", "0.0.0.0", "0.0.0.0")
|
|
|
|
def active(self, is_active=None):
|
|
if is_active is None:
|
|
return self._active
|
|
self._active = is_active
|
|
return None
|
|
|
|
def isconnected(self):
|
|
return self._connected
|
|
|
|
def connect(self, ssid, password):
|
|
self._connected = True
|
|
self._config["essid"] = ssid
|
|
|
|
def disconnect(self):
|
|
self._connected = False
|
|
|
|
def config(self, *args, **kwargs):
|
|
if kwargs:
|
|
self._config.update(kwargs)
|
|
return None
|
|
if args:
|
|
return self._config.get(args[0])
|
|
return self._config
|
|
|
|
def ifconfig(self, cfg=None):
|
|
if cfg is None:
|
|
return self._ifconfig
|
|
self._ifconfig = cfg
|
|
return None
|
|
|
|
def ipconfig(self, key=None):
|
|
config = self.ifconfig()
|
|
mapping = {
|
|
"addr4": config[0],
|
|
"netmask4": config[1],
|
|
"gw4": config[2],
|
|
"dns4": config[3],
|
|
}
|
|
if key is None:
|
|
return mapping
|
|
return mapping.get(key)
|
|
|
|
def scan(self):
|
|
return self._scan_results
|
|
|
|
def __init__(self):
|
|
self._wlan_instances = {}
|
|
|
|
def WLAN(self, interface):
|
|
if interface not in self._wlan_instances:
|
|
self._wlan_instances[interface] = self.MockWLAN(interface)
|
|
return self._wlan_instances[interface]
|
|
|
|
|
|
class MockADC:
|
|
"""Mock ADC for testing."""
|
|
|
|
ATTN_11DB = 3
|
|
|
|
def __init__(self, pin):
|
|
self.pin = pin
|
|
self._atten = None
|
|
self._read_value = 2048
|
|
|
|
def atten(self, value):
|
|
self._atten = value
|
|
|
|
def read(self):
|
|
return self._read_value
|
|
|
|
def set_read_value(self, value):
|
|
"""Test helper to set ADC reading."""
|
|
self._read_value = value
|
|
|
|
|
|
class MockPin:
|
|
"""Mock Pin for testing."""
|
|
|
|
def __init__(self, pin_num):
|
|
self.pin_num = pin_num
|
|
|
|
|
|
class MockMachineADC:
|
|
"""Mock machine module with ADC/Pin."""
|
|
|
|
ADC = MockADC
|
|
Pin = MockPin
|
|
|
|
|
|
class MockWifiService:
|
|
"""Mock WifiService for testing."""
|
|
|
|
wifi_busy = False
|
|
_connected = False
|
|
_temporarily_disabled = False
|
|
|
|
@classmethod
|
|
def is_connected(cls):
|
|
return cls._connected
|
|
|
|
@classmethod
|
|
def disconnect(cls):
|
|
cls._connected = False
|
|
|
|
@classmethod
|
|
def temporarily_disable(cls):
|
|
"""Temporarily disable WiFi and return whether it was connected."""
|
|
if cls.wifi_busy:
|
|
raise RuntimeError("Cannot disable WiFi: WifiService is already busy")
|
|
was_connected = cls._connected
|
|
cls.wifi_busy = True
|
|
cls._connected = False
|
|
cls._temporarily_disabled = True
|
|
return was_connected
|
|
|
|
@classmethod
|
|
def temporarily_enable(cls, was_connected):
|
|
"""Re-enable WiFi and reconnect if it was connected before."""
|
|
cls.wifi_busy = False
|
|
cls._temporarily_disabled = False
|
|
if was_connected:
|
|
cls._connected = True
|
|
|
|
@classmethod
|
|
def reset(cls):
|
|
"""Test helper to reset state."""
|
|
cls.wifi_busy = False
|
|
cls._connected = False
|
|
cls._temporarily_disabled = False
|
|
|
|
|
|
class MockI2C:
|
|
"""Mock I2C bus for testing."""
|
|
|
|
def __init__(self, bus_id, sda=None, scl=None):
|
|
self.bus_id = bus_id
|
|
self.sda = sda
|
|
self.scl = scl
|
|
self.memory = {}
|
|
|
|
def readfrom_mem(self, addr, reg, nbytes):
|
|
"""Read from memory (simulates I2C read)."""
|
|
if addr not in self.memory:
|
|
raise OSError("I2C device not found")
|
|
if reg not in self.memory[addr]:
|
|
return bytes([0] * nbytes)
|
|
return bytes(self.memory[addr][reg])
|
|
|
|
def writeto_mem(self, addr, reg, data):
|
|
"""Write to memory (simulates I2C write)."""
|
|
if addr not in self.memory:
|
|
self.memory[addr] = {}
|
|
self.memory[addr][reg] = list(data)
|
|
|
|
|
|
class MockQMI8658:
|
|
"""Mock QMI8658 IMU sensor."""
|
|
|
|
def __init__(self, i2c_bus, address=0x6B, accel_scale=0b10, gyro_scale=0b100):
|
|
self.i2c = i2c_bus
|
|
self.address = address
|
|
self.accel_scale = accel_scale
|
|
self.gyro_scale = gyro_scale
|
|
|
|
@property
|
|
def temperature(self):
|
|
"""Return mock temperature."""
|
|
return 25.5
|
|
|
|
@property
|
|
def acceleration(self):
|
|
"""Return mock acceleration (in G)."""
|
|
return (0.0, 0.0, 1.0)
|
|
|
|
@property
|
|
def gyro(self):
|
|
"""Return mock gyroscope (in deg/s)."""
|
|
return (0.0, 0.0, 0.0)
|
|
|
|
|
|
class MockWsenIsds:
|
|
"""Mock WSEN_ISDS IMU sensor."""
|
|
|
|
def __init__(self, i2c, address=0x6B, acc_range="8g", acc_data_rate="104Hz",
|
|
gyro_range="500dps", gyro_data_rate="104Hz"):
|
|
self.i2c = i2c
|
|
self.address = address
|
|
self.acc_range = acc_range
|
|
self.gyro_range = gyro_range
|
|
self.acc_sensitivity = 0.244
|
|
self.gyro_sensitivity = 17.5
|
|
self.acc_offset_x = 0
|
|
self.acc_offset_y = 0
|
|
self.acc_offset_z = 0
|
|
self.gyro_offset_x = 0
|
|
self.gyro_offset_y = 0
|
|
self.gyro_offset_z = 0
|
|
|
|
def get_chip_id(self):
|
|
"""Return WHO_AM_I value."""
|
|
return 0x6A
|
|
|
|
def _read_raw_accelerations(self):
|
|
"""Return mock acceleration (in mg)."""
|
|
return (0.0, 0.0, 1000.0)
|
|
|
|
def read_angular_velocities(self):
|
|
"""Return mock gyroscope (in mdps)."""
|
|
return (0.0, 0.0, 0.0)
|
|
|
|
def acc_calibrate(self, samples=None):
|
|
"""Mock calibration."""
|
|
pass
|
|
|
|
def gyro_calibrate(self, samples=None):
|
|
"""Mock calibration."""
|
|
pass
|
|
|
|
|
|
def make_machine_i2c_module(i2c_cls, pin_cls=None):
|
|
if pin_cls is None:
|
|
pin_cls = type("Pin", (), {})
|
|
return type("module", (), {"I2C": i2c_cls, "Pin": pin_cls})()
|
|
|
|
|
|
def make_machine_timer_module(timer_cls):
|
|
return type("module", (), {"Timer": timer_cls})()
|
|
|
|
|
|
def make_usocket_module(socket_cls):
|
|
class MockUsocket:
|
|
"""Mock usocket module."""
|
|
|
|
AF_INET = socket_cls.AF_INET
|
|
SOCK_STREAM = socket_cls.SOCK_STREAM
|
|
|
|
@staticmethod
|
|
def socket(af, sock_type):
|
|
return socket_cls(af, sock_type)
|
|
|
|
return MockUsocket
|
|
|
|
|
|
def make_config_module(shared_prefs_cls):
|
|
return type("module", (), {"SharedPreferences": shared_prefs_cls})()
|