mirror of
https://github.com/dorny/paths-filter.git
synced 2026-03-10 16:34:28 +00:00
test
This commit is contained in:
parent
4fad01a9ab
commit
b2a8b7621d
@ -98,6 +98,31 @@ describe('matching tests', () => {
|
||||
expect(match.dot).toEqual(files)
|
||||
})
|
||||
|
||||
test('does not match when only negated pattern matches', () => {
|
||||
const yaml = `
|
||||
backend:
|
||||
- src/backend/**
|
||||
- '!src/frontend/**'
|
||||
`
|
||||
const filter = new Filter(yaml)
|
||||
const files = modified(['vitest.setup.ts'])
|
||||
const match = filter.match(files)
|
||||
expect(match.backend).toEqual([])
|
||||
})
|
||||
|
||||
test('negated pattern excludes matching files', () => {
|
||||
const yaml = `
|
||||
backend:
|
||||
- '**/*'
|
||||
- '!src/frontend/**'
|
||||
`
|
||||
const filter = new Filter(yaml)
|
||||
const backendFile = modified(['src/backend/main.ts'])
|
||||
const frontendFile = modified(['src/frontend/main.ts'])
|
||||
expect(filter.match(backendFile).backend).toEqual(backendFile)
|
||||
expect(filter.match(frontendFile).backend).toEqual([])
|
||||
})
|
||||
|
||||
test('matches all except tsx and less files (negate a group with or-ed parts)', () => {
|
||||
const yaml = `
|
||||
backend:
|
||||
|
||||
43
dist/index.js
vendored
43
dist/index.js
vendored
@ -130,33 +130,44 @@ class Filter {
|
||||
const aPredicate = (rule) => {
|
||||
return (rule.status === undefined || rule.status.includes(file.status)) && rule.isMatch(file.filename);
|
||||
};
|
||||
if (((_a = this.filterConfig) === null || _a === void 0 ? void 0 : _a.predicateQuantifier) === 'every') {
|
||||
return patterns.every(aPredicate);
|
||||
}
|
||||
else {
|
||||
return patterns.some(aPredicate);
|
||||
}
|
||||
const positives = patterns.filter(p => !p.negate);
|
||||
const negatives = patterns.filter(p => p.negate);
|
||||
const positiveMatch = positives.length === 0
|
||||
? true
|
||||
: ((_a = this.filterConfig) === null || _a === void 0 ? void 0 : _a.predicateQuantifier) === PredicateQuantifier.EVERY
|
||||
? positives.every(aPredicate)
|
||||
: positives.some(aPredicate);
|
||||
const negativeMatch = negatives.some(aPredicate);
|
||||
return positiveMatch && !negativeMatch;
|
||||
}
|
||||
parseFilterItemYaml(item) {
|
||||
if (Array.isArray(item)) {
|
||||
return flat(item.map(i => this.parseFilterItemYaml(i)));
|
||||
}
|
||||
if (typeof item === 'string') {
|
||||
return [{ status: undefined, isMatch: (0, picomatch_1.default)(item, MatchOptions) }];
|
||||
const negated = item.startsWith('!');
|
||||
const pattern = negated ? item.slice(1) : item;
|
||||
return [{ status: undefined, isMatch: (0, picomatch_1.default)(pattern, MatchOptions), negate: negated }];
|
||||
}
|
||||
if (typeof item === 'object') {
|
||||
return Object.entries(item).map(([key, pattern]) => {
|
||||
return Object.entries(item).flatMap(([key, pattern]) => {
|
||||
if (typeof key !== 'string' || (typeof pattern !== 'string' && !Array.isArray(pattern))) {
|
||||
this.throwInvalidFormatError(`Expected [key:string]= pattern:string | string[], but [${key}:${typeof key}]= ${pattern}:${typeof pattern} found`);
|
||||
}
|
||||
return {
|
||||
status: key
|
||||
.split('|')
|
||||
.map(x => x.trim())
|
||||
.filter(x => x.length > 0)
|
||||
.map(x => x.toLowerCase()),
|
||||
isMatch: (0, picomatch_1.default)(pattern, MatchOptions)
|
||||
};
|
||||
const patterns = Array.isArray(pattern) ? pattern : [pattern];
|
||||
return patterns.map(p => {
|
||||
const negated = p.startsWith('!');
|
||||
const pat = negated ? p.slice(1) : p;
|
||||
return {
|
||||
status: key
|
||||
.split('|')
|
||||
.map(x => x.trim())
|
||||
.filter(x => x.length > 0)
|
||||
.map(x => x.toLowerCase()),
|
||||
isMatch: (0, picomatch_1.default)(pat, MatchOptions),
|
||||
negate: negated
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
this.throwInvalidFormatError(`Unexpected element type '${typeof item}'`);
|
||||
|
||||
@ -21,6 +21,7 @@ const MatchOptions = {
|
||||
interface FilterRuleItem {
|
||||
status?: ChangeStatus[] // Required change status of the matched files
|
||||
isMatch: (str: string) => boolean // Matches the filename
|
||||
negate?: boolean // When true, this rule excludes matching files
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,11 +108,20 @@ export class Filter {
|
||||
const aPredicate = (rule: Readonly<FilterRuleItem>): boolean => {
|
||||
return (rule.status === undefined || rule.status.includes(file.status)) && rule.isMatch(file.filename)
|
||||
}
|
||||
if (this.filterConfig?.predicateQuantifier === 'every') {
|
||||
return patterns.every(aPredicate)
|
||||
} else {
|
||||
return patterns.some(aPredicate)
|
||||
}
|
||||
|
||||
const positives = patterns.filter(p => !p.negate)
|
||||
const negatives = patterns.filter(p => p.negate)
|
||||
|
||||
const positiveMatch =
|
||||
positives.length === 0
|
||||
? true
|
||||
: this.filterConfig?.predicateQuantifier === PredicateQuantifier.EVERY
|
||||
? positives.every(aPredicate)
|
||||
: positives.some(aPredicate)
|
||||
|
||||
const negativeMatch = negatives.some(aPredicate)
|
||||
|
||||
return positiveMatch && !negativeMatch
|
||||
}
|
||||
|
||||
private parseFilterItemYaml(item: FilterItemYaml): FilterRuleItem[] {
|
||||
@ -120,24 +130,33 @@ export class Filter {
|
||||
}
|
||||
|
||||
if (typeof item === 'string') {
|
||||
return [{status: undefined, isMatch: picomatch(item, MatchOptions)}]
|
||||
const negated = item.startsWith('!')
|
||||
const pattern = negated ? item.slice(1) : item
|
||||
return [{status: undefined, isMatch: picomatch(pattern, MatchOptions), negate: negated}]
|
||||
}
|
||||
|
||||
if (typeof item === 'object') {
|
||||
return Object.entries(item).map(([key, pattern]) => {
|
||||
return Object.entries(item).flatMap(([key, pattern]) => {
|
||||
if (typeof key !== 'string' || (typeof pattern !== 'string' && !Array.isArray(pattern))) {
|
||||
this.throwInvalidFormatError(
|
||||
`Expected [key:string]= pattern:string | string[], but [${key}:${typeof key}]= ${pattern}:${typeof pattern} found`
|
||||
)
|
||||
}
|
||||
return {
|
||||
status: key
|
||||
.split('|')
|
||||
.map(x => x.trim())
|
||||
.filter(x => x.length > 0)
|
||||
.map(x => x.toLowerCase()) as ChangeStatus[],
|
||||
isMatch: picomatch(pattern, MatchOptions)
|
||||
}
|
||||
|
||||
const patterns = Array.isArray(pattern) ? pattern : [pattern]
|
||||
return patterns.map(p => {
|
||||
const negated = p.startsWith('!')
|
||||
const pat = negated ? p.slice(1) : p
|
||||
return {
|
||||
status: key
|
||||
.split('|')
|
||||
.map(x => x.trim())
|
||||
.filter(x => x.length > 0)
|
||||
.map(x => x.toLowerCase()) as ChangeStatus[],
|
||||
isMatch: picomatch(pat, MatchOptions),
|
||||
negate: negated
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user