aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pearl.el228
-rw-r--r--tests/test-integration-acceptance.el18
-rw-r--r--tests/test-pearl-accounts.el16
-rw-r--r--tests/test-pearl-adhoc.el54
-rw-r--r--tests/test-pearl-bugfixes.el12
-rw-r--r--tests/test-pearl-favorites.el8
-rw-r--r--tests/test-pearl-keymap.el10
-rw-r--r--tests/test-pearl-menu.el8
-rw-r--r--tests/test-pearl-naming.el74
-rw-r--r--tests/test-pearl-resolve.el2
-rw-r--r--tests/test-pearl-saved-query-sync.el110
-rw-r--r--tests/test-pearl-saved.el16
-rw-r--r--tests/test-pearl-views.el4
13 files changed, 317 insertions, 243 deletions
diff --git a/pearl.el b/pearl.el
index 2ef4fae..de803d5 100644
--- a/pearl.el
+++ b/pearl.el
@@ -27,7 +27,7 @@
;; pearl integrates Linear.app issue tracking with Emacs and org-mode.
;; Fetch your issues -- open issues, a project, an ad-hoc filter, a Linear
-;; Custom View, or a named saved query -- into a single self-describing org
+;; Custom View, or a named local view -- into a single self-describing org
;; file: each issue is a heading, its description and comments render in the
;; body, and its structured fields live in a namespaced LINEAR-* drawer.
;;
@@ -1067,7 +1067,7 @@ dashboard / other)."
"Fetch the viewer's favorites and call CALLBACK with a list of normalized
favorite plists (Linear sort-order preserved). Paged via first/after; on a
transport/GraphQL error, CALLBACK receives whatever was collected so far so the
-picker can fall back to local saved queries rather than hanging."
+picker can fall back to local views rather than hanging."
(let (acc)
(cl-labels
((collect (data)
@@ -1087,8 +1087,8 @@ picker can fall back to local saved queries rather than hanging."
pearl--favorites-query nil #'collect
(lambda (&rest _)
;; HP5: a fetch error is not "no favorites" -- message it so the
- ;; picker's fallback to saved queries doesn't masquerade as success.
- (message "Pearl: favorites fetch failed; showing saved queries only")
+ ;; picker's fallback to local views doesn't masquerade as success.
+ (message "Pearl: favorites fetch failed; showing local views only")
(funcall callback (nreverse acc)))))))
(defun pearl--normalize-comment (raw)
@@ -3539,8 +3539,8 @@ just writing the file and leaving it off-screen."
(file-name-nondirectory org-file-path))
(pearl--surface-buffer existing-buf)))))))
-(defcustom pearl-saved-queries nil
- "Named local issue queries, run with `pearl-run-saved-query'.
+(defcustom pearl-local-views nil
+ "Named local views, run with `pearl-run-local-view'.
Each entry is (NAME . SPEC) where SPEC is a plist with `:filter' (an authoring
filter plist), and optional `:sort' (`updated', `created', `priority', or
`title') and `:order' (`asc' or `desc', default `desc'). AND-only in v1; use a
@@ -3575,9 +3575,9 @@ produces the same heading order rather than reshuffling into noise."
;;; Sentinel infrastructure for filter / pick-one prompts
;;
;; These sentinel constants and helpers back the prompt UX shared by
-;; `pearl-run-saved-query', `pearl-delete-saved-query',
+;; `pearl-run-local-view', `pearl-delete-local-view',
;; `pearl-list-issues-filtered', `pearl-pick-source', and
-;; `pearl-sync-saved-query-to-linear'. Defined ahead of those commands so
+;; `pearl-publish-local-view'. Defined ahead of those commands so
;; the byte-compiler resolves the references in order.
(defconst pearl--filter-any "[ Any. ]"
@@ -3590,7 +3590,7 @@ than a hidden empty-input idiom.")
(defconst pearl--filter-cancel "[ Cancel. ]"
"Sentinel candidate shown at the top of pick-an-existing-thing prompts
-(delete a saved query, run a saved query) where the opt-out reads as
+(delete a local view, run a local view) where the opt-out reads as
\"don't do this\" rather than \"no constraint.\" Cancelling these
prompts is a real choice, not a missing one.")
@@ -3638,25 +3638,25 @@ prompts (delete, overwrite) where typing \"yes\" is a safety affordance."
(string= "yes" choice)))
;;;###autoload
-(defun pearl-run-saved-query (name)
- "Run the saved query NAME from `pearl-saved-queries'.
+(defun pearl-run-local-view (name)
+ "Run the local view NAME from `pearl-local-views'.
Interactively, completes over the configured query names. Compiles the stored
filter, fetches, sorts per the query's `:sort'/`:order', and renders into the
active file with the query recorded as the source."
(interactive
- (list (if (null pearl-saved-queries)
- (user-error "No saved queries configured")
+ (list (if (null pearl-local-views)
+ (user-error "No local views configured")
(completing-read
- "Saved query: "
+ "Local view: "
(pearl--completion-table-keep-order
(pearl--with-sentinel pearl--filter-cancel
- (mapcar #'car pearl-saved-queries)))
+ (mapcar #'car pearl-local-views)))
nil t))))
(when (pearl--filter-sentinel-value-p name)
- (user-error "Cancelled; no saved query run"))
- (let ((entry (assoc name pearl-saved-queries)))
+ (user-error "Cancelled; no local view run"))
+ (let ((entry (assoc name pearl-local-views)))
(unless entry
- (user-error "No saved query named %s" name))
+ (user-error "No local view named %s" name))
(let* ((spec (cdr entry))
(filter-plist (plist-get spec :filter))
(sort (plist-get spec :sort))
@@ -3671,19 +3671,19 @@ active file with the query recorded as the source."
(when (and pearl-accounts q-account)
(let ((active (plist-get (pearl--current-account-context) :name)))
(unless (string-equal q-account active)
- (user-error "Saved query '%s' belongs to %s; switch accounts first"
+ (user-error "Local view '%s' belongs to %s; switch accounts first"
name q-account)))))
- ;; Validate the saved query's authoring plist at the command boundary so
+ ;; Validate the local view's authoring plist at the command boundary so
;; a typo'd key or bad value surfaces as a clear user-error instead of
;; being silently dropped or failing deeper in the compiler.
(pearl--validate-issue-filter filter-plist)
- (pearl--progress "Running saved query %s..." name)
+ (pearl--progress "Running local view %s..." name)
(pearl--query-issues-async
(pearl--build-issue-filter filter-plist)
(lambda (result) (pearl--render-query-result result source))
(pearl--sort->order-by sort)))))
-;;; pearl-pick-source -- the unified source picker (favorites + saved queries)
+;;; pearl-pick-source -- the unified source picker (favorites + local views)
(defun pearl--saved-query-scope-label (spec teams)
"Return the scope display label for SPEC (a saved-query plist).
@@ -3707,15 +3707,15 @@ user rather than silently mis-labelling)."
(defun pearl--pick-source-candidates (favorites saved-queries &optional teams)
"Build the picker's candidate alist `((DISPLAY . SOURCE-OR-ACTION) ...)'.
FAVORITES is a list of normalized favorite plists; SAVED-QUERIES is the
-`pearl-saved-queries' alist; TEAMS is the team alist list (see
+`pearl-local-views' alist; TEAMS is the team alist list (see
`pearl--all-teams') used to resolve the scope name of any saved-query
entry carrying `:linear-view-id'. Favorites come first in ascending
-`:sort-order'; saved queries follow alphabetically.
+`:sort-order'; local views follow alphabetically.
Each DISPLAY is one of:
`[KIND] TITLE' for favorites
- `[saved] NAME' for a local-only saved query
- `[saved \\u2192 SCOPE] NAME' for a synced saved query
+ `[saved] NAME' for a local-only local view
+ `[saved \\u2192 SCOPE] NAME' for a synced local view
where SCOPE is the team name resolved from `:linear-view-team-id'
against TEAMS, or \"Personal\" when there's no team scope, or \"?\" when
the team id is stale (no longer in TEAMS) or TEAMS is nil.
@@ -3790,19 +3790,19 @@ on success so the user sees what happened."
;;;###autoload
(defun pearl-pick-source ()
- "Pick a Linear favorite or local saved query and fetch it into the active file.
-Favorites are listed first in Linear's sort order, then local saved queries
+ "Pick a Linear favorite or local view and fetch it into the active file.
+Favorites are listed first in Linear's sort order, then local views
alphabetically. Non-list favorites (issue, document, ...) open in the browser
instead. On a favorites-fetch failure the picker still offers any local saved
queries -- favorites-failure is not the same user state as \"no favorites\".
-With neither favorites nor saved queries, signals a `user-error' naming the
+With neither favorites nor local views, signals a `user-error' naming the
missing setup."
(interactive)
(pearl--progress "Fetching favorites...")
- (let ((saved pearl-saved-queries))
+ (let ((saved pearl-local-views))
(pearl--favorites-async
(lambda (favorites)
- ;; Only fetch teams when at least one saved query is synced -- scope
+ ;; Only fetch teams when at least one local view is synced -- scope
;; resolution is the only thing teams data feeds, and an all-local
;; configuration has no scopes to resolve.
(let* ((teams (and (cl-some (lambda (sq)
@@ -3812,7 +3812,7 @@ missing setup."
(cands (pearl--pick-source-candidates favorites saved teams)))
(unless cands
(user-error
- "No favorites or saved queries -- star views in Linear, or set `pearl-saved-queries'"))
+ "No favorites or local views -- star views in Linear, or set `pearl-local-views'"))
(let* ((display (completing-read "Source: " (mapcar #'car cands) nil t))
(source (cdr (assoc display cands))))
(cond
@@ -3922,16 +3922,16 @@ an id), or `pearl--filter-any' (any assignee, no scoping)."
open state project labels assignee)))
(defun pearl--delete-saved-query-local (name)
- "Remove NAME from `pearl-saved-queries' and persist via Customize.
+ "Remove NAME from `pearl-local-views' and persist via Customize.
The unconditional persistence path shared by the local-only delete and
the synced-entry unlink branch."
- (setq pearl-saved-queries
- (cl-remove name pearl-saved-queries :key #'car :test #'string=))
- (customize-save-variable 'pearl-saved-queries pearl-saved-queries))
+ (setq pearl-local-views
+ (cl-remove name pearl-local-views :key #'car :test #'string=))
+ (customize-save-variable 'pearl-local-views pearl-local-views))
;;;###autoload
-(defun pearl-delete-saved-query (name)
- "Delete the saved query NAME from `pearl-saved-queries' after confirmation.
+(defun pearl-delete-local-view (name)
+ "Delete the local view NAME from `pearl-local-views' after confirmation.
Interactively, completes over the configured query names with
`pearl--filter-cancel' at the top. Local-only entries are removed from
the customized list and persisted via `customize-save-variable'; entries
@@ -3943,29 +3943,29 @@ entry but leaves the Linear view in place; picking YES calls
entry anyway (which leaves the Linear view orphaned -- the message names
the id so it can be deleted by hand)."
(interactive
- (list (if (null pearl-saved-queries)
- (user-error "No saved queries to delete")
+ (list (if (null pearl-local-views)
+ (user-error "No local views to delete")
(completing-read
- "Delete saved query: "
+ "Delete local view: "
(pearl--completion-table-keep-order
(pearl--with-sentinel pearl--filter-cancel
- (mapcar #'car pearl-saved-queries)))
+ (mapcar #'car pearl-local-views)))
nil t))))
(cond
((pearl--filter-sentinel-value-p name)
- (message "Cancelled; no saved query deleted"))
- ((not (assoc name pearl-saved-queries))
- (user-error "No saved query named %s" name))
- ((not (yes-or-no-p (format "Delete saved query %s? " name)))
- (message "Kept saved query %s" name))
+ (message "Cancelled; no local view deleted"))
+ ((not (assoc name pearl-local-views))
+ (user-error "No local view named %s" name))
+ ((not (yes-or-no-p (format "Delete local view %s? " name)))
+ (message "Kept local view %s" name))
(t
- (let ((view-id (plist-get (cdr (assoc name pearl-saved-queries))
+ (let ((view-id (plist-get (cdr (assoc name pearl-local-views))
:linear-view-id)))
(cond
;; Local-only entry: unchanged behavior.
((null view-id)
(pearl--delete-saved-query-local name)
- (message "Deleted saved query %s" name))
+ (message "Deleted local view %s" name))
;; Synced entry: ask whether to also drop the Linear view.
((yes-or-no-p
(format "Also delete the linked Linear view (\"%s\")? " name))
@@ -3973,7 +3973,7 @@ the id so it can be deleted by hand)."
(t
;; Unlink only: drop the local entry, leave the Linear view alone.
(pearl--delete-saved-query-local name)
- (message "Deleted saved query %s; Linear view kept (id %s)"
+ (message "Deleted local view %s; Linear view kept (id %s)"
name view-id)))))))
(defun pearl--delete-saved-query-do-linear-delete (name view-id)
@@ -3988,10 +3988,10 @@ by hand."
(cond
(success
(pearl--delete-saved-query-local name)
- (message "Deleted saved query %s and removed view from Linear" name))
+ (message "Deleted local view %s and removed view from Linear" name))
((plist-get result :timeout)
(message
- "Delete of Linear view for %s timed out after %ds; saved query left in place -- the delete may still have completed (view id %s) -- re-run after the network recovers."
+ "Delete of Linear view for %s timed out after %ds; local view left in place -- the delete may still have completed (view id %s) -- re-run after the network recovers."
name pearl-request-timeout view-id))
((yes-or-no-p
(format
@@ -3999,22 +3999,22 @@ by hand."
(or (plist-get result :error) "unknown error")))
(pearl--delete-saved-query-local name)
(message
- "Deleted saved query %s; Linear view is orphaned (id %s, delete manually)"
+ "Deleted local view %s; Linear view is orphaned (id %s, delete manually)"
name view-id))
(t
- (message "Kept saved query %s; Linear view also untouched" name)))))
+ (message "Kept local view %s; Linear view also untouched" name)))))
(defun pearl--save-query (name filter-plist &optional sort order)
- "Save FILTER-PLIST as the saved query NAME, replacing any entry of that NAME.
-Persists `pearl-saved-queries' via Customize. SORT and ORDER are
+ "Save FILTER-PLIST as the local view NAME, replacing any entry of that NAME.
+Persists `pearl-local-views' via Customize. SORT and ORDER are
stored when given."
(let ((entry (cons name (append (list :filter filter-plist)
(when sort (list :sort sort))
(when order (list :order order))))))
- (setq pearl-saved-queries
- (cons entry (assoc-delete-all name (copy-sequence pearl-saved-queries))))
+ (setq pearl-local-views
+ (cons entry (assoc-delete-all name (copy-sequence pearl-local-views))))
(ignore-errors
- (customize-save-variable 'pearl-saved-queries pearl-saved-queries))))
+ (customize-save-variable 'pearl-local-views pearl-local-views))))
;;; Saved-query -> Linear view sync (see docs/saved-query-sync-spec.org)
@@ -4033,7 +4033,7 @@ agree byte-for-byte."
(defun pearl--sync-scope-candidates (teams filter-team-key)
"Build the (DISPLAY . PLIST) candidate list for the scope-and-visibility prompt.
TEAMS is the team alist list returned by `pearl--all-teams' (each carries
-`id', `key', `name'). FILTER-TEAM-KEY is the saved query's filter `:team'
+`id', `key', `name'). FILTER-TEAM-KEY is the local view's filter `:team'
value (a team key string) or nil.
Each candidate's PLIST is `(:team-id ID-OR-NIL :team-name NAME :shared
@@ -4095,7 +4095,7 @@ Returns the matching view alist or nil."
views)))
(defun pearl--save-query-mark-synced (name team-id shared view-id &optional view-url)
- "Persist the sync metadata for saved query NAME.
+ "Persist the sync metadata for local view NAME.
TEAM-ID is the team UUID or nil (personal scope). SHARED is t or nil.
VIEW-ID is the Linear custom view UUID returned by the API. VIEW-URL,
when provided, is the view's Linear web URL so
@@ -4106,11 +4106,11 @@ unavailable to leave the prior `:linear-view-url' untouched.
Adds or overwrites `:linear-view-id', `:linear-view-team-id',
`:linear-view-shared', `:linear-view-synced-at', and (when VIEW-URL is
non-nil) `:linear-view-url' on the entry, then persists
-`pearl-saved-queries' via Customize. Signals `user-error' when NAME
-isn't in `pearl-saved-queries'."
- (let ((entry (assoc name pearl-saved-queries)))
+`pearl-local-views' via Customize. Signals `user-error' when NAME
+isn't in `pearl-local-views'."
+ (let ((entry (assoc name pearl-local-views)))
(unless entry
- (user-error "No saved query named %s" name))
+ (user-error "No local view named %s" name))
;; Copy the existing spec and plist-put each sync key on top. Earlier
;; versions rebuilt the spec from `:filter', `:sort', `:order' + the four
;; sync keys, which silently dropped any other key on the entry -- a
@@ -4127,10 +4127,10 @@ isn't in `pearl-saved-queries'."
;; whose API response somehow lacks the URL must not erase the prior.
(when view-url
(setq new-spec (plist-put new-spec :linear-view-url view-url)))
- (setq pearl-saved-queries
+ (setq pearl-local-views
(cons (cons name new-spec)
- (assoc-delete-all name (copy-sequence pearl-saved-queries))))
- (customize-save-variable 'pearl-saved-queries pearl-saved-queries))))
+ (assoc-delete-all name (copy-sequence pearl-local-views))))
+ (customize-save-variable 'pearl-local-views pearl-local-views))))
(defun pearl--sync-record-or-orphan-error (name team-id shared view-id verb
&optional scope-label view-url)
@@ -4156,14 +4156,14 @@ local link couldn't be saved."
t)
(error
(message
- "View %s on Linear as %s but local link couldn't be saved (%s). Re-run `pearl-sync-saved-query-to-linear' and pick Replace to reconcile."
+ "View %s on Linear as %s but local link couldn't be saved (%s). Re-run `pearl-publish-local-view' and pick Replace to reconcile."
(if (string= verb "Updated") "updated" "created")
view-id (error-message-string err))
nil)))
(defun pearl--sync-saved-query-pick-scope (filter-plist)
"Prompt the user for the destination scope of a sync-up.
-FILTER-PLIST is the saved query's authoring filter (used to derive the
+FILTER-PLIST is the local view's authoring filter (used to derive the
default candidate). Returns `(DISPLAY . PLIST)', or nil when the user
cancels via the cancel sentinel. DISPLAY is the candidate string the
user picked; PLIST is `(:team-id ID-OR-NIL :team-name NAME :shared
@@ -4210,32 +4210,32 @@ so the user isn't told the API refused something that never reached it."
(if done result (list :success nil :timeout t))))
;;;###autoload
-(defun pearl-sync-saved-query-to-linear (name)
- "Sync the local saved query NAME up to Linear as a Custom View.
-First-time sync prompts for the destination scope (team and visibility),
-then calls `customViewCreate'. Re-syncing an already-synced entry calls
+(defun pearl-publish-local-view (name)
+ "Publish the local view NAME to Linear as a Custom View.
+First publish prompts for the destination scope (team and visibility),
+then calls `customViewCreate'. Re-publishing an already-published entry calls
`customViewUpdate' against the stored view id -- the stored team and
shared flag stay (use Replace/Rename below to reset them). A same-name
collision in the chosen scope prompts Replace / Rename / Cancel. On
success the entry is extended with the four `:linear-view-*' keys via
`customize-save-variable'. On a successful API call followed by a
persist failure, the message names the orphan view's id explicitly so
-the user can re-sync with Replace to reconcile."
+the user can re-publish with Replace to reconcile."
(interactive
- (list (if (null pearl-saved-queries)
- (user-error "No saved queries to sync")
+ (list (if (null pearl-local-views)
+ (user-error "No local views to publish")
(completing-read
- "Sync saved query: "
+ "Publish local view: "
(pearl--completion-table-keep-order
(pearl--with-sentinel pearl--filter-cancel
- (mapcar #'car pearl-saved-queries)))
+ (mapcar #'car pearl-local-views)))
nil t))))
(when (pearl--filter-sentinel-value-p name)
- (user-error "Cancelled; no saved query synced"))
+ (user-error "Cancelled; no local view published"))
(pearl--require-account-context t)
- (let ((entry (assoc name pearl-saved-queries)))
+ (let ((entry (assoc name pearl-local-views)))
(unless entry
- (user-error "No saved query named %s" name))
+ (user-error "No local view named %s" name))
(let* ((spec (cdr entry))
(filter-plist (plist-get spec :filter))
(existing-view-id (plist-get spec :linear-view-id))
@@ -4255,7 +4255,7 @@ the user can re-sync with Replace to reconcile."
;; clicking through the scope picker only to hit "Linear refused".
(unless filter-data
(user-error
- "Saved query %s has no filter constraints; Linear views need at least one constraint -- add one and re-sync"
+ "Local view %s has no filter constraints; Linear views need at least one constraint -- add one and re-sync"
name))
(let ((scope-pair
(if existing-view-id
@@ -4281,7 +4281,7 @@ the user can re-sync with Replace to reconcile."
;; nil (cancel).
(pearl--sync-saved-query-pick-scope filter-plist))))
(unless scope-pair
- (user-error "Cancelled; no saved query synced"))
+ (user-error "Cancelled; no local view published"))
;; Validate the filter at the boundary so a malformed entry surfaces
;; before the API call.
(pearl--validate-issue-filter filter-plist)
@@ -4302,7 +4302,7 @@ the user can re-sync with Replace to reconcile."
target-name))))
(pcase action
('cancel
- (message "Cancelled; %s left unsynced" target-name))
+ (message "Cancelled; %s left unpublished" target-name))
('rename
(setq target-name
(read-string (format "New view name (was %s): " name)))
@@ -4326,7 +4326,7 @@ the user can re-sync with Replace to reconcile."
(defun pearl--sync-saved-query-do-create (name target-name team-id shared
filter-data scope-label)
- "Create a Linear view from saved query NAME, persisting the link on success.
+ "Create a Linear view from local view NAME, persisting the link on success.
TARGET-NAME is the view name to send to Linear (usually NAME, but may
differ when the user picked Rename to dodge a collision). TEAM-ID,
SHARED, FILTER-DATA are the Linear API inputs. SCOPE-LABEL is the
@@ -4342,24 +4342,24 @@ scope-and-visibility display string for the success message."
(cond
((and success view-id)
(pearl--sync-record-or-orphan-error
- name team-id shared view-id "Synced" scope-label view-url))
+ name team-id shared view-id "Published" scope-label view-url))
((plist-get result :timeout)
(message
- "Sync of %s timed out after %ds; the create may still complete on Linear -- re-run and pick Replace to reconcile if a duplicate appears."
+ "Publish of %s timed out after %ds; the create may still complete on Linear -- re-run and pick Replace to reconcile if a duplicate appears."
name pearl-request-timeout))
(t
- (message "Failed to sync %s: %s" name
+ (message "Failed to publish %s: %s" name
(or (plist-get result :error) "Linear refused the create"))))))
;;;###autoload
-(defun pearl-publish-current-source ()
- "Publish the active buffer's local saved query to Linear as a Custom View.
+(defun pearl-publish-current-view ()
+ "Publish the active buffer's local view to Linear as a Custom View.
Convenience wrapper. Reads `#+LINEAR-SOURCE' from the current buffer.
-When it's a `:type filter' source whose `:name' matches a local saved
-query, dispatches to `pearl-sync-saved-query-to-linear' with that name
-pre-filled. Otherwise refuses with a clear message: the source is
-already a Linear view (no publish needed), the filter is transient (no
-name to sync under), or no local saved query matches the recorded name.
+When it's a `:type filter' source whose `:name' matches a local view,
+dispatches to `pearl-publish-local-view' with that name pre-filled.
+Otherwise refuses with a clear message: the source is already a Linear
+view (no publish needed), the filter is transient (no name to publish
+under), or no local view matches the recorded name.
Bound under \\='C-; L f P\\=' inside `pearl-mode' buffers; reachable
through the transient as the `U' (upload) entry in the Fetch group."
@@ -4379,15 +4379,15 @@ through the transient as the `U' (upload) entry in the Fetch group."
type))
((or (null name) (and (stringp name) (string-blank-p name)))
(user-error "Source has no name; save it first via pearl-list-issues-filtered then re-publish"))
- ((not (assoc name pearl-saved-queries))
- (user-error "No local saved query named %s; save it first via pearl-list-issues-filtered"
+ ((not (assoc name pearl-local-views))
+ (user-error "No local view named %s; save it first via pearl-list-issues-filtered"
name))
(t
- (pearl-sync-saved-query-to-linear name)))))
+ (pearl-publish-local-view name)))))
(defun pearl--sync-saved-query-do-update (name view-id team-id shared
filter-data scope-label)
- "Update an existing Linear view from saved query NAME by VIEW-ID.
+ "Update an existing Linear view from local view NAME by VIEW-ID.
TEAM-ID, SHARED, FILTER-DATA are the Linear API inputs. SCOPE-LABEL is
the scope-and-visibility display string for the success message."
(pearl--progress "Updating Linear view %s..." name)
@@ -4423,7 +4423,7 @@ filter; SAVE-NAME, when given, persists it via `pearl--save-query'."
(interactive
(list (pearl--read-filter-interactively)
(when (pearl--read-yes-no "Save this filter locally so you can re-run it (not pushed to Linear)? ")
- (read-string "Name for this saved query: "))))
+ (read-string "Name for this local view: "))))
;; Validate before saving or running, so a bad filter never gets persisted
;; or run -- the command boundary is where the clear error belongs.
(pearl--validate-issue-filter filter-plist)
@@ -4463,7 +4463,7 @@ no Comments subtree."
"Render a query RESULT into the active file, tagged with SOURCE.
Normalizes the raw nodes, writes them via `pearl--update-org-from-issues'
with SOURCE and the truncation flag, and reports the outcome. The one render
-boundary shared by list-issues, the ad-hoc filter, saved queries, views, and
+boundary shared by list-issues, the ad-hoc filter, local views, views, and
refresh."
(pcase (pearl--query-result-status result)
('ok
@@ -5613,7 +5613,7 @@ commands. Errors if no source is recorded."
(_ (user-error "Unknown Linear source type: %s" (plist-get source :type)))))))
;;;###autoload
-(defun pearl-run-view (view-name)
+(defun pearl-run-linear-view (view-name)
"Run a Linear Custom View by VIEW-NAME and render it into the active file.
Interactively, completes over the workspace's Custom Views. The view's own
filter runs server-side; the result replaces the active file (behind the
@@ -6155,17 +6155,17 @@ body stay."
["Delete"
("k" "delete issue" pearl-delete-current-issue)
("K" "delete comment" pearl-delete-current-comment)
- ("q" "delete saved query" pearl-delete-saved-query)]]
+ ("q" "delete local view" pearl-delete-local-view)]]
["Workspace"
["Fetch"
("P" "pick source" pearl-pick-source)
("l" "my open issues" pearl-list-issues)
("p" "by project" pearl-list-issues-by-project)
("f" "build a filter" pearl-list-issues-filtered)
- ("v" "custom view" pearl-run-view)
- ("Q" "saved query" pearl-run-saved-query)
- ("S" "sync saved query" pearl-sync-saved-query-to-linear)
- ("U" "upload current source" pearl-publish-current-source)]
+ ("v" "custom view" pearl-run-linear-view)
+ ("Q" "local view" pearl-run-local-view)
+ ("S" "sync local view" pearl-publish-local-view)
+ ("U" "upload current source" pearl-publish-current-view)]
["View"
("g" "refresh view" pearl-refresh-current-view)
("r" "refresh issue" pearl-refresh-current-issue)
@@ -6205,12 +6205,12 @@ body stay."
(define-key map "o" (cons "my open issues" #'pearl-list-issues))
(define-key map "p" (cons "by project" #'pearl-list-issues-by-project))
(define-key map "f" (cons "build a filter" #'pearl-list-issues-filtered))
- (define-key map "v" (cons "custom view" #'pearl-run-view))
- (define-key map "q" (cons "saved query" #'pearl-run-saved-query))
- (define-key map "S" (cons "sync saved query to Linear"
- #'pearl-sync-saved-query-to-linear))
+ (define-key map "v" (cons "custom view" #'pearl-run-linear-view))
+ (define-key map "q" (cons "local view" #'pearl-run-local-view))
+ (define-key map "S" (cons "sync local view to Linear"
+ #'pearl-publish-local-view))
(define-key map "P" (cons "publish current source to Linear"
- #'pearl-publish-current-source))
+ #'pearl-publish-current-view))
map)
"Pearl fetch commands; a sub-keymap of `pearl-prefix-map'.")
@@ -6235,7 +6235,7 @@ body stay."
(let ((map (make-sparse-keymap)))
(define-key map "t" (cons "delete issue" #'pearl-delete-current-issue))
(define-key map "c" (cons "delete comment" #'pearl-delete-current-comment))
- (define-key map "q" (cons "delete saved query" #'pearl-delete-saved-query))
+ (define-key map "q" (cons "delete local view" #'pearl-delete-local-view))
map)
"Pearl delete commands; a sub-keymap of `pearl-prefix-map'.")
diff --git a/tests/test-integration-acceptance.el b/tests/test-integration-acceptance.el
index 523d1b3..0e1c64d 100644
--- a/tests/test-integration-acceptance.el
+++ b/tests/test-integration-acceptance.el
@@ -29,7 +29,7 @@
;; and a field-setter command — runs for real against a temp active file.
;;
;; Components integrated (all real unless noted):
-;; - pearl-run-saved-query -> --build-issue-filter -> --query-issues-async
+;; - pearl-run-local-view -> --build-issue-filter -> --query-issues-async
;; - --query-issues-async -> --graphql-request-async (MOCKED at the wire)
;; - --render-query-result -> --normalize-issue -> --sort-issues
;; - --update-org-from-issues (real disk write + buffer surface, surface MOCKED)
@@ -102,7 +102,7 @@ because the description-update mutation contains both `IssueDescription' and
(pearl-org-file-path tmp)
(pearl-api-key "test-key")
(pearl-fold-after-update nil)
- (pearl-saved-queries
+ (pearl-local-views
'(("Open" :filter (:open t) :sort priority :order asc)
("Bugs" :filter (:labels ("bug") :open t))))
(test-integration--ops nil))
@@ -124,9 +124,9 @@ because the description-update mutation contains both `IssueDescription' and
(ignore-errors (delete-file tmp))))))
(ert-deftest test-integration-run-saved-query-renders-active-file ()
- "A saved query fetches, renders to the active file with a source header, and surfaces a buffer."
+ "A local view fetches, renders to the active file with a source header, and surfaces a buffer."
(test-integration--with-env
- (pearl-run-saved-query "Open")
+ (pearl-run-local-view "Open")
(let ((buf (find-buffer-visiting pearl-org-file-path)))
(should (buffer-live-p buf))
(with-current-buffer buf
@@ -146,7 +146,7 @@ because the description-update mutation contains both `IssueDescription' and
(ert-deftest test-integration-refresh-reruns-recorded-source ()
"Refresh reads the recorded source from the buffer and merges a re-fetch in place."
(test-integration--with-env
- (pearl-run-saved-query "Open")
+ (pearl-run-local-view "Open")
(with-current-buffer (find-buffer-visiting pearl-org-file-path)
(setq test-integration--ops nil)
(pearl-refresh-current-view)
@@ -159,22 +159,22 @@ because the description-update mutation contains both `IssueDescription' and
(should (re-search-forward "Second issue" nil t)))))
(ert-deftest test-integration-switch-source-protects-dirty-buffer ()
- "Switching to a different saved query with unsaved edits does not overwrite them."
+ "Switching to a different local view with unsaved edits does not overwrite them."
(test-integration--with-env
- (pearl-run-saved-query "Open")
+ (pearl-run-local-view "Open")
(with-current-buffer (find-buffer-visiting pearl-org-file-path)
(goto-char (point-max))
(insert "\nUNSAVED LOCAL EDIT\n")
(should (buffer-modified-p))
;; the switch must defer rather than clobber the dirty buffer
- (pearl-run-saved-query "Bugs")
+ (pearl-run-local-view "Bugs")
(goto-char (point-min))
(should (re-search-forward "UNSAVED LOCAL EDIT" nil t)))))
(ert-deftest test-integration-issue-commands-from-subtree ()
"From inside a rendered issue subtree: syncing an edited body pushes, adding a comment inserts it, and setting priority drives a field update — all through the real request path."
(test-integration--with-env
- (pearl-run-saved-query "Open")
+ (pearl-run-local-view "Open")
(with-current-buffer (find-buffer-visiting pearl-org-file-path)
;; --- sync a description edit (remote unchanged -> clean push) ---
(goto-char (point-min))
diff --git a/tests/test-pearl-accounts.el b/tests/test-pearl-accounts.el
index f8bc06b..2a4cb69 100644
--- a/tests/test-pearl-accounts.el
+++ b/tests/test-pearl-accounts.el
@@ -403,35 +403,35 @@ fetching the active account's issues into it would cross workspaces."
;;; Saved-query :account guard
(ert-deftest test-pearl-run-saved-query-refuses-other-account-before-network ()
- "A saved query tagged for another account refuses before any compilation or fetch."
+ "A local view tagged for another account refuses before any compilation or fetch."
(let ((pearl-accounts '(("work" :api-key-source (:literal "kw") :org-file "/tmp/w.org")
("home" :api-key-source (:literal "kh") :org-file "/tmp/h.org")))
(pearl-active-account "home") (pearl-default-account "home")
- (pearl-saved-queries '(("Work bugs" :account "work" :filter (:assignee :me))))
+ (pearl-local-views '(("Work bugs" :account "work" :filter (:assignee :me))))
(api-called nil))
(cl-letf (((symbol-function 'request) (lambda (&rest _) (setq api-called t))))
- (let ((err (should-error (pearl-run-saved-query "Work bugs") :type 'error)))
+ (let ((err (should-error (pearl-run-local-view "Work bugs") :type 'error)))
(should (string-match-p "work" (error-message-string err))))
(should-not api-called))))
(ert-deftest test-pearl-run-saved-query-account-match-proceeds-to-fetch ()
- "A saved query tagged for the active account compiles and dispatches."
+ "A local view tagged for the active account compiles and dispatches."
(let ((pearl-accounts '(("work" :api-key-source (:literal "kw") :org-file "/tmp/w.org")))
(pearl-active-account "work") (pearl-default-account "work")
- (pearl-saved-queries '(("Work bugs" :account "work" :filter (:assignee :me))))
+ (pearl-local-views '(("Work bugs" :account "work" :filter (:assignee :me))))
(api-called nil))
(cl-letf (((symbol-function 'request) (lambda (&rest _) (setq api-called t))))
- (pearl-run-saved-query "Work bugs")
+ (pearl-run-local-view "Work bugs")
(should api-called))))
(ert-deftest test-pearl-run-saved-query-account-tag-ignored-in-legacy ()
"With no accounts configured, an `:account' tag is inert (shared query)."
(let ((pearl-accounts nil) (pearl-active-account nil) (pearl-default-account nil)
(pearl-api-key "lin_legacy")
- (pearl-saved-queries '(("Work bugs" :account "work" :filter (:assignee :me))))
+ (pearl-local-views '(("Work bugs" :account "work" :filter (:assignee :me))))
(api-called nil))
(cl-letf (((symbol-function 'request) (lambda (&rest _) (setq api-called t))))
- (pearl-run-saved-query "Work bugs")
+ (pearl-run-local-view "Work bugs")
(should api-called))))
;;; pearl-load-api-key-from-env legacy-only
diff --git a/tests/test-pearl-adhoc.el b/tests/test-pearl-adhoc.el
index 558578a..4959840 100644
--- a/tests/test-pearl-adhoc.el
+++ b/tests/test-pearl-adhoc.el
@@ -159,82 +159,82 @@ candidate list, so completion still works the way the framework expects."
(ert-deftest test-pearl-save-query-adds-entry ()
"Saving a query adds it to the saved-queries variable."
- (let ((pearl-saved-queries nil))
+ (let ((pearl-local-views nil))
(cl-letf (((symbol-function 'customize-save-variable) (lambda (&rest _) nil)))
(pearl--save-query "My filter" '(:open t :labels ("bug")))
- (let ((entry (assoc "My filter" pearl-saved-queries)))
+ (let ((entry (assoc "My filter" pearl-local-views)))
(should entry)
(should (equal '(:open t :labels ("bug")) (plist-get (cdr entry) :filter)))))))
(ert-deftest test-pearl-save-query-replaces-same-name ()
"Saving under an existing name replaces that entry rather than duplicating."
- (let ((pearl-saved-queries '(("Dup" :filter (:open t)))))
+ (let ((pearl-local-views '(("Dup" :filter (:open t)))))
(cl-letf (((symbol-function 'customize-save-variable) (lambda (&rest _) nil)))
(pearl--save-query "Dup" '(:priority 1))
- (should (= 1 (cl-count "Dup" pearl-saved-queries
+ (should (= 1 (cl-count "Dup" pearl-local-views
:key #'car :test #'string=)))
(should (equal '(:priority 1)
- (plist-get (cdr (assoc "Dup" pearl-saved-queries)) :filter))))))
+ (plist-get (cdr (assoc "Dup" pearl-local-views)) :filter))))))
-;;; pearl-delete-saved-query
+;;; pearl-delete-local-view
(ert-deftest test-pearl-delete-saved-query-removes-entry-on-yes ()
"Confirming the prompt removes the named entry and persists."
- (let ((pearl-saved-queries '(("Keep" :filter (:open t))
+ (let ((pearl-local-views '(("Keep" :filter (:open t))
("Drop" :filter (:priority 1))))
(persisted nil))
(cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) t))
((symbol-function 'customize-save-variable)
(lambda (&rest _) (setq persisted t))))
- (pearl-delete-saved-query "Drop")
- (should-not (assoc "Drop" pearl-saved-queries))
- (should (assoc "Keep" pearl-saved-queries))
+ (pearl-delete-local-view "Drop")
+ (should-not (assoc "Drop" pearl-local-views))
+ (should (assoc "Keep" pearl-local-views))
(should persisted))))
(ert-deftest test-pearl-delete-saved-query-no-at-confirm-keeps-entry ()
"Declining the confirm prompt leaves the entry in place and does not persist."
- (let ((pearl-saved-queries '(("Keep" :filter (:open t))))
+ (let ((pearl-local-views '(("Keep" :filter (:open t))))
(persisted nil))
(cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) nil))
((symbol-function 'customize-save-variable)
(lambda (&rest _) (setq persisted t))))
- (pearl-delete-saved-query "Keep")
- (should (assoc "Keep" pearl-saved-queries))
+ (pearl-delete-local-view "Keep")
+ (should (assoc "Keep" pearl-local-views))
(should-not persisted))))
(ert-deftest test-pearl-delete-saved-query-sentinel-cancels ()
"Picking the `pearl--filter-cancel' sentinel cancels without touching anything."
- (let ((pearl-saved-queries '(("Keep" :filter (:open t))))
+ (let ((pearl-local-views '(("Keep" :filter (:open t))))
(confirmed nil))
(cl-letf (((symbol-function 'yes-or-no-p)
(lambda (&rest _) (setq confirmed t) t))
((symbol-function 'customize-save-variable)
(lambda (&rest _) nil)))
- (pearl-delete-saved-query pearl--filter-cancel)
- (should (assoc "Keep" pearl-saved-queries))
+ (pearl-delete-local-view pearl--filter-cancel)
+ (should (assoc "Keep" pearl-local-views))
(should-not confirmed))))
(ert-deftest test-pearl-delete-saved-query-unknown-name-errors ()
"An unknown name (e.g. typed past completion) signals a user-error."
- (let ((pearl-saved-queries '(("Keep" :filter (:open t)))))
- (should-error (pearl-delete-saved-query "Nope") :type 'user-error)))
+ (let ((pearl-local-views '(("Keep" :filter (:open t)))))
+ (should-error (pearl-delete-local-view "Nope") :type 'user-error)))
(ert-deftest test-pearl-delete-saved-query-empty-list-errors-on-interactive ()
- "Called interactively with no saved queries, the command errors cleanly
+ "Called interactively with no local views, the command errors cleanly
rather than offering an empty picker."
- (let ((pearl-saved-queries nil))
- (should-error (call-interactively #'pearl-delete-saved-query)
+ (let ((pearl-local-views nil))
+ (should-error (call-interactively #'pearl-delete-local-view)
:type 'user-error)))
-;;; pearl-run-saved-query sentinel cancel
+;;; pearl-run-local-view sentinel cancel
(ert-deftest test-pearl-run-saved-query-sentinel-cancels ()
"Picking the `pearl--filter-cancel' sentinel cancels the run without fetching."
(let ((fetched nil)
- (pearl-saved-queries '(("Open" :filter (:open t)))))
+ (pearl-local-views '(("Open" :filter (:open t)))))
(cl-letf (((symbol-function 'pearl--query-issues-async)
(lambda (&rest _) (setq fetched t))))
- (should-error (pearl-run-saved-query pearl--filter-cancel) :type 'user-error)
+ (should-error (pearl-run-local-view pearl--filter-cancel) :type 'user-error)
(should-not fetched))))
;;; pearl-list-issues-filtered
@@ -255,8 +255,8 @@ rather than offering an empty picker."
(should (equal '(:assignee :me :open t) (plist-get rendered-source :filter))))))
(ert-deftest test-pearl-list-issues-filtered-saves-when-named ()
- "Passing a save name persists the ad-hoc filter as a saved query."
- (let ((pearl-saved-queries nil))
+ "Passing a save name persists the ad-hoc filter as a local view."
+ (let ((pearl-local-views nil))
(cl-letf (((symbol-function 'pearl--build-issue-filter) (lambda (_p) nil))
((symbol-function 'pearl--query-issues-async)
(lambda (_f cb &optional _o)
@@ -264,7 +264,7 @@ rather than offering an empty picker."
((symbol-function 'pearl--render-query-result) (lambda (&rest _) nil))
((symbol-function 'customize-save-variable) (lambda (&rest _) nil)))
(pearl-list-issues-filtered '(:open t) "Saved adhoc")
- (should (assoc "Saved adhoc" pearl-saved-queries)))))
+ (should (assoc "Saved adhoc" pearl-local-views)))))
(provide 'test-pearl-adhoc)
;;; test-pearl-adhoc.el ends here
diff --git a/tests/test-pearl-bugfixes.el b/tests/test-pearl-bugfixes.el
index 9fe2518..c1348f1 100644
--- a/tests/test-pearl-bugfixes.el
+++ b/tests/test-pearl-bugfixes.el
@@ -133,21 +133,21 @@
;;; Bug: saved/ad-hoc query filters bypass validation
(ert-deftest test-pearl-run-saved-query-validates-before-fetch ()
- "A saved query with an unknown filter key errors before any fetch."
- (let ((pearl-saved-queries '(("bad" :filter (:bogus-key "x"))))
+ "A local view with an unknown filter key errors before any fetch."
+ (let ((pearl-local-views '(("bad" :filter (:bogus-key "x"))))
(fetched nil))
(cl-letf (((symbol-function 'pearl--query-issues-async)
(lambda (&rest _) (setq fetched t))))
- (should-error (pearl-run-saved-query "bad") :type 'user-error)
+ (should-error (pearl-run-local-view "bad") :type 'user-error)
(should-not fetched))))
(ert-deftest test-pearl-run-saved-query-validates-bad-priority ()
- "A saved query with an out-of-range priority errors before any fetch."
- (let ((pearl-saved-queries '(("bad" :filter (:priority 9))))
+ "A local view with an out-of-range priority errors before any fetch."
+ (let ((pearl-local-views '(("bad" :filter (:priority 9))))
(fetched nil))
(cl-letf (((symbol-function 'pearl--query-issues-async)
(lambda (&rest _) (setq fetched t))))
- (should-error (pearl-run-saved-query "bad") :type 'user-error)
+ (should-error (pearl-run-local-view "bad") :type 'user-error)
(should-not fetched))))
(provide 'test-pearl-bugfixes)
diff --git a/tests/test-pearl-favorites.el b/tests/test-pearl-favorites.el
index 70507d7..b6235c7 100644
--- a/tests/test-pearl-favorites.el
+++ b/tests/test-pearl-favorites.el
@@ -177,7 +177,7 @@ For an issue node, IDENTIFIER fills the issue's user-facing key."
;;; pick-source candidate builder
(ert-deftest test-pearl-pick-source-candidates-orders-favorites-by-sort-order ()
- "Favorites are listed first in ascending :sort-order, then saved queries alphabetically."
+ "Favorites are listed first in ascending :sort-order, then local views alphabetically."
(let* ((favs (list (test-pearl-fav--norm 'project "p1" "Bravo") ; sort-order 0.0
(let ((f (test-pearl-fav--norm 'view "v1" "Alpha")))
(plist-put f :sort-order -1.0)))) ; lower, comes first
@@ -210,10 +210,10 @@ For an issue node, IDENTIFIER fills the issue's user-facing key."
(should (= 2 (length (delete-dups (copy-sequence labels)))))))
(ert-deftest test-pearl-pick-source-candidates-empty ()
- "No favorites and no saved queries yields no candidates."
+ "No favorites and no local views yields no candidates."
(should (null (pearl--pick-source-candidates nil nil))))
-;;; pick-source candidate builder -- synced saved queries (view-sync Phase 4)
+;;; pick-source candidate builder -- synced local views (view-sync Phase 4)
(ert-deftest test-pearl-pick-source-candidates-synced-saved-query-team-scope ()
"A team-scoped synced entry renders as `[saved \\u2192 <TeamName>] <Name>'."
@@ -285,7 +285,7 @@ source plist; the open-in-Linear command errors cleanly until the user re-syncs.
(should-not (plist-get source :url))))
(ert-deftest test-pearl-pick-source-candidates-local-only-saved-query-keeps-saved-label ()
- "A saved query without :linear-view-id still renders as `[saved] <Name>' and dispatches as filter."
+ "A local view without :linear-view-id still renders as `[saved] <Name>' and dispatches as filter."
(let* ((saved '(("Local" :filter (:open t))))
(cands (pearl--pick-source-candidates nil saved '()))
(source (cdr (assoc "[saved] Local" cands))))
diff --git a/tests/test-pearl-keymap.el b/tests/test-pearl-keymap.el
index 1ae0d3d..f80a002 100644
--- a/tests/test-pearl-keymap.el
+++ b/tests/test-pearl-keymap.el
@@ -71,11 +71,11 @@ The lowercase `c' is no longer a direct command -- it is the create prefix."
(should (eq 'pearl-list-issues (lookup-key pearl-prefix-map (kbd "f o"))))
(should (eq 'pearl-list-issues-by-project (lookup-key pearl-prefix-map (kbd "f p"))))
(should (eq 'pearl-list-issues-filtered (lookup-key pearl-prefix-map (kbd "f f"))))
- (should (eq 'pearl-run-view (lookup-key pearl-prefix-map (kbd "f v"))))
- (should (eq 'pearl-run-saved-query (lookup-key pearl-prefix-map (kbd "f q"))))
- (should (eq 'pearl-sync-saved-query-to-linear
+ (should (eq 'pearl-run-linear-view (lookup-key pearl-prefix-map (kbd "f v"))))
+ (should (eq 'pearl-run-local-view (lookup-key pearl-prefix-map (kbd "f q"))))
+ (should (eq 'pearl-publish-local-view
(lookup-key pearl-prefix-map (kbd "f S"))))
- (should (eq 'pearl-publish-current-source
+ (should (eq 'pearl-publish-current-view
(lookup-key pearl-prefix-map (kbd "f P")))))
(ert-deftest test-pearl-prefix-map-edit-group ()
@@ -94,7 +94,7 @@ The lowercase `c' is no longer a direct command -- it is the create prefix."
(should (eq 'pearl-create-comment (lookup-key pearl-prefix-map (kbd "c c"))))
(should (eq 'pearl-delete-current-issue (lookup-key pearl-prefix-map (kbd "k t"))))
(should (eq 'pearl-delete-current-comment (lookup-key pearl-prefix-map (kbd "k c"))))
- (should (eq 'pearl-delete-saved-query (lookup-key pearl-prefix-map (kbd "k q")))))
+ (should (eq 'pearl-delete-local-view (lookup-key pearl-prefix-map (kbd "k q")))))
(ert-deftest test-pearl-prefix-map-open-and-copy-groups ()
"The open group resolves the two open actions; copy resolves copy-url."
diff --git a/tests/test-pearl-menu.el b/tests/test-pearl-menu.el
index e2ea550..9c97384 100644
--- a/tests/test-pearl-menu.el
+++ b/tests/test-pearl-menu.el
@@ -60,10 +60,10 @@ menu entry that still points at it fails here."
"A representative slice of the command surface is reachable from the menu."
(let ((cmds (mapcar #'cdr (test-pearl-menu--pairs))))
(dolist (expected '(pearl-list-issues
- pearl-run-view
- pearl-run-saved-query
- pearl-sync-saved-query-to-linear
- pearl-publish-current-source
+ pearl-run-linear-view
+ pearl-run-local-view
+ pearl-publish-local-view
+ pearl-publish-current-view
pearl-save-issue
pearl-save-all
pearl-edit-state
diff --git a/tests/test-pearl-naming.el b/tests/test-pearl-naming.el
new file mode 100644
index 0000000..41077e9
--- /dev/null
+++ b/tests/test-pearl-naming.el
@@ -0,0 +1,74 @@
+;;; test-pearl-naming.el --- Naming-regression tests for local/Linear views -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Craig Jennings
+
+;; Author: Craig Jennings <c@cjennings.net>
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The local/Linear views spec renames Pearl's "saved query" surface to
+;; local-view vocabulary with NO obsolete aliases (Pearl has no users).
+;; These tests enforce the contract: the new public symbols exist, the old
+;; ones are gone (not aliased), and no user-facing command exposes "query".
+
+;;; Code:
+
+(require 'test-bootstrap (expand-file-name "test-bootstrap.el"))
+
+(defconst test-pearl-naming--new-commands
+ '(pearl-run-local-view
+ pearl-delete-local-view
+ pearl-publish-local-view
+ pearl-publish-current-view
+ pearl-run-linear-view)
+ "Public commands the rename introduces.")
+
+(defconst test-pearl-naming--old-symbols
+ '(pearl-saved-queries
+ pearl-run-saved-query
+ pearl-delete-saved-query
+ pearl-sync-saved-query-to-linear
+ pearl-run-view
+ pearl-publish-current-source)
+ "Old user-facing symbols that must be gone (renamed, not aliased).")
+
+(ert-deftest test-pearl-naming-new-defcustom-bound ()
+ "`pearl-local-views' is the renamed local-view store."
+ (should (boundp 'pearl-local-views)))
+
+(ert-deftest test-pearl-naming-new-commands-exist ()
+ "Every renamed public command is defined and interactive."
+ (dolist (cmd test-pearl-naming--new-commands)
+ (should (fboundp cmd))
+ (should (commandp cmd))))
+
+(ert-deftest test-pearl-naming-old-symbols-gone ()
+ "The old saved-query symbols are not bound -- direct rename, no aliases."
+ (dolist (sym test-pearl-naming--old-symbols)
+ (should-not (fboundp sym))
+ (should-not (boundp sym))))
+
+(ert-deftest test-pearl-naming-no-user-facing-query-in-docstrings ()
+ "Public local-view commands and the defcustom carry no \"saved query\" text.
+\"query\" alone survives only in internal GraphQL helpers, not here."
+ (dolist (sym (cons 'pearl-local-views test-pearl-naming--new-commands))
+ (let ((doc (or (documentation-property sym 'variable-documentation)
+ (ignore-errors (documentation sym))
+ "")))
+ (should-not (string-match-p "saved quer" doc)))))
+
+(provide 'test-pearl-naming)
+;;; test-pearl-naming.el ends here
diff --git a/tests/test-pearl-resolve.el b/tests/test-pearl-resolve.el
index 0812f94..aefe27a 100644
--- a/tests/test-pearl-resolve.el
+++ b/tests/test-pearl-resolve.el
@@ -21,7 +21,7 @@
;; Tests for the per-team cached collection fetch (`--team-collection') and
;; the name->id resolver (`--resolve-team-id'), which back the field commands,
-;; the ad-hoc filter, and saved queries. The HTTP boundary is stubbed; the
+;; the ad-hoc filter, and local views. The HTTP boundary is stubbed; the
;; cache is reset around each test.
;;; Code:
diff --git a/tests/test-pearl-saved-query-sync.el b/tests/test-pearl-saved-query-sync.el
index e237108..534993e 100644
--- a/tests/test-pearl-saved-query-sync.el
+++ b/tests/test-pearl-saved-query-sync.el
@@ -1,4 +1,4 @@
-;;; test-pearl-saved-query-sync.el --- Tests for syncing saved queries to Linear views -*- lexical-binding: t; -*-
+;;; test-pearl-saved-query-sync.el --- Tests for syncing local views to Linear views -*- lexical-binding: t; -*-
;; Copyright (C) 2026 Craig Jennings
@@ -19,7 +19,7 @@
;;; Commentary:
-;; Tests for `pearl-sync-saved-query-to-linear' and its helpers
+;; Tests for `pearl-publish-local-view' and its helpers
;; (`pearl--sync-scope-candidates', `pearl--find-view-by-name-in-scope',
;; `pearl--customview-create-async', `pearl--customview-update-async',
;; `pearl--save-query-mark-synced', `pearl--sync-record-or-orphan-error').
@@ -254,11 +254,11 @@ label, plist team-id nil + team-name \"Personal\" + shared nil."
(ert-deftest test-pearl-save-query-mark-synced-adds-the-four-keys ()
"After mark-synced, the entry carries `:linear-view-id', `-team-id', `-shared', `-synced-at'."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t))))))
(cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
(pearl--save-query-mark-synced "Q" "team-uuid" t "view-uuid"))
- (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (let ((spec (cdr (assoc "Q" pearl-local-views))))
(should (equal "view-uuid" (plist-get spec :linear-view-id)))
(should (equal "team-uuid" (plist-get spec :linear-view-team-id)))
(should (eq t (plist-get spec :linear-view-shared)))
@@ -268,39 +268,39 @@ label, plist team-id nil + team-name \"Personal\" + shared nil."
(ert-deftest test-pearl-save-query-mark-synced-preserves-sort-and-order ()
"Mark-synced doesn't drop `:sort' or `:order' from the entry."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t) :sort updated :order desc)))))
(cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
(pearl--save-query-mark-synced "Q" nil nil "view-uuid"))
- (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (let ((spec (cdr (assoc "Q" pearl-local-views))))
(should (eq 'updated (plist-get spec :sort)))
(should (eq 'desc (plist-get spec :order))))))
(ert-deftest test-pearl-save-query-mark-synced-personal-nil-team ()
"Personal scope persists `:linear-view-team-id' as nil and `:linear-view-shared' nil."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t))))))
(cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
(pearl--save-query-mark-synced "Q" nil nil "view-uuid"))
- (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (let ((spec (cdr (assoc "Q" pearl-local-views))))
(should (null (plist-get spec :linear-view-team-id)))
(should (null (plist-get spec :linear-view-shared))))))
(ert-deftest test-pearl-save-query-mark-synced-unknown-name-signals-user-error ()
"Mark-synced on a name that doesn't exist signals a `user-error'."
- (let ((pearl-saved-queries '()))
+ (let ((pearl-local-views '()))
(should-error
(pearl--save-query-mark-synced "Q" nil nil "view-uuid")
:type 'user-error)))
(ert-deftest test-pearl-save-query-mark-synced-stores-view-url-when-given ()
"The optional VIEW-URL arg lands in the entry as :linear-view-url."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t))))))
(cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
(pearl--save-query-mark-synced
"Q" nil nil "view-uuid" "https://linear.app/ws/view/abc"))
- (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (let ((spec (cdr (assoc "Q" pearl-local-views))))
(should (equal "https://linear.app/ws/view/abc"
(plist-get spec :linear-view-url))))))
@@ -308,7 +308,7 @@ label, plist team-id nil + team-name \"Personal\" + shared nil."
"Omitting VIEW-URL on a re-sync preserves any previously stored URL.
Re-sync paths whose API response doesn't carry a URL shouldn't erase a
URL the create path already wrote."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)
:linear-view-id "old-id"
:linear-view-team-id nil
@@ -317,7 +317,7 @@ URL the create path already wrote."
(cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
;; No VIEW-URL passed -- the prior URL should survive.
(pearl--save-query-mark-synced "Q" nil nil "new-id"))
- (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (let ((spec (cdr (assoc "Q" pearl-local-views))))
(should (equal "https://linear.app/ws/view/old"
(plist-get spec :linear-view-url))))))
@@ -327,7 +327,7 @@ The earlier implementation rebuilt the spec from a fixed key set and
silently dropped anything outside it. Copy-then-plist-put preserves
arbitrary keys so a future schema field or user annotation isn't
erased on every re-sync."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)
:sort updated
:order desc
@@ -335,7 +335,7 @@ erased on every re-sync."
:user-tag "experimental")))))
(cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
(pearl--save-query-mark-synced "Q" "team-uuid" t "view-uuid" "https://x"))
- (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (let ((spec (cdr (assoc "Q" pearl-local-views))))
;; Original keys survive.
(should (equal '(:open t) (plist-get spec :filter)))
(should (eq 'updated (plist-get spec :sort)))
@@ -351,7 +351,7 @@ erased on every re-sync."
(ert-deftest test-pearl-save-query-mark-synced-overwrites-prior-sync-metadata ()
"Re-syncing an already-synced entry overwrites the four `:linear-view-*' keys."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)
:linear-view-id "OLD-id"
:linear-view-team-id "OLD-team"
@@ -359,7 +359,7 @@ erased on every re-sync."
:linear-view-synced-at "1970-01-01T00:00:00Z")))))
(cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
(pearl--save-query-mark-synced "Q" "NEW-team" t "NEW-id"))
- (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (let ((spec (cdr (assoc "Q" pearl-local-views))))
(should (equal "NEW-id" (plist-get spec :linear-view-id)))
(should (equal "NEW-team" (plist-get spec :linear-view-team-id)))
(should (eq t (plist-get spec :linear-view-shared)))
@@ -445,7 +445,7 @@ erased on every re-sync."
"Re-sync of an entry with `:linear-view-shared :json-false' must NOT flip it shared.
`:json-false' is truthy in Elisp, so a stored `:json-false' would slip past
`(if shared t :json-false)' in the encoder and silently make the view team-shared."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)
:linear-view-id "view-id"
:linear-view-team-id nil
@@ -465,18 +465,18 @@ erased on every re-sync."
(funcall cb (list :success t
:view '((id . "view-id")
(shared . :json-false)))))))
- (pearl-sync-saved-query-to-linear "Q")
+ (pearl-publish-local-view "Q")
(let ((shared-value (cdr (assoc "shared" captured-input))))
(should (eq :json-false shared-value))))))
-;;; pearl-sync-saved-query-to-linear — empty filter refusal
+;;; pearl-publish-local-view — empty filter refusal
(ert-deftest test-pearl-sync-empty-filter-refuses-before-scope-prompt ()
- "A first-time-sync saved query whose filter compiles to nil signals a clear
+ "A first-time-sync local view whose filter compiles to nil signals a clear
user-error before any scope prompt fires. Without the guard, the sync would
pass filterData=null to Linear, which rejects with an opaque error after the
user has already clicked through the scope picker."
- (let ((pearl-saved-queries (copy-tree '(("EmptyFilter" :filter nil))))
+ (let ((pearl-local-views (copy-tree '(("EmptyFilter" :filter nil))))
(scope-prompt-fired nil)
(api-called nil))
(cl-letf (((symbol-function 'pearl--sync-saved-query-pick-scope)
@@ -488,7 +488,7 @@ user has already clicked through the scope picker."
(list :team-id nil :team-name "Personal" :shared nil))))
((symbol-function 'pearl--customview-create-async)
(lambda (&rest _) (setq api-called t))))
- (should-error (pearl-sync-saved-query-to-linear "EmptyFilter")
+ (should-error (pearl-publish-local-view "EmptyFilter")
:type 'user-error)
(should-not scope-prompt-fired)
(should-not api-called))))
@@ -498,7 +498,7 @@ user has already clicked through the scope picker."
edited down to nil takes the same empty-filter guard, refusing without
calling customViewUpdate. Guards against a future refactor accidentally
hoisting the guard into the create-only branch."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("EmptyFilter" :filter nil
:linear-view-id "existing-view-uuid"
:linear-view-team-id nil
@@ -506,11 +506,11 @@ hoisting the guard into the create-only branch."
(update-called nil))
(cl-letf (((symbol-function 'pearl--customview-update-async)
(lambda (&rest _) (setq update-called t))))
- (should-error (pearl-sync-saved-query-to-linear "EmptyFilter")
+ (should-error (pearl-publish-local-view "EmptyFilter")
:type 'user-error)
(should-not update-called))))
-;;; pearl-publish-current-source
+;;; pearl-publish-current-view
(defmacro test-pearl-publish--in-buffer (source-form &rest body)
"Run BODY in an org-mode temp buffer carrying SOURCE-FORM as #+LINEAR-SOURCE.
@@ -526,50 +526,50 @@ SOURCE-FORM is the source plist (or nil for no source header)."
(ert-deftest test-pearl-publish-current-source-no-source-header-errors ()
"A buffer with no #+LINEAR-SOURCE signals a clear user-error."
(test-pearl-publish--in-buffer nil
- (should-error (pearl-publish-current-source) :type 'user-error)))
+ (should-error (pearl-publish-current-view) :type 'user-error)))
(ert-deftest test-pearl-publish-current-source-view-source-errors ()
"A view source signals user-error -- views are already on Linear."
(test-pearl-publish--in-buffer '(:type view :name "Eng dashboard" :id "v1")
- (should-error (pearl-publish-current-source) :type 'user-error)))
+ (should-error (pearl-publish-current-view) :type 'user-error)))
(ert-deftest test-pearl-publish-current-source-transient-filter-no-name-errors ()
"A :type filter with no :name (transient ad-hoc) signals user-error."
(test-pearl-publish--in-buffer '(:type filter :filter (:open t))
- (should-error (pearl-publish-current-source) :type 'user-error)))
+ (should-error (pearl-publish-current-view) :type 'user-error)))
(ert-deftest test-pearl-publish-current-source-no-matching-saved-query-errors ()
- "A :type filter source whose name doesn't match any pearl-saved-queries entry errors."
- (let ((pearl-saved-queries '(("Other" :filter (:open t)))))
+ "A :type filter source whose name doesn't match any pearl-local-views entry errors."
+ (let ((pearl-local-views '(("Other" :filter (:open t)))))
(test-pearl-publish--in-buffer
'(:type filter :name "Gone" :filter (:open t))
- (should-error (pearl-publish-current-source) :type 'user-error))))
+ (should-error (pearl-publish-current-view) :type 'user-error))))
(ert-deftest test-pearl-publish-current-source-dispatches-to-sync-with-name ()
- "A :type filter source whose name matches dispatches to pearl-sync-saved-query-to-linear."
- (let ((pearl-saved-queries '(("Mine" :filter (:open t))))
+ "A :type filter source whose name matches dispatches to pearl-publish-local-view."
+ (let ((pearl-local-views '(("Mine" :filter (:open t))))
(sync-called-with nil))
- (cl-letf (((symbol-function 'pearl-sync-saved-query-to-linear)
+ (cl-letf (((symbol-function 'pearl-publish-local-view)
(lambda (n) (setq sync-called-with n))))
(test-pearl-publish--in-buffer
'(:type filter :name "Mine" :filter (:open t))
- (pearl-publish-current-source))
+ (pearl-publish-current-view))
(should (equal "Mine" sync-called-with)))))
(ert-deftest test-pearl-publish-current-source-empty-name-errors ()
"A :type filter source with an empty-string :name (degenerate) errors cleanly."
(test-pearl-publish--in-buffer
'(:type filter :name "" :filter (:open t))
- (should-error (pearl-publish-current-source) :type 'user-error)))
+ (should-error (pearl-publish-current-view) :type 'user-error)))
(ert-deftest test-pearl-publish-current-source-whitespace-name-errors ()
"A :type filter source with a whitespace-only :name takes the no-name branch
rather than falling through to the no-matching-saved-query branch with a
visibly-blank name in the error message."
- (let ((pearl-saved-queries '()))
+ (let ((pearl-local-views '()))
(test-pearl-publish--in-buffer
'(:type filter :name " " :filter (:open t))
- (let ((err (should-error (pearl-publish-current-source)
+ (let ((err (should-error (pearl-publish-current-view)
:type 'user-error)))
;; The message should name the source-has-no-name reason, not the
;; no-matching-query reason.
@@ -609,7 +609,7 @@ team-key lookups."
(pearl--customview-delete-async "view-uuid" (lambda (r) (setq result r)))
(should-not (plist-get result :success)))))
-;;; pearl-delete-saved-query — synced-entry second-stage prompt
+;;; pearl-delete-local-view — synced-entry second-stage prompt
(defun test-pearl--make-yes-no-stub (answers)
"Return a `yes-or-no-p' replacement that returns each ANSWERS in order.
@@ -623,7 +623,7 @@ more prompts fire than answers were prepared for."
(ert-deftest test-pearl-delete-saved-query-synced-yes-yes-calls-customview-delete ()
"Synced entry, both prompts yes: customViewDelete fires and the local entry is removed."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)
:linear-view-id "view-uuid"
:linear-view-team-id nil
@@ -638,13 +638,13 @@ more prompts fire than answers were prepared for."
(lambda (vid cb)
(setq delete-called-with vid)
(funcall cb (list :success t)))))
- (pearl-delete-saved-query "Q")
+ (pearl-delete-local-view "Q")
(should (equal "view-uuid" delete-called-with))
- (should-not (assoc "Q" pearl-saved-queries)))))
+ (should-not (assoc "Q" pearl-local-views)))))
(ert-deftest test-pearl-delete-saved-query-synced-yes-no-unlinks-only ()
"Synced entry, first prompt yes second prompt no: local entry removed, customViewDelete not called."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)
:linear-view-id "view-uuid"))))
(delete-called nil))
@@ -655,13 +655,13 @@ more prompts fire than answers were prepared for."
((symbol-function 'message) (lambda (&rest _) nil))
((symbol-function 'pearl--customview-delete-async)
(lambda (_ _) (setq delete-called t))))
- (pearl-delete-saved-query "Q")
+ (pearl-delete-local-view "Q")
(should-not delete-called)
- (should-not (assoc "Q" pearl-saved-queries)))))
+ (should-not (assoc "Q" pearl-local-views)))))
(ert-deftest test-pearl-delete-saved-query-synced-api-failure-then-delete-anyway ()
"Synced entry, customViewDelete fails, user accepts delete-anyway prompt: local removed, message names the orphan id."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)
:linear-view-id "ORPHAN-UUID"))))
(last-message nil))
@@ -675,8 +675,8 @@ more prompts fire than answers were prepared for."
((symbol-function 'pearl--customview-delete-async)
(lambda (_ cb)
(funcall cb (list :success nil :error "permission denied")))))
- (pearl-delete-saved-query "Q")
- (should-not (assoc "Q" pearl-saved-queries))
+ (pearl-delete-local-view "Q")
+ (should-not (assoc "Q" pearl-local-views))
(should (string-match-p "ORPHAN-UUID" last-message))
(should (string-match-p "orphan" last-message)))))
@@ -685,7 +685,7 @@ more prompts fire than answers were prepared for."
Verifies the API call actually fires (so the keep branch only runs when the
delete-anyway prompt explicitly declines), guarding against a future refactor
that silently routes to the unlink branch and skips the API call."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)
:linear-view-id "view-uuid"))))
(delete-called-with nil))
@@ -698,13 +698,13 @@ that silently routes to the unlink branch and skips the API call."
(lambda (vid cb)
(setq delete-called-with vid)
(funcall cb (list :success nil :error "permission denied")))))
- (pearl-delete-saved-query "Q")
+ (pearl-delete-local-view "Q")
(should (equal "view-uuid" delete-called-with))
- (should (assoc "Q" pearl-saved-queries)))))
+ (should (assoc "Q" pearl-local-views)))))
(ert-deftest test-pearl-delete-saved-query-local-only-entry-unchanged-behavior ()
"Local-only entry (no `:linear-view-id'): one yes-or-no-p, no second prompt, no API call."
- (let ((pearl-saved-queries
+ (let ((pearl-local-views
(copy-tree '(("Q" :filter (:open t)))))
(delete-called nil)
(prompt-count 0))
@@ -714,10 +714,10 @@ that silently routes to the unlink branch and skips the API call."
((symbol-function 'message) (lambda (&rest _) nil))
((symbol-function 'pearl--customview-delete-async)
(lambda (_ _) (setq delete-called t))))
- (pearl-delete-saved-query "Q")
+ (pearl-delete-local-view "Q")
(should (= 1 prompt-count))
(should-not delete-called)
- (should-not (assoc "Q" pearl-saved-queries)))))
+ (should-not (assoc "Q" pearl-local-views)))))
(provide 'test-pearl-saved-query-sync)
;;; test-pearl-saved-query-sync.el ends here
diff --git a/tests/test-pearl-saved.el b/tests/test-pearl-saved.el
index 88bf468..d5f14e0 100644
--- a/tests/test-pearl-saved.el
+++ b/tests/test-pearl-saved.el
@@ -1,4 +1,4 @@
-;;; test-pearl-saved.el --- Tests for saved queries + sort -*- lexical-binding: t; -*-
+;;; test-pearl-saved.el --- Tests for local views + sort -*- lexical-binding: t; -*-
;; Copyright (C) 2026 Craig Jennings
@@ -19,8 +19,8 @@
;;; Commentary:
-;; Tests for local saved queries and the sort layer: the client-side
-;; `--sort-issues', the sort->orderBy mapping, and `pearl-run-saved-query'
+;; Tests for local views and the sort layer: the client-side
+;; `--sort-issues', the sort->orderBy mapping, and `pearl-run-local-view'
;; threading the filter, source, and order through.
;;; Code:
@@ -69,8 +69,8 @@
;;; run-saved-query
(ert-deftest test-pearl-run-saved-query-threads-filter-and-source ()
- "Running a saved query compiles its filter and renders with a sorted source."
- (let ((pearl-saved-queries
+ "Running a local view compiles its filter and renders with a sorted source."
+ (let ((pearl-local-views
'(("My bugs" :filter (:labels ("bug") :open t) :sort priority :order asc)))
(built nil) (rendered-source nil) (order nil))
(cl-letf (((symbol-function 'pearl--build-issue-filter)
@@ -80,7 +80,7 @@
(funcall cb (pearl--make-query-result 'ok :issues nil))))
((symbol-function 'pearl--render-query-result)
(lambda (_result source) (setq rendered-source source))))
- (pearl-run-saved-query "My bugs")
+ (pearl-run-local-view "My bugs")
(should (equal '(:labels ("bug") :open t) built))
(should (eq 'priority (plist-get rendered-source :sort)))
(should (eq 'asc (plist-get rendered-source :order)))
@@ -89,8 +89,8 @@
(ert-deftest test-pearl-run-saved-query-unknown-errors ()
"An unknown saved-query name signals a user error."
- (let ((pearl-saved-queries '(("Known" :filter (:open t)))))
- (should-error (pearl-run-saved-query "Missing") :type 'user-error)))
+ (let ((pearl-local-views '(("Known" :filter (:open t)))))
+ (should-error (pearl-run-local-view "Missing") :type 'user-error)))
;;; render applies the source sort
diff --git a/tests/test-pearl-views.el b/tests/test-pearl-views.el
index 2f2adfd..a750ae0 100644
--- a/tests/test-pearl-views.el
+++ b/tests/test-pearl-views.el
@@ -20,7 +20,7 @@
;;; Commentary:
;; Tests for reading and running Linear Custom Views: the cached views list,
-;; the server-side `--query-view-async' run, `pearl-run-view', the view
+;; the server-side `--query-view-async' run, `pearl-run-linear-view', the view
;; branch of refresh, and opening the active view in the browser. HTTP is
;; stubbed.
@@ -75,7 +75,7 @@
(funcall cb (pearl--make-query-result 'ok :issues nil))))
((symbol-function 'pearl--render-query-result)
(lambda (_result source) (setq rendered-source source))))
- (pearl-run-view "My View")
+ (pearl-run-linear-view "My View")
(should (string= "v1" ran-id))
(should (eq 'view (plist-get rendered-source :type)))
(should (string= "v1" (plist-get rendered-source :id)))