From 665b3d359cf5db486550afb32d593de2096386b9 Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Mon, 15 Nov 2021 11:33:45 +0300
Subject: [PATCH] test(gradle): Refactor tests for parser (#12657)

---
 .../shallow/__snapshots__/parser.spec.ts.snap |   2 +-
 lib/manager/gradle/shallow/parser.spec.ts     | 412 ++++++------------
 2 files changed, 129 insertions(+), 285 deletions(-)

diff --git a/lib/manager/gradle/shallow/__snapshots__/parser.spec.ts.snap b/lib/manager/gradle/shallow/__snapshots__/parser.spec.ts.snap
index 4eabcf1f14..16b36d3b35 100644
--- a/lib/manager/gradle/shallow/__snapshots__/parser.spec.ts.snap
+++ b/lib/manager/gradle/shallow/__snapshots__/parser.spec.ts.snap
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`manager/gradle/shallow/parser parses fixture from "gradle" manager 1`] = `
+exports[`manager/gradle/shallow/parser calculations parses fixture from "gradle" manager 1`] = `
 Array [
   Object {
     "currentValue": "1.5.2.RELEASE",
diff --git a/lib/manager/gradle/shallow/parser.spec.ts b/lib/manager/gradle/shallow/parser.spec.ts
index 3518da4690..04c0f1bcf3 100644
--- a/lib/manager/gradle/shallow/parser.spec.ts
+++ b/lib/manager/gradle/shallow/parser.spec.ts
@@ -13,307 +13,151 @@ describe('manager/gradle/shallow/parser', () => {
     expect(parseGradle('version = ').deps).toBeEmpty();
     expect(parseGradle('id "foo.bar" version').deps).toBeEmpty();
   });
-  it('parses variables', () => {
-    let deps;
 
-    ({ deps } = parseGradle(
-      [
-        'version = "1.2.3"',
-        '"foo:bar_$version:$version"',
-        'version = "3.2.1"',
-      ].join('\n')
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'foo:bar_1.2.3',
-        currentValue: '1.2.3',
-      },
-    ]);
-
-    ({ deps } = parseGradle(
-      [
-        'set("version", "1.2.3")',
-        '"foo:bar:$version"',
-        'set("version", "3.2.1")',
-      ].join('\n')
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'foo:bar',
-        currentValue: '1.2.3',
-      },
-    ]);
-
-    ({ deps } = parseGradle('version = "1.2.3"\n"foo:bar:$version@@@"'));
-    expect(deps).toBeEmpty();
-
-    ({ deps } = parseGradle(
-      ['versions.foobar = "1.2.3"', '"foo:bar:${versions.foobar}"'].join('\n')
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'foo:bar',
-        currentValue: '1.2.3',
-        groupName: 'versions.foobar',
-      },
-    ]);
-
-    ({ deps } = parseGradle(
-      ['versions.foobar = "1.2.3"', '"foo:bar:$versions.foobar"'].join('\n')
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'foo:bar',
-        currentValue: '1.2.3',
-        groupName: 'versions.foobar',
-      },
-    ]);
-
-    expect(
-      parseGradle('foo.bar = "foo:bar:1.2.3"', {}, 'versions.gradle')
-    ).toMatchObject({
-      vars: {
-        'foo.bar': {
-          fileReplacePosition: 11,
-          key: 'foo.bar',
-          packageFile: 'versions.gradle',
-          value: 'foo:bar:1.2.3',
-        },
-      },
-      deps: [
-        {
-          depName: 'foo:bar',
-          currentValue: '1.2.3',
-          groupName: 'foo.bar',
-          managerData: {
-            fileReplacePosition: 19,
-          },
-        },
-      ],
+  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'}
+    `('$input', ({ input, name, value }) => {
+      const { vars } = parseGradle(input);
+      expect(vars).toContainKey(name);
+      expect(vars[name]).toMatchObject({ key: name, value });
     });
   });
-  it('parses registryUrls', () => {
-    let urls;
-
-    ({ urls } = parseGradle('url ""'));
-    expect(urls).toBeEmpty();
-
-    ({ urls } = parseGradle('url "#!@"'));
-    expect(urls).toBeEmpty();
-
-    ({ urls } = parseGradle('url "https://example.com"'));
-    expect(urls).toStrictEqual(['https://example.com']);
 
-    ({ urls } = parseGradle('url("https://example.com")'));
-    expect(urls).toStrictEqual(['https://example.com']);
-
-    ({ urls } = parseGradle('uri "https://example.com"'));
-    expect(urls).toStrictEqual(['https://example.com']);
-
-    ({ urls } = parseGradle(
-      'mavenCentral(); uri("https://example.com"); jcenter(); google(); gradlePluginPortal();'
-    ));
-    expect(urls).toStrictEqual([
-      MAVEN_REPO,
-      'https://example.com',
-      JCENTER_REPO,
-      GOOGLE_REPO,
-      GRADLE_PLUGIN_PORTAL_REPO,
-    ]);
-
-    ({ urls } = parseGradle(
-      'maven("https://repository.mycompany.com/m2/repository")'
-    ));
-    expect(urls).toStrictEqual([
-      'https://repository.mycompany.com/m2/repository',
-    ]);
+  describe('dependencies', () => {
+    describe('simple cases', () => {
+      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' }}
+        ${'createXmlValueRemover("defaults", "integer", "integer")'}              | ${{ depName: 'defaults:integer', currentValue: 'integer', skipReason: SkipReason.Ignored }}
+        ${'"foo:bar:1.2.3@zip"'}                                                  | ${{ currentValue: '1.2.3', dataType: 'zip', depName: 'foo:bar' }}
+      `('$input', ({ input, output }) => {
+        const { deps } = parseGradle(input);
+        expect(deps).toMatchObject([output].filter(Boolean));
+      });
+    });
 
