Beispiel #1
0
def test_bind(handy_callback):
    widget = teek.Window()
    assert not widget.bindings.keys()

    @handy_callback
    def tcl_call_bound_callback():
        pass

    @handy_callback
    def teek_bound_callback():
        pass

    command = teek.create_command(tcl_call_bound_callback)

    teek.tcl_call(None, 'bind', widget, '<<Asd>>', command)
    assert widget.bindings.keys() == {'<<Asd>>'}
    widget.bind('<<Asd>>', teek_bound_callback)
    teek.update()
    teek.tcl_call(None, 'event', 'generate', widget, '<<Asd>>')

    teek.delete_command(command)

    assert tcl_call_bound_callback.ran_once()  # tests binding with +
    assert teek_bound_callback.ran_once()

    # some binding strings are equivalent
    assert widget.bindings['<Button-3>'] is widget.bindings['<Button-3>']
    assert widget.bindings['<3>'] is widget.bindings['<Button-3>']

    assert repr(widget.bindings) == '<a bindings object, behaves like a dict>'
Beispiel #2
0
def test_delete_command():
    result = []
    command = teek.create_command(result.append, [int])
    teek.tcl_call(None, command, '123')
    assert result == [123]

    teek.delete_command(command)
    with pytest.raises(teek.TclError):
        teek.tcl_call(None, command, '123')
Beispiel #3
0
    def cancel(self):
        """Prevent this timeout from running as scheduled.

        :exc:`RuntimeError` is raised if the timeout has already ran or
        it has been cancelled.

        There is example code in :source:`examples/timeout.py`.
        """
        if self._state != 'pending':
            raise RuntimeError("cannot cancel a %s timeout" % self._state)
        teek.tcl_call(None, 'after', 'cancel', self._id)
        self._state = 'cancelled'
        teek.delete_command(self._tcl_command)
Beispiel #4
0
    def destroy(self):
        """Delete this widget and all child widgets.

        Manual page: :man:`destroy(3tk)`

        .. note::
            Don't override this in a subclass. In some cases, the widget is
            destroyed without a call to this method.

            >>> class BrokenFunnyLabel(teek.Label):
            ...     def destroy(self):
            ...         print("destroying")
            ...         super().destroy()
            ...
            >>> BrokenFunnyLabel(teek.Window()).pack()
            >>> teek.quit()
            >>> # nothing was printed!

            Use the ``<Destroy>`` event instead:

            >>> class WorkingFunnyLabel(teek.Label):
            ...     def __init__(self, *args, **kwargs):
            ...         super().__init__(*args, **kwargs)
            ...         self.bind('<Destroy>', self._destroy_callback)
            ...     def _destroy_callback(self):
            ...         print("destroying")
            ...
            >>> WorkingFunnyLabel(teek.Window()).pack()
            >>> teek.quit()
            destroying
        """
        for name in self._call([str], 'winfo', 'children', self):
            # allow overriding the destroy() method if the widget was
            # created by teek
            if name in _widgets:
                _widgets[name]._destroy_recurser()
            else:
                self._call(None, 'destroy', name)

        # this must be BEFORE deleting command_list commands because <Destroy>
        # bindings may need command_list stuff
        self._call(None, 'destroy', self)

        # this is here because now the widget is basically useless
        del _widgets[self.to_tcl()]

        for command in self.command_list:
            teek.delete_command(command)
        self.command_list.clear()  # why not
