microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
fedimser/is-re

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/language_service/src/hover/tests.rs

1680lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use super::get_hover;
5use crate::test_utils::{compile_notebook_with_markers, compile_with_markers};
6use expect_test::{Expect, expect};
7use indoc::indoc;
8use qsc::line_column::Encoding;
9
10/// Asserts that the hover text at the given cursor position matches the expected hover text.
11/// The cursor position is indicated by a `↘` marker in the source text.
12/// The expected hover span is indicated by two `◉` markers in the source text.
13fn check(source_with_markers: &str, expect: &Expect) {
14 let (compilation, cursor_position, target_spans) =
15 compile_with_markers(source_with_markers, true);
16 let actual = get_hover(&compilation, "<source>", cursor_position, Encoding::Utf8)
17 .expect("Expected a hover.");
18 assert_eq!(&actual.span, &target_spans[0]);
19 expect.assert_eq(&actual.contents);
20}
21
22/// Asserts that there is no hover for the given test case.
23fn check_none(source_with_markers: &str) {
24 let (compilation, cursor_position, _) = compile_with_markers(source_with_markers, true);
25 let actual = get_hover(&compilation, "<source>", cursor_position, Encoding::Utf8);
26 assert!(actual.is_none());
27}
28
29fn check_notebook(cells_with_markers: &[(&str, &str)], expect: &Expect) {
30 let (compilation, cell_uri, position, target_spans) =
31 compile_notebook_with_markers(cells_with_markers);
32
33 let actual =
34 get_hover(&compilation, &cell_uri, position, Encoding::Utf8).expect("Expected a hover.");
35 assert_eq!(&actual.span, &target_spans[0].range);
36 expect.assert_eq(&actual.contents);
37}
38
39fn check_notebook_none(cells_with_markers: &[(&str, &str)]) {
40 let (compilation, cell_uri, position, _) = compile_notebook_with_markers(cells_with_markers);
41
42 let actual = get_hover(&compilation, &cell_uri, position, Encoding::Utf8);
43 assert!(actual.is_none());
44}
45
46#[test]
47fn attr() {
48 check(
49 indoc! {r#"
50 namespace Test {
51 @◉Entr↘yPoint◉()
52 operation Bar() : Unit {}
53 }
54 "#},
55 &expect![[r#"
56 attribute ```EntryPoint```
57
58 Indicates that the callable is the entry point to a program."#]],
59 );
60}
61
62#[test]
63fn attr_with_arg() {
64 check(
65 indoc! {r#"
66 namespace Test {
67 @◉Con↘fig◉(BackwardsBranching)
68 operation Bar() : Unit {}
69 }
70 "#},
71 &expect![[r#"
72 attribute ```Config```
73
74 Provides pre-processing information about when an item should be included in compilation.
75
76 Valid arguments are `Base`, `Adaptive`, `IntegerComputations`, `FloatingPointComputations`, `BackwardsBranching`, `HigherLevelConstructs`, `QubitReset`, and `Unrestricted`.
77
78 The `not` operator is also supported to negate the attribute, e.g. `not Adaptive`."#]],
79 );
80}
81
82#[test]
83fn callable_unit_types() {
84 check(
85 indoc! {r#"
86 namespace Test {
87 /// Doc comment
88 /// with multiple lines!
89 operation ◉B↘ar◉() : Unit {}
90 }
91 "#},
92 &expect![[r#"
93 callable of `Test`
94 ```qsharp
95 operation Bar() : Unit
96 ```
97 ---
98 Doc comment
99 with multiple lines!
100 "#]],
101 );
102}
103
104#[test]
105fn callable_with_callable_types() {
106 check(
107 indoc! {r#"
108 namespace Test {
109 /// Doc comment!
110 operation ◉F↘oo◉(x : (Int => Int)) : (Int => Int) {x}
111 }
112 "#},
113 &expect![[r#"
114 callable of `Test`
115 ```qsharp
116 operation Foo(x : (Int => Int)) : (Int => Int)
117 ```
118 ---
119 Doc comment!
120 "#]],
121 );
122}
123
124#[test]
125fn callable_with_type_params() {
126 check(
127 indoc! {r#"
128 namespace Test {
129 /// Doc comment!
130 operation ◉F↘oo◉<'A, 'B>(a : 'A, b : 'B) : 'B { b }
131 }
132 "#},
133 &expect![[r#"
134 callable of `Test`
135 ```qsharp
136 operation Foo<'A, 'B>(a : 'A, b : 'B) : 'B
137 ```
138 ---
139 Doc comment!
140 "#]],
141 );
142}
143
144#[test]
145fn callable_ref() {
146 check(
147 indoc! {r#"
148 namespace Test {
149 operation Foo() : Unit { ◉B↘ar◉(); }
150
151 operation Bar() : Unit {}
152 }
153 "#},
154 &expect![[r#"
155 callable of `Test`
156 ```qsharp
157 operation Bar() : Unit
158 ```
159 "#]],
160 );
161}
162
163#[test]
164fn callable_with_type_params_ref() {
165 check(
166 indoc! {r#"
167 namespace Test {
168 operation Foo() : Unit {
169 let temp = ◉B↘ar◉(1, 2.0);
170 }
171
172 operation Bar<'A, 'B>(a : 'A, b : 'B) : 'B { b }
173 }
174 "#},
175 &expect![[r#"
176 callable of `Test`
177 ```qsharp
178 operation Bar<'A, 'B>(a : 'A, b : 'B) : 'B
179 ```
180 "#]],
181 );
182}
183
184#[test]
185fn callable_unit_types_functors() {
186 check(
187 indoc! {r#"
188 namespace Test {
189 /// Doc comment!
190 operation ◉F↘oo◉() : Unit is Ctl {}
191 }
192 "#},
193 &expect![[r#"
194 callable of `Test`
195 ```qsharp
196 operation Foo() : Unit is Ctl
197 ```
198 ---
199 Doc comment!
200 "#]],
201 );
202}
203
204#[test]
205fn callable_with_callable_types_functors() {
206 check(
207 indoc! {r#"
208 namespace Test {
209 /// Doc comment!
210 operation ◉F↘oo◉(x : (Int => Int is Ctl + Adj)) : (Int => Int is Adj) is Adj {x}
211 }
212 "#},
213 &expect![[r#"
214 callable of `Test`
215 ```qsharp
216 operation Foo(x : (Int => Int is Adj + Ctl)) : (Int => Int is Adj) is Adj
217 ```
218 ---
219 Doc comment!
220 "#]],
221 );
222}
223
224#[test]
225fn callable_ref_functors() {
226 check(
227 indoc! {r#"
228 namespace Test {
229 operation Foo() : Unit { ◉B↘ar◉(); }
230
231 operation Bar() : Unit is Adj {}
232 }
233 "#},
234 &expect![[r#"
235 callable of `Test`
236 ```qsharp
237 operation Bar() : Unit is Adj
238 ```
239 "#]],
240 );
241}
242
243#[test]
244fn callable_param() {
245 check(
246 indoc! {r#"
247 namespace Test {
248 operation Foo(◉↘x◉ : Int) : Unit { let y = x; }
249 }
250 "#},
251 &expect![[r#"
252 parameter of `Foo`
253 ```qsharp
254 x : Int
255 ```
256 "#]],
257 );
258}
259
260#[test]
261fn callable_param_with_type_param() {
262 check(
263 indoc! {r#"
264 namespace Test {
265 operation Foo<'A>(◉↘x◉ : 'A) : Unit { let y = x; }
266 }
267 "#},
268 &expect![[r#"
269 parameter of `Foo`
270 ```qsharp
271 x : 'A
272 ```
273 "#]],
274 );
275}
276
277#[test]
278fn callable_param_ref() {
279 check(
280 indoc! {r#"
281 namespace Test {
282 operation Foo(x : Int) : Unit { let y = ◉↘x◉; }
283 }
284 "#},
285 &expect![[r#"
286 parameter of `Foo`
287 ```qsharp
288 x : Int
289 ```
290 "#]],
291 );
292}
293
294#[test]
295fn callable_param_with_type_param_ref() {
296 check(
297 indoc! {r#"
298 namespace Test {
299 operation Foo<'A>(x : 'A) : Unit { let y = ◉↘x◉; }
300 }
301 "#},
302 &expect![[r#"
303 parameter of `Foo`
304 ```qsharp
305 x : 'A
306 ```
307 "#]],
308 );
309}
310
311#[test]
312fn callable_spec_param() {
313 check(
314 indoc! {r#"
315 namespace Test {
316 operation Foo(x: Int): Unit is Ctl {
317 body ... { let y = x; }
318 controlled (◉↘ctrl◉, ...) { let z = ctrl; }
319 }
320 }
321 "#},
322 &expect![[r#"
323 parameter of `Foo`
324 ```qsharp
325 ctrl : Qubit[]
326 ```
327 "#]],
328 );
329}
330
331#[test]
332fn callable_spec_param_ref() {
333 check(
334 indoc! {r#"
335 namespace Test {
336 operation Foo(x: Int): Unit is Ctl {
337 body ... { let y = x; }
338 controlled (ctrl, ...) { let z = ◉↘ctrl◉; }
339 }
340 }
341 "#},
342 &expect![[r#"
343 parameter of `Foo`
344 ```qsharp
345 ctrl : Qubit[]
346 ```
347 "#]],
348 );
349}
350
351#[test]
352fn identifier() {
353 check(
354 indoc! {r#"
355 namespace Test {
356 operation Foo() : Unit {
357 let ◉↘x◉ = 3;
358 }
359 }
360 "#},
361 &expect![[r#"
362 local
363 ```qsharp
364 x : Int
365 ```
366 "#]],
367 );
368}
369
370#[test]
371fn identifier_with_type_param() {
372 check(
373 indoc! {r#"
374 namespace Test {
375 operation Foo<'A>(a : 'A) : Unit {
376 let ◉↘x◉ = a;
377 }
378 }
379 "#},
380 &expect![[r#"
381 local
382 ```qsharp
383 x : 'A
384 ```
385 "#]],
386 );
387}
388
389#[test]
390fn identifier_ref() {
391 check(
392 indoc! {r#"
393 namespace Test {
394 operation Foo() : Unit {
395 let x = 3;
396 let y = ◉↘x◉;
397 }
398 }
399 "#},
400 &expect![[r#"
401 local
402 ```qsharp
403 x : Int
404 ```
405 "#]],
406 );
407}
408
409#[test]
410fn identifier_with_type_param_ref() {
411 check(
412 indoc! {r#"
413 namespace Test {
414 operation Foo<'A>(a : 'A) : Unit {
415 let x = a;
416 let y = ◉↘x◉;
417 }
418 }
419 "#},
420 &expect![[r#"
421 local
422 ```qsharp
423 x : 'A
424 ```
425 "#]],
426 );
427}
428
429#[test]
430fn identifier_tuple() {
431 check(
432 indoc! {r#"
433 namespace Test {
434 operation Foo() : Unit {
435 let (x, ◉↘y◉) = (3, 1.4);
436 }
437 }
438 "#},
439 &expect![[r#"
440 local
441 ```qsharp
442 y : Double
443 ```
444 "#]],
445 );
446}
447
448#[test]
449fn identifier_tuple_ref() {
450 check(
451 indoc! {r#"
452 namespace Test {
453 operation Foo() : Unit {
454 let (x, y) = (3, 1.4);
455 let z = ◉↘y◉;
456 }
457 }
458 "#},
459 &expect![[r#"
460 local
461 ```qsharp
462 y : Double
463 ```
464 "#]],
465 );
466}
467
468#[test]
469fn identifier_for_loop() {
470 check(
471 indoc! {r#"
472 namespace Test {
473 operation Foo() : Unit {
474 for ◉↘i◉ in 0..10 {
475 let y = i;
476 }
477 }
478 }
479 "#},
480 &expect![[r#"
481 local
482 ```qsharp
483 i : Int
484 ```
485 "#]],
486 );
487}
488
489#[test]
490fn identifier_for_loop_ref() {
491 check(
492 indoc! {r#"
493 namespace Test {
494 operation Foo() : Unit {
495 for i in 0..10 {
496 let y = ◉↘i◉;
497 }
498 }
499 }
500 "#},
501 &expect![[r#"
502 local
503 ```qsharp
504 i : Int
505 ```
506 "#]],
507 );
508}
509
510#[test]
511fn identifier_nested_ref() {
512 check(
513 indoc! {r#"
514 namespace Test {
515 operation Foo() : Unit {
516 let x = 3;
517 if true {
518 let y = ◉↘x◉;
519 }
520 }
521 }
522 "#},
523 &expect![[r#"
524 local
525 ```qsharp
526 x : Int
527 ```
528 "#]],
529 );
530}
531
532#[test]
533fn lambda() {
534 check(
535 indoc! {r#"
536 namespace Test {
537 operation Foo() : Unit {
538 let a = 3;
539 let ◉la↘mbda◉ = (x, y) => a;
540 let b = lambda(1.2, "yes");
541 }
542 }
543 "#},
544 &expect![[r#"
545 local
546 ```qsharp
547 lambda : ((Double, String) => Int)
548 ```
549 "#]],
550 );
551}
552
553#[test]
554fn lambda_ref() {
555 check(
556 indoc! {r#"
557 namespace Test {
558 operation Foo() : Unit {
559 let a = 3;
560 let lambda = (x, y) => a;
561 let b = ◉la↘mbda◉(1.2, "yes");
562 }
563 }
564 "#},
565 &expect![[r#"
566 local
567 ```qsharp
568 lambda : ((Double, String) => Int)
569 ```
570 "#]],
571 );
572}
573
574#[test]
575fn lambda_param() {
576 check(
577 indoc! {r#"
578 namespace Test {
579 operation Foo() : Unit {
580 let a = 3;
581 let lambda = (x, ◉↘y◉) => a;
582 let b = lambda(1.2, "yes");
583 }
584 }
585 "#},
586 &expect![[r#"
587 lambda parameter
588 ```qsharp
589 y : String
590 ```
591 "#]],
592 );
593}
594
595#[test]
596fn lambda_param_ref() {
597 check(
598 indoc! {r#"
599 namespace Test {
600 operation Foo() : Unit {
601 let lambda = (x, y) => ◉↘y◉;
602 let a = lambda(1.2, "yes");
603 }
604 }
605 "#},
606 &expect![[r#"
607 lambda parameter
608 ```qsharp
609 y : String
610 ```
611 "#]],
612 );
613}
614
615#[test]
616fn lambda_closure_ref() {
617 check(
618 indoc! {r#"
619 namespace Test {
620 operation Foo() : Unit {
621 let a = 3;
622 let lambda = (x, y) => ◉↘a◉;
623 let b = lambda(1.2, "yes");
624 }
625 }
626 "#},
627 &expect![[r#"
628 local
629 ```qsharp
630 a : Int
631 ```
632 "#]],
633 );
634}
635
636#[test]
637fn identifier_udt() {
638 check(
639 indoc! {r#"
640 namespace Test {
641 newtype Pair = (fst : Int, snd : Int);
642 operation Foo() : Unit {
643 let a = Pair(3, 4);
644 let b = ◉↘a◉;
645 }
646 }
647 "#},
648 &expect![[r#"
649 local
650 ```qsharp
651 a : Pair
652 ```
653 "#]],
654 );
655}
656
657#[test]
658fn udt() {
659 check(
660 indoc! {r#"
661 namespace Test {
662 newtype ◉P↘air◉ = (Int, snd : Int);
663 }
664 "#},
665 &expect![[r#"
666 user-defined type of `Test`
667 ```qsharp
668 newtype Pair = (Int, snd : Int)
669 ```
670 "#]],
671 );
672}
673
674#[test]
675fn udt_ref() {
676 check(
677 indoc! {r#"
678 namespace Test {
679 newtype Bar = (fst: Int, (snd : Int, Double, fourth: String), Double, sixth: Int);
680 operation Foo() : ◉B↘ar◉ {
681 Bar(3, (4, 2.1, "Yes"), 4.7, 2)
682 }
683 }
684 "#},
685 &expect![[r#"
686 user-defined type of `Test`
687 ```qsharp
688 newtype Bar = (fst : Int, (snd : Int, Double, fourth : String), Double, sixth : Int)
689 ```
690 "#]],
691 );
692}
693
694#[test]
695fn udt_ref_nested_udt() {
696 check(
697 indoc! {r#"
698 namespace Test {
699 newtype Pair = (fst: Int, snd: Int);
700 newtype Bar = (fst: Int, (snd : Int, Double, fourth: Pair), Double, sixth: Int);
701 operation Foo() : ◉B↘ar◉ {
702 Bar(3, (4, 2.1, Pair(14, 15)), 4.7, 2)
703 }
704 }
705 "#},
706 &expect![[r#"
707 user-defined type of `Test`
708 ```qsharp
709 newtype Bar = (fst : Int, (snd : Int, Double, fourth : Pair), Double, sixth : Int)
710 ```
711 "#]],
712 );
713}
714
715#[test]
716fn udt_anno_ref() {
717 check(
718 indoc! {r#"
719 namespace Test {
720 newtype Pair = (Int, snd : Int);
721 operation Foo() : Unit {
722 let a : ◉P↘air◉ = Pair(3, 4);
723 }
724 }
725 "#},
726 &expect![[r#"
727 user-defined type of `Test`
728 ```qsharp
729 newtype Pair = (Int, snd : Int)
730 ```
731 "#]],
732 );
733}
734
735#[test]
736fn udt_constructor() {
737 check(
738 indoc! {r#"
739 namespace Test {
740 newtype Pair = (Int, snd : Int);
741 operation Foo() : Unit {
742 let a = ◉P↘air◉(3, 4);
743 }
744 }
745 "#},
746 &expect![[r#"
747 user-defined type of `Test`
748 ```qsharp
749 newtype Pair = (Int, snd : Int)
750 ```
751 "#]],
752 );
753}
754
755#[test]
756fn udt_field() {
757 check(
758 indoc! {r#"
759 namespace Test {
760 newtype Pair = (Int, ◉s↘nd◉ : Int);
761 }
762 "#},
763 &expect![[r#"
764 field of `Pair`
765 ```qsharp
766 snd : Int
767 ```
768 "#]],
769 );
770}
771
772#[test]
773fn udt_field_ref() {
774 check(
775 indoc! {r#"
776 namespace Test {
777 newtype Pair = (Int, snd : Int);
778 operation Foo() : Unit {
779 let a = Pair(3, 4);
780 let b = a::◉s↘nd◉;
781 }
782 }
783 "#},
784 &expect![[r#"
785 field of `Pair`
786 ```qsharp
787 snd : Int
788 ```
789 "#]],
790 );
791}
792
793#[test]
794fn identifier_struct() {
795 check(
796 indoc! {r#"
797 namespace Test {
798 struct Pair { fst : Int, snd : Int }
799 operation Foo() : Unit {
800 let a = new Pair { fst = 3, snd = 4 };
801 let b = ◉↘a◉;
802 }
803 }
804 "#},
805 &expect![[r#"
806 local
807 ```qsharp
808 a : Pair
809 ```
810 "#]],
811 );
812}
813
814#[test]
815fn struct_def() {
816 check(
817 indoc! {r#"
818 namespace Test {
819 struct ◉P↘air◉ { fst : Int, snd : Int }
820 }
821 "#},
822 &expect![[r#"
823 struct of `Test`
824 ```qsharp
825 struct Pair { fst : Int, snd : Int }
826 ```
827 "#]],
828 );
829}
830
831#[test]
832fn struct_ref() {
833 check(
834 indoc! {r#"
835 namespace Test {
836 struct Pair { fst : Int, snd : Int }
837 operation Foo() : ◉Pa↘ir◉ {
838 new Pair { fst = 3, snd = 4 }
839 }
840 }
841 "#},
842 &expect![[r#"
843 struct of `Test`
844 ```qsharp
845 struct Pair { fst : Int, snd : Int }
846 ```
847 "#]],
848 );
849}
850
851#[test]
852fn struct_ref_nested_struct() {
853 check(
854 indoc! {r#"
855 namespace Test {
856 struct Pair { fst : Int, snd : Int }
857 struct Bar { fst: Int, snd : Pair }
858 operation Foo() : ◉B↘ar◉ {
859 new Bar { fst = 1, snd = new Pair { fst = 2, snd = 3 } }
860 }
861 }
862 "#},
863 &expect![[r#"
864 struct of `Test`
865 ```qsharp
866 struct Bar { fst : Int, snd : Pair }
867 ```
868 "#]],
869 );
870}
871
872#[test]
873fn struct_anno_ref() {
874 check(
875 indoc! {r#"
876 namespace Test {
877 struct Pair { fst : Int, snd : Int }
878 operation Foo() : Unit {
879 let a : ◉P↘air◉ = new Pair { fst = 3, snd = 4 };
880 }
881 }
882 "#},
883 &expect![[r#"
884 struct of `Test`
885 ```qsharp
886 struct Pair { fst : Int, snd : Int }
887 ```
888 "#]],
889 );
890}
891
892#[test]
893fn struct_constructor() {
894 check(
895 indoc! {r#"
896 namespace Test {
897 struct Pair { fst : Int, snd : Int }
898 operation Foo() : Unit {
899 let a = new ◉P↘air◉ { fst = 3, snd = 4 };
900 }
901 }
902 "#},
903 &expect![[r#"
904 struct of `Test`
905 ```qsharp
906 struct Pair { fst : Int, snd : Int }
907 ```
908 "#]],
909 );
910}
911
912#[test]
913fn struct_fn_constructor() {
914 check(
915 indoc! {r#"
916 namespace Test {
917 struct Pair { fst : Int, snd : Int }
918 operation Foo() : Unit {
919 let a = ◉P↘air◉(3, 4);
920 }
921 }
922 "#},
923 &expect![[r#"
924 struct of `Test`
925 ```qsharp
926 struct Pair { fst : Int, snd : Int }
927 ```
928 "#]],
929 );
930}
931
932#[test]
933fn struct_field() {
934 check(
935 indoc! {r#"
936 namespace Test {
937 struct Pair { fst : Int, ◉s↘nd◉ : Int }
938 }
939 "#},
940 &expect![[r#"
941 field of `Pair`
942 ```qsharp
943 snd : Int
944 ```
945 "#]],
946 );
947}
948
949#[test]
950fn struct_field_ref() {
951 check(
952 indoc! {r#"
953 namespace Test {
954 struct Pair { fst : Int, snd : Int }
955 operation Foo() : Unit {
956 let a = new Pair { fst = 3, snd = 4 };
957 let b = a::◉s↘nd◉;
958 }
959 }
960 "#},
961 &expect![[r#"
962 field of `Pair`
963 ```qsharp
964 snd : Int
965 ```
966 "#]],
967 );
968}
969
970#[test]
971fn struct_field_ref_with_doc() {
972 check(
973 indoc! {r#"
974 namespace Test {
975 struct Pair {
976 fst : Int,
977 /// This is the second field!
978 snd : Int
979 }
980 operation Foo() : Unit {
981 let a = new Pair { fst = 3, snd = 4 };
982 let b = a::◉s↘nd◉;
983 }
984 }
985 "#},
986 &expect![[r#"
987 field of `Pair`
988 ```qsharp
989 /// This is the second field!
990 snd : Int
991 ```
992 "#]],
993 );
994}
995
996#[test]
997fn struct_field_cons_ref() {
998 check(
999 indoc! {r#"
1000 namespace Test {
1001 struct Pair { fst : Int, snd : Int }
1002 operation Foo() : Unit {
1003 let a = new Pair { fst = 3, ◉s↘nd◉ = 4 };
1004 }
1005 }
1006 "#},
1007 &expect![[r#"
1008 field of `Pair`
1009 ```qsharp
1010 snd : Int
1011 ```
1012 "#]],
1013 );
1014}
1015
1016#[test]
1017fn struct_field_path_ref() {
1018 check(
1019 indoc! {r#"
1020 namespace Test {
1021 struct A { b : B }
1022 struct B { c : C }
1023 struct C { i : Int }
1024 operation Foo(a : A) : Unit {
1025 let x = a.b.◉↘c◉.i;
1026 }
1027 }
1028 "#},
1029 &expect![[r#"
1030 field of `B`
1031 ```qsharp
1032 c : C
1033 ```
1034 "#]],
1035 );
1036}
1037
1038#[test]
1039fn struct_field_path_first_ref() {
1040 check(
1041 indoc! {r#"
1042 namespace Test {
1043 struct A { b : B }
1044 struct B { c : C }
1045 struct C { i : Int }
1046 operation Foo(a : A) : Unit {
1047 let x = ◉↘a◉.b.c.i;
1048 }
1049 }
1050 "#},
1051 &expect![[r#"
1052 parameter of `Foo`
1053 ```qsharp
1054 a : A
1055 ```
1056 "#]],
1057 );
1058}
1059
1060#[test]
1061fn struct_field_path_with_expr_ref() {
1062 check(
1063 indoc! {r#"
1064 namespace Test {
1065 struct A { b : B }
1066 struct B { c : C }
1067 struct C { i : Int }
1068 operation Foo(a : A) : Unit {
1069 let x = { a.◉↘b◉ }.c.i;
1070 }
1071 }
1072 "#},
1073 &expect![[r#"
1074 field of `A`
1075 ```qsharp
1076 b : B
1077 ```
1078 "#]],
1079 );
1080}
1081
1082#[test]
1083fn primitive_type() {
1084 check_none(indoc! {r#"
1085 namespace Test {
1086 newtype Pair = (◉I↘nt◉, snd : Int);
1087 operation Foo() : Unit {
1088 let a = Pair(3, 4);
1089 let b = a::snd;
1090 }
1091 }
1092 "#});
1093}
1094
1095#[test]
1096fn foreign_call() {
1097 check(
1098 indoc! {r#"
1099 namespace Test {
1100 open FakeStdLib;
1101 operation Foo() : Unit {
1102 ◉F↘ake◉();
1103 }
1104 }
1105 "#},
1106 &expect![[r#"
1107 callable of `FakeStdLib`
1108 ```qsharp
1109 operation Fake() : Unit
1110 ```
1111 "#]],
1112 );
1113}
1114
1115#[test]
1116fn foreign_call_functors() {
1117 check(
1118 indoc! {r#"
1119 namespace Test {
1120 open FakeStdLib;
1121 operation Foo() : Unit {
1122 ◉F↘akeCtlAdj◉();
1123 }
1124 }
1125 "#},
1126 &expect![[r#"
1127 callable of `FakeStdLib`
1128 ```qsharp
1129 operation FakeCtlAdj() : Unit is Adj + Ctl
1130 ```
1131 "#]],
1132 );
1133}
1134
1135#[test]
1136fn foreign_call_with_param() {
1137 check(
1138 indoc! {r#"
1139 namespace Test {
1140 open FakeStdLib;
1141 operation Foo() : Unit {
1142 ◉FakeWi↘thParam◉(4);
1143 }
1144 }
1145 "#},
1146 &expect![[r#"
1147 callable of `FakeStdLib`
1148 ```qsharp
1149 operation FakeWithParam(x : Int) : Unit
1150 ```
1151 "#]],
1152 );
1153}
1154
1155#[test]
1156fn callable_summary() {
1157 check(
1158 indoc! {r#"
1159 namespace Test {
1160 /// # Summary
1161 /// This is a
1162 /// multi-line summary!
1163 operation ◉F↘oo◉() : Unit {}
1164 }
1165 "#},
1166 &expect![[r#"
1167 callable of `Test`
1168 ```qsharp
1169 operation Foo() : Unit
1170 ```
1171 ---
1172 This is a
1173 multi-line summary!
1174 "#]],
1175 );
1176}
1177
1178#[test]
1179fn callable_summary_stuff_before() {
1180 check(
1181 indoc! {r#"
1182 namespace Test {
1183 /// not the summary
1184 /// # Summary
1185 /// This is a
1186 /// multi-line summary!
1187 operation ◉F↘oo◉() : Unit {}
1188 }
1189 "#},
1190 &expect![[r#"
1191 callable of `Test`
1192 ```qsharp
1193 operation Foo() : Unit
1194 ```
1195 ---
1196 This is a
1197 multi-line summary!
1198 "#]],
1199 );
1200}
1201
1202#[test]
1203fn callable_summary_other_header_before() {
1204 check(
1205 indoc! {r#"
1206 namespace Test {
1207 /// # Not The Summary
1208 /// This stuff is not the summary.
1209 /// # Summary
1210 /// This is a
1211 /// multi-line summary!
1212 operation ◉F↘oo◉() : Unit {}
1213 }
1214 "#},
1215 &expect![[r#"
1216 callable of `Test`
1217 ```qsharp
1218 operation Foo() : Unit
1219 ```
1220 ---
1221 This is a
1222 multi-line summary!
1223 "#]],
1224 );
1225}
1226
1227#[test]
1228fn callable_summary_other_header_after() {
1229 check(
1230 indoc! {r#"
1231 namespace Test {
1232 /// # Summary
1233 /// This is a
1234 /// multi-line summary!
1235 /// # Not The Summary
1236 /// This stuff is not the summary.
1237 operation ◉F↘oo◉() : Unit {}
1238 }
1239 "#},
1240 &expect![[r#"
1241 callable of `Test`
1242 ```qsharp
1243 operation Foo() : Unit
1244 ```
1245 ---
1246 This is a
1247 multi-line summary!
1248 "#]],
1249 );
1250}
1251
1252#[test]
1253fn callable_summary_other_headers() {
1254 check(
1255 indoc! {r#"
1256 namespace Test {
1257 /// # Not The Summary
1258 /// This stuff is not the summary.
1259 /// # Summary
1260 /// This is a
1261 /// multi-line summary!
1262 /// # Also Not The Summary
1263 /// This stuff is also not the summary.
1264 operation ◉F↘oo◉() : Unit {}
1265 }
1266 "#},
1267 &expect![[r#"
1268 callable of `Test`
1269 ```qsharp
1270 operation Foo() : Unit
1271 ```
1272 ---
1273 This is a
1274 multi-line summary!
1275 "#]],
1276 );
1277}
1278
1279#[test]
1280fn callable_headers_but_no_summary() {
1281 check(
1282 indoc! {r#"
1283 namespace Test {
1284 /// # Not The Summary
1285 /// This stuff is not the summary.
1286 /// # Also Not The Summary
1287 /// This stuff is also not the summary.
1288 operation ◉F↘oo◉() : Unit {}
1289 }
1290 "#},
1291 &expect![[r#"
1292 callable of `Test`
1293 ```qsharp
1294 operation Foo() : Unit
1295 ```
1296 ---
1297 # Not The Summary
1298 This stuff is not the summary.
1299 # Also Not The Summary
1300 This stuff is also not the summary.
1301 "#]],
1302 );
1303}
1304
1305#[test]
1306fn callable_summary_only_header_matches() {
1307 check(
1308 indoc! {r#"
1309 namespace Test {
1310 /// # Not The Summary
1311 /// This stuff is not the # Summary.
1312 /// # Summary
1313 /// This is a
1314 /// multi-line # Summary!
1315 /// # Also Not The Summary
1316 /// This stuff is also not the # Summary.
1317 operation ◉F↘oo◉() : Unit {}
1318 }
1319 "#},
1320 &expect![[r#"
1321 callable of `Test`
1322 ```qsharp
1323 operation Foo() : Unit
1324 ```
1325 ---
1326 This is a
1327 multi-line # Summary!
1328 "#]],
1329 );
1330}
1331
1332#[test]
1333fn callable_summary_successive_headers() {
1334 check(
1335 indoc! {r#"
1336 namespace Test {
1337 /// # Not The Summary
1338 /// # Summary
1339 /// This is a
1340 /// multi-line summary!
1341 operation ◉F↘oo◉() : Unit {}
1342 }
1343 "#},
1344 &expect![[r#"
1345 callable of `Test`
1346 ```qsharp
1347 operation Foo() : Unit
1348 ```
1349 ---
1350 This is a
1351 multi-line summary!
1352 "#]],
1353 );
1354}
1355
1356#[test]
1357fn callable_empty_summary() {
1358 check(
1359 indoc! {r#"
1360 namespace Test {
1361 /// # Not The Summary
1362 /// # Summary
1363 /// # Also Not The Summary
1364 operation ◉F↘oo◉() : Unit {}
1365 }
1366 "#},
1367 &expect![[r#"
1368 callable of `Test`
1369 ```qsharp
1370 operation Foo() : Unit
1371 ```
1372 "#]],
1373 );
1374}
1375
1376#[test]
1377fn callable_param_doc() {
1378 check(
1379 indoc! {r#"
1380 namespace Test {
1381
1382 /// Doc string
1383 /// # Summary
1384 /// This is the summary
1385 /// # Input
1386 /// Input string
1387 /// ## x
1388 /// Doc string for `x`
1389 /// ### Note
1390 /// note for `x`
1391 /// ## other
1392 /// Doc string for `other`
1393 /// # Last
1394 /// Last string
1395 operation Foo(x: Int) : Unit {
1396 let y = ◉↘x◉;
1397 }
1398 }
1399 "#},
1400 &expect![[r#"
1401 parameter of `Foo`
1402 ```qsharp
1403 x : Int
1404 ```
1405 ---
1406 Doc string for `x`
1407 ### Note
1408 note for `x`
1409 "#]],
1410 );
1411}
1412
1413#[test]
1414fn callable_generic_functor_display() {
1415 check(
1416 indoc! {"
1417 namespace Test {
1418 operation Foo(op : (Qubit => Unit is Adj)) : Unit {}
1419 operation Main() : Unit {
1420 ◉Fo↘o◉;
1421 }
1422 }
1423 "},
1424 &expect![[r#"
1425 callable of `Test`
1426 ```qsharp
1427 operation Foo(op : (Qubit => Unit is Adj)) : Unit
1428 ```
1429 "#]],
1430 );
1431}
1432
1433#[test]
1434fn udt_field_incorrect() {
1435 check_none(indoc! {r#"
1436 namespace Test {
1437 newtype Foo = (fst : Int, snd : Int);
1438 operation Bar() : Unit {
1439 let foo = Foo(1, 2);
1440 let x : Int = foo::◉n↘one◉;
1441 }
1442 }
1443 "#});
1444}
1445
1446#[test]
1447fn std_udt_return_type() {
1448 check(
1449 r#"
1450 namespace Test {
1451 open FakeStdLib;
1452 operation ◉Fo↘o◉() : Udt {
1453 }
1454 }
1455 "#,
1456 &expect![[r#"
1457 callable of `Test`
1458 ```qsharp
1459 operation Foo() : Udt
1460 ```
1461 "#]],
1462 );
1463}
1464
1465#[test]
1466fn std_callable_with_udt() {
1467 check(
1468 r#"
1469 namespace Test {
1470 open FakeStdLib;
1471 operation Foo() : Udt {
1472 ◉Takes↘Udt◉()
1473 }
1474 }
1475 "#,
1476 &expect![[r#"
1477 callable of `FakeStdLib`
1478 ```qsharp
1479 function TakesUdt(input : Udt) : Udt
1480 ```
1481 "#]],
1482 );
1483}
1484
1485#[test]
1486fn struct_field_incorrect() {
1487 check_none(indoc! {r#"
1488 namespace Test {
1489 struct Foo { fst : Int, snd : Int }
1490 operation Bar() : Unit {
1491 let foo = new Foo { fst = 1, snd = 2 };
1492 let x : Int = foo::◉n↘one◉;
1493 }
1494 }
1495 "#});
1496}
1497
1498#[test]
1499fn std_struct_return_type() {
1500 check(
1501 r#"
1502 namespace Test {
1503 open FakeStdLib;
1504 operation ◉Fo↘o◉() : FakeStruct {}
1505 }
1506 "#,
1507 &expect![[r#"
1508 callable of `Test`
1509 ```qsharp
1510 operation Foo() : FakeStruct
1511 ```
1512 "#]],
1513 );
1514}
1515
1516#[test]
1517fn std_callable_with_struct() {
1518 check(
1519 r#"
1520 namespace Test {
1521 open FakeStdLib;
1522 operation Foo() : Unit {
1523 ◉Takes↘Struct◉();
1524 }
1525 }
1526 "#,
1527 &expect![[r#"
1528 callable of `FakeStdLib`
1529 ```qsharp
1530 function TakesStruct(input : FakeStruct) : FakeStruct
1531 ```
1532 "#]],
1533 );
1534}
1535
1536#[test]
1537fn std_callable_with_type_param() {
1538 check(
1539 r#"
1540 namespace Test {
1541 open FakeStdLib;
1542 operation Foo() : Unit {
1543 let temp = ◉FakeWi↘thTypeParam◉(3);
1544 }
1545 }
1546 "#,
1547 &expect![[r#"
1548 callable of `FakeStdLib`
1549 ```qsharp
1550 operation FakeWithTypeParam<'A>(a : 'A) : 'A
1551 ```
1552 "#]],
1553 );
1554}
1555
1556#[test]
1557fn std_udt_udt_field() {
1558 check(
1559 r#"
1560 namespace Test {
1561 open FakeStdLib;
1562 operation Foo() : Udt {
1563 let f = UdtWrapper(TakesUdt);
1564 f::inner::◉x◉↘
1565 }
1566 }
1567 "#,
1568 &expect![[r#"
1569 field of `Udt`
1570 ```qsharp
1571 x : Int
1572 ```
1573 "#]],
1574 );
1575}
1576
1577#[test]
1578fn std_struct_struct_field() {
1579 check(
1580 r#"
1581 namespace Test {
1582 open FakeStdLib;
1583 operation Foo() : FakeStruct {
1584 let f = new StructWrapper { inner = new FakeStruct { x = 1, y = 2 } };
1585 f::inner::◉x◉↘
1586 }
1587 }
1588 "#,
1589 &expect![[r#"
1590 field of `FakeStruct`
1591 ```qsharp
1592 x : Int
1593 ```
1594 "#]],
1595 );
1596}
1597
1598#[test]
1599fn ty_param_def() {
1600 check(
1601 indoc! {r#"
1602 namespace Test {
1603 operation Foo<◉'↘T◉>(x : 'T) : 'T { x }
1604 }
1605 "#},
1606 &expect![[r#"
1607 type parameter of `Foo`
1608 ```qsharp
1609 'T
1610 ```
1611 "#]],
1612 );
1613}
1614
1615#[test]
1616fn ty_param_ref() {
1617 check(
1618 indoc! {r#"
1619 namespace Test {
1620 operation Foo<'T>(x : ◉'↘T◉) : 'T { x }
1621 }
1622 "#},
1623 &expect![[r#"
1624 type parameter of `Foo`
1625 ```qsharp
1626 'T
1627 ```
1628 "#]],
1629 );
1630}
1631
1632#[test]
1633fn notebook_callable_def_across_cells() {
1634 check_notebook(
1635 &[
1636 ("cell1", "operation Callee() : Unit {}"),
1637 ("cell2", "◉C↘allee◉();"),
1638 ],
1639 &expect![[r#"
1640 callable
1641 ```qsharp
1642 operation Callee() : Unit
1643 ```
1644 "#]],
1645 );
1646}
1647
1648#[test]
1649fn notebook_callable_defined_in_later_cell() {
1650 check_notebook_none(&[
1651 ("cell1", "C↘allee();"),
1652 ("cell2", "operation Callee() : Unit {}"),
1653 ]);
1654}
1655
1656#[test]
1657fn notebook_local_definition() {
1658 check_notebook(
1659 &[("cell1", "let x = 3;"), ("cell2", "let ◉↘y◉ = x + 1;")],
1660 &expect![[r#"
1661 local
1662 ```qsharp
1663 y : Int
1664 ```
1665 "#]],
1666 );
1667}
1668
1669#[test]
1670fn notebook_local_reference() {
1671 check_notebook(
1672 &[("cell1", "let x = 3;"), ("cell2", "let y = ◉↘x◉ + 1;")],
1673 &expect![[r#"
1674 local
1675 ```qsharp
1676 x : Int
1677 ```
1678 "#]],
1679 );
1680}
1681