microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.23.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/language_service/src/hover/tests.rs

1654lines · 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_cons_ref() {
972 check(
973 indoc! {r#"
974 namespace Test {
975 struct Pair { fst : Int, snd : Int }
976 operation Foo() : Unit {
977 let a = new Pair { fst = 3, ◉s↘nd◉ = 4 };
978 }
979 }
980 "#},
981 &expect![[r#"
982 field of `Pair`
983 ```qsharp
984 snd : Int
985 ```
986 "#]],
987 );
988}
989
990#[test]
991fn struct_field_path_ref() {
992 check(
993 indoc! {r#"
994 namespace Test {
995 struct A { b : B }
996 struct B { c : C }
997 struct C { i : Int }
998 operation Foo(a : A) : Unit {
999 let x = a.b.◉↘c◉.i;
1000 }
1001 }
1002 "#},
1003 &expect![[r#"
1004 field of `B`
1005 ```qsharp
1006 c : C
1007 ```
1008 "#]],
1009 );
1010}
1011
1012#[test]
1013fn struct_field_path_first_ref() {
1014 check(
1015 indoc! {r#"
1016 namespace Test {
1017 struct A { b : B }
1018 struct B { c : C }
1019 struct C { i : Int }
1020 operation Foo(a : A) : Unit {
1021 let x = ◉↘a◉.b.c.i;
1022 }
1023 }
1024 "#},
1025 &expect![[r#"
1026 parameter of `Foo`
1027 ```qsharp
1028 a : A
1029 ```
1030 "#]],
1031 );
1032}
1033
1034#[test]
1035fn struct_field_path_with_expr_ref() {
1036 check(
1037 indoc! {r#"
1038 namespace Test {
1039 struct A { b : B }
1040 struct B { c : C }
1041 struct C { i : Int }
1042 operation Foo(a : A) : Unit {
1043 let x = { a.◉↘b◉ }.c.i;
1044 }
1045 }
1046 "#},
1047 &expect![[r#"
1048 field of `A`
1049 ```qsharp
1050 b : B
1051 ```
1052 "#]],
1053 );
1054}
1055
1056#[test]
1057fn primitive_type() {
1058 check_none(indoc! {r#"
1059 namespace Test {
1060 newtype Pair = (◉I↘nt◉, snd : Int);
1061 operation Foo() : Unit {
1062 let a = Pair(3, 4);
1063 let b = a::snd;
1064 }
1065 }
1066 "#});
1067}
1068
1069#[test]
1070fn foreign_call() {
1071 check(
1072 indoc! {r#"
1073 namespace Test {
1074 open FakeStdLib;
1075 operation Foo() : Unit {
1076 ◉F↘ake◉();
1077 }
1078 }
1079 "#},
1080 &expect![[r#"
1081 callable of `FakeStdLib`
1082 ```qsharp
1083 operation Fake() : Unit
1084 ```
1085 "#]],
1086 );
1087}
1088
1089#[test]
1090fn foreign_call_functors() {
1091 check(
1092 indoc! {r#"
1093 namespace Test {
1094 open FakeStdLib;
1095 operation Foo() : Unit {
1096 ◉F↘akeCtlAdj◉();
1097 }
1098 }
1099 "#},
1100 &expect![[r#"
1101 callable of `FakeStdLib`
1102 ```qsharp
1103 operation FakeCtlAdj() : Unit is Adj + Ctl
1104 ```
1105 "#]],
1106 );
1107}
1108
1109#[test]
1110fn foreign_call_with_param() {
1111 check(
1112 indoc! {r#"
1113 namespace Test {
1114 open FakeStdLib;
1115 operation Foo() : Unit {
1116 ◉FakeWi↘thParam◉(4);
1117 }
1118 }
1119 "#},
1120 &expect![[r#"
1121 callable of `FakeStdLib`
1122 ```qsharp
1123 operation FakeWithParam(x : Int) : Unit
1124 ```
1125 "#]],
1126 );
1127}
1128
1129#[test]
1130fn callable_summary() {
1131 check(
1132 indoc! {r#"
1133 namespace Test {
1134 /// # Summary
1135 /// This is a
1136 /// multi-line summary!
1137 operation ◉F↘oo◉() : Unit {}
1138 }
1139 "#},
1140 &expect![[r#"
1141 callable of `Test`
1142 ```qsharp
1143 operation Foo() : Unit
1144 ```
1145 ---
1146 This is a
1147 multi-line summary!
1148 "#]],
1149 );
1150}
1151
1152#[test]
1153fn callable_summary_stuff_before() {
1154 check(
1155 indoc! {r#"
1156 namespace Test {
1157 /// not the summary
1158 /// # Summary
1159 /// This is a
1160 /// multi-line summary!
1161 operation ◉F↘oo◉() : Unit {}
1162 }
1163 "#},
1164 &expect![[r#"
1165 callable of `Test`
1166 ```qsharp
1167 operation Foo() : Unit
1168 ```
1169 ---
1170 This is a
1171 multi-line summary!
1172 "#]],
1173 );
1174}
1175
1176#[test]
1177fn callable_summary_other_header_before() {
1178 check(
1179 indoc! {r#"
1180 namespace Test {
1181 /// # Not The Summary
1182 /// This stuff is not the summary.
1183 /// # Summary
1184 /// This is a
1185 /// multi-line summary!
1186 operation ◉F↘oo◉() : Unit {}
1187 }
1188 "#},
1189 &expect![[r#"
1190 callable of `Test`
1191 ```qsharp
1192 operation Foo() : Unit
1193 ```
1194 ---
1195 This is a
1196 multi-line summary!
1197 "#]],
1198 );
1199}
1200
1201#[test]
1202fn callable_summary_other_header_after() {
1203 check(
1204 indoc! {r#"
1205 namespace Test {
1206 /// # Summary
1207 /// This is a
1208 /// multi-line summary!
1209 /// # Not The Summary
1210 /// This stuff is not the summary.
1211 operation ◉F↘oo◉() : Unit {}
1212 }
1213 "#},
1214 &expect![[r#"
1215 callable of `Test`
1216 ```qsharp
1217 operation Foo() : Unit
1218 ```
1219 ---
1220 This is a
1221 multi-line summary!
1222 "#]],
1223 );
1224}
1225
1226#[test]
1227fn callable_summary_other_headers() {
1228 check(
1229 indoc! {r#"
1230 namespace Test {
1231 /// # Not The Summary
1232 /// This stuff is not the summary.
1233 /// # Summary
1234 /// This is a
1235 /// multi-line summary!
1236 /// # Also Not The Summary
1237 /// This stuff is also not the summary.
1238 operation ◉F↘oo◉() : Unit {}
1239 }
1240 "#},
1241 &expect![[r#"
1242 callable of `Test`
1243 ```qsharp
1244 operation Foo() : Unit
1245 ```
1246 ---
1247 This is a
1248 multi-line summary!
1249 "#]],
1250 );
1251}
1252
1253#[test]
1254fn callable_headers_but_no_summary() {
1255 check(
1256 indoc! {r#"
1257 namespace Test {
1258 /// # Not The Summary
1259 /// This stuff is not the summary.
1260 /// # Also Not The Summary
1261 /// This stuff is also not the summary.
1262 operation ◉F↘oo◉() : Unit {}
1263 }
1264 "#},
1265 &expect![[r#"
1266 callable of `Test`
1267 ```qsharp
1268 operation Foo() : Unit
1269 ```
1270 ---
1271 # Not The Summary
1272 This stuff is not the summary.
1273 # Also Not The Summary
1274 This stuff is also not the summary.
1275 "#]],
1276 );
1277}
1278
1279#[test]
1280fn callable_summary_only_header_matches() {
1281 check(
1282 indoc! {r#"
1283 namespace Test {
1284 /// # Not The Summary
1285 /// This stuff is not the # Summary.
1286 /// # Summary
1287 /// This is a
1288 /// multi-line # Summary!
1289 /// # Also Not The Summary
1290 /// This stuff is also not the # Summary.
1291 operation ◉F↘oo◉() : Unit {}
1292 }
1293 "#},
1294 &expect![[r#"
1295 callable of `Test`
1296 ```qsharp
1297 operation Foo() : Unit
1298 ```
1299 ---
1300 This is a
1301 multi-line # Summary!
1302 "#]],
1303 );
1304}
1305
1306#[test]
1307fn callable_summary_successive_headers() {
1308 check(
1309 indoc! {r#"
1310 namespace Test {
1311 /// # Not The Summary
1312 /// # Summary
1313 /// This is a
1314 /// multi-line summary!
1315 operation ◉F↘oo◉() : Unit {}
1316 }
1317 "#},
1318 &expect![[r#"
1319 callable of `Test`
1320 ```qsharp
1321 operation Foo() : Unit
1322 ```
1323 ---
1324 This is a
1325 multi-line summary!
1326 "#]],
1327 );
1328}
1329
1330#[test]
1331fn callable_empty_summary() {
1332 check(
1333 indoc! {r#"
1334 namespace Test {
1335 /// # Not The Summary
1336 /// # Summary
1337 /// # Also Not The Summary
1338 operation ◉F↘oo◉() : Unit {}
1339 }
1340 "#},
1341 &expect![[r#"
1342 callable of `Test`
1343 ```qsharp
1344 operation Foo() : Unit
1345 ```
1346 "#]],
1347 );
1348}
1349
1350#[test]
1351fn callable_param_doc() {
1352 check(
1353 indoc! {r#"
1354 namespace Test {
1355
1356 /// Doc string
1357 /// # Summary
1358 /// This is the summary
1359 /// # Input
1360 /// Input string
1361 /// ## x
1362 /// Doc string for `x`
1363 /// ### Note
1364 /// note for `x`
1365 /// ## other
1366 /// Doc string for `other`
1367 /// # Last
1368 /// Last string
1369 operation Foo(x: Int) : Unit {
1370 let y = ◉↘x◉;
1371 }
1372 }
1373 "#},
1374 &expect![[r#"
1375 parameter of `Foo`
1376 ```qsharp
1377 x : Int
1378 ```
1379 ---
1380 Doc string for `x`
1381 ### Note
1382 note for `x`
1383 "#]],
1384 );
1385}
1386
1387#[test]
1388fn callable_generic_functor_display() {
1389 check(
1390 indoc! {"
1391 namespace Test {
1392 operation Foo(op : (Qubit => Unit is Adj)) : Unit {}
1393 operation Main() : Unit {
1394 ◉Fo↘o◉;
1395 }
1396 }
1397 "},
1398 &expect![[r#"
1399 callable of `Test`
1400 ```qsharp
1401 operation Foo(op : (Qubit => Unit is Adj)) : Unit
1402 ```
1403 "#]],
1404 );
1405}
1406
1407#[test]
1408fn udt_field_incorrect() {
1409 check_none(indoc! {r#"
1410 namespace Test {
1411 newtype Foo = (fst : Int, snd : Int);
1412 operation Bar() : Unit {
1413 let foo = Foo(1, 2);
1414 let x : Int = foo::◉n↘one◉;
1415 }
1416 }
1417 "#});
1418}
1419
1420#[test]
1421fn std_udt_return_type() {
1422 check(
1423 r#"
1424 namespace Test {
1425 open FakeStdLib;
1426 operation ◉Fo↘o◉() : Udt {
1427 }
1428 }
1429 "#,
1430 &expect![[r#"
1431 callable of `Test`
1432 ```qsharp
1433 operation Foo() : Udt
1434 ```
1435 "#]],
1436 );
1437}
1438
1439#[test]
1440fn std_callable_with_udt() {
1441 check(
1442 r#"
1443 namespace Test {
1444 open FakeStdLib;
1445 operation Foo() : Udt {
1446 ◉Takes↘Udt◉()
1447 }
1448 }
1449 "#,
1450 &expect![[r#"
1451 callable of `FakeStdLib`
1452 ```qsharp
1453 function TakesUdt(input : Udt) : Udt
1454 ```
1455 "#]],
1456 );
1457}
1458
1459#[test]
1460fn struct_field_incorrect() {
1461 check_none(indoc! {r#"
1462 namespace Test {
1463 struct Foo { fst : Int, snd : Int }
1464 operation Bar() : Unit {
1465 let foo = new Foo { fst = 1, snd = 2 };
1466 let x : Int = foo::◉n↘one◉;
1467 }
1468 }
1469 "#});
1470}
1471
1472#[test]
1473fn std_struct_return_type() {
1474 check(
1475 r#"
1476 namespace Test {
1477 open FakeStdLib;
1478 operation ◉Fo↘o◉() : FakeStruct {}
1479 }
1480 "#,
1481 &expect![[r#"
1482 callable of `Test`
1483 ```qsharp
1484 operation Foo() : FakeStruct
1485 ```
1486 "#]],
1487 );
1488}
1489
1490#[test]
1491fn std_callable_with_struct() {
1492 check(
1493 r#"
1494 namespace Test {
1495 open FakeStdLib;
1496 operation Foo() : Unit {
1497 ◉Takes↘Struct◉();
1498 }
1499 }
1500 "#,
1501 &expect![[r#"
1502 callable of `FakeStdLib`
1503 ```qsharp
1504 function TakesStruct(input : FakeStruct) : FakeStruct
1505 ```
1506 "#]],
1507 );
1508}
1509
1510#[test]
1511fn std_callable_with_type_param() {
1512 check(
1513 r#"
1514 namespace Test {
1515 open FakeStdLib;
1516 operation Foo() : Unit {
1517 let temp = ◉FakeWi↘thTypeParam◉(3);
1518 }
1519 }
1520 "#,
1521 &expect![[r#"
1522 callable of `FakeStdLib`
1523 ```qsharp
1524 operation FakeWithTypeParam<'A>(a : 'A) : 'A
1525 ```
1526 "#]],
1527 );
1528}
1529
1530#[test]
1531fn std_udt_udt_field() {
1532 check(
1533 r#"
1534 namespace Test {
1535 open FakeStdLib;
1536 operation Foo() : Udt {
1537 let f = UdtWrapper(TakesUdt);
1538 f::inner::◉x◉↘
1539 }
1540 }
1541 "#,
1542 &expect![[r#"
1543 field of `Udt`
1544 ```qsharp
1545 x : Int
1546 ```
1547 "#]],
1548 );
1549}
1550
1551#[test]
1552fn std_struct_struct_field() {
1553 check(
1554 r#"
1555 namespace Test {
1556 open FakeStdLib;
1557 operation Foo() : FakeStruct {
1558 let f = new StructWrapper { inner = new FakeStruct { x = 1, y = 2 } };
1559 f::inner::◉x◉↘
1560 }
1561 }
1562 "#,
1563 &expect![[r#"
1564 field of `FakeStruct`
1565 ```qsharp
1566 x : Int
1567 ```
1568 "#]],
1569 );
1570}
1571
1572#[test]
1573fn ty_param_def() {
1574 check(
1575 indoc! {r#"
1576 namespace Test {
1577 operation Foo<◉'↘T◉>(x : 'T) : 'T { x }
1578 }
1579 "#},
1580 &expect![[r#"
1581 type parameter of `Foo`
1582 ```qsharp
1583 'T
1584 ```
1585 "#]],
1586 );
1587}
1588
1589#[test]
1590fn ty_param_ref() {
1591 check(
1592 indoc! {r#"
1593 namespace Test {
1594 operation Foo<'T>(x : ◉'↘T◉) : 'T { x }
1595 }
1596 "#},
1597 &expect![[r#"
1598 type parameter of `Foo`
1599 ```qsharp
1600 'T
1601 ```
1602 "#]],
1603 );
1604}
1605
1606#[test]
1607fn notebook_callable_def_across_cells() {
1608 check_notebook(
1609 &[
1610 ("cell1", "operation Callee() : Unit {}"),
1611 ("cell2", "◉C↘allee◉();"),
1612 ],
1613 &expect![[r#"
1614 callable
1615 ```qsharp
1616 operation Callee() : Unit
1617 ```
1618 "#]],
1619 );
1620}
1621
1622#[test]
1623fn notebook_callable_defined_in_later_cell() {
1624 check_notebook_none(&[
1625 ("cell1", "C↘allee();"),
1626 ("cell2", "operation Callee() : Unit {}"),
1627 ]);
1628}
1629
1630#[test]
1631fn notebook_local_definition() {
1632 check_notebook(
1633 &[("cell1", "let x = 3;"), ("cell2", "let ◉↘y◉ = x + 1;")],
1634 &expect![[r#"
1635 local
1636 ```qsharp
1637 y : Int
1638 ```
1639 "#]],
1640 );
1641}
1642
1643#[test]
1644fn notebook_local_reference() {
1645 check_notebook(
1646 &[("cell1", "let x = 3;"), ("cell2", "let y = ◉↘x◉ + 1;")],
1647 &expect![[r#"
1648 local
1649 ```qsharp
1650 x : Int
1651 ```
1652 "#]],
1653 );
1654}