88 lines
3.3 KiB
Swift
88 lines
3.3 KiB
Swift
|
|
import Foundation
|
||
|
|
import Testing
|
||
|
|
@testable import INoteSync
|
||
|
|
|
||
|
|
@Suite("AppleScript script generation")
|
||
|
|
struct AppleScriptTests {
|
||
|
|
@Test("scriptForCreate escapes quotes and backslashes in name, body, folder")
|
||
|
|
func createEscapes() {
|
||
|
|
let script = AppleScriptNoteApplier.scriptForCreate(
|
||
|
|
name: "He said \"hi\"",
|
||
|
|
body: "line1\nline2 with \\ backslash",
|
||
|
|
folder: "Folder \"X\""
|
||
|
|
)
|
||
|
|
// Every raw user-supplied double quote must have been escaped to \"
|
||
|
|
// before being embedded. Verify no occurrence of a bare `"hi"` style
|
||
|
|
// sequence leaks into the script.
|
||
|
|
#expect(!script.contains("said \"hi\""))
|
||
|
|
#expect(script.contains("He said \\\"hi\\\""))
|
||
|
|
// Backslash should have been doubled.
|
||
|
|
#expect(script.contains("line2 with \\\\ backslash"))
|
||
|
|
// Newline should have been escaped to literal \n.
|
||
|
|
#expect(!script.contains("line1\nline2"))
|
||
|
|
#expect(script.contains("line1\\nline2"))
|
||
|
|
// Folder name with quotes escaped.
|
||
|
|
#expect(script.contains("Folder \\\"X\\\""))
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test("scriptForUpdate with both name and body emits two set statements")
|
||
|
|
func updateBoth() {
|
||
|
|
let script = AppleScriptNoteApplier.scriptForUpdate(
|
||
|
|
id: "x-coredata://abc",
|
||
|
|
name: "New Name",
|
||
|
|
body: "<p>hi</p>"
|
||
|
|
)
|
||
|
|
#expect(script.contains("set name of note id \"x-coredata://abc\" to \"New Name\""))
|
||
|
|
#expect(script.contains("set body of note id \"x-coredata://abc\" to \"<p>hi</p>\""))
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test("scriptForUpdate with only body emits only the body setter")
|
||
|
|
func updateBodyOnly() {
|
||
|
|
let script = AppleScriptNoteApplier.scriptForUpdate(
|
||
|
|
id: "id-1",
|
||
|
|
name: nil,
|
||
|
|
body: "<p>new</p>"
|
||
|
|
)
|
||
|
|
#expect(!script.contains("set name of note"))
|
||
|
|
#expect(script.contains("set body of note id \"id-1\" to \"<p>new</p>\""))
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test("scriptForUpdate escapes injected quotes in id")
|
||
|
|
func updateIdEscapes() {
|
||
|
|
let script = AppleScriptNoteApplier.scriptForUpdate(
|
||
|
|
id: "id with \" quote",
|
||
|
|
name: "n",
|
||
|
|
body: nil
|
||
|
|
)
|
||
|
|
#expect(script.contains("id with \\\" quote"))
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test("scriptForDelete escapes the id")
|
||
|
|
func deleteEscapes() {
|
||
|
|
let script = AppleScriptNoteApplier.scriptForDelete(id: "id-\"-1")
|
||
|
|
#expect(script.contains("delete note id \"id-\\\"-1\""))
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test("parse handles a single well-formed record")
|
||
|
|
func parseSingle() {
|
||
|
|
let raw = "id-1\u{001F}Name\u{001F}<p>Body</p>\u{001F}Folder\u{001F}2026-05-13T12:00:00Z\u{001E}"
|
||
|
|
let notes = NotesReader.parse(raw)
|
||
|
|
#expect(notes.count == 1)
|
||
|
|
#expect(notes[0].noteIdentifier == "id-1")
|
||
|
|
#expect(notes[0].name == "Name")
|
||
|
|
#expect(notes[0].body == "<p>Body</p>")
|
||
|
|
#expect(notes[0].folder == "Folder")
|
||
|
|
#expect(notes[0].modificationDate != nil)
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test("parse skips malformed records but keeps valid ones")
|
||
|
|
func parseMalformed() {
|
||
|
|
let valid = "id-1\u{001F}N\u{001F}B\u{001F}F\u{001F}\u{001E}"
|
||
|
|
let malformed = "only-two\u{001F}fields\u{001E}"
|
||
|
|
let notes = NotesReader.parse(malformed + valid)
|
||
|
|
#expect(notes.count == 1)
|
||
|
|
#expect(notes[0].noteIdentifier == "id-1")
|
||
|
|
#expect(notes[0].modificationDate == nil)
|
||
|
|
}
|
||
|
|
}
|