Skip to content

Commit

Permalink
fix(vitest): change test-case to directly module
Browse files Browse the repository at this point in the history
META DATA: @toantranmei
  • Loading branch information
toantranmei committed Apr 5, 2024
1 parent aa0b801 commit b87b337
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 20 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"ohash",
"pathe",
"popperjs",
"safelisting",
"scule",
"tailwindcss",
"toantran",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"lint-staged": "^15.2.2",
"nuxt": "^3.11.1",
"release-it": "^17.1.1",
"typescript": "^5.4.4",
"typescript": "5.3",
"vitest": "^1.4.0",
"vue-tsc": "^2.0.10"
},
Expand Down
7 changes: 3 additions & 4 deletions src/runtime/plugins/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,26 @@ import logger from "consola";
import { hexToRgb } from "../utils";
import { defineNuxtPlugin, useAppConfig, useNuxtApp, useHead } from "#imports";
import colors from "#tailwind-config/index.mjs";
import { name } from "../../../package.json";

export default defineNuxtPlugin(() => {
const appConfig = useAppConfig();
const nuxtApp = useNuxtApp();

const root = computed(() => {
const primary: Record<string, string> | undefined =
// @ts-ignore
colors[appConfig.meiUI.primary];
const gray: Record<string, string> | undefined =
// @ts-ignore
colors[appConfig.meiUI.gray];

if (!primary) {
logger.warn(
`[@mei-ui] Primary color '${appConfig.meiUI?.primary}' not found in Tailwind config`
`[${name}] Primary color '${appConfig.meiUI?.primary}' not found in Tailwind config`
);
}
if (!gray) {
logger.warn(
`[@mei-ui] Gray color '${appConfig.meiUI?.gray}' not found in Tailwind config`
`[${name}] Gray color '${appConfig.meiUI?.gray}' not found in Tailwind config`
);
}

Expand Down
164 changes: 149 additions & 15 deletions test/basic.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,149 @@
import { describe, it, expect } from 'vitest'
import { fileURLToPath } from 'node:url'
import { setup, $fetch } from '@nuxt/test-utils/e2e'

describe('ssr', async () => {
await setup({
rootDir: fileURLToPath(new URL('./fixtures/basic', import.meta.url)),
})

it('renders the index page', async () => {
// Get response to a server-rendered page with `$fetch`.
const html = await $fetch('/')
expect(html).toContain('<div>basic</div>')
})
})
import { describe, expect, it } from "vitest";
import { defu } from "defu";
import { join } from "pathe";
import { loadNuxt } from "@nuxt/kit";
import type { NuxtConfig } from "@nuxt/schema";
import type * as tailwindcss from "tailwindcss";
type TWConfig = tailwindcss.Config;
import type resolveConfig from "tailwindcss/resolveConfig";

async function getTailwindCSSConfig(overrides: Partial<NuxtConfig> = {}) {
let tailwindConfig: ReturnType<typeof resolveConfig<TWConfig>>;
const nuxt = await loadNuxt({
ready: true,
cwd: join(process.cwd(), "fixtures", "empty"),
dev: false,
overrides: defu(overrides, {
ssr: false,
modules: ["../src/module.ts"],
hooks: {
// @ts-ignore
"tailwindcss:resolvedConfig"(
config: ReturnType<typeof resolveConfig<TWConfig>>
): void {
tailwindConfig = config;
},
},
} satisfies NuxtConfig) as NuxtConfig,
});
const nuxtOptions = structuredClone({
plugins: nuxt.options.plugins.map(
(p) => typeof p !== "string" && { src: p.src, mode: p.mode }
),
_requiredModules: nuxt.options._requiredModules,
appConfig: nuxt.options.appConfig,
});
await nuxt.close();

return {
nuxtOptions,
tailwindConfig,
};
}

describe("nuxt", () => {
it("should add plugins and modules to nuxt", async () => {
const { nuxtOptions } = await getTailwindCSSConfig();
expect(nuxtOptions.plugins).toContainEqual(
expect.objectContaining({
src: expect.stringContaining("plugins/colors"),
mode: "all",
})
);
expect(nuxtOptions._requiredModules).toMatchObject({
"@nuxtjs/color-mode": true,
"@nuxtjs/tailwindcss": true,
});
// default values in appConfig
expect(nuxtOptions.appConfig?.meiUI).toMatchObject({
primary: "green",
gray: "cool",
});
});
});

describe("tailwindcss config", () => {
it.each([
/* format:
name,
tailwindcss config, safelistColors,
expected safelistPatterns (add "!" before a pattern to negate it)
*/
[
"default safelist",
{},
[],
["bg-(primary)-50", "bg-(red)-500"], // these both should be in the safelist
],
[
"safelisting single new color",
{},
["myColor"],
"bg-(myColor|primary)-50",
],
[
"reducing amount of theme colors",
{ theme: { colors: { plainBlue: "#00F" } } },
["plainBlue"],
["bg-(plainBlue|primary)-50", "!", /orange/], // the word "orange" should _not_ be found in any safelist pattern
],
])(
"%s",
async (_description, tailwindcss, safelistColors, safelistPatterns) => {
const { tailwindConfig } = await getTailwindCSSConfig({
// @ts-ignore
meiUI: {
safelistColors,
},
tailwindcss: {
config: tailwindcss,
},
});
expect.extend({
toBeRegExp: (received, expected) => {
if (typeof expected === "string" || expected instanceof String) {
return {
message: () =>
`expected ${received} to be exact regex ${expected}`,
pass:
received.toString() === RegExp(expected as string).toString(),
};
} else if (expected instanceof RegExp) {
return {
message: () =>
`expected ${received} to be a regex like ${expected.toString()}`,
pass: received.toString().match(expected),
};
}
return {
message: () => `expected ${received} to be a regex`,
pass: false,
};
},
});
safelistPatterns =
safelistPatterns instanceof Array
? safelistPatterns
: [safelistPatterns];

let negate = false;
for (const safelistPattern of safelistPatterns) {
if (safelistPattern === "!") {
// negate next!
negate = true;
continue;
}
if (negate) {
expect(tailwindConfig.safelist).not.toContainEqual({
pattern: expect.toBeRegExp(safelistPattern),
});
} else {
expect(tailwindConfig.safelist).toContainEqual({
pattern: expect.toBeRegExp(safelistPattern),
});
}
negate = false;
}
}
);
});
11 changes: 11 additions & 0 deletions test/vitest.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type { Assertion, AsymmetricMatchersContaining } from "vitest";

interface CustomMatchers<R = unknown> {
toBeRegExp(expected: string | RegExp): R;
}

declare module "vitest" {
interface Assertion<T = any> extends CustomMatchers<T> {}
interface AsymmetricMatchersContaining extends CustomMatchers {}
}

0 comments on commit b87b337

Please sign in to comment.