lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nwelln...@apache.org
Subject [lucy-commits] git commit: refs/heads/cfc-tests - Port final CFC tests to C
Date Sun, 03 Feb 2013 17:37:48 GMT
Updated Branches:
  refs/heads/cfc-tests e47ccd4cd -> 8ef152ae6


Port final CFC tests to C

Note that testing exceptions in C is not supported yet.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/8ef152ae
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/8ef152ae
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/8ef152ae

Branch: refs/heads/cfc-tests
Commit: 8ef152ae68751b99a48c6366caea972787c81d09
Parents: e47ccd4
Author: Nick Wellnhofer <wellnhofer@aevum.de>
Authored: Sun Feb 3 16:52:36 2013 +0100
Committer: Nick Wellnhofer <wellnhofer@aevum.de>
Committed: Sun Feb 3 18:36:28 2013 +0100

----------------------------------------------------------------------
 clownfish/compiler/perl/t/core/600-parser.t |   25 ++
 clownfish/compiler/src/CFCTest.c            |    1 +
 clownfish/compiler/src/CFCTest.h            |    1 +
 clownfish/compiler/src/CFCTestHierarchy.c   |   93 ++++++-
 clownfish/compiler/src/CFCTestParser.c      |  312 ++++++++++++++++++++++
 5 files changed, 427 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/8ef152ae/clownfish/compiler/perl/t/core/600-parser.t
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/core/600-parser.t b/clownfish/compiler/perl/t/core/600-parser.t
new file mode 100644
index 0000000..0311548
--- /dev/null
+++ b/clownfish/compiler/perl/t/core/600-parser.t
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+use strict;
+use warnings;
+
+use Clownfish::CFC::Test;
+
+my $test   = Clownfish::CFC::Test->new;
+my $passed = $test->run_batch('Clownfish::CFC::Model::Parser');
+
+exit($passed ? 0 : 1);
+

http://git-wip-us.apache.org/repos/asf/lucy/blob/8ef152ae/clownfish/compiler/src/CFCTest.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCTest.c b/clownfish/compiler/src/CFCTest.c
index 5e4f930..309e85f 100644
--- a/clownfish/compiler/src/CFCTest.c
+++ b/clownfish/compiler/src/CFCTest.c
@@ -126,6 +126,7 @@ static const CFCTestBatch *const S_batches[] = {
     &CFCTEST_BATCH_PARCEL,
     &CFCTEST_BATCH_FILE,
     &CFCTEST_BATCH_HIERARCHY,
+    &CFCTEST_BATCH_PARSER,
     NULL
 };
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/8ef152ae/clownfish/compiler/src/CFCTest.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCTest.h b/clownfish/compiler/src/CFCTest.h
index ac80b92..3846023 100644
--- a/clownfish/compiler/src/CFCTest.h
+++ b/clownfish/compiler/src/CFCTest.h
@@ -114,6 +114,7 @@ extern const CFCTestBatch CFCTEST_BATCH_HIERARCHY;
 extern const CFCTestBatch CFCTEST_BATCH_METHOD;
 extern const CFCTestBatch CFCTEST_BATCH_PARAM_LIST;
 extern const CFCTestBatch CFCTEST_BATCH_PARCEL;
+extern const CFCTestBatch CFCTEST_BATCH_PARSER;
 extern const CFCTestBatch CFCTEST_BATCH_SYMBOL;
 extern const CFCTestBatch CFCTEST_BATCH_TYPE;
 extern const CFCTestBatch CFCTEST_BATCH_UTIL;

http://git-wip-us.apache.org/repos/asf/lucy/blob/8ef152ae/clownfish/compiler/src/CFCTestHierarchy.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCTestHierarchy.c b/clownfish/compiler/src/CFCTestHierarchy.c
index 10bd4e2..90a586b 100644
--- a/clownfish/compiler/src/CFCTestHierarchy.c
+++ b/clownfish/compiler/src/CFCTestHierarchy.c
@@ -35,22 +35,35 @@
 #include "CFCTest.h"
 #include "CFCUtil.h"
 
