##// END OF EJS Templates
match: strengthen visit_children_set invariant, Recursive means "all files"...
Arseniy Alekseyev -
r52464:74230abb stable
parent child Browse files
Show More
@@ -2146,7 +2146,11 b' mod tests {'
2146 visit_children_set: &'a VisitChildrenSet,
2146 visit_children_set: &'a VisitChildrenSet,
2147 }
2147 }
2148
2148
2149 fn holds(matching: &Tree, vcs: &VisitChildrenSet) -> bool {
2149 fn holds(
2150 matching: &Tree,
2151 not_matching: &Tree,
2152 vcs: &VisitChildrenSet,
2153 ) -> bool {
2150 match vcs {
2154 match vcs {
2151 VisitChildrenSet::Empty => matching.is_empty(),
2155 VisitChildrenSet::Empty => matching.is_empty(),
2152 VisitChildrenSet::This => {
2156 VisitChildrenSet::This => {
@@ -2154,14 +2158,11 b' mod tests {'
2154 true
2158 true
2155 }
2159 }
2156 VisitChildrenSet::Recursive => {
2160 VisitChildrenSet::Recursive => {
2157 // `Recursive` does not come with any correctness
2161 // `Recursive` requires that *everything* in the
2158 // obligations.
2162 // subtree matches. This
2159 // It instructs the caller to stop calling
2163 // requirement is relied on for example in
2160 // `visit_children_set` for all
2164 // DifferenceMatcher implementation.
2161 // descendants, so may have negative performance
2165 not_matching.is_empty()
2162 // implications, but we're not testing against that
2163 // here.
2164 true
2165 }
2166 }
2166 VisitChildrenSet::Set(allowed_children) => {
2167 VisitChildrenSet::Set(allowed_children) => {
2167 // `allowed_children` does not distinguish between
2168 // `allowed_children` does not distinguish between
@@ -2186,9 +2187,10 b' mod tests {'
2186 matcher: &M,
2187 matcher: &M,
2187 path: &HgPath,
2188 path: &HgPath,
2188 matching: &Tree,
2189 matching: &Tree,
2190 not_matching: &Tree,
2189 visit_children_set: &VisitChildrenSet,
2191 visit_children_set: &VisitChildrenSet,
2190 ) {
2192 ) {
2191 if !holds(matching, visit_children_set) {
2193 if !holds(matching, not_matching, visit_children_set) {
2192 panic!(
2194 panic!(
2193 "{:#?}",
2195 "{:#?}",
2194 Error {
2196 Error {
@@ -2223,34 +2225,52 b' mod tests {'
2223 self.files.is_empty() && self.dirs.is_empty()
2225 self.files.is_empty() && self.dirs.is_empty()
2224 }
2226 }
2225
2227
2228 fn make(
2229 files: BTreeSet<HgPathBuf>,
2230 dirs: BTreeMap<HgPathBuf, Tree>,
2231 ) -> Self {
2232 Self {
2233 files,
2234 dirs: dirs
2235 .into_iter()
2236 .filter(|(_k, v)| (!(v.is_empty())))
2237 .collect(),
2238 }
2239 }
2240
2226 fn filter_and_check<M: Matcher + Debug>(
2241 fn filter_and_check<M: Matcher + Debug>(
2227 &self,
2242 &self,
2228 m: &M,
2243 m: &M,
2229 path: &HgPath,
2244 path: &HgPath,
2230 ) -> Self {
2245 ) -> (Self, Self) {
2231 let files: BTreeSet<HgPathBuf> = self
2246 let (files1, files2): (BTreeSet<HgPathBuf>, BTreeSet<HgPathBuf>) =
2232 .files
2247 self.files
2233 .iter()
2248 .iter()
2234 .filter(|v| m.matches(&path.join(v)))
2249 .map(|v| v.to_owned())
2235 .map(|f| f.to_owned())
2250 .partition(|v| m.matches(&path.join(v)));
2236 .collect();
2251 let (dirs1, dirs2): (
2237 let dirs: BTreeMap<HgPathBuf, Tree> = self
2252 BTreeMap<HgPathBuf, Tree>,
2253 BTreeMap<HgPathBuf, Tree>,
2254 ) = self
2238 .dirs
2255 .dirs
2239 .iter()
2256 .iter()
2240 .filter_map(|(k, v)| {
2257 .map(|(k, v)| {
2241 let path = path.join(k);
2258 let path = path.join(k);
2242 let v = v.filter_and_check(m, &path);
2259 let (t1, t2) = v.filter_and_check(m, &path);
2243 if v.is_empty() {
2260 ((k.clone(), t1), (k.clone(), t2))
2244 None
2245 } else {
2246 Some((k.to_owned(), v))
2247 }
2248 })
2261 })
2249 .collect();
2262 .unzip();
2250 let matching = Self { files, dirs };
2263 let matching = Self::make(files1, dirs1);
2264 let not_matching = Self::make(files2, dirs2);
2251 let vcs = m.visit_children_set(path);
2265 let vcs = m.visit_children_set(path);
2252 invariants::visit_children_set::check(m, path, &matching, &vcs);
2266 invariants::visit_children_set::check(
2253 matching
2267 m,
2268 path,
2269 &matching,
2270 &not_matching,
2271 &vcs,
2272 );
2273 (matching, not_matching)
2254 }
2274 }
2255
2275
2256 fn check_matcher<M: Matcher + Debug>(
2276 fn check_matcher<M: Matcher + Debug>(
@@ -2259,11 +2279,11 b' mod tests {'
2259 expect_count: usize,
2279 expect_count: usize,
2260 ) {
2280 ) {
2261 let res = self.filter_and_check(m, &HgPathBuf::new());
2281 let res = self.filter_and_check(m, &HgPathBuf::new());
2262 if expect_count != res.len() {
2282 if expect_count != res.0.len() {
2263 eprintln!(
2283 eprintln!(
2264 "warning: expected {} matches, got {} for {:#?}",
2284 "warning: expected {} matches, got {} for {:#?}",
2265 expect_count,
2285 expect_count,
2266 res.len(),
2286 res.0.len(),
2267 m
2287 m
2268 );
2288 );
2269 }
2289 }
General Comments 0
You need to be logged in to leave comments. Login now