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 | mod tests { |
|
381 | mod tests { | |
382 |
|
382 | |||
383 | use super::*; |
|
383 | use super::*; | |
|
384 | use crate::testing::{SampleGraph, VecGraph}; | |||
384 | use std::iter::FromIterator; |
|
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 | fn list_ancestors<G: Graph>( |
|
387 | fn list_ancestors<G: Graph>( | |
413 | graph: G, |
|
388 | graph: G, | |
414 | initrevs: Vec<Revision>, |
|
389 | initrevs: Vec<Revision>, | |
@@ -425,25 +400,37 b' mod tests {' | |||||
425 | /// Same tests as test-ancestor.py, without membership |
|
400 | /// Same tests as test-ancestor.py, without membership | |
426 | /// (see also test-ancestor.py.out) |
|
401 | /// (see also test-ancestor.py.out) | |
427 | fn test_list_ancestor() { |
|
402 | fn test_list_ancestor() { | |
428 |
assert_eq!(list_ancestors(S |
|
403 | assert_eq!(list_ancestors(SampleGraph, vec![], 0, false), vec![]); | |
429 | assert_eq!( |
|
404 | assert_eq!( | |
430 |
list_ancestors(S |
|
405 | list_ancestors(SampleGraph, vec![11, 13], 0, false), | |
431 | vec![8, 7, 4, 3, 2, 1, 0] |
|
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 | assert_eq!( |
|
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 | vec![13, 11, 8, 7, 4, 3, 2, 1, 0] |
|
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 | assert_eq!( |
|
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 | vec![13, 11, 8, 7] |
|
422 | vec![13, 11, 8, 7] | |
442 | ); |
|
423 | ); | |
443 | assert_eq!(list_ancestors(Stub, vec![11, 13], 11, true), vec![13, 11]); |
|
424 | assert_eq!( | |
444 |
|
|
425 | list_ancestors(SampleGraph, vec![11, 13], 11, true), | |
|
426 | vec![13, 11] | |||
|
427 | ); | |||
445 | assert_eq!( |
|
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 | vec![10, 5, 4, 2, 1, 0] |
|
434 | vec![10, 5, 4, 2, 1, 0] | |
448 | ); |
|
435 | ); | |
449 | } |
|
436 | } | |
@@ -455,26 +442,26 b' mod tests {' | |||||
455 | /// For instance, run tests/test-obsolete-checkheads.t |
|
442 | /// For instance, run tests/test-obsolete-checkheads.t | |
456 | fn test_nullrev_input() { |
|
443 | fn test_nullrev_input() { | |
457 | let mut iter = |
|
444 | let mut iter = | |
458 |
AncestorsIterator::new(S |
|
445 | AncestorsIterator::new(SampleGraph, vec![-1], 0, false).unwrap(); | |
459 | assert_eq!(iter.next(), None) |
|
446 | assert_eq!(iter.next(), None) | |
460 | } |
|
447 | } | |
461 |
|
448 | |||
462 | #[test] |
|
449 | #[test] | |
463 | fn test_contains() { |
|
450 | fn test_contains() { | |
464 | let mut lazy = |
|
451 | let mut lazy = | |
465 |
AncestorsIterator::new(S |
|
452 | AncestorsIterator::new(SampleGraph, vec![10, 1], 0, true).unwrap(); | |
466 | assert!(lazy.contains(1).unwrap()); |
|
453 | assert!(lazy.contains(1).unwrap()); | |
467 | assert!(!lazy.contains(3).unwrap()); |
|
454 | assert!(!lazy.contains(3).unwrap()); | |
468 |
|
455 | |||
469 | let mut lazy = |
|
456 | let mut lazy = | |
470 |
AncestorsIterator::new(S |
|
457 | AncestorsIterator::new(SampleGraph, vec![0], 0, false).unwrap(); | |
471 | assert!(!lazy.contains(NULL_REVISION).unwrap()); |
|
458 | assert!(!lazy.contains(NULL_REVISION).unwrap()); | |
472 | } |
|
459 | } | |
473 |
|
460 | |||
474 | #[test] |
|
461 | #[test] | |
475 | fn test_peek() { |
|
462 | fn test_peek() { | |
476 | let mut iter = |
|
463 | let mut iter = | |
477 |
AncestorsIterator::new(S |
|
464 | AncestorsIterator::new(SampleGraph, vec![10], 0, true).unwrap(); | |
478 | // peek() gives us the next value |
|
465 | // peek() gives us the next value | |
479 | assert_eq!(iter.peek(), Some(10)); |
|
466 | assert_eq!(iter.peek(), Some(10)); | |
480 | // but it's not been consumed |
|
467 | // but it's not been consumed | |
@@ -490,16 +477,18 b' mod tests {' | |||||
490 | #[test] |
|
477 | #[test] | |
491 | fn test_empty() { |
|
478 | fn test_empty() { | |
492 | let mut iter = |
|
479 | let mut iter = | |
493 |
AncestorsIterator::new(S |
|
480 | AncestorsIterator::new(SampleGraph, vec![10], 0, true).unwrap(); | |
494 | assert!(!iter.is_empty()); |
|
481 | assert!(!iter.is_empty()); | |
495 | while iter.next().is_some() {} |
|
482 | while iter.next().is_some() {} | |
496 | assert!(!iter.is_empty()); |
|
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 | assert!(iter.is_empty()); |
|
487 | assert!(iter.is_empty()); | |
500 |
|
488 | |||
501 | // case where iter.seen == {NULL_REVISION} |
|
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 | assert!(iter.is_empty()); |
|
492 | assert!(iter.is_empty()); | |
504 | } |
|
493 | } | |
505 |
|
494 | |||
@@ -519,7 +508,7 b' mod tests {' | |||||
519 | #[test] |
|
508 | #[test] | |
520 | fn test_initrev_out_of_range() { |
|
509 | fn test_initrev_out_of_range() { | |
521 | // inclusive=false looks up initrev's parents right away |
|
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 | Ok(_) => panic!("Should have been ParentOutOfRange"), |
|
512 | Ok(_) => panic!("Should have been ParentOutOfRange"), | |
524 | Err(e) => assert_eq!(e, GraphError::ParentOutOfRange(25)), |
|
513 | Err(e) => assert_eq!(e, GraphError::ParentOutOfRange(25)), | |
525 | } |
|
514 | } | |
@@ -536,7 +525,7 b' mod tests {' | |||||
536 | #[test] |
|
525 | #[test] | |
537 | fn test_lazy_iter_contains() { |
|
526 | fn test_lazy_iter_contains() { | |
538 | let mut lazy = |
|
527 | let mut lazy = | |
539 |
LazyAncestors::new(S |
|
528 | LazyAncestors::new(SampleGraph, vec![11, 13], 0, false).unwrap(); | |
540 |
|
529 | |||
541 | let revs: Vec<Revision> = lazy.iter().map(|r| r.unwrap()).collect(); |
|
530 | let revs: Vec<Revision> = lazy.iter().map(|r| r.unwrap()).collect(); | |
542 | // compare with iterator tests on the same initial revisions |
|
531 | // compare with iterator tests on the same initial revisions | |
@@ -551,7 +540,7 b' mod tests {' | |||||
551 | #[test] |
|
540 | #[test] | |
552 | fn test_lazy_contains_iter() { |
|
541 | fn test_lazy_contains_iter() { | |
553 | let mut lazy = |
|
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 | assert_eq!(lazy.contains(2), Ok(true)); |
|
545 | assert_eq!(lazy.contains(2), Ok(true)); | |
557 | assert_eq!(lazy.contains(6), Ok(false)); |
|
546 | assert_eq!(lazy.contains(6), Ok(false)); | |
@@ -570,7 +559,7 b' mod tests {' | |||||
570 | /// Test constructor, add/get bases |
|
559 | /// Test constructor, add/get bases | |
571 | fn test_missing_bases() { |
|
560 | fn test_missing_bases() { | |
572 | let mut missing_ancestors = |
|
561 | let mut missing_ancestors = | |
573 |
MissingAncestors::new(S |
|
562 | MissingAncestors::new(SampleGraph, [5, 3, 1, 3].iter().cloned()); | |
574 | let mut as_vec: Vec<Revision> = |
|
563 | let mut as_vec: Vec<Revision> = | |
575 | missing_ancestors.get_bases().iter().cloned().collect(); |
|
564 | missing_ancestors.get_bases().iter().cloned().collect(); | |
576 | as_vec.sort(); |
|
565 | as_vec.sort(); | |
@@ -588,7 +577,7 b' mod tests {' | |||||
588 | expected: &[Revision], |
|
577 | expected: &[Revision], | |
589 | ) { |
|
578 | ) { | |
590 | let mut missing_ancestors = |
|
579 | let mut missing_ancestors = | |
591 |
MissingAncestors::new(S |
|
580 | MissingAncestors::new(SampleGraph, bases.iter().cloned()); | |
592 | let mut revset: HashSet<Revision> = revs.iter().cloned().collect(); |
|
581 | let mut revset: HashSet<Revision> = revs.iter().cloned().collect(); | |
593 | missing_ancestors |
|
582 | missing_ancestors | |
594 | .remove_ancestors_from(&mut revset) |
|
583 | .remove_ancestors_from(&mut revset) | |
@@ -615,7 +604,7 b' mod tests {' | |||||
615 | expected: &[Revision], |
|
604 | expected: &[Revision], | |
616 | ) { |
|
605 | ) { | |
617 | let mut missing_ancestors = |
|
606 | let mut missing_ancestors = | |
618 |
MissingAncestors::new(S |
|
607 | MissingAncestors::new(SampleGraph, bases.iter().cloned()); | |
619 | let missing = missing_ancestors |
|
608 | let missing = missing_ancestors | |
620 | .missing_ancestors(revs.iter().cloned()) |
|
609 | .missing_ancestors(revs.iter().cloned()) | |
621 | .unwrap(); |
|
610 | .unwrap(); | |
@@ -631,16 +620,6 b' mod tests {' | |||||
631 | assert_missing_ancestors(&[7], &[9, 11], &[3, 6, 9, 11]); |
|
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 | /// An interesting case found by a random generator similar to |
|
623 | /// An interesting case found by a random generator similar to | |
645 | /// the one in test-ancestor.py. An early version of Rust MissingAncestors |
|
624 | /// the one in test-ancestor.py. An early version of Rust MissingAncestors | |
646 | /// failed this, yet none of the integration tests of the whole suite |
|
625 | /// failed this, yet none of the integration tests of the whole suite |
@@ -4,6 +4,8 b'' | |||||
4 | // GNU General Public License version 2 or any later version. |
|
4 | // GNU General Public License version 2 or any later version. | |
5 | mod ancestors; |
|
5 | mod ancestors; | |
6 | pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors}; |
|
6 | pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors}; | |
|
7 | #[cfg(test)] | |||
|
8 | pub mod testing; | |||
7 |
|
9 | |||
8 | /// Mercurial revision numbers |
|
10 | /// Mercurial revision numbers | |
9 | /// |
|
11 | /// |
General Comments 0
You need to be logged in to leave comments.
Login now