mage-obsidian 1.0.12 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/jest.config.js +1 -1
  2. package/package.json +3 -2
  3. package/src/__tests__/fixtures/interceptors/emptyTarget.js +2 -0
  4. package/src/__tests__/fixtures/interceptors/pluginForNonFunction.js +7 -0
  5. package/src/__tests__/fixtures/interceptors/pluginModule.js +13 -0
  6. package/src/__tests__/fixtures/interceptors/targetModule.js +12 -0
  7. package/src/__tests__/fixtures/interceptors/targetNonFunction.js +7 -0
  8. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/module.config.js +0 -6
  9. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/module.config.js +0 -5
  10. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/module.config.js +0 -6
  11. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/theme.config.js +0 -12
  12. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-b/web/theme.config.js +0 -17
  13. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/module.config.js +0 -7
  14. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/web/theme.config.js +0 -14
  15. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-d/web/theme.config.js +0 -11
  16. package/src/__tests__/service/generateInterceptors.test.js +196 -0
  17. package/src/__tests__/service/interceptorManager_magento_behavior.test.js +137 -0
  18. package/src/__tests__/service/themeResolverSync.test.js +4 -75
  19. package/src/__tests__/vite-plugins/interceptorsPlugin.test.js +121 -0
  20. package/src/config/default.js +1 -0
  21. package/src/service/configResolver.js +25 -3
  22. package/src/service/generateInterceptors.js +268 -0
  23. package/src/service/interceptorManager.js +137 -0
  24. package/src/service/interceptorsPlugin.js +70 -0
  25. package/src/service/moduleResolver.js +6 -18
  26. package/src/service/themeResolverSync.js +2 -20
  27. package/src/__tests__/service/moduleResolverSync.test.js +0 -188
  28. package/src/service/tailwindResolver.js +0 -11
