예제 #1
0
def test_scrolling():
    text = teek.Text(teek.Window())
    asd = []

    def callback(x, y):
        asd.extend([x, y])

    text.config['yscrollcommand'].connect(callback)
    text.insert(text.end, 'toot\ntoot\n' * text.config['height'])

    # scroll to end, and make sure everything is visible
    text.yview('moveto', 1)
    text.pack()
    teek.update()

    # this fails consistently in travis for some reason, but if i run this
    # locally in xvfb-run, it works fine 0_o
    if 'CI' not in os.environ:
        assert round(asd[-2], 1) == 0.5
        assert asd[-1] == 1.0

    # yview return type checks
    assert text.yview('moveto', 1) is None
    pair = text.yview()
    assert isinstance(pair, tuple) and len(pair) == 2
    assert all(isinstance(item, float) for item in pair)
예제 #2
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>'
예제 #3
0
def test_image_doesnt_load_without_threads():
    souper, widget = create_souped_widget(big_html, threads=False)
    assert 'firefox pic alt' in widget.get()

    end = time.time() + 0.5
    while time.time() < end:
        teek.update()
    assert 'firefox pic alt' in widget.get()
예제 #4
0
def test_image_loads_with_threads(deinit_threads):
    teek.init_threads()
    souper, widget = create_souped_widget(big_html)   # threads=True is default

    assert 'firefox pic alt' in widget.get()
    time.sleep(1)   # this used to be 0.1 and it made tests fail randomly
    teek.update()
    assert 'firefox pic alt' not in widget.get()
예제 #5
0
def test_image_loads_with_threads(deinit_threads):
    teek.init_threads()
    souper, widget = create_souped_widget(big_html)  # threads=True is default

    assert 'firefox pic alt' in widget.get()
    time.sleep(0.1)
    teek.update()
    assert 'firefox pic alt' not in widget.get()
예제 #6
0
def test_bind_break():
    events = []
    widget = teek.Window()
    widget.bind('<<Asd>>', (lambda: events.append('one')))
    widget.bind('<<Asd>>', (lambda: [events.append('two'), 'break'][1]))  # lol
    widget.bind('<<Asd>>', (lambda: events.append('three')))

    teek.update()  # needed for virtual events to work
    widget.event_generate('<<Asd>>')
예제 #7
0
def test_see():
    text = teek.Text(teek.Window())
    for i in range(1, 1000):
        text.insert(text.end, 'toot %d\n' % i)

    teek.update()
    yview1 = text.yview()
    text.see(text.end)
    teek.update()
    yview2 = text.yview()
    assert max(yview1) < 0.5 and min(yview2) > 0.5
예제 #8
0
def test_weird_error(capfd):
    # make sure that previous tests don't mess up
    teek.after_idle(teek.quit)
    teek.run()

    # ignore anything that ended up in the stderr because previous tests
    # TODO: why is stderr SOMETIMES non-empty??
    capfd.readouterr()

    teek.create_command(print)
    # the command is intentionally not deleted
    teek.quit()
    teek.update()
    assert capfd.readouterr() == ('', '')
예제 #9
0
def test_destroy_event_bug(handy_callback):
    for gonna_update_in_between in [True, False]:
        frame = teek.Frame(teek.Window())

        @handy_callback
        def on_destroy():
            pass

        frame.bind('<Destroy>', on_destroy)
        if gonna_update_in_between:
            teek.update()

        frame.destroy()
        assert on_destroy.ran_once()
        teek.update()
예제 #10
0
    def func(monkeypatch, handy_callback):
        @handy_callback
        def fake_run():
            pass

        with monkeypatch.context() as monkey:
            monkey.setattr(teek, 'run', fake_run)
            exec(code, {'__file__': os.path.join(EXAMPLES_DIR, filename)})

        assert fake_run.ran_once()

        # make sure that nothing breaks if the real .run() is called
        teek.update()
        teek.after_idle(teek.quit)
        teek.run()
예제 #11
0
def test_event_objects():
    events = []

    widget = teek.Window()
    widget.bind('<<Asd>>', events.append, event=True)
    teek.update()  # needed for virtual events to work
    widget.event_generate('<<Asd>>', data='asd asd')
    event = events.pop()
    assert not events

    # if some of these checks fail, feel free to make them less strict
    assert event.data(str) == 'asd asd'
    assert event.above is None
    assert event.borderwidth is None
    assert event.button is None
    assert event.char == '??'
    assert event.count is None
    assert event.delta is None
    assert event.focus is None
    assert event.height is None
    assert isinstance(event.i_window, int)
    assert event.keycode is None
    assert event.keysym == '??'
    assert event.keysym_num is None
    assert event.mode == '??'
    assert event.override is None
    assert event.place == '??'
    assert event.property_name == '??'
    assert event.root == 0
    assert event.rootx == -1
    assert event.rooty == -1
    assert event.sendevent is False
    assert isinstance(event.serial, int)
    assert event.state == '0'
    assert event.subwindow == 0
    assert event.time == 0
    assert event.type == 35  # see some docs somewhere i dunno why 35
    assert event.widget is widget
    assert event.width is None
    assert event.x == 0
    assert event.y == 0

    regex = r"<Event: data='asd asd', serial=\d+, type=35>"
    assert re.fullmatch(regex, repr(event)) is not None
