WIP: Test cases covering findings surfaced by ChatGPT.
This commit is contained in:
@@ -4,6 +4,19 @@ import zero_functional
|
|||||||
import vcard
|
import vcard
|
||||||
import vcard/vcard3
|
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":
|
suite "vcard/vcard3":
|
||||||
|
|
||||||
test "vcard3/private tests":
|
test "vcard3/private tests":
|
||||||
@@ -72,3 +85,137 @@ suite "vcard/vcard3":
|
|||||||
cast[VCard3](vcards[0]).fn.value == "Frank Dawson"
|
cast[VCard3](vcards[0]).fn.value == "Frank Dawson"
|
||||||
cast[VCard3](vcards[0]).email.len == 2
|
cast[VCard3](vcards[0]).email.len == 2
|
||||||
(cast[VCard3](vcards[0]).email --> find(it.emailType.contains("PREF"))).isSome
|
(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:")
|
||||||
|
|||||||
@@ -68,8 +68,14 @@ suite "vcard/vcard4":
|
|||||||
types = @["work", "internet"],
|
types = @["work", "internet"],
|
||||||
params = @[("PREF", @["1"]), ("X-ATTACHMENT-LIMIT", @["25MB"])])
|
params = @[("PREF", @["1"]), ("X-ATTACHMENT-LIMIT", @["25MB"])])
|
||||||
|
|
||||||
check serialize(email) ==
|
let serialized = serialize(email)
|
||||||
"EMAIL;X-ATTACHMENT-LIMIT=25MB;TYPE=work,internet;PREF=1:john.smith@testco.test"
|
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":
|
test "can parse properties with escaped characters":
|
||||||
check v4Ex.note.len == 1
|
check v4Ex.note.len == 1
|
||||||
|
|||||||
Reference in New Issue
Block a user