//! ref: composer/tests/Composer/Test/DependencyResolver/RuleSetTest.php use std::cell::RefCell; use std::rc::Rc; use shirabe::dependency_resolver::{ GenericRule, RULE_LEARNED, RULE_ROOT_REQUIRE, ReasonData, Rule, RuleSet, }; use shirabe_semver::constraint::MatchAllConstraint; fn root_require_reason() -> ReasonData { ReasonData::RootRequire { package_name: String::new(), constraint: MatchAllConstraint::new(None).into(), } } fn rule(literals: Vec) -> Rc> { Rc::new(RefCell::new(Rule::Generic(GenericRule::new( literals, RULE_ROOT_REQUIRE, root_require_reason(), )))) } fn learned_rule() -> Rc> { Rc::new(RefCell::new(Rule::Generic(GenericRule::new( vec![], RULE_LEARNED, ReasonData::Int(1), )))) } fn iterator_count(mut iterator: shirabe::dependency_resolver::RuleSetIterator) -> i64 { let mut count = 0; while iterator.valid() { count += 1; iterator.next(); } count } #[test] #[ignore = "RuleSet::add computes Rule::get_hash, which reaches hash_raw (todo!()) in the php-shim"] fn test_add() { let request0 = rule(vec![1]); let request1 = rule(vec![2]); let learned0 = learned_rule(); let mut rule_set = RuleSet::new(); rule_set .add(request0.clone(), RuleSet::TYPE_REQUEST) .unwrap(); rule_set .add(learned0.clone(), RuleSet::TYPE_LEARNED) .unwrap(); rule_set .add(request1.clone(), RuleSet::TYPE_REQUEST) .unwrap(); let rules = rule_set.get_rules(); assert!( rules .get(&RuleSet::TYPE_PACKAGE) .is_none_or(|v| v.is_empty()) ); let request = &rules[&RuleSet::TYPE_REQUEST]; assert_eq!(2, request.len()); assert!(Rc::ptr_eq(&request[0], &request0)); assert!(Rc::ptr_eq(&request[1], &request1)); let learned = &rules[&RuleSet::TYPE_LEARNED]; assert_eq!(1, learned.len()); assert!(Rc::ptr_eq(&learned[0], &learned0)); } #[test] #[ignore = "RuleSet::add computes Rule::get_hash, which reaches hash_raw (todo!()) in the php-shim"] fn test_add_ignores_duplicates() { let mut rule_set = RuleSet::new(); rule_set.add(rule(vec![]), RuleSet::TYPE_REQUEST).unwrap(); rule_set.add(rule(vec![]), RuleSet::TYPE_REQUEST).unwrap(); rule_set.add(rule(vec![]), RuleSet::TYPE_REQUEST).unwrap(); assert_eq!( 1, iterator_count(rule_set.get_iterator_for(vec![RuleSet::TYPE_REQUEST])) ); } #[test] fn test_add_when_type_is_not_recognized() { let mut rule_set = RuleSet::new(); // The unknown-type check happens before the hash is computed. assert!(rule_set.add(rule(vec![]), 7).is_err()); } #[test] #[ignore = "RuleSet::add computes Rule::get_hash, which reaches hash_raw (todo!()) in the php-shim"] fn test_count() { let mut rule_set = RuleSet::new(); rule_set.add(rule(vec![1]), RuleSet::TYPE_REQUEST).unwrap(); rule_set.add(rule(vec![2]), RuleSet::TYPE_REQUEST).unwrap(); assert_eq!(2, rule_set.count()); } #[test] #[ignore = "RuleSet::add computes Rule::get_hash, which reaches hash_raw (todo!()) in the php-shim"] fn test_rule_by_id() { let mut rule_set = RuleSet::new(); let rule = rule(vec![]); rule_set.add(rule.clone(), RuleSet::TYPE_REQUEST).unwrap(); assert!(Rc::ptr_eq(&rule_set.rule_by_id[&0], &rule)); } #[test] #[ignore = "RuleSet::add computes Rule::get_hash, which reaches hash_raw (todo!()) in the php-shim"] fn test_get_iterator() { let mut rule_set = RuleSet::new(); let rule1 = rule(vec![1]); let rule2 = rule(vec![2]); rule_set.add(rule1.clone(), RuleSet::TYPE_REQUEST).unwrap(); rule_set.add(rule2.clone(), RuleSet::TYPE_LEARNED).unwrap(); let mut iterator = rule_set.get_iterator(); assert!(Rc::ptr_eq(&iterator.current(), &rule1)); iterator.next(); assert!(Rc::ptr_eq(&iterator.current(), &rule2)); } #[test] #[ignore = "RuleSet::add computes Rule::get_hash, which reaches hash_raw (todo!()) in the php-shim"] fn test_get_iterator_for() { let mut rule_set = RuleSet::new(); let rule1 = rule(vec![1]); let rule2 = rule(vec![2]); rule_set.add(rule1, RuleSet::TYPE_REQUEST).unwrap(); rule_set.add(rule2.clone(), RuleSet::TYPE_LEARNED).unwrap(); let iterator = rule_set.get_iterator_for(vec![RuleSet::TYPE_LEARNED]); assert!(Rc::ptr_eq(&iterator.current(), &rule2)); } #[test] #[ignore = "RuleSet::add computes Rule::get_hash, which reaches hash_raw (todo!()) in the php-shim"] fn test_get_iterator_without() { let mut rule_set = RuleSet::new(); let rule1 = rule(vec![1]); let rule2 = rule(vec![2]); rule_set.add(rule1, RuleSet::TYPE_REQUEST).unwrap(); rule_set.add(rule2.clone(), RuleSet::TYPE_LEARNED).unwrap(); let iterator = rule_set.get_iterator_without(vec![RuleSet::TYPE_REQUEST]); assert!(Rc::ptr_eq(&iterator.current(), &rule2)); } // In PHP this mocks RepositorySet and Request to build the pretty string. The mocked // collaborators cannot be reproduced here, and add() also reaches hash_raw (todo!()). #[test] #[ignore = "getPrettyString needs mocked RepositorySet/Request, and add() reaches hash_raw (todo!())"] fn test_pretty_string() { todo!() }