VCardParserTest.swift 107 lignes · 3457 octets
import XCTest
@testable import Card2vcf

final class VCardParserTest: XCTestCase {

    // Android loaded these from test resources (vcf/sample3.vcf, vcf/sample4.vcf);
    // they are inlined here to keep the test bundle resource-free.
    private func loadFixture(_ name: String) -> String {
        switch name {
        case "sample3.vcf":
            return """
            BEGIN:VCARD
            VERSION:3.0
            FN:Alice Martin
            N:Martin;Alice;;;
            ORG:Acme
            EMAIL;TYPE=INTERNET:alice@acme.test
            TEL;TYPE=CELL:+33601020304
            NOTE:salon Lyon
            END:VCARD
            BEGIN:VCARD
            VERSION:3.0
            FN:Bob
            EMAIL:bob@unique.test
            END:VCARD
            """
        case "sample4.vcf":
            return """
            BEGIN:VCARD
            VERSION:4.0
            FN:Alice V4
            N:V4;Alice;;;
            EMAIL;TYPE=work:alice@acme.test
            TEL;TYPE=cell:+33601020304
            END:VCARD
            """
        default:
            fatalError("Unknown fixture: \(name)")
        }
    }

    func testParseSample3() {
        let cards = VCardParser.parse(loadFixture("sample3.vcf"))
        XCTAssertEqual(2, cards.count)

        let alice = cards[0]
        XCTAssertEqual("Alice Martin", alice.fullName)
        XCTAssertEqual("Alice", alice.firstName)
        XCTAssertEqual("Martin", alice.lastName)
        XCTAssertEqual("Acme", alice.company)
        XCTAssertEqual(["alice@acme.test"], alice.emails)
        XCTAssertEqual(["+33601020304"], alice.phones)
        XCTAssertEqual("salon Lyon", alice.note)

        let bob = cards[1]
        XCTAssertEqual("Bob", bob.fullName)
        XCTAssertEqual(["bob@unique.test"], bob.emails)
    }

    func testParseSample4() {
        let cards = VCardParser.parse(loadFixture("sample4.vcf"))
        XCTAssertEqual(1, cards.count)
        let alice = cards[0]
        XCTAssertEqual("Alice V4", alice.fullName)
        XCTAssertEqual(["alice@acme.test"], alice.emails)
        XCTAssertEqual(["+33601020304"], alice.phones)
    }

    func testUnfoldFoldedLine() {
        // Leading space/tab of continuation is the fold marker (dropped); extra space stays in value.
        let folded = "BEGIN:VCARD\n"
            + "VERSION:3.0\n"
            + "FN:Alice\n"
            + "  Martin\n"
            + "NOTE:hello\n"
            + "\t world\n"
            + "END:VCARD"
        let cards = VCardParser.parse(folded)
        XCTAssertEqual(1, cards.count)
        XCTAssertEqual("Alice Martin", cards[0].fullName)
        XCTAssertEqual("hello world", cards[0].note)
    }

    func testIgnorePhoto() {
        let text = """
        BEGIN:VCARD
        VERSION:3.0
        FN:Photo Person
        PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQ
        EMAIL:photo@test.example
        END:VCARD
        """
        let cards = VCardParser.parse(text)
        XCTAssertEqual(1, cards.count)
        XCTAssertEqual("Photo Person", cards[0].fullName)
        XCTAssertEqual(["photo@test.example"], cards[0].emails)
        XCTAssertNil(cards[0].note)
    }

    func testExportRoundtripVersion30() {
        let cards = VCardParser.parse(loadFixture("sample3.vcf"))
        let vcf = VCardSerializer.toVCard3(cards[0])
        XCTAssertTrue(vcf.contains("VERSION:3.0"))
        XCTAssertTrue(vcf.contains("FN:Alice Martin"))
        XCTAssertTrue(vcf.contains("ORG:Acme"))
    }
}