From a2592b8d5db8c7b585b050987a3073bfc14dee7e Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Sun, 7 Feb 2021 17:21:51 +0100 Subject: [PATCH] models/version: Add `features/featureList` properties --- app/models/version.js | 14 +++++++ tests/models/version-test.js | 81 ++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/app/models/version.js b/app/models/version.js index 23c69e9a3dd..262d7aca4a2 100644 --- a/app/models/version.js +++ b/app/models/version.js @@ -13,6 +13,7 @@ export default class Version extends Model { @attr('date') created_at; @attr('date') updated_at; @attr downloads; + @attr features; @attr yanked; @attr license; @attr crate_size; @@ -29,6 +30,19 @@ export default class Version extends Model { }) crateName; + get featureList() { + let { features } = this; + if (typeof features !== 'object' || features === null) { + return []; + } + + let defaultFeatures = features.default ?? []; + return Object.keys(features) + .filter(name => name !== 'default') + .sort() + .map(name => ({ name, isDefault: defaultFeatures.includes(name), dependencies: features[name] })); + } + @alias('loadAuthorsTask.last.value') authorNames; @(task(function* () { diff --git a/tests/models/version-test.js b/tests/models/version-test.js index 904c47c05f5..545d1cf5e67 100644 --- a/tests/models/version-test.js +++ b/tests/models/version-test.js @@ -11,6 +11,87 @@ module('Model | Version', function (hooks) { this.store = this.owner.lookup('service:store'); }); + module('featuresList', function () { + async function prepare(context, { features }) { + let { server, store } = context; + + let crate = server.create('crate'); + server.create('version', { crate, features }); + + let crateRecord = await store.findRecord('crate', crate.id); + let versions = (await crateRecord.versions).toArray(); + return versions[0]; + } + + test('`features: {}` results in empty list', async function (assert) { + let version = await prepare(this, { features: {} }); + assert.deepEqual(version.featureList, []); + }); + + test('`features: null` results in empty list', async function (assert) { + let version = await prepare(this, { features: null }); + assert.deepEqual(version.featureList, []); + }); + + test('real world case', async function (assert) { + let features = { + alloc: ['rand_core/alloc'], + default: ['std', 'std_rng'], + getrandom: ['rand_core/getrandom'], + nightly: [], + serde1: ['serde'], + simd_support: ['packed_simd'], + small_rng: [], + std: ['rand_core/std', 'rand_chacha/std', 'alloc', 'getrandom', 'libc'], + std_rng: ['rand_chacha', 'rand_hc'], + }; + + let version = await prepare(this, { features }); + assert.deepEqual(version.featureList, [ + { + dependencies: ['rand_core/alloc'], + isDefault: false, + name: 'alloc', + }, + { + dependencies: ['rand_core/getrandom'], + isDefault: false, + name: 'getrandom', + }, + { + dependencies: [], + isDefault: false, + name: 'nightly', + }, + { + dependencies: ['serde'], + isDefault: false, + name: 'serde1', + }, + { + dependencies: ['packed_simd'], + isDefault: false, + name: 'simd_support', + }, + { + dependencies: [], + isDefault: false, + name: 'small_rng', + }, + { + dependencies: ['rand_core/std', 'rand_chacha/std', 'alloc', 'getrandom', 'libc'], + isDefault: true, + name: 'std', + }, + { + dependencies: ['rand_chacha', 'rand_hc'], + isDefault: true, + name: 'std_rng', + }, + ]); + }); + }); + test('`published_by` relationship is assigned correctly', async function (assert) { let user = this.server.create('user', { name: 'JD' });