From a8ca710dd64c6e33518a57c8451fd47560e5ef30 Mon Sep 17 00:00:00 2001
From: Michael Kriese <michael.kriese@visualon.de>
Date: Wed, 9 Feb 2022 19:12:14 +0100
Subject: [PATCH] fix: improve coverage (#14117)

---
 lib/datasource/cdnjs/index.ts                 |  6 +-
 lib/datasource/galaxy/index.ts                |  2 +-
 lib/datasource/gitlab-tags/util.spec.ts       | 24 +++++
 .../orb/__snapshots__/index.spec.ts.snap      |  2 -
 lib/datasource/orb/index.spec.ts              |  4 +-
 lib/manager/pip_setup/extract.spec.ts         |  4 +
 lib/versioning/semver-coerced/index.spec.ts   | 92 ++++++++++++-------
 lib/versioning/ubuntu/index.spec.ts           |  1 +
 lib/versioning/ubuntu/index.ts                |  6 +-
 9 files changed, 98 insertions(+), 43 deletions(-)
 create mode 100644 lib/datasource/gitlab-tags/util.spec.ts

diff --git a/lib/datasource/cdnjs/index.ts b/lib/datasource/cdnjs/index.ts
index 8f3aa41dd2..7d356a5d9d 100644
--- a/lib/datasource/cdnjs/index.ts
+++ b/lib/datasource/cdnjs/index.ts
@@ -25,7 +25,7 @@ export class CdnJsDatasource extends Datasource {
     // Each library contains multiple assets, so we cache at the library level instead of per-asset
     const library = lookupName.split('/')[0];
     const url = `${registryUrl}libraries/${library}?fields=homepage,repository,assets`;
-    let result: ReleaseResult;
+    let result: ReleaseResult | null = null;
     try {
       const { assets, homepage, repository } = (
         await this.http.getJson<CdnjsResponse>(url)
@@ -36,7 +36,7 @@ export class CdnJsDatasource extends Datasource {
       const assetName = lookupName.replace(`${library}/`, '');
       const releases = assets
         .filter(({ files }) => files.includes(assetName))
-        .map(({ version, sri }) => ({ version, newDigest: sri[assetName] }));
+        .map(({ version, sri }) => ({ version, newDigest: sri?.[assetName] }));
 
       result = { releases };
 
@@ -52,6 +52,6 @@ export class CdnJsDatasource extends Datasource {
       }
       this.handleGenericErrors(err);
     }
-    return result || null;
+    return result;
   }
 }
diff --git a/lib/datasource/galaxy/index.ts b/lib/datasource/galaxy/index.ts
index a5fd5d9d86..e9e37f7a94 100644
--- a/lib/datasource/galaxy/index.ts
+++ b/lib/datasource/galaxy/index.ts
@@ -77,7 +77,7 @@ export class GalaxyDatasource extends Datasource {
     };
 
     result.dependencyUrl = galaxyProjectUrl;
-    const { github_user: user = null, github_repo: repo = null } = resultObject;
+    const { github_user: user, github_repo: repo } = resultObject;
     if (typeof user === 'string' && typeof repo === 'string') {
       result.sourceUrl = `https://github.com/${user}/${repo}`;
     }
diff --git a/lib/datasource/gitlab-tags/util.spec.ts b/lib/datasource/gitlab-tags/util.spec.ts
new file mode 100644
index 0000000000..47f71de6f5
--- /dev/null
+++ b/lib/datasource/gitlab-tags/util.spec.ts
@@ -0,0 +1,24 @@
+import { getDepHost, getSourceUrl } from './util';
+
+describe('datasource/gitlab-tags/util', () => {
+  describe('getDepHost', () => {
+    it('works', () => {
+      expect(getDepHost()).toBe('https://gitlab.com');
+      expect(getDepHost('https://gitlab.domain.test/api/v4')).toBe(
+        'https://gitlab.domain.test'
+      );
+      expect(getDepHost('https://domain.test/gitlab/api/v4')).toBe(
+        'https://domain.test/gitlab'
+      );
+    });
+  });
+
+  describe('getSourceUrl', () => {
+    it('works', () => {
+      expect(getSourceUrl('some/repo')).toBe('https://gitlab.com/some/repo');
+      expect(
+        getSourceUrl('some/repo', 'https://gitlab.domain.test/api/v4')
+      ).toBe('https://gitlab.domain.test/some/repo');
+    });
+  });
+});
diff --git a/lib/datasource/orb/__snapshots__/index.spec.ts.snap b/lib/datasource/orb/__snapshots__/index.spec.ts.snap
index 5cb24825d8..34e723ee1f 100644
--- a/lib/datasource/orb/__snapshots__/index.spec.ts.snap
+++ b/lib/datasource/orb/__snapshots__/index.spec.ts.snap
@@ -18,7 +18,6 @@ Object {
       "version": "4.1.0",
     },
     Object {
-      "releaseTimestamp": "2018-12-11T18:24:13.119Z",
       "version": "4.1.1",
     },
     Object {
@@ -105,7 +104,6 @@ Object {
       "version": "4.1.0",
     },
     Object {
-      "releaseTimestamp": "2018-12-11T18:24:13.119Z",
       "version": "4.1.1",
     },
     Object {
diff --git a/lib/datasource/orb/index.spec.ts b/lib/datasource/orb/index.spec.ts
index fa40d1bd2e..1cda5d482c 100644
--- a/lib/datasource/orb/index.spec.ts
+++ b/lib/datasource/orb/index.spec.ts
@@ -14,7 +14,7 @@ const orbData = {
         { version: '4.1.4', createdAt: '2018-12-11T22:13:29.297Z' },
         { version: '4.1.3', createdAt: '2018-12-11T21:40:44.870Z' },
         { version: '4.1.2', createdAt: '2018-12-11T21:28:37.846Z' },
-        { version: '4.1.1', createdAt: '2018-12-11T18:24:13.119Z' },
+        { version: '4.1.1' },
         { version: '4.1.0', createdAt: '2018-12-11T18:14:41.116Z' },
         { version: '4.0.0', createdAt: '2018-12-11T17:41:26.595Z' },
         { version: '3.0.0', createdAt: '2018-12-11T05:28:14.080Z' },
@@ -94,7 +94,7 @@ describe('datasource/orb/index', () => {
         depName: 'hyper-expanse/library-release-workflows',
       });
       expect(res).toMatchSnapshot();
-      expect(res.homepage).toBe('https://google.com');
+      expect(res?.homepage).toBe('https://google.com');
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
   });
diff --git a/lib/manager/pip_setup/extract.spec.ts b/lib/manager/pip_setup/extract.spec.ts
index 14d5fa6104..bed01de719 100644
--- a/lib/manager/pip_setup/extract.spec.ts
+++ b/lib/manager/pip_setup/extract.spec.ts
@@ -35,5 +35,9 @@ describe('manager/pip_setup/extract', () => {
         ],
       });
     });
