Beispiel #1
0
 def setUp(self):
     self.viewmodel = VectorMetricsViewModel()
Beispiel #2
0
class TestVectorMetricsViewModel(unittest.TestCase):
    def setUp(self):
        self.viewmodel = VectorMetricsViewModel()

    def test_button_disabled_by_default(self):
        self.assertEqual('disabled', self.viewmodel.get_button_state())

    def test_button_enabled_when_metric_set(self):
        self.viewmodel.set_metric('L1')
        self.assertEqual('active', self.viewmodel.get_button_state())

    def test_button_disabled_when_x_value_erased(self):
        self.viewmodel.set_x('')
        self.assertEqual('disabled', self.viewmodel.get_button_state())

    def test_button_disabled_when_incorrect_x_value(self):
        self.viewmodel.set_x('!')
        self.assertEqual('disabled', self.viewmodel.get_button_state())

    def test_set_button_state_changes_state(self):
        self.viewmodel.set_button_state('active')
        self.assertEqual('active', self.viewmodel.get_button_state())

    def test_error_message_on_incorrect_value(self):
        self.viewmodel.set_y('!')
        self.assertEqual(
            'Error: Incorrect expression, only list of float or int values supported',
            self.viewmodel.get_error_message())

    def test_error_message_on_incorrect_type(self):
        self.viewmodel.set_y('3')
        self.assertEqual('Error: Only list notations supported',
                         self.viewmodel.get_error_message())

    def test_button_enabled_when_correct_x_value(self):
        self.viewmodel.set_x('[1, 2, 3]')
        self.assertEqual('active', self.viewmodel.get_button_state())

    def test_error_message_is_empty_on_correct_value(self):
        self.viewmodel.set_y('[1, 2, 3]')
        self.assertEqual('', self.viewmodel.get_error_message())

    def test_can_change_x_value(self):
        self.viewmodel.set_x('[3, 2, 1]')
        self.assertEqual('[3, 2, 1]', self.viewmodel.get_x())

    def test_can_change_y_value(self):
        self.viewmodel.set_y('[4, 5, 1]')
        self.assertEqual('[4, 5, 1]', self.viewmodel.get_y())

    def test_error_message_is_shown_when_length_unequal(self):
        self.viewmodel.set_x('[1, 2, 3]')
        self.viewmodel.set_y('[1, 2, 3, 4]')
        self.viewmodel.set_metric('L1')
        self.viewmodel.compute()
        self.assertEqual(
            'Error: Vectors of different lengths obtained. Distance can only be '
            'calculated between vectors of equal length.',
            self.viewmodel.get_error_message())

    def test_can_compute_metric(self):
        self.viewmodel.set_x('[1.2, 1.5, 1.8]')
        self.viewmodel.set_y('[2.2, 2.5, 2.8]')
        self.viewmodel.set_metric('L1')
        self.viewmodel.compute()
        self.assertEqual('Result: 3.0', self.viewmodel.get_result())
class TestViewModelFakeLogging(unittest.TestCase):
    def setUp(self):
        self.view_model = VectorMetricsViewModel(FakeLogger())

    def test_logging_init(self):
        self.assertEqual('Welcome to The Float Vector Metrics Calculator!',
                         self.view_model.logger.get_last_message())

    def test_logging_changing_x(self):
        self.view_model.set_x('[0, 1, 2]')
        self.assertEqual('Setting x vector to [0, 1, 2]', self.view_model.logger.get_last_message())

    def test_logging_changing_y(self):
        self.view_model.set_y('[0, 1, 2]')
        self.assertEqual('Setting y vector to [0, 1, 2]', self.view_model.logger.get_last_message())

    def test_logging_changing_metric(self):
        self.view_model.set_metric('L1')
        self.assertEqual('Setting metric to L1', self.view_model.logger.get_last_message())

    def test_logging_changing_uncorrect_x(self):
        self.view_model.set_x('{0, 1, 2}')
        self.assertEqual('Error: Only list notations supported', self.view_model.logger.get_last_message())

    def test_logging_changing_uncorrect_y(self):
        self.view_model.set_y('[2, x, 1]')
        self.assertEqual('Error: Incorrect expression, only list of float or int values supported',
                         self.view_model.logger.get_last_message())

    def test_logging_uncorrect_compute(self):
        expected_messages = ['Button clicked',
                             'Error: Vectors of different lengths obtained. Distance can only be '
                             'calculated between vectors of equal length.']
        self.view_model.set_x('[1, 0, 2]')
        self.view_model.set_y('[1, 1, 1, 3]')
        self.view_model.set_metric('L1')
        self.view_model.compute()
        self.assertEqual(expected_messages, self.view_model.logger.get_log_messages()[-2:])

    def test_logging_performing_operation(self):
        expected_messages = ['Button clicked', 'Result: 2']

        self.view_model.set_x('[1, 0, 2]')
        self.view_model.set_y('[1, 1, 1]')
        self.view_model.set_metric('L1')
        self.view_model.compute()

        self.assertEqual(expected_messages, self.view_model.logger.get_log_messages()[-2:])
 def setUp(self):
     self.view_model = VectorMetricsViewModel(FakeLogger())
