aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/test/utils/diagnotics/SuggestedFixCollection.test.ts
blob: 4c1467b5760279e74917f8c9af169c2a88f1b33c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import * as assert from 'assert';
import * as vscode from 'vscode';

import SuggestedFix from '../../../utils/diagnostics/SuggestedFix';
import SuggestedFixCollection from '../../../utils/diagnostics/SuggestedFixCollection';

const uri1 = vscode.Uri.file('/file/1');
const uri2 = vscode.Uri.file('/file/2');

const mockDocument1 = ({
    uri: uri1,
} as unknown) as vscode.TextDocument;

const mockDocument2 = ({
    uri: uri2,
} as unknown) as vscode.TextDocument;

const range1 = new vscode.Range(
    new vscode.Position(1, 2),
    new vscode.Position(3, 4),
);
const range2 = new vscode.Range(
    new vscode.Position(5, 6),
    new vscode.Position(7, 8),
);

const diagnostic1 = new vscode.Diagnostic(range1, 'First diagnostic');
const diagnostic2 = new vscode.Diagnostic(range2, 'Second diagnostic');

// This is a mutable object so return a fresh instance every time
function suggestion1(): SuggestedFix {
    return new SuggestedFix(
        'Replace me!',
        new vscode.Location(uri1, range1),
        'With this!',
    );
}

describe('SuggestedFixCollection', () => {
    it('should add a suggestion then return it as a code action', () => {
        const suggestedFixes = new SuggestedFixCollection();
        suggestedFixes.addSuggestedFixForDiagnostic(suggestion1(), diagnostic1);

        // Specify the document and range that exactly matches
        const codeActions = suggestedFixes.provideCodeActions(
            mockDocument1,
            range1,
        );

        assert.strictEqual(codeActions.length, 1);
        const [codeAction] = codeActions;
        assert.strictEqual(codeAction.title, suggestion1().title);

        const { diagnostics } = codeAction;
        if (!diagnostics) {
            return assert.fail('Diagnostics unexpectedly missing');
        }

        assert.strictEqual(diagnostics.length, 1);
        assert.strictEqual(diagnostics[0], diagnostic1);
    });

    it('should not return code actions for different ranges', () => {
        const suggestedFixes = new SuggestedFixCollection();
        suggestedFixes.addSuggestedFixForDiagnostic(suggestion1(), diagnostic1);

        const codeActions = suggestedFixes.provideCodeActions(
            mockDocument1,
            range2,
        );

        assert(!codeActions || codeActions.length === 0);
    });

    it('should not return code actions for different documents', () => {
        const suggestedFixes = new SuggestedFixCollection();
        suggestedFixes.addSuggestedFixForDiagnostic(suggestion1(), diagnostic1);

        const codeActions = suggestedFixes.provideCodeActions(
            mockDocument2,
            range1,
        );

        assert(!codeActions || codeActions.length === 0);
    });

    it('should not return code actions that have been cleared', () => {
        const suggestedFixes = new SuggestedFixCollection();
        suggestedFixes.addSuggestedFixForDiagnostic(suggestion1(), diagnostic1);
        suggestedFixes.clear();

        const codeActions = suggestedFixes.provideCodeActions(
            mockDocument1,
            range1,
        );

        assert(!codeActions || codeActions.length === 0);
    });

    it('should merge identical suggestions together', () => {
        const suggestedFixes = new SuggestedFixCollection();

        // Add the same suggestion for two diagnostics
        suggestedFixes.addSuggestedFixForDiagnostic(suggestion1(), diagnostic1);
        suggestedFixes.addSuggestedFixForDiagnostic(suggestion1(), diagnostic2);

        const codeActions = suggestedFixes.provideCodeActions(
            mockDocument1,
            range1,
        );

        assert.strictEqual(codeActions.length, 1);
        const [codeAction] = codeActions;
        const { diagnostics } = codeAction;

        if (!diagnostics) {
            return assert.fail('Diagnostics unexpectedly missing');
        }

        // We should be associated with both diagnostics
        assert.strictEqual(diagnostics.length, 2);
        assert.strictEqual(diagnostics[0], diagnostic1);
        assert.strictEqual(diagnostics[1], diagnostic2);
    });
});