Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Sources/Extensions/EscapeStringConstants.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// EscapeStringConstants.swift
// iCalKit
//
// Created by Parthasarathy Gudivada on 1/31/18.
// Copyright © 2018 iCalKit. All rights reserved.
//

import Foundation


extension String {

static let escapedBackslash = "\\\\"
static let unEscapedBackslash = "\\"

static let escapedComma = "\\,"
static let unEscapedComma = ","

static let escapedSemicolon = "\\;"
static let unEscapedSemicolon = ";"

static let escapedNewline = "\\n"
static let unEscapedNewline = "\n"
}









17 changes: 17 additions & 0 deletions Sources/Extensions/String.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,20 @@ extension String {
return iCal.dateFormatter.date(from: self)
}
}

extension String {

func replacingEscapeOccurrences(_ using: [SubstituteEscapeString]) -> String {

var updatedString = self

using.forEach {
updatedString = updatedString.replacingOccurrences(of: $0.encoded,
with: $0.decoded,
options: .caseInsensitive)
}

return updatedString
}
}

26 changes: 26 additions & 0 deletions Sources/Protocols/ICALEscape.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// ICALEscape.swift
// iCalKit
//
// Created by Parthasarathy Gudivada on 1/31/18.
// Copyright © 2018 iCalKit. All rights reserved.
//

import Foundation

protocol ICALEscape {

var escapeUnescapeArray: [SubstituteEscapeString] {
get
}

func unescapedString(_ for: String) -> String
}

extension ICALEscape {

func unescapedString(_ forTheInput: String) -> String {
return forTheInput.replacingEscapeOccurrences(escapeUnescapeArray)
}
}

33 changes: 33 additions & 0 deletions Sources/RFS5545Escape.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// RFS5545Escape.swift
// iCalKit
//
// Created by Parthasarathy Gudivada on 1/31/18.
// Copyright © 2018 iCalKit. All rights reserved.
//

import Foundation




struct RFS5545Escape: ICALEscape {

let replaceComma = SubstituteEscapeString(encoded: .escapedComma,
decoded: .unEscapedComma)
let replaceSemicolon = SubstituteEscapeString(encoded: .escapedSemicolon,
decoded: .unEscapedSemicolon)
let replaceNewline = SubstituteEscapeString(encoded: .escapedNewline,
decoded: .unEscapedNewline)
// let replaceBackslash = SubstituteEscapeString(encoded: .escapedBackslash,
// decoded: .unEscapedBackslash)

var escapeUnescapeArray: [SubstituteEscapeString] {

return [replaceComma,
replaceNewline,
replaceSemicolon]
}

}

18 changes: 18 additions & 0 deletions Sources/ReplaceString.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// ReplaceString.swift
// iCalKit
//
// Created by Parthasarathy Gudivada on 1/31/18.
// Copyright © 2018 iCalKit. All rights reserved.
//

import Foundation

/**
To represent the character that gets encoded and the corresponding decoded character used in the iCAL standards.
eg., Comma (",") gets encoded as ( "\," with the backslash ) for the data interchange.
*/
struct SubstituteEscapeString {
let encoded: String
let decoded: String
}
66 changes: 66 additions & 0 deletions Tests/EscapedTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// EscapedTests.swift
// iCalKit-iOS Tests
//
// Created by Parthasarathy Gudivada on 1/31/18.
// Copyright © 2018 iCalKit. All rights reserved.
//

import XCTest
@testable import iCalKit

class EscapedTests: XCTestCase {

var exampleCals: [iCalKit.Calendar] = []

override func setUp() {
super.setUp()

let bundle = Bundle(for: type(of: self))

guard let url = bundle.url(forResource: "escapedExample", withExtension: "ics") else {
XCTAssert(false, "no test escaped ics file")
return
}

do {
let encodedCalString = try String(contentsOf: url, encoding: .utf8)
let unescapedString = RFS5545Escape().unescapedString(encodedCalString)
exampleCals = iCal.load(string: unescapedString)
} catch {
print(error.localizedDescription)
}
}

override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}

func testLoadLocalFile() {
XCTAssertTrue(exampleCals.count > 0, "we should have a calendar entry")
}

func testValidateEscpaedSummary() {

guard let cal = exampleCals.first else {
XCTAssert(false, "No Calendar found")
return
}

XCTAssertTrue(cal.subComponents.count == 2, "should have two events")

guard let firstEvent = cal.subComponents[0] as? Event else {
XCTAssert(false, "There should be an event")
return
}

let summary = "Bastille , Day ; Party "

XCTAssertTrue(summary == firstEvent.summary!, "summaries should be equal")
}




}
25 changes: 25 additions & 0 deletions Tests/escapedExample.ics
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:uid1@example.com
DTSTAMP:19970714T170000Z
ORGANIZER;CN=John Doe:MAILTO:john.doe@example.com
DTSTART:19970714T170000Z
DTEND:19970715T035959Z
BEGIN:VALARM
TRIGGER:-PT1440M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
SUMMARY:Bastille \, Day \; Party
END:VEVENT
BEGIN:VEVENT
UID:uid2@example.com
DTSTAMP:19980714T170000Z
ORGANIZER;CN=Jim Doe:MAILTO:jim.doe@example.com
DTSTART:19980714T170000Z
DTEND:19980715T035959Z
SUMMARY:Something completely different
END:VEVENT
END:VCALENDAR
1 change: 1 addition & 0 deletions Tests/iCalKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import XCTest
class iCalTests: XCTestCase {
static var allTests = [
("testLoadLocalFile", testLoadLocalFile),

("testEventData", testEventData),
("testQuickstart", testQuickstart),
("testQuickstartFromUrl", testQuickstartFromUrl),
Expand Down
Loading