diff --git a/cli/commands/run/test.ts b/cli/commands/run/test.ts index 4f11e8a..4515c4a 100644 --- a/cli/commands/run/test.ts +++ b/cli/commands/run/test.ts @@ -60,7 +60,7 @@ export class RunTestCommand extends Command { isContinuousIntegration: this.isContinuousIntegration, base: this.base }) - const solutions = await gitAffected.getAffectedSolutions() + const solutions = await gitAffected.getAffectedSolutionsFromGit() return await Test.runManyWithSolutions(solutions) } if ( diff --git a/cli/services/GitAffected.ts b/cli/services/GitAffected.ts index 3b32699..07bedc8 100644 --- a/cli/services/GitAffected.ts +++ b/cli/services/GitAffected.ts @@ -5,7 +5,7 @@ import { Solution } from './Solution' const solutionsRegex = /challenges\/[\s\S]*\/solutions\/(c|cpp|cs|dart|java|javascript|python|rust|typescript)\/[\s\S]*\/(.*).(c|cpp|cs|dart|java|js|py|rs|ts)/ -const dockerRegex = /templates\/docker\/(c|cpp|cs|dart|java|javascript|python|rust|typescript)\/Dockerfile/ +const dockerRegex = /templates\/docker\/(c|cpp|cs|dart|java|javascript|python|rust|typescript)\/(.*)/ const inputOutputRegex = /challenges\/[\s\S]*\/test\/(.*)\/(input.txt|output.txt)/ @@ -61,15 +61,7 @@ export class GitAffected implements GitAffectedOptions { ) } - public async getAffectedSolutions (): Promise { - let files = [ - ...(await this.getUnpushedFiles()), - ...(await this.getUncommittedFiles()) - ] - if (this.base != null) { - files.push(...(await this.getFilesUsingBaseAndHead(this.base, '.'))) - } - files = Array.from(new Set(files)) + public async getAffectedSolutionsFromFiles (files: string[]): Promise { const affectedSolutionsPaths = files.filter((filePath) => { return solutionsRegex.test(filePath) }) @@ -105,4 +97,16 @@ export class GitAffected implements GitAffectedOptions { } return solutionsUnique } + + public async getAffectedSolutionsFromGit (): Promise { + let files = [ + ...(await this.getUnpushedFiles()), + ...(await this.getUncommittedFiles()) + ] + if (this.base != null) { + files.push(...(await this.getFilesUsingBaseAndHead(this.base, '.'))) + } + files = Array.from(new Set(files)) + return await this.getAffectedSolutionsFromFiles(files) + } } diff --git a/cli/services/__test__/GitAffected.test.ts b/cli/services/__test__/GitAffected.test.ts new file mode 100644 index 0000000..fe5abff --- /dev/null +++ b/cli/services/__test__/GitAffected.test.ts @@ -0,0 +1,104 @@ +import { Challenge } from '../Challenge' +import { GitAffected } from '../GitAffected' +import { Solution } from '../Solution' + +const gitAffected = new GitAffected({ isContinuousIntegration: false }) + +describe('services/GitAffected - parseGitOutput', () => { + it('returns the right output array', () => { + expect(gitAffected.parseGitOutput('1.txt\n 2.txt ')).toEqual(['1.txt', '2.txt']) + }) +}) + +describe('services/GitAffected - getAffectedSolutionsFromFiles', () => { + it('returns the affected solutions', async () => { + const files = [ + 'challenges/hello-world/solutions/javascript/function/solution.js', + 'challenges/is-palindrome/solutions/c/function/input.c' + ] + const solutions = await gitAffected.getAffectedSolutionsFromFiles(files) + expect(solutions).toEqual([ + new Solution({ + challenge: new Challenge({ name: 'hello-world' }), + name: 'function', + programmingLanguageName: 'javascript' + }), + new Solution({ + challenge: new Challenge({ name: 'is-palindrome' }), + name: 'function', + programmingLanguageName: 'c' + }) + ]) + }) + + it('returns the affected solutions from Dockerfile changes', async () => { + const files = ['templates/docker/javascript/Dockerfile'] + const solutions = await gitAffected.getAffectedSolutionsFromFiles(files) + expect(solutions[0]).toEqual( + new Solution({ + challenge: new Challenge({ name: 'camel-case' }), + name: 'function', + programmingLanguageName: 'javascript' + }) + ) + expect(solutions[1]).toEqual( + new Solution({ + challenge: new Challenge({ name: 'first-non-repeating-character' }), + name: 'function', + programmingLanguageName: 'javascript' + }) + ) + }) + + it('returns the affected solutions from Docker template changes', async () => { + const files = ['templates/docker/javascript/package.json'] + const solutions = await gitAffected.getAffectedSolutionsFromFiles(files) + expect(solutions[0]).toEqual( + new Solution({ + challenge: new Challenge({ name: 'camel-case' }), + name: 'function', + programmingLanguageName: 'javascript' + }) + ) + expect(solutions[1]).toEqual( + new Solution({ + challenge: new Challenge({ name: 'first-non-repeating-character' }), + name: 'function', + programmingLanguageName: 'javascript' + }) + ) + }) + + it('returns the affected solutions from input/output files', async () => { + const files = ['challenges/hello-world/test/1/input.txt'] + const solutions = await gitAffected.getAffectedSolutionsFromFiles(files) + expect(solutions[0]).toEqual( + new Solution({ + challenge: new Challenge({ name: 'hello-world' }), + name: 'function', + programmingLanguageName: 'c' + }) + ) + expect(solutions[1]).toEqual( + new Solution({ + challenge: new Challenge({ name: 'hello-world' }), + name: 'function', + programmingLanguageName: 'cpp' + }) + ) + expect(solutions[2]).toEqual( + new Solution({ + challenge: new Challenge({ name: 'hello-world' }), + name: 'function', + programmingLanguageName: 'cs' + }) + ) + expect(solutions[3]).toEqual( + new Solution({ + challenge: new Challenge({ name: 'hello-world' }), + name: 'function', + programmingLanguageName: 'dart' + }) + ) + }) +})