+#define T_CFSOURCE        "t" CHY_DIR_SEP "cfsource"
+#define T_CFEXT           "t" CHY_DIR_SEP "cfext"
+#define T_CFDEST          "t" CHY_DIR_SEP "cfdest"
+#define T_CFDEST_INCLUDE  T_CFDEST CHY_DIR_SEP "include"
+#define T_CFDEST_SOURCE   T_CFDEST CHY_DIR_SEP "source"
+
 static void
 S_run_tests(CFCTest *test);
 
+static void
+S_run_basic_tests(CFCTest *test);
+
+static void
+S_run_include_tests(CFCTest *test);
+
 const CFCTestBatch CFCTEST_BATCH_HIERARCHY = {
     "Clownfish::CFC::Model::Hierarchy",
-    20,
+    36,
     S_run_tests
 };
 
 static void
 S_run_tests(CFCTest *test) {
-#define T_CFSOURCE        "t" CHY_DIR_SEP "cfsource"
-#define T_CFDEST          "t" CHY_DIR_SEP "cfdest"
-#define T_CFDEST_INCLUDE  T_CFDEST CHY_DIR_SEP "include"
-#define T_CFDEST_SOURCE   T_CFDEST CHY_DIR_SEP "source"
+    S_run_basic_tests(test);
+    S_run_include_tests(test);
+}
 
