Show More
@@ -0,0 +1,72 b'' | |||
|
1 | // testing.rs | |
|
2 | // | |
|
3 | // Copyright 2018 Georges Racinet <georges.racinet@octobus.net> | |
|
4 | // | |
|
5 | // This software may be used and distributed according to the terms of the | |
|
6 | // GNU General Public License version 2 or any later version. | |
|
7 | ||
|
8 | use crate::{Graph, GraphError, Revision, NULL_REVISION}; | |
|
9 | ||
|
10 | /// A stub `Graph`, same as the one from `test-ancestor.py` | |
|
11 | /// | |
|
12 | /// o 13 | |
|
13 | /// | | |
|
14 | /// | o 12 | |
|
15 | /// | | | |
|
16 | /// | | o 11 | |
|
17 | /// | | |\ | |
|
18 | /// | | | | o 10 | |
|
19 | /// | | | | | | |
|
20 | /// | o---+ | 9 | |
|
21 | /// | | | | | | |
|
22 | /// o | | | | 8 | |
|
23 | /// / / / / | |
|
24 | /// | | o | 7 | |
|
25 | /// | | | | | |
|
26 | /// o---+ | 6 | |
|
27 | /// / / / | |
|
28 | /// | | o 5 | |
|
29 | /// | |/ | |
|
30 | /// | o 4 | |
|
31 | /// | | | |
|
32 | /// o | 3 | |
|
33 | /// | | | |
|
34 | /// | o 2 | |
|
35 | /// |/ | |
|
36 | /// o 1 | |
|
37 | /// | | |
|
38 | /// o 0 | |
|
39 | #[derive(Clone, Debug)] | |
|
40 | pub struct SampleGraph; | |
|
41 | ||
|
42 | impl Graph for SampleGraph { | |
|
43 | fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { | |
|
44 | match rev { | |
|
45 | 0 => Ok([NULL_REVISION, NULL_REVISION]), | |
|
46 | 1 => Ok([0, NULL_REVISION]), | |
|
47 | 2 => Ok([1, NULL_REVISION]), | |
|
48 | 3 => Ok([1, NULL_REVISION]), | |
|
49 | 4 => Ok([2, NULL_REVISION]), | |
|
50 | 5 => Ok([4, NULL_REVISION]), | |
|
51 | 6 => Ok([4, NULL_REVISION]), | |
|
52 | 7 => Ok([4, NULL_REVISION]), | |
|
53 | 8 => Ok([NULL_REVISION, NULL_REVISION]), | |
|
54 | 9 => Ok([6, 7]), | |
|
55 | 10 => Ok([5, NULL_REVISION]), | |
|
56 | 11 => Ok([3, 7]), | |
|
57 | 12 => Ok([9, NULL_REVISION]), | |
|
58 | 13 => Ok([8, NULL_REVISION]), | |
|
59 | r => Err(GraphError::ParentOutOfRange(r)), | |
|
60 | } | |
|
61 | } | |
|
62 | } | |
|
63 | ||
|
64 | // A Graph represented by a vector whose indices are revisions | |
|
65 | // and values are parents of the revisions | |
|
66 | pub type VecGraph = Vec<[Revision; 2]>; | |
|
67 | ||
|
68 | impl Graph for VecGraph { | |
|
69 | fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { | |
|
70 | Ok(self[rev as usize]) | |
|
71 | } | |
|
72 | } |
@@ -381,34 +381,9 b' impl<G: Graph> MissingAncestors<G> {' | |||
|
381 | 381 | mod tests { |
|
382 | 382 | |
|
383 | 383 | use super::*; |
|
384 | use crate::testing::{SampleGraph, VecGraph}; | |
|
384 | 385 | use std::iter::FromIterator; |
|
385 | 386 | |
|
386 | #[derive(Clone, Debug)] | |
|
387 | struct Stub; | |
|
388 | ||
|
389 | /// This is the same as the dict from test-ancestors.py | |
|
390 | impl Graph for Stub { | |
|
391 | fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { | |
|
392 | match rev { | |
|
393 | 0 => Ok([-1, -1]), | |
|
394 | 1 => Ok([0, -1]), | |
|
395 | 2 => Ok([1, -1]), | |
|
396 | 3 => Ok([1, -1]), | |
|
397 | 4 => Ok([2, -1]), | |
|
398 | 5 => Ok([4, -1]), | |
|
399 | 6 => Ok([4, -1]), | |
|
400 | 7 => Ok([4, -1]), | |
|
401 | 8 => Ok([-1, -1]), | |
|
402 | 9 => Ok([6, 7]), | |
|
403 | 10 => Ok([5, -1]), | |
|
404 | 11 => Ok([3, 7]), | |
|
405 | 12 => Ok([9, -1]), | |
|
406 | 13 => Ok([8, -1]), | |
|
407 | r => Err(GraphError::ParentOutOfRange(r)), | |
|
408 | } | |
|
409 | } | |
|
410 | } | |
|
411 | ||
|
412 | 387 | fn list_ancestors<G: Graph>( |
|
413 | 388 | graph: G, |
|
414 | 389 | initrevs: Vec<Revision>, |
@@ -425,25 +400,37 b' mod tests {' | |||
|
425 | 400 | /// Same tests as test-ancestor.py, without membership |
|
426 | 401 | /// (see also test-ancestor.py.out) |
|
427 | 402 | fn test_list_ancestor() { |
|
428 |
assert_eq!(list_ancestors(S |
|
|
403 | assert_eq!(list_ancestors(SampleGraph, vec![], 0, false), vec![]); | |
|
429 | 404 | assert_eq!( |
|
430 |
list_ancestors(S |
|
|
405 | list_ancestors(SampleGraph, vec![11, 13], 0, false), | |
|
431 | 406 | vec![8, 7, 4, 3, 2, 1, 0] |
|
432 | 407 | ); |
|
433 | assert_eq!(list_ancestors(Stub, vec![1, 3], 0, false), vec![1, 0]); | |
|
434 | 408 | assert_eq!( |
|
435 |
list_ancestors(S |
|
|
409 | list_ancestors(SampleGraph, vec![1, 3], 0, false), | |
|
410 | vec![1, 0] | |
|
411 | ); | |
|
412 | assert_eq!( | |
|
413 | list_ancestors(SampleGraph, vec![11, 13], 0, true), | |
|
436 | 414 | vec![13, 11, 8, 7, 4, 3, 2, 1, 0] |
|
437 | 415 | ); |
|
438 | assert_eq!(list_ancestors(Stub, vec![11, 13], 6, false), vec![8, 7]); | |
|
439 | 416 | assert_eq!( |
|
440 |
list_ancestors(S |
|
|
417 | list_ancestors(SampleGraph, vec![11, 13], 6, false), | |
|
418 | vec![8, 7] | |
|
419 | ); | |
|
420 | assert_eq!( | |
|
421 | list_ancestors(SampleGraph, vec![11, 13], 6, true), | |
|
441 | 422 | vec![13, 11, 8, 7] |
|
442 | 423 | ); |
|
443 | assert_eq!(list_ancestors(Stub, vec![11, 13], 11, true), vec![13, 11]); | |
|
444 |
|
|
|
424 | assert_eq!( | |
|
425 | list_ancestors(SampleGraph, vec![11, 13], 11, true), | |
|
426 | vec![13, 11] | |
|
427 | ); | |
|
445 | 428 | assert_eq!( |
|
446 |
list_ancestors(S |
|
|
429 | list_ancestors(SampleGraph, vec![11, 13], 12, true), | |
|
430 | vec![13] | |
|
431 | ); | |
|
432 | assert_eq!( | |
|
433 | list_ancestors(SampleGraph, vec![10, 1], 0, true), | |
|
447 | 434 | vec![10, 5, 4, 2, 1, 0] |
|
448 | 435 | ); |
|
449 | 436 | } |
@@ -455,26 +442,26 b' mod tests {' | |||
|
455 | 442 | /// For instance, run tests/test-obsolete-checkheads.t |
|
456 | 443 | fn test_nullrev_input() { |
|
457 | 444 | let mut iter = |
|
458 |
AncestorsIterator::new(S |
|
|
445 | AncestorsIterator::new(SampleGraph, vec![-1], 0, false).unwrap(); | |
|
459 | 446 | assert_eq!(iter.next(), None) |
|
460 | 447 | } |
|
461 | 448 | |
|
462 | 449 | #[test] |
|
463 | 450 | fn test_contains() { |
|
464 | 451 | let mut lazy = |
|
465 |
AncestorsIterator::new(S |
|
|
452 | AncestorsIterator::new(SampleGraph, vec![10, 1], 0, true).unwrap(); | |
|
466 | 453 | assert!(lazy.contains(1).unwrap()); |
|
467 | 454 | assert!(!lazy.contains(3).unwrap()); |
|
468 | 455 | |
|
469 | 456 | let mut lazy = |
|
470 |
AncestorsIterator::new(S |
|
|
457 | AncestorsIterator::new(SampleGraph, vec![0], 0, false).unwrap(); | |
|
471 | 458 | assert!(!lazy.contains(NULL_REVISION).unwrap()); |
|
472 | 459 | } |
|
473 | 460 | |
|
474 | 461 | #[test] |
|
475 | 462 | fn test_peek() { |
|
476 | 463 | let mut iter = |
|
477 |
AncestorsIterator::new(S |
|
|
464 | AncestorsIterator::new(SampleGraph, vec![10], 0, true).unwrap(); | |
|
478 | 465 | // peek() gives us the next value |
|
479 | 466 | assert_eq!(iter.peek(), Some(10)); |
|
480 | 467 | // but it's not been consumed |
@@ -490,16 +477,18 b' mod tests {' | |||
|
490 | 477 | #[test] |
|
491 | 478 | fn test_empty() { |
|
492 | 479 | let mut iter = |
|
493 |
AncestorsIterator::new(S |
|
|
480 | AncestorsIterator::new(SampleGraph, vec![10], 0, true).unwrap(); | |
|
494 | 481 | assert!(!iter.is_empty()); |
|
495 | 482 | while iter.next().is_some() {} |
|
496 | 483 | assert!(!iter.is_empty()); |
|
497 | 484 | |
|
498 | let iter = AncestorsIterator::new(Stub, vec![], 0, true).unwrap(); | |
|
485 | let iter = | |
|
486 | AncestorsIterator::new(SampleGraph, vec![], 0, true).unwrap(); | |
|
499 | 487 | assert!(iter.is_empty()); |
|
500 | 488 | |
|
501 | 489 | // case where iter.seen == {NULL_REVISION} |
|
502 | let iter = AncestorsIterator::new(Stub, vec![0], 0, false).unwrap(); | |
|
490 | let iter = | |
|
491 | AncestorsIterator::new(SampleGraph, vec![0], 0, false).unwrap(); | |
|
503 | 492 | assert!(iter.is_empty()); |
|
504 | 493 | } |
|
505 | 494 | |
@@ -519,7 +508,7 b' mod tests {' | |||
|
519 | 508 | #[test] |
|
520 | 509 | fn test_initrev_out_of_range() { |
|
521 | 510 | // inclusive=false looks up initrev's parents right away |
|
522 |
match AncestorsIterator::new(S |
|
|
511 | match AncestorsIterator::new(SampleGraph, vec![25], 0, false) { | |
|
523 | 512 | Ok(_) => panic!("Should have been ParentOutOfRange"), |
|
524 | 513 | Err(e) => assert_eq!(e, GraphError::ParentOutOfRange(25)), |
|
525 | 514 | } |
@@ -536,7 +525,7 b' mod tests {' | |||
|
536 | 525 | #[test] |
|
537 | 526 | fn test_lazy_iter_contains() { |
|
538 | 527 | let mut lazy = |
|
539 |
LazyAncestors::new(S |
|
|
528 | LazyAncestors::new(SampleGraph, vec![11, 13], 0, false).unwrap(); | |
|
540 | 529 | |
|
541 | 530 | let revs: Vec<Revision> = lazy.iter().map(|r| r.unwrap()).collect(); |
|
542 | 531 | // compare with iterator tests on the same initial revisions |
@@ -551,7 +540,7 b' mod tests {' | |||
|
551 | 540 | #[test] |
|
552 | 541 | fn test_lazy_contains_iter() { |
|
553 | 542 | let mut lazy = |
|
554 |
LazyAncestors::new(S |
|
|
543 | LazyAncestors::new(SampleGraph, vec![11, 13], 0, false).unwrap(); // reminder: [8, 7, 4, 3, 2, 1, 0] | |
|
555 | 544 | |
|
556 | 545 | assert_eq!(lazy.contains(2), Ok(true)); |
|
557 | 546 | assert_eq!(lazy.contains(6), Ok(false)); |
@@ -570,7 +559,7 b' mod tests {' | |||
|
570 | 559 | /// Test constructor, add/get bases |
|
571 | 560 | fn test_missing_bases() { |
|
572 | 561 | let mut missing_ancestors = |
|
573 |
MissingAncestors::new(S |
|
|
562 | MissingAncestors::new(SampleGraph, [5, 3, 1, 3].iter().cloned()); | |
|
574 | 563 | let mut as_vec: Vec<Revision> = |
|
575 | 564 | missing_ancestors.get_bases().iter().cloned().collect(); |
|
576 | 565 | as_vec.sort(); |
@@ -588,7 +577,7 b' mod tests {' | |||
|
588 | 577 | expected: &[Revision], |
|
589 | 578 | ) { |
|
590 | 579 | let mut missing_ancestors = |
|
591 |
MissingAncestors::new(S |
|
|
580 | MissingAncestors::new(SampleGraph, bases.iter().cloned()); | |
|
592 | 581 | let mut revset: HashSet<Revision> = revs.iter().cloned().collect(); |
|
593 | 582 | missing_ancestors |
|
594 | 583 | .remove_ancestors_from(&mut revset) |
@@ -615,7 +604,7 b' mod tests {' | |||
|
615 | 604 | expected: &[Revision], |
|
616 | 605 | ) { |
|
617 | 606 | let mut missing_ancestors = |
|
618 |
MissingAncestors::new(S |
|
|
607 | MissingAncestors::new(SampleGraph, bases.iter().cloned()); | |
|
619 | 608 | let missing = missing_ancestors |
|
620 | 609 | .missing_ancestors(revs.iter().cloned()) |
|
621 | 610 | .unwrap(); |
@@ -631,16 +620,6 b' mod tests {' | |||
|
631 | 620 | assert_missing_ancestors(&[7], &[9, 11], &[3, 6, 9, 11]); |
|
632 | 621 | } |
|
633 | 622 | |
|
634 | // A Graph represented by a vector whose indices are revisions | |
|
635 | // and values are parents of the revisions | |
|
636 | type VecGraph = Vec<[Revision; 2]>; | |
|
637 | ||
|
638 | impl Graph for VecGraph { | |
|
639 | fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { | |
|
640 | Ok(self[rev as usize]) | |
|
641 | } | |
|
642 | } | |
|
643 | ||
|
644 | 623 | /// An interesting case found by a random generator similar to |
|
645 | 624 | /// the one in test-ancestor.py. An early version of Rust MissingAncestors |
|
646 | 625 | /// failed this, yet none of the integration tests of the whole suite |
General Comments 0
You need to be logged in to leave comments.
Login now