Fix bug in parsing TEL content. Rework unit tests.
- newVC3_Tel was not assigning the value provided to the constructed object. - Private unit tests were run every time the code was compiled due to how the unittest library works. These now only run as part of the unit tests with `nimble test`.
This commit is contained in:
parent
7b71cb2dfe
commit
68554920e5
@ -180,11 +180,6 @@ proc getColNumber*(vcl: VCardLexer, pos: int): int =
|
|||||||
if vcl.lineStart < pos: return pos - vcl.lineStart
|
if vcl.lineStart < pos: return pos - vcl.lineStart
|
||||||
else: return (vcl.buffer.len - vcl.lineStart) + pos
|
else: return (vcl.buffer.len - vcl.lineStart) + pos
|
||||||
|
|
||||||
## Unit Tests
|
|
||||||
## ============================================================================
|
|
||||||
|
|
||||||
import std/unittest
|
|
||||||
|
|
||||||
proc dumpLexerState*(l: VCardLexer): string =
|
proc dumpLexerState*(l: VCardLexer): string =
|
||||||
result =
|
result =
|
||||||
"pos = " & $l.pos & "\p" &
|
"pos = " & $l.pos & "\p" &
|
||||||
@ -195,7 +190,9 @@ proc dumpLexerState*(l: VCardLexer): string =
|
|||||||
"bufEnd = " & $l.bufEnd & "\p" &
|
"bufEnd = " & $l.bufEnd & "\p" &
|
||||||
"buffer = " & l.buffer & "\p"
|
"buffer = " & l.buffer & "\p"
|
||||||
|
|
||||||
suite "vcard/lexer":
|
## Unit Tests
|
||||||
|
## ============================================================================
|
||||||
|
proc runVcardLexerPrivateTests*() =
|
||||||
|
|
||||||
const longTestString =
|
const longTestString =
|
||||||
"This is my test string. There are many like it but this one is mine."
|
"This is my test string. There are many like it but this one is mine."
|
||||||
@ -212,36 +209,34 @@ suite "vcard/lexer":
|
|||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
#test "fillBuffer doesn't double the buffer needlessly":
|
|
||||||
# var l: VCardLexer
|
|
||||||
|
|
||||||
proc readExpected(vcl: var VCardLexer, s: string): bool =
|
proc readExpected(vcl: var VCardLexer, s: string): bool =
|
||||||
for i in 0..<s.len:
|
for i in 0..<s.len:
|
||||||
if vcl.read != s[i]:
|
if vcl.read != s[i]:
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
test "can open and fill buffer":
|
# "can open and fill buffer":
|
||||||
|
block:
|
||||||
var l: VCardLexer
|
var l: VCardLexer
|
||||||
l.open(newStringStream("test"))
|
l.open(newStringStream("test"))
|
||||||
check:
|
assert l.bufferIs("test")
|
||||||
l.bufferIs("test")
|
assert not l.isFull
|
||||||
not l.isFull
|
assert l.readExpected("test")
|
||||||
l.readExpected("test")
|
|
||||||
|
|
||||||
test "refills buffer when emptied":
|
# "refills buffer when emptied":
|
||||||
|
block:
|
||||||
var l: VCardLexer
|
var l: VCardLexer
|
||||||
l.open(newStringStream("test"), 3)
|
l.open(newStringStream("test"), 3)
|
||||||
check:
|
assert l.bufferIs("te")
|
||||||
l.bufferIs("te")
|
assert l.isFull
|
||||||
l.isFull
|
assert l.read == 't'
|
||||||
l.read == 't'
|
assert l.read == 'e'
|
||||||
l.read == 'e'
|
assert l.read == 's'
|
||||||
l.read == 's'
|
assert l.bufferIs("st")
|
||||||
l.bufferIs("st")
|
assert l.read == 't'
|
||||||
l.read == 't'
|
|
||||||
|
|
||||||
test "isFull correctness":
|
# "isFull correctness":
|
||||||
|
block:
|
||||||
var l = VCardLexer(
|
var l = VCardLexer(
|
||||||
pos: 0,
|
pos: 0,
|
||||||
bookmark: -1,
|
bookmark: -1,
|
||||||
@ -251,104 +246,102 @@ suite "vcard/lexer":
|
|||||||
|
|
||||||
# s e
|
# s e
|
||||||
# 0 1 2 3 4 5 6 7 8 9
|
# 0 1 2 3 4 5 6 7 8 9
|
||||||
check l.isFull
|
assert l.isFull
|
||||||
|
|
||||||
# s p e
|
# s p e
|
||||||
# 0 1 2 3 4 5 6 7 8 9
|
# 0 1 2 3 4 5 6 7 8 9
|
||||||
discard l.read
|
discard l.read
|
||||||
check not l.isFull
|
assert not l.isFull
|
||||||
|
|
||||||
# e s
|
# e s
|
||||||
# 0 1 2 3 4 5 6 7 8 9
|
# 0 1 2 3 4 5 6 7 8 9
|
||||||
l.bufStart = 3
|
l.bufStart = 3
|
||||||
l.pos = 3
|
l.pos = 3
|
||||||
l.bufEnd = 2
|
l.bufEnd = 2
|
||||||
check l.isFull
|
assert l.isFull
|
||||||
|
|
||||||
# e s p
|
# e s p
|
||||||
# 0 1 2 3 4 5 6 7 8 9
|
# 0 1 2 3 4 5 6 7 8 9
|
||||||
discard l.read
|
discard l.read
|
||||||
check:
|
assert l.pos == 4
|
||||||
l.pos == 4
|
assert not l.isFull
|
||||||
not l.isFull
|
|
||||||
|
|
||||||
# e s
|
# e s
|
||||||
# 0 1 2 3 4 5 6 7 8 9
|
# 0 1 2 3 4 5 6 7 8 9
|
||||||
l.bufStart = 9
|
l.bufStart = 9
|
||||||
l.pos = 9
|
l.pos = 9
|
||||||
l.bufEnd = 8
|
l.bufEnd = 8
|
||||||
check l.isFull
|
assert l.isFull
|
||||||
|
|
||||||
# p e s
|
# p e s
|
||||||
# 0 1 2 3 4 5 6 7 8 9
|
# 0 1 2 3 4 5 6 7 8 9
|
||||||
discard l.read
|
discard l.read
|
||||||
check:
|
assert l.pos == 0
|
||||||
l.pos == 0
|
assert not l.isFull
|
||||||
not l.isFull
|
|
||||||
|
|
||||||
test "handles wrapped lines":
|
# "handles wrapped lines":
|
||||||
|
block:
|
||||||
var l: VCardLexer
|
var l: VCardLexer
|
||||||
l.open(newStringStream("line\r\n wrap\r\nline 2"), 3)
|
l.open(newStringStream("line\r\n wrap\r\nline 2"), 3)
|
||||||
|
|
||||||
check l.readExpected("line wrap\r\nline 2")
|
assert l.readExpected("line wrap\r\nline 2")
|
||||||
|
|
||||||
test "fillBuffer correctness":
|
# "fillBuffer correctness":
|
||||||
|
block:
|
||||||
var l: VCardLexer
|
var l: VCardLexer
|
||||||
l.open(newStringStream(longTestString), 5)
|
l.open(newStringStream(longTestString), 5)
|
||||||
check:
|
assert l.bufferIs(longTestString[0..<4])
|
||||||
l.bufferIs(longTestString[0..<4])
|
assert l.isFull
|
||||||
l.isFull
|
assert l.bufStart == 0
|
||||||
l.bufStart == 0
|
assert l.bufEnd == 4
|
||||||
l.bufEnd == 4
|
assert l.pos == 0
|
||||||
l.pos == 0
|
assert l.readExpected("Th")
|
||||||
l.readExpected("Th")
|
assert not l.isFull
|
||||||
not l.isFull
|
assert not l.atEnd
|
||||||
not l.atEnd
|
assert l.pos == 2
|
||||||
l.pos == 2
|
|
||||||
|
|
||||||
l.fillBuffer
|
l.fillBuffer
|
||||||
check:
|
assert l.isFull
|
||||||
l.isFull
|
assert l.bufEnd == 1
|
||||||
l.bufEnd == 1
|
assert l.pos == 2
|
||||||
l.pos == 2
|
assert l.bufStart == 2
|
||||||
l.bufStart == 2
|
|
||||||
|
|
||||||
test "bookmark preserves the buffer":
|
# "bookmark preserves the buffer":
|
||||||
|
block:
|
||||||
var l: VCardLexer
|
var l: VCardLexer
|
||||||
l.open(newStringStream(longTestString), 7)
|
l.open(newStringStream(longTestString), 7)
|
||||||
check:
|
assert l.buffer.len == 7
|
||||||
l.buffer.len == 7
|
assert l.bufferIs(longTestString[0..<6])
|
||||||
l.bufferIs(longTestString[0..<6])
|
assert l.isFull
|
||||||
l.isFull
|
assert l.bufEnd == 6
|
||||||
l.bufEnd == 6
|
assert l.pos == 0
|
||||||
l.pos == 0
|
assert l.bookmark == -1
|
||||||
l.bookmark == -1
|
assert l.readExpected(longTestString[0..<5])
|
||||||
l.readExpected(longTestString[0..<5])
|
assert not l.isFull
|
||||||
not l.isFull
|
assert not l.atEnd
|
||||||
not l.atEnd
|
assert l.pos == 5
|
||||||
l.pos == 5
|
|
||||||
|
|
||||||
l.setBookmark
|
l.setBookmark
|
||||||
# read enough to require us to refill the buffer.
|
# read enough to require us to refill the buffer.
|
||||||
check:
|
assert l.bookmark == 5
|
||||||
l.bookmark == 5
|
assert l.readExpected(longTestString[5..<10])
|
||||||
l.readExpected(longTestString[5..<10])
|
assert l.pos == 3
|
||||||
l.pos == 3
|
assert newStartIdx(l) == 5
|
||||||
newStartIdx(l) == 5
|
assert l.buffer.len == 7
|
||||||
l.buffer.len == 7
|
|
||||||
|
|
||||||
l.returnToBookmark
|
l.returnToBookmark
|
||||||
check:
|
assert l.bookmark == -1
|
||||||
l.bookmark == -1
|
assert l.pos == 5
|
||||||
l.pos == 5
|
|
||||||
|
|
||||||
test "readRune":
|
# "readRune":
|
||||||
|
block:
|
||||||
var l: VCardLexer
|
var l: VCardLexer
|
||||||
l.open(newStringStream("TEST"))
|
l.open(newStringStream("TEST"))
|
||||||
check:
|
assert l.bufferIs("TEST")
|
||||||
l.bufferIs("TEST")
|
assert l.peekRune == Rune('T')
|
||||||
l.peekRune == Rune('T')
|
assert l.readRune == Rune('T')
|
||||||
l.readRune == Rune('T')
|
assert l.readRune == Rune('E')
|
||||||
l.readRune == Rune('E')
|
assert l.readRune == Rune('S')
|
||||||
l.readRune == Rune('S')
|
assert l.readRune == Rune('T')
|
||||||
l.readRune == Rune('T')
|
|
||||||
|
when isMainModule: runVcardLexerTests()
|
||||||
|
@ -14,7 +14,7 @@ import std/[base64, macros, options, sequtils, streams, strutils, times,
|
|||||||
|
|
||||||
import zero_functional
|
import zero_functional
|
||||||
|
|
||||||
import vcard/private/[util, lexer]
|
import ./vcard/private/[util, lexer]
|
||||||
|
|
||||||
type
|
type
|
||||||
VC3_ValueTypes = enum
|
VC3_ValueTypes = enum
|
||||||
@ -381,7 +381,7 @@ func newVC3_Tel*(
|
|||||||
telType = @[$ttVoice],
|
telType = @[$ttVoice],
|
||||||
group = none[string]()): VC3_Tel =
|
group = none[string]()): VC3_Tel =
|
||||||
|
|
||||||
return VC3_Tel(name: "TEL", telType: telType, group: group)
|
return assignFields(VC3_Tel(name: "TEL"), value, telType, group)
|
||||||
|
|
||||||
func newVC3_Email*(
|
func newVC3_Email*(
|
||||||
value: string,
|
value: string,
|
||||||
@ -1712,7 +1712,7 @@ proc parseContentLines(p: var VC3Parser): seq[VC3_Content] =
|
|||||||
lat = parseFloat(partsStr[0]),
|
lat = parseFloat(partsStr[0]),
|
||||||
long = parseFloat(partsStr[1])
|
long = parseFloat(partsStr[1])
|
||||||
))
|
))
|
||||||
except:
|
except ValueError:
|
||||||
p.error("expected two float values separated by ';' for the GEO " &
|
p.error("expected two float values separated by ';' for the GEO " &
|
||||||
"content type but received '" & rawValue & "'")
|
"content type but received '" & rawValue & "'")
|
||||||
|
|
||||||
@ -1881,144 +1881,147 @@ stateDiagram-v2
|
|||||||
|
|
||||||
## Private Function Unit Tests
|
## Private Function Unit Tests
|
||||||
## ============================================================================
|
## ============================================================================
|
||||||
|
proc runVcard3PrivateTests*() =
|
||||||
import std/unittest
|
|
||||||
|
|
||||||
suite "vcard/vcard3/private":
|
|
||||||
|
|
||||||
proc initParser(input: string): VC3Parser =
|
proc initParser(input: string): VC3Parser =
|
||||||
result = VC3Parser(filename: "private unittests")
|
result = VC3Parser(filename: "private unittests")
|
||||||
lexer.open(result, newStringStream(input))
|
lexer.open(result, newStringStream(input))
|
||||||
|
|
||||||
test "readGroup with group":
|
# "vcard/vcard3/private"
|
||||||
|
block:
|
||||||
|
|
||||||
var p = initParser("mygroup.BEGIN:VCARD")
|
var p = initParser("mygroup.BEGIN:VCARD")
|
||||||
let g = p.readGroup
|
let g = p.readGroup
|
||||||
|
assert g.isSome
|
||||||
|
assert g.get == "mygroup"
|
||||||
|
|
||||||
check:
|
# "readGroup without group":
|
||||||
g.isSome
|
block:
|
||||||
g.get == "mygroup"
|
|
||||||
|
|
||||||
test "readGroup without group":
|
|
||||||
var p = initParser("BEGIN:VCARD")
|
var p = initParser("BEGIN:VCARD")
|
||||||
check p.readGroup.isNone
|
assert p.readGroup.isNone
|
||||||
|
|
||||||
test "expect (case-sensitive)":
|
# "expect (case-sensitive)":
|
||||||
|
block:
|
||||||
var p = initParser("BEGIN:VCARD")
|
var p = initParser("BEGIN:VCARD")
|
||||||
p.expect("BEGIN", true)
|
p.expect("BEGIN", true)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
p.expect(":vcard", true)
|
p.expect(":vcard", true)
|
||||||
check "" == "expect should have raised an error"
|
assert "" == "expect should have raised an error"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
|
|
||||||
test "expect (case-insensitive)":
|
# "expect (case-insensitive)":
|
||||||
|
block:
|
||||||
var p = initParser("BEGIN:VCARD")
|
var p = initParser("BEGIN:VCARD")
|
||||||
p.expect("begin")
|
p.expect("begin")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
p.expect("begin")
|
p.expect("begin")
|
||||||
check "" == "expect should have raised an error"
|
assert "" == "expect should have raised an error"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
|
|
||||||
test "readName":
|
# "readName":
|
||||||
|
block:
|
||||||
var p = initParser("TEL;tel;x-Example;x-Are1+Name")
|
var p = initParser("TEL;tel;x-Example;x-Are1+Name")
|
||||||
check:
|
assert p.readName == "TEL"
|
||||||
p.readName == "TEL"
|
assert p.read == ';'
|
||||||
p.read == ';'
|
assert p.readName == "TEL"
|
||||||
p.readName == "TEL"
|
assert p.read == ';'
|
||||||
p.read == ';'
|
assert p.readName == "X-EXAMPLE"
|
||||||
p.readName == "X-EXAMPLE"
|
assert p.read == ';'
|
||||||
p.read == ';'
|
assert p.readName == "X-ARE1"
|
||||||
p.readName == "X-ARE1"
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
discard p.readName
|
discard p.readName
|
||||||
check "" == "readName should have raised an error"
|
assert "" == "readName should have raised an error"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
|
|
||||||
test "readParamValue":
|
# "readParamValue":
|
||||||
|
block:
|
||||||
var p = initParser("TEL;TYPE=WORK;TYPE=Fun&Games%:+15551234567")
|
var p = initParser("TEL;TYPE=WORK;TYPE=Fun&Games%:+15551234567")
|
||||||
check:
|
assert p.readName == "TEL"
|
||||||
p.readName == "TEL"
|
assert p.read == ';'
|
||||||
p.read == ';'
|
assert p.readName == "TYPE"
|
||||||
p.readName == "TYPE"
|
assert p.read == '='
|
||||||
p.read == '='
|
assert p.readParamValue == "WORK"
|
||||||
p.readParamValue == "WORK"
|
assert p.read == ';'
|
||||||
p.read == ';'
|
assert p.readName == "TYPE"
|
||||||
p.readName == "TYPE"
|
assert p.read == '='
|
||||||
p.read == '='
|
assert p.readParamValue == "Fun&Games%"
|
||||||
p.readParamValue == "Fun&Games%"
|
|
||||||
|
|
||||||
test "readParams":
|
# "readParams":
|
||||||
|
block:
|
||||||
var p = initParser("TEL;TYPE=WORK;TYPE=Fun&Games%,Extra:+15551234567")
|
var p = initParser("TEL;TYPE=WORK;TYPE=Fun&Games%,Extra:+15551234567")
|
||||||
check p.readName == "TEL"
|
assert p.readName == "TEL"
|
||||||
let params = p.readParams
|
let params = p.readParams
|
||||||
check:
|
assert params.len == 2
|
||||||
params.len == 2
|
assert params[0].name == "TYPE"
|
||||||
params[0].name == "TYPE"
|
assert params[0].values.len == 1
|
||||||
params[0].values.len == 1
|
assert params[0].values[0] == "WORK"
|
||||||
params[0].values[0] == "WORK"
|
assert params[1].name == "TYPE"
|
||||||
params[1].name == "TYPE"
|
assert params[1].values.len == 2
|
||||||
params[1].values.len == 2
|
assert params[1].values[0] == "Fun&Games%"
|
||||||
params[1].values[0] == "Fun&Games%"
|
assert params[1].values[1] == "Extra"
|
||||||
params[1].values[1] == "Extra"
|
|
||||||
|
|
||||||
test "readValue":
|
# "readValue":
|
||||||
|
block:
|
||||||
var p = initParser("TEL;TYPE=WORK:+15551234567\r\nFN:John Smith\r\n")
|
var p = initParser("TEL;TYPE=WORK:+15551234567\r\nFN:John Smith\r\n")
|
||||||
check p.skip("TEL")
|
assert p.skip("TEL")
|
||||||
discard p.readParams
|
discard p.readParams
|
||||||
check p.read == ':'
|
assert p.read == ':'
|
||||||
check p.readValue == "+15551234567"
|
assert p.readValue == "+15551234567"
|
||||||
p.expect("\r\n")
|
p.expect("\r\n")
|
||||||
check p.readName == "FN"
|
assert p.readName == "FN"
|
||||||
discard p.readParams
|
discard p.readParams
|
||||||
check p.read == ':'
|
assert p.read == ':'
|
||||||
check p.readValue == "John Smith"
|
assert p.readValue == "John Smith"
|
||||||
|
|
||||||
test "readTextValueList":
|
# "readTextValueList":
|
||||||
|
block:
|
||||||
var p = initParser("Public;John;Quincey,Adams;Rev.;Esq:limited\r\n")
|
var p = initParser("Public;John;Quincey,Adams;Rev.;Esq:limited\r\n")
|
||||||
check:
|
assert p.readTextValueList == @["Public"]
|
||||||
p.readTextValueList == @["Public"]
|
assert p.readTextValueList(ifPrefix = some(';')) == @["John"]
|
||||||
p.readTextValueList(ifPrefix = some(';')) == @["John"]
|
assert p.readTextValueList(ifPrefix = some(';')) == @["Quincey", "Adams"]
|
||||||
p.readTextValueList(ifPrefix = some(';')) == @["Quincey", "Adams"]
|
assert p.readTextValueList(ifPrefix = some(';')) == @["Rev."]
|
||||||
p.readTextValueList(ifPrefix = some(';')) == @["Rev."]
|
assert p.readTextValueList(ifPrefix = some(';')) == @["Esq:limited"]
|
||||||
p.readTextValueList(ifPrefix = some(';')) == @["Esq:limited"]
|
assert p.readTextValueList(ifPrefix = some(';')) == newSeq[string]()
|
||||||
p.readTextValueList(ifPrefix = some(';')) == newSeq[string]()
|
|
||||||
|
|
||||||
test "existsWithValue":
|
# "existsWithValue":
|
||||||
|
block:
|
||||||
var p = initParser(";TYPE=WORK;TYPE=VOICE;TYPE=CELL")
|
var p = initParser(";TYPE=WORK;TYPE=VOICE;TYPE=CELL")
|
||||||
let params = p.readParams
|
let params = p.readParams
|
||||||
check:
|
assert params.existsWithValue("TYPE", "WORK")
|
||||||
params.existsWithValue("TYPE", "WORK")
|
assert params.existsWithValue("TYPE", "CELL")
|
||||||
params.existsWithValue("TYPE", "CELL")
|
assert not params.existsWithValue("TYPE", "ISDN")
|
||||||
not params.existsWithValue("TYPE", "ISDN")
|
|
||||||
|
|
||||||
test "getSingleValue":
|
# "getSingleValue":
|
||||||
|
block:
|
||||||
var p = initParser(";TYPE=WORK;TYPE=VOICE;TYPE=CELL")
|
var p = initParser(";TYPE=WORK;TYPE=VOICE;TYPE=CELL")
|
||||||
let params = p.readParams
|
let params = p.readParams
|
||||||
let val = params.getSingleValue("TYPE")
|
let val = params.getSingleValue("TYPE")
|
||||||
check:
|
assert val.isSome
|
||||||
val.isSome
|
assert val.get == "WORK"
|
||||||
val.get == "WORK"
|
assert params.getSingleValue("VALUE").isNone
|
||||||
params.getSingleValue("VALUE").isNone
|
|
||||||
|
|
||||||
test "getMultipleValues":
|
# "getMultipleValues":
|
||||||
|
block:
|
||||||
var p = initParser(";TYPE=WORK;TYPE=VOICE;TYPE=CELL")
|
var p = initParser(";TYPE=WORK;TYPE=VOICE;TYPE=CELL")
|
||||||
let params = p.readParams
|
let params = p.readParams
|
||||||
check:
|
assert params.getMultipleValues("TYPE") == @["WORK", "VOICE", "CELL"]
|
||||||
params.getMultipleValues("TYPE") == @["WORK", "VOICE", "CELL"]
|
assert params.getMultipleValues("VALUE") == newSeq[string]()
|
||||||
params.getMultipleValues("VALUE") == newSeq[string]()
|
|
||||||
|
|
||||||
test "validateNoParameters":
|
# "validateNoParameters":
|
||||||
|
block:
|
||||||
var p = initParser(";TYPE=WORK;TYPE=VOICE;TYPE=CELL")
|
var p = initParser(";TYPE=WORK;TYPE=VOICE;TYPE=CELL")
|
||||||
let params = p.readParams
|
let params = p.readParams
|
||||||
p.validateNoParameters(@[], "TEST")
|
p.validateNoParameters(@[], "TEST")
|
||||||
try:
|
try:
|
||||||
p.validateNoParameters(params, "TEST")
|
p.validateNoParameters(params, "TEST")
|
||||||
check "" == "validateNoParameters should have errored"
|
assert "" == "validateNoParameters should have errored"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
|
|
||||||
test "validateRequredParameters":
|
# "validateRequredParameters":
|
||||||
|
block:
|
||||||
var p = initParser(";CONTEXT=word;VALUE=uri;TYPE=CELL")
|
var p = initParser(";CONTEXT=word;VALUE=uri;TYPE=CELL")
|
||||||
let params = p.readParams
|
let params = p.readParams
|
||||||
p.validateRequiredParameters(params,
|
p.validateRequiredParameters(params,
|
||||||
@ -2026,5 +2029,7 @@ suite "vcard/vcard3/private":
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
p.validateRequiredParameters(params, [("TYPE", "VOICE")])
|
p.validateRequiredParameters(params, [("TYPE", "VOICE")])
|
||||||
check "" == "validateRequiredParameters should have errored"
|
assert "" == "validateRequiredParameters should have errored"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
|
|
||||||
|
when isMainModule: runVcard3PrivateTests()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
BEGIN:VCARD
|
BEGIN:VCARD
|
||||||
PRODID:-//CyrusIMAP.org//Cyrus 3.7.0-alpha0-927-gf4c98c8499-fm-202208..//EN
|
|
||||||
VERSION:3.0
|
VERSION:3.0
|
||||||
|
PRODID:-//CyrusIMAP.org//Cyrus 3.7.0-alpha0-927-gf4c98c8499-fm-202208..//EN
|
||||||
UID:cdaf67dc-b702-41ac-9c26-bb61df3032d2
|
UID:cdaf67dc-b702-41ac-9c26-bb61df3032d2
|
||||||
N:Bernard;Jonathan;;;
|
N:Bernard;Jonathan;;;
|
||||||
FN:Jonathan Bernard
|
FN:Jonathan Bernard
|
||||||
|
@ -1,2 +1,6 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import vcard/private/lexer
|
import ./vcard/private/lexer
|
||||||
|
|
||||||
|
suite "vcard/private/lexer":
|
||||||
|
test "private lexer tests":
|
||||||
|
runVcardLexerPrivateTests()
|
||||||
|
@ -1,24 +1,47 @@
|
|||||||
import options, unittest, vcard3, zero_functional
|
import options, unittest, zero_functional
|
||||||
|
|
||||||
|
import ./vcard
|
||||||
|
|
||||||
suite "vcard/vcard3":
|
suite "vcard/vcard3":
|
||||||
|
|
||||||
let testVCard =
|
test "vcard3/private tests":
|
||||||
"BEGIN:VCARD\r\n" &
|
runVcard3PrivateTests()
|
||||||
"VERSION:3.0\r\n" &
|
|
||||||
"FN:Mr. John Q. Public\\, Esq.\r\n" &
|
|
||||||
"N:Public;John;Quinlan;Mr.;Esq.\r\n" &
|
|
||||||
"END:VCARD\r\n"
|
|
||||||
|
|
||||||
test "minimal VCard":
|
let jdbVCard = readFile("tests/jdb.vcf")
|
||||||
let vc = parseVCard3(testVCard)[0]
|
let jdb = parseVCard3(jdbVCard)[0]
|
||||||
|
|
||||||
|
test "parseVCard3":
|
||||||
check:
|
check:
|
||||||
vc.n.family[0] == "Public"
|
jdb.n.family == @["Bernard"]
|
||||||
vc.n.given[0] == "John"
|
jdb.n.given == @["Jonathan"]
|
||||||
vc.fn.value == "Mr. John Q. Public\\, Esq."
|
jdb.fn.value == "Jonathan Bernard"
|
||||||
|
|
||||||
test "serialize minimal VCard":
|
test "parseVCard3File":
|
||||||
let vc = parseVCard3(testVCard)[0]
|
let jdb = parseVCard3File("tests/jdb.vcf")[0]
|
||||||
check $vc == testVCard
|
check:
|
||||||
|
jdb.email.len == 7
|
||||||
|
jdb.email[0].value == "jonathan@jdbernard.com"
|
||||||
|
jdb.email[0].emailType.contains("pref")
|
||||||
|
jdb.fn.value == "Jonathan Bernard"
|
||||||
|
|
||||||
|
test "email is parsed correctly":
|
||||||
|
check:
|
||||||
|
jdb.email.len == 7
|
||||||
|
jdb.email[0].value == "jonathan@jdbernard.com"
|
||||||
|
jdb.email[0].emailType.contains("pref")
|
||||||
|
jdb.email[0].emailType.contains("home")
|
||||||
|
jdb.email[1].value == "jdb@jdb-software.com"
|
||||||
|
jdb.email[1].emailType.contains("work")
|
||||||
|
jdb.email[2].group.isSome
|
||||||
|
jdb.email[2].group.get == "email2"
|
||||||
|
jdb.email[6].value == "jbernard@vectra.ai"
|
||||||
|
jdb.email[6].emailType.contains("work")
|
||||||
|
|
||||||
|
test "tel is parsed correctly":
|
||||||
|
check:
|
||||||
|
jdb.tel.len == 2
|
||||||
|
jdb.tel[0].value == "(512) 777-1602"
|
||||||
|
jdb.tel[0].telType.contains("CELL")
|
||||||
|
|
||||||
test "RFC2426 Author's VCards":
|
test "RFC2426 Author's VCards":
|
||||||
let vcardsStr =
|
let vcardsStr =
|
||||||
@ -53,12 +76,3 @@ suite "vcard/vcard3":
|
|||||||
vcards[0].fn.value == "Frank Dawson"
|
vcards[0].fn.value == "Frank Dawson"
|
||||||
vcards[0].email.len == 2
|
vcards[0].email.len == 2
|
||||||
(vcards[0].email --> find(it.emailType.contains("PREF"))).isSome
|
(vcards[0].email --> find(it.emailType.contains("PREF"))).isSome
|
||||||
|
|
||||||
test "Jonathan Bernard VCard":
|
|
||||||
#const jdbVcard = readFile("tests/jdb.vcf")
|
|
||||||
let jdb = parseVCard3File("tests/jdb.vcf")[0]
|
|
||||||
check:
|
|
||||||
jdb.email.len == 7
|
|
||||||
jdb.email[0].value == "jonathan@jdbernard.com"
|
|
||||||
jdb.email[0].emailType.contains("pref")
|
|
||||||
jdb.fn.value == "Jonathan Bernard"
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
author = "Jonathan Bernard"
|
author = "Jonathan Bernard"
|
||||||
description = "Nim parser for the vCard format version 3.0 (4.0 planned)."
|
description = "Nim parser for the vCard format version 3.0 (4.0 planned)."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user