microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/pythontelem

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc/src/packages/tests.rs

298lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3use crate::{compile, LanguageFeatures, TargetCapabilityFlags};
4use expect_test::expect;
5use qsc_frontend::compile::{CompileUnit, SourceMap};
6use qsc_passes::PackageType;
7use qsc_project::{PackageInfo, Project};
8use rustc_hash::FxHashMap;
9use std::sync::Arc;
10
11fn mock_program() -> Project {
12 Project {
13 // Mock data for the ProgramConfig
14 package_graph_sources: qsc_project::PackageGraphSources {
15 root: qsc_project::PackageInfo {
16 sources: vec![(
17 Arc::from("test"),
18 Arc::from("@EntryPoint() operation Main() : Unit {}"),
19 )],
20 language_features: LanguageFeatures::default(),
21 dependencies: FxHashMap::from_iter(vec![(
22 Arc::from("SomeLibraryAlias"),
23 Arc::from("SomeLibraryKey"),
24 )]),
25 package_type: Some(qsc_project::PackageType::Exe),
26 },
27 packages: FxHashMap::from_iter(vec![(
28 Arc::from("SomeLibraryKey"),
29 PackageInfo {
30 sources: vec![(
31 Arc::from("librarymain"),
32 Arc::from("operation LibraryMain() : Unit {} export LibraryMain;"),
33 )],
34 language_features: LanguageFeatures::default(),
35 dependencies: FxHashMap::default(),
36 package_type: Some(qsc_project::PackageType::Lib),
37 },
38 )]),
39 },
40 lints: vec![],
41 errors: vec![],
42 path: "project/qsharp.json".into(),
43 name: "project".into(),
44 }
45}
46
47#[test]
48fn test_prepare_package_store() {
49 let program = mock_program();
50 let buildable_program = super::prepare_package_store(
51 TargetCapabilityFlags::default(),
52 program.package_graph_sources,
53 );
54
55 expect![[r"
56 []
57 "]]
58 .assert_debug_eq(&buildable_program.dependency_errors);
59
60 // compile the user code
61 let compiled = compile::compile(
62 &buildable_program.store,
63 &buildable_program.user_code_dependencies[..],
64 SourceMap::new(buildable_program.user_code.sources, None),
65 PackageType::Exe,
66 TargetCapabilityFlags::default(),
67 LanguageFeatures::default(),
68 );
69
70 let CompileUnit {
71 package,
72 ast,
73 errors,
74 ..
75 } = compiled.0;
76
77 expect![[r#"
78 Package:
79 entry expression: Expr 8 [0-0] [Type Unit]: Call:
80 Expr 7 [24-28] [Type Unit]: Var: Item 1
81 Expr 6 [28-30] [Type Unit]: Unit
82 Item 0 [0-40] (Public):
83 Namespace (Ident 5 [0-40] "test"): Item 1
84 Item 1 [0-40] (Internal):
85 Parent: 0
86 EntryPoint
87 Callable 0 [14-40] (operation):
88 name: Ident 1 [24-28] "Main"
89 input: Pat 2 [28-30] [Type Unit]: Unit
90 output: Unit
91 functors: empty set
92 body: SpecDecl 3 [14-40]: Impl:
93 Block 4 [38-40]: <empty>
94 adj: <none>
95 ctl: <none>
96 ctl-adj: <none>"#]]
97 .assert_eq(&package.to_string());
98 expect![[r#"
99 Package 0:
100 Namespace 1 [0-40] (Ident 2 [0-40] "test"):
101 Item 3 [0-40]:
102 Attr 4 [0-13] (Ident 5 [1-11] "EntryPoint"):
103 Expr 6 [11-13]: Unit
104 Callable 7 [14-40] (Operation):
105 name: Ident 8 [24-28] "Main"
106 input: Pat 9 [28-30]: Unit
107 output: Type 10 [33-37]: Path: Path 11 [33-37] (Ident 12 [33-37] "Unit")
108 body: Block: Block 13 [38-40]: <empty>"#]]
109 .assert_eq(&ast.package.to_string());
110 expect![[r"
111 []
112 "]]
113 .assert_debug_eq(&errors);
114}
115
116// if there are inconsequential errors in the dependency compilation process, we don't want to
117// abort compilation. This way, we can still show the user some diagnostics.
118
119#[test]
120fn missing_dependency_doesnt_force_failure() {
121 let mut program = mock_program();
122 program
123 .package_graph_sources
124 .root
125 .dependencies
126 .insert("NonExistent".into(), "nonexistent-dep-key".into());
127
128 let buildable_program = super::prepare_package_store(
129 TargetCapabilityFlags::default(),
130 program.package_graph_sources,
131 );
132
133 expect![[r"
134 []
135 "]]
136 .assert_debug_eq(&buildable_program.dependency_errors);
137
138 // compile the user code
139 let compiled = compile::compile(
140 &buildable_program.store,
141 &buildable_program.user_code_dependencies[..],
142 SourceMap::new(buildable_program.user_code.sources, None),
143 PackageType::Exe,
144 TargetCapabilityFlags::default(),
145 LanguageFeatures::default(),
146 );
147
148 let CompileUnit {
149 package,
150 ast,
151 errors,
152 ..
153 } = compiled.0;
154
155 expect![[r#"
156 Package:
157 entry expression: Expr 8 [0-0] [Type Unit]: Call:
158 Expr 7 [24-28] [Type Unit]: Var: Item 1
159 Expr 6 [28-30] [Type Unit]: Unit
160 Item 0 [0-40] (Public):
161 Namespace (Ident 5 [0-40] "test"): Item 1
162 Item 1 [0-40] (Internal):
163 Parent: 0
164 EntryPoint
165 Callable 0 [14-40] (operation):
166 name: Ident 1 [24-28] "Main"
167 input: Pat 2 [28-30] [Type Unit]: Unit
168 output: Unit
169 functors: empty set
170 body: SpecDecl 3 [14-40]: Impl:
171 Block 4 [38-40]: <empty>
172 adj: <none>
173 ctl: <none>
174 ctl-adj: <none>"#]]
175 .assert_eq(&package.to_string());
176 expect![[r#"
177 Package 0:
178 Namespace 1 [0-40] (Ident 2 [0-40] "test"):
179 Item 3 [0-40]:
180 Attr 4 [0-13] (Ident 5 [1-11] "EntryPoint"):
181 Expr 6 [11-13]: Unit
182 Callable 7 [14-40] (Operation):
183 name: Ident 8 [24-28] "Main"
184 input: Pat 9 [28-30]: Unit
185 output: Type 10 [33-37]: Path: Path 11 [33-37] (Ident 12 [33-37] "Unit")
186 body: Block: Block 13 [38-40]: <empty>"#]]
187 .assert_eq(&ast.package.to_string());
188 expect![[r"
189 []
190 "]]
191 .assert_debug_eq(&errors);
192}
193
194#[allow(clippy::too_many_lines)]
195#[test]
196fn dependency_error() {
197 let mut program = mock_program();
198 // Inject a syntax error into one of the dependencies
199 program
200 .package_graph_sources
201 .packages
202 .values_mut()
203 .next()
204 .expect("expected at least one dependency in the mock program")
205 .sources[0]
206 .1 = "broken_syntax".into();
207
208 let buildable_program = super::prepare_package_store(
209 TargetCapabilityFlags::default(),
210 program.package_graph_sources,
211 );
212
213 expect![[r#"
214 [
215 WithSource {
216 sources: [
217 Source {
218 name: "librarymain",
219 contents: "broken_syntax",
220 offset: 0,
221 },
222 ],
223 error: Frontend(
224 Error(
225 Parse(
226 Error(
227 Token(
228 Eof,
229 Ident,
230 Span {
231 lo: 0,
232 hi: 13,
233 },
234 ),
235 ),
236 ),
237 ),
238 ),
239 },
240 ]
241 "#]]
242 .assert_debug_eq(&buildable_program.dependency_errors);
243
244 // compile the user code
245 let compiled = compile::compile(
246 &buildable_program.store,
247 &buildable_program.user_code_dependencies[..],
248 SourceMap::new(buildable_program.user_code.sources, None),
249 PackageType::Exe,
250 TargetCapabilityFlags::default(),
251 LanguageFeatures::default(),
252 );
253
254 let CompileUnit {
255 package,
256 ast,
257 errors,
258 ..
259 } = compiled.0;
260
261 expect![[r#"
262 Package:
263 entry expression: Expr 8 [0-0] [Type Unit]: Call:
264 Expr 7 [24-28] [Type Unit]: Var: Item 1
265 Expr 6 [28-30] [Type Unit]: Unit
266 Item 0 [0-40] (Public):
267 Namespace (Ident 5 [0-40] "test"): Item 1
268 Item 1 [0-40] (Internal):
269 Parent: 0
270 EntryPoint
271 Callable 0 [14-40] (operation):
272 name: Ident 1 [24-28] "Main"
273 input: Pat 2 [28-30] [Type Unit]: Unit
274 output: Unit
275 functors: empty set
276 body: SpecDecl 3 [14-40]: Impl:
277 Block 4 [38-40]: <empty>
278 adj: <none>
279 ctl: <none>
280 ctl-adj: <none>"#]]
281 .assert_eq(&package.to_string());
282 expect![[r#"
283 Package 0:
284 Namespace 1 [0-40] (Ident 2 [0-40] "test"):
285 Item 3 [0-40]:
286 Attr 4 [0-13] (Ident 5 [1-11] "EntryPoint"):
287 Expr 6 [11-13]: Unit
288 Callable 7 [14-40] (Operation):
289 name: Ident 8 [24-28] "Main"
290 input: Pat 9 [28-30]: Unit
291 output: Type 10 [33-37]: Path: Path 11 [33-37] (Ident 12 [33-37] "Unit")
292 body: Block: Block 13 [38-40]: <empty>"#]]
293 .assert_eq(&ast.package.to_string());
294 expect![[r"
295 []
296 "]]
297 .assert_debug_eq(&errors);
298}
299