|
2 | 2 | * @jest-environment jsdom |
3 | 3 | */ |
4 | 4 | import moment from 'moment/moment'; |
| 5 | +import type { CachedMetadata } from 'obsidian'; |
5 | 6 | import type { ListItem } from '../../src/Task/ListItem'; |
6 | 7 | import { getTasksFileFromMockData, listPathAndData } from '../TestingTools/MockDataHelpers'; |
7 | 8 | import inheritance_1parent1child from './__test_data__/inheritance_1parent1child.json'; |
@@ -29,8 +30,9 @@ import callout from './__test_data__/callout.json'; |
29 | 30 | import callout_labelled from './__test_data__/callout_labelled.json'; |
30 | 31 | import callout_custom from './__test_data__/callout_custom.json'; |
31 | 32 | import callouts_nested_issue_2890_unlabelled from './__test_data__/callouts_nested_issue_2890_unlabelled.json'; |
| 33 | +import links_everywhere from './__test_data__/links_everywhere.json'; |
32 | 34 | import { allCacheSampleData } from './AllCacheSampleData'; |
33 | | -import { readTasksFromSimulatedFile } from './SimulatedFile'; |
| 35 | +import { type SimulatedFile, readTasksFromSimulatedFile } from './SimulatedFile'; |
34 | 36 |
|
35 | 37 | window.moment = moment; |
36 | 38 |
|
@@ -604,6 +606,130 @@ describe('cache', () => { |
604 | 606 | }); |
605 | 607 | }); |
606 | 608 |
|
| 609 | +describe('accessing links in file', function () { |
| 610 | + describe('explore accessing links in file "links_everywhere.md"', () => { |
| 611 | + const data = links_everywhere as unknown as SimulatedFile; |
| 612 | + |
| 613 | + const tasks = readTasksFromSimulatedFile(data); |
| 614 | + expect(tasks.length).toEqual(1); |
| 615 | + const task = tasks[0]; |
| 616 | + |
| 617 | + const cachedMetadata: CachedMetadata = task.file.cachedMetadata; |
| 618 | + |
| 619 | + /** |
| 620 | + * I am thinking of the following, to evantually make links accessible to users. |
| 621 | + * 1. Provide a class or interface called Link, with fields: |
| 622 | + * - displayText, e.g. "link_in_yaml" |
| 623 | + * - link, e.g. "link_in_yaml" |
| 624 | + * - original, e.g. "[[link_in_yaml]]" |
| 625 | + * 2. Add some getters that construct the relevant Link objects from cached metadata on demand, such as: |
| 626 | + * - task.file.linksInBody |
| 627 | + * - task.file.linksInFrontMatter |
| 628 | + * - task.file.allLinks |
| 629 | + * - task.links |
| 630 | + * 3. Consider the vocabulary - some dataview users talk about inlines and outlinks. |
| 631 | + * The above are all outlinks - but do we want to name them as such, to prepare |
| 632 | + * for if or when inlinks are also supported? |
| 633 | + */ |
| 634 | + |
| 635 | + it('see source', () => { |
| 636 | + expect(data.fileContents).toMatchInlineSnapshot(` |
| 637 | + "--- |
| 638 | + link-in-frontmatter: "[[link_in_yaml]]" |
| 639 | + --- |
| 640 | + # links_everywhere |
| 641 | +
|
| 642 | + A link in the file body: [[link_in_file_body]] |
| 643 | +
|
| 644 | + ## A link in a [[link_in_heading]] |
| 645 | +
|
| 646 | + - [ ] #task Task in 'links_everywhere' - a link on the task: [[link_in_task_wikilink]] |
| 647 | + " |
| 648 | + `); |
| 649 | + }); |
| 650 | + |
| 651 | + it('should access links in frontmatter', () => { |
| 652 | + // Update to Obsidian API 1.4.0 to access cachedMetadata.frontmatterLinks |
| 653 | + // @ts-expect-error TS2551: Property frontmatterLinks does not exist on type CachedMetadata |
| 654 | + const frontMatterLinks = cachedMetadata['frontmatterLinks']; |
| 655 | + expect(frontMatterLinks).toBeDefined(); |
| 656 | + |
| 657 | + const firstFrontMatterLink = frontMatterLinks![0]; |
| 658 | + expect(firstFrontMatterLink.original).toEqual('[[link_in_yaml]]'); |
| 659 | + expect(firstFrontMatterLink).toMatchInlineSnapshot(` |
| 660 | + { |
| 661 | + "displayText": "link_in_yaml", |
| 662 | + "key": "link-in-frontmatter", |
| 663 | + "link": "link_in_yaml", |
| 664 | + "original": "[[link_in_yaml]]", |
| 665 | + } |
| 666 | + `); |
| 667 | + }); |
| 668 | + |
| 669 | + it('should access links in file body', () => { |
| 670 | + const fileBodyLinks = cachedMetadata.links; |
| 671 | + |
| 672 | + const originalLinkText = fileBodyLinks?.map((link) => link.original).join('\n'); |
| 673 | + expect(originalLinkText).toMatchInlineSnapshot(` |
| 674 | + "[[link_in_file_body]] |
| 675 | + [[link_in_heading]] |
| 676 | + [[link_in_task_wikilink]]" |
| 677 | + `); |
| 678 | + |
| 679 | + const firstFileBodyLink = fileBodyLinks![0]; |
| 680 | + expect(firstFileBodyLink).toMatchInlineSnapshot(` |
| 681 | + { |
| 682 | + "displayText": "link_in_file_body", |
| 683 | + "link": "link_in_file_body", |
| 684 | + "original": "[[link_in_file_body]]", |
| 685 | + "position": { |
| 686 | + "end": { |
| 687 | + "col": 46, |
| 688 | + "line": 5, |
| 689 | + "offset": 114, |
| 690 | + }, |
| 691 | + "start": { |
| 692 | + "col": 25, |
| 693 | + "line": 5, |
| 694 | + "offset": 93, |
| 695 | + }, |
| 696 | + }, |
| 697 | + } |
| 698 | + `); |
| 699 | + }); |
| 700 | + |
| 701 | + it('should access links in task line', () => { |
| 702 | + const fileBodyLinks = cachedMetadata.links; |
| 703 | + const linksOnTask = fileBodyLinks?.filter((link) => link.position.start.line === task.lineNumber); |
| 704 | + |
| 705 | + expect(linksOnTask).toBeDefined(); |
| 706 | + expect(linksOnTask?.length).toEqual(1); |
| 707 | + |
| 708 | + const firstLinkOnTask = linksOnTask![0]; |
| 709 | + expect(firstLinkOnTask.original).toEqual('[[link_in_task_wikilink]]'); |
| 710 | + expect(firstLinkOnTask).toMatchInlineSnapshot(` |
| 711 | + { |
| 712 | + "displayText": "link_in_task_wikilink", |
| 713 | + "link": "link_in_task_wikilink", |
| 714 | + "original": "[[link_in_task_wikilink]]", |
| 715 | + "position": { |
| 716 | + "end": { |
| 717 | + "col": 86, |
| 718 | + "line": 9, |
| 719 | + "offset": 238, |
| 720 | + }, |
| 721 | + "start": { |
| 722 | + "col": 61, |
| 723 | + "line": 9, |
| 724 | + "offset": 213, |
| 725 | + }, |
| 726 | + }, |
| 727 | + } |
| 728 | + `); |
| 729 | + }); |
| 730 | + }); |
| 731 | +}); |
| 732 | + |
607 | 733 | describe('all mock files', () => { |
608 | 734 | const files: any = allCacheSampleData(); |
609 | 735 |
|
|
0 commit comments