#!/usr/bin/env python3 import unittest import sys import os.path import os FAKE_SYS = os.path.join(os.path.dirname(__file__), 'fake-sys') os.environ["FAKE_SYS"] = "1" sys.path.append(FAKE_SYS) sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from populate_arena import populate_arena # noqa: E402 from clean_arena import clean_arena # noqa: E402 import ev3dev2 # noqa: E402 import ev3dev2.stopwatch # noqa: E402 from ev3dev2.motor import \ OUTPUT_A, OUTPUT_B, \ Motor, MediumMotor, LargeMotor, \ MoveTank, MoveSteering, MoveJoystick, \ SpeedPercent, SpeedDPM, SpeedDPS, SpeedRPM, SpeedRPS, SpeedNativeUnits # noqa: E402 from ev3dev2.sensor.lego import InfraredSensor # noqa: E402 from ev3dev2.stopwatch import StopWatch, StopWatchAlreadyStartedException # noqa: E402 from ev3dev2.unit import ( # noqa: E402 DistanceMillimeters, DistanceCentimeters, DistanceDecimeters, DistanceMeters, DistanceInches, DistanceFeet, DistanceYards, DistanceStuds) ev3dev2.Device.DEVICE_ROOT_PATH = os.path.join(FAKE_SYS, 'arena') _internal_set_attribute = ev3dev2.Device._set_attribute def _set_attribute(self, attribute, name, value): # Follow the text with a newline to separate new content from stuff that # already existed in the buffer. On the real device we're writing to sysfs # attributes where there isn't any persistent buffer, but in the test # environment they're normal files on disk which retain previous data. attribute = _internal_set_attribute(self, attribute, name, value) attribute.write(b'\n') return attribute ev3dev2.Device._set_attribute = _set_attribute _internal_get_attribute = ev3dev2.Device._get_attribute def _get_attribute(self, attribute, name): # Split on newline delimiter; see _set_attribute above attribute, value = _internal_get_attribute(self, attribute, name) return attribute, value.split('\n', 1)[0] ev3dev2.Device._get_attribute = _get_attribute def dummy_wait(self, cond, timeout=None): pass Motor.wait = dummy_wait # for StopWatch mock_ticks_ms = 0 def _mock_get_ticks_ms(): return mock_ticks_ms ev3dev2.stopwatch.get_ticks_ms = _mock_get_ticks_ms def set_mock_ticks_ms(value): global mock_ticks_ms mock_ticks_ms = value class TestAPI(unittest.TestCase): def setUp(self): # micropython does not have _testMethodName try: print("\n\n{}\n{}".format(self._testMethodName, "=" * len(self._testMethodName, ))) except AttributeError: pass # ensure tests don't depend on order based on StopWatch tick state set_mock_ticks_ms(0) def test_device(self): clean_arena() populate_arena([('medium_motor', 0, 'outA'), ('infrared_sensor', 0, 'in1')]) ev3dev2.Device('tacho-motor', 'motor*') ev3dev2.Device('tacho-motor', 'motor0') ev3dev2.Device('tacho-motor', 'motor*', driver_name='lego-ev3-m-motor') ev3dev2.Device('tacho-motor', 'motor*', address='outA') with self.assertRaises(ev3dev2.DeviceNotFound): ev3dev2.Device('tacho-motor', 'motor*', address='outA', driver_name='not-valid') with self.assertRaises(ev3dev2.DeviceNotFound): ev3dev2.Device('tacho-motor', 'motor*', address='this-does-not-exist') ev3dev2.Device('lego-sensor', 'sensor*') with self.assertRaises(ev3dev2.DeviceNotFound): ev3dev2.Device('this-does-not-exist') def test_medium_motor(self): def dummy(self): pass clean_arena() populate_arena([('medium_motor', 0, 'outA')]) # Do not write motor.command on exit (so that fake tree stays intact) MediumMotor.__del__ = dummy m = MediumMotor() self.assertEqual(m.device_index, 0) # Check that reading twice works: self.assertEqual(m.driver_name, 'lego-ev3-m-motor') self.assertEqual(m.driver_name, 'lego-ev3-m-motor') self.assertEqual(m.count_per_rot, 360) self.assertEqual( m.commands, ['run-forever', 'run-to-abs-pos', 'run-to-rel-pos', 'run-timed', 'run-direct', 'stop', 'reset']) self.assertEqual(m.duty_cycle, 0) self.assertEqual(m.duty_cycle_sp, 42) self.assertEqual(m.polarity, 'normal') self.assertEqual(m.address, 'outA') self.assertEqual(m.position, 42) self.assertEqual(m.position_sp, 42) self.assertEqual(m.ramp_down_sp, 0) self.assertEqual(m.ramp_up_sp, 0) self.assertEqual(m.speed, 0) self.assertEqual(m.speed_sp, 0) self.assertEqual(m.state, ['running']) self.assertEqual(m.stop_action, 'coast') self.assertEqual(m.time_sp, 1000) with self.assertRaises(Exception): m.command def test_infrared_sensor(self): clean_arena() populate_arena([('infrared_sensor', 0, 'in1')]) s = InfraredSensor() self.assertEqual(s.device_index, 0) self.assertEqual(s.bin_data_format, 's8') self.assertEqual(s.bin_data('