Tests/OrgCoreTests/OrgProtocolTests.swift
74 lines · 4164 bytes
4 symbols in this file
1import Foundation
2import Testing
3@testable import OrgCore
4
5struct OrgProtocolTests {
6 static let urls = [
7 "org-protocol://capture?template=b&url=https%3A%2F%2Fexample.com%2Fa%3Fq%3D1&title=A+Page&body=some%20text",
8 "org-protocol://capture?url=https%3A%2F%2Fx.org&title=&body=",
9 "org-protocol:/capture?template=t&title=Just%20a%20title",
10 "org-protocol://capture?template=t&url=file%3A%2F%2F%2Ftmp%2Fa.org&title=%5Bweird%5D%20%C3%A9",
11 "org-protocol://capture:/b/https%3A%2F%2Fexample.com/Title/Body",
12 "org-protocol://capture:/https%3A%2F%2Fexample.com/Title",
13 "org-protocol://capture://t/https:/example.com/x/Title",
14 "org-protocol://store-link?url=https%3A%2F%2Fexample.com&title=Example",
15 "org-protocol://store-link?url=https%3A%2F%2Fexample.com",
16 "org-protocol://store-link:/https%3A%2F%2Fexample.com/Old%20Title",
17 "https://example.com",
18 ]
19
20 func describe(_ request: OrgProtocol.Request?) -> String {
21 switch request {
22 case .capture(let template, let properties)?:
23 return (["capture template=\(template ?? "nil")"] + ["type", "link", "description", "annotation", "initial"].compactMap { key in
24 properties[key].map { "\(key)=\($0)" }
25 }).joined(separator: "\n")
26 case .storeLink(let url, let title)?:
27 return "store url=\(url)\ntitle=\(title ?? "nil")"
28 case nil:
29 return "none"
30 }
31 }
32
33 @Test(.enabled(if: ProcessInfo.processInfo.environment["ORGSTAR_SKIP_ORACLE"] == nil))
34 func matchesOrgProtocol() throws {
35 let form = """
36 (progn
37 (require 'org-protocol)
38 (let (out (org-stored-links nil))
39 (cl-letf (((symbol-function 'raise-frame) #'ignore)
40 ((symbol-function 'org-capture)
41 (lambda (_ template)
42 (setq out (mapconcat #'identity
43 (cons (format "capture template=%s" (or template "nil"))
44 (delq nil (mapcar (lambda (k)
45 (let ((v (plist-get org-store-link-plist (intern (concat ":" k)))))
46 (and v (format "%s=%s" k v))))
47 '("type" "link" "description" "annotation" "initial"))))
48 "\\n")))))
49 (let ((result (org-protocol-check-filename-for-protocol (buffer-string) nil nil)))
50 (cond (out nil)
51 ((null result)
52 (setq out (format "store url=%s\\ntitle=%s" (car (car org-stored-links)) (or (cadr (car org-stored-links)) "nil"))))
53 (t (setq out "none")))))
54 (erase-buffer)
55 (insert out)))
56 """
57 let results = try EmacsOracle.run(Self.urls.map { EmacsOracle.Case(text: $0, point: 1, form: form) })
58 for (url, result) in zip(Self.urls, results) {
59 let ours = describe(OrgProtocol.parse(url))
60 #expect(ours == result.text, "\(url)\nours: \(ours.debugDescription)\nemacs: \(result.text.debugDescription) \(result.error)")
61 }
62 }
63
64 @Test func captureURLRoundTrips() {
65 let url = OrgProtocol.captureURL(template: "w", url: "https://example.com/a?b=1&c=2+3", title: "Tea & cake = 100% café", body: "line one\nline+two")
66 #expect(OrgProtocol.parse(url) == .capture(template: "w", properties: [
67 "link": "https://example.com/a?b=1&c=2+3", "type": "https",
68 "description": "Tea & cake = 100% café", "initial": "line one\nline+two",
69 "annotation": "[[https://example.com/a?b=1&c=2+3][Tea & cake = 100% café]]",
70 ]))
71 #expect(OrgProtocol.parse(OrgProtocol.captureURL(template: nil, url: nil, title: "", body: "just text"))
72 == .capture(template: nil, properties: ["description": "", "initial": "just text", "annotation": ""]))
73 }
74}