From fdea06731baf2ab27cadb8df6578ee990382f93a Mon Sep 17 00:00:00 2001 From: chris48s Date: Wed, 27 Oct 2021 19:03:07 +0100 Subject: [PATCH] fixes and tests for pipenv helpers --- services/pipenv-helpers.js | 26 ++++--- services/pipenv-helpers.spec.js | 131 ++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 services/pipenv-helpers.spec.js diff --git a/services/pipenv-helpers.js b/services/pipenv-helpers.js index f5663f6b363e8..3237486bcbf13 100644 --- a/services/pipenv-helpers.js +++ b/services/pipenv-helpers.js @@ -1,14 +1,10 @@ import Joi from 'joi' import { InvalidParameter } from './index.js' -const isDependency = Joi.alternatives( - Joi.object({ - version: Joi.string().required(), - }).required(), - Joi.object({ - ref: Joi.string().required(), - }).required() -) +const isDependency = Joi.object({ + version: Joi.string(), + ref: Joi.string(), +}).required() const isLockfile = Joi.object({ _meta: Joi.object({ @@ -16,8 +12,8 @@ const isLockfile = Joi.object({ python_version: Joi.string(), }).required(), }).required(), - default: Joi.object().pattern(Joi.string().required(), isDependency), - develop: Joi.object().pattern(Joi.string().required(), isDependency), + default: Joi.object().pattern(Joi.string(), isDependency), + develop: Joi.object().pattern(Joi.string(), isDependency), }).required() function getDependencyVersion({ @@ -45,8 +41,16 @@ function getDependencyVersion({ if (version) { // Strip the `==` which is always present. return { version: version.replace('==', '') } + } else if (ref) { + if (ref.length === 40) { + // assume it is a commit hash + return { ref: ref.substring(0, 7) } + } + return { ref } // tag } else { - return { ref: ref.substring(1, 8) } + throw new InvalidParameter({ + prettyMessage: `No version or ref for ${wantedDependency}`, + }) } } diff --git a/services/pipenv-helpers.spec.js b/services/pipenv-helpers.spec.js new file mode 100644 index 0000000000000..c126ace5dc2f0 --- /dev/null +++ b/services/pipenv-helpers.spec.js @@ -0,0 +1,131 @@ +import { expect } from 'chai' +import { getDependencyVersion } from './pipenv-helpers.js' +import { InvalidParameter } from './index.js' + +describe('getDependencyVersion', function () { + // loosely based on https://github.com/pypa/pipfile#pipfilelock + const packages = { + chardet: { + hashes: [ + 'sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691', + 'sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae', + ], + version: '==3.0.4', + }, + django: { + editable: true, + git: 'https://github.com/django/django.git', + ref: '1.11.4001', + }, + 'django-cms': { + file: 'https://github.com/divio/django-cms/archive/release/3.4.x.zip', + }, + 'discordlists-py': { + git: 'https://github.com/HexCodeFFF/discordlists.py', + ref: '2df5a2b62144b49774728efa8267d909a8a9787f', + }, + } + + it('throws if dependency not found in (in default object with data)', function () { + expect(() => + getDependencyVersion({ + wantedDependency: 'requests', + lockfileData: { + default: packages, + develop: {}, + }, + }) + ) + .to.throw(InvalidParameter) + .with.property('prettyMessage', 'default dependency not found') + }) + + it('throws if dependency not found in (in empty dev object)', function () { + expect(() => + getDependencyVersion({ + kind: 'dev', + wantedDependency: 'requests', + lockfileData: { + default: packages, + develop: {}, + }, + }) + ) + .to.throw(InvalidParameter) + .with.property('prettyMessage', 'dev dependency not found') + }) + + it('tolerates missing keys', function () { + expect( + getDependencyVersion({ + wantedDependency: 'chardet', + lockfileData: { + default: packages, + }, + }) + ).to.deep.equal({ version: '3.0.4' }) + }) + + it('finds package in develop object', function () { + expect( + getDependencyVersion({ + kind: 'dev', + wantedDependency: 'chardet', + lockfileData: { + default: {}, + develop: packages, + }, + }) + ).to.deep.equal({ version: '3.0.4' }) + }) + + it('returns version if present', function () { + expect( + getDependencyVersion({ + wantedDependency: 'chardet', + lockfileData: { + default: packages, + develop: {}, + }, + }) + ).to.deep.equal({ version: '3.0.4' }) + }) + + it('returns (complete) ref if ref is tag', function () { + expect( + getDependencyVersion({ + wantedDependency: 'django', + lockfileData: { + default: packages, + develop: {}, + }, + }) + ).to.deep.equal({ ref: '1.11.4001' }) + }) + + it('returns truncated ref if ref is commit hash', function () { + expect( + getDependencyVersion({ + wantedDependency: 'discordlists-py', + lockfileData: { + default: packages, + develop: {}, + }, + }) + ).to.deep.equal({ ref: '2df5a2b' }) + }) + + it('throws if no version or ref', function () { + expect(() => + getDependencyVersion({ + wantedDependency: 'django-cms', + lockfileData: { + default: packages, + develop: {}, + }, + }) + ) + .to.throw(InvalidParameter) + .with.property('prettyMessage', 'No version or ref for django-cms') + }) +})