def test_timing_02(capsys): '''stopping in state STARTED after action''' ts = Timespan() t = Task(print_it, args=(ts, 'started')) + Task( print_it, args=(ts, 'hello'), action_stop=print_it, args_stop=(ts, 'stopped'), action_cont=print_it, args_cont=(ts, 'continued'), duration=.2) + Task(print_it, args=(ts, 'finished')) t.start(.1) sleep(.2) assert t.state == STATE_STARTED assert t.activity == ACTIVITY_SLEEP t.stop().join() assert t.state == STATE_STOPPED assert t.activity == ACTIVITY_NONE captured = capsys.readouterr() assert captured.err == '' assert captured.out == '0.1:started 0.1:hello 0.2:stopped ' sleep(.1) t.cont().join() assert t.state == STATE_FINISHED assert t.activity == ACTIVITY_NONE captured = capsys.readouterr() assert captured.err == '' assert captured.out == '0.3:continued 0.4:finished '
def stop_task( self, brake: bool = False, duration: Number = None ) -> Task: """ Stop any movement of the vehicle Keyword Arguments brake flag if activating brake duration duration of movement [s] Returns Task, which needs to be started or combined with other tasks """ assert isinstance(brake, bool), \ "brake needs to be a boolean value" assert duration is None or duration > 0, \ "duration needs to be a positive number" assert duration is None or isinstance(duration, Number), \ "duration needs to be a number" if duration is None: return Task( self._stop, args=(brake,) ) else: return Task( self._stop, args=(brake,), duration=duration )
def test_standard(capsys): t = Task(print, args=('hello, world!', ), kwargs={'end': ''}).start() t.join() assert t.state == STATE_FINISHED captured = capsys.readouterr() assert captured.err == '' assert captured.out == 'hello, world!'
def move_task( self, speed: Integral, turn: Integral, duration: Number = None ) -> Task: """ Start unlimited movement of the vehicle Positional Arguments speed speed in percent [-100 - 100] > 0: forward < 0: backward turn type of turn [-200 - 200] -200: circle right on place -100: turn right with unmoved right wheel 0 : straight 100: turn left with unmoved left wheel 200: circle left on place Keyword Arguments duration duration of movement [s] Returns Task, which needs to be started or combined with other tasks """ assert duration is not None or self._sync_mode != SYNC, \ 'no unlimited operations allowed in sync_mode SYNC' assert isinstance(speed, Integral), \ "speed needs to be an integer value" assert -100 <= speed and speed <= 100, \ "speed needs to be in range [-100 - 100]" assert isinstance(turn, Integral), \ "turn needs to be an integer value" assert -200 <= turn and turn <= 200, \ "turn needs to be in range [-200 - 200]" assert duration is None or isinstance(duration, Number), \ "duration needs to be a positive number" assert duration is None or duration > 0, \ "duration needs to be a positive number" if duration is None: return Task( self.move(speed, turn) ) else: return Task( self.move(speed, turn), duration=duration )
def test_standard(capsys): ts = Timespan() acc = Accelerate(ts, 0.3) t = Task(print_it, args=(ts, 'started')) + Repeated( acc.step, action_stop=print_it, args_stop=(ts, 'stopped'), action_cont=print_it, args_cont=(ts, 'continued')) + Task(print_it, args=(ts, 'finished')) t.start() sleep(.4) assert t.state == STATE_STARTED assert t.activity == ACTIVITY_SLEEP t.stop().join() assert t.state == STATE_STOPPED assert t.activity == ACTIVITY_NONE captured = capsys.readouterr() assert captured.err == '' assert captured.out == \ '0.0:started 0.0:hi 0.3:hi 0.4:stopped ' t.cont(.1).join() assert t.state == STATE_FINISHED assert t.activity == ACTIVITY_NONE captured = capsys.readouterr() assert captured.out == \ '0.5:continued 0.6:hi 0.7:hi 0.7:hi ' + \ '0.7:finished '
def test_add(capsys): '''overloaded add operator''' t1 = Task(print, args=('hello,', )) t2 = Task(print, args=('world!', )) t = t1 + t2 t.start(thread=False) assert t.state == STATE_FINISHED assert t.activity == ACTIVITY_NONE captured = capsys.readouterr() assert captured.err == '' assert captured.out == 'hello,\nworld!\n'
def test_standard(capsys): ts = Timespan() t = Task(print_it, args=(ts, 'started')) + Sleep(.1) + Task( print_it, args=(ts, 'finished')) t.start().join() captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == '0.0:started 0.1:finished '
def drive_turn( self, speed: int, radius_turn: Number, angle: Number = None, right_turn: bool = False ) -> Task: """ Drive the vehicle a turn with given radius. Keep in mind, it never stops, even when angle was set. At the end of the movement, there must be a stop. Positional arguments speed in percent [-100 - 100] (direction depends on its sign) positive sign: forwards negative sign: backwards radius_turn [m] positive sign: turn to the left side negative sign: turn to the right side Optional arguments angle absolute angle (needs to be positive) if None, unlimited movement right_turn flag of turn right (only in case of radius_turn == 0) Returns Task, which needs to be started or combined with other tasks """ assert isinstance(radius_turn, Number), \ "radius_turn needs to be a number" assert isinstance(right_turn, bool), "right_turn needs to be a boolean" assert not right_turn or radius_turn == 0, \ "right_turn only can be set, when turning on place" assert angle is None or isinstance(angle, Number), \ "angle needs to be a number" assert angle is None or angle > 0, "angle needs to be positive" t = self._Drive( self._drive_turn, args=(speed, radius_turn, angle, right_turn), action_stop=self._stop, args_stop=(False,), action_cont=self._vehicle_cont ) if angle is None: return Task(t.start) else: t.append( Repeated(self._test_o), copy=False ) return Task(t.start, join=True)
def test_concat(capsys): ts = Timespan() t = concat(Task(print_it, args=(ts, 'started')), Sleep(.1), Task(print_it, args=(ts, 'hello')), Sleep(.1), Task(print_it, args=(ts, 'world')), Task(print_it, args=(ts, 'finished'))).start(.1).join() captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == '0.1:started 0.2:hello 0.3:world 0.3:finished '
def test_long_lasting(capsys): ts = Timespan() t = Task(print_it, args=(ts, 'started')) + Repeated( print_it_long_lasting, args=(ts, 'hi'), num=2, duration=.3) + Task( print_it, args=(ts, 'finished')) t.start().join() captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == '0.0:started 0.0:hi 0.1:hi 0.3:finished '
def test_netto_time(capsys): ts = Timespan() t = Task(print_it, args=(ts, 'started')) + Periodic( .1, print_it_long_lasting, args=(ts, 'hi'), num=3, netto_time=True) + Task(print_it, args=(ts, 'finished')) t.start().join() captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == \ '0.0:started 0.0:hi 0.2:hi 0.4:hi 0.5:finished '
def test_threadless(capsys): ts = Timespan() t = Task(print_it, args=(ts, 'started')) + Periodic( .1, print_it, args=(ts, 'hi'), num=3) + Task(print_it, args=(ts, 'finished')) t.start(thread=False) captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == \ '0.0:started 0.0:hi 0.1:hi 0.2:hi 0.2:finished '
def test_threadless_child(capsys): ts = Timespan() t = Task( Task(print_it, args=(ts, 'started')) + Repeated(print_it_long_lasting, args=(ts, 'hi'), num=2, duration=.3, netto_time=True) + Task(print_it, args=(ts, 'finished'))).start(thread=False) captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == '0.0:started 0.0:hi 0.2:hi 0.3:finished '
def drive_straight( self, speed: int, distance: float = None ) -> Task: """ Drive the vehicle straight forward or backward. Keep in mind, it never stops, even when distance was set. At the end of the movement, there must be a stop. Positional Arguments speed in percent [-100 - 100] (direction depends on its sign) positive sign: forwards negative sign: backwards Optional Arguments distance in meter, needs to be positive if None, unlimited movement, returns immediately if set, returns, when movement is finished, but does not stop Returns Task, which needs to be started or combined with other tasks """ assert isinstance(speed, int), \ "speed needs to be an interger" assert speed >= -100 and speed <= 100, \ "speed needs to be in range from -100 to 100 (inclusive)" assert distance is None or isinstance(distance, Number), \ "distance needs to be a number" assert distance is None or distance > 0, \ "distance needs to be positive" t = self._Drive( self._drive_straight, args=(speed, distance), action_stop=self._stop, args_stop=(False,), action_cont=self._vehicle_cont ) if distance is None: return Task(t.start) else: t.append( Repeated(self._test_pos), copy=False ) return Task(t.start, join=True)
def cont_as_task(self) -> Task: ''' continues a stopped movement Returns thread_task.Task object, which does the continuing ''' return Task(self.cont)
def test_join_03(capsys): '''stop child from outside --> no continuous joining''' ts = Timespan() t_child = Task(print_it, args=(ts, 'child'), duration=.2) t_parent = concat( Task( print_it, args=(ts, 'parent-root-link'), duration=.1 ), Task(t_child.start), Task(t_child.join), Task(print_it, args=(ts, 'parent-link-4'), duration=.1), Task(print_it, args=(ts, 'parent-finished')) ).start() sleep(.2) assert t_parent.state == STATE_STARTED assert t_parent.activity == ACTIVITY_JOIN assert t_child.state == STATE_STARTED assert t_child.activity == ACTIVITY_SLEEP t_child.stop().join() assert t_parent.state == STATE_STARTED assert t_parent.activity == ACTIVITY_SLEEP assert t_child.state == STATE_STOPPED assert t_child.activity == ACTIVITY_NONE assert len(t_parent.children) == 0 assert t_child.parent is None captured = capsys.readouterr() assert captured.err == '' assert captured.out == '0.0:parent-root-link 0.1:child 0.2:parent-link-4 ' t_parent.stop().join() assert t_parent.state == STATE_STOPPED captured = capsys.readouterr() assert captured.err == '' assert captured.out == '' sleep(.2) t_parent.cont().join() assert t_parent.state == STATE_FINISHED assert t_child.state == STATE_STOPPED captured = capsys.readouterr() assert captured.err == '' assert captured.out == '0.5:parent-finished '
def test_action_final(capsys): t = Task(print, args=('hello, world!', ), kwargs={'end': ''}) + Task( print, args=(' finished', ), kwargs={'end': ''}) t.start() t.join() captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == 'hello, world! finished'
def test_timing_03(capsys): '''stopping in state STARTED after first action (chain)''' ts = Timespan() t = concat( Task(print_it, args=(ts, 'started')), Task(print_it, args=(ts, 'hi_1'), action_stop=print_it, args_stop=(ts, 'stopped'), action_cont=print_it, args_cont=(ts, 'continued'), duration=.2), Task(print_it, args=(ts, 'hi_2'), duration=.1), Task(print_it, args=(ts, 'finished'))) t.start(.1) sleep(.05) assert t.state == STATE_TO_START assert t.activity == ACTIVITY_SLEEP sleep(.1) assert t.state == STATE_STARTED assert t.activity == ACTIVITY_SLEEP captured = capsys.readouterr() assert captured.err == '' assert captured.out == '0.1:started 0.1:hi_1 ' sleep(.05) t.stop().join() assert t.state == STATE_STOPPED assert t.activity == ACTIVITY_NONE captured = capsys.readouterr() assert captured.err == '' assert captured.out == '0.2:stopped ' sleep(.1) t.cont().join() assert t.state == STATE_FINISHED assert t.activity == ACTIVITY_NONE captured = capsys.readouterr() assert captured.err == '' assert captured.out == '0.3:continued 0.4:hi_2 0.5:finished '
def test_netto_time(): '''no argument netto_time for Sleep and Task''' with pytest.raises(AssertionError) as exc: Sleep(2, netto_time=True) assert exc.value.args[0] == \ 'no netto_time for Sleep objects' with pytest.raises(AssertionError) as exc: Task(print, netto_time=True) assert exc.value.args[0] == \ 'no netto_time for Task objects'
def test_action_stop(capsys): t = Task(print, args=('hello, world!', ), kwargs={'end': ''}, duration=.1, action_stop=print, args_stop=(' stopped', ), kwargs_stop={'end': ''}) + Task( print, args=(' finished', ), kwargs={'end': ''}) t.start() sleep(.05) t.stop() t.join() captured = capsys.readouterr() assert t.state == STATE_STOPPED assert captured.err == '' assert captured.out == 'hello, world! stopped'
def test_links_restart(): '''restart deletes parent-child links''' t_child = Task(do_nothing, duration=.1) t_parent = concat( Task(do_nothing, duration=.1), Task(t_child), Task(do_nothing, duration=.1) ).start() sleep(.15) t_parent.stop().join() assert t_parent.state == STATE_STOPPED assert t_child.state == STATE_STOPPED assert t_child in t_parent.children assert t_child.parent is t_parent t_parent.start() sleep(.05) assert t_parent.state == STATE_STARTED assert t_child.state == STATE_STOPPED assert len(t_parent.children) == 0 assert t_child.parent is None
def test_timing_01(capsys): '''stopping in state TO_START (in delay, before started)''' ts = Timespan() t = Task(print_it, args=(ts, 'started')) + Task( print_it, args=(ts, 'hello'), duration=.1) + Task( print_it, args=(ts, 'finished')) t.start(.2) sleep(.1) assert t.state == STATE_TO_START t.stop().join() assert t.state == STATE_STOPPED sleep(.1) t.cont().join() assert t.state == STATE_FINISHED captured = capsys.readouterr() assert captured.err == '' assert captured.out == '0.3:started 0.3:hello 0.4:finished '
def test_links_threadless(): '''threadless child: creation and deletion of parent-child links''' t_child = Task(do_nothing, duration=.1) t_parent = concat( Task(do_nothing, duration=.1), Task(t_child), Task(do_nothing, duration=.1) ).start() sleep(.05) assert t_child.state == STATE_INIT assert len(t_parent.children) == 0 assert t_child.parent is None sleep(.1) assert t_child.state == STATE_STARTED assert t_child in t_parent.children assert t_child.parent is t_parent sleep(.1) assert t_child.state == STATE_FINISHED assert t_parent.state == STATE_STARTED assert len(t_parent.children) == 0 assert t_child.parent is None
def drive_to( self, speed: int, pos_x: float, pos_y: float ) -> Task: """ Drive the vehicle to the given position. Keep in mind, it never stops. At the end of the movement, there must be a stop. Positional Arguments speed in percent [-100 - 100] (direction depends on its sign) positive sign: forwards negative sign: backwards pos_x x-coordinate of target position pos_y y-coordinate of target position """ assert isinstance(speed, int), "speed needs to be an integer value" assert -100 <= speed and speed <= 100, \ "speed needs to be in range [-100 - 100]" assert isinstance(pos_x, Number), "pos_x needs to be a number" assert isinstance(pos_y, Number), "pos_y needs to be a number" return Task( self._Drive( self._drive_to_1, args=(speed, pos_x, pos_y), action_stop=self._stop, args_stop=(False,), action_cont=self._vehicle_cont ).append( Repeated(self._test_o), self._Drive( self._drive_to_2, args=(speed, pos_x, pos_y), action_stop=self._stop, args_stop=(False,), action_cont=self._vehicle_cont ), Repeated(self._test_pos), copy=False ).start, join=True )
def stop_as_task(self, *, brake: bool = False) -> Task: ''' stops the current motor movement, with or without brake (can be used to release brake) Optional keyword arguments brake flag if stopping with active brake Returns thread_task.Task object, which does the stopping ''' assert isinstance(brake, bool), \ 'brake must be a boolean' return Task(self.stop, kwargs={'brake': brake})
def test_timing_00(capsys): ts = Timespan() t = Task(print_it, args=(ts, 'started')) + Task( print_it, args=(ts, 'hello'), duration=.1) + Task( print_it, args=(ts, 'finished')) t.start(.1).join() captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == '0.1:started 0.1:hello 0.2:finished '
def test_links_threadless_stop(): '''stop threadless child from outside''' t_child = Task(do_nothing, duration=.1) t_parent = concat( Task(do_nothing, duration=.1), Task(t_child), Task(do_nothing, duration=.1) ).start() sleep(.15) t_child.stop() sleep(.01) assert t_parent.state == STATE_STARTED assert t_child.state == STATE_STOPPED assert len(t_parent.children) == 0 assert t_child.parent is None t_parent.stop().join() assert t_parent.state == STATE_STOPPED
def rotate_to( self, speed: int, orientation: float ) -> Task: """ Rotate the vehicle to the given orientation. Keep in mind, it never stops. At the end of the movement, there must be a stop. Positional arguments speed in percent [-100 - 100] (direction depends on its sign) positive sign: forwards negative sign: backwards orientation in degrees, mathematical and relative to starting one positive: anti clockwise negative: clockwise Returns Task, which needs to be started or combined with other tasks """ assert isinstance(speed, int), "speed needs to be an integer value" assert -100 <= speed and speed <= 100, \ "speed needs to be in range [-100 - 100]" assert isinstance(orientation, Number), \ "orientation needs to be a number" return Task( self._Drive( self._rotate_to, args=(speed, orientation), action_stop=self._stop, args_stop=(False,), action_cont=self._vehicle_cont ).append( Repeated(self._test_o), copy=False ).start, join=True )
def test_num(capsys): '''argument num only for Repeated and Periodic''' with pytest.raises(AssertionError) as exc: Task(print, num=2) assert exc.value.args[0] == \ 'no num for Task objects' with pytest.raises(AssertionError) as exc: Sleep(print, num=2) assert exc.value.args[0] == \ 'no num for Sleep objects' Periodic(1, print, num=2) captured = capsys.readouterr() assert captured.err == '' assert captured.out == '' Repeated(print, num=2) captured = capsys.readouterr() assert captured.err == '' assert captured.out == ''
def test_action_cont(capsys): # with duration t = Task(print, args=('hello, world!', ), kwargs={'end': ''}, duration=.1, action_stop=print, args_stop=(' stopped', ), kwargs_stop={'end': ''}, action_cont=print, args_cont=(' continued', ), kwargs_cont={'end': ''}) + Task( print, args=(' finished', ), kwargs={'end': ''}) t.start().stop() t.join() assert t.state == STATE_STOPPED t.cont().join() captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == 'hello, world! stopped continued finished' # without duration t = Task(print, args=('hello, world!', ), kwargs={'end': ''}, action_stop=print, args_stop=(' stopped', ), kwargs_stop={'end': ''}, action_cont=print, args_cont=(' continued', ), kwargs_cont={'end': ''}) + Task( print, args=(' finished', ), kwargs={'end': ''}) t.start().stop() t.join() assert t.state == STATE_FINISHED t.cont().join() captured = capsys.readouterr() assert t.state == STATE_FINISHED assert captured.err == '' assert captured.out == 'hello, world! finished'