[gtksourceview] testsuite: add unit tests for GtkSourceView::move-lines



commit 4a1bb212029d6648f1323ec420f644462865d24a
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Wed Mar 29 17:15:40 2017 +0200

    testsuite: add unit tests for GtkSourceView::move-lines
    
    That API sucks, the copy operation doesn't make sense and the count
    parameter makes sense only for 1 and -1.
    
    The function has initially been added with
    commit 6509f96749dab3f4809f7c026777a71a620db674 in 2008, the function
    prototype was just:
    void move_lines (GtkTextView *view, gboolean down);
    
    Then commit 5ac5099a2fe28cc8d7851ba8dcc6c8126dae0f28 in 2010 added the
    keybinding signal with the copy and count/step parameters, even if copy
    was not used and step supported only up and down…
    
    And the function is buggy with the final line.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=624963

 testsuite/Makefile.am |    3 +
 testsuite/test-view.c |  595 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 598 insertions(+), 0 deletions(-)
---
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 55ede27..a467149 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -91,6 +91,9 @@ test_undo_manager_SOURCES = test-undo-manager.c
 UNIT_TEST_PROGS += test-utils
 test_utils_SOURCES = test-utils.c
 
+UNIT_TEST_PROGS += test-view
+test_view_SOURCES = test-view.c
+
 TESTS_ENVIRONMENT = G_TEST_SRCDIR="$(abs_srcdir)"
 TESTS = $(UNIT_TEST_PROGS)
 noinst_PROGRAMS = $(UNIT_TEST_PROGS)
