microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
3fc684b157698c92d12be32ea3c6f7b3521de2b3

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

language_service/src/hover/tests.rs

687lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::get_hover;
5use crate::{
6 hover::Span,
7 test_utils::{compile_with_fake_stdlib, get_source_and_marker_offsets},
8};
9use expect_test::{expect, Expect};
10use indoc::indoc;
11
12/// Asserts that the hover text at the given cursor position matches the expected hover text.
13/// The cursor position is indicated by a `↘` marker in the source text.
14/// The expected hover span is indicated by two `◉` markers in the source text.
15fn check(source_with_markers: &str, expect: &Expect) {
16 let (source, cursor_offsets, target_offsets) =
17 get_source_and_marker_offsets(source_with_markers);
18 let compilation = compile_with_fake_stdlib("<source>", &source);
19 let actual = get_hover(&compilation, "<source>", cursor_offsets[0]).expect("Expected a hover.");
20 assert_eq!(
21 &actual.span,
22 &Span {
23 start: target_offsets[0],
24 end: target_offsets[1],
25 }
26 );
27 expect.assert_debug_eq(&actual.contents);
28}
29
30/// Asserts that there is no hover for the given test case.
31fn check_none(source_with_markers: &str) {
32 let (source, cursor_offsets, _) = get_source_and_marker_offsets(source_with_markers);
33 let compilation = compile_with_fake_stdlib("<source>", &source);
34 let actual = get_hover(&compilation, "<source>", cursor_offsets[0]);
35 assert!(actual.is_none());
36}
37
38#[test]
39fn hover_callable_unit_types() {
40 check(
41 indoc! {r#"
42 namespace Test {
43 /// Doc comment
44 /// with multiple lines!
45 operation ◉B↘ar◉() : Unit {}
46 }
47 "#},
48 &expect![[r#"
49 "Doc comment\nwith multiple lines!\n```qsharp\noperation Bar Unit => Unit\n```\n"
50 "#]],
51 );
52}
53
54#[test]
55fn hover_callable_with_callable_types() {
56 check(
57 indoc! {r#"
58 namespace Test {
59 /// Doc comment!
60 operation ◉F↘oo◉(x : (Int => Int)) : (Int => Int) {x}
61 }
62 "#},
63 &expect![[r#"
64 "Doc comment!\n```qsharp\noperation Foo (Int => Int) => (Int => Int)\n```\n"
65 "#]],
66 );
67}
68
69#[test]
70fn hover_call() {
71 check(
72 indoc! {r#"
73 namespace Test {
74 operation Foo() : Unit { ◉B↘ar◉(); }
75
76 operation Bar() : Unit {}
77 }
78 "#},
79 &expect![[r#"
80 "```qsharp\noperation Bar Unit => Unit\n```\n"
81 "#]],
82 );
83}
84
85#[test]
86fn hover_callable_unit_types_functors() {
87 check(
88 indoc! {r#"
89 namespace Test {
90 /// Doc comment!
91 operation ◉F↘oo◉() : Unit is Ctl {}
92 }
93 "#},
94 &expect![[r#"
95 "Doc comment!\n```qsharp\noperation Foo Unit => Unit is Ctl\n```\n"
96 "#]],
97 );
98}
99
100#[test]
101fn hover_callable_with_callable_types_functors() {
102 check(
103 indoc! {r#"
104 namespace Test {
105 /// Doc comment!
106 operation ◉F↘oo◉(x : (Int => Int is Ctl + Adj)) : (Int => Int is Adj) is Adj {x}
107 }
108 "#},
109 &expect![[r#"
110 "Doc comment!\n```qsharp\noperation Foo (Int => Int is Adj + Ctl) => (Int => Int is Adj) is Adj\n```\n"
111 "#]],
112 );
113}
114
115#[test]
116fn hover_call_functors() {
117 check(
118 indoc! {r#"
119 namespace Test {
120 operation Foo() : Unit { ◉B↘ar◉(); }
121
122 operation Bar() : Unit is Adj {}
123 }
124 "#},
125 &expect![[r#"
126 "```qsharp\noperation Bar Unit => Unit is Adj\n```\n"
127 "#]],
128 );
129}
130
131#[test]
132fn hover_identifier() {
133 check(
134 indoc! {r#"
135 namespace Test {
136 operation Foo() : Unit {
137 let ◉↘x◉ = 3;
138 }
139 }
140 "#},
141 &expect![[r#"
142 "```qsharp\nx: Int\n```\n"
143 "#]],
144 );
145}
146
147#[test]
148fn hover_identifier_ref() {
149 check(
150 indoc! {r#"
151 namespace Test {
152 operation Foo() : Unit {
153 let x = 3;
154 let y = ◉↘x◉;
155 }
156 }
157 "#},
158 &expect![[r#"
159 "```qsharp\nx: Int\n```\n"
160 "#]],
161 );
162}
163
164#[test]
165fn hover_identifier_tuple() {
166 check(
167 indoc! {r#"
168 namespace Test {
169 operation Foo() : Unit {
170 let (x, ◉↘y◉) = (3, 1.4);
171 }
172 }
173 "#},
174 &expect![[r#"
175 "```qsharp\ny: Double\n```\n"
176 "#]],
177 );
178}
179
180#[test]
181fn hover_identifier_tuple_ref() {
182 check(
183 indoc! {r#"
184 namespace Test {
185 operation Foo() : Unit {
186 let (x, y) = (3, 1.4);
187 let z = ◉↘y◉;
188 }
189 }
190 "#},
191 &expect![[r#"
192 "```qsharp\ny: Double\n```\n"
193 "#]],
194 );
195}
196
197#[test]
198fn hover_identifier_for_loop() {
199 check(
200 indoc! {r#"
201 namespace Test {
202 operation Foo() : Unit {
203 for ◉↘i◉ in 0..10 {
204 let y = i;
205 }
206 }
207 }
208 "#},
209 &expect![[r#"
210 "```qsharp\ni: Int\n```\n"
211 "#]],
212 );
213}
214
215#[test]
216fn hover_identifier_for_loop_ref() {
217 check(
218 indoc! {r#"
219 namespace Test {
220 operation Foo() : Unit {
221 for i in 0..10 {
222 let y = ◉↘i◉;
223 }
224 }
225 }
226 "#},
227 &expect![[r#"
228 "```qsharp\ni: Int\n```\n"
229 "#]],
230 );
231}
232
233#[test]
234fn hover_identifier_nested_ref() {
235 check(
236 indoc! {r#"
237 namespace Test {
238 operation Foo() : Unit {
239 let x = 3;
240 if true {
241 let y = ◉↘x◉;
242 }
243 }
244 }
245 "#},
246 &expect![[r#"
247 "```qsharp\nx: Int\n```\n"
248 "#]],
249 );
250}
251
252#[test]
253fn hover_lambda() {
254 check(
255 indoc! {r#"
256 namespace Test {
257 operation Foo() : Unit {
258 let a = 3;
259 let ◉la↘mbda◉ = (x, y) => a;
260 let b = lambda(1.2, "yes");
261 }
262 }
263 "#},
264 &expect![[r#"
265 "```qsharp\nlambda: ((Double, String) => Int)\n```\n"
266 "#]],
267 );
268}
269
270#[test]
271fn hover_lambda_ref() {
272 check(
273 indoc! {r#"
274 namespace Test {
275 operation Foo() : Unit {
276 let a = 3;
277 let lambda = (x, y) => a;
278 let b = ◉la↘mbda◉(1.2, "yes");
279 }
280 }
281 "#},
282 &expect![[r#"
283 "```qsharp\nlambda: ((Double, String) => Int)\n```\n"
284 "#]],
285 );
286}
287
288#[test]
289fn hover_lambda_param() {
290 check(
291 indoc! {r#"
292 namespace Test {
293 operation Foo() : Unit {
294 let a = 3;
295 let lambda = (x, ◉↘y◉) => a;
296 let b = lambda(1.2, "yes");
297 }
298 }
299 "#},
300 &expect![[r#"
301 "```qsharp\ny: String\n```\n"
302 "#]],
303 );
304}
305
306#[test]
307fn hover_lambda_param_ref() {
308 check(
309 indoc! {r#"
310 namespace Test {
311 operation Foo() : Unit {
312 let lambda = (x, y) => ◉↘y◉;
313 let a = lambda(1.2, "yes");
314 }
315 }
316 "#},
317 &expect![[r#"
318 "```qsharp\ny: String\n```\n"
319 "#]],
320 );
321}
322
323#[test]
324fn hover_lambda_closure_ref() {
325 check(
326 indoc! {r#"
327 namespace Test {
328 operation Foo() : Unit {
329 let a = 3;
330 let lambda = (x, y) => ◉↘a◉;
331 let b = lambda(1.2, "yes");
332 }
333 }
334 "#},
335 &expect![[r#"
336 "```qsharp\na: Int\n```\n"
337 "#]],
338 );
339}
340
341#[test]
342fn hover_identifier_udt() {
343 check(
344 indoc! {r#"
345 namespace Test {
346 newtype Pair = (fst : Int, snd : Int);
347 operation Foo() : Unit {
348 let a = Pair(3, 4);
349 let b = ◉↘a◉;
350 }
351 }
352 "#},
353 &expect![[r#"
354 "```qsharp\na: Pair\n```\n"
355 "#]],
356 );
357}
358
359#[test]
360fn hover_udt() {
361 check(
362 indoc! {r#"
363 namespace Test {
364 newtype ◉P↘air◉ = (Int, snd : Int);
365 }
366 "#},
367 &expect![[r#"
368 "```qsharp\nPair = (Int, snd: Int)\n```\n"
369 "#]],
370 );
371}
372
373#[test]
374fn hover_udt_ref() {
375 check(
376 indoc! {r#"
377 namespace Test {
378 newtype Bar = (fst: Int, (snd : Int, Double, fourth: String), Double, sixth: Int);
379 operation Foo() : ◉B↘ar◉ {
380 Bar(3, (4, 2.1, "Yes"), 4.7, 2)
381 }
382 }
383 "#},
384 &expect![[r#"
385 "```qsharp\nBar = (fst: Int, (snd: Int, Double, fourth: String), Double, sixth: Int)\n```\n"
386 "#]],
387 );
388}
389
390#[test]
391fn hover_udt_ref_nested_udt() {
392 check(
393 indoc! {r#"
394 namespace Test {
395 newtype Pair = (fst: Int, snd: Int);
396 newtype Bar = (fst: Int, (snd : Int, Double, fourth: Pair), Double, sixth: Int);
397 operation Foo() : ◉B↘ar◉ {
398 Bar(3, (4, 2.1, Pair(14, 15)), 4.7, 2)
399 }
400 }
401 "#},
402 &expect![[r#"
403 "```qsharp\nBar = (fst: Int, (snd: Int, Double, fourth: Pair), Double, sixth: Int)\n```\n"
404 "#]],
405 );
406}
407
408#[test]
409fn hover_udt_anno_ref() {
410 check(
411 indoc! {r#"
412 namespace Test {
413 newtype Pair = (Int, snd : Int);
414 operation Foo() : Unit {
415 let a : ◉P↘air◉ = Pair(3, 4);
416 }
417 }
418 "#},
419 &expect![[r#"
420 "```qsharp\nPair = (Int, snd: Int)\n```\n"
421 "#]],
422 );
423}
424
425#[test]
426fn hover_udt_constructor() {
427 check(
428 indoc! {r#"
429 namespace Test {
430 newtype Pair = (Int, snd : Int);
431 operation Foo() : Unit {
432 let a = ◉P↘air◉(3, 4);
433 }
434 }
435 "#},
436 &expect![[r#"
437 "```qsharp\nPair = (Int, snd: Int)\n```\n"
438 "#]],
439 );
440}
441
442#[test]
443fn hover_udt_field() {
444 check(
445 indoc! {r#"
446 namespace Test {
447 newtype Pair = (Int, ◉s↘nd◉ : Int);
448 }
449 "#},
450 &expect![[r#"
451 "```qsharp\nsnd: Int\n```\n"
452 "#]],
453 );
454}
455
456#[test]
457fn hover_udt_field_ref() {
458 check(
459 indoc! {r#"
460 namespace Test {
461 newtype Pair = (Int, snd : Int);
462 operation Foo() : Unit {
463 let a = Pair(3, 4);
464 let b = a::◉s↘nd◉;
465 }
466 }
467 "#},
468 &expect![[r#"
469 "```qsharp\nsnd: Int\n```\n"
470 "#]],
471 );
472}
473
474#[test]
475fn hover_primitive_type() {
476 check_none(indoc! {r#"
477 namespace Test {
478 newtype Pair = (◉I↘nt◉, snd : Int);
479 operation Foo() : Unit {
480 let a = Pair(3, 4);
481 let b = a::snd;
482 }
483 }
484 "#});
485}
486
487#[test]
488fn hover_foreign_call() {
489 check(
490 indoc! {r#"
491 namespace Test {
492 open FakeStdLib;
493 operation Foo() : Unit {
494 ◉F↘ake◉();
495 }
496 }
497 "#},
498 &expect![[r#"
499 "```qsharp\noperation Fake Unit => Unit\n```\n"
500 "#]],
501 );
502}
503
504#[test]
505fn hover_foreign_call_functors() {
506 check(
507 indoc! {r#"
508 namespace Test {
509 open FakeStdLib;
510 operation Foo() : Unit {
511 ◉F↘akeCtlAdj◉();
512 }
513 }
514 "#},
515 &expect![[r#"
516 "```qsharp\noperation FakeCtlAdj Unit => Unit is Adj + Ctl\n```\n"
517 "#]],
518 );
519}
520
521#[test]
522fn hover_callable_summary() {
523 check(
524 indoc! {r#"
525 namespace Test {
526 /// # Summary
527 /// This is a
528 /// multi-line summary!
529 operation ◉F↘oo◉() : Unit {}
530 }
531 "#},
532 &expect![[r#"
533 "This is a\nmulti-line summary!\n```qsharp\noperation Foo Unit => Unit\n```\n"
534 "#]],
535 );
536}
537
538#[test]
539fn hover_callable_summary_stuff_before() {
540 check(
541 indoc! {r#"
542 namespace Test {
543 /// not the summary
544 /// # Summary
545 /// This is a
546 /// multi-line summary!
547 operation ◉F↘oo◉() : Unit {}
548 }
549 "#},
550 &expect![[r#"
551 "This is a\nmulti-line summary!\n```qsharp\noperation Foo Unit => Unit\n```\n"
552 "#]],
553 );
554}
555
556#[test]
557fn hover_callable_summary_other_header_before() {
558 check(
559 indoc! {r#"
560 namespace Test {
561 /// # Not The Summary
562 /// This stuff is not the summary.
563 /// # Summary
564 /// This is a
565 /// multi-line summary!
566 operation ◉F↘oo◉() : Unit {}
567 }
568 "#},
569 &expect![[r#"
570 "This is a\nmulti-line summary!\n```qsharp\noperation Foo Unit => Unit\n```\n"
571 "#]],
572 );
573}
574
575#[test]
576fn hover_callable_summary_other_header_after() {
577 check(
578 indoc! {r#"
579 namespace Test {
580 /// # Summary
581 /// This is a
582 /// multi-line summary!
583 /// # Not The Summary
584 /// This stuff is not the summary.
585 operation ◉F↘oo◉() : Unit {}
586 }
587 "#},
588 &expect![[r#"
589 "This is a\nmulti-line summary!\n```qsharp\noperation Foo Unit => Unit\n```\n"
590 "#]],
591 );
592}
593
594#[test]
595fn hover_callable_summary_other_headers() {
596 check(
597 indoc! {r#"
598 namespace Test {
599 /// # Not The Summary
600 /// This stuff is not the summary.
601 /// # Summary
602 /// This is a
603 /// multi-line summary!
604 /// # Also Not The Summary
605 /// This stuff is also not the summary.
606 operation ◉F↘oo◉() : Unit {}
607 }
608 "#},
609 &expect![[r#"
610 "This is a\nmulti-line summary!\n```qsharp\noperation Foo Unit => Unit\n```\n"
611 "#]],
612 );
613}
614
615#[test]
616fn hover_callable_headers_but_no_summary() {
617 check(
618 indoc! {r#"
619 namespace Test {
620 /// # Not The Summary
621 /// This stuff is not the summary.
622 /// # Also Not The Summary
623 /// This stuff is also not the summary.
624 operation ◉F↘oo◉() : Unit {}
625 }
626 "#},
627 &expect![[r##"
628 "# Not The Summary\nThis stuff is not the summary.\n# Also Not The Summary\nThis stuff is also not the summary.\n```qsharp\noperation Foo Unit => Unit\n```\n"
629 "##]],
630 );
631}
632
633#[test]
634fn hover_callable_summary_only_header_matches() {
635 check(
636 indoc! {r#"
637 namespace Test {
638 /// # Not The Summary
639 /// This stuff is not the # Summary.
640 /// # Summary
641 /// This is a
642 /// multi-line # Summary!
643 /// # Also Not The Summary
644 /// This stuff is also not the # Summary.
645 operation ◉F↘oo◉() : Unit {}
646 }
647 "#},
648 &expect![[r#"
649 "This is a\nmulti-line # Summary!\n```qsharp\noperation Foo Unit => Unit\n```\n"
650 "#]],
651 );
652}
653
654#[test]
655fn hover_callable_summary_successive_headers() {
656 check(
657 indoc! {r#"
658 namespace Test {
659 /// # Not The Summary
660 /// # Summary
661 /// This is a
662 /// multi-line summary!
663 operation ◉F↘oo◉() : Unit {}
664 }
665 "#},
666 &expect![[r#"
667 "This is a\nmulti-line summary!\n```qsharp\noperation Foo Unit => Unit\n```\n"
668 "#]],
669 );
670}
671
672#[test]
673fn hover_callable_empty_summary() {
674 check(
675 indoc! {r#"
676 namespace Test {
677 /// # Not The Summary
678 /// # Summary
679 /// # Also Not The Summary
680 operation ◉F↘oo◉() : Unit {}
681 }
682 "#},
683 &expect![[r##"
684 "```qsharp\noperation Foo Unit => Unit\n```\n"
685 "##]],
686 );
687}
688