microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.1.3

Branches

Tags

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

Clone

HTTPS

Download ZIP

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

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