diff --git a/lib/manager/gradle-wrapper/__snapshots__/artifacts.spec.ts.snap b/lib/manager/gradle-wrapper/__snapshots__/artifacts.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..a95465409dc1a15a38ab0a5eb2c18354a23f3451 --- /dev/null +++ b/lib/manager/gradle-wrapper/__snapshots__/artifacts.spec.ts.snap @@ -0,0 +1,67 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`manager/gradle-wrapper/artifacts gradlew failed 1`] = ` +Array [ + Object { + "cmd": "<gradlew> wrapper --gradle-version 5.6.4", + "options": Object { + "cwd": "/root/project/lib/manager/gradle-wrapper/__fixtures__/testFiles", + "encoding": "utf-8", + "env": Object { + "HOME": "/home/user", + "HTTPS_PROXY": "https://example.com", + "HTTP_PROXY": "http://example.com", + "LANG": "en_US.UTF-8", + "LC_ALL": "en_US", + "NO_PROXY": "localhost", + "PATH": "/tmp/path", + }, + "timeout": 900000, + }, + }, +] +`; + +exports[`manager/gradle-wrapper/artifacts replaces existing value 1`] = ` +Array [ + Object { + "cmd": "<gradlew> wrapper --gradle-distribution-url https://services.gradle.org/distributions/gradle-6.3-bin.zip", + "options": Object { + "cwd": "/root/project/lib/manager/gradle-wrapper/__fixtures__/testFiles", + "encoding": "utf-8", + "env": Object { + "HOME": "/home/user", + "HTTPS_PROXY": "https://example.com", + "HTTP_PROXY": "http://example.com", + "LANG": "en_US.UTF-8", + "LC_ALL": "en_US", + "NO_PROXY": "localhost", + "PATH": "/tmp/path", + }, + "timeout": 900000, + }, + }, +] +`; + +exports[`manager/gradle-wrapper/artifacts updates distributionSha256Sum 1`] = ` +Array [ + Object { + "cmd": "<gradlew> wrapper --gradle-distribution-url https://services.gradle.org/distributions/gradle-6.3-bin.zip --gradle-distribution-sha256-sum 038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768", + "options": Object { + "cwd": "/root/project/lib/manager/gradle-wrapper/__fixtures__/testFiles", + "encoding": "utf-8", + "env": Object { + "HOME": "/home/user", + "HTTPS_PROXY": "https://example.com", + "HTTP_PROXY": "http://example.com", + "LANG": "en_US.UTF-8", + "LC_ALL": "en_US", + "NO_PROXY": "localhost", + "PATH": "/tmp/path", + }, + "timeout": 900000, + }, + }, +] +`; diff --git a/lib/manager/gradle-wrapper/artifacts-real.spec.ts b/lib/manager/gradle-wrapper/artifacts-real.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..5dafe01c6a41de2d784ed9e330929a9211cae12f --- /dev/null +++ b/lib/manager/gradle-wrapper/artifacts-real.spec.ts @@ -0,0 +1,289 @@ +import { resolve } from 'path'; +import { readFile, readFileSync } from 'fs-extra'; +import Git from 'simple-git/promise'; +import * as httpMock from '../../../test/httpMock'; +import { getName, partial, platform } from '../../../test/util'; +import { setUtilConfig } from '../../util'; +import * as runCache from '../../util/cache/run'; +import { ifSystemSupportsGradle } from '../gradle/__testutil__/gradle'; +import * as dcUpdate from '.'; + +const fixtures = resolve(__dirname, './__fixtures__'); +const config = { + localDir: resolve(fixtures, './testFiles'), + toVersion: '5.6.4', +}; + +function readString(...paths: string[]): Promise<string> { + return readFile(resolve(fixtures, ...paths), 'utf8'); +} + +function readBinSync(...paths: string[]): Buffer { + return readFileSync(resolve(fixtures, ...paths)); +} + +function compareFile(file: string, path: string) { + expect(readBinSync(`./testFiles/${file}`)).toEqual( + readBinSync(`./${path}/${file}`) + ); +} + +describe(getName(__filename), () => { + ifSystemSupportsGradle(6).describe('real tests', () => { + jest.setTimeout(60 * 1000); + + beforeEach(async () => { + jest.resetAllMocks(); + await setUtilConfig(config); + httpMock.setup(); + runCache.clear(); + }); + + afterEach(async () => { + await Git(fixtures).checkout(['HEAD', '--', '.']); + httpMock.reset(); + }); + + it('replaces existing value', async () => { + platform.getRepoStatus.mockResolvedValue({ + modified: [ + 'gradle/wrapper/gradle-wrapper.properties', + 'gradle/wrapper/gradle-wrapper.jar', + 'gradlew', + 'gradlew.bat', + ], + } as Git.StatusResult); + + const res = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle/wrapper/gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: await readString( + `./expectedFiles/gradle/wrapper/gradle-wrapper.properties` + ), + config: { ...config, toVersion: '6.3' }, + }); + + expect(res).toEqual( + [ + 'gradle/wrapper/gradle-wrapper.properties', + 'gradle/wrapper/gradle-wrapper.jar', + 'gradlew', + 'gradlew.bat', + ].map((fileProjectPath) => { + return { + file: { + name: fileProjectPath, + contents: readBinSync(`./testFiles/${fileProjectPath}`), + }, + }; + }) + ); + + [ + 'gradle/wrapper/gradle-wrapper.properties', + 'gradle/wrapper/gradle-wrapper.jar', + 'gradlew', + 'gradlew.bat', + ].forEach((file) => { + compareFile(file, 'expectedFiles'); + }); + }); + + it('updates from version', async () => { + platform.getRepoStatus.mockResolvedValueOnce( + partial<Git.StatusResult>({ + modified: ['gradle/wrapper/gradle-wrapper.properties'], + }) + ); + + const result = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle/wrapper/gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: ``, + config: { ...config, toVersion: '6.3' }, + }); + + expect(result).toHaveLength(1); + expect(result[0].artifactError).toBeUndefined(); + + compareFile('gradle/wrapper/gradle-wrapper.properties', 'expectedFiles'); + }); + + it('up to date', async () => { + platform.getRepoStatus.mockResolvedValue({ + modified: [], + } as Git.StatusResult); + + const res = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle/wrapper/gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: await readString( + `./testFiles/gradle/wrapper/gradle-wrapper.properties` + ), + config, + }); + + expect(res).toEqual([]); + + // 5.6.4 => 5.6.4 (updates execs) + // 6.3 => (5.6.4) (downgrades execs) + // looks like a bug in Gradle + ['gradle/wrapper/gradle-wrapper.properties'].forEach((file) => { + compareFile(file, 'testFiles-copy'); + }); + }); + + it('getRepoStatus fails', async () => { + platform.getRepoStatus.mockImplementation(() => { + throw new Error('failed'); + }); + + const res = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle/wrapper/gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: await readString( + `./testFiles/gradle/wrapper/gradle-wrapper.properties` + ), + config, + }); + + expect(res[0].artifactError.lockFile).toEqual( + 'gradle/wrapper/gradle-wrapper.properties' + ); + expect(res[0].artifactError.stderr).toEqual('failed'); + + // 5.6.4 => 5.6.4 (updates execs) - unexpected behavior (looks like a bug in Gradle) + ['gradle/wrapper/gradle-wrapper.properties'].forEach((file) => { + compareFile(file, 'testFiles-copy'); + }); + }); + + it('gradlew failed', async () => { + const cfg = { ...config, localDir: resolve(fixtures, './wrongCmd') }; + + await setUtilConfig(cfg); + const res = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle/wrapper/gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: await readString( + `./testFiles/gradle/wrapper/gradle-wrapper.properties` + ), + config: cfg, + }); + + expect(res[0].artifactError.lockFile).toEqual( + 'gradle/wrapper/gradle-wrapper.properties' + ); + expect(res[0].artifactError.stderr).not.toBeNull(); + expect(res[0].artifactError.stderr).not.toEqual(''); + + // 5.6.4 => 5.6.4 (updates execs) - unexpected behavior (looks like a bug in Gradle) + ['gradle/wrapper/gradle-wrapper.properties'].forEach((file) => { + compareFile(file, 'testFiles-copy'); + }); + }); + + it('gradlew not found', async () => { + const res = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: undefined, + config: { + localDir: 'some-dir', + }, + }); + + expect(res).toBeNull(); + }); + + it('updates distributionSha256Sum', async () => { + httpMock + .scope('https://services.gradle.org') + .get('/distributions/gradle-6.3-bin.zip.sha256') + .reply( + 200, + '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768' + ); + + platform.getRepoStatus.mockResolvedValueOnce( + partial<Git.StatusResult>({ + modified: ['gradle/wrapper/gradle-wrapper.properties'], + }) + ); + + const newContent = await readString(`./gradle-wrapper-sum.properties`); + + const result = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle/wrapper/gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: newContent.replace( + '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768', + '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d' + ), + config: { + ...config, + toVersion: '6.3', + currentValue: '5.6.4', + }, + }); + + expect(result).toHaveLength(1); + expect(result[0].artifactError).toBeUndefined(); + + expect( + await readString( + config.localDir, + `./gradle/wrapper/gradle-wrapper.properties` + ) + ).toEqual(newContent); + + expect(httpMock.getTrace()).toEqual([ + { + headers: { + 'accept-encoding': 'gzip, deflate', + host: 'services.gradle.org', + 'user-agent': 'https://github.com/renovatebot/renovate', + }, + method: 'GET', + url: + 'https://services.gradle.org/distributions/gradle-6.3-bin.zip.sha256', + }, + ]); + }); + + it('distributionSha256Sum 404', async () => { + httpMock + .scope('https://services.gradle.org') + .get('/distributions/gradle-6.3-bin.zip.sha256') + .reply(404); + + const result = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle/wrapper/gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: `distributionSha256Sum=336b6898b491f6334502d8074a6b8c2d73ed83b92123106bd4bf837f04111043\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.3-bin.zip`, + config, + }); + + expect(result).toEqual([ + { + artifactError: { + lockFile: 'gradle/wrapper/gradle-wrapper.properties', + stderr: 'Response code 404 (Not Found)', + }, + }, + ]); + expect(httpMock.getTrace()).toEqual([ + { + headers: { + 'accept-encoding': 'gzip, deflate', + host: 'services.gradle.org', + 'user-agent': 'https://github.com/renovatebot/renovate', + }, + method: 'GET', + url: + 'https://services.gradle.org/distributions/gradle-6.3-bin.zip.sha256', + }, + ]); + }); + }); +}); diff --git a/lib/manager/gradle-wrapper/artifacts.spec.ts b/lib/manager/gradle-wrapper/artifacts.spec.ts index c6994b2843d54b9fd2a069115022fd0431a54cbc..8c863ac49ca9f3bc5857dca45d738ac8939b6762 100644 --- a/lib/manager/gradle-wrapper/artifacts.spec.ts +++ b/lib/manager/gradle-wrapper/artifacts.spec.ts @@ -1,297 +1,204 @@ +import { exec as _exec } from 'child_process'; import { resolve } from 'path'; -import { readFile, readFileSync } from 'fs-extra'; +import { readFile } from 'fs-extra'; import Git from 'simple-git/promise'; +import { envMock, mockExecAll } from '../../../test/execUtil'; import * as httpMock from '../../../test/httpMock'; import { - bufferSerializer, + addReplacingSerializer, + env, + fs, getName, partial, platform, } from '../../../test/util'; import { setUtilConfig } from '../../util'; -import * as runCache from '../../util/cache/run'; -import { ifSystemSupportsGradle } from '../gradle/__testutil__/gradle'; +import { BinarySource } from '../../util/exec/common'; +import { resetPrefetchedImages } from '../../util/exec/docker'; import * as dcUpdate from '.'; +jest.mock('child_process'); +jest.mock('../../util/fs'); +jest.mock('../../util/exec/env'); + +const exec: jest.Mock<typeof _exec> = _exec as any; const fixtures = resolve(__dirname, './__fixtures__'); const config = { localDir: resolve(fixtures, './testFiles'), toVersion: '5.6.4', }; +const dockerConfig = { ...config, binarySource: BinarySource.Docker }; -jest.mock('../../platform'); - -expect.addSnapshotSerializer(bufferSerializer()); +addReplacingSerializer('gradlew.bat', '<gradlew>'); +addReplacingSerializer('./gradlew', '<gradlew>'); function readString(...paths: string[]): Promise<string> { return readFile(resolve(fixtures, ...paths), 'utf8'); } -function readBinSync(...paths: string[]): Buffer { - return readFileSync(resolve(fixtures, ...paths)); -} - -function compareFile(file: string, path: string) { - expect(readBinSync(`./testFiles/${file}`)).toEqual( - readBinSync(`./${path}/${file}`) - ); -} - describe(getName(__filename), () => { - ifSystemSupportsGradle(6).describe('real tests', () => { - jest.setTimeout(60 * 1000); - - beforeEach(async () => { - jest.resetAllMocks(); - await setUtilConfig(config); - httpMock.setup(); - runCache.clear(); + beforeEach(async () => { + jest.resetAllMocks(); + httpMock.setup(); + + env.getChildProcessEnv.mockReturnValue({ + ...envMock.basic, + LANG: 'en_US.UTF-8', + LC_ALL: 'en_US', }); - afterEach(async () => { - await Git(fixtures)?.checkout(['HEAD', '--', '.']); - httpMock.reset(); - }); - - it('replaces existing value', async () => { - platform.getRepoStatus.mockResolvedValue({ - modified: [ - 'gradle/wrapper/gradle-wrapper.properties', - 'gradle/wrapper/gradle-wrapper.jar', - 'gradlew', - 'gradlew.bat', - ], - } as Git.StatusResult); + await setUtilConfig(config); + resetPrefetchedImages(); - const res = await dcUpdate.updateArtifacts({ - packageFileName: 'gradle/wrapper/gradle-wrapper.properties', - updatedDeps: [], - newPackageFileContent: await readString( - `./expectedFiles/gradle/wrapper/gradle-wrapper.properties` - ), - config: { ...config, toVersion: '6.3' }, - }); + fs.readLocalFile.mockResolvedValue('test'); + }); - expect(res).toEqual( - [ - 'gradle/wrapper/gradle-wrapper.properties', - 'gradle/wrapper/gradle-wrapper.jar', - 'gradlew', - 'gradlew.bat', - ].map((fileProjectPath) => { - return { - file: { - name: fileProjectPath, - contents: readBinSync(`./testFiles/${fileProjectPath}`), - }, - }; - }) - ); + afterEach(() => { + httpMock.reset(); + }); - [ + it('replaces existing value', async () => { + platform.getRepoStatus.mockResolvedValue({ + modified: [ 'gradle/wrapper/gradle-wrapper.properties', - 'gradle/wrapper/gradle-wrapper.jar', 'gradlew', 'gradlew.bat', - ].forEach((file) => { - compareFile(file, 'expectedFiles'); - }); + ], + } as Git.StatusResult); + + const execSnapshots = mockExecAll(exec); + + const res = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: await readString( + `./expectedFiles/gradle/wrapper/gradle-wrapper.properties` + ), + config: { ...config, toVersion: '6.3' }, }); - it('updates from version', async () => { - platform.getRepoStatus.mockResolvedValueOnce( - partial<Git.StatusResult>({ - modified: ['gradle/wrapper/gradle-wrapper.properties'], - }) - ); - - const result = await dcUpdate.updateArtifacts({ - packageFileName: 'gradle/wrapper/gradle-wrapper.properties', - updatedDeps: [], - newPackageFileContent: ``, - config: { ...config, toVersion: '6.3' }, - }); - - expect(result).toHaveLength(1); - expect(result[0].artifactError).toBeUndefined(); - - compareFile('gradle/wrapper/gradle-wrapper.properties', 'expectedFiles'); - }); - - it('up to date', async () => { - platform.getRepoStatus.mockResolvedValue({ - modified: [], - } as Git.StatusResult); - - const res = await dcUpdate.updateArtifacts({ - packageFileName: 'gradle/wrapper/gradle-wrapper.properties', - updatedDeps: [], - newPackageFileContent: await readString( - `./testFiles/gradle/wrapper/gradle-wrapper.properties` - ), - config, - }); - - expect(res).toEqual([]); + expect(res).toEqual( + [ + 'gradle/wrapper/gradle-wrapper.properties', + 'gradlew', + 'gradlew.bat', + ].map((fileProjectPath) => { + return { + file: { + name: fileProjectPath, + contents: 'test', + }, + }; + }) + ); + expect(execSnapshots).toMatchSnapshot(); + }); - // 5.6.4 => 5.6.4 (updates execs) - // 6.3 => (5.6.4) (downgrades execs) - // looks like a bug in Gradle - ['gradle/wrapper/gradle-wrapper.properties'].forEach((file) => { - compareFile(file, 'testFiles-copy'); - }); + it('gradlew not found', async () => { + const res = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: undefined, + config: { + localDir: 'some-dir', + }, }); - it('getRepoStatus fails', async () => { - platform.getRepoStatus.mockImplementation(() => { - throw new Error('failed'); - }); - - const res = await dcUpdate.updateArtifacts({ - packageFileName: 'gradle/wrapper/gradle-wrapper.properties', - updatedDeps: [], - newPackageFileContent: await readString( - `./testFiles/gradle/wrapper/gradle-wrapper.properties` - ), - config, - }); - - expect(res[0].artifactError.lockFile).toEqual( - 'gradle/wrapper/gradle-wrapper.properties' - ); - expect(res[0].artifactError.stderr).toEqual('failed'); + expect(res).toBeNull(); + }); - // 5.6.4 => 5.6.4 (updates execs) - unexpected behavior (looks like a bug in Gradle) - ['gradle/wrapper/gradle-wrapper.properties'].forEach((file) => { - compareFile(file, 'testFiles-copy'); - }); + it('gradlew failed', async () => { + const execSnapshots = mockExecAll(exec, new Error('failed')); + platform.getRepoStatus.mockResolvedValueOnce( + partial<Git.StatusResult>({ + modified: [], + }) + ); + const res = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: '', + config, }); - it('gradlew failed', async () => { - const cfg = { ...config, localDir: resolve(fixtures, './wrongCmd') }; - - await setUtilConfig(cfg); - const res = await dcUpdate.updateArtifacts({ - packageFileName: 'gradle-wrapper.properties', - updatedDeps: [], - newPackageFileContent: await readString( - `./testFiles/gradle/wrapper/gradle-wrapper.properties` - ), - config: cfg, - }); + expect(execSnapshots).toMatchSnapshot(); + expect(res).toEqual([]); + }); - expect(res[0].artifactError.lockFile).toEqual( - 'gradle-wrapper.properties' + it.only('updates distributionSha256Sum', async () => { + httpMock + .scope('https://services.gradle.org') + .get('/distributions/gradle-6.3-bin.zip.sha256') + .reply( + 200, + '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768' ); - expect(res[0].artifactError.stderr).not.toBeNull(); - expect(res[0].artifactError.stderr).not.toEqual(''); - // 5.6.4 => 5.6.4 (updates execs) - unexpected behavior (looks like a bug in Gradle) - ['gradle/wrapper/gradle-wrapper.properties'].forEach((file) => { - compareFile(file, 'testFiles-copy'); - }); - }); + platform.getRepoStatus.mockResolvedValueOnce( + partial<Git.StatusResult>({ + modified: ['gradle/wrapper/gradle-wrapper.properties'], + }) + ); - it('gradlew not found', async () => { - const res = await dcUpdate.updateArtifacts({ - packageFileName: 'gradle-wrapper.properties', - updatedDeps: [], - newPackageFileContent: undefined, - config: { - localDir: 'some-dir', - }, - }); + const execSnapshots = mockExecAll(exec); - expect(res).toBeNull(); + const result = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: `distributionSha256Sum=336b6898b491f6334502d8074a6b8c2d73ed83b92123106bd4bf837f04111043\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.3-bin.zip`, + config: dockerConfig, }); - it('updates distributionSha256Sum', async () => { - httpMock - .scope('https://services.gradle.org') - .get('/distributions/gradle-6.3-bin.zip.sha256') - .reply( - 200, - '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768' - ); + expect(result).toHaveLength(1); + expect(result[0].artifactError).toBeUndefined(); - platform.getRepoStatus.mockResolvedValueOnce( - partial<Git.StatusResult>({ - modified: ['gradle/wrapper/gradle-wrapper.properties'], - }) - ); - const newContent = await readString(`./gradle-wrapper-sum.properties`); - - const result = await dcUpdate.updateArtifacts({ - packageFileName: 'gradle/wrapper/gradle-wrapper.properties', - updatedDeps: [], - newPackageFileContent: newContent.replace( - '038794feef1f4745c6347107b6726279d1c824f3fc634b60f86ace1e9fbd1768', - '1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d' - ), - config: { - ...config, - toVersion: '6.3', - currentValue: '5.6.4', + expect(execSnapshots).toMatchSnapshot(); + expect(httpMock.getTrace()).toEqual([ + { + headers: { + 'accept-encoding': 'gzip, deflate', + host: 'services.gradle.org', + 'user-agent': 'https://github.com/renovatebot/renovate', }, - }); - - expect(result).toHaveLength(1); - expect(result[0].artifactError).toBeUndefined(); - - expect( - await readString( - config.localDir, - `./gradle/wrapper/gradle-wrapper.properties` - ) - ).toEqual(newContent); + method: 'GET', + url: + 'https://services.gradle.org/distributions/gradle-6.3-bin.zip.sha256', + }, + ]); + }); - expect(httpMock.getTrace()).toEqual([ - { - headers: { - 'accept-encoding': 'gzip, deflate', - host: 'services.gradle.org', - 'user-agent': 'https://github.com/renovatebot/renovate', - }, - method: 'GET', - url: - 'https://services.gradle.org/distributions/gradle-6.3-bin.zip.sha256', - }, - ]); + it('distributionSha256Sum 404', async () => { + httpMock + .scope('https://services.gradle.org') + .get('/distributions/gradle-6.3-bin.zip.sha256') + .reply(404); + + const result = await dcUpdate.updateArtifacts({ + packageFileName: 'gradle-wrapper.properties', + updatedDeps: [], + newPackageFileContent: `distributionSha256Sum=336b6898b491f6334502d8074a6b8c2d73ed83b92123106bd4bf837f04111043\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.3-bin.zip`, + config, }); - it('distributionSha256Sum 404', async () => { - httpMock - .scope('https://services.gradle.org') - .get('/distributions/gradle-6.3-bin.zip.sha256') - .reply(404); - - const result = await dcUpdate.updateArtifacts({ - packageFileName: 'gradle/wrapper/gradle-wrapper.properties', - updatedDeps: [], - newPackageFileContent: `distributionSha256Sum=336b6898b491f6334502d8074a6b8c2d73ed83b92123106bd4bf837f04111043\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.3-bin.zip`, - config, - }); - - expect(result).toEqual([ - { - artifactError: { - lockFile: 'gradle/wrapper/gradle-wrapper.properties', - stderr: 'Response code 404 (Not Found)', - }, + expect(result).toEqual([ + { + artifactError: { + lockFile: 'gradle-wrapper.properties', + stderr: 'Response code 404 (Not Found)', }, - ]); - expect(httpMock.getTrace()).toEqual([ - { - headers: { - 'accept-encoding': 'gzip, deflate', - host: 'services.gradle.org', - 'user-agent': 'https://github.com/renovatebot/renovate', - }, - method: 'GET', - url: - 'https://services.gradle.org/distributions/gradle-6.3-bin.zip.sha256', + }, + ]); + expect(httpMock.getTrace()).toEqual([ + { + headers: { + 'accept-encoding': 'gzip, deflate', + host: 'services.gradle.org', + 'user-agent': 'https://github.com/renovatebot/renovate', }, - ]); - }); + method: 'GET', + url: + 'https://services.gradle.org/distributions/gradle-6.3-bin.zip.sha256', + }, + ]); }); }); diff --git a/lib/manager/gradle-wrapper/artifacts.ts b/lib/manager/gradle-wrapper/artifacts.ts index f7d75d262b0bfca0cc51d7866d869e5cf63d03cc..e396226e5c2b82e10526b8404c8d4e74877ff868 100644 --- a/lib/manager/gradle-wrapper/artifacts.ts +++ b/lib/manager/gradle-wrapper/artifacts.ts @@ -1,4 +1,3 @@ -/* istanbul ignore file */ import { resolve } from 'path'; import * as fs from 'fs-extra'; import Git from 'simple-git/promise'; diff --git a/package.json b/package.json index ccb040dd29350fc46ff48eb320c014be03d42901..260603a8cc2687c3e1844017a460092a0031fdf5 100644 --- a/package.json +++ b/package.json @@ -184,6 +184,7 @@ "@babel/plugin-syntax-dynamic-import": "7.8.3", "@babel/preset-env": "7.9.6", "@babel/preset-typescript": "7.9.0", + "@jest/globals": "26.0.1", "@jest/reporters": "26.0.1", "@jest/test-result": "26.0.1", "@semantic-release/exec": "5.0.0", diff --git a/test/execUtil.ts b/test/execUtil.ts index babd4063a1f7c9462a4875a5a3cc3fb4fe523010..479f33559765b33855e645886f2ceb9438201a24 100644 --- a/test/execUtil.ts +++ b/test/execUtil.ts @@ -1,4 +1,7 @@ import { exec as _exec } from 'child_process'; +import is from '@sindresorhus/is'; +import traverse from 'traverse'; +import { toUnix } from 'upath'; import { ExecOptions } from '../lib/util/exec'; type CallOptions = ExecOptions | null | undefined; @@ -18,15 +21,15 @@ export function execSnapshot(cmd: string, options?: CallOptions): ExecSnapshot { options, }; - const str = JSON.stringify(snapshot, (k, v) => (v === undefined ? null : v)); + const cwd = toUnix(process.cwd()); - const cwd = process.cwd().replace(/\\(\w)/g, '/$1'); - return JSON.parse( - str - .replace(/\\(\w)/g, '/$1') - .split(cwd) - .join('/root/project') - ); + // eslint-disable-next-line array-callback-return + return traverse(snapshot).map(function fixup(v) { + if (is.string(v)) { + const val = v.replace(/\\(\w)/g, '/$1').replace(cwd, '/root/project'); + this.update(val); + } + }); } const defaultExecResult = { stdout: '', stderr: '' }; diff --git a/test/util.ts b/test/util.ts index 34e742350300090ca56d4fe3765202a05e49c930..c94ec68c2f3e0702543c39c1e79fa83b5b338a06 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,9 +1,12 @@ import crypto from 'crypto'; +import { expect, jest } from '@jest/globals'; import * as upath from 'upath'; import { RenovateConfig as _RenovateConfig } from '../lib/config'; import { getConfig } from '../lib/config/defaults'; import { platform as _platform } from '../lib/platform'; +import * as _env from '../lib/util/exec/env'; import * as _fs from '../lib/util/fs'; +import * as _hostRules from '../lib/util/host-rules'; /** * Simple wrapper for getting mocked version of a module @@ -26,7 +29,7 @@ export function mocked<T>(module: T): jest.Mocked<T> { */ export function mockPartial(moduleName: string, overrides?: object): unknown { const absolutePath = upath.join(module.parent.filename, '../', moduleName); - const originalModule = jest.requireActual(absolutePath); + const originalModule = jest.requireActual(absolutePath) as any; return { __esModule: true, ...originalModule, @@ -44,6 +47,8 @@ export function partial<T>(obj: Partial<T>): T { export const fs = mocked(_fs); export const platform = mocked(_platform); +export const env = mocked(_env); +export const hostRules = mocked(_hostRules); // Required because of isolatedModules export type RenovateConfig = _RenovateConfig; @@ -75,14 +80,22 @@ export const replacingSerializer = ( }, }); +export function addReplacingSerializer(from: string, to: string): void { + expect.addSnapshotSerializer(replacingSerializer(from, to)); +} + function toHash(buf: Buffer): string { return crypto.createHash('sha256').update(buf).digest('hex'); } -export const bufferSerializer = (): jest.SnapshotSerializerPlugin => ({ +const bufferSerializer: jest.SnapshotSerializerPlugin = { test: (value) => Buffer.isBuffer(value), serialize: (val, config, indent, depth, refs, printer) => { const replaced = toHash(val); return printer(replaced, config, indent, depth, refs); }, -}); +}; + +export function addBufferSerializer(): void { + expect.addSnapshotSerializer(bufferSerializer); +} diff --git a/yarn.lock b/yarn.lock index c58b15251e25dc5c7dc40ba0402b151aaaaaa57a..c0bf83756e74c53f8832896181ad8786da04e659 100644 --- a/yarn.lock +++ b/yarn.lock @@ -946,7 +946,7 @@ jest-mock "^26.0.1" jest-util "^26.0.1" -"@jest/globals@^26.0.1": +"@jest/globals@26.0.1", "@jest/globals@^26.0.1": version "26.0.1" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.0.1.tgz#3f67b508a7ce62b6e6efc536f3d18ec9deb19a9c" integrity sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==