Extend filter syntax with optional specification of file status: add, modified, deleted (#22)

* Add support for specification of change type (add,modified,delete)

* Use NULL as separator in git-diff command output

* Improve PR test workflow

* Fix the workflow file
This commit is contained in:
Michal Dorner 2020-07-11 17:17:56 +02:00
parent caef9bef1f
commit 1ff702da35
No known key found for this signature in database
GPG key ID: 9EEE04B48DA36786
11 changed files with 397 additions and 90 deletions

View file

@ -1,4 +1,5 @@
import Filter from '../src/filter'
import {File, ChangeStatus} from '../src/file'
describe('yaml filter parsing tests', () => {
test('throws if yaml is not a dictionary', () => {
@ -6,14 +7,6 @@ describe('yaml filter parsing tests', () => {
const t = () => new Filter(yaml)
expect(t).toThrow(/^Invalid filter.*/)
})
test('throws on invalid yaml', () => {
const yaml = `
src:
src/**/*.js
`
const t = () => new Filter(yaml)
expect(t).toThrow(/^Invalid filter.*/)
})
test('throws if pattern is not a string', () => {
const yaml = `
src:
@ -27,13 +20,21 @@ describe('yaml filter parsing tests', () => {
})
describe('matching tests', () => {
test('matches single inline rule', () => {
const yaml = `
src: "src/**/*.js"
`
let filter = new Filter(yaml)
const match = filter.match(modified(['src/app/module/file.js']))
expect(match.src).toBeTruthy()
})
test('matches single rule in single group', () => {
const yaml = `
src:
- src/**/*.js
`
const filter = new Filter(yaml)
const match = filter.match(['src/app/module/file.js'])
const match = filter.match(modified(['src/app/module/file.js']))
expect(match.src).toBeTruthy()
})
@ -43,7 +44,7 @@ describe('matching tests', () => {
- src/**/*.js
`
const filter = new Filter(yaml)
const match = filter.match(['not_src/other_file.js'])
const match = filter.match(modified(['not_src/other_file.js']))
expect(match.src).toBeFalsy()
})
@ -55,7 +56,7 @@ describe('matching tests', () => {
- test/**/*.js
`
const filter = new Filter(yaml)
const match = filter.match(['test/test.js'])
const match = filter.match(modified(['test/test.js']))
expect(match.src).toBeFalsy()
expect(match.test).toBeTruthy()
})
@ -67,7 +68,7 @@ describe('matching tests', () => {
- test/**/*.js
`
const filter = new Filter(yaml)
const match = filter.match(['test/test.js'])
const match = filter.match(modified(['test/test.js']))
expect(match.src).toBeTruthy()
})
@ -77,7 +78,7 @@ describe('matching tests', () => {
- "**/*"
`
const filter = new Filter(yaml)
const match = filter.match(['test/test.js'])
const match = filter.match(modified(['test/test.js']))
expect(match.any).toBeTruthy()
})
@ -87,7 +88,7 @@ describe('matching tests', () => {
- "**/*.js"
`
const filter = new Filter(yaml)
const match = filter.match(['.test/.test.js'])
const match = filter.match(modified(['.test/.test.js']))
expect(match.dot).toBeTruthy()
})
@ -101,7 +102,44 @@ describe('matching tests', () => {
- src/**/*
`
let filter = new Filter(yaml)
const match = filter.match(['config/settings.yml'])
const match = filter.match(modified(['config/settings.yml']))
expect(match.src).toBeTruthy()
})
})
describe('matching specific change status', () => {
test('does not match modified file as added', () => {
const yaml = `
add:
- added: "**/*"
`
let filter = new Filter(yaml)
const match = filter.match(modified(['file.js']))
expect(match.add).toBeFalsy()
})
test('match added file as added', () => {
const yaml = `
add:
- added: "**/*"
`
let filter = new Filter(yaml)
const match = filter.match([{status: ChangeStatus.Added, filename: 'file.js'}])
expect(match.add).toBeTruthy()
})
test('matches when multiple statuses are configured', () => {
const yaml = `
addOrModify:
- added|modified: "**/*"
`
let filter = new Filter(yaml)
const match = filter.match([{status: ChangeStatus.Modified, filename: 'file.js'}])
expect(match.addOrModify).toBeTruthy()
})
})
function modified(paths: string[]): File[] {
return paths.map(filename => {
return {filename, status: ChangeStatus.Modified}
})
}

View file

@ -1,4 +1,27 @@
import * as git from '../src/git'
import {ExecOptions} from '@actions/exec'
import {ChangeStatus} from '../src/file'
describe('parsing of the git diff-index command', () => {
test('getChangedFiles returns files with correct change status', async () => {
const files = await git.getChangedFiles(git.FETCH_HEAD, (cmd, args, opts) => {
const stdout = opts?.listeners?.stdout
if (stdout) {
stdout(Buffer.from('A\u0000LICENSE\u0000'))
stdout(Buffer.from('M\u0000src/index.ts\u0000'))
stdout(Buffer.from('D\u0000src/main.ts\u0000'))
}
return Promise.resolve(0)
})
expect(files.length).toBe(3)
expect(files[0].filename).toBe('LICENSE')
expect(files[0].status).toBe(ChangeStatus.Added)
expect(files[1].filename).toBe('src/index.ts')
expect(files[1].status).toBe(ChangeStatus.Modified)
expect(files[2].filename).toBe('src/main.ts')
expect(files[2].status).toBe(ChangeStatus.Deleted)
})
})
describe('git utility function tests (those not invoking git)', () => {
test('Detects if ref references a tag', () => {