blob: 77b5ddd30b6ff52e4bd856a9dc09a52dd47d5537 [file] [log] [blame]
Philipp Le4071d912022-04-26 22:02:43 +02001# SPDX-License-Identifier: MPL-2.0
2# Copyright (c) 2022 Philipp Le <philipp@philipple.de>.
3# This Source Code Form is subject to the terms of the Mozilla Public
4# License, v. 2.0. If a copy of the MPL was not distributed with this
5# file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7import unittest
8from typing import List
9from pydantic import conint, confloat
Philipp Lecefab922022-04-26 22:06:33 +020010from tkinter import Tk, ttk
Philipp Le4071d912022-04-26 22:02:43 +020011from enum import IntEnum
Philipp Lecefab922022-04-26 22:06:33 +020012import toml
Philipp Le4071d912022-04-26 22:02:43 +020013
14from dcs.config.store import Store, ConfigObject, ConfigControlFrame
15from dcs.config.ui import ui_create
16
17
18class ExampleSubFrame(ConfigControlFrame):
Philipp Lecefab922022-04-26 22:06:33 +020019 wdg_id: ttk.Spinbox
Philipp Lecfb6d2a2022-04-26 22:08:48 +020020 wdg_title: ttk.Entry
Philipp Le4071d912022-04-26 22:02:43 +020021
22
23@ui_create
24class ExampleSub(ConfigObject):
25 id: conint(ge=0, lt=10000) = 1
26 title: str = 'test'
27
28 def make_config_widget(self, parent: ttk.Widget) -> ConfigControlFrame:
29 frm = ExampleSubFrame(parent)
Philipp Lecefab922022-04-26 22:06:33 +020030 frm.pack()
31 ttk.Label(frm, text="Id:").grid(row=0, column=0)
32 frm.wdg_id = self.ui_create_id(frm)
33 frm.wdg_id.grid(row=0, column=1)
Philipp Lecfb6d2a2022-04-26 22:08:48 +020034 ttk.Label(frm, text="Title:").grid(row=1, column=0)
35 frm.wdg_title = self.ui_create_title(frm)
36 frm.wdg_title.grid(row=1, column=1)
Philipp Le4071d912022-04-26 22:02:43 +020037 return frm
38
39
40
41class ExampleIntEnum(IntEnum):
42 Option1 = 1
43 Option2 = 2
44
45
46@ui_create
47class ExampleConfig(ConfigObject):
48 _KEY = 'example'
49 id: conint(ge=0, lt=10) = 1
50 name: str = 'Hello'
51 sub: List[ExampleSub] = [
52 ExampleSub(id=1, title='item 1'),
53 ExampleSub(id=2, title='item 2'),
54 ]
55 int_option: ExampleIntEnum = ExampleIntEnum.Option2
56 flt: confloat(ge=0.0, lt=10.0, multiple_of=0.01) = 0.12
57
58
59class UITest(unittest.TestCase):
60 def test_deserialize(self):
61 in_data = {
62 'example': {
63 'id': 0,
64 'name': 'Test1',
65 'sub': [
66 {
67 'id': 0,
68 'title': 'Title1',
69 },
70 {
71 'id': 1,
72 'title': 'Title2',
73 },
74 ]
75 }
76 }
77
78 loaded_store = Store.load_obj(in_data, 'default')
79
80 store = Store.get_instance('default')
81 self.assertEqual(id(loaded_store), id(store))
82
83 cfg: ExampleConfig = store.get_config(ExampleConfig)
84 self.assertIn('ui_create_id', dir(cfg))
Philipp Lecefab922022-04-26 22:06:33 +020085
86
87class UIInteractiveTest(unittest.TestCase):
88 def setUp(self) -> None:
89 self.root = Tk()
90 self.frm = ttk.Frame(self.root, padding=10)
91 self.frm.pack()
92
93 self.store = Store.new('default')
94
95 def _print_cfg(self) -> None:
96 print(repr(self.store.get_config(ExampleConfig)))
97 print(toml.dumps(self.store.dump_obj()))
98 #print(self.store.get_config(ExampleConfig).json())
99
100 def _run_ui(self) -> bool:
101 self.res = False
102
103 def act(ok: bool) -> None:
104 self.root.destroy()
105 self.res = ok
106
107 self.ok_btn = ttk.Button(self.root, text='Test OK', command=lambda: act(True))
108 self.ok_btn.pack()
109 self.ok_fail = ttk.Button(self.root, text='Test Fail', command=lambda: act(False))
110 self.ok_fail.pack()
111
112 self.root.mainloop()
113
114 return self.res
115
116 def test_int_widget(self):
117 cfg = self.store.get_config(ExampleConfig)
118 wdg = cfg.ui_create_id(self.frm)
119 wdg.pack()
120 wdg.listen_change(lambda x, y, z: self._print_cfg())
121
122 self.assertTrue(self._run_ui())
123
124 def test_float_widget(self):
125 cfg = self.store.get_config(ExampleConfig)
126 wdg = cfg.ui_create_flt(self.frm)
127 wdg.pack()
128 wdg.listen_change(lambda x, y, z: self._print_cfg())
129
130 self.assertTrue(self._run_ui())
Philipp Lee93a2c42022-04-26 22:11:14 +0200131
132 def test_dropdown_widget(self):
133 cfg = self.store.get_config(ExampleConfig)
134 wdg = cfg.ui_create_int_option_dropdown(self.frm)
135 wdg.pack()
136 wdg.listen_change(lambda x, y, z: self._print_cfg())
137
138 self.assertTrue(self._run_ui())