Skip to content

Commit cf93643

Browse files
committed
Squashed commit of the following:
commit 04eb24616eb3ee0e1e1c5df39753adba904d2593 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Tue Feb 18 18:57:31 2025 -0800 Favorites 1.2.6 commit ac3defa62ff27ddc9c9f1a98a58502c5f51d2172 Merge: f6e7f853 6f1b06b Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Tue Feb 18 18:50:34 2025 -0800 Merge branch 'main' into favorites-set-by-frontmatter commit f6e7f853c1cfdf06f6d100b5085534cf953c48d0 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Tue Feb 18 18:50:10 2025 -0800 Still hunting down the intermittent JS bug on settings change commit 4f33276c129db69dc37ad8a4e2dacef273af56b1 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Tue Feb 18 16:07:56 2025 -0800 Frontmatter fixes/optimizations and denoising logs commit 8afd2f025d087deecb7c0715403486125a6cd946 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Tue Feb 18 13:32:04 2025 -0800 more wip tests commit b21b4b434fc80b9f30cf6680ff7401195b599d46 Merge: c70586e2 f7e26c5 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Mon Feb 17 16:58:41 2025 -0800 Merge branch 'main' into favorites-set-by-frontmatter commit c70586e2d8d7d1d0d8514b90bb8b972e8d072fc9 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Mon Feb 17 16:56:15 2025 -0800 Updated the Editor mock to use a proxy commit ce793ef4418a0e61162d84698db3b626263911b5 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Mon Feb 17 15:07:50 2025 -0800 Lots of changes to Note mocking and frontmatter commit fd261cde4651dc53da7d94818599fd3c4cbd50e3 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Sun Feb 16 19:26:45 2025 -0800 wip changes commit a57430c9794e1c3894e88560032e4c4374a227c8 Merge: 56f5da5b 664d844 Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Sun Feb 16 03:24:40 2025 -0800 Merge branch 'main' into favorites-set-by-frontmatter commit 56f5da5b3dec860edf0c370d7c2cc4c1b9a768fa Author: David Wertheimer <dwertheimer@users.noreply.github.com> Date: Sun Feb 16 03:24:04 2025 -0800 Add frontmatter option to Favorites + tests
1 parent 6f1b06b commit cf93643

File tree

32 files changed

+1399
-528
lines changed

32 files changed

+1399
-528
lines changed

__mocks__/Editor.mock.js

Lines changed: 54 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,173 +1,72 @@
11
/* eslint-disable */
2-
/*
3-
* Editor mocks
2+
/**
3+
* Editor mocks with Proxy
44
*
5-
* Note: nested object example data are there for reference only -- will need to be deleted or cleaned up before use (consider using a factory)
6-
* For functions: check whether async or not & add params & return value
5+
* Editor and Note share many of the same properties+methods (CoreNoteFields), so most of them are defined in Note.mock.js and can apply to both.
76
*
8-
* TODO: IMPORTANT NOTE
9-
* - @dwertheimer started adding some of the underlying methods to Note.mock.js, but it's not complete
10-
* - if you need to add a method to Editor that's in Note also, add it to Note.mock.js and then add it here
7+
* This module uses a JavaScript Proxy to redirect all function calls to the underlying `note` object unless specifically overridden.
8+
* The `get` trap in the Proxy checks if a property exists on the `Editor` object. If it does, it returns that property.
9+
* If not, it delegates the call to the `note` object. If the property is not found in either, it throws an error.
1110
*
11+
* To override a function that is not in the underlying `note`, simply define it in the `editorOverrides` object.
12+
*
13+
* Note: All `open*` functions are specifically overridden to return `this.note`.
1214
*/
1315

1416
import { Note } from './Note.mock'
15-
const blankNote = new Note() // NOTE: try to reference the code in the Note mock wherever possible!
16-
// NOTE: blankNote is spread into Editor below, so any properties that exist in Note will overwrite the ones in Editor
17+
const noteObject = new Note() // NOTE: try to reference the code in the Note mock wherever possible!
18+
// NOTE: noteObject is spread into Editor below, so any properties that exist in Note will overwrite the ones in Editor
1719

