mirror of
https://github.com/zhigang1992/nativewind.git
synced 2026-06-12 08:58:20 +08:00
test: setup tailwindcss tests
This commit is contained in:
68
__tests__/tailwindcss/container.spec.ts
Normal file
68
__tests__/tailwindcss/container.spec.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { tailwindRunner, Case } from "./runner";
|
||||
|
||||
const cases: Array<Case> = [
|
||||
[
|
||||
"Layout - Container",
|
||||
[
|
||||
[
|
||||
"container",
|
||||
{
|
||||
styles: {
|
||||
container: { width: "100%" },
|
||||
container1: { maxWidth: 640 },
|
||||
container2: { maxWidth: 768 },
|
||||
container3: { maxWidth: 1024 },
|
||||
container4: { maxWidth: 1280 },
|
||||
container5: { maxWidth: 1536 },
|
||||
},
|
||||
media: {
|
||||
container: [
|
||||
{ media: ["(min-width: 640px)"], suffix: 1 },
|
||||
{ media: ["(min-width: 768px)"], suffix: 2 },
|
||||
{ media: ["(min-width: 1024px)"], suffix: 3 },
|
||||
{ media: ["(min-width: 1280px)"], suffix: 4 },
|
||||
{ media: ["(min-width: 1536px)"], suffix: 5 },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
"sm:container",
|
||||
{
|
||||
styles: {
|
||||
"sm\\:container0": { width: "100%" },
|
||||
"sm\\:container1": { maxWidth: 640 },
|
||||
"sm\\:container2": { maxWidth: 768 },
|
||||
"sm\\:container3": { maxWidth: 1024 },
|
||||
"sm\\:container4": { maxWidth: 1280 },
|
||||
"sm\\:container5": { maxWidth: 1536 },
|
||||
},
|
||||
media: {
|
||||
"sm\\:container": [
|
||||
{ media: ["(min-width: 640px)"], suffix: 0 },
|
||||
{ media: ["(min-width: 640px)"], suffix: 1 },
|
||||
{
|
||||
media: ["(min-width: 640px)", "(min-width: 768px)"],
|
||||
suffix: 2,
|
||||
},
|
||||
{
|
||||
media: ["(min-width: 640px)", "(min-width: 1024px)"],
|
||||
suffix: 3,
|
||||
},
|
||||
{
|
||||
media: ["(min-width: 640px)", "(min-width: 1280px)"],
|
||||
suffix: 4,
|
||||
},
|
||||
{
|
||||
media: ["(min-width: 640px)", "(min-width: 1536px)"],
|
||||
suffix: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
tailwindRunner(cases);
|
||||
30
__tests__/tailwindcss/runner.ts
Normal file
30
__tests__/tailwindcss/runner.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { MediaRecord, StyleRecord } from "../../src/babel/types";
|
||||
import { processStyles } from "../../src/babel/utils/process-styles";
|
||||
|
||||
export type Case = [string, Array<Test>];
|
||||
export type Test = [string, Expected];
|
||||
|
||||
export interface Expected {
|
||||
styles: StyleRecord;
|
||||
media?: MediaRecord;
|
||||
}
|
||||
|
||||
export function tailwindRunner(cases: Case[]) {
|
||||
describe.each(cases)("%s", (_, testCases) => {
|
||||
test.each(testCases)(
|
||||
"%s",
|
||||
(css, { styles: expectedStyles, media: expectedMedia }) => {
|
||||
const { styles, media } = processStyles({
|
||||
theme: {},
|
||||
content: [{ raw: `<div class="${css}">`, extension: "html" } as any],
|
||||
});
|
||||
|
||||
expect(styles).toEqual(expectedStyles);
|
||||
|
||||
if (expectedMedia) {
|
||||
expect(media).toEqual(expectedMedia);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -7,5 +7,6 @@ module.exports = {
|
||||
"/__tests__/native-context-fixtures/",
|
||||
"/__tests__/native-inline-fixtures/",
|
||||
"/__tests__/web-fixtures/",
|
||||
"/__tests__/tailwindcss/runner.ts",
|
||||
],
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ export default function (
|
||||
cwd: string
|
||||
) {
|
||||
const tailwindConfig = getTailwindConfig(cwd, options);
|
||||
const { styles, media } = processStyles(babel, tailwindConfig);
|
||||
const { styles, media } = processStyles(tailwindConfig);
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
|
||||
@@ -71,7 +71,7 @@ export default function (
|
||||
/**
|
||||
* Override tailwind to only process the classnames in this file
|
||||
*/
|
||||
const { styles, media } = processStyles(babel, {
|
||||
const { styles, media } = processStyles({
|
||||
...tailwindConfig,
|
||||
// Make sure its relative to the tailwind.config.js
|
||||
content: [relative(rootDir, filename)],
|
||||
|
||||
8
src/babel/types.d.ts
vendored
8
src/babel/types.d.ts
vendored
@@ -1,9 +1,15 @@
|
||||
import { ViewStyle, TextStyle, ImageStyle } from "react-native";
|
||||
import * as BabelCore from "@babel/core";
|
||||
|
||||
export type Style = ViewStyle | TextStyle | ImageStyle;
|
||||
export type Babel = typeof BabelCore;
|
||||
|
||||
export type Style = ViewStyle | TextStyle | ImageStyle;
|
||||
export type StyleRecord = Record<string, ViewStyle | TextStyle | ImageStyle>;
|
||||
export type MediaRecord = Record<
|
||||
string,
|
||||
Array<{ media: string[]; suffix: number }>
|
||||
>;
|
||||
|
||||
export interface TailwindReactNativeOptions {
|
||||
tailwindConfigPath?: string;
|
||||
platform?: "web" | "native" | "native-context" | "native-inline";
|
||||
|
||||
@@ -3,7 +3,7 @@ import { TailwindConfig } from "tailwindcss/tailwind-config";
|
||||
import { AtRule, Comment, Media, Rule, StyleRules } from "css";
|
||||
|
||||
import { normaliseSelector } from "../../shared/selector";
|
||||
import { Babel, Style } from "../types";
|
||||
import { Style } from "../types";
|
||||
import { isValidStyle } from "./is-valid-style";
|
||||
|
||||
interface CssRule {
|
||||
@@ -19,14 +19,13 @@ interface CssRule {
|
||||
* - flattens styles to be react-native style objects
|
||||
*/
|
||||
export function flattenRules(
|
||||
babel: Babel,
|
||||
cssRules: StyleRules["rules"],
|
||||
tailwindConfig: TailwindConfig,
|
||||
media: string[] = []
|
||||
): CssRule[] {
|
||||
return cssRules.flatMap((cssRule) => {
|
||||
if (isMedia(cssRule)) {
|
||||
return flattenRules(babel, cssRule.rules ?? [], tailwindConfig, [
|
||||
return flattenRules(cssRule.rules ?? [], tailwindConfig, [
|
||||
...new Set(cssRule.media ? [...media, cssRule.media] : media),
|
||||
]);
|
||||
} else if (isRule(cssRule)) {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Expression, Statement } from "@babel/types";
|
||||
import { Babel } from "../types";
|
||||
import { Statement } from "@babel/types";
|
||||
import serialize from "babel-literal-to-ast";
|
||||
import { Babel, MediaRecord, StyleRecord } from "../types";
|
||||
|
||||
export function appendVariables(
|
||||
babel: Babel,
|
||||
body: Statement[],
|
||||
styles: Expression,
|
||||
media: Expression
|
||||
styles: StyleRecord,
|
||||
media: MediaRecord
|
||||
) {
|
||||
const { types: t } = babel;
|
||||
|
||||
@@ -18,7 +19,7 @@ export function appendVariables(
|
||||
t.identifier("StyleSheet"),
|
||||
t.identifier("create")
|
||||
),
|
||||
[styles]
|
||||
[serialize(styles)]
|
||||
)
|
||||
),
|
||||
])
|
||||
@@ -26,7 +27,7 @@ export function appendVariables(
|
||||
|
||||
body.push(
|
||||
t.variableDeclaration("const", [
|
||||
t.variableDeclarator(t.identifier("__tailwindMedia"), media),
|
||||
t.variableDeclarator(t.identifier("__tailwindMedia"), serialize(media)),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Babel, Style } from "../types";
|
||||
import { MediaRecord, Style, StyleRecord } from "../types";
|
||||
|
||||
import css from "css";
|
||||
import postcss from "postcss";
|
||||
@@ -6,15 +6,15 @@ import tailwind from "tailwindcss";
|
||||
import postcssCssvariables from "postcss-css-variables";
|
||||
import postcssColorRBG from "postcss-color-rgb";
|
||||
import postcssRemToPixel from "postcss-rem-to-pixel";
|
||||
import serialize from "babel-literal-to-ast";
|
||||
|
||||
import { flattenRules } from "./flatten-rules";
|
||||
import { normaliseSelector } from "../../shared/selector";
|
||||
import { TailwindConfig } from "tailwindcss/tailwind-config";
|
||||
|
||||
export function processStyles(babel: Babel, tailwindConfig: TailwindConfig) {
|
||||
const cssInput = "@tailwind utilities";
|
||||
|
||||
export function processStyles(
|
||||
tailwindConfig: TailwindConfig,
|
||||
cssInput: string = "@tailwind components;@tailwind utilities;"
|
||||
) {
|
||||
const processedCss = postcss([
|
||||
tailwind(tailwindConfig),
|
||||
postcssCssvariables(),
|
||||
@@ -36,13 +36,10 @@ export function processStyles(babel: Babel, tailwindConfig: TailwindConfig) {
|
||||
|
||||
const cssRules = css.parse(processedCss).stylesheet?.rules ?? [];
|
||||
|
||||
const parsedRules = flattenRules(babel, cssRules, tailwindConfig);
|
||||
const parsedRules = flattenRules(cssRules, tailwindConfig);
|
||||
|
||||
const styles: Record<string, Style> = {};
|
||||
const mediaRules: Record<
|
||||
string,
|
||||
Array<{ media: string[]; suffix: number }>
|
||||
> = {};
|
||||
const styles: StyleRecord = {};
|
||||
const mediaRules: MediaRecord = {};
|
||||
|
||||
for (const [suffix, parsedRule] of parsedRules.entries()) {
|
||||
const { selector, media, rules } = parsedRule;
|
||||
@@ -66,7 +63,7 @@ export function processStyles(babel: Babel, tailwindConfig: TailwindConfig) {
|
||||
}
|
||||
|
||||
return {
|
||||
styles: serialize(styles),
|
||||
media: serialize(mediaRules),
|
||||
styles,
|
||||
media: mediaRules,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user