|
| 1 | +#!/usr/bin/env tarantool |
| 2 | + |
| 3 | +local tap = require('tap') |
| 4 | +local test = tap.test("errno") |
| 5 | +local date = require('datetime') |
| 6 | + |
| 7 | +test:plan(5) |
| 8 | + |
| 9 | +test:test("Simple tests for parser", function(test) |
| 10 | + test:plan(2) |
| 11 | + test:ok(date("1970-01-01T01:00:00Z") == |
| 12 | + date {year=1970, month=1, day=1, hour=1, minute=0, second=0}) |
| 13 | + test:ok(date("1970-01-01T02:00:00+02:00") == |
| 14 | + date {year=1970, month=1, day=1, hour=2, minute=0, second=0, tz=120}) |
| 15 | +end) |
| 16 | + |
| 17 | +test:test("Multiple tests for parser (with nanoseconds)", function(test) |
| 18 | + test:plan(165) |
| 19 | + -- borrowed from p5-time-moments/t/180_from_string.t |
| 20 | + local tests = |
| 21 | + { |
| 22 | + { '1970-01-01T00:00:00Z', 0, 0, 0 }, |
| 23 | + { '1970-01-01T02:00:00+02:00', 0, 0, 120 }, |
| 24 | + { '1970-01-01T01:30:00+01:30', 0, 0, 90 }, |
| 25 | + { '1970-01-01T01:00:00+01:00', 0, 0, 60 }, |
| 26 | + { '1970-01-01T00:01:00+00:01', 0, 0, 1 }, |
| 27 | + { '1970-01-01T00:00:00+00:00', 0, 0, 0 }, |
| 28 | + { '1969-12-31T23:59:00-00:01', 0, 0, -1 }, |
| 29 | + { '1969-12-31T23:00:00-01:00', 0, 0, -60 }, |
| 30 | + { '1969-12-31T22:30:00-01:30', 0, 0, -90 }, |
| 31 | + { '1969-12-31T22:00:00-02:00', 0, 0, -120 }, |
| 32 | + { '1970-01-01T00:00:00.123456789Z', 0, 123456789, 0 }, |
| 33 | + { '1970-01-01T00:00:00.12345678Z', 0, 123456780, 0 }, |
| 34 | + { '1970-01-01T00:00:00.1234567Z', 0, 123456700, 0 }, |
| 35 | + { '1970-01-01T00:00:00.123456Z', 0, 123456000, 0 }, |
| 36 | + { '1970-01-01T00:00:00.12345Z', 0, 123450000, 0 }, |
| 37 | + { '1970-01-01T00:00:00.1234Z', 0, 123400000, 0 }, |
| 38 | + { '1970-01-01T00:00:00.123Z', 0, 123000000, 0 }, |
| 39 | + { '1970-01-01T00:00:00.12Z', 0, 120000000, 0 }, |
| 40 | + { '1970-01-01T00:00:00.1Z', 0, 100000000, 0 }, |
| 41 | + { '1970-01-01T00:00:00.01Z', 0, 10000000, 0 }, |
| 42 | + { '1970-01-01T00:00:00.001Z', 0, 1000000, 0 }, |
| 43 | + { '1970-01-01T00:00:00.0001Z', 0, 100000, 0 }, |
| 44 | + { '1970-01-01T00:00:00.00001Z', 0, 10000, 0 }, |
| 45 | + { '1970-01-01T00:00:00.000001Z', 0, 1000, 0 }, |
| 46 | + { '1970-01-01T00:00:00.0000001Z', 0, 100, 0 }, |
| 47 | + { '1970-01-01T00:00:00.00000001Z', 0, 10, 0 }, |
| 48 | + { '1970-01-01T00:00:00.000000001Z', 0, 1, 0 }, |
| 49 | + { '1970-01-01T00:00:00.000000009Z', 0, 9, 0 }, |
| 50 | + { '1970-01-01T00:00:00.00000009Z', 0, 90, 0 }, |
| 51 | + { '1970-01-01T00:00:00.0000009Z', 0, 900, 0 }, |
| 52 | + { '1970-01-01T00:00:00.000009Z', 0, 9000, 0 }, |
| 53 | + { '1970-01-01T00:00:00.00009Z', 0, 90000, 0 }, |
| 54 | + { '1970-01-01T00:00:00.0009Z', 0, 900000, 0 }, |
| 55 | + { '1970-01-01T00:00:00.009Z', 0, 9000000, 0 }, |
| 56 | + { '1970-01-01T00:00:00.09Z', 0, 90000000, 0 }, |
| 57 | + { '1970-01-01T00:00:00.9Z', 0, 900000000, 0 }, |
| 58 | + { '1970-01-01T00:00:00.99Z', 0, 990000000, 0 }, |
| 59 | + { '1970-01-01T00:00:00.999Z', 0, 999000000, 0 }, |
| 60 | + { '1970-01-01T00:00:00.9999Z', 0, 999900000, 0 }, |
| 61 | + { '1970-01-01T00:00:00.99999Z', 0, 999990000, 0 }, |
| 62 | + { '1970-01-01T00:00:00.999999Z', 0, 999999000, 0 }, |
| 63 | + { '1970-01-01T00:00:00.9999999Z', 0, 999999900, 0 }, |
| 64 | + { '1970-01-01T00:00:00.99999999Z', 0, 999999990, 0 }, |
| 65 | + { '1970-01-01T00:00:00.999999999Z', 0, 999999999, 0 }, |
| 66 | + { '1970-01-01T00:00:00.0Z', 0, 0, 0 }, |
| 67 | + { '1970-01-01T00:00:00.00Z', 0, 0, 0 }, |
| 68 | + { '1970-01-01T00:00:00.000Z', 0, 0, 0 }, |
| 69 | + { '1970-01-01T00:00:00.0000Z', 0, 0, 0 }, |
| 70 | + { '1970-01-01T00:00:00.00000Z', 0, 0, 0 }, |
| 71 | + { '1970-01-01T00:00:00.000000Z', 0, 0, 0 }, |
| 72 | + { '1970-01-01T00:00:00.0000000Z', 0, 0, 0 }, |
| 73 | + { '1970-01-01T00:00:00.00000000Z', 0, 0, 0 }, |
| 74 | + { '1970-01-01T00:00:00.000000000Z', 0, 0, 0 }, |
| 75 | + { '1973-11-29T21:33:09Z', 123456789, 0, 0 }, |
| 76 | + { '2013-10-28T17:51:56Z', 1382982716, 0, 0 }, |
| 77 | + -- { '9999-12-31T23:59:59Z', 253402300799, 0, 0 }, |
| 78 | + } |
| 79 | + for _, value in ipairs(tests) do |
| 80 | + local str, epoch, nsec, offset |
| 81 | + str, epoch, nsec, offset = unpack(value) |
| 82 | + local dt = date(str) |
| 83 | + test:ok(dt.secs == epoch, ('%s: dt.secs == %d'):format(str, epoch)) |
| 84 | + test:ok(dt.nsec == nsec, ('%s: dt.nsec == %d'):format(str, nsec)) |
| 85 | + test:ok(dt.offset == offset, ('%s: dt.offset == %d'):format(str, offset)) |
| 86 | + end |
| 87 | +end) |
| 88 | + |
| 89 | +local ffi = require('ffi') |
| 90 | + |
| 91 | +ffi.cdef [[ |
| 92 | + void tzset(void); |
| 93 | +]] |
| 94 | + |
| 95 | +test:test("Datetime string formatting", function(test) |
| 96 | + test:plan(7) |
| 97 | + local str = "1970-01-01" |
| 98 | + local t = date(str) |
| 99 | + test:ok(t.secs == 0, ('%s: t.secs == %d'):format(str, t.secs)) |
| 100 | + test:ok(t.nsec == 0, ('%s: t.nsec == %d'):format(str, t.nsec)) |
| 101 | + test:ok(t.offset == 0, ('%s: t.offset == %d'):format(str, t.offset)) |
| 102 | + test:ok(date.asctime(t) == 'Thu Jan 1 00:00:00 1970\n', ('%s: asctime'):format(str)) |
| 103 | + -- ctime() is local timezone dependent. To make sure that |
| 104 | + -- test is deterministic we enforce timezone via TZ environment |
| 105 | + -- manipulations and calling tzset() |
| 106 | + |
| 107 | + -- redefine timezone to be always GMT-2 |
| 108 | + os.setenv('TZ', 'GMT-2') |
| 109 | + ffi.C.tzset() |
| 110 | + test:ok(date.ctime(t) == 'Thu Jan 1 02:00:00 1970\n', ('%s: ctime with timezone'):format(str)) |
| 111 | + test:ok(date.strftime('%d/%m/%Y', t) == '01/01/1970', ('%s: strftime #1'):format(str)) |
| 112 | + test:ok(date.strftime('%A %d. %B %Y', t) == 'Thursday 01. January 1970', ('%s: strftime #2'):format(str)) |
| 113 | +end) |
| 114 | + |
| 115 | +test:test("Parse iso date - valid strings", function(test) |
| 116 | + test:plan(32) |
| 117 | + local good = { |
| 118 | + {2012, 12, 24, "20121224", 8 }, |
| 119 | + {2012, 12, 24, "20121224 Foo bar", 8 }, |
| 120 | + {2012, 12, 24, "2012-12-24", 10 }, |
| 121 | + {2012, 12, 24, "2012-12-24 23:59:59", 10 }, |
| 122 | + {2012, 12, 24, "2012-12-24T00:00:00+00:00", 10 }, |
| 123 | + {2012, 12, 24, "2012359", 7 }, |
| 124 | + {2012, 12, 24, "2012359T235959+0130", 7 }, |
| 125 | + {2012, 12, 24, "2012-359", 8 }, |
| 126 | + {2012, 12, 24, "2012W521", 8 }, |
| 127 | + {2012, 12, 24, "2012-W52-1", 10 }, |
| 128 | + {2012, 12, 24, "2012Q485", 8 }, |
| 129 | + {2012, 12, 24, "2012-Q4-85", 10 }, |
| 130 | + { 1, 1, 1, "0001-Q1-01", 10 }, |
| 131 | + { 1, 1, 1, "0001-W01-1", 10 }, |
| 132 | + { 1, 1, 1, "0001-01-01", 10 }, |
| 133 | + { 1, 1, 1, "0001-001", 8 }, |
| 134 | + } |
| 135 | + |
| 136 | + for _, value in ipairs(good) do |
| 137 | + local year, month, day, str, date_part_len; |
| 138 | + year, month, day, str, date_part_len = unpack(value) |
| 139 | + local expected_date = date{year = year, month = month, day = day} |
| 140 | + local date_part, len |
| 141 | + date_part, len = date.parse_date(str) |
| 142 | + test:ok(len == date_part_len, ('%s: length check %d'):format(str, len)) |
| 143 | + test:ok(expected_date == date_part, ('%s: expected date'):format(str)) |
| 144 | + end |
| 145 | +end) |
| 146 | + |
| 147 | +test:test("Parse iso date - invalid strings", function(test) |
| 148 | + test:plan(62) |
| 149 | + local bad = { |
| 150 | + "20121232" , -- Invalid day of month |
| 151 | + "2012-12-310", -- Invalid day of month |
| 152 | + "2012-13-24" , -- Invalid month |
| 153 | + "2012367" , -- Invalid day of year |
| 154 | + "2012-000" , -- Invalid day of year |
| 155 | + "2012W533" , -- Invalid week of year |
| 156 | + "2012-W52-8" , -- Invalid day of week |
| 157 | + "2012Q495" , -- Invalid day of quarter |
| 158 | + "2012-Q5-85" , -- Invalid quarter |
| 159 | + "20123670" , -- Trailing digit |
| 160 | + "201212320" , -- Trailing digit |
| 161 | + "2012-12" , -- Reduced accuracy |
| 162 | + "2012-Q4" , -- Reduced accuracy |
| 163 | + "2012-Q42" , -- Invalid |
| 164 | + "2012-Q1-1" , -- Invalid day of quarter |
| 165 | + "2012Q--420" , -- Invalid |
| 166 | + "2012-Q-420" , -- Invalid |
| 167 | + "2012Q11" , -- Incomplete |
| 168 | + "2012Q1234" , -- Trailing digit |
| 169 | + "2012W12" , -- Incomplete |
| 170 | + "2012W1234" , -- Trailing digit |
| 171 | + "2012W-123" , -- Invalid |
| 172 | + "2012-W12" , -- Incomplete |
| 173 | + "2012-W12-12", -- Trailing digit |
| 174 | + "2012U1234" , -- Invalid |
| 175 | + "2012-1234" , -- Invalid |
| 176 | + "2012-X1234" , -- Invalid |
| 177 | + "0000-Q1-01" , -- Year less than 0001 |
| 178 | + "0000-W01-1" , -- Year less than 0001 |
| 179 | + "0000-01-01" , -- Year less than 0001 |
| 180 | + "0000-001" , -- Year less than 0001 |
| 181 | + } |
| 182 | + |
| 183 | + for _, str in ipairs(bad) do |
| 184 | + local date_part, len |
| 185 | + date_part, len = date.parse_date(str) |
| 186 | + test:ok(len == 0, ('%s: length check %d'):format(str, len)) |
| 187 | + test:ok(date_part == nil, ('%s: empty date check %s'):format(str, date_part)) |
| 188 | + end |
| 189 | +end) |
| 190 | + |
| 191 | +os.exit(test:check() and 0 or 1) |
0 commit comments