Skip to content

Commit

Permalink
feat: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Niznikr committed Jan 17, 2025
1 parent 2210a38 commit 4f6860a
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 32 deletions.
174 changes: 174 additions & 0 deletions packages/tokens/__tests__/__snapshots__/tokens.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Tokens > builds dark alias tokens 1`] = `
"/**
* Do not edit directly, this file was auto-generated.
*/
[data-theme='dark'] {
--lp-color-bg-interactive-link: rgba(71, 97, 255, 0.2);
--lp-color-bg-feedback-error: var(--lp-color-red-900);
--lp-color-bg-feedback-info: var(--lp-color-blue-900);
--lp-color-bg-feedback-success: var(--lp-color-green-900);
--lp-color-bg-interactive-primary-base: var(--lp-color-blue-600);
--lp-color-bg-interactive-primary-active: var(--lp-color-blue-600);
--lp-color-bg-interactive-primary-focus: var(--lp-color-blue-500);
--lp-color-bg-interactive-primary-hover: var(--lp-color-blue-500);
--lp-color-bg-interactive-secondary-focus: var(--lp-color-gray-800);
--lp-color-bg-interactive-secondary-hover: var(--lp-color-gray-800);
--lp-color-bg-interactive-tertiary-focus: var(--lp-color-gray-800);
--lp-color-bg-interactive-tertiary-hover: var(--lp-color-gray-800);
--lp-color-bg-interactive-destructive-base: var(--lp-color-red-600);
--lp-color-bg-interactive-destructive-active: var(--lp-color-red-600);
--lp-color-bg-interactive-destructive-focus: var(--lp-color-red-500);
--lp-color-bg-interactive-destructive-hover: var(--lp-color-red-500);
--lp-color-bg-interactive-disabled: var(--lp-color-gray-800);
--lp-color-bg-interactive-selected: var(--lp-color-blue-950);
--lp-color-bg-ui-primary: var(--lp-color-gray-950);
--lp-color-bg-ui-secondary: var(--lp-color-gray-900);
--lp-color-bg-ui-tertiary: var(--lp-color-gray-800);
--lp-color-bg-product-beta: var(--lp-color-purple-900);
--lp-color-bg-product-federal: var(--lp-color-brand-yellow-dark);
--lp-color-border-feedback-error: var(--lp-color-red-400);
--lp-color-border-feedback-info: var(--lp-color-blue-400);
--lp-color-border-feedback-success: var(--lp-color-green-400);
--lp-color-border-field-active: var(--lp-color-blue-400);
--lp-color-border-field-focus: var(--lp-color-blue-400);
--lp-color-border-interactive-focus: var(--lp-color-blue-400);
--lp-color-border-interactive-selected: var(--lp-color-blue-400);
--lp-color-border-ui-primary: var(--lp-color-gray-700);
--lp-color-border-ui-secondary: var(--lp-color-gray-800);
--lp-color-fill-ui-primary: var(--lp-color-gray-200);
--lp-color-fill-field-base: var(--lp-color-gray-400);
--lp-color-shadow-interactive-focus: var(--lp-color-blue-400);
--lp-color-shadow-interactive-primary: var(--lp-color-gray-950);
--lp-color-shadow-ui-primary: var(--lp-color-black-200);
--lp-color-shadow-ui-secondary: var(--lp-color-black-100);
--lp-color-text-feedback-error: var(--lp-color-red-400);
--lp-color-text-feedback-success: var(--lp-color-green-400);
--lp-color-text-feedback-info: var(--lp-color-blue-400);
--lp-color-text-interactive-base: var(--lp-color-blue-400);
--lp-color-text-interactive-active: var(--lp-color-purple-400);
--lp-color-text-interactive-secondary: var(--lp-color-gray-400);
--lp-color-text-interactive-disabled: var(--lp-color-gray-600);
--lp-color-text-ui-primary-base: var(--lp-color-gray-0);
--lp-color-text-ui-primary-inverted: var(--lp-color-gray-950);
--lp-color-text-ui-secondary: var(--lp-color-gray-400);
--lp-color-text-field-placeholder: var(--lp-color-gray-400);
--lp-color-text-product-beta: var(--lp-color-purple-400);
--lp-color-text-code-function: var(--lp-color-brand-purple-base);
--lp-color-text-code-tag: var(--lp-color-brand-orange-base);
--lp-color-text-code-string: var(--lp-color-brand-cyan-light);
--lp-color-text-code-base: var(--lp-color-gray-200);
--lp-color-text-code-keyword: var(--lp-color-brand-pink-light);
--lp-color-text-code-title: var(--lp-color-brand-orange-light);
--lp-color-text-code-number: var(--lp-color-brand-blue-light);
--lp-color-bg-overlay-secondary: var(--lp-color-bg-ui-secondary);
--lp-color-bg-field-base: var(--lp-color-bg-ui-secondary);
}
"
`;

exports[`Tokens > builds default alias tokens 1`] = `
"/**
* Do not edit directly, this file was auto-generated.
*/
:root, [data-theme] {
--lp-color-bg-interactive-tertiary-base: rgba(0, 0, 0, 0);
--lp-color-bg-interactive-tertiary-active: rgba(0, 0, 0, 0);
--lp-color-border-interactive-primary-base: rgba(0, 0, 0, 0);
--lp-color-border-interactive-primary-active: rgba(0, 0, 0, 0);
--lp-color-border-interactive-primary-focus: rgba(0, 0, 0, 0);
--lp-color-border-interactive-primary-hover: rgba(0, 0, 0, 0);
--lp-color-border-interactive-disabled: rgba(0, 0, 0, 0);
--lp-color-bg-feedback-primary: var(--lp-color-gray-800);
--lp-color-bg-feedback-error: var(--lp-color-red-50);
--lp-color-bg-feedback-info: var(--lp-color-blue-50);
--lp-color-bg-feedback-success: var(--lp-color-green-50);
--lp-color-bg-interactive-primary-base: var(--lp-color-blue-500);
--lp-color-bg-interactive-primary-active: var(--lp-color-blue-500);
--lp-color-bg-interactive-primary-focus: var(--lp-color-blue-600);
--lp-color-bg-interactive-primary-hover: var(--lp-color-blue-600);
--lp-color-bg-interactive-secondary-focus: var(--lp-color-gray-50);
--lp-color-bg-interactive-secondary-hover: var(--lp-color-gray-50);
--lp-color-bg-interactive-tertiary-focus: var(--lp-color-gray-50);
--lp-color-bg-interactive-tertiary-hover: var(--lp-color-gray-50);
--lp-color-bg-interactive-destructive-base: var(--lp-color-red-500);
--lp-color-bg-interactive-destructive-active: var(--lp-color-red-500);
--lp-color-bg-interactive-destructive-focus: var(--lp-color-red-600);
--lp-color-bg-interactive-destructive-hover: var(--lp-color-red-600);
--lp-color-bg-interactive-disabled: var(--lp-color-gray-100);
--lp-color-bg-interactive-link: var(--lp-color-blue-50);
--lp-color-bg-interactive-selected: var(--lp-color-blue-0);
--lp-color-bg-ui-primary: var(--lp-color-white-950);
--lp-color-bg-ui-secondary: var(--lp-color-gray-0);
--lp-color-bg-ui-tertiary: var(--lp-color-gray-50);
--lp-color-bg-product-beta: var(--lp-color-purple-100);
--lp-color-bg-product-federal: var(--lp-color-brand-yellow-base);
--lp-color-border-feedback-error: var(--lp-color-red-500);
--lp-color-border-feedback-info: var(--lp-color-blue-500);
--lp-color-border-feedback-success: var(--lp-color-green-500);
--lp-color-border-field-active: var(--lp-color-blue-500);
--lp-color-border-field-focus: var(--lp-color-blue-500);
--lp-color-border-interactive-focus: var(--lp-color-blue-500);
--lp-color-border-interactive-selected: var(--lp-color-blue-500);
--lp-color-border-ui-primary: var(--lp-color-gray-100);
--lp-color-border-ui-secondary: var(--lp-color-gray-50);
--lp-color-fill-feedback-error: var(--lp-color-red-500);
--lp-color-fill-feedback-info: var(--lp-color-blue-500);
--lp-color-fill-feedback-success: var(--lp-color-green-500);
--lp-color-fill-interactive-primary: var(--lp-color-white-950);
--lp-color-fill-interactive-destructive: var(--lp-color-red-500);
--lp-color-fill-ui-primary: var(--lp-color-gray-700);
--lp-color-fill-ui-secondary: var(--lp-color-gray-500);
--lp-color-fill-field-base: var(--lp-color-gray-600);
--lp-color-shadow-interactive-focus: var(--lp-color-blue-600);
--lp-color-shadow-interactive-primary: var(--lp-color-white-950);
--lp-color-shadow-ui-primary: var(--lp-color-black-50);
--lp-color-shadow-ui-secondary: var(--lp-color-black-0);
--lp-color-text-feedback-error: var(--lp-color-red-600);
--lp-color-text-feedback-success: var(--lp-color-green-600);
--lp-color-text-feedback-info: var(--lp-color-blue-600);
--lp-color-text-interactive-base: var(--lp-color-blue-600);
--lp-color-text-interactive-active: var(--lp-color-purple-700);
--lp-color-text-interactive-primary-base: var(--lp-color-white-950);
--lp-color-text-interactive-primary-active: var(--lp-color-white-950);
--lp-color-text-interactive-primary-focus: var(--lp-color-white-950);
--lp-color-text-interactive-primary-hover: var(--lp-color-white-950);
--lp-color-text-interactive-secondary: var(--lp-color-gray-600);
--lp-color-text-interactive-disabled: var(--lp-color-gray-500);
--lp-color-text-ui-primary-base: var(--lp-color-gray-900);
--lp-color-text-ui-primary-inverted: var(--lp-color-white-950);
--lp-color-text-ui-secondary: var(--lp-color-gray-600);
--lp-color-text-field-disabled: var(--lp-color-gray-500);
--lp-color-text-field-placeholder: var(--lp-color-gray-500);
--lp-color-text-product-beta: var(--lp-color-purple-600);
--lp-color-text-product-federal: var(--lp-color-gray-950);
--lp-color-text-code-function: var(--lp-color-brand-purple-dark);
--lp-color-text-code-tag: var(--lp-color-brand-orange-dark);
--lp-color-text-code-string: var(--lp-color-brand-cyan-dark);
--lp-color-text-code-comment: var(--lp-color-gray-400);
--lp-color-text-code-base: var(--lp-color-gray-600);
--lp-color-text-code-keyword: var(--lp-color-brand-pink-base);
--lp-color-text-code-title: var(--lp-color-brand-orange-base);
--lp-color-text-code-number: var(--lp-color-brand-blue-dark);
--lp-color-bg-interactive-secondary-base: var(--lp-color-bg-ui-primary);
--lp-color-bg-interactive-secondary-active: var(--lp-color-bg-ui-primary);
--lp-color-bg-overlay-primary: var(--lp-color-bg-ui-primary);
--lp-color-bg-overlay-secondary: var(--lp-color-bg-ui-primary);
--lp-color-bg-field-base: var(--lp-color-bg-ui-primary);
--lp-color-bg-field-disabled: var(--lp-color-bg-ui-tertiary);
--lp-color-border-field-base: var(--lp-color-border-ui-primary);
--lp-color-border-field-error: var(--lp-color-border-feedback-error);
--lp-color-border-field-disabled: var(--lp-color-border-ui-secondary);
--lp-color-border-interactive-secondary-base: var(--lp-color-border-ui-primary);
--lp-color-border-interactive-secondary-active: var(--lp-color-border-ui-primary);
--lp-color-border-interactive-secondary-focus: var(--lp-color-border-ui-primary);
--lp-color-border-interactive-secondary-hover: var(--lp-color-border-ui-primary);
--lp-color-border-interactive-destructive: var(--lp-color-border-feedback-error);
--lp-color-text-feedback-base: var(--lp-color-text-ui-primary-base);
--lp-color-text-interactive-destructive: var(--lp-color-text-feedback-error);
}
"
`;
57 changes: 57 additions & 0 deletions packages/tokens/__tests__/tokens.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { DesignTokens } from 'style-dictionary/types';

import path from 'path';
import StyleDictionary from 'style-dictionary';
import { describe, expect, it } from 'vitest';

import { css } from '../src/themes';
import aliasDark from '../tokens/color-aliases.dark.json' with { type: 'json' };
import aliasDefault from '../tokens/color-aliases.default.json' with { type: 'json' };

const sameKeys = (tokens1: DesignTokens, tokens2: DesignTokens) => {
for (const key in tokens1) {
if (!(key in tokens2)) {
return false;
}

if (typeof tokens1[key] === 'object' && typeof tokens2[key] === 'object') {
if (!sameKeys(tokens1[key], tokens2[key])) {
return false;
}
}
}

return true;
};

describe('Tokens', () => {
it('uses default theme as base for dark theme', () => {
expect(sameKeys(aliasDark, aliasDefault)).toBeTruthy();
});

it('builds default alias tokens', async () => {
const config = css('default');
config.source = [
path.resolve(__dirname, '../tokens/color-primitives.json'),
path.resolve(__dirname, '../tokens/color-aliases.default.json'),
];

const sd = new StyleDictionary(config);
const [file] = await sd.formatPlatform('css');

expect(file.output).toMatchSnapshot();
});

it('builds dark alias tokens', async () => {
const config = css('dark');
config.source = [
path.resolve(__dirname, '../tokens/color-primitives.json'),
path.resolve(__dirname, '../tokens/color-aliases.dark.json'),
];

const sd = new StyleDictionary(config);
const [file] = await sd.formatPlatform('css');

expect(file.output).toMatchSnapshot();
});
});
4 changes: 2 additions & 2 deletions packages/tokens/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
"./dist/tokens.json": "./dist/tokens.json"
},
"scripts": {
"build": "tsx build.ts && tsc --noEmit",
"build": "tsx src/build.ts && tsc --noEmit",
"clean": "rm -rf dist",
"lint": "exit 0",
"test": "exit 0"
"test": "vitest run"
},
"devDependencies": {
"json-to-ts": "^2.1.0",
Expand Down
36 changes: 6 additions & 30 deletions packages/tokens/build.ts → packages/tokens/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,17 @@ import StyleDictionary from 'style-dictionary';
import { formats, transformGroups, transforms } from 'style-dictionary/enums';
import { fileHeader, minifyDictionary } from 'style-dictionary/utils';

const themes = ['dark', 'default'].map(
(theme) =>
({
source: ['tokens/color-primitives.json', `tokens/*.${theme}.json`],
platforms: {
css: {
prefix: 'lp',
transformGroup: transformGroups.css,
transforms: [transforms.colorRgb],
options: {
outputReferences: true,
usesDtcg: true,
},
files: [
{
destination: `${theme}.css`,
format: formats.cssVariables,
options: {
selector: theme === 'default' ? ':root, [data-theme]' : `[data-theme='${theme}']`,
},
filter: (token) => token.filePath.includes(theme),
},
],
},
},
}) satisfies Config,
);
import { css, themes } from './themes';

const configs = themes.map(css);

const runSD = async (cfg: Config) => {
const sd = new StyleDictionary(cfg);
const [file] = await sd.formatPlatform('css');
return [file.destination, file.output];
};

const outputs = Object.fromEntries(await Promise.all(themes.map(runSD)));
const aliasTokens = Object.fromEntries(await Promise.all(configs.map(runSD)));

const sd = new StyleDictionary({
source: ['tokens/*.json'],
Expand Down Expand Up @@ -142,8 +118,8 @@ const sd = new StyleDictionary({
sd.registerFormat({
name: 'css/themes',
format: async () => {
const light = outputs['default.css'];
const dark = outputs['dark.css'];
const light = aliasTokens['default.css'];
const dark = aliasTokens['dark.css'];

return `${light}\n${dark}`;
},
Expand Down
31 changes: 31 additions & 0 deletions packages/tokens/src/themes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Config } from 'style-dictionary/types';

import { formats, transformGroups, transforms } from 'style-dictionary/enums';

export const themes = ['default', 'dark'] as const;
export type Theme = (typeof themes)[number];

export const css = (theme: Theme): Config => ({
source: ['tokens/color-primitives.json', `tokens/*.${theme}.json`],
platforms: {
css: {
prefix: 'lp',
transformGroup: transformGroups.css,
transforms: [transforms.colorRgb],
options: {
outputReferences: true,
usesDtcg: true,
},
files: [
{
destination: `${theme}.css`,
format: formats.cssVariables,
options: {
selector: theme === 'default' ? ':root, [data-theme]' : `[data-theme='${theme}']`,
},
filter: (token) => token.filePath.includes(theme),
},
],
},
},
});

0 comments on commit 4f6860a

Please sign in to comment.