195 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #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();
 | |
| }
 |