def test_move(): notebook = teek.Notebook(teek.Window()) tab1 = teek.NotebookTab(teek.Label(notebook, text="one")) tab2 = teek.NotebookTab(teek.Label(notebook, text="two")) notebook.extend([tab1, tab2]) notebook.move(tab2, 0) assert list(notebook) == [tab2, tab1] notebook.move(tab2, 0) assert list(notebook) == [tab2, tab1] notebook.move(tab1, 0) assert list(notebook) == [tab1, tab2] notebook.move(tab1, 1) assert list(notebook) == [tab2, tab1] notebook.move(tab1, -1) # some_list[-1] is last item assert list(notebook) == [tab2, tab1] notebook.move(tab1, -2) assert list(notebook) == [tab1, tab2] with pytest.raises(IndexError): notebook.move(tab1, 2) with pytest.raises(IndexError): notebook.move(tab1, -3) tab3 = teek.NotebookTab(teek.Label(notebook, text="three")) with pytest.raises(ValueError): notebook.move(tab3, 0)
def test_options(): window = teek.Window() for widget in [teek.Button(window), teek.Label(window)]: assert 'behaves like a dict' in repr(widget.config) assert len(widget.config) == len(list(widget.config)) # abbreviations aren't allowed, it simplifies the implementation # and people aren't aware of abbreviating things in tk anyway assert 'text' in widget.config assert 'tex' not in widget.config with pytest.raises(KeyError): widget.config['tex'] with pytest.raises(TypeError): widget.config.pop('text') # buttons are tested below, this makes sure that windows and # labels don't do something weird when they get an option that # they shouldn't support if not isinstance(widget, teek.Button): with pytest.raises(KeyError): widget.config['command'] = print widget1 = teek.Label(window, 'lol') widget1.config.update({'text': 'asd'}) widget2 = teek.Label(window, text='asd') assert widget1.config == widget2.config widget2.config['text'] = 'tootie' assert widget1.config != widget2.config
def test_insert_with_different_indexes(): notebook = teek.Notebook(teek.Window()) notebook.insert(0, teek.NotebookTab(teek.Label(notebook, "1"))) notebook.insert(1, teek.NotebookTab(teek.Label(notebook, "2"))) notebook.insert(10, teek.NotebookTab(teek.Label(notebook, "3"))) notebook.insert(-10, teek.NotebookTab(teek.Label(notebook, "0"))) assert [tab.widget.config['text'] for tab in notebook] == list('0123')
def test_moves_only(): notebook = teek.Notebook(teek.Window()) tab1 = teek.NotebookTab(teek.Label(notebook, text="1"), text="One") tab2 = teek.NotebookTab(teek.Label(notebook, text="2"), text="Two") notebook.extend([tab1, tab2]) tab1.config['text'] = 'wut1' tab2.config['text'] = 'wut2' notebook.insert(1, notebook[0]) assert tab1.config['text'] == 'wut1' assert tab2.config['text'] == 'wut2' assert list(notebook) != [tab1, tab2] assert list(notebook) == [tab2, tab1]
def test_label(): window = teek.Window() label = teek.Label(window) assert "text=''" in repr(label) assert label.config['text'] == '' label.config.update({'text': 'new text'}) assert label.config['text'] == 'new text' assert "text='new text'" in repr(label) label2 = teek.Label(window, 'new text') assert label.config == label2.config
def test_in_use(): image = teek.Image(file=SMILEY_PATH) assert image.in_use() is False window = teek.Window() assert image.in_use() is False widget = teek.Label(window, image=image) assert image.in_use() is True widget2 = teek.Label(window, image=image) assert image.in_use() is True widget.destroy() assert image.in_use() is True widget2.destroy() assert image.in_use() is False
def test_selected_tab(): notebook = teek.Notebook(teek.Window()) tab1 = teek.NotebookTab(teek.Label(notebook, text="one")) tab2 = teek.NotebookTab(teek.Label(notebook, text="two")) notebook.extend([tab1, tab2]) assert notebook.selected_tab is tab1 notebook.selected_tab = tab2 assert notebook.selected_tab is tab2 notebook.selected_tab = tab2 # intentionally repeated assert notebook.selected_tab is tab2 notebook.clear() assert notebook.selected_tab is None
def test_reprs(): notebook = teek.Notebook(teek.Window()) label = teek.Label(notebook, "asd") label2 = teek.Label(notebook, "asdasd") tab = teek.NotebookTab(label, text='toot') tab2 = LolTab(label2, text='toot toot') assert repr(tab) == "NotebookTab(" + repr(label) + ", text='toot')" assert repr(tab2) == "LolTab(" + repr(label2) + ", text='toot toot')" assert repr(notebook) == '<teek.Notebook widget: contains 0 tabs>' notebook.append(tab) assert repr(notebook) == '<teek.Notebook widget: contains 1 tabs>' notebook.remove(tab) assert repr(notebook) == '<teek.Notebook widget: contains 0 tabs>'
def test_config_types(check_config_types): notebook = teek.Notebook(teek.Window()) check_config_types(notebook.config, 'Notebook') tab = teek.NotebookTab(teek.Label(notebook, "asd")) notebook.append(tab) check_config_types(tab.config, 'NotebookTab')
def test_grid_row_and_column_objects(check_config_types): window = teek.Window() assert window.grid_rows == [] assert window.grid_columns == [] # a new list is created every time assert window.grid_rows is not window.grid_rows assert window.grid_rows == window.grid_rows label = teek.Label(window) label.grid() for rows_columns in [window.grid_rows, window.grid_columns]: assert isinstance(rows_columns, list) assert len(rows_columns) == 1 row_column = rows_columns[0] assert row_column.get_slaves() == [label] check_config_types(row_column.config, 'grid row or column object') row_column.config['weight'] = 4 assert isinstance(row_column.config['weight'], float) assert row_column.config['weight'] == 4.0 assert row_column == row_column assert row_column != 'toot' assert {row_column: 'woot'}[row_column] == 'woot'
def test_destroy(): window = teek.Window() label = teek.Label(window) frame = teek.Frame(window) button = teek.Button(frame) widgets = [window, label, button] command = teek.create_command(print, str) label.command_list.append(command) assert teek.tcl_call([str], 'info', 'commands', command) == [command] assert window.winfo_children() == [label, frame] assert frame.winfo_children() == [button] for widget in widgets: assert widget.winfo_exists() window.destroy() for widget in widgets: assert not widget.winfo_exists() assert repr(widget).startswith('<destroyed ') assert teek.tcl_call([str], 'info', 'commands', command) == [] with pytest.raises(RuntimeError) as error: label.config['text'] = 'lel' assert str(error.value) == 'the widget has been destroyed'
def test_insert_errors(): window = teek.Window() notebook1 = teek.Notebook(window) label1 = teek.Label(notebook1, text="one") notebook2 = teek.Notebook(window) tab2 = teek.NotebookTab(teek.Label(notebook2, text="two")) with pytest.raises(ValueError) as error: notebook1.append(tab2) assert (repr(notebook2) + "'s tab") in str(error.value) assert str(error.value).endswith('to ' + repr(notebook1)) # i imagine this will be a common mistake, so better be prepared to it with pytest.raises(TypeError) as error: notebook1.append(label1) assert str(error.value).startswith('expected a NotebookTab object')
def test_place_special_error(): label = teek.Label(teek.Window()) with pytest.raises(TypeError) as error: label.place() assert str(error.value).startswith( "cannot call widget.place() without any arguments, do e.g. ")
def test_tab_added_with_tcl_call_so_notebooktab_object_is_created_automagic(): notebook = teek.Notebook(teek.Window()) label = teek.Label(notebook) teek.tcl_call(None, notebook, 'add', label) # looking up notebook[0] should create a new NotebookTab object assert isinstance(notebook[0], teek.NotebookTab) assert notebook[0] is notebook[0] # and it should be "cached" now
def test_get_tab_by_widget_error(): notebook = teek.Notebook(teek.Window()) with pytest.raises(ValueError) as error: notebook.get_tab_by_widget(teek.Label(teek.Window(), text='lol')) assert str( error.value) == ("expected a widget with the notebook as its parent, " "got <teek.Label widget: text='lol'>")
def test_list_like_behaviour(): notebook = teek.Notebook(teek.Window()) tab1 = teek.NotebookTab(teek.Label(notebook, "1")) tab2 = teek.NotebookTab(teek.Label(notebook, "2")) tab3 = teek.NotebookTab(teek.Label(notebook, "3")) tab4 = teek.NotebookTab(teek.Label(notebook, "4")) tab5 = teek.NotebookTab(teek.Label(notebook, "5")) notebook.append(tab3) notebook.extend([tab4, tab5]) notebook.insert(0, tab1) notebook.insert(1, tab2) assert list(notebook) == [tab1, tab2, tab3, tab4, tab5] assert notebook.pop() == tab5 assert list(notebook) == [tab1, tab2, tab3, tab4] notebook[0] = tab5 assert list(notebook) == [tab5, tab2, tab3, tab4]
def test_hide_unhide_preserve_order(): notebook = teek.Notebook(teek.Window()) tabs = [teek.NotebookTab(teek.Label(notebook, str(n))) for n in [1, 2, 3]] notebook.extend(tabs) assert list(notebook) == tabs tabs[1].hide() assert list(notebook) == tabs tabs[1].unhide() assert list(notebook) == tabs
def test_basic_repr_stuff(monkeypatch): monkeypatch.syspath_prepend(DATA_DIR) import subclasser window = teek.Window() frame = teek.Frame(window) label1 = teek.Label(window, text='a') label2 = subclasser.LolLabel(window, text='b') assert repr(label1) == "<teek.Label widget: text='a'>" assert repr(label2) == "<subclasser.LolLabel widget: text='b'>" assert repr(frame) == "<teek.Frame widget>"
def test_place(): window = teek.Window() button = teek.Button(window) button.place(x=123, rely=0.5) place_info = button.place_info() assert place_info['anchor'] == 'nw' assert place_info['bordermode'] == 'inside' assert place_info['in'] is window assert place_info['x'] == teek.ScreenDistance(123) assert place_info['rely'] == 0.5 assert isinstance(place_info['relx'], float) assert isinstance(place_info['rely'], float) assert isinstance(place_info['x'], teek.ScreenDistance) assert isinstance(place_info['y'], teek.ScreenDistance) assert place_info['width'] is None assert place_info['height'] is None assert place_info['relwidth'] is None assert place_info['relheight'] is None button.place_forget() assert button.place_info() == {} button.place(**place_info) assert button.place_info() == place_info button.place_forget() assert window.place_slaves() == [] label1 = teek.Label(window, 'label one') label1.place(x=1) label2 = teek.Label(window, 'label two') label2.place(x=2) assert set(window.place_slaves()) == {label1, label2} # allow any order frame = teek.Frame(window) label2.place(in_=frame) assert window.place_slaves() == [label1] assert frame.place_slaves() == [label2]
def test_pack(): window = teek.Window() button = teek.Button(window) button.pack(fill='both', expand=True) pack_info = button.pack_info() assert pack_info['in'] is window assert pack_info['side'] == 'top' assert pack_info['fill'] == 'both' assert pack_info['expand'] is True assert pack_info['anchor'] == 'center' for option in ['padx', 'pady']: assert isinstance(pack_info[option], list) assert len(pack_info[option]) in {1, 2} for item in pack_info[option]: assert isinstance(item, teek.ScreenDistance) for option in ['ipadx', 'ipady']: assert isinstance(pack_info[option], teek.ScreenDistance) button.pack_forget() with pytest.raises(teek.TclError): button.pack_info() button.pack(**pack_info) assert button.pack_info() == pack_info button.pack_forget() assert window.pack_slaves() == [] label1 = teek.Label(window, 'label one') label1.pack() label2 = teek.Label(window, 'label two') label2.pack() assert window.pack_slaves() == [label1, label2] frame = teek.Frame(window) label2.pack(in_=frame) assert window.pack_slaves() == [label1] assert frame.pack_slaves() == [label2]
def test_initial_options(): notebook = teek.Notebook(teek.Window()) tab = teek.NotebookTab(teek.Label(notebook)) with pytest.raises(RuntimeError): tab.config['text'] = 'lol' with pytest.raises(RuntimeError): tab.config['text'] assert tab.initial_options == {} tab.initial_options['text'] = 'lol' notebook.append(tab) assert tab.config['text'] == 'lol'
def test_notebooktab_init_errors(): notebook = teek.Notebook(teek.Window()) label = teek.Label(notebook) lel_widget = teek.Window() with pytest.raises(ValueError) as error: teek.NotebookTab(lel_widget) assert ('widgets of NotebookTabs must be child widgets of a Notebook' in str(error.value)) teek.NotebookTab(label) with pytest.raises(RuntimeError) as error: teek.NotebookTab(label) assert 'there is already a NotebookTab' in str(error.value)
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
def all_widgets(): window = teek.Window() return [ teek.Button(window), teek.Checkbutton(window), teek.Combobox(window), teek.Entry(window), teek.Frame(window), teek.Label(window), teek.LabelFrame(window), teek.Notebook(window), teek.Menu(), teek.Progressbar(window), teek.Scrollbar(window), teek.Separator(window), teek.Spinbox(window), teek.Text(window), teek.Toplevel(), window, ]
def __init__(self, title, text, entry_creator, validator, initial_value, parent): self.validator = validator self.window = teek.Window(title) self.window.on_delete_window.connect(self.on_cancel) if parent is not None: self.window.transient = parent self.var = teek.StringVar() teek.Label(self.window, text).grid(row=0, column=0, columnspan=2) entry = entry_creator(self.window) entry.config['textvariable'] = self.var entry.grid(row=1, column=0, columnspan=2) entry.bind('<Return>', self.on_ok) entry.bind('<Escape>', self.on_cancel) self.ok_button = teek.Button(self.window, "OK", self.on_ok) self.ok_button.grid(row=3, column=0) teek.Button(self.window, "Cancel", self.on_cancel).grid(row=3, column=1) self.window.grid_rows[0].config['weight'] = 1 self.window.grid_rows[2].config['weight'] = 1 for column in self.window.grid_columns: column.config['weight'] = 1 self.result = None self.var.write_trace.connect(self.on_var_changed) self.var.set(initial_value) self.on_var_changed(self.var) # TODO: is this needed? # TODO: add a way to select stuff to teek self.window.geometry(300, 150) entry.focus() teek.tcl_call(None, entry, 'selection', 'range', '0', 'end')
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.label = teek.Label(self) self.label.pack() self.updater_callback()
def __init__(self, window, bus, queue, *args, **kwargs): super().__init__(window, *args, **kwargs) self._bus = bus self._queue = queue def say_hello(): print("Hello.") def toggle_listener(): self._bus.emit("toggle_listener") frame = teek.Frame(window) frame.grid(column=0, row=0) """LABELS""" label_font_setting = ('Helvetica', 16) target1 = teek.Label(frame, text="Target 1 coordinates: ") target1.config['font'] = label_font_setting target1.grid(column=1, row=2, sticky="W", padx=20, pady=5) target2 = teek.Label(frame, text="Target 2 coordinates: ") target2.config['font'] = label_font_setting target2.grid(column=1, row=3, sticky="W", padx=20, pady=5) item_target = teek.Label(frame, text="Target Item coordinates: ") item_target.config['font'] = label_font_setting item_target.grid(column=1, row=4, sticky="W", padx=20, pady=5) stat_tier = teek.Label(frame, text="Minimum Stat Tier: ") stat_tier.config['font'] = label_font_setting stat_tier.grid(column=1, row=5, sticky="W", padx=20, pady=5) max_iterations = teek.Label(frame, text="Max # of iterations: ") max_iterations.config['font'] = label_font_setting max_iterations.grid(column=1, row=6, sticky="W", padx=20, pady=5) target_1_limit = teek.Label(frame, "Target 1 currency limit: ") target_1_limit.config['font'] = label_font_setting target_1_limit.grid(column=5, row=2, sticky="W", padx=20, pady=5) target_2_limit = teek.Label(frame, "Target 2 currency limit: ") target_2_limit.config['font'] = label_font_setting target_2_limit.grid(column=5, row=3, sticky="W", padx=20, pady=5) status_label = teek.Label(frame, text="Program Status Updates: ") status_label.config['font'] = label_font_setting status_label.grid(column=8, row=1, columnspan=2, sticky="WS", pady=5) # Cycles current_cycle_num = teek.IntVar() current_cycle_num.set(0) cycle_number_label = teek.Label(frame, "Current Cycle: ") cycle_number_label.config['font'] = label_font_setting cycle_number_label.grid( column=8, row=7, sticky="WS") cycle_number_count = teek.Label(frame, text=current_cycle_num.get()) cycle_number_count.grid( column=9, row=7, sticky="WS") """VARIABLES""" """ To use variables, you can't just try to manually assign them like you would normally in Python. a = 10 won't work. In the case of a, you'd need to write a.set(new_value) because we're technically using a subclass of TclVariable. We need to use the getter/setter methods to access and modify data stored in each object instance. """ # Do I even need these? If I'm already storing these as a tuple in the preset, I might not need this. t1_x_var = teek.FloatVar() t1_y_var = teek.FloatVar() t1_var_tuple = (t1_x_var, t1_y_var) t2_x_var = teek.FloatVar() t2_y_var = teek.FloatVar() t2_var_tuple = (t2_x_var, t2_y_var) target_item_x = teek.FloatVar() target_item_y = teek.FloatVar() target_item_tuple = (target_item_x, target_item_y) # I may want to define the defaults inside the Preset class. # These presets are more of a data attribute that should be handled elsewhere. t1_limit_var = teek.IntVar() t1_limit_var.set(5000) t2_limit_var = teek.IntVar() t2_limit_var.set(5000) item_stat_tier = teek.IntVar() item_stat_tier.set(1) stat_tier_entry = teek.Entry(frame, text=item_stat_tier.get()) stat_tier_entry.grid(column=2, row=5, sticky="W") max_iterations = teek.IntVar() max_iterations.set(5000) set_preset_name_label = teek.Label(frame, text="Set Preset Name: ") set_preset_name_label.grid(column=5, row=6, sticky="W") set_preset_name = teek.StringVar() """BUTTONS""" target_1_set = teek.Button( frame, text="Set target 1 (x,y)", width=15, command=toggle_listener) target_1_set.grid(column=3, row=2, sticky="W", padx=3) target_2_set = teek.Button( frame, text="Set target 2 (x,y)", width=15, command=say_hello) target_2_set.grid(column=3, row=3, sticky="W", padx=3) item_target_set = teek.Button( frame, text="Set item target (x,y)", width=15, command=say_hello) item_target_set.grid(column=3, row=4, sticky="W", padx=3) """INPUT FIELDS""" # Will need to BIND these. max_iteration_input = teek.Entry(frame, text=max_iterations.get()) max_iteration_input.grid( column=2, row=6, columnspan=2, sticky="W", padx=3) t1_limit_input = teek.Entry(frame, text=t1_limit_var.get()) t1_limit_input.grid( column=6, row=2, sticky="W", padx=3) t2_limit_input = teek.Entry(frame, text=t2_limit_var.get()) t2_limit_input.grid( column=6, row=3, sticky="W", padx=3)
def test_check_in_notebook(): tab = teek.NotebookTab(teek.Label(teek.Notebook(teek.Window()))) with pytest.raises(RuntimeError) as error: tab.hide() assert 'not in the notebook' in str(error.value)
import teek window = teek.Window() teek.Label(window, "asd asd").pack() teek.Separator(window).pack(fill='x') teek.Label(window, "moar asd").pack() window.on_delete_window.connect(teek.quit) teek.run()
def test_tab_object_caching(): notebook = teek.Notebook(teek.Window()) tab1 = teek.NotebookTab(teek.Label(notebook, "asd")) notebook.append(tab1) assert notebook[0] is tab1 assert notebook.get_tab_by_widget(tab1.widget) is tab1