Skip to content

Commit

Permalink
Merge pull request #5 from shreyas-jadhav/tests
Browse files Browse the repository at this point in the history
Tests
  • Loading branch information
brandonmcconnell authored Jun 13, 2023
2 parents 7badb69 + a0cec03 commit 8f2b5b0
Show file tree
Hide file tree
Showing 7 changed files with 8,955 additions and 2,206 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules/
.DS_Store
dist/
coverage/
71 changes: 41 additions & 30 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function hasOwn<T extends object>(obj: T, key: keyof T): key is keyof T {
}

// valid color modes for chroma-js
const validColorModes = [
export const validColorModes = [
'rgb',
'lab',
'lch',
Expand All @@ -32,7 +32,7 @@ const validColorModes = [
// types for tailwind-lerp-colors
type NumericObjKey = number | `${number}`;
type Shades = Record<NumericObjKey, string>;
type Colors = Record<string, Shades>;
type Colors = Record<string, Shades | string>;
type ColorMode = (typeof validColorModes)[number];
type Options = {
includeBase?: boolean;
Expand Down Expand Up @@ -67,17 +67,44 @@ const throwError = (message: string) => {
throw new Error(message);
};

const isValidShade = (shades: Shades) => {
if (
// undefined or null
shades == null ||
// check if shades is an object
typeof shades !== 'object' ||
// check if shades is an array
Array.isArray(shades) ||
shades.toString() !== '[object Object]' ||
!keys(shades).every((key) => {
return !isNaN(+key);
})
) {
return false;
}
return true;
};

export const lerpColor = (shades: Shades, options: SingularOptions = {}) => {
// validate lerpEnds
if (isOptionInvalid(options, 'lerpEnds', (v) => typeof v === 'boolean'))
throwError('tailwind-lerp-colors option `lerpEnds` must be a boolean.');

// validate interval
if (isOptionInvalid(options, 'interval', (v) => Number.isInteger(v) && typeof v === 'number' && v > 0))
throwError('tailwind-lerp-colors option `interval` must be a positive integer greater than 0.');

// validate mode
if (isOptionInvalid(options, 'mode', (v) => typeof v === 'string' && validColorModes.includes(v)))
throwError(
`tailwind-lerp-colors option \`mode\` must be one of the following values: ${validColorModes.join(', ')}.`
);

if (!isValidShade(shades))
throwError(
'tailwind-lerp-colors object `shades` must be an object with numeric keys.\n\nvalue used: ' +
JSON.stringify(shades, null, 2)
);
const { lerpEnds, interval, mode } = {
...defaultSingleOptions,
...(options ?? {}),
Expand All @@ -87,26 +114,12 @@ export const lerpColor = (shades: Shades, options: SingularOptions = {}) => {
return numericKeyA - numericKeyB;
};

if (
['null', 'undefined'].includes(typeof shades) ||
!shades.toString ||
typeof shades === 'string' ||
Array.isArray(shades) ||
shades.toString() !== '[object Object]' ||
!keys(shades).every((key) => {
return !isNaN(+key);
})
) {
throwError(
'tailwind-lerp-colors object `shades` must be an object with numeric keys.\n\nvalue used: ' +
JSON.stringify(shades, null, 2)
);
}
const shadesArray = entries(shades)
.map(([numericStringKey, color]) => {
return [Number(numericStringKey), color] as [number, string];
})
.sort(sortByNumericFirstIndex);

if (lerpEnds) {
shadesArray.unshift([0, '#ffffff']);
shadesArray.push([1000, '#000000']);
Expand Down Expand Up @@ -134,13 +147,16 @@ export const lerpColor = (shades: Shades, options: SingularOptions = {}) => {
};

export const lerpColors = (colorsObj: Colors = {}, options: Options = {}) => {
const legacyNames = ['lightBlue', 'warmGray', 'trueGray', 'coolGray', 'blueGray'];

// validate includeBase
if (isOptionInvalid(options, 'includeBase', (v) => typeof v === 'boolean'))
throwError('tailwind-lerp-colors option `includeBase` must be a boolean.');

// validate includeLegacy
if (isOptionInvalid(options, 'includeLegacy', (v) => typeof v === 'boolean'))
throwError('tailwind-lerp-colors option `includeLegacy` must be a boolean.');

const legacyNames = ['lightBlue', 'warmGray', 'trueGray', 'coolGray', 'blueGray'];

const { includeBase, includeLegacy, lerpEnds, interval, mode } = {
...defaultOptions,
...options,
Expand All @@ -154,6 +170,7 @@ export const lerpColors = (colorsObj: Colors = {}, options: Options = {}) => {
}
}
}

const initialColors = entries({
...baseColors,
...colorsObj,
Expand All @@ -162,20 +179,14 @@ export const lerpColors = (colorsObj: Colors = {}, options: Options = {}) => {
const finalColors: Colors = {};

for (const [name, shades] of initialColors) {
if (['null', 'undefined'].includes(typeof shades) || !shades.toString) {
continue;
}
finalColors[`${name}`] = shades;
if (
typeof shades === 'string' ||
Array.isArray(shades) ||
shades.toString() !== '[object Object]' ||
!keys(shades).every((key) => {
return !isNaN(+key);
})
) {

// some shades from tailwind base colors are not objects;
// skip those
if (!isValidShade(shades)) {
continue;
}

finalColors[name] = lerpColor(shades, { lerpEnds, interval, mode });
}

Expand Down
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
Loading

0 comments on commit 8f2b5b0

Please sign in to comment.