From 2352979708f778c46744e38383c24a7fa6549672 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Mon, 14 Feb 2022 18:07:03 +0100 Subject: [PATCH] implement `getSortOrder` instead of `sortClassList` --- src/lib/setupContextUtils.js | 30 +++++--------- ...ClassList.test.js => getSortOrder.test.js} | 41 ++++++++++++++++++- 2 files changed, 50 insertions(+), 21 deletions(-) rename tests/{sortClassList.test.js => getSortOrder.test.js} (64%) diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index beea5b47d34b..e2a32e832771 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -744,33 +744,25 @@ function registerPlugins(plugins, context) { // sorting could be weird since you still require them in order to make the // host utitlies work properly. (Thanks Biology) let parasiteUtilities = new Set([prefix(context, 'group'), prefix(context, 'peer')]) - context.sortClassList = function sortClassList(classes) { + context.getSortOrder = function getSortOrder(classes) { let sortedClassNames = new Map() for (let [sort, rule] of generateRules(new Set(classes), context)) { if (sortedClassNames.has(rule.raws.tailwind.candidate)) continue sortedClassNames.set(rule.raws.tailwind.candidate, sort) } - return classes - .map((className) => { - let order = sortedClassNames.get(className) ?? null + return classes.map((className) => { + let order = sortedClassNames.get(className) ?? null - if (order === null && parasiteUtilities.has(className)) { - // This will make sure that it is at the very beginning of the - // `components` layer which technically means 'before any - // components'. - order = context.layerOrder.components - } + if (order === null && parasiteUtilities.has(className)) { + // This will make sure that it is at the very beginning of the + // `components` layer which technically means 'before any + // components'. + order = context.layerOrder.components + } - return [className, order] - }) - .sort(([, a], [, z]) => { - if (a === z) return 0 - if (a === null) return -1 - if (z === null) return 1 - return bigSign(a - z) - }) - .map(([className]) => className) + return [className, order] + }) } // Generate a list of strings for autocompletion purposes, e.g. diff --git a/tests/sortClassList.test.js b/tests/getSortOrder.test.js similarity index 64% rename from tests/sortClassList.test.js rename to tests/getSortOrder.test.js index 0220f190727a..00868ef100ab 100644 --- a/tests/sortClassList.test.js +++ b/tests/getSortOrder.test.js @@ -1,5 +1,42 @@ import resolveConfig from '../src/public/resolve-config' import { createContext } from '../src/lib/setupContextUtils' +import bigSign from '../src/util/bigSign' + +/** + * This is a function that the prettier-plugin-tailwindcss would use. It would + * do the actual sorting based on the classes and order we return from `getSortOrder`. + * + * This way the actual sorting logic is done in the plugin which allows you to + * put unknown classes at the end for example. + * + * @param {Array<[string, bigint]>} arrayOfTuples + * @returns {string} + */ +function defaultSort(arrayOfTuples) { + return arrayOfTuples + .sort(([, a], [, z]) => { + if (a === z) return 0 + if (a === null) return -1 + if (z === null) return 1 + return bigSign(a - z) + }) + .map(([className]) => className) + .join(' ') +} + +it('should return a list of tuples with the sort order', () => { + let input = 'font-bold underline hover:font-medium unknown' + let config = {} + let context = createContext(resolveConfig(config)) + expect(context.getSortOrder(input.split(' '))).toEqual([ + ['font-bold', expect.any(BigInt)], + ['underline', expect.any(BigInt)], + ['hover:font-medium', expect.any(BigInt)], + + // Unknown values receive `null` + ['unknown', null], + ]) +}) it.each([ // Utitlies @@ -33,7 +70,7 @@ it.each([ ])('should sort "%s" based on the order we generate them in to "%s"', (input, output) => { let config = {} let context = createContext(resolveConfig(config)) - expect(context.sortClassList(input.split(' ')).join(' ')).toEqual(output) + expect(defaultSort(context.getSortOrder(input.split(' ')))).toEqual(output) }) it.each([ @@ -73,6 +110,6 @@ it.each([ (input, output) => { let config = { prefix: 'tw-' } let context = createContext(resolveConfig(config)) - expect(context.sortClassList(input.split(' ')).join(' ')).toEqual(output) + expect(defaultSort(context.getSortOrder(input.split(' ')))).toEqual(output) } )