/* -*- 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 . */ #include 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"); 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"); 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); } #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"); 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"); 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/move-several-lines", test_move_lines__move_several_lines); return g_test_run(); }