microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/telemmocks

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/interpret/debug/tests.rs

176lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use indoc::indoc;
5use miette::Result;
6use qsc_data_structures::{language_features::LanguageFeatures, target::TargetCapabilityFlags};
7use qsc_eval::{output::CursorReceiver, val::Value};
8use qsc_frontend::compile::SourceMap;
9use qsc_passes::PackageType;
10use std::io::Cursor;
11
12use crate::interpret::{Error, InterpretResult, Interpreter};
13
14fn line(interpreter: &mut Interpreter, line: impl AsRef<str>) -> (InterpretResult, String) {
15 let mut cursor = Cursor::new(Vec::<u8>::new());
16 let mut receiver = CursorReceiver::new(&mut cursor);
17 (
18 interpreter.eval_fragments(&mut receiver, line.as_ref()),
19 receiver.dump(),
20 )
21}
22
23fn eval(interpreter: &mut Interpreter) -> (Result<Value, Vec<Error>>, String) {
24 let mut cursor = Cursor::new(Vec::<u8>::new());
25 let mut receiver = CursorReceiver::new(&mut cursor);
26 (interpreter.eval_entry(&mut receiver), receiver.dump())
27}
28
29#[test]
30fn stack_traces_can_cross_eval_session_and_file_boundaries() {
31 let source1 = indoc! { r#"
32 namespace Test {
33 operation B(input : Int) : Unit is Adj {
34 body ... {
35 C(input)
36 }
37 adjoint invert;
38 }
39
40 operation C(input : Int) : Unit is Adj {
41 body ... {
42 1 / input;
43 }
44 adjoint self;
45 }
46 }
47 "#};
48 let source2 = indoc! { r#"
49 namespace Test2 {
50 open Test;
51 operation A(input : Int) : Unit is Adj {
52 body ... {
53 B(input)
54 }
55 adjoint invert;
56 }
57 }
58 "#};
59
60 let source_map = SourceMap::new(
61 [
62 ("1.qs".into(), source1.into()),
63 ("2.qs".into(), source2.into()),
64 ],
65 None,
66 );
67
68 let (std_id, store) = crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
69 let mut interpreter = Interpreter::new(
70 source_map,
71 PackageType::Lib,
72 TargetCapabilityFlags::all(),
73 LanguageFeatures::default(),
74 store,
75 &[(std_id, None)],
76 )
77 .expect("Failed to compile base environment.");
78
79 let (result, _) = line(
80 &mut interpreter,
81 "operation Z(input : Int) : Unit { Adjoint Test2.A(input); }",
82 );
83 result.expect("code should compile");
84
85 let (result, _output) = line(&mut interpreter, "Z(0)");
86
87 match result {
88 Ok(_) => panic!("Expected error"),
89 Err(e) => {
90 let stack_trace = e[0]
91 .stack_trace()
92 .as_ref()
93 .expect("code should have a valid stack trace");
94 let expectation = indoc! {r#"
95 Error: division by zero
96 Call stack:
97 at Adjoint Test.C in 1.qs
98 at Adjoint Test.B in 1.qs
99 at Adjoint Test2.A in 2.qs
100 at Z in line_0
101 "#};
102 assert_eq!(expectation, stack_trace);
103 }
104 }
105}
106
107#[test]
108fn stack_traces_can_cross_file_and_entry_boundaries() {
109 let source1 = indoc! { r#"
110 namespace Test {
111 operation B(input : Int) : Unit is Adj {
112 body ... {
113 C(input)
114 }
115 adjoint invert;
116 }
117
118 operation C(input : Int) : Unit is Adj {
119 body ... {
120 1 / input;
121 }
122 adjoint self;
123 }
124 }
125 "#};
126 let source2 = indoc! { r#"
127 namespace Test2 {
128 open Test;
129 operation A(input : Int) : Unit is Adj {
130 body ... {
131 B(input)
132 }
133 adjoint invert;
134 }
135 }
136 "#};
137
138 let source_map = SourceMap::new(
139 [
140 ("1.qs".into(), source1.into()),
141 ("2.qs".into(), source2.into()),
142 ],
143 Some("Adjoint Test2.A(0)".into()),
144 );
145
146 let (std_id, store) = crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
147 let mut interpreter = Interpreter::new(
148 source_map,
149 PackageType::Exe,
150 TargetCapabilityFlags::all(),
151 LanguageFeatures::default(),
152 store,
153 &[(std_id, None)],
154 )
155 .expect("Failed to compile base environment.");
156
157 let (result, _) = eval(&mut interpreter);
158
159 match result {
160 Ok(_) => panic!("Expected error"),
161 Err(e) => {
162 let stack_trace = e[0]
163 .stack_trace()
164 .as_ref()
165 .expect("code should have a valid stack trace");
166 let expectation = indoc! {r#"
167 Error: division by zero
168 Call stack:
169 at Adjoint Test.C in 1.qs
170 at Adjoint Test.B in 1.qs
171 at Adjoint Test2.A in 2.qs
172 "#};
173 assert_eq!(expectation, stack_trace);
174 }
175 }
176}
177