WIP: Test cases covering findings surfaced by ChatGPT.

This commit is contained in:
2026-03-28 09:58:12 -05:00
parent ab2579bdb5
commit c9de20f3a7
2 changed files with 155 additions and 2 deletions

View File

@@ -4,6 +4,19 @@ import zero_functional
import vcard
import vcard/vcard3
template vcard3Doc(lines: varargs[string]): string =
"BEGIN:VCARD\r\n" &
lines.join("\r\n") &
"\r\nEND:VCARD\r\n"
proc parseSingleVCard3(content: string): VCard3 =
cast[VCard3](parseVCards(content)[0])
proc newMinimalVCard3(): VCard3 =
result = VCard3(parsedVersion: VCardV3)
result.add(newVC3_Fn("John Smith"))
result.add(newVC3_N(family = @["Smith"], given = @["John"]))
suite "vcard/vcard3":
test "vcard3/private tests":
@@ -72,3 +85,137 @@ suite "vcard/vcard3":
cast[VCard3](vcards[0]).fn.value == "Frank Dawson"
cast[VCard3](vcards[0]).email.len == 2
(cast[VCard3](vcards[0]).email --> find(it.emailType.contains("PREF"))).isSome
test "spec: parser rejects cards missing VERSION":
expect(VCardParsingError):
discard parseVCards(vcard3Doc(
"FN:John Smith",
"N:Smith;John;;;"))
test "spec: parser rejects cards missing FN":
expect(VCardParsingError):
discard parseVCards(vcard3Doc(
"VERSION:3.0",
"N:Smith;John;;;"))
test "spec: parser rejects cards missing N":
expect(VCardParsingError):
discard parseVCards(vcard3Doc(
"VERSION:3.0",
"FN:John Smith"))
test "spec: simple text values decode RFC 2426 escapes when parsing":
let parsed = parseSingleVCard3(vcard3Doc(
"VERSION:3.0",
r"FN:Jane\, Smith\; Esq.\\Office\nSecond line",
"N:Smith;Jane;;;"))
check parsed.fn.value == "Jane, Smith; Esq.\\Office\nSecond line"
test "spec: simple text values escape special characters when serializing":
let vc = newMinimalVCard3()
vc.set(newVC3_Fn("Jane, Smith; Esq.\\Office\nSecond line"))
check ($vc).contains(r"FN:Jane\, Smith\; Esq.\\Office\nSecond line")
test "spec: structured text values escape special characters when serializing":
let vc = VCard3(parsedVersion: VCardV3)
vc.add(newVC3_Fn("John Smith"))
vc.add(newVC3_N(
family = @["Smith, Sr."],
given = @["John;Jack"],
additional = @["Back\\Slash"],
prefixes = @["Dr.\nProf."],
suffixes = @["III"]))
check ($vc).contains(r"N:Smith\, Sr.;John\;Jack;Back\\Slash;Dr.\nProf.;III")
test "spec: list text values escape special characters when serializing":
let vc = newMinimalVCard3()
vc.add(newVC3_Categories(@["alpha,beta", "semi;colon", "slash\\value"]))
check ($vc).contains(r"CATEGORIES:alpha\,beta,semi\;colon,slash\\value")
test "spec: inline binary values round-trip without double encoding":
let payload = "aGVsbG8="
let serialized = $parseSingleVCard3(vcard3Doc(
"VERSION:3.0",
"FN:John Smith",
"N:Smith;John;;;",
"PHOTO;ENCODING=b;TYPE=JPEG:" & payload,
"LOGO;ENCODING=b;TYPE=GIF:" & payload,
"SOUND;ENCODING=b;TYPE=WAVE:" & payload,
"KEY;ENCODING=b;TYPE=PGP:" & payload))
check:
serialized.contains("PHOTO;ENCODING=b;TYPE=JPEG:" & payload)
serialized.contains("LOGO;ENCODING=b;TYPE=GIF:" & payload)
serialized.contains("SOUND;ENCODING=b;TYPE=WAVE:" & payload)
serialized.contains("KEY;ENCODING=b;TYPE=PGP:" & payload)
test "spec: quoted parameter values are accepted":
let parsed = parseSingleVCard3(vcard3Doc(
"VERSION:3.0",
"FN;LANGUAGE=\"en\":John Smith",
"N:Smith;John;;;"))
check parsed.fn.language == some("en")
test "spec: PROFILE is exposed as the standard property type":
let parsed = parseSingleVCard3(vcard3Doc(
"VERSION:3.0",
"PROFILE:VCARD",
"FN:John Smith",
"N:Smith;John;;;"))
check parsed.profile.isSome
test "spec: AGENT uri values survive parse and serialize":
let serialized = $parseSingleVCard3(vcard3Doc(
"VERSION:3.0",
"FN:John Smith",
"N:Smith;John;;;",
"AGENT;VALUE=uri:mailto:assistant@example.com"))
check serialized.contains("AGENT;VALUE=uri:mailto:assistant@example.com")
test "spec: folded lines may continue with horizontal tab":
let parsed = parseSingleVCard3(
"BEGIN:VCARD\r\n" &
"VERSION:3.0\r\n" &
"FN:John Smith\r\n" &
"N:Smith;John;;;\r\n" &
"NOTE:one two \r\n" &
"\tthree four\r\n" &
"END:VCARD\r\n")
check:
parsed.note.len == 1
parsed.note[0].value == "one two three four"
test "spec: group names may contain hyphens":
let parsed = parseSingleVCard3(vcard3Doc(
"VERSION:3.0",
"FN:John Smith",
"N:Smith;John;;;",
"item-1.EMAIL:test@example.com"))
check:
parsed.email.len == 1
parsed.email[0].group == some("item-1")
test "spec: REV with VALUE=date serializes as a date":
let vc = newMinimalVCard3()
vc.add(newVC3_Rev(
value = parse("2000-01-02", "yyyy-MM-dd"),
valueType = some("date")))
check ($vc).contains("REV;VALUE=date:2000-01-02")
test "spec: KEY defaults to text rather than uri":
let vc = newMinimalVCard3()
vc.add(newVC3_Key("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC"))
check:
($vc).contains("KEY:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC")
not ($vc).contains("KEY;VALUE=uri:")

View File

@@ -68,8 +68,14 @@ suite "vcard/vcard4":
types = @["work", "internet"],
params = @[("PREF", @["1"]), ("X-ATTACHMENT-LIMIT", @["25MB"])])
check serialize(email) ==
"EMAIL;X-ATTACHMENT-LIMIT=25MB;TYPE=work,internet;PREF=1:john.smith@testco.test"
let serialized = serialize(email)
check:
serialized.startsWith("EMAIL;")
serialized.endsWith(":john.smith@testco.test")
serialized.contains(";PREF=1")
serialized.contains(";TYPE=work,internet")
serialized.contains(";X-ATTACHMENT-LIMIT=25MB")
serialized.count(';') == 3
test "can parse properties with escaped characters":
check v4Ex.note.len == 1