microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.25.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/language_service/src/definition/tests.rs

784lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use expect_test::{Expect, expect};
5use qsc::location::Location;
6
7use super::get_definition;
8use crate::{
9 Encoding,
10 test_utils::{compile_notebook_with_markers, compile_with_markers},
11};
12
13/// Asserts that the definition given at the cursor position matches the expected range.
14/// The cursor position is indicated by a `↘` marker in the source text.
15/// The expected definition range is indicated by `◉` markers in the source text.
16fn assert_definition(source_with_markers: &str) {
17 let (compilation, cursor_position, target_spans) =
18 compile_with_markers(source_with_markers, true);
19 let actual_definition =
20 get_definition(&compilation, "<source>", cursor_position, Encoding::Utf8);
21 let expected_definition = if target_spans.is_empty() {
22 None
23 } else {
24 Some(Location {
25 source: "<source>".into(),
26 range: target_spans[0],
27 })
28 };
29 assert_eq!(&expected_definition, &actual_definition);
30}
31
32fn assert_definition_notebook(cells_with_markers: &[(&str, &str)]) {
33 let (compilation, cell_uri, position, target_spans) =
34 compile_notebook_with_markers(cells_with_markers);
35 let actual_definition = get_definition(&compilation, &cell_uri, position, Encoding::Utf8);
36 let expected_definition = if target_spans.is_empty() {
37 None
38 } else {
39 Some(target_spans[0].clone())
40 };
41 assert_eq!(&expected_definition, &actual_definition);
42}
43
44fn check(source_with_markers: &str, expect: &Expect) {
45 let (compilation, cursor_position, _) = compile_with_markers(source_with_markers, true);
46 let actual_definition =
47 get_definition(&compilation, "<source>", cursor_position, Encoding::Utf8);
48 expect.assert_debug_eq(&actual_definition);
49}
50
51#[test]
52fn callable() {
53 assert_definition(
54 r#"
55 namespace Test {
56 operation ◉F↘oo◉() : Unit {
57 }
58 }
59 "#,
60 );
61}
62
63#[test]
64fn callable_ref() {
65 assert_definition(
66 r#"
67 namespace Test {
68 operation ◉Callee◉() : Unit {
69 }
70
71 operation Caller() : Unit {
72 C↘allee();
73 }
74 }
75 "#,
76 );
77}
78
79#[test]
80fn variable() {
81 assert_definition(
82 r#"
83 namespace Test {
84 operation Foo() : Unit {
85 let ◉↘x◉ = 3;
86 }
87 }
88 "#,
89 );
90}
91
92#[test]
93fn variable_ref() {
94 assert_definition(
95 r#"
96 namespace Test {
97 operation Foo() : Unit {
98 let ◉x◉ = 3;
99 let y = ↘x;
100 }
101 }
102 "#,
103 );
104}
105
106#[test]
107fn parameter() {
108 assert_definition(
109 r#"
110 namespace Test {
111 operation Foo(◉↘x◉: Int) : Unit {
112 }
113 }
114 "#,
115 );
116}
117
118#[test]
119fn parameter_ref() {
120 assert_definition(
121 r#"
122 namespace Test {
123 operation Foo(◉x◉: Int) : Unit {
124 let y = ↘x;
125 }
126 }
127 "#,
128 );
129}
130
131#[test]
132fn udt() {
133 assert_definition(
134 r#"
135 namespace Test {
136 newtype ◉B↘ar◉ = (a: Int, b: Double);
137 }
138 "#,
139 );
140}
141
142#[test]
143fn udt_ref() {
144 assert_definition(
145 r#"
146 namespace Test {
147 newtype ◉Bar◉ = (a: Int, b: Double);
148
149 operation Foo() : Unit {
150 let x = B↘ar(1, 2.3);
151 }
152 }
153 "#,
154 );
155}
156
157#[test]
158fn udt_ref_sig() {
159 assert_definition(
160 r#"
161 namespace Test {
162 newtype ◉Bar◉ = (a: Int, b: Double);
163
164 operation Foo() : B↘ar {
165 Bar(1, 2.3)
166 }
167 }
168 "#,
169 );
170}
171
172#[test]
173fn udt_ref_param() {
174 assert_definition(
175 r#"
176 namespace Test {
177 newtype ◉Bar◉ = (a: Int, b: Double);
178
179 operation Foo(x: B↘ar) : Unit {
180 }
181 }
182 "#,
183 );
184}
185
186#[test]
187fn udt_ref_anno() {
188 assert_definition(
189 r#"
190 namespace Test {
191 newtype ◉Bar◉ = (a: Int, b: Double);
192
193 operation Foo() : Unit {
194 let x: B↘ar = Bar(1, 2.3);
195 }
196 }
197 "#,
198 );
199}
200
201#[test]
202fn udt_ref_ty_def() {
203 assert_definition(
204 r#"
205 namespace Test {
206 newtype ◉Bar◉ = (a: Int, b: Double);
207 newtype Foo = (a: B↘ar, b: Double);
208 }
209 "#,
210 );
211}
212
213#[test]
214fn udt_field() {
215 assert_definition(
216 r#"
217 namespace Test {
218 newtype Pair = (◉f↘st◉: Int, snd: Double);
219 }
220 "#,
221 );
222}
223
224#[test]
225fn udt_field_ref() {
226 assert_definition(
227 r#"
228 namespace Test {
229 newtype Pair = (fst: Int, ◉snd◉: Double);
230 operation Foo() : Unit {
231 let a = Pair(1, 2.3);
232 let b = a::s↘nd;
233 }
234 }
235 "#,
236 );
237}
238
239#[test]
240fn struct_def() {
241 assert_definition(
242 r#"
243 namespace Test {
244 struct ◉B↘ar◉ { a : Int, b : Double }
245 }
246 "#,
247 );
248}
249
250#[test]
251fn struct_ref() {
252 assert_definition(
253 r#"
254 namespace Test {
255 struct ◉Bar◉ { a : Int, b : Double }
256
257 operation Foo() : Unit {
258 let x = new B↘ar { a = 1, b = 2.3 };
259 }
260 }
261 "#,
262 );
263}
264
265#[test]
266fn struct_ref_sig() {
267 assert_definition(
268 r#"
269 namespace Test {
270 struct ◉Bar◉ { a : Int, b : Double }
271
272 operation Foo() : B↘ar {
273 new Bar { a = 1, b = 2.3 }
274 }
275 }
276 "#,
277 );
278}
279
280#[test]
281fn struct_ref_param() {
282 assert_definition(
283 r#"
284 namespace Test {
285 struct ◉Bar◉ { a : Int, b : Double }
286 operation Foo(x: B↘ar) : Unit {}
287 }
288 "#,
289 );
290}
291
292#[test]
293fn struct_ref_anno() {
294 assert_definition(
295 r#"
296 namespace Test {
297 struct ◉Bar◉ { a : Int, b : Double }
298
299 operation Foo() : Unit {
300 let x: B↘ar = new Bar { a = 1, b = 2.3 };
301 }
302 }
303 "#,
304 );
305}
306
307#[test]
308fn struct_ref_ty_def() {
309 assert_definition(
310 r#"
311 namespace Test {
312 struct ◉Bar◉ { a : Int, b : Double }
313 newtype Foo = (a: B↘ar, b: Double);
314 }
315 "#,
316 );
317}
318
319#[test]
320fn struct_ref_struct_def() {
321 assert_definition(
322 r#"
323 namespace Test {
324 struct ◉Bar◉ { a : Int, b : Double }
325 struct Foo { a : B↘ar, b : Double }
326 }
327 "#,
328 );
329}
330
331#[test]
332fn struct_field() {
333 assert_definition(
334 r#"
335 namespace Test {
336 struct Pair { ◉f↘st◉ : Int, snd : Double }
337 }
338 "#,
339 );
340}
341
342#[test]
343fn struct_field_ref() {
344 assert_definition(
345 r#"
346 namespace Test {
347 struct Pair { fst : Int, ◉snd◉ : Double }
348 operation Foo() : Unit {
349 let a = new Pair { fst = 1, snd = 2.3 };
350 let b = a::s↘nd;
351 }
352 }
353 "#,
354 );
355}
356
357#[test]
358fn struct_field_ref_cons() {
359 assert_definition(
360 r#"
361 namespace Test {
362 struct Pair { fst : Int, ◉snd◉ : Double }
363 operation Foo() : Unit {
364 let a = new Pair { fst = 1, s↘nd = 2.3 };
365 }
366 }
367 "#,
368 );
369}
370
371#[test]
372fn struct_field_ref_path() {
373 assert_definition(
374 r#"
375 namespace Test {
376 struct A { b : B }
377 struct B { ◉c◉ : C }
378 struct C { i : Int }
379 operation Foo(a : A) : Unit {
380 let x = a.b.↘c.i;
381 }
382 }
383 "#,
384 );
385}
386
387#[test]
388fn struct_field_ref_path_with_expr() {
389 assert_definition(
390 r#"
391 namespace Test {
392 struct A { b : B }
393 struct B { ◉c◉ : C }
394 struct C { i : Int }
395 operation Foo(a : A) : Unit {
396 let x = { a.b }.↘c.i;
397 }
398 }
399 "#,
400 );
401}
402
403#[test]
404fn struct_field_ref_path_inside_expr() {
405 assert_definition(
406 r#"
407 namespace Test {
408 struct A { ◉b◉ : B }
409 struct B { c : C }
410 struct C { i : Int }
411 operation Foo(a : A) : Unit {
412 let x = { a.↘b }.c.i;
413 }
414 }
415 "#,
416 );
417}
418
419#[test]
420fn lambda_param() {
421 assert_definition(
422 r#"
423 namespace Test {
424 operation Foo() : Unit {
425 let local = (◉↘x◉, y) => x;
426 let z = local(1, 2.3);
427 }
428 }
429 "#,
430 );
431}
432
433#[test]
434fn lambda_param_ref() {
435 assert_definition(
436 r#"
437 namespace Test {
438 operation Foo() : Unit {
439 let local = (◉x◉, y) => ↘x;
440 let z = local(1, 2.3);
441 }
442 }
443 "#,
444 );
445}
446
447#[test]
448fn lambda_closure_ref() {
449 assert_definition(
450 r#"
451 namespace Test {
452 operation Foo() : Unit {
453 let ◉a◉ = "Hello";
454 let local = (x, y) => ↘a;
455 let z = local(1, 2.3);
456 }
457 }
458 "#,
459 );
460}
461
462#[test]
463fn std_call() {
464 check(
465 r#"
466 namespace Test {
467 open FakeStdLib;
468 operation Foo() : Unit {
469 F↘ake();
470 }
471 }
472 "#,
473 &expect![[r#"
474 Some(
475 Location {
476 source: "qsharp-library-source:<std>",
477 range: Range {
478 start: Position {
479 line: 2,
480 column: 18,
481 },
482 end: Position {
483 line: 2,
484 column: 22,
485 },
486 },
487 },
488 )
489 "#]],
490 );
491}
492
493#[test]
494fn other_namespace_call_ref() {
495 assert_definition(
496 r#"
497 namespace Test {
498 open Other;
499 operation Foo() : Unit {
500 B↘ar();
501 }
502 }
503
504 namespace Other {
505 operation ◉Bar◉() : Unit {}
506 }
507 "#,
508 );
509}
510
511#[test]
512fn parameter_ref_with_body_specialization() {
513 assert_definition(
514 r#"
515 namespace Test {
516 operation Foo(◉x◉: Int) : Unit is Adj {
517 body ... {
518 let y = ↘x;
519 }
520 }
521 }
522 "#,
523 );
524}
525
526#[test]
527fn parameter_ref_with_adj_specialization() {
528 assert_definition(
529 r#"
530 namespace Test {
531 operation Foo(◉x◉: Int) : Unit is Adj {
532 body ... {}
533 adjoint ... {
534 let y = ↘x;
535 }
536 }
537 }
538 "#,
539 );
540}
541
542#[test]
543fn ctl_specialization_parameter() {
544 assert_definition(
545 r#"
546 namespace Test {
547 operation Foo(x: Int) : Unit is Ctl {
548 body ... {}
549 controlled (◉c↘s◉, ...) {}
550 }
551 }
552 "#,
553 );
554}
555
556#[test]
557fn ctl_specialization_parameter_ref() {
558 assert_definition(
559 r#"
560 namespace Test {
561 operation Foo(x: Int) : Unit is Ctl {
562 body ... {}
563 controlled (◉cs◉, ...) {
564 let y = c↘s;
565 }
566 }
567 }
568 "#,
569 );
570}
571
572#[test]
573fn std_udt() {
574 check(
575 r#"
576 namespace Test {
577 operation Foo() : FakeStdLib.Ud↘t {
578 }
579 }
580 "#,
581 &expect![[r#"
582 Some(
583 Location {
584 source: "qsharp-library-source:<std>",
585 range: Range {
586 start: Position {
587 line: 5,
588 column: 16,
589 },
590 end: Position {
591 line: 5,
592 column: 19,
593 },
594 },
595 },
596 )
597 "#]],
598 );
599}
600
601#[test]
602fn std_udt_udt_field() {
603 check(
604 r#"
605 namespace Test {
606 open FakeStdLib;
607 operation Foo() : Udt {
608 let f = UdtWrapper(TakesUdt);
609 f::inner::x↘
610 }
611 }
612 "#,
613 &expect![[r#"
614 Some(
615 Location {
616 source: "qsharp-library-source:<std>",
617 range: Range {
618 start: Position {
619 line: 5,
620 column: 23,
621 },
622 end: Position {
623 line: 5,
624 column: 24,
625 },
626 },
627 },
628 )
629 "#]],
630 );
631}
632
633#[test]
634fn ty_param_def() {
635 assert_definition(
636 r#"
637 namespace Test {
638 operation Foo<◉'↘T◉>(x : 'T) : 'T { x }
639 }
640 "#,
641 );
642}
643
644#[test]
645fn ty_param_ref() {
646 assert_definition(
647 r#"
648 namespace Test {
649 operation Foo<◉'T◉>(x : '↘T) : 'T { x }
650 }
651 "#,
652 );
653}
654
655#[test]
656fn notebook_callable_def_across_cells() {
657 assert_definition_notebook(&[
658 ("cell1", "operation ◉Callee◉() : Unit {}"),
659 ("cell2", "C↘allee();"),
660 ]);
661}
662
663#[test]
664fn notebook_callable_defined_in_later_cell() {
665 assert_definition_notebook(&[
666 ("cell1", "C↘allee();"),
667 ("cell2", "operation Callee() : Unit {}"),
668 ]);
669}
670
671#[test]
672fn notebook_local_from_same_cell() {
673 assert_definition_notebook(&[("cell1", "let ◉x◉ = 3; let y = ↘x + 1;")]);
674}
675
676#[test]
677fn notebook_local_from_later_cell() {
678 assert_definition_notebook(&[
679 ("cell1", "let ◉x◉ = 3; let y = x + 1;"),
680 ("cell2", "let z = ↘x + 2;"),
681 ]);
682}
683
684#[test]
685fn item_export() {
686 assert_definition(
687 r#"
688 namespace Test {
689 operation ◉Foo◉() : Unit {
690 }
691 export Fo↘o;
692 }
693 "#,
694 );
695}
696
697#[test]
698fn item_export_with_alias_on_path() {
699 assert_definition(
700 r#"
701 namespace Test {
702 operation ◉Foo◉() : Unit {
703 }
704 export Fo↘o as Bar;
705 }
706 "#,
707 );
708}
709
710#[test]
711fn item_export_with_alias_on_alias() {
712 assert_definition(
713 r#"
714 namespace Test {
715 operation ◉Foo◉() : Unit {
716 }
717 export Foo as B↘ar;
718 }
719 "#,
720 );
721}
722
723#[test]
724fn item_import() {
725 assert_definition(
726 r#"
727 namespace Test {
728 operation ◉Foo◉() : Unit {
729 }
730 }
731 namespace Other {
732 import X, Test.Fo↘o;
733 }
734 "#,
735 );
736}
737
738#[test]
739fn item_import_incomplete() {
740 assert_definition(
741 r#"
742 namespace Test {
743 operation ◉Foo◉() : Unit {
744 }
745 }
746 namespace Other {
747 import X, Test.Foo↘
748 }
749 "#,
750 );
751}
752
753#[test]
754fn item_import_alias() {
755 assert_definition(
756 r#"
757 namespace Test {
758 operation ◉Foo◉() : Unit {
759 }
760 }
761 namespace Other {
762 import Test.Foo as B↘ar;
763 }
764 "#,
765 );
766}
767
768#[test]
769fn item_import_alias_usage() {
770 assert_definition(
771 r#"
772 namespace Test {
773 operation ◉Foo◉() : Unit {
774 }
775 }
776 namespace Other {
777 import Test.Foo as Bar;
778 operation Baz() : Unit {
779 let x = Ba↘r();
780 }
781 }
782 "#,
783 );
784}
785