-    ({ urls } = parseGradle(
-      'maven { url = uri("https://maven.springframework.org/release") }'
-    ));
-    expect(urls).toStrictEqual(['https://maven.springframework.org/release']);
+    describe('variable substitutions', () => {
+      test.each`
+        def                    | str                                          | output
+        ${'foo = "1.2.3"'}     | ${'"foo:bar:$foo@@@"'}                       | ${null}
+        ${'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.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' }}
+      `('$def | $str', ({ def, str, output }) => {
+        const input = [def, str].join('\n');
+        const { deps } = parseGradle(input);
+        expect(deps).toMatchObject([output].filter(Boolean));
+      });
+    });
 
-    ({ urls } = parseGradle(
-      "maven { url 'https://repository.mycompany.com/m2/repository' }"
-    ));
-    expect(urls).toStrictEqual([
-      'https://repository.mycompany.com/m2/repository',
-    ]);
+    describe('plugins', () => {
+      test.each`
+        input                               | output
+        ${'id "foo.bar" version "1.2.3"'}   | ${{ depName: 'foo.bar', lookupName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }}
+        ${'id("foo.bar") version "1.2.3"'}  | ${{ depName: 'foo.bar', lookupName: 'foo.bar:foo.bar.gradle.plugin', currentValue: '1.2.3' }}
+        ${'kotlin("jvm") version "1.3.71"'} | ${{ depName: 'org.jetbrains.kotlin.jvm', lookupName: 'org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin', currentValue: '1.3.71' }}
+      `('$input', ({ input, output }) => {
+        const { deps } = parseGradle(input);
+        expect(deps).toMatchObject([output].filter(Boolean));
+      });
+    });
   });
-  it('parses long form deps', () => {
-    let deps;
-    ({ deps } = parseGradle(
-      'group: "com.example", name: "my.dependency", version: "1.2.3"'
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'com.example:my.dependency',
-        currentValue: '1.2.3',
-      },
-    ]);
-
-    ({ deps } = parseGradle(
-      "implementation platform(group: 'foo', name: 'bar', version: '1.2.3')"
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'foo:bar',
-        currentValue: '1.2.3',
-      },
-    ]);
-
-    ({ deps } = parseGradle(
-      'group: "com.example", name: "my.dependency", version: depVersion'
-    ));
-    expect(deps).toBeEmpty();
-
-    ({ deps } = parseGradle(
-      'depVersion = "1.2.3"\ngroup: "com.example", name: "my.dependency", version: depVersion'
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'com.example:my.dependency',
-        currentValue: '1.2.3',
-      },
-    ]);
-
-    ({ deps } = parseGradle('("com.example", "my.dependency", "1.2.3")'));
-    expect(deps).toMatchObject([
-      {
-        depName: 'com.example:my.dependency',
-        currentValue: '1.2.3',
-      },
-    ]);
 