+
+    it('returns nothing', () => {
+      expect(extractPackageFile('', packageFile, config)).toBeNull();
+    });
   });
 });
diff --git a/lib/versioning/semver-coerced/index.spec.ts b/lib/versioning/semver-coerced/index.spec.ts
index 2741806679..e5ed201abe 100644
--- a/lib/versioning/semver-coerced/index.spec.ts
+++ b/lib/versioning/semver-coerced/index.spec.ts
@@ -14,6 +14,10 @@ describe('versioning/semver-coerced/index', () => {
     it('should return false for non-equal versions', () => {
       expect(semverCoerced.equals('2.0.1', '2.3.0')).toBeFalse();
     });
+
+    it('invalid version', () => {
+      expect(semverCoerced.equals('xxx', '1.2.3')).toBeFalse();
+    });
   });
 
   describe('.getMajor(input)', () => {
@@ -24,6 +28,10 @@ describe('versioning/semver-coerced/index', () => {
     it('should return major version number for non-strict semver', () => {
       expect(semverCoerced.getMajor('v3.1')).toBe(3);
     });
+
+    it('invalid version', () => {
+      expect(semverCoerced.getMajor('xxx')).toBeNull();
+    });
   });
 
   describe('.getMinor(input)', () => {
@@ -34,6 +42,10 @@ describe('versioning/semver-coerced/index', () => {
     it('should return minor version number for non-strict semver', () => {
       expect(semverCoerced.getMinor('v3.1')).toBe(1);
     });
+
+    it('invalid version', () => {
+      expect(semverCoerced.getMajor('xxx')).toBeNull();
+    });
   });
 
   describe('.getPatch(input)', () => {
@@ -44,133 +56,145 @@ describe('versioning/semver-coerced/index', () => {
     it('should return patch version number for non-strict semver', () => {
       expect(semverCoerced.getPatch('v3.1.2-foo')).toBe(2);
     });
+
+    it('invalid version', () => {
+      expect(semverCoerced.getMajor('xxx')).toBeNull();
+    });
   });
 
   describe('.isCompatible(input)', () => {
     it('should return true for strict semver', () => {
-      expect(semverCoerced.isCompatible('1.0.2')).toBeTruthy();
+      expect(semverCoerced.isCompatible('1.0.2')).toBeTrue();
     });
 
     it('should return true for non-strict semver', () => {
-      expect(semverCoerced.isCompatible('v3.1.2-foo')).toBeTruthy();
+      expect(semverCoerced.isCompatible('v3.1.2-foo')).toBeTrue();
     });
 
     it('should return false for non-semver', () => {
-      expect(semverCoerced.isCompatible('foo')).toBeFalsy();
+      expect(semverCoerced.isCompatible('foo')).toBeFalse();
     });
   });
 
   describe('.isGreaterThan(a, b)', () => {
     it('should return true for a greater version in strict semver', () => {
-      expect(semverCoerced.isGreaterThan('1.0.2', '1.0.0')).toBeTruthy();
+      expect(semverCoerced.isGreaterThan('1.0.2', '1.0.0')).toBeTrue();
     });
 
     it('should return false for lower version in strict semver', () => {
-      expect(semverCoerced.isGreaterThan('3.1.2', '4.1.0')).toBeFalsy();
+      expect(semverCoerced.isGreaterThan('3.1.2', '4.1.0')).toBeFalse();
     });
 
     it('should return false if version cannot be coerced', () => {
-      expect(semverCoerced.isGreaterThan('e.e.e', '4.1.0')).toBeFalsy();
+      expect(semverCoerced.isGreaterThan('e.e.e', '4.1.0')).toBeFalse();
     });
   });
 
   describe('.isLessThanRange(version, range)', () => {
     it('should return true for a lower version in strict semver', () => {
-      expect(semverCoerced.isLessThanRange?.('1.0.2', '~2.0')).toBeTruthy();
+      expect(semverCoerced.isLessThanRange?.('1.0.2', '~2.0')).toBeTrue();
     });
 
     it('should return false for in-range version in strict semver', () => {
-      expect(semverCoerced.isLessThanRange?.('3.0.2', '~3.0')).toBeFalsy();
+      expect(semverCoerced.isLessThanRange?.('3.0.2', '~3.0')).toBeFalse();
+    });
+
+    it('invalid version', () => {
+      expect(semverCoerced.isLessThanRange?.('xxx', '1.2.3')).toBeFalse();
     });
   });
 
   describe('.isSingleVersion()', () => {
     it('returns true if naked version', () => {
-      expect(semverCoerced.isSingleVersion('1.2.3')).toBeTruthy();
-      expect(semverCoerced.isSingleVersion('1.2.3-alpha.1')).toBeTruthy();
+      expect(semverCoerced.isSingleVersion('1.2.3')).toBeTrue();
+      expect(semverCoerced.isSingleVersion('1.2.3-alpha.1')).toBeTrue();
     });
 
     it('returns false if equals', () => {
-      expect(semverCoerced.isSingleVersion('=1.2.3')).toBeFalsy();
-      expect(semverCoerced.isSingleVersion('= 1.2.3')).toBeFalsy();
+      expect(semverCoerced.isSingleVersion('=1.2.3')).toBeFalse();
+      expect(semverCoerced.isSingleVersion('= 1.2.3')).toBeFalse();
     });
 
     it('returns false when not version', () => {
-      expect(semverCoerced.isSingleVersion('~1.0')).toBeFalsy();
+      expect(semverCoerced.isSingleVersion('~1.0')).toBeFalse();
     });
   });
 
   describe('.isStable(input)', () => {
     it('should return true for a stable version', () => {
-      expect(semverCoerced.isStable('1.0.0')).toBeTruthy();
+      expect(semverCoerced.isStable('1.0.0')).toBeTrue();
     });
 
     it('should return false for an prerelease version', () => {
-      expect(semverCoerced.isStable('v1.0-alpha')).toBeFalsy();
+      expect(semverCoerced.isStable('v1.0-alpha')).toBeFalse();
     });
   });
 
   describe('.isValid(input)', () => {
     it('should return null for non-digit version strings', () => {
-      expect(semverCoerced.isValid('version two')).toBeFalsy();
+      expect(semverCoerced.isValid('version two')).toBeFalse();
     });
 
     it('should return null for irregular version strings', () => {
-      expect(semverCoerced.isValid('17.04.0')).toBeFalsy();
+      expect(semverCoerced.isValid('17.04.0')).toBeFalse();
     });
 
     it('should support strict semver', () => {
-      expect(semverCoerced.isValid('1.2.3')).toBeTruthy();
+      expect(semverCoerced.isValid('1.2.3')).toBeTrue();
     });
 
     it('should treat semver with dash as a valid version', () => {
-      expect(semverCoerced.isValid('1.2.3-foo')).toBeTruthy();
+      expect(semverCoerced.isValid('1.2.3-foo')).toBeTrue();
     });
 
     it('should treat semver without dash as a valid version', () => {
-      expect(semverCoerced.isValid('1.2.3foo')).toBeTruthy();
+      expect(semverCoerced.isValid('1.2.3foo')).toBeTrue();
     });
 
     it('should treat ranges as valid versions', () => {
-      expect(semverCoerced.isValid('~1.2.3')).toBeTruthy();
-      expect(semverCoerced.isValid('^1.2.3')).toBeTruthy();
-      expect(semverCoerced.isValid('>1.2.3')).toBeTruthy();
+      expect(semverCoerced.isValid('~1.2.3')).toBeTrue();
+      expect(semverCoerced.isValid('^1.2.3')).toBeTrue();
+      expect(semverCoerced.isValid('>1.2.3')).toBeTrue();
     });
 
     it('should reject github repositories', () => {
-      expect(semverCoerced.isValid('renovatebot/renovate')).toBeFalsy();
-      expect(semverCoerced.isValid('renovatebot/renovate#master')).toBeFalsy();
+      expect(semverCoerced.isValid('renovatebot/renovate')).toBeFalse();
+      expect(semverCoerced.isValid('renovatebot/renovate#master')).toBeFalse();
       expect(
         semverCoerced.isValid('https://github.com/renovatebot/renovate.git')
-      ).toBeFalsy();
+      ).toBeFalse();
     });
   });
 
   describe('.isVersion(input)', () => {
     it('should return null for non-digit versions', () => {
-      expect(semverCoerced.isValid('version one')).toBeFalsy();
+      expect(semverCoerced.isValid('version one')).toBeFalse();
     });
 
     it('should support strict semver versions', () => {
-      expect(semverCoerced.isValid('1.2.3')).toBeTruthy();
+      expect(semverCoerced.isValid('1.2.3')).toBeTrue();
     });
 
     it('should support non-strict versions', () => {
-      expect(semverCoerced.isValid('v1.2')).toBeTruthy();
+      expect(semverCoerced.isValid('v1.2')).toBeTrue();
     });
   });
 
   describe('.matches(version, range)', () => {
     it('should return true when version is in range', () => {
-      expect(semverCoerced.matches('1.0.0', '1.0.0 || 1.0.1')).toBeTruthy();
+      expect(semverCoerced.matches('1.0.0', '1.0.0 || 1.0.1')).toBeTrue();
     });
 
     it('should return true with non-strict version in range', () => {
-      expect(semverCoerced.matches('v1.0', '1.0.0 || 1.0.1')).toBeTruthy();
+      expect(semverCoerced.matches('v1.0', '1.0.0 || 1.0.1')).toBeTrue();
     });
 
     it('should return false when version is not in range', () => {
-      expect(semverCoerced.matches('1.2.3', '1.4.1 || 1.4.2')).toBeFalsy();
+      expect(semverCoerced.matches('1.2.3', '1.4.1 || 1.4.2')).toBeFalse();
+    });
+
+    it('invalid version', () => {
+      expect(semverCoerced.matches('xxx', '1.2.3')).toBe(false);
     });
   });
 
@@ -231,5 +255,9 @@ describe('versioning/semver-coerced/index', () => {
     it('should return zero for equal non-strict versions', () => {
       expect(semverCoerced.sortVersions('v1.0', '1.x')).toBe(0);
     });
+
+    it('works with invalid version', () => {
+      expect(semverCoerced.sortVersions('v1.0', 'xx')).toBe(0);
+    });
   });
 });
diff --git a/lib/versioning/ubuntu/index.spec.ts b/lib/versioning/ubuntu/index.spec.ts
index 99812ccdfb..0b1a5d6aca 100644
--- a/lib/versioning/ubuntu/index.spec.ts
+++ b/lib/versioning/ubuntu/index.spec.ts
@@ -197,6 +197,7 @@ describe('versioning/ubuntu/index', () => {
     ${'16.04.7'} | ${'16.04.1'} | ${true}
     ${'19.10.1'} | ${'20.04.1'} | ${false}
     ${'20.04.1'} | ${'19.10.1'} | ${true}
+    ${'xxx'}     | ${'yyy'}     | ${false}
   `('isGreaterThan("$a", "$b") === $expected', ({ a, b, expected }) => {
     expect(ubuntu.isGreaterThan(a, b)).toBe(expected);
   });
diff --git a/lib/versioning/ubuntu/index.ts b/lib/versioning/ubuntu/index.ts
index 0bce4216a5..1f40823693 100644
--- a/lib/versioning/ubuntu/index.ts
+++ b/lib/versioning/ubuntu/index.ts
@@ -44,7 +44,7 @@ function isStable(version: string): boolean {
 
 function getMajor(version: string): null | number {
   if (isValid(version)) {
-    const [major] = version.split('.') || [];
+    const [major] = version.split('.');
     return parseInt(major, 10);
   }
   return null;
@@ -52,7 +52,7 @@ function getMajor(version: string): null | number {
 
 function getMinor(version: string): null | number {
   if (isValid(version)) {
-    const [, minor] = version.split('.') || [];
+    const [, minor] = version.split('.');
     return parseInt(minor, 10);
   }
   return null;
@@ -60,7 +60,7 @@ function getMinor(version: string): null | number {
 
 function getPatch(version: string): null | number {
   if (isValid(version)) {
-    const [, , patch] = version.split('.') || [];
+    const [, , patch] = version.split('.');
     return patch ? parseInt(patch, 10) : null;
   }
   return null;
-- 
GitLab