Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ coverage/






2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ import { TemplateRegistry } from 'create-react-forge/templates';
const registry = new TemplateRegistry();
const templates = registry.loadTemplatesForConfig({
runtime: 'vite',
styling: { solution: 'tailwind' },
styling: { solution: 'styled-components' },
stateManagement: 'zustand',
testing: { enabled: true, unit: { runner: 'vitest' }, e2e: { enabled: true, runner: 'playwright' } },
dataFetching: { enabled: true },
Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/integration/build-verification.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('Build Verification Tests', () => {
it('should generate and build a minimal Next.js project', async () => {
const config = createConfig('nextjs-build-minimal', {
runtime: 'nextjs',
styling: { solution: 'css' },
styling: { solution: 'none' },
});
projectPaths.push(config.path);

Expand Down Expand Up @@ -122,7 +122,7 @@ describe('Build Verification Tests', () => {
it('should generate and build Next.js with state management', async () => {
const config = createConfig('nextjs-build-zustand', {
runtime: 'nextjs',
styling: { solution: 'css' },
styling: { solution: 'none' },
stateManagement: 'zustand',
});
projectPaths.push(config.path);
Expand Down Expand Up @@ -156,7 +156,7 @@ describe('Build Verification Tests', () => {
it('should generate and build a minimal Vite project', async () => {
const config = createConfig('vite-build-minimal', {
runtime: 'vite',
styling: { solution: 'css' },
styling: { solution: 'styled-components' },
});
projectPaths.push(config.path);

Expand Down
6 changes: 3 additions & 3 deletions src/__tests__/integration/generator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,11 @@ describe('ProjectGenerator Integration', () => {
expect(devDeps).toHaveProperty('@playwright/test');
});

it.skip('should generate Next.js + CSS Modules + Redux', async () => {
it.skip('should generate Next.js + None styling + Redux', async () => {
const config = createBaseConfig({
name: 'nextjs-redux',
runtime: 'nextjs',
styling: { solution: 'css-modules' },
styling: { solution: 'none' },
stateManagement: 'redux',
testing: {
enabled: true,
Expand Down Expand Up @@ -231,7 +231,7 @@ describe('ProjectGenerator Integration', () => {
const config = createBaseConfig({
name: 'vite-jest-pw',
runtime: 'vite',
styling: { solution: 'css-modules' },
styling: { solution: 'styled-components' },
testing: {
enabled: true,
unit: { enabled: true, runner: 'jest' },
Expand Down
7 changes: 4 additions & 3 deletions src/__tests__/integration/package-json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,10 @@ describe('Package.json Generation', () => {
expect(devDeps).toHaveProperty('autoprefixer');
});

it.skip('should not include tailwind when css-modules selected', async () => {
const config = createConfig('css-modules-deps', {
styling: { solution: 'css-modules' },
it.skip('should not include tailwind when none styling selected', async () => {
const config = createConfig('none-styling-deps', {
runtime: 'nextjs',
styling: { solution: 'none' },
});
projectPaths.push(config.path);

Expand Down
8 changes: 4 additions & 4 deletions src/__tests__/integration/scenarios.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ describe('Real-World Scenarios', () => {
});

describe('Scenario: Minimal SPA (Learning/Prototyping)', () => {
it('should generate minimal Vite + CSS project', async () => {
it('should generate minimal Vite + styled-components project', async () => {
const config = createConfig('minimal-spa', {
runtime: 'vite',
styling: { solution: 'css' },
styling: { solution: 'styled-components' },
stateManagement: 'none',
dataFetching: { enabled: false, library: 'tanstack-query' },
testing: {
Expand Down Expand Up @@ -230,10 +230,10 @@ describe('Real-World Scenarios', () => {
});

describe.skip('Scenario: Next.js with Redux', () => {
it('should generate Next.js + CSS Modules + Redux', async () => {
it('should generate Next.js + None styling + Redux', async () => {
const config = createConfig('nextjs-redux', {
runtime: 'nextjs',
styling: { solution: 'css-modules' },
styling: { solution: 'none' },
stateManagement: 'redux',
dataFetching: { enabled: false, library: 'tanstack-query' },
testing: {
Expand Down
131 changes: 52 additions & 79 deletions src/__tests__/integration/styling-verification.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { execa } from 'execa';
import { existsSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { afterEach, describe, expect, it } from 'vitest';
import { execa } from 'execa';
import { ProjectConfig } from '../../config/schema.js';
import { ProjectGenerator } from '../../generator/index.js';

Expand All @@ -28,7 +28,7 @@ function createConfig(name: string, overrides: Partial<ProjectConfig>): ProjectC
path: basePath,
runtime: 'vite',
language: 'typescript',
styling: { solution: 'tailwind' },
styling: { solution: 'styled-components' },
stateManagement: 'none',
dataFetching: { enabled: false, library: 'tanstack-query' },
testing: {
Expand All @@ -53,11 +53,11 @@ describe('Styling Solutions Verification', () => {
projectPaths.length = 0;
});

describe('Plain CSS', () => {
it('should generate and build with plain CSS', async () => {
const config = createConfig('css-plain', {
describe('Styled Components (Vite)', () => {
it('should generate project with Styled Components file structure', async () => {
const config = createConfig('styled-vite-structure', {
runtime: 'vite',
styling: { solution: 'css' },
styling: { solution: 'styled-components' },
});
projectPaths.push(config.path);

Expand All @@ -66,50 +66,37 @@ describe('Styling Solutions Verification', () => {

expect(result.success).toBe(true);

// Install dependencies
console.log('Installing dependencies for plain CSS project...');
const installResult = await execa('npm', ['install'], {
cwd: config.path,
timeout: 120000,
});
expect(installResult.exitCode).toBe(0);

// Build the project
console.log('Building plain CSS project...');
const buildResult = await execa('npm', ['run', 'build'], {
cwd: config.path,
timeout: 120000,
});
expect(buildResult.exitCode).toBe(0);

expect(existsSync(join(config.path, 'dist'))).toBe(true);
}, 300000);
});
// Verify Styled Components files exist
expect(existsSync(join(config.path, 'src/styles/globals.ts'))).toBe(true);
expect(existsSync(join(config.path, 'src/components/ui/Button.styled.ts'))).toBe(true);
expect(existsSync(join(config.path, 'src/app/provider.tsx'))).toBe(true);
expect(existsSync(join(config.path, 'src/main.tsx'))).toBe(true);
}, 60000);

describe.skip('CSS Modules', () => {
it('should generate and build with CSS Modules', async () => {
const config = createConfig('css-modules', {
it('should generate and build with Styled Components', async () => {
const config = createConfig('styled-vite', {
runtime: 'vite',
styling: { solution: 'css-modules' },
styling: { solution: 'styled-components' },
});
projectPaths.push(config.path);

const generator = new ProjectGenerator(config);
const result = await generator.generate();

expect(result.success).toBe(true);
expect(existsSync(join(config.path, 'src/components/ui/Button.module.css'))).toBe(true);
expect(existsSync(join(config.path, 'src/styles/globals.ts'))).toBe(true);
expect(existsSync(join(config.path, 'src/components/ui/Button.styled.ts'))).toBe(true);

// Install dependencies
console.log('Installing dependencies for CSS Modules project...');
console.log('Installing dependencies for Styled Components project...');
const installResult = await execa('npm', ['install'], {
cwd: config.path,
timeout: 120000,
});
expect(installResult.exitCode).toBe(0);

// Build the project
console.log('Building CSS Modules project...');
console.log('Building Styled Components project...');
const buildResult = await execa('npm', ['run', 'build'], {
cwd: config.path,
timeout: 120000,
Expand All @@ -120,106 +107,92 @@ describe('Styling Solutions Verification', () => {
}, 300000);
});

describe.skip('Styled Components', () => {
it('should generate and build with Styled Components (Vite)', async () => {
const config = createConfig('styled-vite', {
runtime: 'vite',
styling: { solution: 'styled-components' },
describe('Tailwind CSS (Next.js)', () => {
it('should generate and build with Tailwind', async () => {
const config = createConfig('tailwind-nextjs', {
runtime: 'nextjs',
styling: { solution: 'tailwind' },
});
projectPaths.push(config.path);

const generator = new ProjectGenerator(config);
const result = await generator.generate();

expect(result.success).toBe(true);
expect(existsSync(join(config.path, 'src/styles/globals.ts'))).toBe(true);
expect(existsSync(join(config.path, 'src/components/ui/Button.styled.ts'))).toBe(true);
expect(existsSync(join(config.path, 'tailwind.config.js'))).toBe(true);
expect(existsSync(join(config.path, 'postcss.config.js'))).toBe(true);

// Install dependencies
console.log('Installing dependencies for Styled Components project...');
console.log('Installing dependencies for Tailwind project...');
const installResult = await execa('npm', ['install'], {
cwd: config.path,
timeout: 120000,
});
expect(installResult.exitCode).toBe(0);

// Build the project
console.log('Building Styled Components project...');
console.log('Building Tailwind project...');
const buildResult = await execa('npm', ['run', 'build'], {
cwd: config.path,
timeout: 120000,
timeout: 180000,
});
expect(buildResult.exitCode).toBe(0);

expect(existsSync(join(config.path, 'dist'))).toBe(true);
}, 300000);
expect(existsSync(join(config.path, '.next'))).toBe(true);
}, 360000);
});

it('should generate and build with Styled Components (Next.js)', async () => {
const config = createConfig('styled-nextjs', {
describe('None Styling (Next.js)', () => {
it('should generate project with no styling framework', async () => {
const config = createConfig('none-nextjs-structure', {
runtime: 'nextjs',
styling: { solution: 'styled-components' },
styling: { solution: 'none' },
});
projectPaths.push(config.path);

const generator = new ProjectGenerator(config);
const result = await generator.generate();

expect(result.success).toBe(true);
expect(existsSync(join(config.path, 'src/styles/globals.ts'))).toBe(true);

// Install dependencies
console.log('Installing dependencies for Next.js + Styled Components...');
const installResult = await execa('npm', ['install'], {
cwd: config.path,
timeout: 120000,
});
expect(installResult.exitCode).toBe(0);
// Verify no Tailwind config files
expect(existsSync(join(config.path, 'tailwind.config.js'))).toBe(false);
expect(existsSync(join(config.path, 'postcss.config.js'))).toBe(false);

// Build the project
console.log('Building Next.js + Styled Components...');
const buildResult = await execa('npm', ['run', 'build'], {
cwd: config.path,
timeout: 180000,
});
expect(buildResult.exitCode).toBe(0);

expect(existsSync(join(config.path, '.next'))).toBe(true);
}, 360000);
});
// Verify base files exist
expect(existsSync(join(config.path, 'src/app/page.tsx'))).toBe(true);
expect(existsSync(join(config.path, 'src/styles/globals.css'))).toBe(true);
}, 60000);

describe('Tailwind CSS', () => {
it('should generate and build with Tailwind', async () => {
const config = createConfig('tailwind', {
runtime: 'vite',
styling: { solution: 'tailwind' },
it('should generate and build with no styling framework', async () => {
const config = createConfig('none-nextjs', {
runtime: 'nextjs',
styling: { solution: 'none' },
});
projectPaths.push(config.path);

const generator = new ProjectGenerator(config);
const result = await generator.generate();

expect(result.success).toBe(true);
expect(existsSync(join(config.path, 'tailwind.config.js'))).toBe(true);
expect(existsSync(join(config.path, 'postcss.config.js'))).toBe(true);

// Install dependencies
console.log('Installing dependencies for Tailwind project...');
console.log('Installing dependencies for None styling project...');
const installResult = await execa('npm', ['install'], {
cwd: config.path,
timeout: 120000,
});
expect(installResult.exitCode).toBe(0);

// Build the project
console.log('Building Tailwind project...');
console.log('Building None styling project...');
const buildResult = await execa('npm', ['run', 'build'], {
cwd: config.path,
timeout: 120000,
timeout: 180000,
});
expect(buildResult.exitCode).toBe(0);

expect(existsSync(join(config.path, 'dist'))).toBe(true);
}, 300000);
expect(existsSync(join(config.path, '.next'))).toBe(true);
}, 360000);
});
});

Loading
Loading