-    ({ deps } = parseGradle(
-      '(group = "com.example", name = "my.dependency", version = "1.2.3")'
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'com.example:my.dependency',
-        currentValue: '1.2.3',
-      },
-    ]);
-
-    ({ deps } = parseGradle(
-      'createXmlValueRemover("defaults", "integer", "integer")'
-    ));
-    expect(deps).toMatchObject([
-      {
-        depName: 'defaults:integer',
-        currentValue: 'integer',
-        skipReason: SkipReason.Ignored,
-      },
-    ]);
-
-    ({ deps } = parseGradle('url "https://example.com"; "foo:bar:1.2.3@zip"'));
-    expect(deps).toMatchInlineSnapshot(`
-      Array [
-        Object {
-          "currentValue": "1.2.3",
-          "dataType": "zip",
-          "depName": "foo:bar",
-          "managerData": Object {
-            "fileReplacePosition": 36,
-            "packageFile": undefined,
-          },
-        },
-      ]
-    `);
+  describe('registryUrls', () => {
+    test.each`
+      input                                           | url
+      ${'url ""'}                                     | ${null}
+      ${'url "#!@"'}                                  | ${null}
+      ${'url "https://example.com"'}                  | ${'https://example.com'}
+      ${'url("https://example.com")'}                 | ${'https://example.com'}
+      ${'mavenCentral()'}                             | ${MAVEN_REPO}
+      ${'jcenter()'}                                  | ${JCENTER_REPO}
+      ${'google()'}                                   | ${GOOGLE_REPO}
+      ${'gradlePluginPortal()'}                       | ${GRADLE_PLUGIN_PORTAL_REPO}
+      ${'maven("https://foo.bar/baz/qux")'}           | ${'https://foo.bar/baz/qux'}
+      ${'maven { url = uri("https://foo.bar/baz") }'} | ${'https://foo.bar/baz'}
+      ${"maven { url 'https://foo.bar/baz' }"}        | ${'https://foo.bar/baz'}
+    `('$input', ({ input, url }) => {
+      const expected = [url].filter(Boolean);
+      const { urls } = parseGradle(input);
+      expect(urls).toStrictEqual(expected);
+    });
   });
