Skip to content

Commit

Permalink
[Beta] Implement the new structure of the match object for the change…
Browse files Browse the repository at this point in the history
…d-files section (#680)

* Implement the new structure of the match object for changed files section

* Replace inner loops with the find method
  • Loading branch information
MaksimZhukov committed Sep 20, 2023
1 parent 4f05277 commit f4eefdc
Show file tree
Hide file tree
Showing 8 changed files with 612 additions and 115 deletions.
190 changes: 152 additions & 38 deletions __tests__/changedFiles.test.ts
Expand Up @@ -2,7 +2,11 @@ import {
ChangedFilesMatchConfig,
checkAllChangedFiles,
checkAnyChangedFiles,
toChangedFilesMatchConfig
toChangedFilesMatchConfig,
checkIfAnyGlobMatchesAnyFile,
checkIfAllGlobsMatchAnyFile,
checkIfAnyGlobMatchesAllFiles,
checkIfAllGlobsMatchAllFiles
} from '../src/changedFiles';

jest.mock('@actions/core');
Expand All @@ -11,20 +15,28 @@ jest.mock('@actions/github');
describe('checkAllChangedFiles', () => {
const changedFiles = ['foo.txt', 'bar.txt'];

describe('when the globs match every file that has been changed', () => {
const globs = ['*.txt'];
describe('when all given glob pattern configs matched', () => {
const globPatternsConfigs = [
{AnyGlobToAnyFile: ['foo.txt']},
{AnyGlobToAllFiles: ['*.txt']},
{AllGlobsToAllFiles: ['**']}
];

it('returns true', () => {
const result = checkAllChangedFiles(changedFiles, globs);
const result = checkAllChangedFiles(changedFiles, globPatternsConfigs);
expect(result).toBe(true);
});
});

describe(`when the globs don't match every file that has changed`, () => {
const globs = ['foo.txt'];
describe(`when some given glob pattern config did not match`, () => {
const globPatternsConfigs = [
{AnyGlobToAnyFile: ['*.md']},
{AnyGlobToAllFiles: ['*.txt']},
{AllGlobsToAllFiles: ['**']}
];

it('returns false', () => {
const result = checkAllChangedFiles(changedFiles, globs);
const result = checkAllChangedFiles(changedFiles, globPatternsConfigs);
expect(result).toBe(false);
});
});
Expand All @@ -33,20 +45,26 @@ describe('checkAllChangedFiles', () => {
describe('checkAnyChangedFiles', () => {
const changedFiles = ['foo.txt', 'bar.txt'];

describe('when any glob matches any of the files that have changed', () => {
const globs = ['*.txt', '*.md'];
describe('when any given glob pattern config matched', () => {
const globPatternsConfigs = [
{AnyGlobToAnyFile: ['*.md']},
{AnyGlobToAllFiles: ['*.txt']}
];

it('returns true', () => {
const result = checkAnyChangedFiles(changedFiles, globs);
const result = checkAnyChangedFiles(changedFiles, globPatternsConfigs);
expect(result).toBe(true);
});
});

describe('when none of the globs match any files that have changed', () => {
const globs = ['*.md'];
describe('when none of the given glob pattern configs matched', () => {
const globPatternsConfigs = [
{AnyGlobToAnyFile: ['*.md']},
{AnyGlobToAllFiles: ['!*.txt']}
];

it('returns false', () => {
const result = checkAnyChangedFiles(changedFiles, globs);
const result = checkAnyChangedFiles(changedFiles, globPatternsConfigs);
expect(result).toBe(false);
});
});
Expand All @@ -63,44 +81,140 @@ describe('toChangedFilesMatchConfig', () => {
});

describe(`when there is a 'changed-files' key in the config`, () => {
describe('and the value is an array of strings', () => {
const config = {'changed-files': ['testing']};
describe('but the glob pattern config key is not provided', () => {
const config = {'changed-files': ['bar']};

it('throws the error', () => {
expect(() => {
toChangedFilesMatchConfig(config);
}).toThrow(
`The "changed-files" section must have a valid config structure. Please read the action documentation for more information`
);
});
});

it('sets the value in the config object', () => {
const result = toChangedFilesMatchConfig(config);
expect(result).toEqual<ChangedFilesMatchConfig>({
changedFiles: ['testing']
});
describe('but the glob pattern config key is not valid', () => {
const config = {'changed-files': [{NotValidConfigKey: ['bar']}]};

it('throws the error', () => {
expect(() => {
toChangedFilesMatchConfig(config);
}).toThrow(
`Unknown config options were under "changed-files": NotValidConfigKey`
);
});
});

describe('and the value is a string', () => {
const config = {'changed-files': 'testing'};
describe('and the glob pattern config key is provided', () => {
describe('and the value is an array of strings', () => {
const config = {'changed-files': [{AnyGlobToAnyFile: ['testing']}]};

it(`sets the string as an array in the config object`, () => {
const result = toChangedFilesMatchConfig(config);
expect(result).toEqual<ChangedFilesMatchConfig>({
changedFiles: ['testing']
it('sets the value in the config object', () => {
const result = toChangedFilesMatchConfig(config);
expect(result).toEqual<ChangedFilesMatchConfig>({
changedFiles: [{AnyGlobToAnyFile: ['testing']}]
});
});
});
});

describe('but the value is an empty string', () => {
const config = {'changed-files': ''};
describe('and the value is a string', () => {
const config = {'changed-files': [{AnyGlobToAnyFile: 'testing'}]};

it(`returns an empty object`, () => {
const result = toChangedFilesMatchConfig(config);
expect(result).toEqual<ChangedFilesMatchConfig>({});
it(`sets the string as an array in the config object`, () => {
const result = toChangedFilesMatchConfig(config);
expect(result).toEqual<ChangedFilesMatchConfig>({
changedFiles: [{AnyGlobToAnyFile: ['testing']}]
});
});
});
});
});
});

describe('but the value is an empty array', () => {
const config = {'changed-files': []};
describe('checkIfAnyGlobMatchesAnyFile', () => {
const changedFiles = ['foo.txt', 'bar.txt'];

it(`returns an empty object`, () => {
const result = toChangedFilesMatchConfig(config);
expect(result).toEqual<ChangedFilesMatchConfig>({});
});
describe('when any given glob pattern matched any file', () => {
const globPatterns = ['*.md', 'foo.txt'];

it('returns true', () => {
const result = checkIfAnyGlobMatchesAnyFile(changedFiles, globPatterns);
expect(result).toBe(true);
});
});

describe('when none of the given glob pattern matched any file', () => {
const globPatterns = ['*.md', '!*.txt'];

it('returns false', () => {
const result = checkIfAnyGlobMatchesAnyFile(changedFiles, globPatterns);
expect(result).toBe(false);
});
});
});

describe('checkIfAllGlobsMatchAnyFile', () => {
const changedFiles = ['foo.txt', 'bar.txt'];

describe('when all given glob patterns matched any file', () => {
const globPatterns = ['**/bar.txt', 'bar.txt'];

it('returns true', () => {
const result = checkIfAllGlobsMatchAnyFile(changedFiles, globPatterns);
expect(result).toBe(true);
});
});

describe('when some of the given glob patterns did not match any file', () => {
const globPatterns = ['*.txt', '*.md'];

it('returns false', () => {
const result = checkIfAllGlobsMatchAnyFile(changedFiles, globPatterns);
expect(result).toBe(false);
});
});
});

describe('checkIfAnyGlobMatchesAllFiles', () => {
const changedFiles = ['foo.txt', 'bar.txt'];

describe('when any given glob pattern matched all files', () => {
const globPatterns = ['*.md', '*.txt'];

it('returns true', () => {
const result = checkIfAnyGlobMatchesAllFiles(changedFiles, globPatterns);
expect(result).toBe(true);
});
});

describe('when none of the given glob patterns matched all files', () => {
const globPatterns = ['*.md', 'bar.txt', 'foo.txt'];

it('returns false', () => {
const result = checkIfAnyGlobMatchesAllFiles(changedFiles, globPatterns);
expect(result).toBe(false);
});
});
});

describe('checkIfAllGlobsMatchAllFiles', () => {
const changedFiles = ['foo.txt', 'bar.txt'];

describe('when all given glob patterns matched all files', () => {
const globPatterns = ['*.txt', '**'];

it('returns true', () => {
const result = checkIfAllGlobsMatchAllFiles(changedFiles, globPatterns);
expect(result).toBe(true);
});
});

describe('when some of the given glob patterns did not match all files', () => {
const globPatterns = ['**', 'foo.txt'];

it('returns false', () => {
const result = checkIfAllGlobsMatchAllFiles(changedFiles, globPatterns);
expect(result).toBe(false);
});
});
});
9 changes: 6 additions & 3 deletions __tests__/fixtures/all_options.yml
@@ -1,14 +1,17 @@
label1:
- any:
- changed-files: ['glob']
- changed-files:
- AnyGlobToAnyFile: ['glob']
- head-branch: ['regexp']
- base-branch: ['regexp']
- all:
- changed-files: ['glob']
- changed-files:
- AllGlobsToAllFiles: ['glob']
- head-branch: ['regexp']
- base-branch: ['regexp']

label2:
- changed-files: ['glob']
- changed-files:
- AnyGlobToAnyFile: ['glob']
- head-branch: ['regexp']
- base-branch: ['regexp']
6 changes: 4 additions & 2 deletions __tests__/fixtures/any_and_all.yml
@@ -1,6 +1,8 @@
tests:
- any:
- head-branch: ['^tests/', '^test/']
- changed-files: ['tests/**/*']
- changed-files:
- AnyGlobToAnyFile: ['tests/**/*']
- all:
- changed-files: ['!tests/requirements.txt']
- changed-files:
- AllGlobsToAllFiles: ['!tests/requirements.txt']
3 changes: 2 additions & 1 deletion __tests__/fixtures/only_pdfs.yml
@@ -1,2 +1,3 @@
touched-a-pdf-file:
- changed-files: ['*.pdf']
- changed-files:
- AnyGlobToAnyFile: ['*.pdf']
25 changes: 16 additions & 9 deletions __tests__/labeler.test.ts
Expand Up @@ -29,14 +29,14 @@ describe('getLabelConfigMapFromObject', () => {
expected.set('label1', [
{
any: [
{changedFiles: ['glob']},
{changedFiles: [{AnyGlobToAnyFile: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
},
{
all: [
{changedFiles: ['glob']},
{changedFiles: [{AllGlobsToAllFiles: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
Expand All @@ -45,7 +45,7 @@ describe('getLabelConfigMapFromObject', () => {
expected.set('label2', [
{
any: [
{changedFiles: ['glob']},
{changedFiles: [{AnyGlobToAnyFile: ['glob']}]},
{baseBranch: undefined, headBranch: ['regexp']},
{baseBranch: ['regexp'], headBranch: undefined}
]
Expand All @@ -61,12 +61,12 @@ describe('getLabelConfigMapFromObject', () => {
describe('toMatchConfig', () => {
describe('when all expected config options are present', () => {
const config = {
'changed-files': ['testing-files'],
'changed-files': [{AnyGlobToAnyFile: ['testing-files']}],
'head-branch': ['testing-head'],
'base-branch': ['testing-base']
};
const expected: BaseMatchConfig = {
changedFiles: ['testing-files'],
changedFiles: [{AnyGlobToAnyFile: ['testing-files']}],
headBranch: ['testing-head'],
baseBranch: ['testing-base']
};
Expand All @@ -89,7 +89,9 @@ describe('toMatchConfig', () => {

describe('checkMatchConfigs', () => {
describe('when a single match config is provided', () => {
const matchConfig: MatchConfig[] = [{any: [{changedFiles: ['*.txt']}]}];
const matchConfig: MatchConfig[] = [
{any: [{changedFiles: [{AnyGlobToAnyFile: ['*.txt']}]}]}
];

it('returns true when our pattern does match changed files', () => {
const changedFiles = ['foo.txt', 'bar.txt'];
Expand All @@ -107,7 +109,12 @@ describe('checkMatchConfigs', () => {

it('returns true when either the branch or changed files patter matches', () => {
const matchConfig: MatchConfig[] = [
{any: [{changedFiles: ['*.txt']}, {headBranch: ['some-branch']}]}
{
any: [
{changedFiles: [{AnyGlobToAnyFile: ['*.txt']}]},
{headBranch: ['some-branch']}
]
}
];
const changedFiles = ['foo.txt', 'bar.txt'];

Expand All @@ -118,7 +125,7 @@ describe('checkMatchConfigs', () => {

describe('when multiple MatchConfigs are supplied', () => {
const matchConfig: MatchConfig[] = [
{any: [{changedFiles: ['*.txt']}]},
{any: [{changedFiles: [{AnyGlobToAnyFile: ['*.txt']}]}]},
{any: [{headBranch: ['some-branch']}]}
];
const changedFiles = ['foo.txt', 'bar.md'];
Expand All @@ -130,7 +137,7 @@ describe('checkMatchConfigs', () => {

it('returns true when only both config matches', () => {
const matchConfig: MatchConfig[] = [
{any: [{changedFiles: ['*.txt']}]},
{any: [{changedFiles: [{AnyGlobToAnyFile: ['*.txt']}]}]},
{any: [{headBranch: ['head-branch']}]}
];
const result = checkMatchConfigs(changedFiles, matchConfig);
Expand Down

0 comments on commit f4eefdc

Please sign in to comment.