]> git.lizzy.rs Git - rust.git/blob - editors/code/src/test/utils/diagnotics/rust.test.ts
cee59061f3b529f1091edf5662401c49ead47c14
[rust.git] / editors / code / src / test / utils / diagnotics / rust.test.ts
1 import * as assert from 'assert';
2 import * as fs from 'fs';
3 import * as vscode from 'vscode';
4
5 import {
6     MappedRustDiagnostic,
7     mapRustDiagnosticToVsCode,
8     RustDiagnostic,
9     SuggestionApplicability,
10 } from '../../../utils/diagnostics/rust';
11
12 function loadDiagnosticFixture(name: string): RustDiagnostic {
13     const jsonText = fs
14         .readFileSync(
15             // We're actually in our JavaScript output directory, climb out
16             `${__dirname}/../../../../src/test/fixtures/rust-diagnostics/${name}.json`,
17         )
18         .toString();
19
20     return JSON.parse(jsonText);
21 }
22
23 function mapFixtureToVsCode(name: string): MappedRustDiagnostic {
24     const rd = loadDiagnosticFixture(name);
25     const mapResult = mapRustDiagnosticToVsCode(rd);
26
27     if (!mapResult) {
28         return assert.fail('Mapping unexpectedly failed');
29     }
30     return mapResult;
31 }
32
33 describe('mapRustDiagnosticToVsCode', () => {
34     it('should map an incompatible type for trait error', () => {
35         const { diagnostic, suggestedFixes } = mapFixtureToVsCode(
36             'error/E0053',
37         );
38
39         assert.strictEqual(
40             diagnostic.severity,
41             vscode.DiagnosticSeverity.Error,
42         );
43         assert.strictEqual(diagnostic.source, 'rustc');
44         assert.strictEqual(
45             diagnostic.message,
46             [
47                 `method \`next\` has an incompatible type for trait`,
48                 `expected type \`fn(&mut ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&ty::Ref<M>>\``,
49                 `   found type \`fn(&ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&'list ty::Ref<M>>\``,
50             ].join('\n'),
51         );
52         assert.strictEqual(diagnostic.code, 'E0053');
53         assert.deepStrictEqual(diagnostic.tags, []);
54
55         // No related information
56         assert.deepStrictEqual(diagnostic.relatedInformation, []);
57
58         // There are no suggested fixes
59         assert.strictEqual(suggestedFixes.length, 0);
60     });
61
62     it('should map an unused variable warning', () => {
63         const { diagnostic, suggestedFixes } = mapFixtureToVsCode(
64             'warning/unused_variables',
65         );
66
67         assert.strictEqual(
68             diagnostic.severity,
69             vscode.DiagnosticSeverity.Warning,
70         );
71         assert.strictEqual(
72             diagnostic.message,
73             [
74                 'unused variable: `foo`',
75                 '#[warn(unused_variables)] on by default',
76             ].join('\n'),
77         );
78         assert.strictEqual(diagnostic.code, 'unused_variables');
79         assert.strictEqual(diagnostic.source, 'rustc');
80         assert.deepStrictEqual(diagnostic.tags, [
81             vscode.DiagnosticTag.Unnecessary,
82         ]);
83
84         // No related information
85         assert.deepStrictEqual(diagnostic.relatedInformation, []);
86
87         // One suggested fix available to prefix the variable
88         assert.strictEqual(suggestedFixes.length, 1);
89         const [suggestedFix] = suggestedFixes;
90         assert.strictEqual(
91             suggestedFix.title,
92             'consider prefixing with an underscore: `_foo`',
93         );
94         assert.strictEqual(
95             suggestedFix.applicability,
96             SuggestionApplicability.MachineApplicable,
97         );
98     });
99
100     it('should map a wrong number of parameters error', () => {
101         const { diagnostic, suggestedFixes } = mapFixtureToVsCode(
102             'error/E0061',
103         );
104
105         assert.strictEqual(
106             diagnostic.severity,
107             vscode.DiagnosticSeverity.Error,
108         );
109         assert.strictEqual(
110             diagnostic.message,
111             [
112                 'this function takes 2 parameters but 3 parameters were supplied',
113                 'expected 2 parameters',
114             ].join('\n'),
115         );
116         assert.strictEqual(diagnostic.code, 'E0061');
117         assert.strictEqual(diagnostic.source, 'rustc');
118         assert.deepStrictEqual(diagnostic.tags, []);
119
120         // One related information for the original definition
121         const relatedInformation = diagnostic.relatedInformation;
122         if (!relatedInformation) {
123             return assert.fail('Related information unexpectedly undefined');
124         }
125         assert.strictEqual(relatedInformation.length, 1);
126         const [related] = relatedInformation;
127         assert.strictEqual(related.message, 'defined here');
128
129         // There are no suggested fixes
130         assert.strictEqual(suggestedFixes.length, 0);
131     });
132
133     it('should map a Clippy copy pass by ref warning', () => {
134         const { diagnostic, suggestedFixes } = mapFixtureToVsCode(
135             'clippy/trivially_copy_pass_by_ref',
136         );
137
138         assert.strictEqual(
139             diagnostic.severity,
140             vscode.DiagnosticSeverity.Warning,
141         );
142         assert.strictEqual(diagnostic.source, 'clippy');
143         assert.strictEqual(
144             diagnostic.message,
145             [
146                 'this argument is passed by reference, but would be more efficient if passed by value',
147                 '#[warn(clippy::trivially_copy_pass_by_ref)] implied by #[warn(clippy::all)]',
148                 'for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref',
149             ].join('\n'),
150         );
151         assert.strictEqual(diagnostic.code, 'trivially_copy_pass_by_ref');
152         assert.deepStrictEqual(diagnostic.tags, []);
153
154         // One related information for the lint definition
155         const relatedInformation = diagnostic.relatedInformation;
156         if (!relatedInformation) {
157             return assert.fail('Related information unexpectedly undefined');
158         }
159         assert.strictEqual(relatedInformation.length, 1);
160         const [related] = relatedInformation;
161         assert.strictEqual(related.message, 'lint level defined here');
162
163         // One suggested fix to pass by value
164         assert.strictEqual(suggestedFixes.length, 1);
165         const [suggestedFix] = suggestedFixes;
166         assert.strictEqual(
167             suggestedFix.title,
168             'consider passing by value instead: `self`',
169         );
170         // Clippy does not mark this with any applicability
171         assert.strictEqual(
172             suggestedFix.applicability,
173             SuggestionApplicability.Unspecified,
174         );
175     });
176
177     it('should map a mismatched type error', () => {
178         const { diagnostic, suggestedFixes } = mapFixtureToVsCode(
179             'error/E0308',
180         );
181
182         assert.strictEqual(
183             diagnostic.severity,
184             vscode.DiagnosticSeverity.Error,
185         );
186         assert.strictEqual(
187             diagnostic.message,
188             ['mismatched types', 'expected usize, found u32'].join('\n'),
189         );
190         assert.strictEqual(diagnostic.code, 'E0308');
191         assert.strictEqual(diagnostic.source, 'rustc');
192         assert.deepStrictEqual(diagnostic.tags, []);
193
194         // No related information
195         assert.deepStrictEqual(diagnostic.relatedInformation, []);
196
197         // There are no suggested fixes
198         assert.strictEqual(suggestedFixes.length, 0);
199     });
200 });