From ef2f17a173a9c22e55a4fa8e8536a6edcf990d47 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 27 May 2016 15:52:21 -0400
Subject: [PATCH 02/16] diagnostic-show-locus.c: add selftests

gcc/ChangeLog:
	* diagnostic-show-locus.c: Include "selftest.h".
	(make_range): New function.
	(test_range_contains_point_for_single_point): New function.
	(test_range_contains_point_test_for_single_line): New function.
	(test_range_contains_point_for_multiple_lines): New function.
	(assert_eq): New function.
	(test_get_line_width_without_trailing_whitespace): New function.
	(selftest::diagnostic_show_locus_c_tests): New function.
---
 gcc/diagnostic-show-locus.c | 156 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 156 insertions(+)

diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index eeccee5..38b424d 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "backtrace.h"
 #include "diagnostic.h"
 #include "diagnostic-color.h"
+#include "selftest.h"
 
 #ifdef HAVE_TERMIOS_H
 # include <termios.h>
@@ -442,6 +443,118 @@ layout_range::contains_point (int row, int column) const
   return column <= m_finish.m_column;
 }
 
+#if CHECKING_P
+
+/* A helper function for testing layout_range::contains_point.  */
+
+static layout_range
+make_range (int start_line, int start_col,
+	    int end_line, int end_col)
+{
+  const expanded_location start_exploc
+    = {"test.c", start_line, start_col, NULL, false};
+  const expanded_location finish_exploc
+    = {"test.c", end_line, end_col, NULL, false};
+  return layout_range (&start_exploc, &finish_exploc, false,
+		       &start_exploc);
+}
+
+/* Selftests for layout_range::contains_point.  */
+
+static void
+test_range_contains_point_for_single_point ()
+{
+  /* A range with start==end.  */
+  layout_range point = make_range (7, 10, 7, 10);
+
+  /* Before the line. */
+  ASSERT_FALSE (point.contains_point (6, 1));
+
+  /* On the line, but before start.  */
+  ASSERT_FALSE (point.contains_point (7, 9));
+
+  /* At the point.  */
+  ASSERT_TRUE (point.contains_point (7, 10));
+
+  /* On the line, after the point.  */
+  ASSERT_FALSE (point.contains_point (7, 11));
+
+  /* After the line.  */
+  ASSERT_FALSE (point.contains_point (8, 1));
+}
+
+static void
+test_range_contains_point_test_for_single_line ()
+{
+  /* The single-line example from above.  */
+  layout_range example_a = make_range (2, 22, 2, 38);
+
+  /* Before the line. */
+  ASSERT_FALSE (example_a.contains_point (1, 1));
+
+  /* On the line, but before start.  */
+  ASSERT_FALSE (example_a.contains_point (2, 21));
+
+  /* On the line, at the start.  */
+  ASSERT_TRUE (example_a.contains_point (2, 22));
+
+  /* On the line, within the range.  */
+  ASSERT_TRUE (example_a.contains_point (2, 23));
+
+  /* On the line, at the end.  */
+  ASSERT_TRUE (example_a.contains_point (2, 38));
+
+  /* On the line, after the end.  */
+  ASSERT_FALSE (example_a.contains_point (2, 39));
+
+  /* After the line.  */
+  ASSERT_FALSE (example_a.contains_point (2, 39));
+}
+
+static void
+test_range_contains_point_for_multiple_lines ()
+{
+  /* The multi-line example from above.  */
+  layout_range example_b = make_range (3, 14, 5, 8);
+
+  /* Before first line. */
+  ASSERT_FALSE (example_b.contains_point (1, 1));
+
+  /* On the first line, but before start.  */
+  ASSERT_FALSE (example_b.contains_point (3, 13));
+
+  /* At the start.  */
+  ASSERT_TRUE (example_b.contains_point (3, 14));
+
+  /* On the first line, within the range.  */
+  ASSERT_TRUE (example_b.contains_point (3, 15));
+
+  /* On an interior line.
+     The column number should not matter; try various boundary
+     values.  */
+  ASSERT_TRUE (example_b.contains_point (4, 1));
+  ASSERT_TRUE (example_b.contains_point (4, 7));
+  ASSERT_TRUE (example_b.contains_point (4, 8));
+  ASSERT_TRUE (example_b.contains_point (4, 9));
+  ASSERT_TRUE (example_b.contains_point (4, 13));
+  ASSERT_TRUE (example_b.contains_point (4, 14));
+  ASSERT_TRUE (example_b.contains_point (4, 15));
+
+  /* On the final line, before the end.  */
+  ASSERT_TRUE (example_b.contains_point (5, 7));
+
+  /* On the final line, at the end.  */
+  ASSERT_TRUE (example_b.contains_point (5, 8));
+
+  /* On the final line, after the end.  */
+  ASSERT_FALSE (example_b.contains_point (5, 9));
+
+  /* After the line.  */
+  ASSERT_FALSE (example_b.contains_point (6, 1));
+}
+
+#endif /* #if CHECKING_P */
+
 /* Given a source line LINE of length LINE_WIDTH, determine the width
    without any trailing whitespace.  */
 
@@ -465,6 +578,31 @@ get_line_width_without_trailing_whitespace (const char *line, int line_width)
   return result;
 }
 
+#if CHECKING_P
+
+/* A helper function for testing get_line_width_without_trailing_whitespace.  */
+
+static void
+assert_eq (const char *line, int expected_width)
+{
+  int actual_value
+    = get_line_width_without_trailing_whitespace (line, strlen (line));
+  ASSERT_EQ (actual_value, expected_width);
+}
+
+static void
+test_get_line_width_without_trailing_whitespace ()
+{
+  assert_eq ("", 0);
+  assert_eq (" ", 0);
+  assert_eq ("\t", 0);
+  assert_eq ("hello world", 11);
+  assert_eq ("hello world     ", 11);
+  assert_eq ("hello world     \t\t  ", 11);
+}
+
+#endif /* #if CHECKING_P */
+
 /* Helper function for layout's ctor, for sanitizing locations relative
    to the primary location within a diagnostic.
 
@@ -1171,3 +1309,21 @@ diagnostic_show_locus (diagnostic_context * context,
 
   pp_set_prefix (context->printer, saved_prefix);
 }
+
+#if CHECKING_P
+
+namespace selftest {
+
+void
+diagnostic_show_locus_c_tests ()
+{
+  test_range_contains_point_for_single_point ();
+  test_range_contains_point_test_for_single_line ();
+  test_range_contains_point_for_multiple_lines ();
+
+  test_get_line_width_without_trailing_whitespace ();
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
-- 
1.8.5.3

