def test_operation_division_second_numerator_zero_calculate_button_disabled( self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("12/3") viewmodel.set_second_number("0/1") viewmodel.set_operation("/") self.assertEqual("disabled", viewmodel.get_calculate_button_state())
def test_first_valid_second_valid_div_calculate(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("12/3") viewmodel.set_second_number("2/7") viewmodel.set_operation("/") viewmodel.calculate() self.assertEqual("14", viewmodel.get_result())
def test_denominators_of_numbers_are_zero_info_message_correct(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("13/0") viewmodel.set_second_number("7/0") self.assertEqual( "Denominator of first number is zero.Denominator of second number is zero.", viewmodel.get_info_message())
def test_number_updated_result_empty(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("12/3") viewmodel.set_second_number("2/7") viewmodel.set_operation("+") viewmodel.calculate() viewmodel.set_first_number("12/11") self.assertEqual("", viewmodel.get_result())
def test_operation_division_second_numerator_zero_info_message_correct( self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("12/3") viewmodel.set_second_number("0/1") viewmodel.set_operation("/") self.assertEqual( "Numerator of second number is zero. Division by zero is not allowed.", viewmodel.get_info_message())
def test_calculate_button_disabled_by_default(self): viewmodel = RationalNumberViewModel() self.assertEqual("disabled", viewmodel.get_calculate_button_state())
def test_operation_invalid_calculate_button_disabled(self): viewmodel = RationalNumberViewModel() viewmodel.set_operation("%") self.assertEqual("disabled", viewmodel.get_calculate_button_state())
def test_first_invalid_second_invalid_info_correct(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("aaa") viewmodel.set_second_number("bbbb") self.assertEqual("First number is invalid.Second number is invalid.", viewmodel.get_info_message())
def test_first_valid_second_empty_info_correct(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("3/4") viewmodel.set_second_number("") self.assertEqual("Second number is empty.", viewmodel.get_info_message())
def test_first_valid_second_valid_info_empty(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("12/3") viewmodel.set_second_number("2/7") self.assertEqual("", viewmodel.get_info_message())
def test_numbers_invalid_calculate_button_disabled(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("a") viewmodel.set_second_number("2/7") self.assertEqual("disabled", viewmodel.get_calculate_button_state())
def setUp(self): self.view_model = RationalNumberViewModel(RealLogger())
def test_numbers_filled_calculate_button_enabled(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("1/2") viewmodel.set_second_number("2/7") self.assertEqual("normal", viewmodel.get_calculate_button_state())
def test_denominator_of_number_zero_calculate_button_disabled(self): viewmodel = RationalNumberViewModel() viewmodel.set_first_number("12/0") viewmodel.set_second_number("2/7") viewmodel.set_operation("+") self.assertEqual("disabled", viewmodel.get_calculate_button_state())
class GUIView(ttk.Frame): N_LOG_MESSAGES_TO_DISPLAY = 10 default_sticky = tkinter.W + tkinter.E + tkinter.N + tkinter.S viewmodel = RationalNumberViewModel() def set_weight_to_grid(self): self.rowconfigure(0, weight=1) self.rowconfigure(1, weight=1) self.rowconfigure(2, weight=1) self.rowconfigure(3, weight=1) self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.columnconfigure(2, weight=1) self.columnconfigure(3, weight=1) self.columnconfigure(4, weight=1) def bind_events(self): self.txt_first_number.bind('<KeyRelease>', self.txt_first_number_changed) self.txt_second_number.bind('<KeyRelease>', self.txt_second_number_changed) self.cmb_operation.bind('<<ComboboxSelected>>', self.operation_changed) self.btn_calculate.bind('<Button-1>', self.calculate_clicked) def mvvm_bind(self): self.viewmodel.set_first_number( self.txt_first_number.get("1.0", tkinter.END)) self.viewmodel.set_second_number( self.txt_second_number.get("1.0", tkinter.END)) self.viewmodel.set_operation(self.cmb_operation.get()) def mvvm_back_bind(self): self.btn_calculate.config( state=self.viewmodel.get_calculate_button_state()) self.lbl_message.config(text=self.viewmodel.get_info_message()) self.lbl_result.config(text=self.viewmodel.get_result()) log_messages = self.viewmodel.logger.get_log_messages() logger_text = '\n'.join( log_messages[:-self.N_LOG_MESSAGES_TO_DISPLAY:-1]) self.lbl_log.config(text=logger_text) def __init__(self): ttk.Frame.__init__(self) self.master.title("Rational number calculator") self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=5) self.grid(sticky=self.default_sticky) self.txt_first_number = tkinter.Text(self, height=1, width=10, borderwidth=2, relief="groove") self.txt_first_number.grid(row=0, column=0, sticky=self.default_sticky) self.cmb_operation = ttk.Combobox( self, height=1, width=5, values=RationalNumberViewModel.VALID_OPERATIONS, state="readonly") self.cmb_operation.current(0) self.cmb_operation.grid(row=0, column=1, sticky=self.default_sticky) self.txt_second_number = tkinter.Text(self, height=1, width=10, borderwidth=2, relief="groove") self.txt_second_number.grid(row=0, column=2, sticky=self.default_sticky) self.lbl_equal_to = tkinter.Label(self, text="=", height=1, width=5, borderwidth=2, relief="groove") self.lbl_equal_to.grid(row=0, column=3, sticky=self.default_sticky) self.lbl_result = tkinter.Label(self, text="", height=1, width=10, borderwidth=2, relief="groove") self.lbl_result.grid(row=0, column=4, sticky=self.default_sticky) self.btn_calculate = ttk.Button(self, text='Calculate') self.btn_calculate.grid(row=1, column=1, columnspan=3, sticky=self.default_sticky) self.lbl_message = ttk.Label(self, text="Info box") self.lbl_message.grid(row=2, column=0, columnspan=5, sticky=tkinter.W + tkinter.N) self.lbl_log = tkinter.Label(self.master, text="Here will be log") self.lbl_log.grid(row=3, column=0, columnspan=5, sticky=tkinter.W + tkinter.N) self.bind_events() self.set_weight_to_grid() self.mvvm_back_bind() def calculate_clicked(self, event): self.mvvm_bind() self.viewmodel.calculate() self.mvvm_back_bind() def txt_first_number_changed(self, event): self.mvvm_bind() self.mvvm_back_bind() def txt_second_number_changed(self, event): self.mvvm_bind() self.mvvm_back_bind() def operation_changed(self, event): self.mvvm_bind() self.mvvm_back_bind()