tests: Add test_groups test to validate xml output

This is for multiple groups in one test to make sure they do not create
invalid xml.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 0422487..68ae4ac 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -12,6 +12,7 @@
     test_group_setup_fail
     test_fixtures
     test_group_fixtures
+    test_groups
     test_assert_macros
     test_assert_macros_fail
     test_exception_handler
@@ -142,6 +143,7 @@
 set(OUTPUT_TESTS
     test_basics
     test_assert_macros_fail
+    test_groups
     test_skip
     test_setup_fail)
 
@@ -151,32 +153,64 @@
     xml)
 
 set(test_basics_tap_out
-    "^\t1\\.\\.2[ \n\r]+\tok 1 - null_test_success[ \n\r]+\tok 2 - int_test_success[ \n\r]+ok - tests")
+    "^\t1\\.\\.2"
+    "\tok 1 - null_test_success"
+    "\tok 2 - int_test_success"
+    "ok - tests")
 set(test_assert_macros_fail_tap_out
-    "^\t1\\.\\.1[ \n\r]+\tnot ok 1 - test_assert_return_code_fail[ \n\r]+\t#[^\n\r]+[\n\r]\t#[^\n\r]+[\n\r]not ok - tests")
-
+    "^\t1\\.\\.1"
+    "\tnot ok 1 - test_assert_return_code_fail"
+    "\t#[^\n\r]+[\n\r]\t#[^\n\r]+[\n\r]not ok - tests")
+set(test_groups_tap_out
+    "^\t1\\.\\.1"
+    "\tok 1 - null_test_success"
+    "ok - test_group1"
+    "\t1\\.\\.1"
+    "\tok 1 - int_test_success"
+    "ok - test_group2")
 set(test_skip_tap_out
     "not ok 1 # SKIP")
 set(test_setup_fail_tap_out
     "not ok 1 - int_test_ignored Could not run the test - check test fixtures")
 
 set(test_basics_subunit_out
-    "^test: null_test_success[ \n\r]+success: null_test_success")
+    "^test: null_test_success"
+    "success: null_test_success")
 set(test_assert_macros_fail_subunit_out
     "failure: test_assert_return_code_fail \\[")
+set(test_groups_subunit_out
+    "^test: null_test_success"
+    "success: null_test_success")
 set(test_skip_subunit_out
-    "^test: test_check_skip[ \n\r]+skip: test_check_skip")
+    "^test: test_check_skip"
+    "skip: test_check_skip")
 set(test_setup_fail_subunit_out
     "error: int_test_ignored \\[ Could not run the test - check test fixtures \\]")
 
 set(test_basics_xml_out
-    "<testsuite name=\"tests\" time=\"[0-9.]+\" tests=\"2\" failures=\"0\" errors=\"0\" skipped=\"0\" >[ \n\r]+<testcase name=\"null_test_success\" time=\"[0-9.]+\" >.*</testcase>")
+    "<testsuite name=\"tests\" time=\"[0-9.]+\" tests=\"2\" failures=\"0\" errors=\"0\" skipped=\"0\" >"
+    "<testcase name=\"null_test_success\" time=\"[0-9.]+\" >.*</testcase>")
 set(test_assert_macros_fail_xml_out
-    "<testcase name=\"test_assert_return_code_fail\" time=\"[0-9.]+\" >[ \n\r]+<failure>")
+    "<testcase name=\"test_assert_return_code_fail\" time=\"[0-9.]+\" >"
+    "<failure>")
+set(test_groups_xml_out
+    "^<\\?xml version=\"1.0\" encoding=\"UTF-8\" \\?>"
+    "<testsuites>"
+    "<testsuite name=\"test_group1\" time=\"[0-9.]+\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\" >"
+    "<testcase name=\"null_test_success\" time=\"[0-9.]+\" >"
+    "</testcase>"
+    "</testsuite>"
+    ".*<testsuite name=\"test_group2\" time=\"[0-9.]+\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\" >"
+    "<testcase name=\"int_test_success\" time=\"[0-9.]+\" >"
+    "</testcase>"
+    "</testsuite>"
+    "</testsuites>")
 set(test_skip_xml_out
-    "<testcase name=\"test_check_skip\" time=\"[0-9.]+\" >[ \n\r]+<skipped/>")
+    "<testcase name=\"test_check_skip\" time=\"[0-9.]+\" >"
+    "<skipped/>")
 set(test_setup_fail_xml_out
-    "<testcase name=\"int_test_ignored\" time=\"[0-9.]+\" >[ \n\r]+<failure><!\\[CDATA\\[Test setup failed\\]\\]></failure>")
+    "<testcase name=\"int_test_ignored\" time=\"[0-9.]+\" >"
+    "<failure><!\\[CDATA\\[Test setup failed\\]\\]></failure>")
 
 foreach(_TEST_OUTPUT_FMT ${TEST_OUTPUT_FMTS})
     foreach(_OUTPUT_TEST ${OUTPUT_TESTS})
@@ -190,11 +224,20 @@
                 ENVIRONMENT CMOCKA_MESSAGE_OUTPUT=${_TEST_OUTPUT_FMT}
             )
 
-            set_tests_properties(
-                    ${TEST_NAME}
-                    PROPERTIES
-                    PASS_REGULAR_EXPRESSION
-                    ${${TEST_NAME}_out}
-            )
+        list(LENGTH ${TEST_NAME}_out len)
+        list(GET ${TEST_NAME}_out 0 output)
+        if(len GREATER 1)
+            list(REMOVE_AT ${TEST_NAME}_out 0)
+            foreach(line ${${TEST_NAME}_out})
+                set(output "${output}[ \n\r]+${line}")
+            endforeach()
+        endif()
+
+        set_tests_properties(
+            ${TEST_NAME}
+            PROPERTIES
+            PASS_REGULAR_EXPRESSION
+            ${output}
+        )
     endforeach()
 endforeach()
diff --git a/tests/test_groups.c b/tests/test_groups.c
new file mode 100644
index 0000000..af9e2b8
--- /dev/null
+++ b/tests/test_groups.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2016 David Schneider <schneidav81@gmail.com>
+ *
+ * Licensed 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 the unit test allocators */
+#define UNIT_TESTING 1
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+static int setup(void **state) {
+    int *answer = malloc(sizeof(int));
+
+    assert_non_null(answer);
+    *answer = 42;
+
+    *state = answer;
+
+    return 0;
+}
+
+static int teardown(void **state) {
+    free(*state);
+
+    return 0;
+}
+
+/* A test case that does nothing and succeeds. */
+static void null_test_success(void **state) {
+    (void) state;
+}
+
+/* A test case that does check if an int is equal. */
+static void int_test_success(void **state) {
+    int *answer = *state;
+
+    assert_int_equal(*answer, 42);
+}
+
+
+int main(void) {
+    const struct CMUnitTest test_group1[] = {
+        cmocka_unit_test(null_test_success),
+    };
+
+    const struct CMUnitTest test_group2[] = {
+        cmocka_unit_test_setup_teardown(int_test_success, setup, teardown),
+    };
+
+    int result = 0;
+    result += cmocka_run_group_tests(test_group1, NULL, NULL);
+    result += cmocka_run_group_tests(test_group2, NULL, NULL);
+
+    return result;
+}