diff --git a/lib/modules/manager/gradle/extract.spec.ts b/lib/modules/manager/gradle/extract.spec.ts index 43ee5438be915cebcade2b8d8a6b83a5ea3c40a7..a497da28611a25c0258f0a8247aba5bfdd5d4258 100644 --- a/lib/modules/manager/gradle/extract.spec.ts +++ b/lib/modules/manager/gradle/extract.spec.ts @@ -105,7 +105,8 @@ describe('modules/manager/gradle/extract', () => { it('works with file-ext-var', async () => { mockFs({ 'gradle.properties': 'baz=1.2.3', - 'build.gradle': 'url "https://example.com"; "foo:bar:$baz@zip"', + 'build.gradle': + 'repositories { maven { url "https://example.com" } }; "foo:bar:$baz@zip"', 'settings.gradle': null as never, // TODO: #7154 }); @@ -171,10 +172,10 @@ describe('modules/manager/gradle/extract', () => { it('deduplicates registry urls', async () => { const fsMock = { 'build.gradle': [ - 'url "https://repo.maven.apache.org/maven2"', - 'url "https://repo.maven.apache.org/maven2"', - 'url "https://example.com"', - 'url "https://example.com"', + 'repositories { maven { url "https://repo.maven.apache.org/maven2" } }', + 'repositories { maven { url "https://repo.maven.apache.org/maven2" } }', + 'repositories { maven { url "https://example.com" } }', + 'repositories { maven { url "https://example.com" } }', 'id "foo.bar" version "1.2.3"', '"foo:bar:1.2.3"', ].join(';\n'), diff --git a/lib/modules/manager/gradle/parser.spec.ts b/lib/modules/manager/gradle/parser.spec.ts index 896c2dd827598e500a5c78ee76bbabc78217d74d..c9a9eb457477bdcfe8e6962e3c35c5b34c954f12 100644 --- a/lib/modules/manager/gradle/parser.spec.ts +++ b/lib/modules/manager/gradle/parser.spec.ts @@ -32,129 +32,184 @@ describe('modules/manager/gradle/parser', () => { expect((await parseGradle('id "foo.bar" version')).deps).toBeEmpty(); }); - describe('variable assignments', () => { - test.each` - input | name | value - ${'version = "1.2.3"'} | ${'version'} | ${'1.2.3'} - ${'set("version", "1.2.3")'} | ${'version'} | ${'1.2.3'} - ${'versions.foobar = "1.2.3"'} | ${'versions.foobar'} | ${'1.2.3'} - ${'ext.foobar = "1.2.3"'} | ${'foobar'} | ${'1.2.3'} - ${'project.foobar = "1.2.3"'} | ${'foobar'} | ${'1.2.3'} - ${'rootProject.foobar = "1.2.3"'} | ${'foobar'} | ${'1.2.3'} - `('$input', async ({ input, name, value }) => { - const { vars } = await parseGradle(input); - expect(vars).toContainKey(name); - expect(vars[name]).toMatchObject({ key: name, value }); + describe('variables', () => { + describe('Groovy: single var assignments', () => { + test.each` + input | name | value + ${'foo = "1.2.3"'} | ${'foo'} | ${'1.2.3'} + ${'foo.bar = "1.2.3"'} | ${'foo.bar'} | ${'1.2.3'} + ${'ext.foobar = "1.2.3"'} | ${'foobar'} | ${'1.2.3'} + ${'project.foobar = "1.2.3"'} | ${'foobar'} | ${'1.2.3'} + ${'project.ext.foo.bar = "1.2.3"'} | ${'foo.bar'} | ${'1.2.3'} + ${'rootProject.foobar = "1.2.3"'} | ${'foobar'} | ${'1.2.3'} + ${'rootProject.foo.bar = "1.2.3"'} | ${'foo.bar'} | ${'1.2.3'} + `('$input', async ({ input, name, value }) => { + const { vars } = await parseGradle(input); + expect(vars).toContainKey(name); + expect(vars[name]).toMatchObject({ key: name, value }); + }); + }); + + describe('Kotlin: single var assignments', () => { + test.each` + input | name | value + ${'set("foo", "1.2.3")'} | ${'foo'} | ${'1.2.3'} + ${'version("foo", "1.2.3")'} | ${'foo'} | ${'1.2.3'} + `('$input', async ({ input, name, value }) => { + const { vars } = await parseGradle(input); + expect(vars).toContainKey(name); + expect(vars[name]).toMatchObject({ key: name, value }); + }); }); }); describe('dependencies', () => { - describe('simple cases', () => { + describe('simple dependency strings', () => { test.each` - input | output - ${'group: "foo", name: "bar", version: "1.2.3"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} - ${"implementation platform(group: 'foo', name: 'bar', version: '1.2.3')"} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} - ${'group: "foo", name: "bar", version: depVersion'} | ${null} - ${'("foo", "bar", "1.2.3")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} - ${'(group = "foo", name = "bar", version = "1.2.3")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} - ${'"foo:bar:1.2.3@zip"'} | ${{ currentValue: '1.2.3', dataType: 'zip', depName: 'foo:bar' }} - ${'(group: "foo", name: "bar", version: "1.2.3", classifier: "sources")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} - ${'(group: "foo", name: "bar", version: "1.2.3") {exclude module: "spring-jcl"}'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + input | output + ${'"foo:bar:1.2.3"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${'"foo:bar:1.2.3@zip"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', dataType: 'zip' }} + ${'foo.bar = "foo:bar:1.2.3"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} `('$input', async ({ input, output }) => { const { deps } = await parseGradle(input); expect(deps).toMatchObject([output].filter(Boolean)); }); }); - describe('annoying methods', () => { + describe('interpolated dependency strings', () => { test.each` - input | output - ${'createXmlValueRemover("defaults", "integer", "integer")'} | ${{ depName: 'defaults:integer', currentValue: 'integer', skipReason: 'ignored' }} - ${'events("passed", "skipped", "failed")'} | ${{ depName: 'passed:skipped', currentValue: 'failed', skipReason: 'ignored' }} - ${'args("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} - ${'arrayOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} - ${'listOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} - ${'mutableListOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} - ${'setOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} - ${'mutableSetOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} - ${'stages("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} - `('$input', async ({ input, output }) => { - const { deps } = await parseGradle(input); + def | str | output + ${'foo = "1.2.3"'} | ${'"foo:bar:$foo@@@"'} | ${null} + ${''} | ${'"foo:bar:$baz"'} | ${null} + ${'foo = "1"; bar = "2"; baz = "3"'} | ${'"foo:bar:$foo.$bar.$baz"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', skipReason: 'contains-variable' }} + ${'baz = "1.2.3"'} | ${'"foo:bar:$baz"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} + ${'foo.bar = "1.2.3"'} | ${'"foo:bar:$foo.bar"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'foo.bar' }} + ${'foo = "1.2.3"'} | ${'"foo:bar_$foo:4.5.6"'} | ${{ depName: 'foo:bar_1.2.3', managerData: { fileReplacePosition: 28 } }} + ${'baz = "1.2.3"'} | ${'foobar = "foo:bar:$baz"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} + `('$def | $str', async ({ def, str, output }) => { + const { deps } = await parseGradle([def, str].join('\n')); expect(deps).toMatchObject([output].filter(Boolean)); }); }); - describe('variable substitutions', () => { + describe('map notation dependencies', () => { test.each` - def | str | output - ${'foo = "1.2.3"'} | ${'"foo:bar:$foo@@@"'} | ${null} - ${'foo = "1"; bar = "2"; baz = "3"'} | ${'"foo:bar:$foo.$bar.$baz"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', skipReason: 'contains-variable' }} - ${'baz = "1.2.3"'} | ${'"foo:bar:$baz"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} - ${'foo.bar = "1.2.3"'} | ${'"foo:bar:$foo.bar"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'foo.bar' }} - ${'foo = "1.2.3"'} | ${'"foo:bar_$foo:4.5.6"'} | ${{ depName: 'foo:bar_1.2.3', managerData: { fileReplacePosition: 28 } }} - ${''} | ${'foo.bar = "foo:bar:1.2.3"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} - ${'baz = "1.2.3"'} | ${'foobar = "foo:bar:$baz"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} - ${'baz = "1.2.3"'} | ${'group: "foo", name: "bar", version: baz'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} - ${'baz = "1.2.3"'} | ${'library("foo.bar", "foo", "bar").versionRef("baz")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} - ${''} | ${'library("foo.bar", "foo", "bar").version("1.2.3")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} - ${'library("foo-bar_baz-qux", "foo", "bar")'} | ${'"${foo.bar.baz.qux}:1.2.3"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + def | str | output + ${''} | ${'group: "foo", name: "bar", version: "1.2.3"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${''} | ${'group: "foo", name: "bar", version: baz'} | ${null} + ${'baz = "1.2.3"'} | ${'group: "foo", name: "bar", version: baz'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} + ${''} | ${'(group: "foo", name: "bar", version: "1.2.3", classifier: "sources")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${''} | ${'(group: "foo", name: "bar", version: "1.2.3") {exclude module: "spring-jcl"}'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${''} | ${"implementation platform(group: 'foo', name: 'bar', version: '1.2.3')"} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${''} | ${'(group = "foo", name = "bar", version = "1.2.3")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} `('$def | $str', async ({ def, str, output }) => { - const input = [def, str].join('\n'); - const { deps } = await parseGradle(input); + const { deps } = await parseGradle([def, str].join('\n')); expect(deps).toMatchObject([output].filter(Boolean)); }); }); describe('plugins', () => { test.each` - def | input | output - ${''} | ${'id "foo.bar" version "1.2.3"'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} - ${''} | ${'id("foo.bar") version "1.2.3"'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} - ${''} | ${'kotlin("jvm") version "1.3.71"'} | ${{ depName: 'org.jetbrains.kotlin.jvm', packageName: 'org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin', currentValue: '1.3.71' }} - ${''} | ${'id "foo.bar" version something'} | ${{ depName: 'foo.bar', currentValue: 'something', skipReason: 'unknown-version' }} - ${'baz = "1.2.3"'} | ${'id "foo.bar" version baz'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} - ${'baz = "1.2.3"'} | ${'id("foo.bar") version baz'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} - ${'baz = "1.3.71"'} | ${'kotlin("jvm") version baz'} | ${{ depName: 'org.jetbrains.kotlin.jvm', packageName: 'org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin', currentValue: '1.3.71' }} - ${'z = "1.2.3"'} | ${'id "x.y" version "$z"'} | ${{ depName: 'x.y', packageName: 'x.y:x.y.gradle.plugin', currentValue: '1.2.3' }} - ${''} | ${'id "x.y" version "$z"'} | ${{ depName: 'x.y', skipReason: 'unknown-version', currentValue: 'z' }} - ${''} | ${'id "x.y" version "x${y}z"'} | ${{ depName: 'x.y', skipReason: 'unknown-version' }} - ${'z = "1.2.3"'} | ${'id("x.y") version "$z"'} | ${{ depName: 'x.y', packageName: 'x.y:x.y.gradle.plugin', currentValue: '1.2.3' }} - ${''} | ${'id("x.y") version "$z"'} | ${{ depName: 'x.y', skipReason: 'unknown-version', currentValue: 'z' }} - ${''} | ${'id("x.y") version "x${y}z"'} | ${{ depName: 'x.y', skipReason: 'unknown-version' }} - `('$input', async ({ def, input, output }) => { + def | input | output + ${''} | ${'id "foo.bar" version "1.2.3"'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} + ${''} | ${'id(["foo.bar"]) version "1.2.3"'} | ${null} + ${''} | ${'id("foo", "bar") version "1.2.3"'} | ${null} + ${''} | ${'id("foo.bar") version "1.2.3"'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} + ${''} | ${'id "foo.bar" version "$baz"'} | ${{ depName: 'foo.bar', skipReason: 'unknown-version', currentValue: 'baz' }} + ${'baz = "1.2.3"'} | ${'id "foo.bar" version "$baz"'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} + ${'baz = "1.2.3"'} | ${'id("foo.bar") version "$baz"'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} + ${''} | ${'id "foo.bar" version "x${ab}cd"'} | ${{ depName: 'foo.bar', skipReason: 'unknown-version' }} + ${''} | ${'id("foo.bar") version "$baz"'} | ${{ depName: 'foo.bar', skipReason: 'unknown-version', currentValue: 'baz' }} + ${''} | ${'id("foo.bar") version "x${ab}cd"'} | ${{ depName: 'foo.bar', skipReason: 'unknown-version' }} + ${''} | ${'id "foo.bar" version baz'} | ${{ depName: 'foo.bar', currentValue: 'baz', skipReason: 'unknown-version' }} + ${'baz = "1.2.3"'} | ${'id "foo.bar" version baz'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} + ${'baz = "1.2.3"'} | ${'id("foo.bar") version baz'} | ${{ depName: 'foo.bar', packageName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }} + ${''} | ${'kotlin("jvm") version "1.3.71"'} | ${{ depName: 'org.jetbrains.kotlin.jvm', packageName: 'org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin', currentValue: '1.3.71' }} + ${'baz = "1.3.71"'} | ${'kotlin("jvm") version baz'} | ${{ depName: 'org.jetbrains.kotlin.jvm', packageName: 'org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin', currentValue: '1.3.71' }} + `('$def | $input', async ({ def, input, output }) => { const { deps } = await parseGradle([def, input].join('\n')); expect(deps).toMatchObject([output].filter(Boolean)); }); }); }); - describe('registryUrls', () => { + describe('registries', () => { + describe('predefined registries', () => { + test.each` + input | output + ${'mavenCentral()'} | ${MAVEN_REPO} + ${'google()'} | ${GOOGLE_REPO} + ${'google { content { includeGroup "foo" } }'} | ${GOOGLE_REPO} + ${'gradlePluginPortal()'} | ${GRADLE_PLUGIN_PORTAL_REPO} + ${'jcenter()'} | ${JCENTER_REPO} + `('$input', async ({ input, output }) => { + const { urls } = await parseGradle(input); + expect(urls).toStrictEqual([output].filter(Boolean)); + }); + }); + + describe('custom registries', () => { + test.each` + def | input | url + ${''} | ${'maven("")'} | ${null} + ${''} | ${'maven(["https://foo.bar/baz/qux"])'} | ${null} + ${''} | ${'maven("foo", "bar")'} | ${null} + ${''} | ${'maven("https://foo.bar/baz")'} | ${'https://foo.bar/baz'} + ${'base="https://foo.bar"'} | ${'maven("${base}/baz")'} | ${'https://foo.bar/baz'} + ${''} | ${'maven(uri(["https://foo.bar/baz"]))'} | ${null} + ${''} | ${'maven { ["https://foo.bar/baz"] }'} | ${null} + ${''} | ${'maven { url "https://foo.bar/baz" }'} | ${'https://foo.bar/baz'} + ${'base="https://foo.bar"'} | ${'maven { url "${base}/baz" }'} | ${'https://foo.bar/baz'} + ${''} | ${'maven { url = "https://foo.bar/baz" }'} | ${'https://foo.bar/baz'} + ${'base="https://foo.bar"'} | ${'maven { url = "${base}/baz" }'} | ${'https://foo.bar/baz'} + ${''} | ${'maven { url = uri("https://foo.bar/baz") }'} | ${'https://foo.bar/baz'} + ${'base="https://foo.bar"'} | ${'maven { url = uri("${base}/baz") }'} | ${'https://foo.bar/baz'} + ${'base="https://foo.bar"'} | ${'maven { name = "baz"\nurl = "${base}/${name}" }'} | ${'https://foo.bar/baz'} + `('$def | $input', async ({ def, input, url }) => { + const expected = [url].filter(Boolean); + const { urls } = await parseGradle([def, input].join('\n')); + expect(urls).toStrictEqual(expected); + }); + }); + }); + + describe('version catalog', () => { test.each` - def | input | url - ${''} | ${'url ""'} | ${null} - ${''} | ${'url "#!@"'} | ${null} - ${''} | ${'url "https://example.com"'} | ${'https://example.com'} - ${'base="https://foo.bar"'} | ${'url "${base}/baz"'} | ${'https://foo.bar/baz'} - ${''} | ${'url("https://example.com")'} | ${'https://example.com'} - ${'base="https://foo.bar"'} | ${'url("${base}/baz")'} | ${'https://foo.bar/baz'} - ${''} | ${'mavenCentral()'} | ${MAVEN_REPO} - ${''} | ${'jcenter()'} | ${JCENTER_REPO} - ${''} | ${'google()'} | ${GOOGLE_REPO} - ${''} | ${'google { content { includeGroup "foo" } }'} | ${GOOGLE_REPO} - ${''} | ${'gradlePluginPortal()'} | ${GRADLE_PLUGIN_PORTAL_REPO} - ${''} | ${'maven("https://foo.bar/baz/qux")'} | ${'https://foo.bar/baz/qux'} - ${'base="https://foo.bar"'} | ${'maven("${base}/baz/qux")'} | ${'https://foo.bar/baz/qux'} - ${''} | ${'maven { url = uri("https://foo.bar/baz")'} | ${'https://foo.bar/baz'} - ${'base="https://foo.bar"'} | ${'maven { url = uri("${base}/baz")'} | ${'https://foo.bar/baz'} - ${''} | ${"maven { url 'https://foo.bar/baz'"} | ${'https://foo.bar/baz'} - ${'base="https://foo.bar"'} | ${'maven { url "${base}/baz"'} | ${'https://foo.bar/baz'} - ${''} | ${"maven { url = 'https://foo.bar/baz'"} | ${'https://foo.bar/baz'} - ${'base="https://foo.bar"'} | ${'maven { url = "${base}/baz"'} | ${'https://foo.bar/baz'} - ${'base="https://foo.bar"'} | ${'maven { name = "baz"\nurl = "${base}/${name}"'} | ${'https://foo.bar/baz'} - `('$def | $input', async ({ def, input, url }) => { - const expected = [url].filter(Boolean); - const { urls } = await parseGradle([def, input].join('\n')); - expect(urls).toStrictEqual(expected); + def | str | output + ${'version("baz", "1.2.3")'} | ${'library("foo.bar", "foo", "bar").versionRef("baz")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} + ${'version("baz", "1.2.3")'} | ${'library("foo.bar", "foo", "bar").versionRef("baz")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3', groupName: 'baz' }} + ${''} | ${'library("foo.bar", "foo", "bar").version("1.2.3")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${''} | ${'library(["foo.bar", "foo", "bar"]).version("1.2.3")'} | ${null} + ${''} | ${'library("foo", "bar", "baz", "qux"]).version("1.2.3")'} | ${null} + ${''} | ${'library("foo.bar", "foo", "bar").version("1.2.3", "4.5.6")'} | ${null} + ${'group = "foo"; artifact="bar"'} | ${'library("foo.bar", group, artifact).version("1.2.3")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${'library("foo-bar_baz-qux", "foo", "bar")'} | ${'"${foo.bar.baz.qux}:1.2.3"'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + `('$def | $str', async ({ def, str, output }) => { + const input = [def, str].join('\n'); + const { deps } = await parseGradle(input); + expect(deps).toMatchObject([output].filter(Boolean)); + }); + }); + + describe('heuristic dependency matching', () => { + test.each` + input | output + ${'("foo", "bar", "1.2.3")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${'("foo", "bar", "1.2.3", "4.5.6")'} | ${null} + ${'(["foo", "bar", "1.2.3"])'} | ${null} + ${'someMethod("foo", "bar", "1.2.3")'} | ${{ depName: 'foo:bar', currentValue: '1.2.3' }} + ${'createXmlValueRemover("defaults", "integer", "integer")'} | ${{ depName: 'defaults:integer', currentValue: 'integer', skipReason: 'ignored' }} + ${'events("passed", "skipped", "failed")'} | ${{ depName: 'passed:skipped', currentValue: 'failed', skipReason: 'ignored' }} + ${'args("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} + ${'arrayOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} + ${'listOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} + ${'mutableListOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} + ${'setOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} + ${'mutableSetOf("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} + ${'stages("foo", "bar", "baz")'} | ${{ depName: 'foo:bar', currentValue: 'baz', skipReason: 'ignored' }} + `('$input', async ({ input, output }) => { + const { deps } = await parseGradle(input); + expect(deps).toMatchObject([output].filter(Boolean)); }); }); @@ -241,34 +296,39 @@ describe('modules/manager/gradle/parser', () => { }, }; - mockFs({ + const fileContents = { 'foo/bar.gradle': key + ' = "' + value + '"', - }); + }; + mockFs(fileContents); test.each` - def | input | output - ${''} | ${'apply from: ""'} | ${{}} - ${''} | ${'apply from: "foo/invalid.gradle"'} | ${{}} - ${''} | ${'apply from: "foo/invalid.non-gradle"'} | ${{}} - ${''} | ${'apply from: "https://someurl.com/file.gradle"'} | ${{}} - ${''} | ${'apply from: "foo/bar.gradle"'} | ${validOutput} - ${'base="foo"'} | ${'apply from: "${base}/bar.gradle"'} | ${validOutput} - ${''} | ${'apply from: file("foo/bar.gradle")'} | ${validOutput} - ${'base="foo"'} | ${'apply from: file("${base}/bar.gradle")'} | ${validOutput} - ${''} | ${'apply from: project.file("foo/bar.gradle")'} | ${validOutput} - ${''} | ${'apply from: rootProject.file("foo/bar.gradle")'} | ${validOutput} - ${''} | ${'apply from: new File("foo/bar.gradle")'} | ${validOutput} - ${'base="foo"'} | ${'apply from: new File("${base}/bar.gradle")'} | ${validOutput} - ${''} | ${'apply from: new File("foo", "bar.gradle")'} | ${validOutput} - ${'base="foo"'} | ${'apply from: new File(base, "bar.gradle")'} | ${validOutput} - ${'base="foo"'} | ${'apply from: new File("${base}", "bar.gradle")'} | ${validOutput} - ${''} | ${'apply(from = "foo/bar.gradle"))'} | ${validOutput} - ${'base="foo"'} | ${'apply(from = "${base}/bar.gradle"))'} | ${validOutput} - ${''} | ${'apply(from = File("foo/bar.gradle"))'} | ${validOutput} - ${'base="foo"'} | ${'apply(from = File("${base}/bar.gradle"))'} | ${validOutput} - ${''} | ${'apply(from = File("foo", "bar.gradle"))'} | ${validOutput} - ${'base="foo"'} | ${'apply(from = File(base, "bar.gradle"))'} | ${validOutput} - ${'base="foo"'} | ${'apply(from = File("${base}", "bar.gradle"))'} | ${validOutput} + def | input | output + ${''} | ${'apply from: ""'} | ${{}} + ${''} | ${'apply from: "foo/invalid.gradle"'} | ${{}} + ${''} | ${'apply from: "${base}"'} | ${{}} + ${''} | ${'apply from: "foo/invalid.non-gradle"'} | ${{}} + ${''} | ${'apply from: "https://someurl.com/file.gradle"'} | ${{}} + ${''} | ${'apply from: "foo/bar.gradle"'} | ${validOutput} + ${'base="foo"'} | ${'apply from: "${base}/bar.gradle"'} | ${validOutput} + ${''} | ${'apply from: file("foo/bar.gradle")'} | ${validOutput} + ${'base="foo"'} | ${'apply from: file("${base}/bar.gradle")'} | ${validOutput} + ${''} | ${'apply from: project.file("foo/bar.gradle")'} | ${validOutput} + ${''} | ${'apply from: rootProject.file("foo/bar.gradle")'} | ${validOutput} + ${''} | ${'apply from: new File("foo/bar.gradle")'} | ${validOutput} + ${'base="foo"'} | ${'apply from: new File("${base}/bar.gradle")'} | ${validOutput} + ${''} | ${'apply from: new File("foo", "bar.gradle")'} | ${validOutput} + ${'base="foo"'} | ${'apply from: new File(base, "bar.gradle")'} | ${validOutput} + ${'base="foo"'} | ${'apply from: new File("${base}", "bar.gradle")'} | ${validOutput} + ${'path="bar.gradle"'} | ${'apply from: new File("foo", "${path}")'} | ${validOutput} + ${''} | ${'apply(from = "foo/bar.gradle"))'} | ${validOutput} + ${'base="foo"'} | ${'apply(from = "${base}/bar.gradle"))'} | ${validOutput} + ${''} | ${'apply(from = File("foo/bar.gradle"))'} | ${validOutput} + ${''} | ${'apply(from = File("foo", "bar", "baz"))'} | ${{}} + ${''} | ${'apply(from = File(["${somedir}/foo.gradle"]))'} | ${{}} + ${'base="foo"'} | ${'apply(from = File("${base}/bar.gradle"))'} | ${validOutput} + ${''} | ${'apply(from = File("foo", "bar.gradle"))'} | ${validOutput} + ${'base="foo"'} | ${'apply(from = File(base, "bar.gradle"))'} | ${validOutput} + ${'base="foo"'} | ${'apply(from = File("${base}", "bar.gradle"))'} | ${validOutput} `('$def | $input', async ({ def, input, output }) => { const { vars } = await parseGradle([def, input].join('\n')); expect(vars).toMatchObject(output);