class GUI(ttk.Frame):
    view_model = VectorMetricsViewModel()
    metrics = ['L1', 'L2', 'L3', 'L4', 'Linf']

    def __init__(self):
        ttk.Frame.__init__(self)
        self.master.title("Vector metrics calculator")

        self.x_label = tk.Label(self.master, text="First vector")
        self.x_label.grid(row=0, column=0)
        self.x_vector = tk.Entry(self.master)
        self.x_vector.grid(row=0, column=1, columnspan=2)

        self.y_label = tk.Label(self.master, text="Second vector")
        self.y_label.grid(row=1, column=0)
        self.y_vector = tk.Entry(self.master)
        self.y_vector.grid(row=1, column=1, columnspan=2)

        self.metric_label = tk.Label(self.master, text="Metric")
        self.metric_label.grid(row=0, column=3)
        self.metrics_listbox = tk.Listbox(self.master, width=5)
        for metr in self.metrics:
            self.metrics_listbox.insert(tk.END, metr)
        self.metrics_listbox.grid(row=1, column=3)

        self.button = tk.Button(self.master, text='Compute')
        self.button.grid(row=3, column=3)

        self.result = tk.Label(self.master, text='Result: ')
        self.result.grid(row=2, column=0, columnspan=2)

        self.error_message = tk.Label(self.master, text='', wraplength=150)
        self.error_message.grid(row=3, column=0, columnspan=2)

        self.bind_events()
        self.mvvm_back_bind()

    def bind_events(self):
        self.button.bind('<Button-1>', self.button_clicked)
        self.x_vector.bind('<FocusOut>', self.x_vector_changed)
        self.y_vector.bind('<FocusOut>', self.y_vector_changed)
        self.metrics_listbox.bind('<<ListboxSelect>>',
                                  self.metrics_listbox_changed)

    def mvvm_bind(self):
        x_set = self.view_model.set_x(self.x_vector.get())
        if not x_set:
            self.view_model.set_button_state('disabled')
            return
        y_set = self.view_model.set_y(self.y_vector.get())
        if not y_set:
            self.view_model.set_button_state('disabled')

    def mvvm_back_bind(self):
        self.x_vector.delete(0, tk.END)
        self.x_vector.insert(tk.INSERT, self.view_model.get_x())

        self.y_vector.delete(0, tk.END)
        self.y_vector.insert(tk.INSERT, self.view_model.get_y())

        self.result.config(text='{}'.format(self.view_model.get_result()))

        self.button.config(state=self.view_model.get_button_state())
        self.error_message.config(
            text='{}'.format(self.view_model.get_error_message()))

    def button_clicked(self, event):
        self.mvvm_bind()
        self.view_model.compute()
        self.mvvm_back_bind()

    def x_vector_changed(self, event):
        self.mvvm_bind()
        self.mvvm_back_bind()

    def y_vector_changed(self, event):
        self.mvvm_bind()
        self.mvvm_back_bind()

    def metrics_listbox_changed(self, event):
        self.mvvm_bind()
        current_selection = self.metrics_listbox.curselection()
        if len(current_selection) > 0:
            self.view_model.set_metric(self.metrics[current_selection[0]])
        else:
            self.view_model.set_button_state('disabled')
        self.mvvm_back_bind()