113 lines
7.9 KiB
Python
113 lines
7.9 KiB
Python
#!/usr/bin/env python3
|
||
"""Generates the shared inputs of the differential tests (tests/misc_data/*.json) with a fixed seed.
|
||
|
||
Both the Python reference driver and the C++ driver read these files, so the two sides see identical
|
||
inputs. Re-run: python3 -I tests/gen_misc_data.py (from taicpp/).
|
||
"""
|
||
import json
|
||
import os
|
||
import random
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
OUT = os.path.join(HERE, "misc_data")
|
||
|
||
|
||
def write(name, data):
|
||
os.makedirs(OUT, exist_ok=True)
|
||
with open(os.path.join(OUT, name), "w", encoding="utf-8") as handle:
|
||
json.dump(data, handle, ensure_ascii=True, indent=0)
|
||
handle.write("\n")
|
||
|
||
|
||
def json_cases():
|
||
cases = [
|
||
"{}", "[]", "null", "true", "false", "0", "-0", "1", "-1", "123456789012", "1.5", "-0.25", "1e3", "1E-7", "0.1", "1e22", "1e16", "123456789.123456789",
|
||
"0.00001", "0.0001", "100.0", "1e-5", "5e-324", "1.7976931348623157e308", "NaN", "Infinity", "-Infinity",
|
||
'"plain"', '"quote\\"inside"', '"back\\\\slash"', '"tab\\there"', '"nl\\nhere"', '"cr\\rhere"', '"\\b\\f"', '"\\u00e9"', '"\\u20ac"', '"\\ud83d\\ude00"',
|
||
'"\\u007f"', '"\\u0000"', '"\\u001f"', '"/"', '"\\/"', '"café"', '"€100"', '"\U0001f600 smile"', '"\\ud83d"',
|
||
'{"a": 1, "b": [1, 2, {"c": null}], "d": "e"}', '{"z": 1, "a": 2, "z": 3}', '[1, [2, [3, [4]]]]', ' { "x" : [ 1 , 2 ] } ',
|
||
'{"source": "tai-bundled", "mode": "bundled", "scope": "home", "files": {"SKILL.md": "abc12345"}, "installed_at": "2026-10-25T10:11:12.123456+00:00"}',
|
||
'[1,2', '{"a":}', '{"a" 1}', "{'a': 1}", '"unterminated', '[1,]', '{"a":1,}', "tru", "01", "1.", ".5", "+1", '"\\x41"', "", " ", "{} extra", '"a\nb"',
|
||
'[true, false, null, 1, 2.0, "s"]', '{"k": "\\u00e9\\u20ac\\ud83d\\ude00"}', "12345678901234567890", "-9223372036854775808", "9223372036854775807",
|
||
]
|
||
return cases
|
||
|
||
|
||
def datetime_cases():
|
||
return [
|
||
"2026-10-08T09:00", "2026-10-08 09:00", "2026-10-08", "2026-10-08T09:00:30", "2026-10-08T09:00:30.5", "2026-10-08T09:00:30.123456",
|
||
"2026-10-08T09:00:30.1234567", "2026-10-08T09:00Z", "2026-10-08T09:00:00z", "2026-10-08T09:00+02:00", "2026-10-08T09:00-05:30", "2026-10-08T09:00:00+0200",
|
||
"2026-10-08T09:00:00+02", "2026-10-08T09:00:00.25+02:00", "20261008T0900", "20261008", "20261008T090030", "2026-10-08T09", "2026-10-08T0900", "2026-10-08x09:00",
|
||
"2026-13-01", "2026-02-30", "2024-02-29T12:00", "2023-02-29T12:00", "2026-10-08T25:00", "2026-10-08T09:61", "2026-10-08T09:00:61", "now", "", " ", "tomorrow",
|
||
"2026-10-08T", "2026-10-08T09:", "2026-10-08T09:0", "2026-1-8", "26-10-08", "2026-10-08T09:00+25:00", "2026-10-08T09:00+02:00:30", " 2026-10-08T09:00 ",
|
||
"2026-10-08T09:00:00.123+01:00", "0001-01-01T00:00", "9999-12-31T23:59:59.999999", "2026-10-08T09:00 +02:00", "2026-10-08T09:00:00Z\n", "2026-03-29T02:30",
|
||
"2026-10-25T02:30", "2026-10-25T12:00:00+00:00", "2026-10-25T12:00:00.000001+00:00",
|
||
"2026-10-08T09:00x+02:00", "2026-10-08T09:00\u00a0+02:00", "2026-10-08T09:00\n+02:00", "2026-10-08T09:00:00x-02:00", "2026-10-08T09:00:00xZ", "2026-10-08T09:00:00 Z",
|
||
"2026-10-08T09 Z", "2026-10-08T0900 Z", "2026-10-08T090000 +01", "2026-10-08T09:00:00.123456789 +01", "2026-10-08T09:00:00,5 +01", "2026-10-08T09:00:00.5x+01",
|
||
"2026-10-08T09:00:00+01 ", "2026-10-08T09:00:00+0100", "2026-10-08T09:00:00+01:0", "2026-10-08T09:00:00+1", "2026-10-08T09:00:00+01:00:", "2026-10-08T09:00:00++01",
|
||
"2026-10-08T09:00:00+01Z", "2026-10-08T09:00:00 +", "2026-10-08T09:00:00-", "2026-10-08 T09:00", "2026-10-08TT09:00", "2026-10-08\u00e9", "2026-10-08\u00e909:00",
|
||
"2026-10-08\u20ac09:00", "2026-10-08T09:00:00.000001+01:00:00.5", "1999-12-31T24:00:00", "2026-10-08T24:00", "2026-10-08T24:00:00.0", "9999-12-31T24:00",
|
||
"2026-10-08T09:00:00+0100:00", "2026-10-08T09:00:00+01:00:0000", "2026-10-08T09:00:00-00:00", "2026-W01-1", "2026-W53-7", "2026-W00-1", "2026-W41-8", "2026W414",
|
||
"2026W41", "2026-W41-4T10:00", "2026-W41T10:00", "2026-10-08t09:00", "2026-10-08T09:+02:00", "2026-10-08T09:00xx+02:00", "2026-10-08T09:00:00.12345x+02:00",
|
||
"2026-10-08T09:00:00.1234567x+02:00", "2026-10-08T09:00:00.123456xy+02:00", "2026-10-08T09:0+02:00", "2026-10-08T09:00:00:00", "2026-10-08T09:00:00.5.5", "2026-10-08T0900:00",
|
||
"2026-10-08T09:0000", "2026-10-08T09:00:00+01:00:00.1234567", "2026-10-08T09:00:00+01:00:00.", "2026-W53-1", "2020-W53-5", "2015-W53-4", "2026-W41-4 10:00", "2026-W41-4x",
|
||
"2026-W41-4-10", "2026-W41-410", "2026W4141", "2026W41410", "2026-10-08T09:00-23:59", "2026-10-08T09:00+23:59:59", "2026-10-08T09:00+24:00", "2026-10-08T09:00-24:00",
|
||
"0001-01-01T00:00+00:00", "0001-01-01T00:00+01:00", "0001-01-01T00:00-01:00", "0001-01-01T10:00:00+00:00", "9999-12-31T23:59:59.999999+00:00", "9999-12-31T23:59:59+00:00",
|
||
"9999-12-31T23:59:59-01:00", "9999-12-31T00:00:00+01:00", "0001-01-01T00:00:00.000001+00:00", "1970-01-01T00:00:00", "1900-01-01T00:00:00", "1800-06-15T12:00:00",
|
||
"2026-03-29T01:59:59", "2026-03-29T02:00:00", "2026-03-29T03:00:00", "2026-10-25T01:59:59", "2026-10-25T02:00:00", "2026-10-25T03:00:00", "2026-10-25T02:59:59.999999",
|
||
"2038-01-19T03:14:08", "2100-12-31T23:59:59", "5000-01-01T00:00:00", "2026-10-08T09:00:00\u00e9", "\u2003 2026-10-08T09:00 \u2003", "2026-10-08T09:00:00,123",
|
||
"2026-02-29", "2028-02-29", "2100-02-29", "2000-02-29", "20260229", "2026-10-08T09:00:00.5+02:00", "2026-10-08T09:00:00,5+02:00", "2026-10-08T09:00:00.+02:00",
|
||
]
|
||
|
||
|
||
def duration_cases():
|
||
return ["30", "30s", "5m", "2h", "1d", "1w", "10 m", " 7D ", "0", "0s", "5x", "", "m", "-5", "5.5", "1e3", "00012h", "9999999999d", "5 M", "5mm", "5٠"]
|
||
|
||
|
||
def delay_cases():
|
||
return [-5.5, -1, -0.5, 0, 0.9, 1, 59, 59.99, 60, 61, 3599, 3600, 3601, 86399, 86400, 86401, 90061, 1000000, 1e9]
|
||
|
||
|
||
def chunk_cases():
|
||
rng = random.Random(20261025)
|
||
words = ["alpha", "beta", "gamma", "delta", "epsilon", "café", "naïve", "€", "\U0001f600", "x", "long" * 20, "", " ", "\t"]
|
||
seps = ["\n", "\r\n", "\r", "\x0b", "\x0c", "\x1c", "\x1d", "\x1e", "\x85", "
", "
"]
|
||
cases = []
|
||
fixed = [
|
||
"", "one line", "a\nb\nc", "a\n\nb\n\n\nc", "\n\n\n", " \n ", "trail\n", "\nlead", "a\r\nb\rc\x0bd\x0ce\x1cf\x1dg\x1eh\x85i
j
k",
|
||
"x" * 5000, "\n".join("line %d" % i for i in range(200)), "\n".join("w" * 50 for _ in range(100)), "é" * 4100 + "\nnext", "\n".join(["same"] * 12),
|
||
"a\nb\nb\nb\nc\nc\nd", "p\np\np\nq\nq\nq\nq\nr", "same\nsame\nsame", "\n".join(["same"] * 2 + ["other"] + ["same"] * 3),
|
||
]
|
||
for text in fixed:
|
||
cases.append({"text": text, "max_lines": 60, "overlap": 3, "max_chars": 4000})
|
||
for text in fixed[:12]:
|
||
cases.append({"text": text, "max_lines": 5, "overlap": 2, "max_chars": 40})
|
||
cases.append({"text": text, "max_lines": 3, "overlap": 0, "max_chars": 10})
|
||
cases.append({"text": text, "max_lines": 4, "overlap": 9, "max_chars": 100})
|
||
for index in range(80):
|
||
count = rng.randint(0, 150)
|
||
parts = []
|
||
for _ in range(count):
|
||
parts.append(" ".join(rng.choice(words) for _ in range(rng.randint(0, 12))))
|
||
parts.append(rng.choice(seps) if rng.random() < 0.3 else "\n")
|
||
text = "".join(parts)
|
||
cases.append({"text": text, "max_lines": rng.choice([60, 7, 13, 1, 2]), "overlap": rng.choice([3, 0, 1, 5]), "max_chars": rng.choice([4000, 120, 300, 17])})
|
||
return cases
|
||
|
||
|
||
def fts_cases():
|
||
return ["", "hello world", "Hello, World!", "café naïve", "Kelvin", "İstanbul", "a-b_c d.e", "UPPER lower 123", " ", "!!!", "x", "\"quoted\" 'single'", "tab\tsep\nnl", "éè ü", "snake_case_word", "alpha1beta2"]
|
||
|
||
|
||
def main():
|
||
write("json_cases.json", json_cases())
|
||
write("datetime_cases.json", datetime_cases())
|
||
write("duration_cases.json", duration_cases())
|
||
write("delay_cases.json", delay_cases())
|
||
write("chunk_cases.json", chunk_cases())
|
||
write("fts_cases.json", fts_cases())
|
||
print("wrote %s" % OUT)
|
||
|
||
|
||
main()
|