diff --git a/testsuite/test-view.c b/testsuite/test-view.c
new file mode 100644
index 0000000..5906e55
--- /dev/null
+++ b/testsuite/test-view.c
@@ -0,0 +1,595 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
+/*
+ * This file is part of GtkSourceView
+ *
+ * Copyright (C) 2017 - Sébastien Wilmet
+ *
+ * GtkSourceView is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * GtkSourceView is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gtksourceview/gtksource.h>
+
+static gchar *
+get_text (GtkTextBuffer *buffer)
+{
+       GtkTextIter start;
+       GtkTextIter end;
+
+       gtk_text_buffer_get_bounds (buffer, &start, &end);
+       return gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
+}
+
+#define N_CASES_INITIAL_SELECTION_FOR_SINGLE_LINE (6)
+
+static void
+set_initial_selection_for_single_line (GtkTextBuffer *buffer,
+                                      gint           line_num,
+                                      gint           case_num)
+{
+       GtkTextIter start;
+       GtkTextIter end;
+
+       switch (case_num)
+       {
+               case 0:
+                       gtk_text_buffer_get_iter_at_line (buffer, &start, line_num);
+                       gtk_text_buffer_place_cursor (buffer, &start);
+                       break;
+
+               case 1:
+                       gtk_text_buffer_get_iter_at_line_offset (buffer, &start, line_num, 1);
+                       gtk_text_buffer_place_cursor (buffer, &start);
+                       break;
+
+               case 2:
+                       gtk_text_buffer_get_iter_at_line (buffer, &start, line_num);
+                       gtk_text_iter_forward_to_line_end (&start);
+                       gtk_text_buffer_place_cursor (buffer, &start);
+                       break;
+
+               case 3:
+                       gtk_text_buffer_get_iter_at_line (buffer, &start, line_num);
+                       end = start;
+                       gtk_text_iter_forward_to_line_end (&end);
+                       gtk_text_buffer_select_range (buffer, &start, &end);
+                       break;
+
+               case 4:
+                       gtk_text_buffer_get_iter_at_line (buffer, &start, line_num);
+                       gtk_text_buffer_get_iter_at_line (buffer, &end, line_num + 1);
+                       gtk_text_buffer_select_range (buffer, &start, &end);
+                       break;
+
+               case 5:
+                       gtk_text_buffer_get_iter_at_line_offset (buffer, &start, line_num, 1);
+                       gtk_text_buffer_get_iter_at_line_offset (buffer, &end, line_num, 2);
+                       gtk_text_buffer_select_range (buffer, &start, &end);
+                       break;
+
+               default:
+                       g_assert_not_reached ();
+       }
+}
+
+static void
+test_move_lines__move_single_line (void)
+{
+       GtkSourceView *view;
+       GtkTextBuffer *buffer;
+       GtkTextIter start;
+       GtkTextIter end;
+       gchar *text;
+       gint case_num;
+
+       view = GTK_SOURCE_VIEW (gtk_source_view_new ());
+       g_object_ref_sink (view);
+
+       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+       /* Move down first line */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SINGLE_LINE; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3",
+                                         -1);
+
+               set_initial_selection_for_single_line (buffer, 0, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, 1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line2\n"
+                                "line1\n"
+                                "line3");
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 6);
+               g_assert_cmpint (gtk_text_iter_get_offset (&end), ==, 12);
+       }
+
+       /* Move up second line */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SINGLE_LINE; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3",
+                                         -1);
+
+               set_initial_selection_for_single_line (buffer, 1, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, -1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line2\n"
+                                "line1\n"
+                                "line3");
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert (gtk_text_iter_is_start (&start));
+               g_assert_cmpint (gtk_text_iter_get_offset (&end), ==, 6);
+       }
+
+       /* Move down second line, without final newline */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SINGLE_LINE; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3",
+                                         -1);
+
+               set_initial_selection_for_single_line (buffer, 1, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, 1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line1\n"
+                                "line3\n"
+                                "line2\n"); /* FIXME should be "line2" without the '\n'. */
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 12);
+               g_assert (gtk_text_iter_is_end (&end));
+       }
+
+       /* Move down second line, with final newline */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SINGLE_LINE; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3\n",
+                                         -1);
+
+               set_initial_selection_for_single_line (buffer, 1, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, 1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line1\n"
+                                "line3\n"
+                                "line2\n");
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 12);
+               g_assert (gtk_text_iter_is_end (&end));
+       }
+
+       /* Move up third line, without final newline */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SINGLE_LINE; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3",
+                                         -1);
+
+               set_initial_selection_for_single_line (buffer, 2, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, -1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line1\n"
+                                "line3\n"
+                                "line2\n"); /* FIXME should be "line2" without the '\n'. */
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 6);
+               g_assert_cmpint (gtk_text_iter_get_offset (&end), ==, 12);
+       }
+
+       /* Move up third line, with final newline */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SINGLE_LINE; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3\n",
+                                         -1);
+
+               set_initial_selection_for_single_line (buffer, 2, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, -1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line1\n"
+                                "line3\n"
+                                "line2\n");
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 6);
+               g_assert_cmpint (gtk_text_iter_get_offset (&end), ==, 12);
+       }
+
+       /* Move down last line */
+       gtk_text_buffer_set_text (buffer,
+                                 "line1\n"
+                                 "line2\n"
+                                 "line3",
+                                 -1);
+
+       gtk_text_buffer_get_end_iter (buffer, &end);
+       gtk_text_buffer_place_cursor (buffer, &end);
+
+       g_signal_emit_by_name (view, "move-lines", FALSE, 1);
+       text = get_text (buffer);
+       g_assert_cmpstr (text, ==,
+                        "line1\n"
+                        "line2\n"
+                        "line3");
+       g_free (text);
+
+       gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+       g_assert (gtk_text_iter_is_end (&start));
+       g_assert (gtk_text_iter_is_end (&end));
+
+       /* Move up first line */
+       gtk_text_buffer_set_text (buffer,
+                                 "line1\n"
+                                 "line2\n"
+                                 "line3",
+                                 -1);
+
+       gtk_text_buffer_get_start_iter (buffer, &start);
+       gtk_text_buffer_place_cursor (buffer, &start);
+
+       g_signal_emit_by_name (view, "move-lines", FALSE, -1);
+       text = get_text (buffer);
+       g_assert_cmpstr (text, ==,
+                        "line1\n"
+                        "line2\n"
+                        "line3");
+       g_free (text);
+
+       gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+       g_assert (gtk_text_iter_is_start (&start));
+       g_assert (gtk_text_iter_is_start (&end));
+
+       g_object_unref (view);
+}
+
+static void
+test_move_lines__copy_single_line (void)
+{
+       GtkSourceView *view;
+       GtkTextBuffer *buffer;
+       GtkTextIter iter;
+       gchar *text;
+
+       view = GTK_SOURCE_VIEW (gtk_source_view_new ());
+       g_object_ref_sink (view);
+
+       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+       gtk_text_buffer_set_text (buffer,
+                                 "line1\n"
+                                 "line2\n"
+                                 "line3",
+                                 -1);
+
+       gtk_text_buffer_get_start_iter (buffer, &iter);
+       gtk_text_buffer_place_cursor (buffer, &iter);
+
+       /* Strange operation. A more useful operation would result to:
+        * line1\n
+        * line1\n
+        * line2\n
+        * line3
+        *
+        * The copy parameter has been added in
+        * commit 5ac5099a2fe28cc8d7851ba8dcc6c8126dae0f28, but it seems that it
+        * has never been used, at least not by GtkSourceView itself (there are
+        * no move-lines keybindings with copy=TRUE).
+        */
+       g_signal_emit_by_name (view, "move-lines", TRUE, 1);
+       text = get_text (buffer);
+       g_assert_cmpstr (text, ==,
+                        "line1\n"
+                        "line2\n"
+                        "line1\n"
+                        "line3");
+       g_free (text);
+
+       g_object_unref (view);
+}
+
+#define N_CASES_INITIAL_SELECTION_FOR_SEVERAL_LINES (3)
+
+static void
+set_initial_selection_for_several_lines (GtkTextBuffer *buffer,
+                                        gint           start_line_num,
+                                        gint           end_line_num,
+                                        gint           case_num)
+{
+       GtkTextIter start;
+       GtkTextIter end;
+
+       switch (case_num)
+       {
+               case 0:
+                       gtk_text_buffer_get_iter_at_line (buffer, &start, start_line_num);
+                       gtk_text_buffer_get_iter_at_line (buffer, &end, end_line_num);
+                       gtk_text_iter_forward_to_line_end (&end);
+                       gtk_text_buffer_select_range (buffer, &start, &end);
+                       break;
+
+               case 1:
+                       gtk_text_buffer_get_iter_at_line (buffer, &start, start_line_num);
+                       gtk_text_buffer_get_iter_at_line (buffer, &end, end_line_num + 1);
+                       gtk_text_buffer_select_range (buffer, &start, &end);
+                       break;
+
+               case 2:
+                       gtk_text_buffer_get_iter_at_line_offset (buffer, &start, start_line_num, 1);
+                       gtk_text_buffer_get_iter_at_line_offset (buffer, &end, end_line_num, 1);
+                       gtk_text_buffer_select_range (buffer, &start, &end);
+                       break;
+
+               default:
+                       g_assert_not_reached ();
+       }
+}
+
+static void
+test_move_lines__move_several_lines (void)
+{
+       GtkSourceView *view;
+       GtkTextBuffer *buffer;
+       GtkTextIter start;
+       GtkTextIter end;
+       gchar *text;
+       gint case_num;
+
+       view = GTK_SOURCE_VIEW (gtk_source_view_new ());
+       g_object_ref_sink (view);
+
+       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+       /* Move down first two lines */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SEVERAL_LINES; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3\n"
+                                         "line4",
+                                         -1);
+
+               set_initial_selection_for_several_lines (buffer, 0, 1, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, 1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line3\n"
+                                "line1\n"
+                                "line2\n"
+                                "line4");
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 6);
+               g_assert_cmpint (gtk_text_iter_get_offset (&end), ==, 18);
+       }
+
+       /* Move up second and third lines */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SEVERAL_LINES; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3\n"
+                                         "line4",
+                                         -1);
+
+               set_initial_selection_for_several_lines (buffer, 1, 2, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, -1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line2\n"
+                                "line3\n"
+                                "line1\n"
+                                "line4");
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert (gtk_text_iter_is_start (&start));
+               g_assert_cmpint (gtk_text_iter_get_offset (&end), ==, 12);
+       }
+
+       /* Move down second and third lines, without final newline */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SEVERAL_LINES; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3\n"
+                                         "line4",
+                                         -1);
+
+               set_initial_selection_for_several_lines (buffer, 1, 2, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, 1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line1\n"
+                                "line4\n"
+                                "line2\n"
+                                "line3\n"); /* FIXME should be "line3" without the '\n'. */
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 12);
+               g_assert (gtk_text_iter_is_end (&end));
+       }
+
+       /* Move down second and third lines, with final newline */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SEVERAL_LINES; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3\n"
+                                         "line4\n",
+                                         -1);
+
+               set_initial_selection_for_several_lines (buffer, 1, 2, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, 1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line1\n"
+                                "line4\n"
+                                "line2\n"
+                                "line3\n");
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 12);
+               g_assert (gtk_text_iter_is_end (&end));
+       }
+
+       /* Move up third and fourth lines, without final newline */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SEVERAL_LINES; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3\n"
+                                         "line4",
+                                         -1);
+
+               set_initial_selection_for_several_lines (buffer, 2, 3, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, -1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line1\n"
+                                "line3\n"
+                                "line4\n"
+                                "line2\n"); /* FIXME should be "line2" without the '\n'. */
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 6);
+               g_assert_cmpint (gtk_text_iter_get_offset (&end), ==, 18);
+       }
+
+       /* Move up third and fourth lines, with final newline */
+       for (case_num = 0; case_num < N_CASES_INITIAL_SELECTION_FOR_SEVERAL_LINES; case_num++)
+       {
+               gtk_text_buffer_set_text (buffer,
+                                         "line1\n"
+                                         "line2\n"
+                                         "line3\n"
+                                         "line4\n",
+                                         -1);
+
+               set_initial_selection_for_several_lines (buffer, 2, 3, case_num);
+
+               g_signal_emit_by_name (view, "move-lines", FALSE, -1);
+               text = get_text (buffer);
+               g_assert_cmpstr (text, ==,
+                                "line1\n"
+                                "line3\n"
+                                "line4\n"
+                                "line2\n");
+               g_free (text);
+
+               gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+               g_assert_cmpint (gtk_text_iter_get_offset (&start), ==, 6);
+               g_assert_cmpint (gtk_text_iter_get_offset (&end), ==, 18);
+       }
+
+       /* Move down last two lines */
+       gtk_text_buffer_set_text (buffer,
+                                 "line1\n"
+                                 "line2\n"
+                                 "line3\n"
+                                 "line4",
+                                 -1);
+
+       set_initial_selection_for_several_lines (buffer, 2, 3, 0);
+
+       g_signal_emit_by_name (view, "move-lines", FALSE, 1);
+       text = get_text (buffer);
+       g_assert_cmpstr (text, ==,
+                        "line1\n"
+                        "line2\n"
+                        "line3\n"
+                        "line4");
+       g_free (text);
+
+       /* Move up first two lines */
+       gtk_text_buffer_set_text (buffer,
+                                 "line1\n"
+                                 "line2\n"
+                                 "line3\n"
+                                 "line4",
+                                 -1);
+
+       set_initial_selection_for_several_lines (buffer, 0, 1, 0);
+
+       g_signal_emit_by_name (view, "move-lines", FALSE, -1);
+       text = get_text (buffer);
+       g_assert_cmpstr (text, ==,
+                        "line1\n"
+                        "line2\n"
+                        "line3\n"
+                        "line4");
+       g_free (text);
+
+       g_object_unref (view);
+}
+
+int
+main (int argc, char **argv)
+{
+       gtk_test_init (&argc, &argv);
+
+       g_test_add_func ("/view/move-lines/move-single-line", test_move_lines__move_single_line);
+       g_test_add_func ("/view/move-lines/copy-single-line", test_move_lines__copy_single_line);
+       g_test_add_func ("/view/move-lines/move-several-lines", test_move_lines__move_several_lines);
+
+       return g_test_run();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]