Skip to content

Commit 5fcf71c

Browse files
authored
Improve test_strptime_symmetry. NFC (#22152)
- Rename file to match test name - Convert to C - Capture detailed expectations
1 parent a864dde commit 5fcf71c

File tree

7 files changed

+99
-84
lines changed

7 files changed

+99
-84
lines changed

test/core/test_strptime_reentrant.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* found in the LICENSE file.
66
*/
77

8+
// glibc requires _XOPEN_SOURCE to be defined in order to get strptime.
9+
#define _XOPEN_SOURCE
810
#include <time.h>
911
#include <stdio.h>
1012
#include <string.h>
@@ -23,14 +25,14 @@ int main() {
2325
strptime("12", "%d", &tm) == NULL || strptime("Feb", "%b", &tm) == NULL ||
2426
strptime("13", "%M", &tm) == NULL || strptime("21", "%S", &tm) == NULL ||
2527
strptime("16", "%H", &tm) == NULL) {
26-
printf("ERR: returned NULL");
28+
printf("ERR: returned NULL\n");
2729
exit(EXIT_FAILURE);
2830
}
2931

3032
if (tm.tm_sec != 21 || tm.tm_min != 13 || tm.tm_hour != 16 ||
3133
tm.tm_mday != 12 || tm.tm_mon != 1 || tm.tm_year != 107 ||
3234
tm.tm_wday != 1 || tm.tm_yday != 42) {
33-
printf("ERR: unexpected tm content (1) - %d/%d/%d %d:%d:%d", tm.tm_mon + 1,
35+
printf("ERR: unexpected tm content (1) - %d/%d/%d %d:%d:%d\n", tm.tm_mon + 1,
3436
tm.tm_mday, tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
3537
exit(EXIT_FAILURE);
3638
}
@@ -43,10 +45,10 @@ int main() {
4345
if (tm.tm_sec != 21 || tm.tm_min != 13 || tm.tm_hour != 16 ||
4446
tm.tm_mday != 8 || tm.tm_mon != 1 || tm.tm_year != 107 ||
4547
tm.tm_wday != 4 || tm.tm_yday != 38) {
46-
printf("ERR: unexpected tm content (2) - %d/%d/%d %d:%d:%d", tm.tm_mon + 1,
48+
printf("ERR: unexpected tm content (2) - %d/%d/%d %d:%d:%d\n", tm.tm_mon + 1,
4749
tm.tm_mday, tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
4850
exit(EXIT_FAILURE);
4951
}
5052

51-
printf("OK");
53+
printf("OK\n");
5254
}

test/core/test_strptime_tm.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* found in the LICENSE file.
66
*/
77

8+
// glibc requires _XOPEN_SOURCE to be defined in order to get strptime.
9+
#define _XOPEN_SOURCE
10+
// glibc requires _DEFAULT_SOURCE to be defined in order to get tm_gmtoff.
11+
#define _DEFAULT_SOURCE
812
#include <time.h>
913
#include <stdio.h>
1014
#include <string.h>

test/other/test_strptime_symmetry.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2018 The Emscripten Authors. All rights reserved.
2+
// Emscripten is available under two separate licenses, the MIT license and the
3+
// University of Illinois/NCSA Open Source License. Both these licenses can be
4+
// found in the LICENSE file.
5+
6+
// glibc requires _XOPEN_SOURCE to be defined in order to get strptime.
7+
#define _XOPEN_SOURCE
8+
#include <assert.h>
9+
#include <time.h>
10+
#include <string.h>
11+
#include <stdio.h>
12+
#include <stdbool.h>
13+
14+
typedef struct tm TimeStruct;
15+
16+
static void formatTM(TimeStruct const tm, char* buffer) {
17+
sprintf(buffer, "%04d-%02d-%02dT%02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1,
18+
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
19+
}
20+
21+
static bool isTimeStructEqual(const TimeStruct LHS, const TimeStruct RHS) {
22+
return LHS.tm_year == RHS.tm_year && LHS.tm_mon == RHS.tm_mon && LHS.tm_mday == RHS.tm_mday &&
23+
LHS.tm_hour == RHS.tm_hour && LHS.tm_min == RHS.tm_min && LHS.tm_sec == RHS.tm_sec;
24+
}
25+
26+
bool parseAndCompare(const char* time, const char* expectedTime) {
27+
TimeStruct tm;
28+
memset(&tm, 0, sizeof(TimeStruct));
29+
assert(strptime(time, "%FT%T%z", &tm));
30+
31+
char actualTime[256];
32+
formatTM(tm, actualTime);
33+
printf("input : %s\n", time);
34+
printf("expected: %s\n", expectedTime);
35+
printf("actual : %s\n", actualTime);
36+
bool isEqual = strcmp(actualTime, expectedTime) == 0;
37+
return isEqual;
38+
}
39+
40+
// Ensure that the %c specifier can roundtrip. Meaning we use the same format
41+
// for strftime and strptime.
42+
bool roundTripCSpecifier() {
43+
TimeStruct tm;
44+
time_t t = time(NULL);
45+
memcpy(&tm, localtime(&t), sizeof(TimeStruct));
46+
47+
char timeBuffer[256];
48+
if (strftime(timeBuffer, sizeof(timeBuffer), "%c", &tm) == 0) {
49+
printf("Failed to format current time\n");
50+
return false;
51+
}
52+
53+
TimeStruct newTm;
54+
const char* lastParsed;
55+
if ((lastParsed = strptime(timeBuffer, "%c", &newTm)) == NULL) {
56+
printf("Failed to parse time string '%s'\n", timeBuffer);
57+
return false;
58+
}
59+
60+
return isTimeStructEqual(tm, newTm);
61+
}
62+
63+
int main(int argc, char** argv) {
64+
assert(parseAndCompare("2018-03-27T19:33:09+0000", "2018-03-27T19:33:09"));
65+
assert(parseAndCompare("2018-03-27T19:33:09-0735", "2018-03-27T19:33:09"));
66+
assert(parseAndCompare("2018-03-27T19:33:09+1043", "2018-03-27T19:33:09"));
67+
assert(parseAndCompare("1900-01-01T00:00:00+0000", "1900-01-01T00:00:00"));
68+
assert(parseAndCompare("2018-12-31T23:59:59+0000", "2018-12-31T23:59:59"));
69+
assert(roundTripCSpecifier());
70+
printf("TEST PASSED\n");
71+
return 0;
72+
}

test/other/test_strptime_symmetry.out

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
input : 2018-03-27T19:33:09+0000
2+
expected: 2018-03-27T19:33:09
3+
actual : 2018-03-27T19:33:09
4+
input : 2018-03-27T19:33:09-0735
5+
expected: 2018-03-27T19:33:09
6+
actual : 2018-03-27T19:33:09
7+
input : 2018-03-27T19:33:09+1043
8+
expected: 2018-03-27T19:33:09
9+
actual : 2018-03-27T19:33:09
10+
input : 1900-01-01T00:00:00+0000
11+
expected: 1900-01-01T00:00:00
12+
actual : 1900-01-01T00:00:00
13+
input : 2018-12-31T23:59:59+0000
14+
expected: 2018-12-31T23:59:59
15+
actual : 2018-12-31T23:59:59
16+
TEST PASSED

test/strptime_symmetry.cpp

Lines changed: 0 additions & 77 deletions
This file was deleted.

test/test_core.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,8 +2695,6 @@ def test_strptime_days(self):
26952695
self.do_core_test('test_strptime_days.c')
26962696

26972697
def test_strptime_reentrant(self):
2698-
# needs to flush stdio streams
2699-
self.set_setting('EXIT_RUNTIME')
27002698
self.do_core_test('test_strptime_reentrant.c')
27012699

27022700
@crossplatform

test/test_other.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5884,7 +5884,7 @@ def test_strftime_zZ(self):
58845884
self.do_runf('other/test_strftime_zZ.c', 'ok!')
58855885

58865886
def test_strptime_symmetry(self):
5887-
self.do_runf('strptime_symmetry.cpp', 'TEST PASSED')
5887+
self.do_other_test('test_strptime_symmetry.c')
58885888

58895889
@also_with_wasmfs
58905890
def test_truncate_from_0(self):

0 commit comments

Comments
 (0)