From 55447a2fb6a52a5529ae4a6ff4326487efde42bd Mon Sep 17 00:00:00 2001 From: szaman <2622838+szamanr@users.noreply.github.com> Date: Tue, 9 Apr 2024 08:59:02 +0000 Subject: [PATCH 1/5] update tests --- deno/lib/__tests__/string.test.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/deno/lib/__tests__/string.test.ts b/deno/lib/__tests__/string.test.ts index 5ae802ac0..ecec2871f 100644 --- a/deno/lib/__tests__/string.test.ts +++ b/deno/lib/__tests__/string.test.ts @@ -517,7 +517,19 @@ test("date", () => { test("date parsing", () => { const date = z.string().date(); date.parse("1970-01-01"); - date.parse("2022-10-13"); + date.parse("2022-01-31"); + date.parse("2022-02-29"); + date.parse("2022-03-31"); + date.parse("2022-04-30"); + date.parse("2022-05-31"); + date.parse("2022-06-30"); + date.parse("2022-07-31"); + date.parse("2022-08-31"); + date.parse("2022-09-30"); + date.parse("2022-10-31"); + date.parse("2022-11-30"); + date.parse("2022-12-31"); + expect(() => date.parse("")).toThrow(); expect(() => date.parse("foo")).toThrow(); expect(() => date.parse("200-01-01")).toThrow(); @@ -534,6 +546,17 @@ test("date parsing", () => { expect(() => date.parse("2020-10-14T17:42:29Z")).toThrow(); expect(() => date.parse("2020-10-14T17:42:29")).toThrow(); expect(() => date.parse("2020-10-14T17:42:29.123Z")).toThrow(); + + expect(() => date.parse("2000-01-32")).toThrow(); + expect(() => date.parse("2000-13-01")).toThrow(); + expect(() => date.parse("2000-21-01")).toThrow(); + + expect(() => date.parse("2000-02-30")).toThrow(); + expect(() => date.parse("2000-02-31")).toThrow(); + expect(() => date.parse("2000-04-31")).toThrow(); + expect(() => date.parse("2000-06-31")).toThrow(); + expect(() => date.parse("2000-09-31")).toThrow(); + expect(() => date.parse("2000-11-31")).toThrow(); }); test("time", () => { From fc395f66049d104bca6080761093e17b30047fec Mon Sep 17 00:00:00 2001 From: szaman <2622838+szamanr@users.noreply.github.com> Date: Tue, 9 Apr 2024 09:03:20 +0000 Subject: [PATCH 2/5] add tests for passing 00 as day or month --- deno/lib/__tests__/string.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deno/lib/__tests__/string.test.ts b/deno/lib/__tests__/string.test.ts index ecec2871f..233f8ede5 100644 --- a/deno/lib/__tests__/string.test.ts +++ b/deno/lib/__tests__/string.test.ts @@ -547,6 +547,8 @@ test("date parsing", () => { expect(() => date.parse("2020-10-14T17:42:29")).toThrow(); expect(() => date.parse("2020-10-14T17:42:29.123Z")).toThrow(); + expect(() => date.parse("2000-00-12")).toThrow(); + expect(() => date.parse("2000-12-00")).toThrow(); expect(() => date.parse("2000-01-32")).toThrow(); expect(() => date.parse("2000-13-01")).toThrow(); expect(() => date.parse("2000-21-01")).toThrow(); From 4e6f7f44a99d812c627fb6a263e50989f9775f81 Mon Sep 17 00:00:00 2001 From: szamanr Date: Thu, 11 Apr 2024 08:51:04 +0200 Subject: [PATCH 3/5] move code to src --- deno/lib/__tests__/string.test.ts | 6 +++--- deno/lib/types.ts | 3 ++- src/__tests__/string.test.ts | 27 ++++++++++++++++++++++++++- src/types.ts | 3 ++- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/deno/lib/__tests__/string.test.ts b/deno/lib/__tests__/string.test.ts index 233f8ede5..65e9c8287 100644 --- a/deno/lib/__tests__/string.test.ts +++ b/deno/lib/__tests__/string.test.ts @@ -529,7 +529,7 @@ test("date parsing", () => { date.parse("2022-10-31"); date.parse("2022-11-30"); date.parse("2022-12-31"); - + expect(() => date.parse("")).toThrow(); expect(() => date.parse("foo")).toThrow(); expect(() => date.parse("200-01-01")).toThrow(); @@ -546,13 +546,13 @@ test("date parsing", () => { expect(() => date.parse("2020-10-14T17:42:29Z")).toThrow(); expect(() => date.parse("2020-10-14T17:42:29")).toThrow(); expect(() => date.parse("2020-10-14T17:42:29.123Z")).toThrow(); - + expect(() => date.parse("2000-00-12")).toThrow(); expect(() => date.parse("2000-12-00")).toThrow(); expect(() => date.parse("2000-01-32")).toThrow(); expect(() => date.parse("2000-13-01")).toThrow(); expect(() => date.parse("2000-21-01")).toThrow(); - + expect(() => date.parse("2000-02-30")).toThrow(); expect(() => date.parse("2000-02-31")).toThrow(); expect(() => date.parse("2000-04-31")).toThrow(); diff --git a/deno/lib/types.ts b/deno/lib/types.ts index 65ff8130b..08d0b253a 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -600,7 +600,8 @@ const ipv4Regex = const ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/; -const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`; +// const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`; +const dateRegexSource = `\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\\d|2\\d))`; const dateRegex = new RegExp(`^${dateRegexSource}$`); function timeRegexSource(args: { precision?: number | null }) { diff --git a/src/__tests__/string.test.ts b/src/__tests__/string.test.ts index 7728ed734..d4fea8bb4 100644 --- a/src/__tests__/string.test.ts +++ b/src/__tests__/string.test.ts @@ -516,7 +516,19 @@ test("date", () => { test("date parsing", () => { const date = z.string().date(); date.parse("1970-01-01"); - date.parse("2022-10-13"); + date.parse("2022-01-31"); + date.parse("2022-02-29"); + date.parse("2022-03-31"); + date.parse("2022-04-30"); + date.parse("2022-05-31"); + date.parse("2022-06-30"); + date.parse("2022-07-31"); + date.parse("2022-08-31"); + date.parse("2022-09-30"); + date.parse("2022-10-31"); + date.parse("2022-11-30"); + date.parse("2022-12-31"); + expect(() => date.parse("")).toThrow(); expect(() => date.parse("foo")).toThrow(); expect(() => date.parse("200-01-01")).toThrow(); @@ -533,6 +545,19 @@ test("date parsing", () => { expect(() => date.parse("2020-10-14T17:42:29Z")).toThrow(); expect(() => date.parse("2020-10-14T17:42:29")).toThrow(); expect(() => date.parse("2020-10-14T17:42:29.123Z")).toThrow(); + + expect(() => date.parse("2000-00-12")).toThrow(); + expect(() => date.parse("2000-12-00")).toThrow(); + expect(() => date.parse("2000-01-32")).toThrow(); + expect(() => date.parse("2000-13-01")).toThrow(); + expect(() => date.parse("2000-21-01")).toThrow(); + + expect(() => date.parse("2000-02-30")).toThrow(); + expect(() => date.parse("2000-02-31")).toThrow(); + expect(() => date.parse("2000-04-31")).toThrow(); + expect(() => date.parse("2000-06-31")).toThrow(); + expect(() => date.parse("2000-09-31")).toThrow(); + expect(() => date.parse("2000-11-31")).toThrow(); }); test("time", () => { diff --git a/src/types.ts b/src/types.ts index 1b5c22cc8..541774add 100644 --- a/src/types.ts +++ b/src/types.ts @@ -600,7 +600,8 @@ const ipv4Regex = const ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/; -const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`; +// const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`; +const dateRegexSource = `\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\\d|2\\d))`; const dateRegex = new RegExp(`^${dateRegexSource}$`); function timeRegexSource(args: { precision?: number | null }) { From b966ee2a3a8b4418c8684505df7829b72a02b6d3 Mon Sep 17 00:00:00 2001 From: szamanr Date: Thu, 11 Apr 2024 08:54:12 +0200 Subject: [PATCH 4/5] make datetime only accept valid times --- deno/lib/types.ts | 3 ++- src/types.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deno/lib/types.ts b/deno/lib/types.ts index 08d0b253a..a0d349c80 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -605,7 +605,8 @@ const dateRegexSource = `\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9] const dateRegex = new RegExp(`^${dateRegexSource}$`); function timeRegexSource(args: { precision?: number | null }) { - let regex = `\\d{2}:\\d{2}:\\d{2}`; + // let regex = `\\d{2}:\\d{2}:\\d{2}`; + let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`; if (args.precision) { regex = `${regex}\\.\\d{${args.precision}}`; } else if (args.precision == null) { diff --git a/src/types.ts b/src/types.ts index 541774add..b0256b5b2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -605,7 +605,8 @@ const dateRegexSource = `\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9] const dateRegex = new RegExp(`^${dateRegexSource}$`); function timeRegexSource(args: { precision?: number | null }) { - let regex = `\\d{2}:\\d{2}:\\d{2}`; + // let regex = `\\d{2}:\\d{2}:\\d{2}`; + let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`; if (args.precision) { regex = `${regex}\\.\\d{${args.precision}}`; } else if (args.precision == null) { From 403535e4f2e74baae8ac5962e4963ed3a5bb69fb Mon Sep 17 00:00:00 2001 From: szamanr Date: Thu, 11 Apr 2024 08:57:17 +0200 Subject: [PATCH 5/5] add test cases --- deno/lib/__tests__/string.test.ts | 9 +++++++++ src/__tests__/string.test.ts | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/deno/lib/__tests__/string.test.ts b/deno/lib/__tests__/string.test.ts index 65e9c8287..f75d3abc8 100644 --- a/deno/lib/__tests__/string.test.ts +++ b/deno/lib/__tests__/string.test.ts @@ -569,6 +569,10 @@ test("time", () => { test("time parsing", () => { const time = z.string().time(); time.parse("00:00:00"); + time.parse("23:00:00"); + time.parse("00:59:00"); + time.parse("00:00:59"); + time.parse("23:59:59"); time.parse("09:52:31"); time.parse("23:59:59.9999999"); expect(() => time.parse("")).toThrow(); @@ -579,6 +583,11 @@ test("time parsing", () => { expect(() => time.parse("00:00:0")).toThrow(); expect(() => time.parse("00:00:00.000+00:00")).toThrow(); + expect(() => time.parse("24:00:00")).toThrow(); + expect(() => time.parse("00:60:00")).toThrow(); + expect(() => time.parse("00:00:60")).toThrow(); + expect(() => time.parse("24:60:60")).toThrow(); + const time2 = z.string().time({ precision: 2 }); time2.parse("00:00:00.00"); time2.parse("09:52:31.12"); diff --git a/src/__tests__/string.test.ts b/src/__tests__/string.test.ts index d4fea8bb4..6530b6be1 100644 --- a/src/__tests__/string.test.ts +++ b/src/__tests__/string.test.ts @@ -568,6 +568,10 @@ test("time", () => { test("time parsing", () => { const time = z.string().time(); time.parse("00:00:00"); + time.parse("23:00:00"); + time.parse("00:59:00"); + time.parse("00:00:59"); + time.parse("23:59:59"); time.parse("09:52:31"); time.parse("23:59:59.9999999"); expect(() => time.parse("")).toThrow(); @@ -578,6 +582,11 @@ test("time parsing", () => { expect(() => time.parse("00:00:0")).toThrow(); expect(() => time.parse("00:00:00.000+00:00")).toThrow(); + expect(() => time.parse("24:00:00")).toThrow(); + expect(() => time.parse("00:60:00")).toThrow(); + expect(() => time.parse("00:00:60")).toThrow(); + expect(() => time.parse("24:60:60")).toThrow(); + const time2 = z.string().time({ precision: 2 }); time2.parse("00:00:00.00"); time2.parse("09:52:31.12");