예제 #12
0
def test_winfo_x_y_rootx_rooty_width_height_reqwidth_reqheight():
    # layout in the window looks like this:
    #     ________
    #    |        |
    #    |        |
    #    |        |
    #    |        |456px
    #    |        |
    #    |        |
    #    |________|___
    #      123px  | a |
    #             `---'
    window = teek.Window()
    spacer = teek.Frame(window, width=123, height=456)
    spacer.grid(row=1, column=1)
    label = teek.Label(window, text='a')
    label.grid(row=2, column=2)
    window.geometry(100, 200)
    teek.update()

    assert window.toplevel.winfo_x() == window.toplevel.winfo_rootx()
    assert window.toplevel.winfo_y() == window.toplevel.winfo_rooty()
    assert window.toplevel.winfo_width() == 100
    assert window.toplevel.winfo_height() == 200
    assert window.toplevel.winfo_reqwidth() > 123
    assert window.toplevel.winfo_reqheight() > 456

    assert spacer.winfo_x() == 0
    assert spacer.winfo_y() == 0
    assert spacer.winfo_rootx() == window.toplevel.winfo_x()
    assert spacer.winfo_rooty() == window.toplevel.winfo_y()
    assert spacer.winfo_width() == 123
    assert spacer.winfo_height() == 456
    assert spacer.winfo_reqwidth() == 123
    assert spacer.winfo_reqheight() == 456

    assert label.winfo_x() == 123
    assert label.winfo_y() == 456
    assert label.winfo_rootx() == window.toplevel.winfo_x() + 123
    assert label.winfo_rooty() == window.toplevel.winfo_y() + 456
    assert label.winfo_width() > 0
    assert label.winfo_height() > 0
    assert label.winfo_reqwidth() > 0
    assert label.winfo_reqheight() > 0
예제 #13
0
def test_window():
    windows = [
        (teek.Window("hello hello"), "hello hello"),
        (teek.Window(), None),
    ]

    for window, default_title in windows:
        assert window.winfo_toplevel() is window.toplevel
        assert isinstance(window.toplevel, teek.Toplevel)
        teek.update()  # you can add more of these if the tests don't work

        assert window.wm_state == 'normal'
        if default_title is not None:
            assert window.title == default_title
            assert repr(default_title) in repr(window)

        window.title = "hello hello"
        assert window.title == "hello hello"

    not_a_window = teek.Frame(teek.Window())
    assert not hasattr(not_a_window, 'title')
예제 #14
0
def test_bind_class(handy_callback):
    @handy_callback
    def class_callback():
        pass

    @handy_callback
    def all_callback():
        pass

    teek.Text.bind_class('<<Lol>>', class_callback)
    teek.Widget.bind_class('<<Lol>>', all_callback)

    text = teek.Text(teek.Window())
    text.pack()
    teek.update()  # make sure that virtual events work
    text.event_generate('<<Lol>>')

    assert class_callback.ran_once()
    assert all_callback.ran_once()

    class FunnyWidget(teek.Widget):
        pass

    with pytest.raises(AttributeError) as error:
        text.class_bindings

    assert str(error.value) == (
        "the class_bindings attribute must be used like Text.class_bindings, "
        "not like some_text_instance.class_bindings")

    with pytest.raises(AttributeError) as error2:
        FunnyWidget.class_bindings

    with pytest.raises(AttributeError) as error3:
        FunnyWidget.bind_class('<<Lol>>', print)

    assert str(error2.value) == str(error3.value) == (
        "FunnyWidget cannot be used with class_bindings and bind_class()")
예제 #15
0
def test_window_states():
    window = teek.Window()
    for method, state in [(window.withdraw, 'withdrawn'),
                          (window.iconify, 'iconic')]:
        method()
        teek.update()
        assert window.wm_state == state
        assert ("wm_state='%s'" % state) in repr(window)
        window.deiconify()
        teek.update()
        assert window.wm_state == 'normal'
        assert "wm_state='normal'" not in repr(window)

        window.wm_state = state  # should do same as method()
        teek.update()
        assert window.wm_state == state
        window.deiconify()
        teek.update()
        assert window.wm_state == 'normal'
예제 #16
0
def test_winfo_ismapped():
    window = teek.Window()
    teek.update()
    assert window.winfo_ismapped() is True

    frame = teek.Frame(window)
    assert frame.winfo_ismapped() is False
    teek.update()
    assert frame.winfo_ismapped() is False

    frame.pack()
    teek.update()
    assert frame.winfo_ismapped() is True
예제 #17
0
def test_geometry_changes():
    window = teek.Window()

    window.geometry(300, 400)
    teek.update()
    assert window.geometry()[:2] == (300, 400)

    window.geometry(x=123, y=456)
    teek.update()
    assert window.geometry() == (300, 400, 123, 456)

    window.geometry(100, 200, 300, 400)
    teek.update()
    assert window.geometry() == (100, 200, 300, 400)
예제 #18
0
def run_event_loop(for_how_long):
    # this is dumb
    start = time.time()
    while time.time() < start + for_how_long:
        teek.update()
예제 #19
0
def test_update_idletasks(fake_command):
    with fake_command('update') as called:
        teek.update(idletasks_only=True)
        assert called == [['idletasks']]