microsoft/qdk

Public

mirrored fromhttps://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/debug/tests.rs

178lines · modecode

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