Skip to content

refresh lockfile

refresh lockfile #2183

GitHub Actions / Tests succeeded Oct 15, 2024 in 0s

561 passed, 0 failed and 0 skipped

Tests passed successfully

✅ reports/tests-junit.xml

561 tests were completed in 28s with 561 passed, 0 failed and 0 skipped.

Test suite Passed Failed Skipped Time
src/api/helpers.test.ts 20✅ 53ms
src/api/index.test.tsx 26✅ 247ms
src/api/logging.test.tsx 7✅ 50ms
src/clients/citoid/base.test.ts 4✅ 173ms
src/clients/citoid/hooks.test.ts 3✅ 1s
src/clients/index.test.ts 1✅ 70ms
src/clients/semantic/base.test.ts 1✅ 119ms
src/clients/semantic/hooks.test.ts 1✅ 94ms
src/clients/zotero/base.test.ts 22✅ 534ms
src/clients/zotero/helpers.test.ts 19✅ 22ms
src/clients/zotero/hooks.test.ts 5✅ 314ms
src/clients/zotero/mutations.test.tsx 3✅ 228ms
src/components/Dashboard/Explorer/helpers.test.tsx 23✅ 418ms
src/components/Dashboard/Explorer/QueryItems/filters.test.tsx 51✅ 399ms
src/components/Dashboard/Explorer/QueryNotes/filters.test.ts 4✅ 8ms
src/components/Dashboard/Explorer/QueryPDFs/filters.test.ts 8✅ 9ms
src/components/Dashboard/Explorer/QueryPDFs/helpers.test.ts 2✅ 7ms
src/components/Dashboard/TagManager/utils.test.ts 11✅ 13ms
src/components/GraphWatcher/helpers.test.ts 6✅ 8ms
src/components/GraphWatcher/Menus/helpers.test.ts 12✅ 10ms
src/components/GraphWatcher/Menus/utils.test.tsx 9✅ 76ms
src/components/GraphWatcher/WebImport/helpers.test.tsx 3✅ 43ms
src/components/NotesDrawer/helpers.test.ts 1✅ 4ms
src/components/SearchPanel/helpers.test.ts 9✅ 11ms
src/components/UserSettings/common.test.ts 3✅ 4ms
src/components/ZoteroImport/helpers.test.ts 2✅ 6ms
src/hooks/index.test.ts 17✅ 59ms
src/hooks/useSearchQuery/helpers.test.ts 75✅ 29ms
src/hooks/useSearchQuery/index.test.ts 32✅ 94ms
src/services/events/index.test.ts 14✅ 69ms
src/services/idb/index.test.ts 4✅ 69ms
src/services/react-query/index.test.ts 6✅ 18ms
src/services/search/index.test.ts 30✅ 19ms
src/services/smartblocks/helpers.test.ts 5✅ 9ms
src/services/smartblocks/index.test.ts 19✅ 551ms
tests/utils/annotations.test.ts 4✅ 8ms
tests/utils/formatters.test.ts 33✅ 19ms
tests/utils/items.test.ts 2✅ 9ms
tests/utils/misc.test.ts 6✅ 8ms
tests/utils/notes.test.ts 8✅ 13ms
tests/utils/search.test.ts 15✅ 19ms
tests/utils/setup.test.tsx 35✅ 72ms

✅ src/api/helpers.test.ts

src/api/helpers.test.ts
  ✅ cleanBibliographyHTML > formats citations with one content div (like Chicago)
  ✅ cleanBibliographyHTML > formats citations with multiple content divs (like Vancouver)
  ✅ compareAnnotationRawIndices
  ✅ formatNotes > sorts output
  ✅ formatNotes > handles nested output (with preset)
  ✅ formatNotes > handles nested output (with custom string)
  ✅ formatNotes > handles nested output, with block checking
  ✅ formatNotes > handles nested output, with block checking & position
  ✅ formatZoteroAnnotations > formats with defaults
  ✅ formatZoteroAnnotations > groups by day added
  ✅ getItemCreators > 0
  ✅ getItemCreators > 1
  ✅ getItemCreators > 2
  ✅ getItemCreators > 3
  ✅ getItemDateAdded
  ✅ getItemTags > 0
  ✅ getItemTags > 1
  ✅ getItemTags > 2
  ✅ getItemTags > 3
  ✅ getItemTags > 4

✅ src/api/index.test.tsx

src/api/index.test.tsx
  ✅ Formatting utils > formatNotes
  ✅ Formatting utils > formatPDFs
  ✅ Formatting utils > getItemDateAdded
  ✅ Formatting utils > getItemLink
  ✅ Formatting utils > getItemPublication > 0 - no brackets
  ✅ Formatting utils > getItemPublication > 1 - no brackets
  ✅ Formatting utils > getItemPublication > 2 - no brackets
  ✅ Formatting utils > getItemPublication > 3 - no brackets
  ✅ Formatting utils > getItemPublication > 0 - with brackets
  ✅ Formatting utils > getItemPublication > 1 - with brackets
  ✅ Formatting utils > getItemPublication > 2 - with brackets
  ✅ Formatting utils > getItemPublication > 3 - with brackets
  ✅ Formatting utils > Retrieving the formatted type for an item > 0
  ✅ Formatting utils > Retrieving the formatted type for an item > 1
  ✅ Retrieval utils > Retrieving creators data for an item
  ✅ Retrieval utils > Retrieving tags data for an item
  ✅ Retrieval utils > Retrieving bibliography for an item > It should return the clean bibliography
  ✅ Retrieval utils > Retrieving bibliographic entries for a list of citekeys
  ✅ Database connectivity > can manage the cache
  ✅ Database connectivity > can delete the database
  ✅ isDataCached > returns false when no data has been persisted yet
  ✅ isDataCached > returns true when data has been persisted
  ✅ isDataCached > returns false when there is no database
  ✅ Error logging when the database no longer exists > handles attempting to clear the React Query store
  ✅ Error logging when the database no longer exists > handles attempting to check if there is cached data
  ✅ Error logging when the database no longer exists > handles attempting to fetch the timestamp for the last caching operation

