krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Tests/OrgCoreTests/OrgProtocolTests.swift

2fa201330f61c801f777baa3f2943d49d8758cda
orgstar/Tests/OrgCoreTests/OrgProtocolTests.swift history · blame · raw

74 lines · 4164 bytes

 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}