microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
cesarzc/try-rca-array-assign-improvement

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/interpret/debugger_tests.rs

239lines · modecode

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