Add timespec -- add tests for it too.
This commit is contained in:
46
include/timespec.h
Normal file
46
include/timespec.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "mgos.h"
|
||||||
|
|
||||||
|
/* A simple time specifier for windows of time throughout a 24 hour day.
|
||||||
|
*
|
||||||
|
* Callers construct a struct mgos_timespec and then add time range
|
||||||
|
* specifications to the object. Ranges consist of ':', '-' and [0-9]
|
||||||
|
* characters and describe a [start-stop> time range where 'start' is
|
||||||
|
* included but 'stop' is not. Start and stop can have hours, minutes
|
||||||
|
* and seconds separated by ':'. Example specs:
|
||||||
|
* "8:00-10:00" (from 8am to 10am -- 7200 seconds)
|
||||||
|
* "23-01" (from 11pm to 1am -- 7200 seconds)
|
||||||
|
* "01:02:03-02" (from 01:02:03 to 2am -- 3477 seconds)
|
||||||
|
*
|
||||||
|
* Example to demonstrate the usage:
|
||||||
|
*
|
||||||
|
* struct tm target;
|
||||||
|
* struct mgos_timespec *ts = timespec_create();
|
||||||
|
* timespec_add_spec(ts, "8:00-10:00"); // 7200 seconds, [08:00:00 - 10:00:00>
|
||||||
|
* timespec_add_spec(ts, "23-01"); // 7200 seconds, [23:00:00 - 01:00:00>
|
||||||
|
* timespec_add_spec(ts, "01:02:03-02:03:04"); // 3661 seconds, [01:02:03 - 02:03:04>
|
||||||
|
*
|
||||||
|
* target.tm_hour=8; target.tm_min=0; target.tm_sec=0; // 08:00:00
|
||||||
|
* timespec_match(ts, &target); // TRUE; start of first spec
|
||||||
|
*
|
||||||
|
* target.tm_hour=10; target.tm_min=0; target.tm_sec=0; // 10:00:00
|
||||||
|
* timespec_match(ts, &target); // FALSE; end of first spec; end times are excluded!
|
||||||
|
*
|
||||||
|
* target.tm_hour=0; target.tm_min=0; target.tm_sec=0; // 00:00:00
|
||||||
|
* timespec_match(ts, &target); // TRUE; in the middle of the second spec
|
||||||
|
*
|
||||||
|
* target.tm_hour=1; target.tm_min=2; target.tm_sec=3; // 01:02:03
|
||||||
|
* timespec_match(ts, &target); // TRUE; the first second of the third spec
|
||||||
|
*
|
||||||
|
* target.tm_hour=2; target.tm_min=3; target.tm_sec=3; // 02:03:03
|
||||||
|
* timespec_match(ts, &target); // TRUE; the last second of the third spec
|
||||||
|
*
|
||||||
|
* timespec_destroy(&ts);
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct mgos_timespec;
|
||||||
|
|
||||||
|
struct mgos_timespec *timespec_create();
|
||||||
|
bool timespec_destroy(struct mgos_timespec **ts);
|
||||||
|
bool timespec_add_spec(struct mgos_timespec *ts, const char *spec);
|
||||||
|
bool timespec_match(const struct mgos_timespec *ts, const struct tm *tm);
|
193
src/timespec.c
Normal file
193
src/timespec.c
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
#include "timespec.h"
|
||||||
|
|
||||||
|
/* Private prototypes and declarations */
|
||||||
|
struct mgos_timespec_spec {
|
||||||
|
uint8_t start_h, start_m, start_s;
|
||||||
|
uint8_t stop_h, stop_m, stop_s;
|
||||||
|
SLIST_ENTRY(mgos_timespec_spec) entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mgos_timespec {
|
||||||
|
SLIST_HEAD(mgos_timespec_specs, mgos_timespec_spec) specs;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool timespec_spec_parse(const char *spec, struct mgos_timespec_spec *out) {
|
||||||
|
uint8_t start_h = 0, start_m = 0, start_s = 0;
|
||||||
|
uint8_t stop_h = 0, stop_m = 0, stop_s = 0;
|
||||||
|
char * p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!spec || strlen(spec) == 0) {
|
||||||
|
LOG(LL_ERROR, ("spec cannot be NULL or empty"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 1; i < (int) strlen(spec); i++) {
|
||||||
|
if (spec[i] != ':' && spec[i] != '-' && !(spec[i] >= '0' && spec[i] <= '9')) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': illegal chars, only want [:\\-0-9]", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
p = (char *)spec;
|
||||||
|
if (!isdigit((int)*p)) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': start time must begin with a digit", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// start_h
|
||||||
|
i = strtol(p, &p, 10);
|
||||||
|
if (i < 0 || i > 23) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': start hour must be [0..23]", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
start_h = i;
|
||||||
|
if (*p == ':') {
|
||||||
|
// start_m
|
||||||
|
i = strtol(p + 1, &p, 10);
|
||||||
|
if (i < 0 || i > 59) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': start minute must be [0..59]", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
start_m = i;
|
||||||
|
}
|
||||||
|
if (*p == ':') {
|
||||||
|
// start_s
|
||||||
|
i = strtol(p + 1, &p, 10);
|
||||||
|
if (i < 0 || i > 59) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': start second must be [0..59]", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
start_s = i;
|
||||||
|
}
|
||||||
|
if (*p != '-') {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': No separator '-' found after start", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop_h
|
||||||
|
if (!isdigit((int)*(p + 1))) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': stop time must begin with a digit", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
i = strtol(p + 1, &p, 10);
|
||||||
|
if (i < 0 || i > 23) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': stop hour must be [0..23]", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stop_h = i;
|
||||||
|
if (*p == ':') {
|
||||||
|
// start_m
|
||||||
|
i = strtol(p + 1, &p, 10);
|
||||||
|
if (i < 0 || i > 59) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': stop minute must be [0..59]", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stop_m = i;
|
||||||
|
}
|
||||||
|
if (*p == ':') {
|
||||||
|
// stop_s
|
||||||
|
i = strtol(p + 1, &p, 10);
|
||||||
|
if (i < 0 || i > 59) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': stop second must be [0..59]", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stop_s = i;
|
||||||
|
}
|
||||||
|
if (*p) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s': dangling characters after stop time", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOG(LL_DEBUG, ("start=%d stop=%d", start, stop));
|
||||||
|
if (out) {
|
||||||
|
out->start_h = start_h;
|
||||||
|
out->start_m = start_m;
|
||||||
|
out->start_s = start_s;
|
||||||
|
out->stop_h = stop_h;
|
||||||
|
out->stop_m = stop_m;
|
||||||
|
out->stop_s = stop_s;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mgos_timespec *timespec_create() {
|
||||||
|
struct mgos_timespec *ts = calloc(1, sizeof(struct mgos_timespec));
|
||||||
|
|
||||||
|
if (!ts) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool timespec_destroy(struct mgos_timespec **ts) {
|
||||||
|
if (!ts) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (!SLIST_EMPTY(&(*ts)->specs)) {
|
||||||
|
struct mgos_timespec_spec *t_spec;
|
||||||
|
|
||||||
|
t_spec = SLIST_FIRST(&(*ts)->specs);
|
||||||
|
SLIST_REMOVE_HEAD(&(*ts)->specs, entries);
|
||||||
|
if (t_spec) {
|
||||||
|
// LOG(LL_DEBUG, ("Removed mgos_timespec_spec"));
|
||||||
|
free(t_spec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(*ts);
|
||||||
|
*ts = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool timespec_add_spec(struct mgos_timespec *ts, const char *spec) {
|
||||||
|
struct mgos_timespec_spec *t_spec = calloc(1, sizeof(struct mgos_timespec_spec));
|
||||||
|
|
||||||
|
if (!ts) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!t_spec) {
|
||||||
|
LOG(LL_ERROR, ("Could not alloc memory for struct mgos_timespec_spec"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!timespec_spec_parse(spec, t_spec)) {
|
||||||
|
LOG(LL_ERROR, ("spec='%s' is malformed, refusing to add", spec));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SLIST_INSERT_HEAD(&ts->specs, t_spec, entries);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool timespec_match(const struct mgos_timespec *ts, const struct tm *tm) {
|
||||||
|
struct mgos_timespec_spec *t_spec;
|
||||||
|
|
||||||
|
if (!ts) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SLIST_FOREACH(t_spec, &ts->specs, entries) {
|
||||||
|
uint32_t start, stop, target;
|
||||||
|
|
||||||
|
start = t_spec->start_h * 3600 + t_spec->start_m * 60 + t_spec->start_s;
|
||||||
|
stop = t_spec->stop_h * 3600 + t_spec->stop_m * 60 + t_spec->stop_s;
|
||||||
|
target = tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
|
||||||
|
if (start == stop) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (stop >= start) {
|
||||||
|
if (target >= start && target < stop) {
|
||||||
|
// LOG(LL_DEBUG, ("start=%d stop=%d target=%d matched", start, stop, target));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (target >= start || target < stop) {
|
||||||
|
// LOG(LL_DEBUG, ("start=%d stop=%d target=%d matched", start, stop, target));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// LOG(LL_DEBUG, ("start=%d stop=%d target=%d did not match", start, stop, target));
|
||||||
|
}
|
||||||
|
(void)tm;
|
||||||
|
return false;
|
||||||
|
}
|
@ -9,7 +9,7 @@ default: $(TARGET)
|
|||||||
all: default
|
all: default
|
||||||
|
|
||||||
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
|
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
|
||||||
SRCS = frozen/frozen.c ../src/channel.c ../src/mqtt.c ../src/statusled.c
|
SRCS = frozen/frozen.c ../src/channel.c ../src/mqtt.c ../src/statusled.c ../src/timespec.c
|
||||||
HEADERS = $(wildcard *.h)
|
HEADERS = $(wildcard *.h)
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
%.o: %.c $(HEADERS)
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
int test_failures = 0;
|
|
||||||
int assert_count = 0;
|
|
||||||
|
|
||||||
uint32_t mqtt_pub_count;
|
|
||||||
uint32_t mqtt_sub_count;
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
test_buttons();
|
test_init();
|
||||||
|
|
||||||
if (test_failures) {
|
test_buttons();
|
||||||
LOG(LL_ERROR, ("%d test failures", test_failures));
|
test_timespec();
|
||||||
return -1;
|
|
||||||
}
|
LOG(LL_INFO, ("Tests run=%d (success=%d fail=%d)", test_count_total(), test_count_success(), test_count_fail()));
|
||||||
LOG(LL_INFO, ("All tests passed, %d assertions OK", assert_count));
|
if (test_count_total() == test_count_success()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
22
unittest/test.c
Normal file
22
unittest/test.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "test.h"
|
||||||
|
|
||||||
|
uint32_t s_test_count_total;
|
||||||
|
uint32_t s_test_count_fail;
|
||||||
|
|
||||||
|
void test_init() {
|
||||||
|
s_test_count_total = 0;
|
||||||
|
s_test_count_fail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t test_count_total() {
|
||||||
|
return s_test_count_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t test_count_success() {
|
||||||
|
return s_test_count_total - s_test_count_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t test_count_fail() {
|
||||||
|
return s_test_count_fail;
|
||||||
|
}
|
||||||
|
|
@ -1,26 +1,34 @@
|
|||||||
#ifndef __TEST_H
|
#pragma once
|
||||||
#define __TEST_H
|
#include "mgos.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "frozen/frozen.h"
|
#include <stdint.h>
|
||||||
#include "mgos_mock.h"
|
#include <stdbool.h>
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
extern int test_failures;
|
extern uint32_t s_test_count_fail, s_test_count_total;
|
||||||
extern int assert_count;
|
|
||||||
|
|
||||||
#define ASSERT(expr, errstr) \
|
#define ASSERT(expr, msg) \
|
||||||
do { \
|
do { \
|
||||||
|
s_test_count_total++; \
|
||||||
if (!(expr)) { \
|
if (!(expr)) { \
|
||||||
LOG(LL_ERROR, ("ASSERT FAIL: "errstr)); \
|
LOG(LL_ERROR, ("TEST FAILURE line=%d expr='%s' msg='%s'", __LINE__, #expr, msg)); \
|
||||||
test_failures++; \
|
s_test_count_fail++; \
|
||||||
|
} else { \
|
||||||
|
LOG(LL_INFO, ("TEST PASS line=%d expr='%s' msg='%s'", __LINE__, #expr, msg)); \
|
||||||
} \
|
} \
|
||||||
assert_count++; \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define RUN_TEST(test) \
|
||||||
|
do { \
|
||||||
|
const char *msg = test(); \
|
||||||
|
if (msg) { return msg; } \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
void test_init();
|
||||||
|
uint32_t test_count_total();
|
||||||
|
uint32_t test_count_success();
|
||||||
|
uint32_t test_count_fail();
|
||||||
|
|
||||||
int test_buttons(void);
|
// Insert test methods here
|
||||||
|
void test_buttons();
|
||||||
#endif // __TEST_H
|
void test_timespec();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
int test_buttons() {
|
void test_buttons() {
|
||||||
channel_init("testdata/testconfig0.json");
|
channel_init("testdata/testconfig0.json");
|
||||||
channel_init("testdata/testconfig1.json");
|
channel_init("testdata/testconfig1.json");
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
194
unittest/test_timespec.c
Normal file
194
unittest/test_timespec.c
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
#include "mgos.h"
|
||||||
|
#include "test.h"
|
||||||
|
#include "timespec.h"
|
||||||
|
|
||||||
|
static void test_timespec_pass(void) {
|
||||||
|
struct mgos_timespec *ts;
|
||||||
|
static const char * tests[] = {
|
||||||
|
"08-20",
|
||||||
|
"8-20",
|
||||||
|
"08:01-20:59",
|
||||||
|
"8:00-20",
|
||||||
|
"08:00:00-20:00:00",
|
||||||
|
"8:00:00-20:00:00",
|
||||||
|
"0-0:01",
|
||||||
|
"0-23:59:59",
|
||||||
|
"08-20:30",
|
||||||
|
"20-08",
|
||||||
|
"20:01:02-08:01:02",
|
||||||
|
"00:00-00:00",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
ts = timespec_create();
|
||||||
|
ASSERT(ts, "Created timespec");
|
||||||
|
for (int i = 0; tests[i]; i++) {
|
||||||
|
ASSERT(timespec_add_spec(ts, tests[i]), tests[i]);
|
||||||
|
}
|
||||||
|
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_timespec_fail(void) {
|
||||||
|
struct mgos_timespec *ts;
|
||||||
|
static const char * tests[] = {
|
||||||
|
"08", // No endtime given
|
||||||
|
"08-", // No endtime given
|
||||||
|
"-20", // No begintime given
|
||||||
|
"08:00:00:00-20", // Malformed begintime
|
||||||
|
"08:00-20:00:00:00", // Malformed endtime
|
||||||
|
"24-01", // Hours >23
|
||||||
|
"08:60-20:00", // Minutes >59
|
||||||
|
"08:59:60-20:00", // Seconds >59
|
||||||
|
"08:59:59-24:00:00", // Hours >23
|
||||||
|
"08:59:59-23:60:00", // Minutes >59
|
||||||
|
"08:59:59-23:59:60", // Seconds >59
|
||||||
|
"abc", // Invalid chars
|
||||||
|
"", // Empty spec
|
||||||
|
"-", // No times specified
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
ts = timespec_create();
|
||||||
|
ASSERT(ts, "Created timespec");
|
||||||
|
for (int i = 0; tests[i]; i++) {
|
||||||
|
ASSERT(!timespec_add_spec(ts, tests[i]), tests[i]);
|
||||||
|
}
|
||||||
|
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_timespec_flips_and_seconds(const struct mgos_timespec *ts, const uint32_t expected_flips, const uint32_t expected_seconds_on) {
|
||||||
|
struct tm target;
|
||||||
|
bool state = false;
|
||||||
|
int state_flips = 0;
|
||||||
|
int state_seconds_on = 0;
|
||||||
|
int state_seconds_off = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 86400; i++) {
|
||||||
|
target.tm_sec = i % 60;
|
||||||
|
target.tm_min = (i / 60) % 60;
|
||||||
|
target.tm_hour = (i / 3600) % 24;
|
||||||
|
if (state != timespec_match(ts, &target)) {
|
||||||
|
state = !state;
|
||||||
|
state_flips++;
|
||||||
|
LOG(LL_DEBUG, ("State flipped to %s at %02d:%02d:%02d", state ? "On" : "Off", target.tm_hour, target.tm_min, target.tm_sec));
|
||||||
|
}
|
||||||
|
if (state) {
|
||||||
|
state_seconds_on++;
|
||||||
|
} else{
|
||||||
|
state_seconds_off++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(LL_DEBUG, ("state_flips=%d state_seconds_on=%d", state_flips, state_seconds_on));
|
||||||
|
|
||||||
|
ASSERT(state_flips == expected_flips, "Want to see expected_flips number of state flips");
|
||||||
|
ASSERT(state_seconds_on == expected_seconds_on, "State seconds on should be expected_seconds_on");
|
||||||
|
ASSERT(state_seconds_on + state_seconds_off == 86400, "State seconds on + off should be 86400 seconds");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_timespec_state(void) {
|
||||||
|
struct mgos_timespec *ts = timespec_create();
|
||||||
|
struct tm target;
|
||||||
|
|
||||||
|
ASSERT(ts, "Created timespec");
|
||||||
|
ASSERT(timespec_add_spec(ts, "08-10"), "Added timespec");
|
||||||
|
ASSERT(timespec_add_spec(ts, "12:00-13:00"), "Added timespec");
|
||||||
|
ASSERT(timespec_add_spec(ts, "14:11:05-14:59:52"), "Added timespec");
|
||||||
|
ASSERT(timespec_add_spec(ts, "23:01:02-01:02:03"), "Added timespec");
|
||||||
|
ASSERT(!timespec_add_spec(ts, "14:60-15:01"), "Illegal timespec");
|
||||||
|
|
||||||
|
target.tm_sec = 59; target.tm_min = 59; target.tm_hour = 7;
|
||||||
|
ASSERT(!timespec_match(ts, &target), "No match at 07:59:59");
|
||||||
|
|
||||||
|
target.tm_sec = 0; target.tm_min = 0; target.tm_hour = 8;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 08:00:00");
|
||||||
|
|
||||||
|
target.tm_sec = 59; target.tm_min = 59; target.tm_hour = 9;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 09:59:59");
|
||||||
|
|
||||||
|
target.tm_sec = 0; target.tm_min = 0; target.tm_hour = 10;
|
||||||
|
ASSERT(!timespec_match(ts, &target), "No Match at 10:00:00");
|
||||||
|
|
||||||
|
target.tm_sec = 59; target.tm_min = 59; target.tm_hour = 11;
|
||||||
|
ASSERT(!timespec_match(ts, &target), "No match at 11:59:59");
|
||||||
|
|
||||||
|
target.tm_sec = 0; target.tm_min = 0; target.tm_hour = 12;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 12:00:00");
|
||||||
|
|
||||||
|
target.tm_sec = 59; target.tm_min = 59; target.tm_hour = 12;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 12:59:59");
|
||||||
|
|
||||||
|
target.tm_sec = 0; target.tm_min = 0; target.tm_hour = 13;
|
||||||
|
ASSERT(!timespec_match(ts, &target), "No match at 13:00:00");
|
||||||
|
|
||||||
|
target.tm_sec = 4; target.tm_min = 11; target.tm_hour = 14;
|
||||||
|
ASSERT(!timespec_match(ts, &target), "No match at 14:11:04");
|
||||||
|
|
||||||
|
target.tm_sec = 5; target.tm_min = 11; target.tm_hour = 14;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 14:11:05");
|
||||||
|
|
||||||
|
target.tm_sec = 51; target.tm_min = 59; target.tm_hour = 14;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 14:59:51");
|
||||||
|
|
||||||
|
target.tm_sec = 52; target.tm_min = 59; target.tm_hour = 14;
|
||||||
|
ASSERT(!timespec_match(ts, &target), "No match at 14:59:52");
|
||||||
|
|
||||||
|
target.tm_sec = 1; target.tm_min = 1; target.tm_hour = 23;
|
||||||
|
ASSERT(!timespec_match(ts, &target), "No match at 23:01:01");
|
||||||
|
|
||||||
|
target.tm_sec = 2; target.tm_min = 1; target.tm_hour = 23;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 23:01:02");
|
||||||
|
|
||||||
|
target.tm_sec = 59; target.tm_min = 59; target.tm_hour = 23;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 23:59:59");
|
||||||
|
|
||||||
|
target.tm_sec = 0; target.tm_min = 0; target.tm_hour = 0;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 00:00:00");
|
||||||
|
|
||||||
|
target.tm_sec = 2; target.tm_min = 2; target.tm_hour = 1;
|
||||||
|
ASSERT(timespec_match(ts, &target), "Match at 01:02:02");
|
||||||
|
|
||||||
|
target.tm_sec = 3; target.tm_min = 2; target.tm_hour = 1;
|
||||||
|
ASSERT(!timespec_match(ts, &target), "No match at 01:02:03");
|
||||||
|
|
||||||
|
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
||||||
|
|
||||||
|
// Some time counting tests
|
||||||
|
ts = timespec_create();
|
||||||
|
ASSERT(ts, "Created timespec");
|
||||||
|
ASSERT(timespec_add_spec(ts, "08-10"), "Added timespec");
|
||||||
|
test_timespec_flips_and_seconds(ts, 2, 7200);
|
||||||
|
|
||||||
|
// Zero seconds long
|
||||||
|
ASSERT(timespec_add_spec(ts, "00:00:00-00:00:00"), "Added timespec");
|
||||||
|
test_timespec_flips_and_seconds(ts, 2, 7200 + 0);
|
||||||
|
|
||||||
|
// Add two hours wrapping midnight
|
||||||
|
ASSERT(timespec_add_spec(ts, "23:00:00-01:00:00"), "Added timespec");
|
||||||
|
test_timespec_flips_and_seconds(ts, 5, 7200 + 0 + 7200);
|
||||||
|
|
||||||
|
// Add single second
|
||||||
|
ASSERT(timespec_add_spec(ts, "02:00:00-02:00:01"), "Added timespec");
|
||||||
|
test_timespec_flips_and_seconds(ts, 7, 7200 + 0 + 7200 + 1);
|
||||||
|
|
||||||
|
// Add an hour, a minute and a second
|
||||||
|
ASSERT(timespec_add_spec(ts, "03:02:03-04:03:04"), "Added timespec");
|
||||||
|
test_timespec_flips_and_seconds(ts, 9, 7200 + 0 + 7200 + 1 + 3661);
|
||||||
|
|
||||||
|
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
||||||
|
|
||||||
|
// Some other time counting tests
|
||||||
|
ts = timespec_create();
|
||||||
|
ASSERT(ts, "Created timespec");
|
||||||
|
ASSERT(timespec_add_spec(ts, "00-12"), "Added timespec");
|
||||||
|
test_timespec_flips_and_seconds(ts, 2, 12 * 60 * 60);
|
||||||
|
ASSERT(timespec_add_spec(ts, "12-00"), "Added timespec");
|
||||||
|
test_timespec_flips_and_seconds(ts, 1, 24 * 60 * 60);
|
||||||
|
|
||||||
|
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_timespec() {
|
||||||
|
test_timespec_pass();
|
||||||
|
test_timespec_fail();
|
||||||
|
test_timespec_state();
|
||||||
|
}
|
Reference in New Issue
Block a user