✅ src/api/logging.test.tsx

src/api/logging.test.tsx
  ✅ ZoteroRoamLog > uses fallback values
  ✅ ZoteroRoamLog > initializes with values provided
  ✅ ZoteroRoamLog > calls the toaster when showToaster is provided
  ✅ ZoteroRoamLog > creates the right message for the toaster
  ✅ Logger > logs errors
  ✅ Logger > logs infos
  ✅ Logger > logs warnings

✅ src/clients/citoid/base.test.ts

src/clients/citoid/base.test.ts
  ✅ fetchCitoid > 0 Successfully mocking Citoid data for https://www.jmir.org/2021/9/e27283
  ✅ fetchCitoid > 1 Successfully mocking Citoid data for https://doi.org/10.1370/afm.1918
  ✅ fetchCitoid > 2 Successfully mocking Citoid data for https://doi.org/10.3122/jabfm.2017.01.160355
  ✅ fetchCitoid > 0 Successfully mocking Citoid error for https://projects.iq.harvard.edu/files/harvarduxgroup/files/ux-research-guide-sample-questions-for-user-interviews.pdf

✅ src/clients/citoid/hooks.test.ts

src/clients/citoid/hooks.test.ts
  ✅ useCitoids > 1 valid identifier
  ✅ useCitoids > 1 invalid identifier
  ✅ useCitoids > 1 valid + 1 invalid

✅ src/clients/index.test.ts

src/clients/index.test.ts
  ✅ Mock fallback > is called when no matching handler exists

✅ src/clients/semantic/base.test.ts

src/clients/semantic/base.test.ts
  ✅ Fetching mocked Semantic data > 0 Successfully mocking Semantic data for 10.1503/cmaj.210229

✅ src/clients/semantic/hooks.test.ts

src/clients/semantic/hooks.test.ts
  ✅ useSemantic > returns fetch results - 10.1503/cmaj.210229

✅ src/clients/zotero/base.test.ts

src/clients/zotero/base.test.ts
  ✅ Fetching mocked API Key permissions > 0 Fetching permissions for keyWithFullAccess
  ✅ Fetching mocked API Key permissions > 1 Fetching permissions for keyWithNoGroupAccess
  ✅ Fetching mocked bibliography > 0 Fetching bibliography as bib for itemInLibrary
  ✅ Fetching mocked bibliography > 1 Fetching bibliography as bib for itemFromUserLibrary
  ✅ Fetching mocked bibliography entries > 0 Fetching a bibliography entry from userLibrary
  ✅ Fetching mocked bibliography entries > 1 Fetching a bibliography entry from groupLibrary
  ✅ Fetching mocked collections > 0 There should be no items older than latest in userLibrary
  ✅ Fetching mocked collections > 1 There should be no items older than latest in groupLibrary
  ✅ Fetching mocked collections > 0 Fetching collections for userLibrary
  ✅ Fetching mocked collections > 1 Fetching collections for groupLibrary
  ✅ Fetching mocked deleted entities > 0 Fetching entities deleted from userLibrary
  ✅ Fetching mocked deleted entities > 1 Fetching entities deleted from groupLibrary
  ✅ Fetching mocked deleted entities > 0 Checking that no entities are versioned over latest in userLibrary
  ✅ Fetching mocked deleted entities > 1 Checking that no entities are versioned over latest in groupLibrary
  ✅ Fetching mocked items > 0 Fetching items for userLibrary
  ✅ Fetching mocked items > 1 Fetching items for groupLibrary
  ✅ writeItems > 0 Updating an item from userLibrary
  ✅ writeItems > 1 Updating an item from groupLibrary
  ✅ fetchTags > 0 Fetching tags for userLibrary
  ✅ fetchTags > 1 Fetching tags for groupLibrary
  ✅ deleteTags > 0 Deleting tags in userLibrary
  ✅ deleteTags > 1 Deleting tags in groupLibrary

✅ src/clients/zotero/helpers.test.ts

src/clients/zotero/helpers.test.ts
  ✅ Extracting citekeys for Zotero items
  ✅ Comparing tag entries > Tag comparison 0
  ✅ Comparing tag entries > Tag comparison 1
  ✅ Comparing tag entries > Tag comparison 2
  ✅ Comparing tag entries > Tag comparison 3
  ✅ Comparing tag entries > Tag comparison 4
  ✅ Comparing tag entries > Tag comparison 5
  ✅ Comparing tag entries > Inputs with incorrect format are detected
  ✅ Building tag maps > New entries are added correctly
  ✅ Building tag maps > New entries are appended correctly - Object entries
  ✅ Building tag maps > New entries are appended correctly - Array entries
  ✅ Building tag maps > Duplicates are prevented - Object entries
  ✅ Building tag maps > Duplicates are prevented - Array entries
  ✅ Building tag maps > Badly constructed maps are detected
  ✅ Creating formatted tag lists > 0 Creating tag list for userLibrary
  ✅ Creating formatted tag lists > 1 Creating tag list for groupLibrary
  ✅ Merging data updates
  ✅ wrappedFetchItems > Fetching items when query cache is empty
  ✅ wrappedFetchItems > Fetching items when query cache has version data

✅ src/clients/zotero/hooks.test.ts

