]>
Commit | Line | Data |
---|---|---|
9fa01778 XL |
1 | use crate::source_map::{SourceMap, FilePathMapping}; |
2 | use crate::with_globals; | |
3 | ||
476ff2be SL |
4 | use errors::Handler; |
5 | use errors::emitter::EmitterWriter; | |
9fa01778 | 6 | |
476ff2be SL |
7 | use std::io; |
8 | use std::io::prelude::*; | |
0531ce1d | 9 | use rustc_data_structures::sync::Lrc; |
476ff2be SL |
10 | use std::str; |
11 | use std::sync::{Arc, Mutex}; | |
ff7c6d11 | 12 | use std::path::Path; |
476ff2be SL |
13 | use syntax_pos::{BytePos, NO_EXPANSION, Span, MultiSpan}; |
14 | ||
15 | /// Identify a position in the text by the Nth occurrence of a string. | |
16 | struct Position { | |
17 | string: &'static str, | |
18 | count: usize, | |
19 | } | |
20 | ||
21 | struct SpanLabel { | |
22 | start: Position, | |
23 | end: Position, | |
24 | label: &'static str, | |
25 | } | |
26 | ||
27 | struct Shared<T: Write> { | |
28 | data: Arc<Mutex<T>>, | |
29 | } | |
30 | ||
31 | impl<T: Write> Write for Shared<T> { | |
32 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
33 | self.data.lock().unwrap().write(buf) | |
34 | } | |
35 | ||
36 | fn flush(&mut self) -> io::Result<()> { | |
37 | self.data.lock().unwrap().flush() | |
38 | } | |
39 | } | |
40 | ||
41 | fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) { | |
0531ce1d XL |
42 | with_globals(|| { |
43 | let output = Arc::new(Mutex::new(Vec::new())); | |
44 | ||
a1dfa0c6 XL |
45 | let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); |
46 | source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned()); | |
0531ce1d XL |
47 | |
48 | let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end); | |
49 | let mut msp = MultiSpan::from_span(primary_span); | |
50 | for span_label in span_labels { | |
51 | let span = make_span(&file_text, &span_label.start, &span_label.end); | |
52 | msp.push_span_label(span, span_label.label.to_string()); | |
53 | println!("span: {:?} label: {:?}", span, span_label.label); | |
a1dfa0c6 | 54 | println!("text: {:?}", source_map.span_to_snippet(span)); |
0531ce1d | 55 | } |
476ff2be | 56 | |
0531ce1d | 57 | let emitter = EmitterWriter::new(Box::new(Shared { data: output.clone() }), |
a1dfa0c6 | 58 | Some(source_map.clone()), |
0531ce1d XL |
59 | false, |
60 | false); | |
61 | let handler = Handler::with_emitter(true, false, Box::new(emitter)); | |
62 | handler.span_err(msp, "foo"); | |
476ff2be | 63 | |
0531ce1d XL |
64 | assert!(expected_output.chars().next() == Some('\n'), |
65 | "expected output should begin with newline"); | |
66 | let expected_output = &expected_output[1..]; | |
476ff2be | 67 | |
0531ce1d XL |
68 | let bytes = output.lock().unwrap(); |
69 | let actual_output = str::from_utf8(&bytes).unwrap(); | |
70 | println!("expected output:\n------\n{}------", expected_output); | |
71 | println!("actual output:\n------\n{}------", actual_output); | |
476ff2be | 72 | |
0531ce1d XL |
73 | assert!(expected_output == actual_output) |
74 | }) | |
476ff2be SL |
75 | } |
76 | ||
77 | fn make_span(file_text: &str, start: &Position, end: &Position) -> Span { | |
78 | let start = make_pos(file_text, start); | |
79 | let end = make_pos(file_text, end) + end.string.len(); // just after matching thing ends | |
80 | assert!(start <= end); | |
ea8adc8c | 81 | Span::new(BytePos(start as u32), BytePos(end as u32), NO_EXPANSION) |
476ff2be SL |
82 | } |
83 | ||
84 | fn make_pos(file_text: &str, pos: &Position) -> usize { | |
85 | let mut remainder = file_text; | |
86 | let mut offset = 0; | |
87 | for _ in 0..pos.count { | |
88 | if let Some(n) = remainder.find(&pos.string) { | |
89 | offset += n; | |
90 | remainder = &remainder[n + 1..]; | |
91 | } else { | |
92 | panic!("failed to find {} instances of {:?} in {:?}", | |
93 | pos.count, | |
94 | pos.string, | |
95 | file_text); | |
96 | } | |
97 | } | |
98 | offset | |
99 | } | |
100 | ||
101 | #[test] | |
102 | fn ends_on_col0() { | |
103 | test_harness(r#" | |
104 | fn foo() { | |
105 | } | |
106 | "#, | |
107 | vec![ | |
108 | SpanLabel { | |
109 | start: Position { | |
110 | string: "{", | |
111 | count: 1, | |
112 | }, | |
113 | end: Position { | |
114 | string: "}", | |
115 | count: 1, | |
116 | }, | |
117 | label: "test", | |
118 | }, | |
119 | ], | |
120 | r#" | |
121 | error: foo | |
122 | --> test.rs:2:10 | |
123 | | | |
124 | 2 | fn foo() { | |
cc61c64b | 125 | | __________^ |
476ff2be | 126 | 3 | | } |
cc61c64b | 127 | | |_^ test |
476ff2be SL |
128 | |
129 | "#); | |
130 | } | |
131 | ||
132 | #[test] | |
133 | fn ends_on_col2() { | |
134 | test_harness(r#" | |
135 | fn foo() { | |
136 | ||
137 | ||
138 | } | |
139 | "#, | |
140 | vec![ | |
141 | SpanLabel { | |
142 | start: Position { | |
143 | string: "{", | |
144 | count: 1, | |
145 | }, | |
146 | end: Position { | |
147 | string: "}", | |
148 | count: 1, | |
149 | }, | |
150 | label: "test", | |
151 | }, | |
152 | ], | |
153 | r#" | |
154 | error: foo | |
155 | --> test.rs:2:10 | |
156 | | | |
157 | 2 | fn foo() { | |
cc61c64b | 158 | | __________^ |
476ff2be SL |
159 | 3 | | |
160 | 4 | | | |
161 | 5 | | } | |
cc61c64b | 162 | | |___^ test |
476ff2be SL |
163 | |
164 | "#); | |
165 | } | |
166 | #[test] | |
167 | fn non_nested() { | |
168 | test_harness(r#" | |
169 | fn foo() { | |
170 | X0 Y0 | |
171 | X1 Y1 | |
172 | X2 Y2 | |
173 | } | |
174 | "#, | |
175 | vec![ | |
176 | SpanLabel { | |
177 | start: Position { | |
178 | string: "X0", | |
179 | count: 1, | |
180 | }, | |
181 | end: Position { | |
182 | string: "X2", | |
183 | count: 1, | |
184 | }, | |
185 | label: "`X` is a good letter", | |
186 | }, | |
187 | SpanLabel { | |
188 | start: Position { | |
189 | string: "Y0", | |
190 | count: 1, | |
191 | }, | |
192 | end: Position { | |
193 | string: "Y2", | |
194 | count: 1, | |
195 | }, | |
196 | label: "`Y` is a good letter too", | |
197 | }, | |
198 | ], | |
199 | r#" | |
200 | error: foo | |
201 | --> test.rs:3:3 | |
202 | | | |
203 | 3 | X0 Y0 | |
cc61c64b | 204 | | ____^__- |
476ff2be | 205 | | | ___| |
cc61c64b | 206 | | || |
476ff2be SL |
207 | 4 | || X1 Y1 |
208 | 5 | || X2 Y2 | |
cc61c64b | 209 | | ||____^__- `Y` is a good letter too |
476ff2be | 210 | | |____| |
cc61c64b | 211 | | `X` is a good letter |
476ff2be SL |
212 | |
213 | "#); | |
214 | } | |
215 | ||
216 | #[test] | |
217 | fn nested() { | |
218 | test_harness(r#" | |
219 | fn foo() { | |
220 | X0 Y0 | |
221 | Y1 X1 | |
222 | } | |
223 | "#, | |
224 | vec![ | |
225 | SpanLabel { | |
226 | start: Position { | |
227 | string: "X0", | |
228 | count: 1, | |
229 | }, | |
230 | end: Position { | |
231 | string: "X1", | |
232 | count: 1, | |
233 | }, | |
234 | label: "`X` is a good letter", | |
235 | }, | |
236 | SpanLabel { | |
237 | start: Position { | |
238 | string: "Y0", | |
239 | count: 1, | |
240 | }, | |
241 | end: Position { | |
242 | string: "Y1", | |
243 | count: 1, | |
244 | }, | |
245 | label: "`Y` is a good letter too", | |
246 | }, | |
247 | ], | |
248 | r#" | |
249 | error: foo | |
250 | --> test.rs:3:3 | |
251 | | | |
252 | 3 | X0 Y0 | |
cc61c64b | 253 | | ____^__- |
476ff2be | 254 | | | ___| |
cc61c64b | 255 | | || |
476ff2be | 256 | 4 | || Y1 X1 |
cc61c64b | 257 | | ||____-__^ `X` is a good letter |
476ff2be | 258 | | |_____| |
cc61c64b | 259 | | `Y` is a good letter too |
476ff2be SL |
260 | |
261 | "#); | |
262 | } | |
263 | ||
264 | #[test] | |
265 | fn different_overlap() { | |
266 | test_harness(r#" | |
267 | fn foo() { | |
268 | X0 Y0 Z0 | |
269 | X1 Y1 Z1 | |
270 | X2 Y2 Z2 | |
271 | X3 Y3 Z3 | |
272 | } | |
273 | "#, | |
274 | vec![ | |
275 | SpanLabel { | |
276 | start: Position { | |
277 | string: "Y0", | |
278 | count: 1, | |
279 | }, | |
280 | end: Position { | |
281 | string: "X2", | |
282 | count: 1, | |
283 | }, | |
284 | label: "`X` is a good letter", | |
285 | }, | |
286 | SpanLabel { | |
287 | start: Position { | |
288 | string: "Z1", | |
289 | count: 1, | |
290 | }, | |
291 | end: Position { | |
292 | string: "X3", | |
293 | count: 1, | |
294 | }, | |
295 | label: "`Y` is a good letter too", | |
296 | }, | |
297 | ], | |
298 | r#" | |
299 | error: foo | |
300 | --> test.rs:3:6 | |
301 | | | |
302 | 3 | X0 Y0 Z0 | |
cc61c64b | 303 | | ______^ |
476ff2be | 304 | 4 | | X1 Y1 Z1 |
cc61c64b | 305 | | |_________- |
476ff2be | 306 | 5 | || X2 Y2 Z2 |
cc61c64b | 307 | | ||____^ `X` is a good letter |
476ff2be | 308 | 6 | | X3 Y3 Z3 |
cc61c64b | 309 | | |_____- `Y` is a good letter too |
476ff2be SL |
310 | |
311 | "#); | |
312 | } | |
313 | ||
314 | #[test] | |
315 | fn triple_overlap() { | |
316 | test_harness(r#" | |
317 | fn foo() { | |
318 | X0 Y0 Z0 | |
319 | X1 Y1 Z1 | |
320 | X2 Y2 Z2 | |
321 | } | |
322 | "#, | |
323 | vec![ | |
324 | SpanLabel { | |
325 | start: Position { | |
326 | string: "X0", | |
327 | count: 1, | |
328 | }, | |
329 | end: Position { | |
330 | string: "X2", | |
331 | count: 1, | |
332 | }, | |
333 | label: "`X` is a good letter", | |
334 | }, | |
335 | SpanLabel { | |
336 | start: Position { | |
337 | string: "Y0", | |
338 | count: 1, | |
339 | }, | |
340 | end: Position { | |
341 | string: "Y2", | |
342 | count: 1, | |
343 | }, | |
344 | label: "`Y` is a good letter too", | |
345 | }, | |
346 | SpanLabel { | |
347 | start: Position { | |
348 | string: "Z0", | |
349 | count: 1, | |
350 | }, | |
351 | end: Position { | |
352 | string: "Z2", | |
353 | count: 1, | |
354 | }, | |
355 | label: "`Z` label", | |
356 | }, | |
357 | ], | |
358 | r#" | |
359 | error: foo | |
360 | --> test.rs:3:3 | |
361 | | | |
362 | 3 | X0 Y0 Z0 | |
cc61c64b | 363 | | _____^__-__- |
476ff2be | 364 | | | ____|__| |
cc61c64b XL |
365 | | || ___| |
366 | | ||| | |
476ff2be SL |
367 | 4 | ||| X1 Y1 Z1 |
368 | 5 | ||| X2 Y2 Z2 | |
cc61c64b | 369 | | |||____^__-__- `Z` label |
476ff2be | 370 | | ||____|__| |
cc61c64b XL |
371 | | |____| `Y` is a good letter too |
372 | | `X` is a good letter | |
476ff2be SL |
373 | |
374 | "#); | |
375 | } | |
376 | ||
377 | #[test] | |
378 | fn minimum_depth() { | |
379 | test_harness(r#" | |
380 | fn foo() { | |
381 | X0 Y0 Z0 | |
382 | X1 Y1 Z1 | |
383 | X2 Y2 Z2 | |
384 | X3 Y3 Z3 | |
385 | } | |
386 | "#, | |
387 | vec![ | |
388 | SpanLabel { | |
389 | start: Position { | |
390 | string: "Y0", | |
391 | count: 1, | |
392 | }, | |
393 | end: Position { | |
394 | string: "X1", | |
395 | count: 1, | |
396 | }, | |
397 | label: "`X` is a good letter", | |
398 | }, | |
399 | SpanLabel { | |
400 | start: Position { | |
401 | string: "Y1", | |
402 | count: 1, | |
403 | }, | |
404 | end: Position { | |
405 | string: "Z2", | |
406 | count: 1, | |
407 | }, | |
408 | label: "`Y` is a good letter too", | |
409 | }, | |
410 | SpanLabel { | |
411 | start: Position { | |
412 | string: "X2", | |
413 | count: 1, | |
414 | }, | |
415 | end: Position { | |
416 | string: "Y3", | |
417 | count: 1, | |
418 | }, | |
419 | label: "`Z`", | |
420 | }, | |
421 | ], | |
422 | r#" | |
423 | error: foo | |
424 | --> test.rs:3:6 | |
425 | | | |
426 | 3 | X0 Y0 Z0 | |
cc61c64b | 427 | | ______^ |
476ff2be | 428 | 4 | | X1 Y1 Z1 |
cc61c64b | 429 | | |____^_- |
476ff2be | 430 | | ||____| |
cc61c64b | 431 | | | `X` is a good letter |
476ff2be | 432 | 5 | | X2 Y2 Z2 |
cc61c64b | 433 | | |____-______- `Y` is a good letter too |
476ff2be | 434 | | ____| |
cc61c64b | 435 | | | |
476ff2be | 436 | 6 | | X3 Y3 Z3 |
cc61c64b | 437 | | |________- `Z` |
476ff2be SL |
438 | |
439 | "#); | |
440 | } | |
441 | ||
442 | #[test] | |
443 | fn non_overlaping() { | |
444 | test_harness(r#" | |
445 | fn foo() { | |
446 | X0 Y0 Z0 | |
447 | X1 Y1 Z1 | |
448 | X2 Y2 Z2 | |
449 | X3 Y3 Z3 | |
450 | } | |
451 | "#, | |
452 | vec![ | |
453 | SpanLabel { | |
454 | start: Position { | |
cc61c64b | 455 | string: "X0", |
476ff2be SL |
456 | count: 1, |
457 | }, | |
458 | end: Position { | |
459 | string: "X1", | |
460 | count: 1, | |
461 | }, | |
462 | label: "`X` is a good letter", | |
463 | }, | |
464 | SpanLabel { | |
465 | start: Position { | |
466 | string: "Y2", | |
467 | count: 1, | |
468 | }, | |
469 | end: Position { | |
470 | string: "Z3", | |
471 | count: 1, | |
472 | }, | |
473 | label: "`Y` is a good letter too", | |
474 | }, | |
475 | ], | |
476 | r#" | |
477 | error: foo | |
cc61c64b | 478 | --> test.rs:3:3 |
476ff2be | 479 | | |
cc61c64b | 480 | 3 | / X0 Y0 Z0 |
476ff2be | 481 | 4 | | X1 Y1 Z1 |
cc61c64b | 482 | | |____^ `X` is a good letter |
476ff2be | 483 | 5 | X2 Y2 Z2 |
cc61c64b | 484 | | ______- |
476ff2be | 485 | 6 | | X3 Y3 Z3 |
cc61c64b | 486 | | |__________- `Y` is a good letter too |
476ff2be SL |
487 | |
488 | "#); | |
489 | } | |
32a655c1 | 490 | |
476ff2be SL |
491 | #[test] |
492 | fn overlaping_start_and_end() { | |
493 | test_harness(r#" | |
494 | fn foo() { | |
495 | X0 Y0 Z0 | |
496 | X1 Y1 Z1 | |
497 | X2 Y2 Z2 | |
498 | X3 Y3 Z3 | |
499 | } | |
500 | "#, | |
501 | vec![ | |
502 | SpanLabel { | |
503 | start: Position { | |
504 | string: "Y0", | |
505 | count: 1, | |
506 | }, | |
507 | end: Position { | |
508 | string: "X1", | |
509 | count: 1, | |
510 | }, | |
511 | label: "`X` is a good letter", | |
512 | }, | |
513 | SpanLabel { | |
514 | start: Position { | |
515 | string: "Z1", | |
516 | count: 1, | |
517 | }, | |
518 | end: Position { | |
519 | string: "Z3", | |
520 | count: 1, | |
521 | }, | |
522 | label: "`Y` is a good letter too", | |
523 | }, | |
524 | ], | |
525 | r#" | |
526 | error: foo | |
527 | --> test.rs:3:6 | |
528 | | | |
529 | 3 | X0 Y0 Z0 | |
cc61c64b | 530 | | ______^ |
476ff2be | 531 | 4 | | X1 Y1 Z1 |
cc61c64b | 532 | | |____^____- |
476ff2be | 533 | | ||____| |
cc61c64b | 534 | | | `X` is a good letter |
476ff2be SL |
535 | 5 | | X2 Y2 Z2 |
536 | 6 | | X3 Y3 Z3 | |
cc61c64b | 537 | | |___________- `Y` is a good letter too |
476ff2be SL |
538 | |
539 | "#); | |
540 | } | |
32a655c1 SL |
541 | |
542 | #[test] | |
543 | fn multiple_labels_primary_without_message() { | |
544 | test_harness(r#" | |
545 | fn foo() { | |
546 | a { b { c } d } | |
547 | } | |
548 | "#, | |
549 | vec![ | |
550 | SpanLabel { | |
551 | start: Position { | |
552 | string: "b", | |
553 | count: 1, | |
554 | }, | |
555 | end: Position { | |
556 | string: "}", | |
557 | count: 1, | |
558 | }, | |
559 | label: "", | |
560 | }, | |
561 | SpanLabel { | |
562 | start: Position { | |
563 | string: "a", | |
564 | count: 1, | |
565 | }, | |
566 | end: Position { | |
567 | string: "d", | |
568 | count: 1, | |
569 | }, | |
570 | label: "`a` is a good letter", | |
571 | }, | |
572 | SpanLabel { | |
573 | start: Position { | |
574 | string: "c", | |
575 | count: 1, | |
576 | }, | |
577 | end: Position { | |
578 | string: "c", | |
579 | count: 1, | |
580 | }, | |
581 | label: "", | |
582 | }, | |
583 | ], | |
584 | r#" | |
585 | error: foo | |
586 | --> test.rs:3:7 | |
587 | | | |
588 | 3 | a { b { c } d } | |
589 | | ----^^^^-^^-- `a` is a good letter | |
590 | ||
591 | "#); | |
592 | } | |
593 | ||
594 | #[test] | |
595 | fn multiple_labels_secondary_without_message() { | |
596 | test_harness(r#" | |
597 | fn foo() { | |
598 | a { b { c } d } | |
599 | } | |
600 | "#, | |
601 | vec![ | |
602 | SpanLabel { | |
603 | start: Position { | |
604 | string: "a", | |
605 | count: 1, | |
606 | }, | |
607 | end: Position { | |
608 | string: "d", | |
609 | count: 1, | |
610 | }, | |
611 | label: "`a` is a good letter", | |
612 | }, | |
613 | SpanLabel { | |
614 | start: Position { | |
615 | string: "b", | |
616 | count: 1, | |
617 | }, | |
618 | end: Position { | |
619 | string: "}", | |
620 | count: 1, | |
621 | }, | |
622 | label: "", | |
623 | }, | |
624 | ], | |
625 | r#" | |
626 | error: foo | |
627 | --> test.rs:3:3 | |
628 | | | |
629 | 3 | a { b { c } d } | |
630 | | ^^^^-------^^ `a` is a good letter | |
631 | ||
632 | "#); | |
633 | } | |
634 | ||
635 | #[test] | |
636 | fn multiple_labels_primary_without_message_2() { | |
637 | test_harness(r#" | |
638 | fn foo() { | |
639 | a { b { c } d } | |
640 | } | |
641 | "#, | |
642 | vec![ | |
643 | SpanLabel { | |
644 | start: Position { | |
645 | string: "b", | |
646 | count: 1, | |
647 | }, | |
648 | end: Position { | |
649 | string: "}", | |
650 | count: 1, | |
651 | }, | |
652 | label: "`b` is a good letter", | |
653 | }, | |
654 | SpanLabel { | |
655 | start: Position { | |
656 | string: "a", | |
657 | count: 1, | |
658 | }, | |
659 | end: Position { | |
660 | string: "d", | |
661 | count: 1, | |
662 | }, | |
663 | label: "", | |
664 | }, | |
665 | SpanLabel { | |
666 | start: Position { | |
667 | string: "c", | |
668 | count: 1, | |
669 | }, | |
670 | end: Position { | |
671 | string: "c", | |
672 | count: 1, | |
673 | }, | |
674 | label: "", | |
675 | }, | |
676 | ], | |
677 | r#" | |
678 | error: foo | |
679 | --> test.rs:3:7 | |
680 | | | |
681 | 3 | a { b { c } d } | |
682 | | ----^^^^-^^-- | |
683 | | | | |
684 | | `b` is a good letter | |
685 | ||
686 | "#); | |
687 | } | |
688 | ||
689 | #[test] | |
690 | fn multiple_labels_secondary_without_message_2() { | |
691 | test_harness(r#" | |
692 | fn foo() { | |
693 | a { b { c } d } | |
694 | } | |
695 | "#, | |
696 | vec![ | |
697 | SpanLabel { | |
698 | start: Position { | |
699 | string: "a", | |
700 | count: 1, | |
701 | }, | |
702 | end: Position { | |
703 | string: "d", | |
704 | count: 1, | |
705 | }, | |
706 | label: "", | |
707 | }, | |
708 | SpanLabel { | |
709 | start: Position { | |
710 | string: "b", | |
711 | count: 1, | |
712 | }, | |
713 | end: Position { | |
714 | string: "}", | |
715 | count: 1, | |
716 | }, | |
717 | label: "`b` is a good letter", | |
718 | }, | |
719 | ], | |
720 | r#" | |
721 | error: foo | |
722 | --> test.rs:3:3 | |
723 | | | |
724 | 3 | a { b { c } d } | |
725 | | ^^^^-------^^ | |
726 | | | | |
727 | | `b` is a good letter | |
728 | ||
729 | "#); | |
730 | } | |
731 | ||
041b39d2 XL |
732 | #[test] |
733 | fn multiple_labels_secondary_without_message_3() { | |
734 | test_harness(r#" | |
735 | fn foo() { | |
736 | a bc d | |
737 | } | |
738 | "#, | |
739 | vec![ | |
740 | SpanLabel { | |
741 | start: Position { | |
742 | string: "a", | |
743 | count: 1, | |
744 | }, | |
745 | end: Position { | |
746 | string: "b", | |
747 | count: 1, | |
748 | }, | |
749 | label: "`a` is a good letter", | |
750 | }, | |
751 | SpanLabel { | |
752 | start: Position { | |
753 | string: "c", | |
754 | count: 1, | |
755 | }, | |
756 | end: Position { | |
757 | string: "d", | |
758 | count: 1, | |
759 | }, | |
760 | label: "", | |
761 | }, | |
762 | ], | |
763 | r#" | |
764 | error: foo | |
765 | --> test.rs:3:3 | |
766 | | | |
767 | 3 | a bc d | |
768 | | ^^^^---- | |
769 | | | | |
770 | | `a` is a good letter | |
771 | ||
772 | "#); | |
773 | } | |
774 | ||
32a655c1 SL |
775 | #[test] |
776 | fn multiple_labels_without_message() { | |
777 | test_harness(r#" | |
778 | fn foo() { | |
779 | a { b { c } d } | |
780 | } | |
781 | "#, | |
782 | vec![ | |
783 | SpanLabel { | |
784 | start: Position { | |
785 | string: "a", | |
786 | count: 1, | |
787 | }, | |
788 | end: Position { | |
789 | string: "d", | |
790 | count: 1, | |
791 | }, | |
792 | label: "", | |
793 | }, | |
794 | SpanLabel { | |
795 | start: Position { | |
796 | string: "b", | |
797 | count: 1, | |
798 | }, | |
799 | end: Position { | |
800 | string: "}", | |
801 | count: 1, | |
802 | }, | |
803 | label: "", | |
804 | }, | |
805 | ], | |
806 | r#" | |
807 | error: foo | |
808 | --> test.rs:3:3 | |
809 | | | |
810 | 3 | a { b { c } d } | |
811 | | ^^^^-------^^ | |
812 | ||
813 | "#); | |
814 | } | |
815 | ||
816 | #[test] | |
817 | fn multiple_labels_without_message_2() { | |
818 | test_harness(r#" | |
819 | fn foo() { | |
820 | a { b { c } d } | |
821 | } | |
822 | "#, | |
823 | vec![ | |
824 | SpanLabel { | |
825 | start: Position { | |
826 | string: "b", | |
827 | count: 1, | |
828 | }, | |
829 | end: Position { | |
830 | string: "}", | |
831 | count: 1, | |
832 | }, | |
833 | label: "", | |
834 | }, | |
835 | SpanLabel { | |
836 | start: Position { | |
837 | string: "a", | |
838 | count: 1, | |
839 | }, | |
840 | end: Position { | |
841 | string: "d", | |
842 | count: 1, | |
843 | }, | |
844 | label: "", | |
845 | }, | |
846 | SpanLabel { | |
847 | start: Position { | |
848 | string: "c", | |
849 | count: 1, | |
850 | }, | |
851 | end: Position { | |
852 | string: "c", | |
853 | count: 1, | |
854 | }, | |
855 | label: "", | |
856 | }, | |
857 | ], | |
858 | r#" | |
859 | error: foo | |
860 | --> test.rs:3:7 | |
861 | | | |
862 | 3 | a { b { c } d } | |
863 | | ----^^^^-^^-- | |
864 | ||
865 | "#); | |
866 | } | |
867 | ||
868 | #[test] | |
869 | fn multiple_labels_with_message() { | |
870 | test_harness(r#" | |
871 | fn foo() { | |
872 | a { b { c } d } | |
873 | } | |
874 | "#, | |
875 | vec![ | |
876 | SpanLabel { | |
877 | start: Position { | |
878 | string: "a", | |
879 | count: 1, | |
880 | }, | |
881 | end: Position { | |
882 | string: "d", | |
883 | count: 1, | |
884 | }, | |
885 | label: "`a` is a good letter", | |
886 | }, | |
887 | SpanLabel { | |
888 | start: Position { | |
889 | string: "b", | |
890 | count: 1, | |
891 | }, | |
892 | end: Position { | |
893 | string: "}", | |
894 | count: 1, | |
895 | }, | |
896 | label: "`b` is a good letter", | |
897 | }, | |
898 | ], | |
899 | r#" | |
900 | error: foo | |
901 | --> test.rs:3:3 | |
902 | | | |
903 | 3 | a { b { c } d } | |
904 | | ^^^^-------^^ | |
905 | | | | | |
906 | | | `b` is a good letter | |
907 | | `a` is a good letter | |
908 | ||
909 | "#); | |
910 | } | |
911 | ||
912 | #[test] | |
913 | fn single_label_with_message() { | |
914 | test_harness(r#" | |
915 | fn foo() { | |
916 | a { b { c } d } | |
917 | } | |
918 | "#, | |
919 | vec![ | |
920 | SpanLabel { | |
921 | start: Position { | |
922 | string: "a", | |
923 | count: 1, | |
924 | }, | |
925 | end: Position { | |
926 | string: "d", | |
927 | count: 1, | |
928 | }, | |
929 | label: "`a` is a good letter", | |
930 | }, | |
931 | ], | |
932 | r#" | |
933 | error: foo | |
934 | --> test.rs:3:3 | |
935 | | | |
936 | 3 | a { b { c } d } | |
937 | | ^^^^^^^^^^^^^ `a` is a good letter | |
938 | ||
939 | "#); | |
940 | } | |
941 | ||
942 | #[test] | |
943 | fn single_label_without_message() { | |
944 | test_harness(r#" | |
945 | fn foo() { | |
946 | a { b { c } d } | |
947 | } | |
948 | "#, | |
949 | vec![ | |
950 | SpanLabel { | |
951 | start: Position { | |
952 | string: "a", | |
953 | count: 1, | |
954 | }, | |
955 | end: Position { | |
956 | string: "d", | |
957 | count: 1, | |
958 | }, | |
959 | label: "", | |
960 | }, | |
961 | ], | |
962 | r#" | |
963 | error: foo | |
964 | --> test.rs:3:3 | |
965 | | | |
966 | 3 | a { b { c } d } | |
967 | | ^^^^^^^^^^^^^ | |
968 | ||
969 | "#); | |
970 | } | |
cc61c64b XL |
971 | |
972 | #[test] | |
973 | fn long_snippet() { | |
974 | test_harness(r#" | |
975 | fn foo() { | |
976 | X0 Y0 Z0 | |
977 | X1 Y1 Z1 | |
978 | 1 | |
979 | 2 | |
980 | 3 | |
981 | 4 | |
982 | 5 | |
983 | 6 | |
984 | 7 | |
985 | 8 | |
986 | 9 | |
987 | 10 | |
988 | X2 Y2 Z2 | |
989 | X3 Y3 Z3 | |
990 | } | |
991 | "#, | |
992 | vec![ | |
993 | SpanLabel { | |
994 | start: Position { | |
995 | string: "Y0", | |
996 | count: 1, | |
997 | }, | |
998 | end: Position { | |
999 | string: "X1", | |
1000 | count: 1, | |
1001 | }, | |
1002 | label: "`X` is a good letter", | |
1003 | }, | |
1004 | SpanLabel { | |
1005 | start: Position { | |
1006 | string: "Z1", | |
1007 | count: 1, | |
1008 | }, | |
1009 | end: Position { | |
1010 | string: "Z3", | |
1011 | count: 1, | |
1012 | }, | |
1013 | label: "`Y` is a good letter too", | |
1014 | }, | |
1015 | ], | |
1016 | r#" | |
1017 | error: foo | |
1018 | --> test.rs:3:6 | |
1019 | | | |
1020 | 3 | X0 Y0 Z0 | |
1021 | | ______^ | |
1022 | 4 | | X1 Y1 Z1 | |
1023 | | |____^____- | |
1024 | | ||____| | |
1025 | | | `X` is a good letter | |
1026 | 5 | | 1 | |
1027 | 6 | | 2 | |
1028 | 7 | | 3 | |
1029 | ... | | |
1030 | 15 | | X2 Y2 Z2 | |
1031 | 16 | | X3 Y3 Z3 | |
1032 | | |___________- `Y` is a good letter too | |
1033 | ||
1034 | "#); | |
1035 | } | |
1036 | ||
1037 | #[test] | |
1038 | fn long_snippet_multiple_spans() { | |
1039 | test_harness(r#" | |
1040 | fn foo() { | |
1041 | X0 Y0 Z0 | |
1042 | 1 | |
1043 | 2 | |
1044 | 3 | |
1045 | X1 Y1 Z1 | |
1046 | 4 | |
1047 | 5 | |
1048 | 6 | |
1049 | X2 Y2 Z2 | |
1050 | 7 | |
1051 | 8 | |
1052 | 9 | |
1053 | 10 | |
1054 | X3 Y3 Z3 | |
1055 | } | |
1056 | "#, | |
1057 | vec![ | |
1058 | SpanLabel { | |
1059 | start: Position { | |
1060 | string: "Y0", | |
1061 | count: 1, | |
1062 | }, | |
1063 | end: Position { | |
1064 | string: "Y3", | |
1065 | count: 1, | |
1066 | }, | |
1067 | label: "`Y` is a good letter", | |
1068 | }, | |
1069 | SpanLabel { | |
1070 | start: Position { | |
1071 | string: "Z1", | |
1072 | count: 1, | |
1073 | }, | |
1074 | end: Position { | |
1075 | string: "Z2", | |
1076 | count: 1, | |
1077 | }, | |
1078 | label: "`Z` is a good letter too", | |
1079 | }, | |
1080 | ], | |
1081 | r#" | |
1082 | error: foo | |
1083 | --> test.rs:3:6 | |
1084 | | | |
1085 | 3 | X0 Y0 Z0 | |
1086 | | ______^ | |
1087 | 4 | | 1 | |
1088 | 5 | | 2 | |
1089 | 6 | | 3 | |
1090 | 7 | | X1 Y1 Z1 | |
1091 | | |_________- | |
1092 | 8 | || 4 | |
1093 | 9 | || 5 | |
1094 | 10 | || 6 | |
1095 | 11 | || X2 Y2 Z2 | |
1096 | | ||__________- `Z` is a good letter too | |
1097 | ... | | |
1098 | 15 | | 10 | |
1099 | 16 | | X3 Y3 Z3 | |
1100 | | |_______^ `Y` is a good letter | |
1101 | ||
1102 | "#); | |
1103 | } | |
1104 |