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/debugger_tests.rs

237lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::interpret::Debugger;
5use crate::line_column::Encoding;
6use qsc_data_structures::language_features::LanguageFeatures;
7use qsc_eval::{output::CursorReceiver, StepAction, StepResult};
8use qsc_fir::fir::StmtId;
9use qsc_frontend::compile::SourceMap;
10use std::io::Cursor;
11
12fn get_breakpoint_ids(debugger: &Debugger, path: &str) -> Vec<StmtId> {
13 let mut bps = debugger.get_breakpoints(path);
14 bps.sort_by_key(|f| f.id);
15 let ids = bps.iter().map(|f| f.id.into()).collect::<Vec<_>>();
16 ids
17}
18
19fn expect_return(mut debugger: Debugger, expected: &str) {
20 let r = step_next(&mut debugger, &[]);
21 match r.0 {
22 Ok(StepResult::Return(value)) => assert_eq!(value.to_string(), expected),
23 Ok(v) => panic!("Expected Return, got {v:?}"),
24 Err(e) => panic!("Expected Return, got {e:?}"),
25 }
26}
27
28fn expect_bp(debugger: &mut Debugger, ids: &[StmtId], expected_id: StmtId) {
29 let r = step_next(debugger, ids);
30 match r.0 {
31 Ok(StepResult::BreakpointHit(actual_id)) => assert!(actual_id == expected_id),
32 Ok(v) => panic!("Expected BP, got {v:?}"),
33 Err(e) => panic!("Expected BP, got {e:?}"),
34 }
35}
36
37fn step_in(
38 debugger: &mut Debugger,
39 breakpoints: &[StmtId],
40) -> (Result<StepResult, Vec<crate::interpret::Error>>, String) {
41 step(debugger, breakpoints, qsc_eval::StepAction::In)
42}
43
44fn step_next(
45 debugger: &mut Debugger,
46 breakpoints: &[StmtId],
47) -> (Result<StepResult, Vec<crate::interpret::Error>>, String) {
48 step(debugger, breakpoints, qsc_eval::StepAction::Next)
49}
50
51fn step_out(
52 debugger: &mut Debugger,
53 breakpoints: &[StmtId],
54) -> (Result<StepResult, Vec<crate::interpret::Error>>, String) {
55 step(debugger, breakpoints, qsc_eval::StepAction::Out)
56}
57
58fn step(
59 debugger: &mut Debugger,
60 breakpoints: &[StmtId],
61 step: StepAction,
62) -> (Result<StepResult, Vec<crate::interpret::Error>>, String) {
63 let mut cursor = Cursor::new(Vec::<u8>::new());
64 let mut receiver = CursorReceiver::new(&mut cursor);
65 (
66 debugger.eval_step(&mut receiver, breakpoints, step),
67 receiver.dump(),
68 )
69}
70
71fn expect_next(debugger: &mut Debugger) {
72 let result = step_next(debugger, &[]);
73 match result.0 {
74 Ok(StepResult::Next) => (),
75 Ok(v) => panic!("Expected Next, got {v:?}"),
76 Err(e) => panic!("Expected Next, got {e:?}"),
77 }
78}
79
80fn expect_in(debugger: &mut Debugger) {
81 let result = step_in(debugger, &[]);
82 match result.0 {
83 Ok(StepResult::StepIn) => (),
84 Ok(v) => panic!("Expected StepIn, got {v:?}"),
85 Err(e) => panic!("Expected StepIn, got {e:?}"),
86 }
87}
88
89fn expect_out(debugger: &mut Debugger) {
90 let result = step_out(debugger, &[]);
91 match result.0 {
92 Ok(StepResult::StepOut) => (),
93 Ok(v) => panic!("Expected StepOut, got {v:?}"),
94 Err(e) => panic!("Expected StepOut, got {e:?}"),
95 }
96}
97
98#[cfg(test)]
99mod given_debugger {
100 use super::*;
101
102 static STEPPING_SOURCE: &str = r#"
103 namespace Test {
104 @EntryPoint()
105 operation A() : Int {
106 let d = B();
107 let e = d / 1;
108 e
109 }
110 operation B() : Int {
111 let g = 10;
112 let h = 20;
113 let l = C(g, h);
114 42
115 }
116 operation C(m: Int, n: Int) : Int {
117 let o = 42 - (m + n);
118 let p = (m + n) + o;
119 p
120 }
121 }"#;
122 #[cfg(test)]
123 mod step {
124 use qsc_data_structures::target::TargetCapabilityFlags;
125
126 use super::*;
127
128 #[test]
129 fn in_one_level_operation_works() -> Result<(), Vec<crate::interpret::Error>> {
130 use qsc_data_structures::language_features::LanguageFeatures;
131 let sources = SourceMap::new([("test".into(), STEPPING_SOURCE.into())], None);
132 let (std_id, store) =
133 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
134 let mut debugger = Debugger::new(
135 sources,
136 TargetCapabilityFlags::all(),
137 Encoding::Utf8,
138 LanguageFeatures::default(),
139 store,
140 &[(std_id, None)],
141 )?;
142 let ids = get_breakpoint_ids(&debugger, "test");
143 let expected_id = ids[0];
144 expect_bp(&mut debugger, &ids, expected_id);
145 expect_in(&mut debugger);
146 expect_next(&mut debugger);
147 expect_next(&mut debugger);
148 expect_next(&mut debugger);
149 expect_next(&mut debugger);
150 expect_next(&mut debugger);
151 let expected = "42";
152 expect_return(debugger, expected);
153 Ok(())
154 }
155
156 #[test]
157 fn next_crosses_operation_works() -> Result<(), Vec<crate::interpret::Error>> {
158 let sources = SourceMap::new([("test".into(), STEPPING_SOURCE.into())], None);
159 let (std_id, store) =
160 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
161 let mut debugger = Debugger::new(
162 sources,
163 TargetCapabilityFlags::all(),
164 Encoding::Utf8,
165 LanguageFeatures::default(),
166 store,
167 &[(std_id, None)],
168 )?;
169 let ids = get_breakpoint_ids(&debugger, "test");
170 let expected_id = ids[0];
171 expect_bp(&mut debugger, &ids, expected_id);
172 expect_next(&mut debugger);
173 expect_next(&mut debugger);
174 let expected = "42";
175 expect_return(debugger, expected);
176 Ok(())
177 }
178
179 #[test]
180 fn in_multiple_operations_works() -> Result<(), Vec<crate::interpret::Error>> {
181 let sources = SourceMap::new([("test".into(), STEPPING_SOURCE.into())], None);
182 let (std_id, store) =
183 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
184 let mut debugger = Debugger::new(
185 sources,
186 TargetCapabilityFlags::all(),
187 Encoding::Utf8,
188 LanguageFeatures::default(),
189 store,
190 &[(std_id, None)],
191 )?;
192 let ids = get_breakpoint_ids(&debugger, "test");
193 let expected_id = ids[0];
194 expect_bp(&mut debugger, &ids, expected_id);
195 expect_in(&mut debugger);
196 expect_next(&mut debugger);
197 expect_next(&mut debugger);
198 expect_in(&mut debugger);
199 expect_next(&mut debugger);
200 expect_next(&mut debugger);
201 expect_next(&mut debugger);
202 expect_next(&mut debugger);
203 expect_next(&mut debugger);
204 let expected = "42";
205 expect_return(debugger, expected);
206 Ok(())
207 }
208
209 #[test]
210 fn out_multiple_operations_works() -> Result<(), Vec<crate::interpret::Error>> {
211 let sources = SourceMap::new([("test".into(), STEPPING_SOURCE.into())], None);
212 let (std_id, store) =
213 crate::compile::package_store_with_stdlib(TargetCapabilityFlags::all());
214 let mut debugger = Debugger::new(
215 sources,
216 TargetCapabilityFlags::all(),
217 Encoding::Utf8,
218 LanguageFeatures::default(),
219 store,
220 &[(std_id, None)],
221 )?;
222 let ids = get_breakpoint_ids(&debugger, "test");
223 let expected_id = ids[0];
224 expect_bp(&mut debugger, &ids, expected_id);
225 expect_in(&mut debugger);
226 expect_next(&mut debugger);
227 expect_next(&mut debugger);
228 expect_in(&mut debugger);
229 expect_out(&mut debugger);
230 expect_out(&mut debugger);
231 expect_next(&mut debugger);
232 let expected = "42";
233 expect_return(debugger, expected);
234 Ok(())
235 }
236 }
237}
238