logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git
commit: c1568ad2ba283336378e135ce329bb4c4c1b92f2
parent 1050fed5589c44105c3d22aba3350969deb06e5c
Author: Henry Jameson <me@hjkos.com>
Date:   Mon, 25 Mar 2024 18:18:48 +0200

fix massive issue in getAllPossibleCombinations

Diffstat:

Msrc/services/theme_data/iss_utils.js16+++++++++++++---
Mtest/unit/specs/services/theme_data/theme_data3.spec.js18++++++++++++++++--
2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/src/services/theme_data/iss_utils.js b/src/services/theme_data/iss_utils.js @@ -11,18 +11,28 @@ export const unroll = (item) => { } // This gives you an array of arrays of all possible unique (i.e. order-insensitive) combinations +// Can only accept primitives. Duplicates are not supported and can cause unexpected behavior export const getAllPossibleCombinations = (array) => { const combos = [array.map(x => [x])] for (let comboSize = 2; comboSize <= array.length; comboSize++) { const previous = combos[combos.length - 1] - const selfSet = new Set() const newCombos = previous.map(self => { + const selfSet = new Set() self.forEach(x => selfSet.add(x)) const nonSelf = array.filter(x => !selfSet.has(x)) return nonSelf.map(x => [...self, x]) }) const flatCombos = newCombos.reduce((acc, x) => [...acc, ...x], []) - combos.push(flatCombos) + const uniqueComboStrings = new Set() + const uniqueCombos = flatCombos.map(x => x.toSorted()).filter(x => { + if (uniqueComboStrings.has(x.join())) { + return false + } else { + uniqueComboStrings.add(x.join()) + return true + } + }) + combos.push(uniqueCombos) } return combos.reduce((acc, x) => [...acc, ...x], []) } @@ -31,7 +41,7 @@ export const getAllPossibleCombinations = (array) => { export const genericRuleToSelector = components => (rule, ignoreOutOfTreeSelector, isParent) => { if (!rule && !isParent) return null const component = components[rule.component] - const { states, variants, selector, outOfTreeSelector } = component + const { states = {}, variants = {}, selector, outOfTreeSelector } = component const applicableStates = ((rule.state || []).filter(x => x !== 'normal')).map(state => states[state]) diff --git a/test/unit/specs/services/theme_data/theme_data3.spec.js b/test/unit/specs/services/theme_data/theme_data3.spec.js @@ -11,9 +11,23 @@ import { describe.only('Theme Data 3', () => { describe('getAllPossibleCombinations', () => { - it('test simple case', () => { + it('test simple 3 values case', () => { const out = getAllPossibleCombinations([1, 2, 3]).map(x => x.sort((a, b) => a - b)) - expect(out).to.eql([[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]) + expect(out).to.eql([ + [1], [2], [3], + [1, 2], [1, 3], [2, 3], + [1, 2, 3] + ]) + }) + + it('test simple 4 values case', () => { + const out = getAllPossibleCombinations([1, 2, 3, 4]).map(x => x.sort((a, b) => a - b)) + expect(out).to.eql([ + [1], [2], [3], [4], + [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4], + [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], + [1, 2, 3, 4] + ]) }) })