package/jest.config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export default {
2
2
  testEnvironment: 'node',
3
3
  transform: {},
4
- testPathIgnorePatterns: ['/__tests__/magento_scenarios/','/node_modules/', '/__tests__/__mocks__/'],
4
+ testPathIgnorePatterns: ['/__tests__/magento_scenarios/','/node_modules/', '/__tests__/__mocks__/', '/__tests__/fixtures/'],
5
5
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mage-obsidian",
3
- "version": "1.0.12",
3
+ "version": "1.1.1",
4
4
  "description": "Mage Obsidian Ultis",
5
5
  "main": "./src/scripts/buildThemes.js",
6
6
  "keywords": [
@@ -22,7 +22,8 @@
22
22
  ".": "./src/scripts/buildThemes.js",
23
23
  "./service/": "./src/service/",
24
24
  "./utils/": "./src/utils/",
25
- "./config/": "./src/config/"
25
+ "./config/": "./src/config/",
26
+ "./service/*": "./src/service/*"
26
27
  },
27
28
  "dependencies": {
28
29
  "chalk": "^5.4.1",
@@ -0,0 +1,2 @@
1
+
2
+ export const someOtherFunction = () => {};
@@ -0,0 +1,7 @@
1
+
2
+ export function beforeConfig() {
3
+ console.log('Should not run');
4
+ }
5
+ export function beforeDefault() {
6
+ console.log('Should not run');
7
+ }
@@ -0,0 +1,13 @@
1
+
2
+ export function beforeTargetFunction(arg) {
3
+ return [`Modified: ${arg}`];
4
+ }
5
+
6
+ export function afterAnotherFunction(result) {
7
+ return `${result} - Modified`;
8
+ }
9
+
10
+ export function beforeDefault() {
11
+ return ['Default Modified'];
12
+ }
13
+
@@ -0,0 +1,12 @@
1
+
2
+ export function targetFunction(arg) {
3
+ return `Original: ${arg}`;
4
+ }
5
+
6
+ export function anotherFunction() {
7
+ return 'Another';
8
+ }
9
+
10
+ export default function defaultExport() {
11
+ return 'Default';
12
+ }
@@ -0,0 +1,7 @@
1
+
2
+ export const config = {
3
+ some: 'value'
4
+ };
5
+ export default {
6
+ main: 'config'
7
+ };
@@ -1,8 +1,2 @@
1
1
  export default {
2
- tailwind: {
3
- content: [
4
- '../templates/**/*.phtml',
5
- '/from_theme'
6
- ]
7
- }
8
2
  };
@@ -1,7 +1,2 @@
1
1
  export default {
2
- tailwind: {
3
- content: [
4
- '../templates/**/*.phtml'
5
- ]
6
- }
7
2
  };
@@ -1,8 +1,2 @@
1
1
  export default {
2
- tailwind: {
3
- content: [
4
- '../templates/**/*.phtml',
5
- 'pollo'
6
- ]
7
- }
8
2
  };
@@ -1,16 +1,4 @@
1
1
  export default {
2
- tailwind: {
3
- theme: {
4
- extend: {},
5
- },
6
- plugins: [],
7
- content: [
8
- './**/*.{vue,js}',
9
- '../**/*.phtml',
10
- '../*/page_layout/override/base/*.xml',
11
- ],
12
- },
13
- ignoredTailwindConfigFromModules: [],
14
2
  ignoredCssFromModules: [
15
3
  'Vendor_ModuleNameA',
16
4
  ],
@@ -1,21 +1,4 @@
1
1
  export default {
2
- tailwind: {
3
- theme: {
4
- extend: {
5
- textColor: {
6
- 'primary': '#3490dc',
7
- 'secondary': '#ffed4a',
8
- 'danger': '#e3342f',
9
- },
10
- },
11
- },
12
- plugins: [],
13
- content: [
14
- './**/*.{vue,js}',
15
- '../**/*.phtml',
16
- '../*/page_layout/override/base/*.xml',
17
- ],
18
- },
19
2
  ignoredCssFromModules: [
20
3
  'Vendor_ModuleNameNoConfig'
21
4
  ]
@@ -1,9 +1,2 @@
1
1
  export default {
2
- tailwind: {
3
- plugins: ['test_from_theme'],
4
- content: [
5
- '../templates/**/*.phtml',
6
- '/from_theme'
7
- ]
8
- }
9
2
  };
@@ -1,16 +1,2 @@
1
1
  export default {
2
- tailwind: {
3
- theme: {
4
- extend: {
5
- },
6
- },
7
- plugins: [],
8
- content: [
9
- './**/*.{vue,js}',
10
- '../**/*.phtml',
11
- '../*/page_layout/override/base/*.xml',
12
- ],
13
- },
14
- includeTailwindConfigFromParentThemes: false,
15
- ignoredTailwindConfigFromModules: 'all'
16
2
  }
@@ -1,14 +1,3 @@
1
1
  export default {
2
- tailwind: {
3
- theme: {
4
- extend: {
5
- },
6
- },
7
- plugins: [],
8
- content: [],
9
- },
10
- ignoredTailwindConfigFromModules: [
11
- 'Vendor_ModuleNameC'
12
- ],
13
2
  includeCssSourceFromParentThemes: false,
14
3
  }
@@ -0,0 +1,196 @@
1
+
2
+ import { jest } from '@jest/globals';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const fixturesDir = path.resolve(__dirname, '../fixtures/interceptors');
8
+ const targetModulePath = path.join(fixturesDir, 'targetModule.js');
9
+ const pluginModulePath = path.join(fixturesDir, 'pluginModule.js');
10
+ const targetNonFunctionPath = path.join(fixturesDir, 'targetNonFunction.js');
11
+ const pluginForNonFunctionPath = path.join(fixturesDir, 'pluginForNonFunction.js');
12
+
13
+ describe('generateInterceptors', () => {
14
+ let generateInterceptorsService;
15
+ let themeResolverMock;
16
+ let moduleResolverMock;
17
+ let interceptorManager;
18
+
19
+ beforeEach(async () => {
20
+ jest.resetModules();
21
+
22
+ themeResolverMock = {
23
+ getThemeConfig: jest.fn(),
24
+ };
25
+
26
+ moduleResolverMock = {
27
+ getModuleConfigByThemeConfig: jest.fn(),
28
+ getAllJsVueFilesWithInheritanceCached: jest.fn(),
29
+ getAllJsVueFilesWithInheritance: jest.fn(),
30
+ };
31
+
32
+ jest.unstable_mockModule('../../service/themeResolverSync.js', () => ({
33
+ default: themeResolverMock
34
+ }));
35
+
36
+ jest.unstable_mockModule('../../service/moduleResolver.js', () => ({
37
+ default: moduleResolverMock
38
+ }));
39
+
40
+ jest.unstable_mockModule('../../service/configResolver.js', () => ({
41
+ default: {
42
+ resolveLibRealPath: jest.fn().mockReturnValue('/mocked/path/to/interceptorManager')
43
+ }
44
+ }));
45
+
46
+ // Import real interceptorManager to reset state
47
+ interceptorManager = (await import('../../service/interceptorManager.js')).default;
48
+ interceptorManager.interceptors = {};
49
+
50
+ generateInterceptorsService = (await import('../../service/generateInterceptors.js')).default;
51
+ });
52
+
53
+ test('should generate interceptors correctly', async () => {
54
+ const themeName = 'Vendor/theme-test';
55
+
56
+ themeResolverMock.getThemeConfig.mockReturnValue({
57
+ src: '/path/to/theme'
58
+ });
59
+
60
+ moduleResolverMock.getModuleConfigByThemeConfig.mockResolvedValue({
61
+ interceptors: {
62
+ 'TestPlugin': {
63
+ name: 'TestPlugin',
64
+ target: 'Vendor_TargetModule::js/target.js',
65
+ interceptor: 'Vendor_PluginModule::js/plugin.js',
66
+ sortOrder: 10,
67
+ active: true
68
+ }
69
+ }
70
+ });
71
+
72
+ const allFilesMap = {
73
+ 'Vendor_TargetModule/js/target': targetModulePath,
74
+ 'Vendor_PluginModule/js/plugin': pluginModulePath
75
+ };
76
+
77
+ moduleResolverMock.getAllJsVueFilesWithInheritanceCached.mockReturnValue(allFilesMap);
78
+
79
+ const result = await generateInterceptorsService.generateInterceptors(themeName);
80
+
81
+ const targetIdentifier = 'Vendor_TargetModule::js/target.js';
82
+ // Use bracket access check to avoid Jest treating '.' as nested property
83
+ expect(result[targetIdentifier]).toBeDefined();
84
+
85
+ const interceptorData = result[targetIdentifier];
86
+ expect(interceptorData).toHaveProperty('proxy');
87
+ expect(interceptorData).toHaveProperty('source');
88
+ expect(interceptorData).toHaveProperty('targetPath', targetModulePath);
89
+ expect(interceptorData.interceptors).toHaveLength(1);
90
+ expect(interceptorData.interceptors[0].name).toBe('TestPlugin');
91
+
92
+ // Verify Source Code Generation
93
+ const source = interceptorData.source;
94
+ expect(source).toContain(`import * as originalModule from '/@fs${targetModulePath}?originalIntercepted';`);
95
+ expect(source).toContain(`import * as interceptor_0 from '/@fs${pluginModulePath}';`);
96
+ expect(source).toContain(`interceptorManager.addInterceptor('${targetIdentifier}::targetFunction', 'TestPlugin', 'before', interceptor_0.beforeTargetFunction, 10);`);
97
+ expect(source).toContain(`interceptorManager.addInterceptor('${targetIdentifier}::default', 'TestPlugin', 'before', interceptor_0.beforeDefault, 10);`);
98
+ expect(source).toContain(`export const targetFunction = proxy.targetFunction;`);
99
+
100
+ // Verify Proxy Behavior
101
+ const proxy = interceptorData.proxy;
102
+ const resultFunc = await proxy.targetFunction('test');
103
+ expect(resultFunc).toBe('Original: Modified: test');
104
+
105
+ const resultAnother = await proxy.anotherFunction();
106
+ expect(resultAnother).toBe('Another - Modified');
107
+
108
+ const resultDefault = await proxy.default();
109
+ expect(resultDefault).toBe('Default'); // The mock plugin returns ['Default Modified'] but the original function ignores args and returns 'Default'.
110
+ // Wait, before interceptor modifies arguments.
111
+ // targetModule.js: export default function defaultExport() { return 'Default'; }
112
+ // It doesn't take arguments, so modifying arguments won't change output unless we check arguments.
113
+ // But we just want to verify it was registered.
114
+
115
+ });
116
+
117
+ test('should handle missing target module gracefully', async () => {
118
+ themeResolverMock.getThemeConfig.mockReturnValue({});
119
+ moduleResolverMock.getModuleConfigByThemeConfig.mockResolvedValue({
120
+ 'Vendor_TargetModule': { interceptors: [] }
121
+ });
122
+ moduleResolverMock.getAllJsVueFilesWithInheritanceCached.mockReturnValue({});
123
+
124
+ const result = await generateInterceptorsService.generateInterceptors('Vendor/theme-missing');
125
+ expect(result).toEqual({});
126
+ });
127
+
128
+ test('should throw error if plugin targets non-existent method', async () => {
129
+ const themeName = 'Vendor/theme-test';
130
+ themeResolverMock.getThemeConfig.mockReturnValue({});
131
+ moduleResolverMock.getModuleConfigByThemeConfig.mockResolvedValue({
132
+ interceptors: {
133
+ 'BadPlugin': {
134
+ name: 'BadPlugin',
135
+ target: 'Vendor_TargetModule::js/target.js',
136
+ interceptor: 'Vendor_PluginModule::js/plugin.js',
137
+ sortOrder: 10
138
+ }
139
+ }
140
+ });
141
+
142
+ const emptyTargetModulePath = path.join(fixturesDir, 'emptyTarget.js');
143
+
144
+ const allFilesMap = {
145
+ 'Vendor_TargetModule/js/target': emptyTargetModulePath,
146
+ 'Vendor_PluginModule/js/plugin': pluginModulePath
147
+ };
148
+
149
+ moduleResolverMock.getAllJsVueFilesWithInheritanceCached.mockReturnValue(allFilesMap);
150
+
151
+ // We expect the promise to reject because generateInterceptors throws on invalid target method
152
+ await expect(generateInterceptorsService.generateInterceptors(themeName))
153
+ .rejects
154
+ .toThrow(/does not export/);
155
+ });
156
+
157
+ test('should skip interception for non-function exports', async () => {
158
+ const themeName = 'Vendor/theme-test';
159
+
160
+ themeResolverMock.getThemeConfig.mockReturnValue({
161
+ src: '/path/to/theme'
162
+ });
163
+
164
+ moduleResolverMock.getModuleConfigByThemeConfig.mockResolvedValue({
165
+ interceptors: {
166
+ 'TestPlugin': {
167
+ name: 'TestPlugin',
168
+ target: 'Vendor_TargetModule::js/targetNonFunction.js',
169
+ interceptor: 'Vendor_PluginModule::js/pluginForNonFunction.js',
170
+ sortOrder: 10,
171
+ active: true
172
+ }
173
+ }
174
+ });
175
+
176
+ const allFilesMap = {
177
+ 'Vendor_TargetModule/js/targetNonFunction': targetNonFunctionPath,
178
+ 'Vendor_PluginModule/js/pluginForNonFunction': pluginForNonFunctionPath
179
+ };
180
+
181
+ moduleResolverMock.getAllJsVueFilesWithInheritanceCached.mockReturnValue(allFilesMap);
182
+
183
+ const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
184
+
185
+ const result = await generateInterceptorsService.generateInterceptors(themeName);
186
+
187
+ const targetIdentifier = 'Vendor_TargetModule::js/targetNonFunction.js';
188
+
189
+ // Since both 'config' and 'default' are objects, and we are trying to intercept them,
190
+ // they should be skipped. If all are skipped, the targetIdentifier should not be in result.
191
+ expect(result[targetIdentifier]).toBeUndefined();
192
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('is not a function'));
193
+
194
+ consoleSpy.mockRestore();
195
+ });
196
+ });
@@ -0,0 +1,137 @@
1
+
2
+ import { jest } from '@jest/globals';
3
+ import interceptorManager from '../../service/interceptorManager.js';
4
+
5
+ describe('InterceptorManager Magento Behavior', () => {
6
+ beforeEach(() => {
7
+ // Reset interceptors before each test
8
+ interceptorManager.interceptors = {};
9
+ });
10
+
11
+ test('Before interceptors: should chain arguments and handle null returns', async () => {
12
+ const targetName = 'Test::beforeChain';
13
+ const originalFn = jest.fn((arg1, arg2) => `Original: ${arg1}, ${arg2}`);
14
+ const context = {};
15
+
16
+ // Interceptor 1: Modifies arguments
17
+ const beforeInterceptor1 = jest.fn((arg1, arg2) => {
18
+ return [arg1 + '_mod1', arg2 + '_mod1'];
19
+ });
20
+
21
+ // Interceptor 2: Returns null (should keep arguments from Interceptor 1)
22
+ const beforeInterceptor2 = jest.fn((arg1, arg2) => {
23
+ return null;
24
+ });
25
+
26
+ // Interceptor 3: Modifies arguments again
27
+ const beforeInterceptor3 = jest.fn((arg1, arg2) => {
28
+ return [arg1 + '_mod3', arg2 + '_mod3'];
29
+ });
30
+
31
+ interceptorManager.addInterceptor(targetName, 'Interceptor1', 'before', beforeInterceptor1, 10);
32
+ interceptorManager.addInterceptor(targetName, 'Interceptor2', 'before', beforeInterceptor2, 20);
33
+ interceptorManager.addInterceptor(targetName, 'Interceptor3', 'before', beforeInterceptor3, 30);
34
+
35
+ const result = await interceptorManager.execute(targetName, originalFn, context, 'A', 'B');
36
+
37
+ // Verify Interceptor 1 received original args
38
+ expect(beforeInterceptor1).toHaveBeenCalledWith('A', 'B');
39
+
40
+ // Verify Interceptor 2 received args modified by Interceptor 1
41
+ expect(beforeInterceptor2).toHaveBeenCalledWith('A_mod1', 'B_mod1');
42
+
43
+ // Verify Interceptor 3 received args from Interceptor 1 (since Interceptor 2 returned null)
44
+ expect(beforeInterceptor3).toHaveBeenCalledWith('A_mod1', 'B_mod1');
45
+
46
+ // Verify Original received args modified by Interceptor 3
47
+ expect(originalFn).toHaveBeenCalledWith('A_mod1_mod3', 'B_mod1_mod3');
48
+
49
+ expect(result).toBe('Original: A_mod1_mod3, B_mod1_mod3');
50
+ });
51
+
52
+ test('Around interceptors: should wrap execution and modify args/result', async () => {
53
+ const targetName = 'Test::aroundChain';
54
+ const originalFn = jest.fn((arg) => `Original(${arg})`);
55
+ const context = {};
56
+
57
+ // Outer Around Interceptor
58
+ const aroundInterceptor1 = jest.fn(async (proceed, arg) => {
59
+ const result = await proceed(arg + '_outerIn');
60
+ return `Outer(${result})`;
61
+ });
62
+
63
+ // Inner Around Interceptor
64
+ const aroundInterceptor2 = jest.fn(async (proceed, arg) => {
65
+ const result = await proceed(arg + '_innerIn');
66
+ return `Inner(${result})`;
67
+ });
68
+
69
+ interceptorManager.addInterceptor(targetName, 'Interceptor1', 'around', aroundInterceptor1, 10);
70
+ interceptorManager.addInterceptor(targetName, 'Interceptor2', 'around', aroundInterceptor2, 20);
71
+
72
+ const result = await interceptorManager.execute(targetName, originalFn, context, 'Start');
73
+
74
+ // Execution flow:
75
+ // Interceptor1 (Start) -> calls proceed('Start_outerIn')
76
+ // -> Interceptor2 ('Start_outerIn') -> calls proceed('Start_outerIn_innerIn')
77
+ // -> Original ('Start_outerIn_innerIn') -> returns 'Original(Start_outerIn_innerIn)'
78
+ // -> Interceptor2 returns 'Inner(Original(Start_outerIn_innerIn))'
79
+ // -> Interceptor1 returns 'Outer(Inner(Original(Start_outerIn_innerIn)))'
80
+
81
+ expect(originalFn).toHaveBeenCalledWith('Start_outerIn_innerIn');
82
+ expect(result).toBe('Outer(Inner(Original(Start_outerIn_innerIn)))');
83
+ });
84
+
85
+ test('After interceptors: should chain results', async () => {
86
+ const targetName = 'Test::afterChain';
87
+ const originalFn = jest.fn(() => 'Original');
88
+ const context = {};
89
+
90
+ const afterInterceptor1 = jest.fn((result) => {
91
+ return result + '_After1';
92
+ });
93
+
94
+ const afterInterceptor2 = jest.fn((result) => {
95
+ return result + '_After2';
96
+ });
97
+
98
+ interceptorManager.addInterceptor(targetName, 'Interceptor1', 'after', afterInterceptor1, 10);
99
+ interceptorManager.addInterceptor(targetName, 'Interceptor2', 'after', afterInterceptor2, 20);
100
+
101
+ const result = await interceptorManager.execute(targetName, originalFn, context);
102
+
103
+ expect(afterInterceptor1).toHaveBeenCalledWith('Original');
104
+ expect(afterInterceptor2).toHaveBeenCalledWith('Original_After1');
105
+ expect(result).toBe('Original_After1_After2');
106
+ });
107
+
108
+ test('Full Chain: Before -> Around -> Original -> After', async () => {
109
+ const targetName = 'Test::fullChain';
110
+ const originalFn = jest.fn((arg) => `Original(${arg})`);
111
+ const context = {};
112
+
113
+ // Before: Modifies arg
114
+ interceptorManager.addInterceptor(targetName, 'Before', 'before', (arg) => [arg + '_Before'], 10);
115
+
116
+ // Around: Wraps and modifies arg further
117
+ interceptorManager.addInterceptor(targetName, 'Around', 'around', async (proceed, arg) => {
118
+ const res = await proceed(arg + '_AroundIn');
119
+ return `Around(${res})`;
120
+ }, 20);
121
+
122
+ // After: Modifies result
123
+ interceptorManager.addInterceptor(targetName, 'After', 'after', (res) => res + '_After', 30);
124
+
125
+ const result = await interceptorManager.execute(targetName, originalFn, context, 'Start');
126
+
127
+ // Flow:
128
+ // Before: Start -> Start_Before
129
+ // Around: Start_Before -> calls proceed(Start_Before_AroundIn)
130
+ // Original: Start_Before_AroundIn -> returns Original(Start_Before_AroundIn)
131
+ // Around: returns Around(Original(Start_Before_AroundIn))
132
+ // After: receives Around(...) -> returns Around(...)_After
133
+
134
+ expect(originalFn).toHaveBeenCalledWith('Start_Before_AroundIn');
135
+ expect(result).toBe('Around(Original(Start_Before_AroundIn))_After');
136
+ });
137
+ });
@@ -12,90 +12,40 @@ let scenarios = [
12
12
  {
13
13
  code: 'Vendor/theme-a',
14
14
  expected: {
15
- tailwind: {
16
- theme: { extend: {} },
17
- plugins: [],
18
- content: [
19
- 'magento_scenarios/app/design/frontend/Vendor/theme-a/web/**/*.{vue,js}',
20
- 'magento_scenarios/app/design/frontend/Vendor/theme-a/**/*.phtml',
21
- 'magento_scenarios/app/design/frontend/Vendor/theme-a/*/page_layout/override/base/*.xml'
22
- ]
23
- },
24
- includeTailwindConfigFromParentThemes: true,
25
15
  includeCssSourceFromParentThemes: true,
26
16
  ignoredCssFromModules: [
27
17
  'Vendor_ModuleNameA'
28
18
  ],
29
- ignoredTailwindConfigFromModules: [],
30
19
  exposeNpmPackages: []
31
20
  }
32
21
  },
33
22
  {
34
23
  code: 'Vendor/theme-b',
35
24
  expected: {
36
- tailwind: {
37
- theme: {
38
- extend: {
39
- textColor: {
40
- 'primary': '#3490dc',
41
- 'secondary': '#ffed4a',
42
- 'danger': '#e3342f',
43
- },
44
- }
45
- },
46
- plugins: [],
47
- content: [
48
- 'magento_scenarios/app/design/frontend/Vendor/theme-a/web/**/*.{vue,js}',
49
- 'magento_scenarios/app/design/frontend/Vendor/theme-a/**/*.phtml',
50
- 'magento_scenarios/app/design/frontend/Vendor/theme-a/*/page_layout/override/base/*.xml',
51
- 'magento_scenarios/app/design/frontend/Vendor/theme-b/web/**/*.{vue,js}',
52
- 'magento_scenarios/app/design/frontend/Vendor/theme-b/**/*.phtml',
53
- 'magento_scenarios/app/design/frontend/Vendor/theme-b/*/page_layout/override/base/*.xml'
54
- ]
55
- },
56
- includeTailwindConfigFromParentThemes: true,
57
25
  includeCssSourceFromParentThemes: true,
58
26
  ignoredCssFromModules: [
59
27
  'Vendor_ModuleNameA',
60
28
  'Vendor_ModuleNameNoConfig'
61
29
  ],
62
- ignoredTailwindConfigFromModules: [],
63
30
  exposeNpmPackages: []
64
31
  }
65
32
  },
66
33
  {
67
34
  code: 'Vendor/theme-c',
68
35
  expected: {
69
- tailwind: {
70
- theme: { extend: {} },
71
- plugins: [],
72
- content: [
73
- 'magento_scenarios/app/design/frontend/Vendor/theme-c/web/**/*.{vue,js}',
74
- 'magento_scenarios/app/design/frontend/Vendor/theme-c/**/*.phtml',
75
- 'magento_scenarios/app/design/frontend/Vendor/theme-c/*/page_layout/override/base/*.xml'
76
- ]
77
- },
78
- includeTailwindConfigFromParentThemes: false,
79
36
  includeCssSourceFromParentThemes: true,
80
- ignoredCssFromModules: [],
81
- ignoredTailwindConfigFromModules: 'all',
37
+ ignoredCssFromModules: [
38
+ 'Vendor_ModuleNameA',
39
+ 'Vendor_ModuleNameNoConfig'
40
+ ],
82
41
  exposeNpmPackages: []
83
42
  }
84
43
  },
85
44
  {
86
45
  code: 'Vendor/theme-d',
87
46
  expected: {
88
- tailwind: {
89
- theme: { extend: {} },
90
- plugins: [],
91
- content: []
92
- },
93
- includeTailwindConfigFromParentThemes: true,
94
47
  includeCssSourceFromParentThemes: false,
95
48
  ignoredCssFromModules: [],
96
- ignoredTailwindConfigFromModules: [
97
- 'Vendor_ModuleNameC'
98
- ],
99
49
  exposeNpmPackages: []
100
50
  }
101
51
  }
@@ -107,7 +57,6 @@ for (const scenario of scenarios) {
107
57
  for (const themeKey in scenario.themes) {
108
58
  let theme = scenario.themes[themeKey];
109
59
  const expected = theme.expected;
110
- expected.tailwind.content = expected.tailwind.content?.map((content) => path.resolve(__dirname, '..', content));
111
60
  }
112
61
  }
113
62
 
@@ -145,24 +94,4 @@ describe('getThemeConfig', () => {
145
94
  });
146
95
  });
147
96
 
148
- describe('getTailwindThemeConfig', () => {
149
- let themeResolver;
150
-
151
- beforeEach(() => {
152
- jest.resetModules();
153
- });
154
-
155
- test.each(scenarios.flatMap(({ scenario, themes }) =>
156
- themes.map(({ code, expected }) => ([ scenario, code, expected ]))
157
- ))('Scenario "%s", Theme "%s"', async ( scenario, code, expected ) => {
158
- themeResolver = await setupThemeResolver(scenario);
159
-
160
- const result = await themeResolver.getTailwindThemeConfig(code);
161
-
162
- expect(result).toMatchObject(
163
- expected.tailwind,
164
- `Expected:\n${JSON.stringify(expected.tailwind, null, 2)}\nReceived:\n${JSON.stringify(result, null, 2)}\nScenario: "${scenario}", Theme: "${code}"`
165
- );
166
- });
167
- });
168
97