src/clients/zotero/hooks.test.ts
  ✅ useCollections > returns fetch results
  ✅ Hook for items queries > returns fetch results
  ✅ Hook for tags queries > returns fetch results
  ✅ useWriteableLibraries > Key with full access
  ✅ useWriteableLibraries > Key with no group access

✅ src/clients/zotero/mutations.test.tsx

src/clients/zotero/mutations.test.tsx
  ✅ Mutation hooks for the Zotero API > useDeleteTags > callback on success
  ✅ Mutation hooks for the Zotero API > useImportCitoids > callback on success
  ✅ Mutation hooks for the Zotero API > useModifyTags > callback on success

✅ src/components/Dashboard/Explorer/helpers.test.tsx

src/components/Dashboard/Explorer/helpers.test.tsx
  ✅ parseDateInThePast > 0 - 'bad input', expect null
  ✅ parseDateInThePast > 1 - '2019', expect null
  ✅ parseDateInThePast > 2 - 'Jan 2019', expect 2019-01-01T00:00:00.000Z
  ✅ parseDateInThePast > 3 - 'Jan 13-Jan 17', expect 2021-01-13T00:00:00.000Z
  ✅ parseDateInThePast > 4 - 'today', expect 2021-04-06T00:00:00.000Z
  ✅ parseDateInThePast > 5 - 'last 2 days', expect 2021-04-04T00:00:00.000Z
  ✅ parseDateInThePast > 6 - 'last 2 weeks', expect 2021-03-23T00:00:00.000Z
  ✅ parseDateInThePast > 7 - 'Monday', expect 2021-04-05T00:00:00.000Z
  ✅ parseDateInThePast > 8 - 'this week', expect 2021-04-04T00:00:00.000Z
  ✅ parseDateInThePast > 9 - 'this month', expect 2021-04-01T00:00:00.000Z
  ✅ parseDateInThePast > 10 - 'this year', expect 2021-01-01T00:00:00.000Z
  ✅ parseDateRangeInThePast > 0 - 'bad input', expect null
  ✅ parseDateRangeInThePast > 1 - 'Jan 2017 - Jan 2020', expect [ 2017-01-01T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 2 - 'Jan 3rd - Apr 5th', expect [ 2021-01-03T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 3 - 'Jan 2019', expect [ 2019-01-01T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 4 - 'last 2 days', expect [ 2021-04-04T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 5 - 'last 2 weeks', expect [ 2021-03-23T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 6 - 'Monday', expect [ 2021-04-05T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 7 - 'this week', expect [ 2021-04-04T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 8 - 'this month', expect [ 2021-04-01T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 9 - 'this year', expect [ 2021-01-01T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 10 - 'Feb 2nd - today', expect [ 2021-02-02T00:00:00.000Z, …(1) ]
  ✅ parseDateRangeInThePast > 11 - 'Feb 2nd - now', expect [ 2021-02-02T00:00:00.000Z, …(1) ]

✅ src/components/Dashboard/Explorer/QueryItems/filters.test.tsx

src/components/Dashboard/Explorer/QueryItems/filters.test.tsx
  ✅ useItemFilters > returns a list of filters
  ✅ useItemFilters > abstract > 0
  ✅ useItemFilters > abstract > 1
  ✅ useItemFilters > abstract > 2
  ✅ useItemFilters > abstract > 3
  ✅ useItemFilters > hasAbstract > 0
  ✅ useItemFilters > hasAbstract > 1
  ✅ useItemFilters > hasAbstract > 2
  ✅ useItemFilters > hasAbstract > 3
  ✅ useItemFilters > hasCitekey > 0
  ✅ useItemFilters > hasCitekey > 1
  ✅ useItemFilters > hasCitekey > 2
  ✅ useItemFilters > hasCitekey > 3
  ✅ useItemFilters > hasDOI > 0
  ✅ useItemFilters > hasDOI > 1
  ✅ useItemFilters > hasDOI > 2
  ✅ useItemFilters > hasDOI > 3
  ✅ useItemFilters > hasDOI > 4
  ✅ useItemFilters > hasDOI > 5
  ✅ useItemFilters > hasDOI > 6
  ✅ useItemFilters > hasDOI > 7
  ✅ useItemFilters > addedBefore > 0 - 'today', '2023-08-02T00:00'
  ✅ useItemFilters > addedBefore > 1 - 'today', '2023-08-01T00:00'
  ✅ useItemFilters > addedBefore > 2 - 'this week', '2023-07-30T00:00'
  ✅ useItemFilters > addedBefore > 3 - 'this week', '2023-07-29T00:00'
  ✅ useItemFilters > addedBefore > 4 - 'this year', '2023-01-02T00:00'
  ✅ useItemFilters > addedBefore > 5 - 'this year', '2023-01-01T00:00'
  ✅ useItemFilters > addedBefore > 6 - 'this year', '2022-12-31T00:00'
  ✅ useItemFilters > addedBefore > 7 - 'last 2 weeks', '2023-07-19T00:00'
  ✅ useItemFilters > addedBefore > 8 - 'last 2 weeks', '2023-07-18T00:00'
  ✅ useItemFilters > addedBefore > 9 - 'Monday', '2023-07-31T00:00'
  ✅ useItemFilters > addedBefore > 10 - 'Monday', '2023-07-30T00:00'
  ✅ useItemFilters > addedBefore > 11 - 'bad input', '2020-03-01T00:00'
  ✅ useItemFilters > type > 0
  ✅ useItemFilters > type > 1
  ✅ useItemFilters > hasNotes > 0
  ✅ useItemFilters > hasNotes > 1
  ✅ useItemFilters > hasNotes > 2
  ✅ useItemFilters > hasNotes > 3
  ✅ useItemFilters > hasPDFs > 0
  ✅ useItemFilters > hasPDFs > 1
  ✅ useItemFilters > hasPDFs > 2
  ✅ useItemFilters > hasPDFs > 3
  ✅ useItemFilters > inRoam > 0
  ✅ useItemFilters > inRoam > 1
  ✅ useItemFilters > inRoam > 2
  ✅ useItemFilters > inRoam > 3
  ✅ useItemFilters > tags > 0
  ✅ useItemFilters > tags > 1
  ✅ useItemFilters > tags > 2
  ✅ useItemFilters > tags > 3

✅ src/components/Dashboard/Explorer/QueryNotes/filters.test.ts

src/components/Dashboard/Explorer/QueryNotes/filters.test.ts
  ✅ tags > 0
  ✅ tags > 1
  ✅ tags > 2
  ✅ tags > 3

✅ src/components/Dashboard/Explorer/QueryPDFs/filters.test.ts

src/components/Dashboard/Explorer/QueryPDFs/filters.test.ts
  ✅ hasAnnotations > 0
  ✅ hasAnnotations > 1
  ✅ hasAnnotations > 2
  ✅ hasAnnotations > 3
  ✅ tags > 0
  ✅ tags > 1
  ✅ tags > 2
  ✅ tags > 3

✅ src/components/Dashboard/Explorer/QueryPDFs/helpers.test.ts

src/components/Dashboard/Explorer/QueryPDFs/helpers.test.ts
  ✅ Identifies the connections of a PDF item
  ✅ Formats PDF metadata

✅ src/components/Dashboard/TagManager/utils.test.ts

src/components/Dashboard/TagManager/utils.test.ts
  ✅ Collects tag stats
  ✅ Counts tag usage
  ✅ Identifies singleton tags > { roam: [], zotero: [ { tag: 'culture' } ] }
  ✅ Identifies singleton tags > { roam: [ { title: 'culture' } ], zotero: [ { tag: 'culture' } ] }
  ✅ Identifies singleton tags > { roam: [ { title: 'Culture' } ], zotero: [ { tag: 'culture' } ] }
  ✅ Identifies singleton tags > { roam: [], zotero: [ { tag: 'culture' }, { tag: 'Culture' } ] }
  ✅ Makes correct suggestions for tags > { roam: [], zotero: [ { tag: 'PKM' } ] }
  ✅ Makes correct suggestions for tags > { roam: [], zotero: [ { tag: 'PKM', meta: { type: +0 } }, { tag: 'PKM', meta: { type: 1 } } ] }
  ✅ Makes correct suggestions for tags > { roam: [ { title: 'housing' }, { title: 'Housing' } ], zotero: [ { tag: 'housing' } ] }
  ✅ Match Zotero tags with Roam pages
  ✅ Sorts tags list

✅ src/components/GraphWatcher/helpers.test.ts

src/components/GraphWatcher/helpers.test.ts
  ✅ hasNodeListChanged > Empty list doesn't get identified as a change
  ✅ hasNodeListChanged > Identical list doesn't get identified as a change
  ✅ hasNodeListChanged > Non-empty list becoming empty is a change
  ✅ hasNodeListChanged > Empty list becoming non-empty is a change
  ✅ hasNodeListChanged > Change in list contents is a change
  ✅ sortElems > sorts object arrays on a string key

✅ src/components/GraphWatcher/Menus/helpers.test.ts

src/components/GraphWatcher/Menus/helpers.test.ts
  ✅ cleanSemantic > simplifies SemanticScholar item metadata
  ✅ compareItemsByYear > sorts Zotero items by publication year & creators
  ✅ getAuthorLastName > extracts from single names
  ✅ getAuthorLastName > extracts from simple names
  ✅ getAuthorLastName > extracts from names with hyphen
  ✅ getAuthorLastName > extracts from names with particle
  ✅ getAuthorLastName > extracts from names with middle name
  ✅ makeAuthorsSummary > returns an empty string when given an empty input
  ✅ makeAuthorsSummary > formats correctly with 1 author
  ✅ makeAuthorsSummary > formats correctly with 2 authors
  ✅ makeAuthorsSummary > formats correctly with 3 authors
  ✅ makeAuthorsSummary > formats correctly with 4+ authors

✅ src/components/GraphWatcher/Menus/utils.test.tsx

src/components/GraphWatcher/Menus/utils.test.tsx
  ✅ Citekey menu containers are inserted > 0
  ✅ Citekey menu containers are inserted > 1
  ✅ DNP menu containers are inserted > 0
  ✅ DNP menu containers are inserted > 1
  ✅ DNP menu containers are inserted > 2
  ✅ DNP menu containers are inserted > 3
  ✅ DNP menu containers are inserted > 4
  ✅ Tag menu containers are inserted > 0
  ✅ Tag menu containers are inserted > 1

✅ src/components/GraphWatcher/WebImport/helpers.test.tsx

src/components/GraphWatcher/WebImport/helpers.test.tsx
  ✅ WebImport divs are inserted > 0
  ✅ WebImport divs are inserted > 1
  ✅ matchArrays > Finds if two string arrays have elements in common

✅ src/components/NotesDrawer/helpers.test.ts

src/components/NotesDrawer/helpers.test.ts
  ✅ simplifyZoteroNotes

✅ src/components/SearchPanel/helpers.test.ts

src/components/SearchPanel/helpers.test.ts
  ✅ cleanLibrary > Simplifies Zotero item metadata
  ✅ formatItemReferenceWithDefault > page-reference
  ✅ formatItemReferenceWithDefault > raw
  ✅ formatItemReferenceWithDefault > tag
  ✅ formatItemReferenceWithDefault > citation
  ✅ formatItemReferenceWithDefault > citekey
  ✅ Item reference formatting - with template > 0 - @{{key}}
  ✅ Item reference formatting - with template > 1 - [{{title}}]([[@{{key}}]])
  ✅ Item reference formatting - with template > 2 - [{{authors}} ({{year}})]([[@{{key}}]])

✅ src/components/UserSettings/common.test.ts

src/components/UserSettings/common.test.ts
  ✅ camelToTitleCase > 0 - someText
  ✅ camelToTitleCase > 1 - toggleDashboard
  ✅ camelToTitleCase > 2 - copyAsReference

✅ src/components/ZoteroImport/helpers.test.ts

src/components/ZoteroImport/helpers.test.ts
  ✅ Zotero collections sorting > returns an empty array when given an empty input
  ✅ Zotero collections sorting > correctly sorts an array of Zotero collections

✅ src/hooks/index.test.ts

src/hooks/index.test.ts
  ✅ Hook for array reducer > Add an element
  ✅ Hook for array reducer > Remove an element
  ✅ Hook for array reducer > Update an element
  ✅ Hook for boolean state > Toggle method
  ✅ Hook for boolean state > Set method
  ✅ Hook for boolean state > Switch on
  ✅ Hook for boolean state > Switch off
  ✅ Hook for filters list > Toggle filter on
  ✅ Hook for filters list > Toggle filter off
  ✅ Hook for multiple selection state > Behavior with base config
  ✅ Hook for multiple selection state > With custom match functions
  ✅ Hook for numeric state
  ✅ Hook for pagination
  ✅ Hook for single selection state > Behavior with base config
  ✅ Hook for single selection state > With custom transform function
  ✅ Hook for text state
  ✅ Hook for toggle state > Toggle method

✅ src/hooks/useSearchQuery/helpers.test.ts

src/hooks/useSearchQuery/helpers.test.ts
  ✅ computeCursorPosition > { terms: [ '' ], cursorPosition: +0, expectedResult: { position: +0, term: '', termIndex: +0 } }
  ✅ computeCursorPosition > { terms: [ 'text' ], cursorPosition: 4, expectedResult: { position: 4, term: 'text', termIndex: +0 } }
  ✅ computeCursorPosition > { terms: [ 'text ', '' ], cursorPosition: 5, expectedResult: { position: +0, term: '', termIndex: 1 } }
  ✅ computeCursorPosition > { terms: [ 'inRoam:' ], cursorPosition: 7, expectedResult: { position: 7, term: 'inRoam:', termIndex: +0 } }
  ✅ computeCursorPosition > { terms: [ 'inRoam: ', '' ], cursorPosition: 8, expectedResult: { position: +0, term: '', termIndex: 1 } }
  ✅ computeCursorPosition > { terms: [ 'inRoam:true' ], cursorPosition: 11, expectedResult: { position: 11, term: 'inRoam:true', termIndex: +0 } }
  ✅ computeCursorPosition > { terms: [ 'inRoam:true ', '' ], cursorPosition: 12, expectedResult: { position: +0, term: '', termIndex: 1 } }
  ✅ computeCursorPosition > { terms: [ 'inRoam:true ', 'text' ], cursorPosition: 12, expectedResult: { position: +0, term: 'text', termIndex: 1 } }
  ✅ computeSuggestions > '', cursor at +0
  ✅ computeSuggestions > '#', cursor at +0
  ✅ computeSuggestions > '#', cursor at 1
  ✅ computeSuggestions > 'roa', cursor at +0
  ✅ computeSuggestions > 'roa', cursor at 1
  ✅ computeSuggestions > 'exists', cursor at 6
  ✅ computeSuggestions > 'roam:', cursor at 5
  ✅ computeSuggestions > 'roam:t', cursor at 6
  ✅ computeSuggestions > 'something:', cursor at 10
  ✅ computeSuggestions > 'roam:"true', cursor at 10
  ✅ computeSuggestions > 'roam:"true"', cursor at 11
  ✅ computeSuggestions > '"text string', cursor at 12
  ✅ computeSuggestions > 'roam exists', cursor at 11
  ✅ computeSuggestions > '"roam exists', cursor at 12
  ✅ isIncompleteFilter > '' should return false
  ✅ isIncompleteFilter > 'operator' should return false
  ✅ isIncompleteFilter > 'operator ' should return false
  ✅ isIncompleteFilter > 'operator:' should return true
  ✅ isIncompleteFilter > 'operator: ' should return false
  ✅ isIncompleteFilter > 'operator:text' should return false
  ✅ isIncompleteFilter > 'operator:text ' should return false
  ✅ isIncompleteFilter > 'operator:"' should return true
  ✅ isIncompleteFilter > 'operator:" ' should return true
  ✅ isIncompleteFilter > 'operator:"text' should return true
  ✅ isIncompleteFilter > 'operator:"text ' should return true
  ✅ isIncompleteFilter > 'operator:"text"' should return false
  ✅ isIncompleteFilter > 'operator:"text" ' should return false
  ✅ isIncompleteFreeText > '' should return false
  ✅ isIncompleteFreeText > ' ' should return false
  ✅ isIncompleteFreeText > 'text' should return false
  ✅ isIncompleteFreeText > 'text ' should return false
  ✅ isIncompleteFreeText > 'text string' should return false
  ✅ isIncompleteFreeText > 'text string ' should return false
  ✅ isIncompleteFreeText > '"' should return true
  ✅ isIncompleteFreeText > '"text' should return true
  ✅ isIncompleteFreeText > '"text ' should return true
  ✅ isIncompleteFreeText > '"text"' should return false
  ✅ isIncompleteFreeText > '"text" ' should return false
  ✅ parseQueryTerms > ''
  ✅ parseQueryTerms > 'i'
  ✅ parseQueryTerms > 'i '
  ✅ parseQueryTerms > 'inRoam'
  ✅ parseQueryTerms > 'inRoam:'
  ✅ parseQueryTerms > 'inRoam:true'
  ✅ parseQueryTerms > 'inRoam:true '
  ✅ parseQueryTerms > 'abstract:"'
  ✅ parseQueryTerms > 'abstract:"text string'
  ✅ parseQueryTerms > 'abstract:"text string"'
  ✅ parseQueryTerms > 'text abstract:string'
  ✅ parseQueryTerms > 'abstract:string text'
  ✅ parseQueryTerms > 'inRoam:true abstract:string'
  ✅ parseSearchTerms > 0 - [] (expect: [])
  ✅ parseSearchTerms > 1 - [ '' ] (expect: [])
  ✅ parseSearchTerms > 2 - [ 'text' ] (expect: [ 'text' ])
  ✅ parseSearchTerms > 3 - [ '"text search"' ] (expect: [ 'text search' ])
  ✅ parseSearchTerms > 4 - [ 'someFilter:query' ] (expect: [])
  ✅ parseSearchTerms > 5 - [ 'roam:true' ] (expect: [ { filter: { …(4) }, query: 'true' } ])
  ✅ parseSearchTerms > 6 - [ 'roam:"true"' ] (expect: [ { filter: { …(4) }, query: 'true' } ])
  ✅ parseSearchTerms > 7 - [ 'roam:true ', 'text string' ] (expect: [ { filter: { …(4) }, …(1) }, …(1) ])
  ✅ parseSearchTerms > 8 - [ 'roam:true ', '"text string"' ] (expect: [ { filter: { …(4) }, …(1) }, …(1) ])
  ✅ parseSearchTerms > 9 - [ '"text string"', 'roam:true' ] (expect: [ { filter: { …(4) }, …(1) }, …(1) ])
  ✅ parseSearchTerms > 10 - [ 'text ', 'roam:true ', 'string' ] (expect: [ { filter: { …(4) }, …(1) }, …(1) ])
  ✅ runSearch > returns all items when the query is empty
  ✅ runSearch > free-text search > returns all items when no searchable field is provided
  ✅ runSearch > free-text search > returns filtered items when a searchable field is provided
  ✅ runSearch > filter-based search > 0
  ✅ runSearch > filter-based search > 1

✅ src/hooks/useSearchQuery/index.test.ts

src/hooks/useSearchQuery/index.test.ts
  ✅ useSearchQuery > returns all filters when the query is empty
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 0
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 2
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 5
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 7
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 9
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 10
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 12
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 14
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 16
  ✅ useSearchQuery > with fully qualified query > returns no suggestions - cursor at 18
  ✅ useSearchQuery > with fully qualified query and a trailing space > returns all filters
  ✅ useSearchQuery > with partially typed operator > returns filters with matching name - 0 - +0 results
  ✅ useSearchQuery > with partially typed operator > returns filters with matching name - 1 - 1 results
  ✅ useSearchQuery > with partially typed operator > returns filters with matching name - 2 - 1 results
  ✅ useSearchQuery > returns presets when the user has selected an operator
  ✅ useSearchQuery > applySuggestion > it auto-completes filter operators > 0 - '', cursor at +0 -> 'created'
  ✅ useSearchQuery > applySuggestion > it auto-completes filter operators > 1 - 'ro', cursor at +0 -> 'created'
  ✅ useSearchQuery > applySuggestion > it auto-completes filter operators > 2 - 'ro', cursor at 1 -> 'created'
  ✅ useSearchQuery > applySuggestion > it auto-completes filter operators > 3 - 'ro', cursor at 2 -> 'created'
  ✅ useSearchQuery > applySuggestion > it auto-completes filter operators > 4 - '', cursor at +0 -> 'roam'
  ✅ useSearchQuery > applySuggestion > it auto-completes filter operators > 5 - 'ro', cursor at +0 -> 'roam'
  ✅ useSearchQuery > applySuggestion > it auto-completes filter operators > 6 - 'ro', cursor at 1 -> 'roam'
  ✅ useSearchQuery > applySuggestion > it auto-completes filter operators > 7 - 'ro', cursor at 2 -> 'roam'
  ✅ useSearchQuery > applySuggestion > it inserts filter presets > 0 - 'created:' 'today'
  ✅ useSearchQuery > applySuggestion > it inserts filter presets > 1 - 'created:' '-1d'
  ✅ useSearchQuery > applySuggestion > it inserts filter presets > 2 - 'created:' '-7d'
  ✅ useSearchQuery > applySuggestion > it inserts filter presets > 3 - 'roam:' 'true'
  ✅ useSearchQuery > applySuggestion > it inserts filter presets > 4 - 'roam:' 'false'
  ✅ useSearchQuery > search > matches items with filters
  ✅ useSearchQuery > search > matches items with free-text search when enabled
  ✅ useSearchQuery > search > ignores free-text search when disabled

✅ src/services/events/index.test.ts

src/services/events/index.test.ts
  ✅ metadataAdded > hook behavior on error
  ✅ metadataAdded > hook behavior on success
  ✅ metadataAdded > hook fallback
  ✅ notesAdded > hook behavior on error
  ✅ notesAdded > hook behavior on success
  ✅ notesAdded > hook fallback
  ✅ tagsDeleted > hook behavior on error
  ✅ tagsDeleted > hook behavior on success
  ✅ tagsModified > hook behavior on error
  ✅ tagsModified > hook behavior on partial success
  ✅ tagsModified > hook behavior on full success
  ✅ writeFinished > hook behavior on error
  ✅ writeFinished > hook behavior on partial success
  ✅ writeFinished > hook behavior on full success

✅ src/services/idb/index.test.ts

src/services/idb/index.test.ts
  ✅ Store handling
  ✅ DB creation
  ✅ DB deletion
  ✅ DB conflict

✅ src/services/react-query/index.test.ts

src/services/react-query/index.test.ts
  ✅ selectItemChildren
  ✅ selectItemCollections
  ✅ selectItemRelated
  ✅ selectItems
  ✅ selectTags > 0 Retrieving tags data for 0
  ✅ selectTags > 1 Retrieving tags data for 1

✅ src/services/search/index.test.ts

src/services/search/index.test.ts
  ✅ Query > _parse() > handles single-term queries
  ✅ Query > _parse() > handles operator queries > 'history|sociology'
  ✅ Query > _parse() > handles operator queries > '-history|sociology'
  ✅ Query > _parse() > handles operator queries > 'history&sociology'
  ✅ Query > _parse() > handles operator queries > '-history&sociology'
  ✅ Query > _parse() > handles operator queries > '(history|sociology)'
  ✅ Query > _parse() > handles operator queries > '(history&sociology)'
  ✅ Query > _parse() > handles operator queries > '-(history|sociology)'
  ✅ Query > _parse() > handles operator queries > '-(history&sociology)'
  ✅ Query > _parse() > handles multi-level queries > '(history|sociology)&TODO'
  ✅ Query > _parse() > handles multi-level queries > 'history|(sociology&TODO)'
  ✅ Query > _parse() > handles multi-level queries > '(-history)|(sociology&TODO)'
  ✅ Query > _parse() > handles multi-level queries > '-history|(sociology&TODO)'
  ✅ Query > _parse() > handles multi-level queries > '-(history|(sociology&TODO))'
  ✅ Query > _parse() > handles multi-level queries > '-((sociology&TODO)|history)'
  ✅ Query > _parse() > handles multi-level queries > '(-DONE)&(history|sociology)'
  ✅ Query > match() > query: 'systems' | expect: true
  ✅ Query > match() > query: 'software' | expect: false
  ✅ Query > match() > query: '-TODO' | expect: true
  ✅ Query > match() > query: 'systems&software' | expect: false
  ✅ Query > match() > query: '(systems&software)' | expect: false
  ✅ Query > match() > query: 'software|TODO' | expect: false
  ✅ Query > match() > query: '(software|TODO)' | expect: false
  ✅ Query > match() > query: 'PKM&culture' | expect: true
  ✅ Query > match() > query: '(PKM&culture)' | expect: true
  ✅ Query > match() > query: 'TODO&(systems|culture)' | expect: false
  ✅ Query > match() > query: 'history|(systems&culture)' | expect: true
  ✅ Query > match() > query: '-systems&TODO' | expect: true
  ✅ Query > match() > query: '-(systems&TODO)' | expect: true
  ✅ Query > match() > query: '(-systems)&TODO' | expect: false

✅ src/services/smartblocks/helpers.test.ts

src/services/smartblocks/helpers.test.ts
  ✅ reformatImportableBlocks > 0 - []
  ✅ reformatImportableBlocks > 1 - [ 'some', 'block' ]
  ✅ reformatImportableBlocks > 2 - [ 'some', { string: 'object', text: 'object', children: [] } ]
  ✅ reformatImportableBlocks > 3 - [ 'some', { string: 'object', text: 'object', children: [ 'child', 'string' ] } ]
  ✅ reformatImportableBlocks > throws when passed an invalid element

✅ src/services/smartblocks/index.test.ts

src/services/smartblocks/index.test.ts
  ✅ All commands return correct output > ZOTERORANDOMCITEKEY
  ✅ All commands return correct output > ZOTEROITEMABSTRACT
  ✅ All commands return correct output > ZOTEROITEMCITATION > It returns the correct output
  ✅ All commands return correct output > ZOTEROITEMCITEKEY
  ✅ All commands return correct output > ZOTEROITEMCOLLECTIONS
  ✅ All commands return correct output > ZOTEROITEMCREATORS
  ✅ All commands return correct output > ZOTEROITEMDATEADDED
  ✅ All commands return correct output > ZOTEROITEMKEY
  ✅ All commands return correct output > ZOTEROITEMLINK
  ✅ All commands return correct output > ZOTEROITEMMETADATA
  ✅ All commands return correct output > ZOTEROITEMPUBLICATION
  ✅ All commands return correct output > ZOTEROITEMRELATED
  ✅ All commands return correct output > ZOTEROITEMTAGS
  ✅ All commands return correct output > ZOTEROITEMTITLE
  ✅ All commands return correct output > ZOTEROITEMTYPE
  ✅ All commands return correct output > ZOTEROITEMURL
  ✅ All commands return correct output > ZOTEROITEMYEAR
  ✅ All commands return correct output > ZOTERONOTES
  ✅ All commands return correct output > ZOTEROPDFS

✅ tests/utils/annotations.test.ts

tests/utils/annotations.test.ts
  ✅ Extracts annotation indices from string > 0 - 00001|00002|00003
  ✅ Extracts annotation indices from string > 1 - 00045|00056|00067
  ✅ Sorts annotation indices
  ✅ Simplifies annotations

✅ tests/utils/formatters.test.ts

tests/utils/formatters.test.ts
  ✅ Creating timestamps > formats with 24-hour clock
  ✅ Creating timestamps > formats correctly with single digits for minutes
  ✅ Creating from-ago dates > identifies dates from today
  ✅ Creating from-ago dates > identifies dates from yesterday
  ✅ Creating from-ago dates > identifies dates from earlier in the year
  ✅ Creating from-ago dates > identifies dates from previous years
  ✅ Parsing DOIs > converts DOI to lowercase
  ✅ Parsing DOIs > parses DOI from full URL
  ✅ Parsing DOIs > rejects DOI with incorrect format
  ✅ Parsing DOIs > rejects empty string
  ✅ Transforming DOIs
  ✅ Making Zotero local link > creates Markdown link by default
  ✅ Making Zotero local link > correctly generates the target URL
  ✅ Making Zotero local link > correctly generates the target URL for an item in a group library
  ✅ Making Zotero web link > creates Markdown link by default
  ✅ Making Zotero web link > correctly generates the target URL for user libraries
  ✅ Making Zotero web link > correctly generates the target URL for group libraries
  ✅ Making PDF links > creates target link by default
  ✅ Making PDF links > correctly generates Markdown link
  ✅ Making PDF links > has fallback defaults
  ✅ Formatting Zotero item references > formats as inline reference
  ✅ Formatting Zotero item references > formats as citation
  ✅ Formatting Zotero item references > formats as citekey
  ✅ Formatting Zotero item references > formats as key
  ✅ Formatting Zotero item references > formats as page reference
  ✅ Formatting Zotero item references > formats as popover
  ✅ Formatting Zotero item references > formats as tag
  ✅ Formatting Zotero item references > formats as Zettlr-like reference
  ✅ Formatting Zotero item references > formats with a custom template
  ✅ Formatting Zotero item references > uses the citekey format as fallback
  ✅ Pluralizes tokens
  ✅ Creating a dictionary > Creates dictionary from string Array
  ✅ Creating a dictionary > Bad inputs are detected

✅ tests/utils/items.test.ts

tests/utils/items.test.ts
  ✅ Categorizes Zotero items
  ✅ Identifies the children of a Zotero item

✅ tests/utils/misc.test.ts

tests/utils/misc.test.ts
  ✅ Appends element in array
  ✅ Removes array element at index
  ✅ Updates value of array element
  ✅ Executing a function by name > executes a function attached to the window
  ✅ Executing a function by name > executes the function with args
  ✅ Executing a function by name > throws a custom error if the function doesn't exist

✅ tests/utils/notes.test.ts

tests/utils/notes.test.ts
  ✅ Splitting HTML notes > No separator provided - function throws
  ✅ Splitting HTML notes > Incorrect type of separator provided - function throws
  ✅ Splitting HTML notes > Simple separator
  ✅ Splitting HTML notes > HTML tag separator
  ✅ Parsing HTML notes > cleans markup from rich tags
  ✅ Parsing HTML notes > formats links into Markdown
  ✅ Parsing HTML notes > removes newlines
  ✅ Parsing HTML notes > cleans list markup

✅ tests/utils/search.test.ts

tests/utils/search.test.ts
  ✅ Search engine inputs > rejects invalid search inputs
  ✅ Search engine inputs > applies search to an array
  ✅ Search engine inputs > escapes strings with special characters > 0 - In-text *asterisks*
  ✅ Search engine inputs > escapes strings with special characters > 1 - *Self-Management
  ✅ Case-sensitive search
  ✅ Search - matching modes > matches on partial words
  ✅ Search - matching modes > matches on word boundaries only
  ✅ Search - matching modes > finds exact matches - single-word query
  ✅ Search - matching modes > finds exact matches - multi-word query
  ✅ Search - compounds > matches compounds - single-word query
  ✅ Search - compounds > matches compounds - multi-word query
  ✅ Search - word order > matches words in the order provided
  ✅ Search - word order > matches words in any order
  ✅ Search - word order > matches in the order provided, on word boundaries
  ✅ Search - word order > matches words in any order, on word boundaries

✅ tests/utils/setup.test.tsx

tests/utils/setup.test.tsx
  ✅ Parsing user data requests > passes if an empty array of requests is provided
  ✅ Parsing user data requests > throws if none of the requests has an API key
  ✅ Parsing user data requests > throws if any of the requests is missing a data URI
  ✅ Parsing user data requests > throws if any of the requests has an incorrect data URI
  ✅ Parsing user data requests > throws if any of the requests has an incorrect library ID
  ✅ Parsing user data requests > throws if any of the requests has an incorrect library type
  ✅ Parsing user data requests > throws if the same library is provided twice
  ✅ Parsing user data requests > accepts an Object as input
  ✅ Parsing user data requests > returns proper configuration when given correct input
  ✅ Parsing user data requests > returns proper configuration when given correct input (from library)
  ✅ Parsing mock data requests > should be a valid configuration
  ✅ Parsing initial user settings > should return defaults if given no settings
  ✅ Parsing user shortcuts > 0 - {}
  ✅ Parsing user shortcuts > 1 - { copyDefault: 'alt+E' }
  ✅ Parsing user shortcuts > 2 - { toggleDashboard: 'alt+ +' }
  ✅ Parsing user shortcuts > 3 - { goToItemPage: '' }
  ✅ Creating IndexedDB persister > persist, restore, delete client
  ✅ Creating IndexedDB persister > persist errors are raised
  ✅ Filtering queries for persistence > 0
  ✅ Filtering queries for persistence > 1
  ✅ Filtering queries for persistence > 2
  ✅ Filtering queries for persistence > 3
  ✅ Filtering queries for persistence > 4
  ✅ Filtering queries for persistence > 5
  ✅ Initial configuration > Roam Depot - no requests set
  ✅ Initial configuration > Roam Depot - requests are provided
  ✅ Initial configuration > RoamJS
  ✅ Theme setter > use_dark_theme = true
  ✅ Theme setter > use_dark_theme = false
  ✅ Portals setup > Extension slot > Topbar exists: true
  ✅ Portals setup > Extension slot > Topbar exists: false
  ✅ Portals setup > Portals container > App exists: true
  ✅ Portals setup > Portals container > App exists: false
  ✅ Teardown > Extension slot
  ✅ Teardown > Portals container