diff --git a/functions/webhook/parseGitPatch.js b/functions/webhook/parseGitPatch.js index 1efb961..cd0dacb 100644 --- a/functions/webhook/parseGitPatch.js +++ b/functions/webhook/parseGitPatch.js @@ -67,8 +67,8 @@ export function parseGitPatch(patch) { const [, a, b] = match4 - let nA = parseInt(a) - let nB = parseInt(b) + let nA = parseInt(a) - 1 + let nB = parseInt(b) - 1 lines.forEach(line => { nA++ diff --git a/tests/functions/webhook/fixture.leading_blank_line.diff b/tests/functions/webhook/fixture.leading_blank_line.diff new file mode 100644 index 0000000..f45c6b1 --- /dev/null +++ b/tests/functions/webhook/fixture.leading_blank_line.diff @@ -0,0 +1,12 @@ +diff --git a/src/App.tsx b/src/App.tsx +index 898cc83..eebeccc 100644 +--- a/src/App.tsx ++++ b/src/App.tsx +@@ -5,6 +5,7 @@ import { useAuthContext } from './hooks/useAuthContext' + + function App() { + const { isLoggedIn, login } = useAuthContext() ++ console.log('hello world') + return ( + <> +
diff --git a/tests/functions/webhook/fixture.nominal_multi_files.diff b/tests/functions/webhook/fixture.nominal_multi_files.diff new file mode 100644 index 0000000..d3c7754 --- /dev/null +++ b/tests/functions/webhook/fixture.nominal_multi_files.diff @@ -0,0 +1,50 @@ +diff --git a/package.json b/package.json +index babfea0..abf98a6 100644 +--- a/package.json ++++ b/package.json +@@ -2,7 +2,10 @@ + "name": "@nearform/quantum", + "version": "0.2.0", + "description": "Component library based on the Quantum Design System", +- "main": "dist/index.js", ++ "exports": { ++ ".": "./dist/index.js", ++ "./plugin": "./dist/plugin.js" ++ }, + "scripts": { + "build": "tsup", + "lint": "eslint .", +diff --git a/src/plugin.js b/src/plugin.js +new file mode 100644 +index 0000000..3f8185c +--- /dev/null ++++ b/src/plugin.js +@@ -0,0 +1,10 @@ ++const quantumConfig = require('../tailwind.config.js') ++const plugin = require('tailwindcss/plugin') ++ ++const quantumPlugin = plugin(() => {}, { ++ theme: { ++ ...quantumConfig.theme ++ } ++}) ++ ++module.exports = quantumPlugin +diff --git a/tsup.config.ts b/tsup.config.ts +index 143fd12..c0e6ed0 100644 +--- a/tsup.config.ts ++++ b/tsup.config.ts +@@ -1,7 +1,12 @@ + import { defineConfig } from 'tsup' + + export default defineConfig({ +- entry: ['src/index.ts', 'src/global.css', 'src/colors/index.ts'], ++ entry: [ ++ 'src/index.ts', ++ 'src/global.css', ++ 'src/colors/index.ts', ++ 'src/plugin.js' ++ ], + dts: { entry: ['src/index.ts'] }, + clean: true, + sourcemap: true diff --git a/tests/functions/webhook/fixture.nominal_single_file.diff b/tests/functions/webhook/fixture.nominal_single_file.diff new file mode 100644 index 0000000..314d16d --- /dev/null +++ b/tests/functions/webhook/fixture.nominal_single_file.diff @@ -0,0 +1,19 @@ +diff --git a/functions/webhook/triggerReviews.js b/functions/webhook/triggerReviews.js +index 316c3a5..2b2e758 100644 +--- a/functions/webhook/triggerReviews.js ++++ b/functions/webhook/triggerReviews.js +@@ -85,7 +85,13 @@ export function shouldTriggerLLMReview(payload) { + } + + export function shouldTriggerRuleBasedReview(payload) { +- return payload.pull_request && payload.action === 'ready_for_review' ++ const pullRequest = payload.pull_request ++ return ( ++ pullRequest && ++ pullRequest.user.type === 'User' && ++ (payload.action === 'ready_for_review' || ++ (payload.action === 'opened' && pullRequest.draft === false)) ++ ) + } + + export async function triggerLLMReview(context) { diff --git a/tests/functions/webhook/parseGitPatch.test.js b/tests/functions/webhook/parseGitPatch.test.js new file mode 100644 index 0000000..f135603 --- /dev/null +++ b/tests/functions/webhook/parseGitPatch.test.js @@ -0,0 +1,242 @@ +import { describe, test } from 'node:test' +import assert from 'node:assert' +import { readFileSync } from 'node:fs' +import parseGitPatch from '../../../functions/webhook/parseGitPatch.js' + +import path from 'path' +import url from 'url' +const __dirname = path.dirname(url.fileURLToPath(import.meta.url)) + +describe('Parsing git patches', () => { + test('nominal - single file', () => { + const rawGitPatch = readFileSync( + path.join(__dirname, 'fixture.nominal_single_file.diff'), + 'utf8' + ) + const parsedGitPatch = parseGitPatch(rawGitPatch) + + assert.deepEqual(parsedGitPatch, { + files: [ + { + added: false, + deleted: false, + beforeName: 'functions/webhook/triggerReviews.js', + afterName: 'functions/webhook/triggerReviews.js', + modifiedLines: [ + { + added: false, + lineNumber: 88, + line: " return payload.pull_request && payload.action === 'ready_for_review'" + }, + { + added: true, + lineNumber: 88, + line: ' const pullRequest = payload.pull_request' + }, + { + added: true, + lineNumber: 89, + line: ' return (' + }, + { + added: true, + lineNumber: 90, + line: ' pullRequest &&' + }, + { + added: true, + lineNumber: 91, + line: " pullRequest.user.type === 'User' &&" + }, + { + added: true, + lineNumber: 92, + line: " (payload.action === 'ready_for_review' ||" + }, + { + added: true, + lineNumber: 93, + line: " (payload.action === 'opened' && pullRequest.draft === false))" + }, + { + added: true, + lineNumber: 94, + line: ' )' + } + ] + } + ] + }) + }) + + test('nominal - multi files', () => { + const rawGitPatch = readFileSync( + path.join(__dirname, 'fixture.nominal_multi_files.diff'), + 'utf8' + ) + const parsedGitPatch = parseGitPatch(rawGitPatch) + + assert.deepEqual(parsedGitPatch, { + files: [ + { + added: false, + deleted: false, + beforeName: 'package.json', + afterName: 'package.json', + modifiedLines: [ + { + added: false, + lineNumber: 5, + line: ' "main": "dist/index.js",' + }, + { + added: true, + lineNumber: 5, + line: ' "exports": {' + }, + { + added: true, + lineNumber: 6, + line: ' ".": "./dist/index.js",' + }, + { + added: true, + lineNumber: 7, + line: ' "./plugin": "./dist/plugin.js"' + }, + { + added: true, + lineNumber: 8, + line: ' },' + } + ] + }, + { + added: true, + deleted: false, + beforeName: 'src/plugin.js', + afterName: 'src/plugin.js', + modifiedLines: [ + { + added: true, + lineNumber: 1, + line: "const quantumConfig = require('../tailwind.config.js')" + }, + { + added: true, + lineNumber: 2, + line: "const plugin = require('tailwindcss/plugin')" + }, + { + added: true, + lineNumber: 3, + line: '' + }, + { + added: true, + lineNumber: 4, + line: 'const quantumPlugin = plugin(() => {}, {' + }, + { + added: true, + lineNumber: 5, + line: ' theme: {' + }, + { + added: true, + lineNumber: 6, + line: ' ...quantumConfig.theme' + }, + { + added: true, + lineNumber: 7, + line: ' }' + }, + { + added: true, + lineNumber: 8, + line: '})' + }, + { + added: true, + lineNumber: 9, + line: '' + }, + { + added: true, + lineNumber: 10, + line: 'module.exports = quantumPlugin' + } + ] + }, + { + added: false, + deleted: false, + beforeName: 'tsup.config.ts', + afterName: 'tsup.config.ts', + modifiedLines: [ + { + added: false, + lineNumber: 4, + line: " entry: ['src/index.ts', 'src/global.css', 'src/colors/index.ts']," + }, + { + added: true, + lineNumber: 4, + line: ' entry: [' + }, + { + added: true, + lineNumber: 5, + line: " 'src/index.ts'," + }, + { + added: true, + lineNumber: 6, + line: " 'src/global.css'," + }, + { + added: true, + lineNumber: 7, + line: " 'src/colors/index.ts'," + }, + { + added: true, + lineNumber: 8, + line: " 'src/plugin.js'" + }, + { + added: true, + lineNumber: 9, + line: ' ],' + } + ] + } + ] + }) + }) + + test('Leading blank line is counted', () => { + const rawGitPatch = readFileSync( + path.join(__dirname, 'fixture.leading_blank_line.diff'), + 'utf8' + ) + const parsedGitPatch = parseGitPatch(rawGitPatch) + + assert.ok(parsedGitPatch.files) + assert.equal(parsedGitPatch.files.length, 1) + assert.deepEqual(parsedGitPatch.files[0], { + added: false, + deleted: false, + beforeName: 'src/App.tsx', + afterName: 'src/App.tsx', + modifiedLines: [ + { + added: true, + lineNumber: 8, + line: " console.log('hello world')" + } + ] + }) + }) +})