##// END OF EJS Templates
rust: factorized testing Graphs...
Georges Racinet -
r41277:168041fa default
parent child Browse files
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(Stub, vec![], 0, false), vec![]);
403 assert_eq!(list_ancestors(SampleGraph, vec![], 0, false), vec![]);
429 assert_eq!(
404 assert_eq!(
430 list_ancestors(Stub, vec![11, 13], 0, false),
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(Stub, vec![11, 13], 0, true),
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(Stub, vec![11, 13], 6, true),
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 assert_eq!(list_ancestors(Stub, vec![11, 13], 12, true), vec![13]);
425 list_ancestors(SampleGraph, vec![11, 13], 11, true),
426 vec![13, 11]
427 );
445 assert_eq!(
428 assert_eq!(
446 list_ancestors(Stub, vec![10, 1], 0, true),
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(Stub, vec![-1], 0, false).unwrap();
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(Stub, vec![10, 1], 0, true).unwrap();
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(Stub, vec![0], 0, false).unwrap();
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(Stub, vec![10], 0, true).unwrap();
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(Stub, vec![10], 0, true).unwrap();
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(Stub, vec![25], 0, false) {
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(Stub, vec![11, 13], 0, false).unwrap();
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(Stub, vec![11, 13], 0, false).unwrap(); // reminder: [8, 7, 4, 3, 2, 1, 0]
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(Stub, [5, 3, 1, 3].iter().cloned());
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(Stub, bases.iter().cloned());
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(Stub, bases.iter().cloned());
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