blob: 0b88588f57020227c626daac4f7dbad4bf967f57 [file] [log] [blame]
/**
* Copyright 2012-2016 Nest Labs Inc. All Rights Reserved.
*
* 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.
*/
/**
* @file
* This file implements functions that effect a simple, portable
* unit test suite framework.
*
*/
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <nltest.h>
/* Function Prototypes */
static void def_log_name(struct _nlTestSuite* inSuite);
static void def_log_initialize(struct _nlTestSuite * inSuite, int inResult, int inWidth);
static void def_log_terminate(struct _nlTestSuite * inSuite, int inResult, int inWidth);
static void def_log_setup(struct _nlTestSuite* inSuite, int inResult, int inWidth);
static void def_log_test(struct _nlTestSuite *inSuite, int inWidth, int inIndex);
static void def_log_teardown(struct _nlTestSuite* inSuite, int inResult, int inWidth);
static void def_log_statTest(struct _nlTestSuite* inSuite);
static void def_log_statAssert(struct _nlTestSuite* inSuite);
static void csv_log_name(struct _nlTestSuite* inSuite);
static void csv_log_initialize(struct _nlTestSuite * inSuite, int inResult, int inWidth);
static void csv_log_terminate(struct _nlTestSuite * inSuite, int inResult, int inWidth);
static void csv_log_setup(struct _nlTestSuite* inSuite, int inResult, int inWidth);
static void csv_log_test(struct _nlTestSuite *inSuite, int inWidth, int inIndex);
static void csv_log_teardown(struct _nlTestSuite* inSuite, int inResult, int inWidth);
static void csv_log_statTest(struct _nlTestSuite* inSuite);
static void csv_log_statAssert(struct _nlTestSuite* inSuite);
/* Global Variables */
static nl_test_output_logger_t nl_test_logger_default = {
def_log_name,
def_log_initialize,
def_log_terminate,
def_log_setup,
def_log_test,
def_log_teardown,
def_log_statTest,
def_log_statAssert,
};
static nl_test_output_logger_t nl_test_logger_csv = {
csv_log_name,
csv_log_initialize,
csv_log_terminate,
csv_log_setup,
csv_log_test,
csv_log_teardown,
csv_log_statTest,
csv_log_statAssert,
};
/* Global Output Style Variable */
static const nl_test_output_logger_t *logger_output = &nl_test_logger_default;
static int isSentinel(const nlTest* inTests, size_t inIndex)
{
if (inTests[inIndex].name == NULL
&& inTests[inIndex].function == NULL)
{
return 1;
}
return 0;
}
/* Human-readable (Default) Output Functions */
static void def_log_name(struct _nlTestSuite* inSuite)
{
printf("[ %s ]\n", inSuite->name);
}
static void def_log_initialize(struct _nlTestSuite * inSuite, int inResult, int inWidth)
{
printf("[ %s : %-*s ] : %s\n", inSuite->name, inWidth, "Initialize", inResult==FAILURE ? "FAILED" : "PASSED" );
}
static void def_log_terminate(struct _nlTestSuite * inSuite, int inResult, int inWidth)
{
printf("[ %s : %-*s ] : %s\n", inSuite->name, inWidth,"Terminate", inResult==FAILURE ? "FAILED" : "PASSED" );
}
static void def_log_setup(struct _nlTestSuite* inSuite, int inResult, int inWidth)
{
printf("[ %s : %-*s ] : %s\n", inSuite->name, inWidth, "Setup", inResult == FAILURE ? "FAILED" : "PASSED");
}
static void def_log_test(struct _nlTestSuite *inSuite, int inWidth, int inIndex)
{
printf("[ %s : %-*s ] : %s\n", inSuite->name, inWidth, inSuite->tests[inIndex].name, inSuite->flagError ? "FAILED" : "PASSED");
}
static void def_log_teardown(struct _nlTestSuite* inSuite, int inResult, int inWidth)
{
printf("[ %s : %-*s ] : %s\n", inSuite->name, inWidth, "TearDown", inResult == FAILURE ? "FAILED" : "PASSED");
}
static void def_log_statTest(struct _nlTestSuite* inSuite)
{
printf("Failed Tests: %d / %d\n", inSuite->failedTests, inSuite->runTests);
}
static void def_log_statAssert(struct _nlTestSuite* inSuite)
{
printf("Failed Asserts: %d / %d\n", inSuite->failedAssertions, inSuite->performedAssertions);
}
/* CSV Output Functions */
static void csv_log_name(struct _nlTestSuite* inSuite)
{
printf("'#0:','%s'\n", inSuite->name);
}
static void csv_log_initialize(struct _nlTestSuite * inSuite, int inResult, int inWidth)
{
printf("'#1:','%-*s','%s'\n", inWidth, "Initialize", inResult==FAILURE ? "FAILED" : "PASSED" );
}
static void csv_log_terminate(struct _nlTestSuite * inSuite, int inResult, int inWidth)
{
printf("'#5:','%-*s','%s'\n", inWidth,"Terminate", inResult==FAILURE ? "FAILED" : "PASSED" );
}
static void csv_log_setup(struct _nlTestSuite* inSuite, int inResult, int inWidth)
{
printf("'#2:','%-*s','%s'\n", inWidth, "Setup", inResult == FAILURE ? "FAILED" : "PASSED");
}
static void csv_log_test(struct _nlTestSuite *inSuite, int inWidth, int inIndex)
{
printf("'#3:','%-*s','%s'\n", inWidth, inSuite->tests[inIndex].name, inSuite->flagError ? "FAILED" : "PASSED");
}
static void csv_log_teardown(struct _nlTestSuite* inSuite, int inResult, int inWidth)
{
printf("'#4:','%-*s','%s'\n", inWidth, "Teardown", inResult == FAILURE ? "FAILED" : "PASSED");
}
static void csv_log_statTest(struct _nlTestSuite* inSuite)
{
printf("'#6:','%d','%d'\n", inSuite->failedTests, inSuite->runTests);
}
static void csv_log_statAssert(struct _nlTestSuite* inSuite)
{
printf("'#7:','%d','%d'\n", inSuite->failedAssertions, inSuite->performedAssertions);
}
void nlTestRunner(struct _nlTestSuite* inSuite, void* inContext)
{
int i = 0;
size_t len, max = 0;
logger_output->PrintName(inSuite);
/* Determine the maximum test name length */
for (i = 0; i < kTestSuiteMaxTests; i++)
{
if (isSentinel(inSuite->tests, i))
break;
len = strlen(inSuite->tests[i].name);
if (len > max)
max = len;
}
inSuite->runTests = 0;
inSuite->failedTests = 0;
inSuite->performedAssertions = 0;
inSuite->failedAssertions = 0;
/* Run the tests and display the test and summary result */
if (inSuite->setup != NULL)
{
int resSetup = inSuite->setup(inContext);
logger_output->PrintSetup(inSuite,resSetup, max);
}
for (i = 0; i < kTestSuiteMaxTests; i++)
{
if (isSentinel(inSuite->tests, i))
break;
if (inSuite->initialize != NULL)
{
int resInitialize = inSuite->initialize(inContext);
logger_output->PrintInitialize(inSuite,resInitialize, max);
}
inSuite->flagError = false;
inSuite->tests[i].function(inSuite, inContext);
inSuite->runTests += 1;
if (inSuite->flagError)
inSuite->failedTests += 1;
logger_output->PrintTest(inSuite, max, i);
if (inSuite->terminate != NULL)
{
int resTerminate = inSuite->terminate(inContext);
logger_output->PrintTerminate(inSuite,resTerminate, max);
}
}
if (inSuite->tear_down != NULL)
{
int resTeardown = inSuite->tear_down(inContext);
logger_output->PrintTeardown(inSuite,resTeardown, max);
}
}
int nlTestRunnerStats(struct _nlTestSuite* inSuite)
{
logger_output->PrintStatTests(inSuite);
logger_output->PrintStatAsserts(inSuite);
return 0 - inSuite->failedTests;
}
void nlTestSetOutputStyle(nlTestOutputStyle inStyle)
{
if (inStyle == OUTPUT_DEF)
{
logger_output = &nl_test_logger_default;
}
else if (inStyle == OUTPUT_CSV)
{
logger_output = &nl_test_logger_csv;
}
}
void nlTestSetLogger(const nlTestOutputLogger* inLogger)
{
logger_output = inLogger;
}