|
1 | 1 | import * as fs from "fs"; |
2 | 2 | import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
3 | | -import { extractCustomTheme, findTailwindConfig, loadTailwindConfig } from "./config-loader"; |
| 3 | +import { |
| 4 | + extractCustomTheme, |
| 5 | + findTailwindConfig, |
| 6 | + loadTailwindConfig, |
| 7 | + warnUnsupportedThemeKeys, |
| 8 | +} from "./config-loader"; |
4 | 9 |
|
5 | 10 | // Mock fs |
6 | 11 | vi.mock("fs"); |
@@ -122,33 +127,78 @@ describe("config-loader", () => { |
122 | 127 | const result = extractCustomTheme("/project/src/file.ts"); |
123 | 128 | expect(result).toEqual({ colors: {}, fontFamily: {}, fontSize: {} }); |
124 | 129 | }); |
| 130 | + }); |
125 | 131 |
|
126 | | - it("should return empty theme when config has no theme", () => { |
127 | | - const configPath = "/project/tailwind.config.js"; |
| 132 | + describe("warnUnsupportedThemeKeys", () => { |
| 133 | + it("should warn about unsupported theme keys", () => { |
| 134 | + const configPath = "/project/unsupported/tailwind.config.js"; |
| 135 | + const mockConfig = { |
| 136 | + theme: { |
| 137 | + extend: { |
| 138 | + colors: { brand: "#123456" }, |
| 139 | + spacing: { "72": "18rem" }, // Unsupported |
| 140 | + borderRadius: { xl: "1rem" }, // Unsupported |
| 141 | + }, |
| 142 | + screens: { tablet: "640px" }, // Unsupported |
| 143 | + }, |
| 144 | + }; |
128 | 145 |
|
129 | | - vi.spyOn(fs, "existsSync").mockImplementation((filepath) => filepath === configPath); |
130 | | - vi.spyOn(require, "resolve").mockReturnValue(configPath); |
| 146 | + const consoleSpy = vi.spyOn(console, "warn").mockImplementation(vi.fn()); |
131 | 147 |
|
132 | | - // loadTailwindConfig will be called, but we've already tested it |
133 | | - // For integration, we'd need to mock the entire flow |
134 | | - const result = extractCustomTheme("/project/src/file.ts"); |
| 148 | + warnUnsupportedThemeKeys(mockConfig, configPath); |
135 | 149 |
|
136 | | - // Without actual config loading, this returns empty |
137 | | - expect(result).toEqual({ colors: {}, fontFamily: {}, fontSize: {} }); |
| 150 | + expect(consoleSpy).toHaveBeenCalledWith( |
| 151 | + expect.stringContaining("Unsupported theme configuration detected"), |
| 152 | + ); |
| 153 | + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("theme.extend.spacing")); |
| 154 | + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("theme.extend.borderRadius")); |
| 155 | + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("theme.screens")); |
| 156 | + expect(consoleSpy).toHaveBeenCalledWith( |
| 157 | + expect.stringContaining("https://github.com/mgcrea/react-native-tailwind/issues/new"), |
| 158 | + ); |
| 159 | + |
| 160 | + consoleSpy.mockRestore(); |
| 161 | + }); |
| 162 | + |
| 163 | + it("should not warn for supported theme keys only", () => { |
| 164 | + const configPath = "/project/supported/tailwind.config.js"; |
| 165 | + const mockConfig = { |
| 166 | + theme: { |
| 167 | + extend: { |
| 168 | + colors: { brand: "#123456" }, |
| 169 | + fontFamily: { custom: "CustomFont" }, |
| 170 | + fontSize: { huge: "48px" }, |
| 171 | + }, |
| 172 | + }, |
| 173 | + }; |
| 174 | + |
| 175 | + const consoleSpy = vi.spyOn(console, "warn").mockImplementation(vi.fn()); |
| 176 | + |
| 177 | + warnUnsupportedThemeKeys(mockConfig, configPath); |
| 178 | + |
| 179 | + expect(consoleSpy).not.toHaveBeenCalled(); |
| 180 | + |
| 181 | + consoleSpy.mockRestore(); |
138 | 182 | }); |
139 | 183 |
|
140 | | - it("should extract colors and fontFamily from theme.extend", () => { |
141 | | - // This would require complex mocking of the entire require flow |
142 | | - // Testing the logic: theme.extend is preferred |
143 | | - const colors = { brand: { light: "#fff", dark: "#000" } }; |
144 | | - const fontFamily = { sans: ['"SF Pro"'], custom: ['"Custom Font"'] }; |
145 | | - const theme = { |
146 | | - extend: { colors, fontFamily }, |
| 184 | + it("should only warn once per config path", () => { |
| 185 | + const configPath = "/project/once/tailwind.config.js"; |
| 186 | + const mockConfig = { |
| 187 | + theme: { |
| 188 | + extend: { |
| 189 | + spacing: { "72": "18rem" }, |
| 190 | + }, |
| 191 | + }, |
147 | 192 | }; |
148 | 193 |
|
149 | | - // If we had the config, we'd flatten the colors and convert fontFamily |
150 | | - expect(theme.extend.colors).toEqual(colors); |
151 | | - expect(theme.extend.fontFamily).toEqual(fontFamily); |
| 194 | + const consoleSpy = vi.spyOn(console, "warn").mockImplementation(vi.fn()); |
| 195 | + |
| 196 | + warnUnsupportedThemeKeys(mockConfig, configPath); |
| 197 | + warnUnsupportedThemeKeys(mockConfig, configPath); |
| 198 | + |
| 199 | + expect(consoleSpy).toHaveBeenCalledTimes(1); |
| 200 | + |
| 201 | + consoleSpy.mockRestore(); |
152 | 202 | }); |
153 | 203 | }); |
154 | 204 | }); |
0 commit comments