diff --git a/Makefile b/Makefile index b889d85..4a1602d 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,10 @@ help: @echo " test-integration - Run all integration tests" @echo " test-integration-csharp - Run C# integration tests" @echo " test-integration-go - Run Go integration tests" + @echo " test-integration-java - Run Java integration tests" + @echo " test-integration-nestjs - Run NestJS integration tests" @echo " test-integration-nodejs - Run NodeJS integration tests" + @echo " test-integration-react - Run React integration tests" @echo " generate - Generate all code (API clients, docs, schema)" @echo " generate-api - Generate API clients from OpenAPI specs" @echo " generate-docs - Generate documentation" @@ -67,6 +70,21 @@ test-integration-angular: @echo "Running Angular integration test with Dagger..." @go run ./test/integration/cmd/angular/run.go +.PHONY: test-integration-java +test-integration-java: + @echo "Running Java integration test with Dagger..." + @go run ./test/integration/cmd/java/run.go + +.PHONY: test-integration-nestjs +test-integration-nestjs: + @echo "Running NestJS integration test with Dagger..." + @go run ./test/integration/cmd/nestjs/run.go + +.PHONY: test-integration-react +test-integration-react: + @echo "Running React integration test with Dagger..." + @go run ./test/integration/cmd/react/run.go + .PHONY: test-integration test-integration: @echo "Running all integration tests with Dagger..." diff --git a/test/integration/cmd/java/run.go b/test/integration/cmd/java/run.go new file mode 100644 index 0000000..3caca9f --- /dev/null +++ b/test/integration/cmd/java/run.go @@ -0,0 +1,99 @@ +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + + "dagger.io/dagger" + "github.com/open-feature/cli/test/integration" +) + +// Test implements the integration test for the Java generator +type Test struct { + // ProjectDir is the absolute path to the root of the project + ProjectDir string + // TestDir is the absolute path to the test directory + TestDir string +} + +// New creates a new Test +func New(projectDir, testDir string) *Test { + return &Test{ + ProjectDir: projectDir, + TestDir: testDir, + } +} + +// Run executes the Java integration test using Dagger +func (t *Test) Run(ctx context.Context, client *dagger.Client) (*dagger.Container, error) { + // Source code container + source := client.Host().Directory(t.ProjectDir) + testFiles := client.Host().Directory(t.TestDir, dagger.HostDirectoryOpts{ + Include: []string{"pom.xml", "src/**/*.java"}, + }) + + // Build the CLI + cli := client.Container(). + From("golang:1.24-alpine"). + WithExec([]string{"apk", "add", "--no-cache", "git"}). + WithDirectory("/src", source). + WithWorkdir("/src"). + WithExec([]string{"go", "mod", "tidy"}). + WithExec([]string{"go", "mod", "download"}). + WithExec([]string{"go", "build", "-o", "cli", "./cmd/openfeature"}) + + // Generate Java client + generated := cli.WithExec([]string{ + "./cli", "generate", "java", + "--manifest=/src/sample/sample_manifest.json", + "--output=/tmp/generated", + "--package-name=dev.openfeature.generated", + }) + + // Get generated files + generatedFiles := generated.Directory("/tmp/generated") + + // Test Java compilation with the generated files + javaContainer := client.Container(). + From("maven:3.9-eclipse-temurin-21-alpine"). + WithWorkdir("/app"). + WithDirectory("/app", testFiles). + WithDirectory("/app/src/main/java/dev/openfeature/generated", generatedFiles). + WithExec([]string{"mvn", "clean", "compile", "-B", "-q"}). + WithExec([]string{"mvn", "exec:java", "-Dexec.mainClass=dev.openfeature.Main", "-q"}) + + return javaContainer, nil +} + +// Name returns the name of the integration test +func (t *Test) Name() string { + return "java" +} + +func main() { + ctx := context.Background() + + // Get project root + projectDir, err := filepath.Abs(os.Getenv("PWD")) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to get project dir: %v\n", err) + os.Exit(1) + } + + // Get test directory + testDir, err := filepath.Abs(filepath.Join(projectDir, "test/java-integration")) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to get test dir: %v\n", err) + os.Exit(1) + } + + // Create and run the Java integration test + test := New(projectDir, testDir) + + if err := integration.RunTest(ctx, test); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +} diff --git a/test/integration/cmd/nestjs/run.go b/test/integration/cmd/nestjs/run.go new file mode 100644 index 0000000..29179d4 --- /dev/null +++ b/test/integration/cmd/nestjs/run.go @@ -0,0 +1,99 @@ +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + + "dagger.io/dagger" + "github.com/open-feature/cli/test/integration" +) + +// Test implements the integration test for the NestJS generator +type Test struct { + // ProjectDir is the absolute path to the root of the project + ProjectDir string + // TestDir is the absolute path to the test directory + TestDir string +} + +// New creates a new Test +func New(projectDir, testDir string) *Test { + return &Test{ + ProjectDir: projectDir, + TestDir: testDir, + } +} + +// Run executes the NestJS integration test using Dagger +func (t *Test) Run(ctx context.Context, client *dagger.Client) (*dagger.Container, error) { + // Source code container + source := client.Host().Directory(t.ProjectDir) + testFiles := client.Host().Directory(t.TestDir, dagger.HostDirectoryOpts{ + Include: []string{"package.json", "tsconfig.json", "src/**/*.ts"}, + }) + + // Build the CLI + cli := client.Container(). + From("golang:1.24-alpine"). + WithExec([]string{"apk", "add", "--no-cache", "git"}). + WithDirectory("/src", source). + WithWorkdir("/src"). + WithExec([]string{"go", "mod", "tidy"}). + WithExec([]string{"go", "mod", "download"}). + WithExec([]string{"go", "build", "-o", "cli", "./cmd/openfeature"}) + + // Generate NestJS client + generated := cli.WithExec([]string{ + "./cli", "generate", "nestjs", + "--manifest=/src/sample/sample_manifest.json", + "--output=/tmp/generated", + }) + + // Get generated files + generatedFiles := generated.Directory("/tmp/generated") + + // Test NestJS compilation with the generated files + nestjsContainer := client.Container(). + From("node:20-alpine"). + WithWorkdir("/app"). + WithDirectory("/app", testFiles). + WithDirectory("/app/src/generated", generatedFiles). + WithExec([]string{"npm", "install"}). + WithExec([]string{"npm", "run", "build"}). + WithExec([]string{"node", "dist/main.js"}) + + return nestjsContainer, nil +} + +// Name returns the name of the integration test +func (t *Test) Name() string { + return "nestjs" +} + +func main() { + ctx := context.Background() + + // Get project root + projectDir, err := filepath.Abs(os.Getenv("PWD")) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to get project dir: %v\n", err) + os.Exit(1) + } + + // Get test directory + testDir, err := filepath.Abs(filepath.Join(projectDir, "test/nestjs-integration")) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to get test dir: %v\n", err) + os.Exit(1) + } + + // Create and run the NestJS integration test + test := New(projectDir, testDir) + + if err := integration.RunTest(ctx, test); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +} diff --git a/test/integration/cmd/react/run.go b/test/integration/cmd/react/run.go new file mode 100644 index 0000000..fb50b62 --- /dev/null +++ b/test/integration/cmd/react/run.go @@ -0,0 +1,99 @@ +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + + "dagger.io/dagger" + "github.com/open-feature/cli/test/integration" +) + +// Test implements the integration test for the React generator +type Test struct { + // ProjectDir is the absolute path to the root of the project + ProjectDir string + // TestDir is the absolute path to the test directory + TestDir string +} + +// New creates a new Test +func New(projectDir, testDir string) *Test { + return &Test{ + ProjectDir: projectDir, + TestDir: testDir, + } +} + +// Run executes the React integration test using Dagger +func (t *Test) Run(ctx context.Context, client *dagger.Client) (*dagger.Container, error) { + // Source code container + source := client.Host().Directory(t.ProjectDir) + testFiles := client.Host().Directory(t.TestDir, dagger.HostDirectoryOpts{ + Include: []string{"package.json", "tsconfig.json", "src/**/*.ts", "src/**/*.tsx"}, + }) + + // Build the CLI + cli := client.Container(). + From("golang:1.24-alpine"). + WithExec([]string{"apk", "add", "--no-cache", "git"}). + WithDirectory("/src", source). + WithWorkdir("/src"). + WithExec([]string{"go", "mod", "tidy"}). + WithExec([]string{"go", "mod", "download"}). + WithExec([]string{"go", "build", "-o", "cli", "./cmd/openfeature"}) + + // Generate React client + generated := cli.WithExec([]string{ + "./cli", "generate", "react", + "--manifest=/src/sample/sample_manifest.json", + "--output=/tmp/generated", + }) + + // Get generated files + generatedFiles := generated.Directory("/tmp/generated") + + // Test React compilation with the generated files + reactContainer := client.Container(). + From("node:20-alpine"). + WithWorkdir("/app"). + WithDirectory("/app", testFiles). + WithDirectory("/app/src/generated", generatedFiles). + WithExec([]string{"npm", "install"}). + WithExec([]string{"npm", "run", "build"}). + WithExec([]string{"node", "dist/test.js"}) + + return reactContainer, nil +} + +// Name returns the name of the integration test +func (t *Test) Name() string { + return "react" +} + +func main() { + ctx := context.Background() + + // Get project root + projectDir, err := filepath.Abs(os.Getenv("PWD")) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to get project dir: %v\n", err) + os.Exit(1) + } + + // Get test directory + testDir, err := filepath.Abs(filepath.Join(projectDir, "test/react-integration")) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to get test dir: %v\n", err) + os.Exit(1) + } + + // Create and run the React integration test + test := New(projectDir, testDir) + + if err := integration.RunTest(ctx, test); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +} diff --git a/test/integration/cmd/run.go b/test/integration/cmd/run.go index 5923c26..176b22d 100644 --- a/test/integration/cmd/run.go +++ b/test/integration/cmd/run.go @@ -45,6 +45,33 @@ func main() { os.Exit(1) } + // Run the Java integration test + javaCmd := exec.Command("go", "run", "github.com/open-feature/cli/test/integration/cmd/java") + javaCmd.Stdout = os.Stdout + javaCmd.Stderr = os.Stderr + if err := javaCmd.Run(); err != nil { + fmt.Fprintf(os.Stderr, "Error running Java integration test: %v\n", err) + os.Exit(1) + } + + // Run the NestJS integration test + nestjsCmd := exec.Command("go", "run", "github.com/open-feature/cli/test/integration/cmd/nestjs") + nestjsCmd.Stdout = os.Stdout + nestjsCmd.Stderr = os.Stderr + if err := nestjsCmd.Run(); err != nil { + fmt.Fprintf(os.Stderr, "Error running NestJS integration test: %v\n", err) + os.Exit(1) + } + + // Run the React integration test + reactCmd := exec.Command("go", "run", "github.com/open-feature/cli/test/integration/cmd/react") + reactCmd.Stdout = os.Stdout + reactCmd.Stderr = os.Stderr + if err := reactCmd.Run(); err != nil { + fmt.Fprintf(os.Stderr, "Error running React integration test: %v\n", err) + os.Exit(1) + } + // Add more tests here as they are available fmt.Println("=== All integration tests passed successfully ===") diff --git a/test/java-integration/pom.xml b/test/java-integration/pom.xml new file mode 100644 index 0000000..6525552 --- /dev/null +++ b/test/java-integration/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + dev.openfeature + cli-java-integration-test + 1.0-SNAPSHOT + + + 11 + 11 + UTF-8 + + + + + + dev.openfeature + sdk + 1.14.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 11 + 11 + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + dev.openfeature.Main + + + + + diff --git a/test/java-integration/src/main/java/dev/openfeature/Main.java b/test/java-integration/src/main/java/dev/openfeature/Main.java new file mode 100644 index 0000000..e994c19 --- /dev/null +++ b/test/java-integration/src/main/java/dev/openfeature/Main.java @@ -0,0 +1,107 @@ +package dev.openfeature; + +import dev.openfeature.generated.*; +import dev.openfeature.sdk.*; +import dev.openfeature.sdk.providers.memory.Flag; +import dev.openfeature.sdk.providers.memory.InMemoryProvider; + +import java.util.HashMap; +import java.util.Map; + +public class Main { + public static void main(String[] args) { + try { + run(); + System.out.println("Generated Java code compiles successfully!"); + } catch (Exception e) { + System.err.println("Error: " + e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + } + + private static void run() throws Exception { + // Set up the in-memory provider with test flags + Map> flags = new HashMap<>(); + + flags.put("discountPercentage", Flag.builder() + .variant("default", 0.15) + .defaultVariant("default") + .build()); + + flags.put("enableFeatureA", Flag.builder() + .variant("default", false) + .defaultVariant("default") + .build()); + + flags.put("greetingMessage", Flag.builder() + .variant("default", "Hello there!") + .defaultVariant("default") + .build()); + + flags.put("usernameMaxLength", Flag.builder() + .variant("default", 50) + .defaultVariant("default") + .build()); + + Map themeConfig = new HashMap<>(); + themeConfig.put("primaryColor", "#007bff"); + themeConfig.put("secondaryColor", "#6c757d"); + + flags.put("themeCustomization", Flag.builder() + .variant("default", new Value(themeConfig)) + .defaultVariant("default") + .build()); + + InMemoryProvider provider = new InMemoryProvider(flags); + + // Set the provider + OpenFeatureAPI.getInstance().setProviderAndWait(provider); + + Client client = OpenFeatureAPI.getInstance().getClient(); + MutableContext evalContext = new MutableContext(); + + // Use the generated code for all flag evaluations + Boolean enableFeatureA = EnableFeatureA.value(client, evalContext); + System.out.println("enableFeatureA: " + enableFeatureA); + FlagEvaluationDetails enableFeatureADetails = EnableFeatureA.valueWithDetails(client, evalContext); + if (enableFeatureADetails.getErrorCode() != null) { + throw new Exception("Error evaluating boolean flag"); + } + + Double discount = DiscountPercentage.value(client, evalContext); + System.out.printf("Discount Percentage: %.2f%n", discount); + FlagEvaluationDetails discountDetails = DiscountPercentage.valueWithDetails(client, evalContext); + if (discountDetails.getErrorCode() != null) { + throw new Exception("Failed to get discount"); + } + + String greetingMessage = GreetingMessage.value(client, evalContext); + System.out.println("greetingMessage: " + greetingMessage); + FlagEvaluationDetails greetingDetails = GreetingMessage.valueWithDetails(client, evalContext); + if (greetingDetails.getErrorCode() != null) { + throw new Exception("Error evaluating string flag"); + } + + Integer usernameMaxLength = UsernameMaxLength.value(client, evalContext); + System.out.println("usernameMaxLength: " + usernameMaxLength); + FlagEvaluationDetails usernameDetails = UsernameMaxLength.valueWithDetails(client, evalContext); + if (usernameDetails.getErrorCode() != null) { + throw new Exception("Error evaluating int flag"); + } + + Value themeCustomization = ThemeCustomization.value(client, evalContext); + FlagEvaluationDetails themeDetails = ThemeCustomization.valueWithDetails(client, evalContext); + if (themeDetails.getErrorCode() != null) { + throw new Exception("Error evaluating object flag"); + } + System.out.println("themeCustomization: " + themeCustomization); + + // Test the getKey() method functionality for all flags + System.out.println("enableFeatureA flag key: " + EnableFeatureA.getKey()); + System.out.println("discountPercentage flag key: " + DiscountPercentage.getKey()); + System.out.println("greetingMessage flag key: " + GreetingMessage.getKey()); + System.out.println("usernameMaxLength flag key: " + UsernameMaxLength.getKey()); + System.out.println("themeCustomization flag key: " + ThemeCustomization.getKey()); + } +} diff --git a/test/nestjs-integration/package.json b/test/nestjs-integration/package.json new file mode 100644 index 0000000..528971e --- /dev/null +++ b/test/nestjs-integration/package.json @@ -0,0 +1,21 @@ +{ + "name": "cli-nestjs-integration-test", + "version": "1.0.0", + "description": "Integration test for OpenFeature CLI NestJS generator", + "scripts": { + "build": "tsc", + "start": "node dist/main.js" + }, + "dependencies": { + "@nestjs/common": "^10.0.0", + "@nestjs/core": "^10.0.0", + "@openfeature/nestjs-sdk": "^0.7.0", + "@openfeature/server-sdk": "^1.34.0", + "reflect-metadata": "^0.1.13", + "rxjs": "^7.8.1" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "typescript": "^5.3.0" + } +} diff --git a/test/nestjs-integration/src/main.ts b/test/nestjs-integration/src/main.ts new file mode 100644 index 0000000..f4bf7aa --- /dev/null +++ b/test/nestjs-integration/src/main.ts @@ -0,0 +1,120 @@ +import { NestFactory } from '@nestjs/core'; +import { Module } from '@nestjs/common'; +import { OpenFeatureModule } from '@openfeature/nestjs-sdk'; +import { InMemoryProvider } from '@openfeature/server-sdk'; +import * as generated from './generated'; + +@Module({ + imports: [ + OpenFeatureModule.forRoot({ + provider: new InMemoryProvider({ + discountPercentage: { + disabled: false, + variants: { + default: 0.15, + }, + defaultVariant: 'default', + }, + enableFeatureA: { + disabled: false, + variants: { + default: false, + }, + defaultVariant: 'default', + }, + greetingMessage: { + disabled: false, + variants: { + default: 'Hello there!', + }, + defaultVariant: 'default', + }, + usernameMaxLength: { + disabled: false, + variants: { + default: 50, + }, + defaultVariant: 'default', + }, + themeCustomization: { + disabled: false, + variants: { + default: { + primaryColor: '#007bff', + secondaryColor: '#6c757d', + }, + }, + defaultVariant: 'default', + }, + }), + }), + ], +}) +class AppModule {} + +async function bootstrap() { + const app = await NestFactory.createApplicationContext(AppModule); + + try { + const client = app.get('OPENFEATURE_CLIENT'); + + // Use the generated code for all flag evaluations + const enableFeatureA = await generated.EnableFeatureA.value(client, {}); + console.log('enableFeatureA:', enableFeatureA); + + const enableFeatureADetails = await generated.EnableFeatureA.valueWithDetails(client, {}); + if (enableFeatureADetails.errorCode) { + throw new Error('Error evaluating boolean flag'); + } + + const discount = await generated.DiscountPercentage.value(client, {}); + console.log('Discount Percentage:', discount.toFixed(2)); + + const discountDetails = await generated.DiscountPercentage.valueWithDetails(client, {}); + if (discountDetails.errorCode) { + throw new Error('Failed to get discount'); + } + + const greetingMessage = await generated.GreetingMessage.value(client, {}); + console.log('greetingMessage:', greetingMessage); + + const greetingDetails = await generated.GreetingMessage.valueWithDetails(client, {}); + if (greetingDetails.errorCode) { + throw new Error('Error evaluating string flag'); + } + + const usernameMaxLength = await generated.UsernameMaxLength.value(client, {}); + console.log('usernameMaxLength:', usernameMaxLength); + + const usernameDetails = await generated.UsernameMaxLength.valueWithDetails(client, {}); + if (usernameDetails.errorCode) { + throw new Error('Error evaluating int flag'); + } + + const themeCustomization = await generated.ThemeCustomization.value(client, {}); + console.log('themeCustomization:', themeCustomization); + + const themeDetails = await generated.ThemeCustomization.valueWithDetails(client, {}); + if (themeDetails.errorCode) { + throw new Error('Error evaluating object flag'); + } + + // Test the getKey() method functionality for all flags + console.log('enableFeatureA flag key:', generated.EnableFeatureA.getKey()); + console.log('discountPercentage flag key:', generated.DiscountPercentage.getKey()); + console.log('greetingMessage flag key:', generated.GreetingMessage.getKey()); + console.log('usernameMaxLength flag key:', generated.UsernameMaxLength.getKey()); + console.log('themeCustomization flag key:', generated.ThemeCustomization.getKey()); + + console.log('Generated NestJS code compiles successfully!'); + + await app.close(); + process.exit(0); + } catch (error) { + console.error('Error:', error); + await app.close(); + process.exit(1); + } +} + +bootstrap(); diff --git a/test/nestjs-integration/tsconfig.json b/test/nestjs-integration/tsconfig.json new file mode 100644 index 0000000..5485d9d --- /dev/null +++ b/test/nestjs-integration/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ES2021", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": false, + "noImplicitAny": false, + "strictBindCallApply": false, + "forceConsistentCasingInFileNames": false, + "noFallthroughCasesInSwitch": false, + "esModuleInterop": true + } +} diff --git a/test/react-integration/package.json b/test/react-integration/package.json new file mode 100644 index 0000000..9ffea5c --- /dev/null +++ b/test/react-integration/package.json @@ -0,0 +1,19 @@ +{ + "name": "cli-react-integration-test", + "version": "1.0.0", + "description": "Integration test for OpenFeature CLI React generator", + "scripts": { + "build": "tsc", + "test": "node dist/test.js" + }, + "dependencies": { + "@openfeature/react-sdk": "^1.0.0", + "@openfeature/server-sdk": "^1.34.0", + "react": "^18.2.0" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "@types/react": "^18.2.0", + "typescript": "^5.3.0" + } +} diff --git a/test/react-integration/src/test.ts b/test/react-integration/src/test.ts new file mode 100644 index 0000000..affcc3e --- /dev/null +++ b/test/react-integration/src/test.ts @@ -0,0 +1,69 @@ +import * as generated from './generated'; + +async function main() { + try { + // Validate that all generated exports exist and have the expected structure + const flags = [ + { name: 'EnableFeatureA', flag: generated.EnableFeatureA }, + { name: 'DiscountPercentage', flag: generated.DiscountPercentage }, + { name: 'GreetingMessage', flag: generated.GreetingMessage }, + { name: 'UsernameMaxLength', flag: generated.UsernameMaxLength }, + { name: 'ThemeCustomization', flag: generated.ThemeCustomization }, + ]; + + for (const { name, flag } of flags) { + // Validate the flag object has the expected properties + if (typeof flag !== 'object' || flag === null) { + throw new Error(`${name} is not an object`); + } + + // Check for getKey method + if (typeof flag.getKey !== 'function') { + throw new Error(`${name}.getKey is not a function`); + } + + const key = flag.getKey(); + console.log(`${name} flag key:`, key); + + if (typeof key !== 'string' || key.length === 0) { + throw new Error(`${name}.getKey() did not return a valid string`); + } + + // Check for useFlag hook + if (typeof flag.useFlag !== 'function') { + throw new Error(`${name}.useFlag is not a function`); + } + + // Check for useFlagWithDetails hook + if (typeof flag.useFlagWithDetails !== 'function') { + throw new Error(`${name}.useFlagWithDetails is not a function`); + } + } + + // Verify expected flag keys + if (generated.EnableFeatureA.getKey() !== 'enableFeatureA') { + throw new Error('EnableFeatureA has incorrect key'); + } + if (generated.DiscountPercentage.getKey() !== 'discountPercentage') { + throw new Error('DiscountPercentage has incorrect key'); + } + if (generated.GreetingMessage.getKey() !== 'greetingMessage') { + throw new Error('GreetingMessage has incorrect key'); + } + if (generated.UsernameMaxLength.getKey() !== 'usernameMaxLength') { + throw new Error('UsernameMaxLength has incorrect key'); + } + if (generated.ThemeCustomization.getKey() !== 'themeCustomization') { + throw new Error('ThemeCustomization has incorrect key'); + } + + console.log('All generated React hooks are properly structured!'); + console.log('Generated React code compiles successfully!'); + process.exit(0); + } catch (error: any) { + console.error('Error:', error.message); + process.exit(1); + } +} + +main(); diff --git a/test/react-integration/tsconfig.json b/test/react-integration/tsconfig.json new file mode 100644 index 0000000..1cafe6d --- /dev/null +++ b/test/react-integration/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2021", + "module": "commonjs", + "lib": ["ES2021"], + "jsx": "react", + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "moduleResolution": "node" + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +}