[recipes] Add a test for number parsing
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] Add a test for number parsing
- Date: Fri, 23 Dec 2016 23:59:50 +0000 (UTC)
commit b85ca9ac6b5bef780971c3f83cd3f9f492768ee1
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Dec 23 18:15:40 2016 -0500
Add a test for number parsing
This already found quite a few irregularities, so yay for testing.
tests/Makefile.am | 16 ++-
tests/number-data/number1.expected | 396 ++++++++++++++++++++++++++++++++++++
tests/number-data/number1.in | 60 ++++++
tests/number.c | 156 ++++++++++++++
4 files changed, 626 insertions(+), 2 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 41775ca..978af86 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -5,9 +5,13 @@ TESTS_ENVIRONMENT = \
MALLOC_CHECK_=2 \
MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256))
-TESTS = ingredients
+TESTS = \
+ number \
+ ingredients
-check_PROGRAMS = ingredients
+check_PROGRAMS = \
+ number \
+ ingredients
ingredients_SOURCES = ingredients.c
ingredients_CFLAGS = \
@@ -17,6 +21,14 @@ ingredients_CFLAGS = \
ingredients_LDADD = $(RECIPES_LIBS)
+number_SOURCES = number.c
+number_CFLAGS = \
+ $(RECIPES_CFLAGS) \
+ -DPKGDATADIR=\"$(pkgdatadir)\" \
+ -I$(top_srcdir)/src
+
+number_LDADD = $(RECIPES_LIBS)
+
EXTRA_DIST = \
ingredients-data/valid-1.expected ingredients-data/valid-1.in \
ingredients-data/valid-2.expected ingredients-data/valid-2.in \
diff --git a/tests/number-data/number1.expected b/tests/number-data/number1.expected
new file mode 100644
index 0000000..383bb22
--- /dev/null
+++ b/tests/number-data/number1.expected
@@ -0,0 +1,396 @@
+INPUT '123'
+REST ''
+FRACTION 1
+NUMERATOR 123
+DENOMINATOR 1
+VALUE 123
+FORMATTED '123'
+
+INPUT '123/201'
+REST ''
+FRACTION 1
+NUMERATOR 41
+DENOMINATOR 67
+VALUE 0.61194
+FORMATTED '41/67'
+
+INPUT '10.11'
+REST ''
+FRACTION 0
+NUMERATOR 0
+DENOMINATOR 0
+VALUE 10.11
+FORMATTED '10.11'
+
+INPUT '-0.001'
+REST ''
+FRACTION 0
+NUMERATOR 0
+DENOMINATOR 0
+VALUE -0.001
+FORMATTED '-0.001'
+
+INPUT '1/2'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 2
+VALUE 0.5
+FORMATTED '½'
+
+INPUT '1/3'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 3
+VALUE 0.333333
+FORMATTED '⅓'
+
+INPUT '2/6'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 3
+VALUE 0.333333
+FORMATTED '⅓'
+
+INPUT '1/0'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 0
+VALUE inf
+FORMATTED '1/0'
+
+INPUT '1/-1'
+REST ''
+FRACTION 1
+NUMERATOR -1
+DENOMINATOR 1
+VALUE -1
+FORMATTED '-1'
+
+INPUT '-3/-4'
+REST ''
+FRACTION 1
+NUMERATOR 3
+DENOMINATOR 4
+VALUE 0.75
+FORMATTED '¾'
+
+INPUT 'a dozen'
+REST ''
+FRACTION 1
+NUMERATOR 12
+DENOMINATOR 1
+VALUE 12
+FORMATTED '12'
+
+INPUT 'one'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 1
+VALUE 1
+FORMATTED '1'
+
+INPUT 'two'
+REST ''
+FRACTION 1
+NUMERATOR 2
+DENOMINATOR 1
+VALUE 2
+FORMATTED '2'
+
+INPUT 'three'
+REST ''
+FRACTION 1
+NUMERATOR 3
+DENOMINATOR 1
+VALUE 3
+FORMATTED '3'
+
+INPUT 'four'
+REST ''
+FRACTION 1
+NUMERATOR 4
+DENOMINATOR 1
+VALUE 4
+FORMATTED '4'
+
+INPUT 'five'
+REST ''
+FRACTION 1
+NUMERATOR 5
+DENOMINATOR 1
+VALUE 5
+FORMATTED '5'
+
+INPUT 'six'
+REST ''
+FRACTION 1
+NUMERATOR 6
+DENOMINATOR 1
+VALUE 6
+FORMATTED '6'
+
+INPUT 'seven'
+REST ''
+FRACTION 1
+NUMERATOR 7
+DENOMINATOR 1
+VALUE 7
+FORMATTED '7'
+
+INPUT 'eight'
+REST ''
+FRACTION 1
+NUMERATOR 8
+DENOMINATOR 1
+VALUE 8
+FORMATTED '8'
+
+INPUT 'nine'
+REST ''
+FRACTION 1
+NUMERATOR 9
+DENOMINATOR 1
+VALUE 9
+FORMATTED '9'
+
+INPUT 'ten'
+REST ''
+FRACTION 1
+NUMERATOR 10
+DENOMINATOR 1
+VALUE 10
+FORMATTED '10'
+
+INPUT 'eleven'
+REST ''
+FRACTION 1
+NUMERATOR 11
+DENOMINATOR 1
+VALUE 11
+FORMATTED '11'
+
+INPUT 'twelve'
+REST ''
+FRACTION 1
+NUMERATOR 12
+DENOMINATOR 1
+VALUE 12
+FORMATTED '12'
+
+INPUT '¼'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 4
+VALUE 0.25
+FORMATTED '¼'
+
+INPUT '½'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 2
+VALUE 0.5
+FORMATTED '½'
+
+INPUT '¾'
+REST ''
+FRACTION 1
+NUMERATOR 3
+DENOMINATOR 4
+VALUE 0.75
+FORMATTED '¾'
+
+INPUT '⅐'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 7
+VALUE 0.142857
+FORMATTED '⅐'
+
+INPUT '⅑'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 9
+VALUE 0.111111
+FORMATTED '⅑'
+
+INPUT '⅒'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 10
+VALUE 0.1
+FORMATTED '⅒'
+
+INPUT '⅓'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 3
+VALUE 0.333333
+FORMATTED '⅓'
+
+INPUT '⅔'
+REST ''
+FRACTION 1
+NUMERATOR 2
+DENOMINATOR 3
+VALUE 0.666667
+FORMATTED '⅔'
+
+INPUT '⅕'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 5
+VALUE 0.2
+FORMATTED '⅕'
+
+INPUT '⅖'
+REST ''
+FRACTION 1
+NUMERATOR 2
+DENOMINATOR 5
+VALUE 0.4
+FORMATTED '⅖'
+
+INPUT '⅗'
+REST ''
+FRACTION 1
+NUMERATOR 3
+DENOMINATOR 5
+VALUE 0.6
+FORMATTED '⅗'
+
+INPUT '⅘'
+REST ''
+FRACTION 1
+NUMERATOR 4
+DENOMINATOR 5
+VALUE 0.8
+FORMATTED '⅘'
+
+INPUT '⅙'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 6
+VALUE 0.166667
+FORMATTED '⅙'
+
+INPUT '⅚'
+REST ''
+FRACTION 1
+NUMERATOR 5
+DENOMINATOR 6
+VALUE 0.833333
+FORMATTED '⅚'
+
+INPUT '⅛'
+REST ''
+FRACTION 1
+NUMERATOR 1
+DENOMINATOR 8
+VALUE 0.125
+FORMATTED '⅛'
+
+INPUT '⅜'
+REST ''
+FRACTION 1
+NUMERATOR 3
+DENOMINATOR 8
+VALUE 0.375
+FORMATTED '⅜'
+
+INPUT '⅝'
+REST ''
+FRACTION 1
+NUMERATOR 5
+DENOMINATOR 8
+VALUE 0.625
+FORMATTED '⅝'
+
+INPUT '⅞'
+REST ''
+FRACTION 1
+NUMERATOR 7
+DENOMINATOR 8
+VALUE 0.875
+FORMATTED '⅞'
+
+INPUT '1 1/2'
+REST ''
+FRACTION 1
+NUMERATOR 3
+DENOMINATOR 2
+VALUE 1.5
+FORMATTED '1 ½'
+
+INPUT '2 23/47'
+REST ''
+FRACTION 1
+NUMERATOR 117
+DENOMINATOR 47
+VALUE 2.48936
+FORMATTED '2 23/47'
+
+INPUT '1 ¼'
+REST ''
+FRACTION 1
+NUMERATOR 5
+DENOMINATOR 4
+VALUE 1.25
+FORMATTED '1 ¼'
+
+INPUT '2 ½'
+REST ''
+FRACTION 1
+NUMERATOR 5
+DENOMINATOR 2
+VALUE 2.5
+FORMATTED '2 ½'
+
+INPUT '1¼'
+REST ''
+FRACTION 1
+NUMERATOR 5
+DENOMINATOR 4
+VALUE 1.25
+FORMATTED '1 ¼'
+
+INPUT '2½'
+REST ''
+FRACTION 1
+NUMERATOR 5
+DENOMINATOR 2
+VALUE 2.5
+FORMATTED '2 ½'
+
+INPUT '10.11.12'
+REST '10.11.12'
+ERROR Could not parse 10.11.12 as a number
+
+INPUT '1/2/3'
+REST '1/2/3'
+ERROR Could not parse 1/2/3 as a number
+
+INPUT '--2'
+REST '--2'
+ERROR Could not parse --2 as a number
+
+INPUT '10 11.12'
+REST ' 11.12'
+FRACTION 0
+NUMERATOR 0
+DENOMINATOR 0
+VALUE 10
+FORMATTED '10'
+
diff --git a/tests/number-data/number1.in b/tests/number-data/number1.in
new file mode 100644
index 0000000..b8a34d0
--- /dev/null
+++ b/tests/number-data/number1.in
@@ -0,0 +1,60 @@
+# the following are all valid
+123
+123/201
+10.11
+-0.001
+1/2
+1/3
+2/6
+1/0
+1/-1
+-3/-4
+
+# number words we recognize
+a dozen
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+eleven
+twelve
+
+# vulgar fractions
+¼
+½
+¾
+⅐
+⅑
+⅒
+⅓
+⅔
+⅕
+⅖
+⅗
+⅘
+⅙
+⅚
+⅛
+⅜
+⅝
+⅞
+
+# mixed numbers
+1 1/2
+2 23/47
+1 ¼
+2 ½
+1¼
+2½
+
+# now some invalid ones
+10.11.12
+1/2/3
+--2
+10 11.12
diff --git a/tests/number.c b/tests/number.c
new file mode 100644
index 0000000..c9775cc
--- /dev/null
+++ b/tests/number.c
@@ -0,0 +1,156 @@
+/* numbers.c
+ *
+ * Copyright (C) 2016 Matthias Clasen <mclasen redhat com#}#>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more &details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <locale.h>
+#include <stdio.h>
+#include <glib.h>
+#include "gr-number.h"
+#include "gr-number.c"
+
+static GString *string;
+
+static void
+test_line (const char *line)
+{
+ GrNumber number;
+ char *input;
+ g_autoptr(GError) error = NULL;
+
+ g_string_append_printf (string, "INPUT '%s'\n", line);
+
+ input = (char *)line;
+ if (!gr_number_parse (&number, &input, &error)) {
+ g_string_append_printf (string, "REST '%s'\n", input);
+ g_string_append_printf (string, "ERROR %s\n", error->message);
+ }
+ else {
+ g_autofree char *formatted;
+
+ formatted = gr_number_format (&number);
+
+ g_string_append_printf (string, "REST '%s'\n", input);
+ g_string_append_printf (string, "FRACTION %d\n", number.fraction);
+ g_string_append_printf (string, "NUMERATOR %d\n", number.num);
+ g_string_append_printf (string, "DENOMINATOR %d\n", number.denom);
+ g_string_append_printf (string, "VALUE %g\n", number.value);
+ g_string_append_printf (string, "FORMATTED '%s'\n", formatted);
+ }
+
+ g_string_append (string, "\n");
+}
+
+static void
+test_file (const char *filename)
+{
+ g_autofree char *contents = NULL;
+ gsize length;
+ g_autoptr(GError) error = NULL;
+ g_auto(GStrv) lines = NULL;
+ int i;
+
+ if (!g_file_get_contents (filename, &contents, &length, &error)) {
+ fprintf (stderr, "%s\n", error->message);
+ return;
+ }
+
+ lines = g_strsplit (contents, "\n", -1);
+ for (i = 0; lines[i]; i++) {
+ if (lines[i][0] != 0 && lines[i][0] != '#')
+ test_line (lines[i]);
+ }
+}
+
+static char *
+get_expected_filename (const char *filename)
+{
+ char *f, *p, *expected;
+
+ f = g_strdup (filename);
+ p = strstr (f, ".in");
+ if (p)
+ *p = 0;
+ expected = g_strconcat (f, ".expected", NULL);
+
+ g_free (f);
+
+ return expected;
+}
+
+static void
+test_parse (gconstpointer d)
+{
+ const char *filename = d;
+ char *expected_file;
+ char *expected;
+ GError *error = NULL;
+
+ expected_file = get_expected_filename (filename);
+
+ string = g_string_sized_new (0);
+
+ test_file (filename);
+
+ g_file_get_contents (expected_file, &expected, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (string->str, ==, expected);
+ g_free (expected);
+
+ g_string_free (string, TRUE);
+
+ g_free (expected_file);
+}
+
+int main (int argc, char *argv[])
+{
+ GDir *dir;
+ GError *error;
+ const char *name;
+ char *path;
+
+ g_setenv ("LC_ALL", "en_US.UTF-8", TRUE);
+ setlocale (LC_ALL, "");
+
+ g_test_init (&argc, &argv, NULL);
+
+ /* allow to easily generate expected output for new test cases */
+ if (argc > 1) {
+ string = g_string_sized_new (0);
+ test_file (argv[1]);
+ g_print ("%s", string->str);
+ return 0;
+ }
+
+ error = NULL;
+ path = g_test_build_filename (G_TEST_DIST, "number-data", NULL);
+ dir = g_dir_open (path, 0, &error);
+ g_free (path);
+ g_assert_no_error (error);
+ while ((name = g_dir_read_name (dir)) != NULL) {
+ if (!g_str_has_suffix (name, ".in"))
+ continue;
+
+ path = g_strdup_printf ("/number/parse/%s", name);
+ g_test_add_data_func_full (path, g_test_build_filename (G_TEST_DIST, "number-data", name,
NULL),
+ test_parse, g_free);
+ g_free (path);
+ }
+ g_dir_close (dir);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]