Beispiel #5
0
def test_create_command(capsys):
    def working_func():
        # no type checking is done, this turns into a dict below
        return CustomSequence()

    command = teek.create_command(working_func)

    assert teek.tcl_call({'a b c': int}, command) == {'a b c': 123}
    assert capsys.readouterr() == ('', '')

    teek.tcl_call(None, command, 'asda')
    output, errors = capsys.readouterr()
    assert not output
    assert errors.endswith(
        "TypeError: expected 0 arguments, got 1 arguments\n")

    teek.delete_command(command)

    def broken_func(arg1):
        if arg1 == 'lol':
            print('it works')
        else:
            print('it doesnt works :(', arg1)
        raise RuntimeError("oh noes")

    command = teek.create_command(broken_func, [str])
    assert teek.tcl_call(str, command, 'lol') == ''
    teek.delete_command(command)

    output, errors = capsys.readouterr()
    assert output == 'it works\n'
    assert 'raise RuntimeError("oh noes")' in errors

    def create_the_command():
        return teek.create_command(broken_func, [str])

    command = create_the_command()
    assert teek.tcl_call(str, command, 'lol') == ''
    teek.delete_command(command)

    output, errors = capsys.readouterr()
    assert output == 'it works\n'
    assert 'raise RuntimeError("oh noes")' in errors
    assert 'command = create_the_command()' in errors
    assert 'return teek.create_command(broken_func, [str])' in errors

    # test return values
    def lel():
        return (True, 3, ['a', 'b', 'c'])

    command = teek.create_command(lel)
    assert (teek.tcl_call((bool, int, [str]), command) ==
            (True, 3, ['a', 'b', 'c']))
    teek.delete_command(command)

    assert capsys.readouterr() == ('', '')
Beispiel #6
0
    def faker(name, return_value=None):
        called = []

        def command_func(*args):
            called.append(list(args))
            return return_value

        fake = teek.create_command(command_func, [], extra_args_type=str)

        teek.tcl_call(None, 'rename', name, name + '_real')
        try:
            teek.tcl_call(None, 'rename', fake, name)
            yield called
        finally:
            try:
                teek.delete_command(name)
            except teek.TclError:
                pass
            teek.tcl_call(None, 'rename', name + '_real', name)
Beispiel #7
0
    def _run(self):
        needs_cleanup = True

        # this is important, thread tests freeze without this special
        # case for some reason
        def quit_callback():
            nonlocal needs_cleanup
            needs_cleanup = False

        teek.before_quit.connect(quit_callback)

        try:
            self._callback(*self._args, **self._kwargs)
            self._state = 'successfully completed'
        except Exception as e:
            self._state = 'failed'
            raise e
        finally:
            teek.before_quit.disconnect(quit_callback)
            if needs_cleanup:
                teek.delete_command(self._tcl_command)
Beispiel #8
0
def test_screen_distances():
    assert teek.ScreenDistance(123).pixels == 123
    assert teek.ScreenDistance('123').pixels == 123
    assert round(teek.ScreenDistance(123).fpixels, 3) == 123.0
    assert round(teek.ScreenDistance('123').fpixels, 3) == 123.0

    assert teek.ScreenDistance(123) == teek.ScreenDistance('123')
    assert hash(teek.ScreenDistance(123)) == hash(teek.ScreenDistance('123'))

    inch = teek.ScreenDistance('1i')
    centimeter = teek.ScreenDistance('1c')
    pixel = teek.ScreenDistance(1)
    assert round(inch.fpixels / centimeter.fpixels, 2) == 2.54

    assert repr(inch) == "ScreenDistance('1i')"
    assert repr(centimeter) == "ScreenDistance('1c')"
    assert repr(pixel) == "ScreenDistance('1')"

    assert inch.to_tcl() == '1i'
    assert centimeter.to_tcl() == '1c'
    assert pixel.to_tcl() == '1'

    assert inch != centimeter
    assert inch > centimeter

    assert inch != 'asd'
    assert inch != '1i'
    with pytest.raises(TypeError):
        inch < '1i'

    teek.tcl_eval(None, 'proc returnArg {arg} {return $arg}')
    try:
        assert teek.tcl_eval(teek.ScreenDistance, 'returnArg 1i') == inch
        assert teek.tcl_eval(teek.ScreenDistance, 'returnArg 1c') == centimeter
        assert teek.tcl_eval(teek.ScreenDistance, 'returnArg 1') == pixel
    finally:
        teek.delete_command('returnArg')

    with pytest.raises(teek.TclError):
        teek.ScreenDistance('asdf asdf')
Beispiel #9
0
def handy_commands():
    teek.tcl_eval(None, 'proc returnArg {arg} { return $arg }')
    teek.tcl_eval(None, 'proc returnEmptyString {} {}')
    yield
    teek.delete_command('returnArg')
    teek.delete_command('returnEmptyString')