-  it('parses plugin', () => {
-    let deps;
 
-    ({ deps } = parseGradle('id "foo.bar" version "1.2.3"'));
-    expect(deps).toMatchObject([
-      {
-        depName: 'foo.bar',
-        lookupName: 'foo.bar:foo.bar.gradle.plugin',
-        currentValue: '1.2.3',
-      },
-    ]);
-
-    ({ deps } = parseGradle('id("foo.bar") version "1.2.3"'));
-    expect(deps).toMatchObject([
-      {
-        depName: 'foo.bar',
-        lookupName: 'foo.bar:foo.bar.gradle.plugin',
-        currentValue: '1.2.3',
-      },
-    ]);
+  describe('calculations', () => {
+    it('calculates offset', () => {
+      const content = "'foo:bar:1.2.3'";
+      const { deps } = parseGradle(content);
+      const [res] = deps;
+      const idx = content
+        .slice(res.managerData.fileReplacePosition)
+        .indexOf('1.2.3');
+      expect(idx).toBe(0);
+    });
 
-    ({ deps } = parseGradle('kotlin("jvm") version "1.3.71"'));
-    expect(deps).toMatchObject([
-      {
-        depName: 'org.jetbrains.kotlin.jvm',
-        lookupName:
-          'org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin',
-        currentValue: '1.3.71',
-      },
-    ]);
-  });
-  it('parses fixture from "gradle" manager', () => {
-    const content = loadFixture('build.gradle.example1', '../deep/');
-    const { deps } = parseGradle(content, {}, 'build.gradle');
-    deps.forEach((dep) => {
-      expect(
-        content
-          .slice(dep.managerData.fileReplacePosition)
-          .indexOf(dep.currentValue)
-      ).toBe(0);
+    it('parses fixture from "gradle" manager', () => {
+      const content = loadFixture('build.gradle.example1', '../deep/');
+      const { deps } = parseGradle(content, {}, 'build.gradle');
+      const replacementIndices = deps.map(({ managerData, currentValue }) =>
+        content.slice(managerData.fileReplacePosition).indexOf(currentValue)
+      );
+      expect(replacementIndices.every((idx) => idx === 0)).toBeTrue();
+      expect(deps).toMatchSnapshot();
     });
-    expect(deps).toMatchSnapshot();
-  });
-  it('calculates offset', () => {
-    const content = "'foo:bar:1.2.3'";
-    const { deps } = parseGradle(content);
-    const res = deps[0];
-    expect(
-      content.slice(res.managerData.fileReplacePosition).indexOf('1.2.3')
-    ).toBe(0);
   });
-  it('gradle.properties', () => {
-    expect(parseProps('foo=bar')).toMatchObject({
-      vars: {
-        foo: {
-          fileReplacePosition: 4,
-          key: 'foo',
-          value: 'bar',
-        },
-      },
-      deps: [],
-    });
-    expect(parseProps(' foo = bar ')).toMatchObject({
-      vars: {
-        foo: { key: 'foo', value: 'bar', fileReplacePosition: 7 },
-      },
-      deps: [],
+
+  describe('gradle.properties', () => {
+    test.each`
+      input            | key          | value    | fileReplacePosition
+      ${'foo=bar'}     | ${'foo'}     | ${'bar'} | ${4}
+      ${' foo = bar '} | ${'foo'}     | ${'bar'} | ${7}
+      ${'foo.bar=baz'} | ${'foo.bar'} | ${'baz'} | ${8}
+    `('$input', ({ input, key, value, fileReplacePosition }) => {
+      expect(parseProps(input)).toMatchObject({
+        vars: { [key]: { key, value, fileReplacePosition } },
+      });
     });
-    expect(parseProps('foo.bar=baz')).toMatchObject({
-      vars: {
-        'foo.bar': { key: 'foo.bar', value: 'baz', fileReplacePosition: 8 },
-      },
-      deps: [],
+
+    it('handles multi-line file', () => {
+      expect(parseProps('foo=foo\nbar=bar')).toMatchObject({
+        vars: {
+          foo: { key: 'foo', value: 'foo', fileReplacePosition: 4 },
+          bar: { key: 'bar', value: 'bar', fileReplacePosition: 12 },
+        },
+        deps: [],
+      });
     });
-    expect(parseProps('foo=foo\nbar=bar')).toMatchObject({
-      vars: {
-        foo: { key: 'foo', value: 'foo', fileReplacePosition: 4 },
-        bar: { key: 'bar', value: 'bar', fileReplacePosition: 12 },
-      },
-      deps: [],
+
+    it('attaches packageFile', () => {
+      expect(
+        parseProps('foo = bar', 'foo/bar/gradle.properties')
+      ).toMatchObject({
+        vars: { foo: { packageFile: 'foo/bar/gradle.properties' } },
+      });
     });
-    expect(parseProps('x=foo:bar:baz', 'x/gradle.properties')).toMatchObject({
-      vars: {},
-      deps: [
-        {
-          currentValue: 'baz',
-          depName: 'foo:bar',
-          managerData: {
-            fileReplacePosition: 10,
-            packageFile: 'x/gradle.properties',
+
+    it('parses dependencies', () => {
+      const res = parseProps('dep = foo:bar:1.2.3');
+
+      expect(res).toMatchObject({
+        deps: [
+          {
+            currentValue: '1.2.3',
+            depName: 'foo:bar',
+            managerData: { fileReplacePosition: 14 },
           },
-        },
-      ],
+        ],
+      });
     });
   });
 });
-- 
GitLab