+static void
+S_run_basic_tests(CFCTest *test) {
     CFCHierarchy *hierarchy = CFCHierarchy_new(T_CFDEST);
     STR_EQ(test, CFCHierarchy_get_dest(hierarchy), T_CFDEST, "get_dest");
     STR_EQ(test, CFCHierarchy_get_include_dest(hierarchy), T_CFDEST_INCLUDE,
@@ -137,5 +150,75 @@ S_run_tests(CFCTest *test) {
     rmdir(T_CFDEST);
 
     CFCBase_decref((CFCBase*)hierarchy);
+    CFCClass_clear_registry();
+}
+
+static void
+S_run_include_tests(CFCTest *test) {
+    {
+        CFCHierarchy *hierarchy = CFCHierarchy_new(T_CFDEST);
+        CFCHierarchy_add_source_dir(hierarchy, T_CFEXT);
+        CFCHierarchy_add_include_dir(hierarchy, T_CFSOURCE);
+        const char **include_dirs = CFCHierarchy_get_include_dirs(hierarchy);
+        STR_EQ(test, include_dirs[0], T_CFSOURCE, "include_dirs[0]");
+        OK(test, include_dirs[1] == NULL, "include_dirs[1]");
+
+        CFCHierarchy_build(hierarchy);
+
+        CFCClass **classes    = CFCHierarchy_ordered_classes(hierarchy);
+        CFCClass  *rottweiler = NULL;;
+        int num_classes;
+        int num_source_classes = 0;
+        for (num_classes = 0; classes[num_classes]; ++num_classes) {
+            CFCClass *klass = classes[num_classes];
+            int expect_included = 1;
+            const char *class_name = CFCClass_get_class_name(klass);
+            if (strcmp(class_name, "Animal::Rottweiler") == 0) {
+                rottweiler      = klass;
+                expect_included = 0;
+                ++num_source_classes;
+            }
+            INT_EQ(test, CFCClass_included(klass), expect_included,
+                   "included");
+        }
+        INT_EQ(test, num_classes, 4, "class count");
+        INT_EQ(test, num_source_classes, 1, "source class count");
+        STR_EQ(test, CFCClass_get_class_name(CFCClass_get_parent(rottweiler)),
+               "Animal::Dog", "parent of included class");
+
+        CFCBase_decref((CFCBase*)hierarchy);
+        CFCClass_clear_registry();
+    }
+
+    {
+        CFCHierarchy *hierarchy = CFCHierarchy_new(T_CFDEST);
+        CFCHierarchy_add_source_dir(hierarchy, T_CFSOURCE);
+        CFCHierarchy_add_source_dir(hierarchy, T_CFEXT);
+
+        CFCHierarchy_build(hierarchy);
+
+        CFCClass **classes    = CFCHierarchy_ordered_classes(hierarchy);
+        CFCClass  *rottweiler = NULL;;
+        int num_classes;
+        for (num_classes = 0; classes[num_classes]; ++num_classes) {
+            CFCClass *klass = classes[num_classes];
+            const char *class_name = CFCClass_get_class_name(klass);
+            if (strcmp(class_name, "Animal::Rottweiler") == 0) {
+                rottweiler = klass;
+            }
+            OK(test, !CFCClass_included(klass), "not included");
+        }
+        INT_EQ(test, num_classes, 4, "class count");
+        OK(test, rottweiler != NULL, "found rottweiler");
+        STR_EQ(test, CFCClass_get_class_name(CFCClass_get_parent(rottweiler)),
+               "Animal::Dog", "parent of class from second source");
+
+        CFCBase_decref((CFCBase*)hierarchy);
+        CFCClass_clear_registry();
+    }
+
+    rmdir(T_CFDEST_INCLUDE);
+    rmdir(T_CFDEST_SOURCE);
+    rmdir(T_CFDEST);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/8ef152ae/clownfish/compiler/src/CFCTestParser.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCTestParser.c b/clownfish/compiler/src/CFCTestParser.c
new file mode 100644
index 0000000..f3eb1cd
--- /dev/null
+++ b/clownfish/compiler/src/CFCTestParser.c
@@ -0,0 +1,312 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define CFC_USE_TEST_MACROS
+#include "CFCBase.h"
+#include "CFCClass.h"
+#include "CFCMethod.h"
+#include "CFCParamList.h"
+#include "CFCParcel.h"
+#include "CFCParser.h"
+#include "CFCSymbol.h"
+#include "CFCTest.h"
+#include "CFCType.h"
+#include "CFCUtil.h"
+#include "CFCVariable.h"
+
+static void
+S_run_tests(CFCTest *test);
+
+static void
+S_test_initial_value(CFCTest *test, CFCParser *parser,
+                     const char *const *values, const char *type,
+                     const char *test_name);
+
+const CFCTestBatch CFCTEST_BATCH_PARSER = {
+    "Clownfish::CFC::Model::Parser",
+    192,
+    S_run_tests
+};
+
+static void
+S_run_tests(CFCTest *test) {
+    CFCParser *parser = CFCParser_new();
+    OK(test, parser != NULL, "new");
+
+    {
+        CFCParcel *fish = CFCTest_parse_parcel(test, parser, "parcel Fish;");
+
+        CFCParcel *registered = CFCParcel_new("Crustacean", "Crust", NULL);
+        CFCParcel_register(registered);
+        CFCParcel *parcel
+            = CFCTest_parse_parcel(test, parser, "parcel Crustacean;");
+        OK(test, parcel == registered, "Fetch registered parcel");
+        OK(test, CFCParser_get_parcel(parser) == parcel,
+           "parcel_definition sets internal var");
+
+        CFCBase_decref((CFCBase*)fish);
+        CFCBase_decref((CFCBase*)registered);
+        CFCBase_decref((CFCBase*)parcel);
+    }
+
+    {
+        static const char *const specifiers[8] = {
+            "foo", "_foo", "foo_yoo", "FOO", "Foo", "fOO", "f00", "foo_foo_foo"
+        };
+        for (int i = 0; i < 8; ++i) {
+            const char *specifier = specifiers[i];
+            char *src = CFCUtil_sprintf("int32_t %s;", specifier);
+            CFCVariable *var = CFCTest_parse_variable(test, parser, src);
+            STR_EQ(test, CFCVariable_micro_sym(var), specifier,
+                   "identifier/declarator: %s", specifier);
+            FREEMEM(src);
+            CFCBase_decref((CFCBase*)var);
+        }
+    }
+
+    {
+        static const char *const specifiers[6] = {
+            "void", "float", "uint32_t", "int64_t", "uint8_t", "bool"
+        };
+        for (int i = 0; i < 6; ++i) {
+            const char *specifier = specifiers[i];
+            char *src = CFCUtil_sprintf("int32_t %s;", specifier);
+            CFCBase *result = CFCParser_parse(parser, src);
+            OK(test, result == NULL,
+               "reserved word not parsed as identifier: %s", specifier);
+            FREEMEM(src);
+            CFCBase_decref(result);
+        }
+    }
+
+    {
+        static const char *const type_strings[7] = {
+            "bool", "const char *", "Obj*", "i32_t", "char[]", "long[1]",
+            "i64_t[30]"
+        };
+        for (int i = 0; i < 7; ++i) {
+            const char *type_string = type_strings[i];
+            CFCType *type = CFCTest_parse_type(test, parser, type_string);
+            CFCBase_decref((CFCBase*)type);
+        }
+    }
+
+    {
+        static const char *const class_names[7] = {
+            "ByteBuf", "Obj", "ANDMatcher", "Foo", "FooJr", "FooIII", "Foo4th"
+        };
+        for (int i = 0; i < 7; ++i) {
+            const char *class_name = class_names[i];
+            char *src      = CFCUtil_sprintf("%s*", class_name);
+            char *expected = CFCUtil_sprintf("crust_%s", class_name);
+            CFCType *type = CFCTest_parse_type(test, parser, src);
+            STR_EQ(test, CFCType_get_specifier(type), expected,
+                   "object_type_specifier: %s", class_name);
+            FREEMEM(src);
+            FREEMEM(expected);
+            CFCBase_decref((CFCBase*)type);
+        }
+    }
+
+    {
+        CFCType *type = CFCTest_parse_type(test, parser, "const char");
+        OK(test, CFCType_const(type), "type_qualifier const");
+        CFCBase_decref((CFCBase*)type);
+    }
+
+    {
+        static const char *const exposures[3] = {
+            "public", "private", "parcel"
+        };
+        static int (*const accessors[3])(CFCSymbol *sym) = {
+            CFCSymbol_public, CFCSymbol_private, CFCSymbol_parcel
+        };
+        for (int i = 0; i < 3; ++i) {
+            const char *exposure = exposures[i];
+            char *src = CFCUtil_sprintf("%s int32_t foo;", exposure);
+            CFCVariable *var = CFCTest_parse_variable(test, parser, src);
+            OK(test, accessors[i]((CFCSymbol*)var), "exposure_specifier %s",
+               exposure);
+            FREEMEM(src);
+            CFCBase_decref((CFCBase*)var);
+        }
+    }
+
+    {
+        static const char *const hex_constants[] = {
+            "0x1", "0x0a", "0xFFFFFFFF", "-0xFC", NULL
+        };
+        S_test_initial_value(test, parser, hex_constants, "int32_t",
+                             "hex_constant:");
+    }
+
+    {
+        static const char *const integer_constants[] = {
+            "1", "-9999", "0", "10000", NULL
+        };
+        S_test_initial_value(test, parser, integer_constants, "int32_t",
+                             "integer_constant:");
+    }
+
+    {
+        static const char *const float_constants[] = {
+            "1.0", "-9999.999", "0.1", "0.0", NULL
+        };
+        S_test_initial_value(test, parser, float_constants, "double",
+                             "float_constant:");
+    }
+
+    {
+        static const char *const string_literals[] = {
+            "\"blah\"", "\"blah blah\"", "\"\\\"blah\\\" \\\"blah\\\"\"", NULL
+        };
+        S_test_initial_value(test, parser, string_literals, "CharBuf*",
+                             "string_literal:");
+    }
+
+    {
+        static const char *const composites[5] = {
+            "int[]", "i32_t **", "Foo **", "Foo ***", "const void *"
+        };
+        for (int i = 0; i < 5; ++i) {
+            const char *composite = composites[i];
+            CFCType *type = CFCTest_parse_type(test, parser, composite);
+            OK(test, CFCType_is_composite(type), "composite_type: %s",
+               composite);
+            CFCBase_decref((CFCBase*)type);
+        }
+    }
+
+    {
+        static const char *const object_types[5] = {
+            "Obj *", "incremented Foo*", "decremented CharBuf *"
+        };
+        for (int i = 0; i < 3; ++i) {
+            const char *object_type = object_types[i];
+            CFCType *type = CFCTest_parse_type(test, parser, object_type);
+            OK(test, CFCType_is_object(type), "object_type: %s",
+               object_type);
+            CFCBase_decref((CFCBase*)type);
+        }
+    }
+
+    {
+        static const char *const param_list_strings[3] = {
+            "()",
+            "(int foo)",
+            "(Obj *foo, Foo **foo_ptr)"
+        };
+        for (int i = 0; i < 3; ++i) {
+            const char *param_list_string = param_list_strings[i];
+            CFCParamList *param_list
+                = CFCTest_parse_param_list(test, parser, param_list_string);
+            INT_EQ(test, CFCParamList_num_vars(param_list), i,
+                   "param list num_vars: %d", i);
+            CFCBase_decref((CFCBase*)param_list);
+        }
+    }
+
+    {
+        CFCParamList *param_list
+            = CFCTest_parse_param_list(test, parser, "(int foo, ...)");
+        OK(test, CFCParamList_variadic(param_list), "variadic param list");
+        CFCBase_decref((CFCBase*)param_list);
+    }
+
+    {
+        const char *param_list_string =
+            "(int foo = 0xFF, char *bar =\"blah\")";
+        CFCParamList *param_list
+            = CFCTest_parse_param_list(test, parser, param_list_string);
+        const char **initial_values
+            = CFCParamList_get_initial_values(param_list);
+        STR_EQ(test, initial_values[0], "0xFF",
+               "param list initial_values[0]");
+        STR_EQ(test, initial_values[1], "\"blah\"",
+               "param list initial_values[1]");
+        OK(test, initial_values[2] == NULL, "param list initial_values[2]");
+        CFCBase_decref((CFCBase*)param_list);
+    }
+
+    {
+        CFCParser_set_class_name(parser, "Stuff::Obj");
+        CFCParser_set_class_cnick(parser, "Obj");
+
+        const char *method_string =
+            "public Foo* Spew_Foo(Obj *self, uint32_t *how_many);";
+        CFCMethod *method = CFCTest_parse_method(test, parser, method_string);
+        CFCBase_decref((CFCBase*)method);
+
+        const char *var_string =
+            "private Hash *hash;";
+        CFCVariable *var = CFCTest_parse_variable(test, parser, var_string);
+        CFCBase_decref((CFCBase*)var);
+    }
+
+    {
+        static const char *const class_names[4] = {
+            "Foo", "Foo::FooJr", "Foo::FooJr::FooIII",
+            "Foo::FooJr::FooIII::Foo4th"
+        };
+        for (int i = 0; i < 4; ++i) {
+            const char *class_name = class_names[i];
+            char *class_string = CFCUtil_sprintf("class %s { }", class_name);
+            CFCClass *klass
+                = CFCTest_parse_class(test, parser, class_string);
+            STR_EQ(test, CFCClass_get_class_name(klass), class_name,
+                   "class_name: %s", class_name);
+            FREEMEM(class_string);
+            CFCBase_decref((CFCBase*)klass);
+        }
+    }
+
+    {
+        static const char *const cnicks[2] =  { "Foo", "FF" };
+        for (int i = 0; i < 2; ++i) {
+            const char *cnick = cnicks[i];
+            char *class_string
+                = CFCUtil_sprintf("class Foodie%s cnick %s { }", cnick, cnick);
+            CFCClass *klass
+                = CFCTest_parse_class(test, parser, class_string);
+            STR_EQ(test, CFCClass_get_cnick(klass), cnick, "cnick: %s", cnick);
+            FREEMEM(class_string);
+            CFCBase_decref((CFCBase*)klass);
+        }
+    }
+
+    CFCBase_decref((CFCBase*)parser);
+
+    CFCClass_clear_registry();
+    CFCParcel_reap_singletons();
+}
+
+static void
+S_test_initial_value(CFCTest *test, CFCParser *parser,
+                     const char *const *values, const char *type,
+                     const char *test_name) {
+    for (int i = 0; values[i]; ++i) {
+        const char *value = values[i];
+        char *src = CFCUtil_sprintf("(%s foo = %s)", type, value);
+        CFCParamList *param_list
+            = CFCTest_parse_param_list(test, parser, src);
+        const char **initial_values
+            = CFCParamList_get_initial_values(param_list);
+        STR_EQ(test, initial_values[0], value, "%s %s", test_name, value);
+        FREEMEM(src);
+        CFCBase_decref((CFCBase*)param_list);
+    }
+}
+


Mime
View raw message