18-
export const Editor = {
20+
const editorOverrides = {
1921
...{
20-
syncEditorWithNote() {
21-
this.paragraphs = this.note.paragraphs
22-
this.content = this.note.content
23-
// add other fields as needed
24-
},
25-
note: blankNote,
26-
addBlockID(p) {
27-
return this.note.addBlockID(p)
28-
},
29-
// async addParagraphBelowHeadingTitle() { return null },
30-
// async addTheme() { return null },
31-
// async addTodoBelowHeadingTitle() { return null },
32-
async appendParagraph(title = 'mock tester', type: 'text') {
33-
return this.note.appendParagraph(title, type)
34-
},
35-
// async appendParagraphBelowHeadingLineIndex() { return null },
36-
// async appendTodo() { return null },
37-
// async appendTodoBelowHeadingLineIndex() { return null },
38-
/* availableThemes: [{ return default }], */
39-
// content: VALUE ,
40-
// async copySelection() { return null },
41-
filename: 'thisFileName.txt',
42-
// async highlight() { return null },
43-
// async highlightByIndex() { return null },
44-
// async highlightByRange() { return null },
45-
// async insertCancelledTodo() { return null },
46-
// async insertCompletedTodo() { return null },
47-
// async insertHeading() { return null },
48-
// async insertList() { return null },
49-
// insertParagraph(name = 'mock tester', lineIndex = 1, type: 'text') {
50-
// return blankNote.insertParagraph(name, lineIndex, type)
51-
// },
52-
// async insertParagraphAfterParagraph() { return null },
53-
// async insertParagraphAtCursor() { return null },
54-
// async insertParagraphBeforeParagraph() { return null },
55-
// async insertQuote() { return null },
56-
// async insertScheduledTodo() { return null },
57-
async insertTextAtCharacterIndex(text = '', length = 0) {
58-
this.note.insertTextAtCharacterIndex(text, length)
59-
this.syncEditorWithNote()
60-
},
61-
async insertTextAtCursor(text: string) {
62-
this.note.insertTextAtCursor(text)
63-
this.syncEditorWithNote()
64-
},
65-
// async insertTodo() { return null },
66-
// async insertTodoAfterParagraph() { return null },
67-
// async insertTodoBeforeParagraph() { return null },
68-
async isFolded(para) {
69-
return false
70-
},
7122
async openNoteByDate(date: Date, newWindow?: boolean, highlightStart?: number, highlightEnd?: number, splitView?: boolean, timeframe?: string): Promise<TNote> {
72-
return this.note
73-
},
74-
// async openNoteByDateString() { return null },
75-
async openNoteByFilename() {
76-
return this.note
77-
},
78-
// async openNoteByTitle() { return null },
79-
// async openNoteByTitleCaseInsensitive() { return null },
80-
async paragraphRangeAtCharacterIndex() {
81-
return null
82-
},
83-
/* paragraphs: [{ return {
84-
"type": "title",
85-
"content": "MyNoteTitle",
86-
"rawContent": "# MyNoteTitle",
87-
"prefix": "# ",
88-
"contentRange": {},
89-
"lineIndex": 0,
90-
"heading": "",
91-
"headingLevel": 1,
92-
"isRecurring": false,
93-
"indents": 0,
94-
"filename": "_TEST/New Note - 15.3950.md",
95-
"noteType": "Notes",
96-
"linkedNoteTitles": [],
97-
"subItems": [],
98-
"referencedBlocks": [],
99-
"note": {}
100-
} }], */
101-
// async pasteClipboard() { return null },
102-
// async prependParagraph() { return null },
103-
// async prependTodo() { return null },
104-
// async printNote() { return null },
105-
// async removeBlockID() { return null },
106-
107-
async removeParagraph(para) {
108-
this.note.removeParagraph(para)
109-
this.syncEditorWithNote()
110-
return
23+
return noteObject
11124
},
112-
async removeParagraphs(paras) {
113-
this.note.removeParagraphs(paras)
114-
this.syncEditorWithNote()
115-
return
25+
async openNoteByDateString() {
26+
return noteObject
11627
},
117-
118-
// async removeParagraphAtIndex() { return null },
119-
// async renderedSelect() { return null },
120-
/* renderedSelection: {
121-
"start": 36,
122-
"end": 36,
123-
"length": 0
124-
} , */
125-
// async replaceSelectionWithText() { return null },
126-
// async replaceTextInCharacterRange() { return null },
127-
// async select() { return null },
128-
// async selectAll() { return null },
129-
/* selectedLinesText: [{ return * one task in the note }], */
130-
/* selectedParagraphs: [{ return {
131-
"type": "open",
132-
"content": "one task in the note",
133-
"rawContent": "* one task in the note",
134-
"prefix": "* ",
135-
"contentRange": {},
136-
"lineIndex": 0,
137-
"heading": "",
138-
"headingLevel": -1,
139-
"isRecurring": false,
140-
"indents": 0,
141-
"filename": "_TEST/New Note - 15.3950.md",
142-
"noteType": "Notes",
143-
"linkedNoteTitles": [],
144-
"subItems": [],
145-
"referencedBlocks": [],
146-
"note": {}
147-
} }], */
148-
// selectedText: VALUE ,
149-
/* selection: {
150-
"start": 36,
151-
"end": 36,
152-
"length": 0
153-
} , */
154-
// async setTheme() { return null },
155-
// title: VALUE ,
156-
async toggleFolding() {
157-
return null
28+
async openNoteByFilename() {
29+
return noteObject
15830
},
159-
// type: VALUE ,
160-
161-
async updateParagraph(para) {
162-
this.note.updateParagraph(para)
163-
this.syncEditorWithNote()
31+
async openNoteByTitle() {
32+
return noteObject
16433
},
165-
async updateParagraphs(paras) {
166-
this.note.updateParagraphs(paras)
167-
this.syncEditorWithNote()
34+
async openNoteByTitleCaseInsensitive() {
35+
return noteObject
16836
},
37+
note: noteObject,
16938
},
170-
...blankNote,
39+
...noteObject,
17140
}
17241

173-
// module.exports = Editor
42+
export const Editor = new Proxy(editorOverrides, {
43+
get(target, prop) {
44+
if (prop in target) {
45+
return target[prop]
46+
}
47+
if (prop in target.note) {
48+
return target.note[prop]
49+
}
50+
// Handle known built-in Symbol properties with sensible defaults
51+
const symbolProperties = [Symbol.iterator, Symbol.toPrimitive, Symbol.asyncIterator, Symbol.hasInstance, Symbol.toStringTag]
52+
if (symbolProperties.includes(prop)) {
53+
if (prop === Symbol.iterator) return undefined
54+
if (prop === Symbol.toPrimitive) return (hint) => (hint === 'number' ? NaN : String(target.note))
55+
if (prop === Symbol.asyncIterator) return undefined
56+
if (prop === Symbol.hasInstance) return undefined
57+
if (prop === Symbol.toStringTag) return 'Editor'
58+
}
59+
// Handle Jest specific methods that are not defined on Note and which should not cause errors
60+
if (['asymmetricMatch'].includes(prop)) {
61+
return undefined
62+
}
63+
// Throw detailed error if property is not found
64+
throw new Error(
65+
`Editor.mock.js: Property "${String(prop)}" not found. Editor.${String(prop)} or Note.${String(prop)} does not exist.\n` +
66+
`- Check if this property/method should be implemented in Note.mock.js.\n` +
67+
`- If it's Editor-specific, consider adding it to Editor.mock.js overrides in editorOverrides.\n` +
68+
`- If this is a Jest-specific method (such as 'asymmetricMatch') or a built-in Symbol (e.g., Symbol.iterator, Symbol.toPrimitive), ` +
69+
`return a sensible default instead.\n`,
70+
)
71+
},
72+
})

0 commit comments

Comments
 (0)