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