-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: Add tests for golang and react with in memory files (#43)
<!-- Please use this template for your pull request. --> <!-- Please use the sections that you need and delete other sections --> ## This PR <!-- add the description of the PR here --> - adds tests for React and Golang ### Related Issues #42 Fixes #42 ### How to test `go test ./...` from root folder --------- Signed-off-by: Florin-Mihai Anghel <[email protected]> Signed-off-by: Florin-Mihai Anghel <[email protected]> Co-authored-by: Michael Beemer <[email protected]>
- Loading branch information
1 parent
8fa83b0
commit ce14e1c
Showing
12 changed files
with
285 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package generate | ||
|
||
import ( | ||
"codegen/internal/flagkeys" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
|
||
"github.com/spf13/afero" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
func TestGenerateGoSuccess(t *testing.T) { | ||
// Constant paths. | ||
const memoryManifestPath = "manifest/path.json" | ||
const memoryOutputPath = "output/path.go" | ||
const packageName = "testpackage" | ||
const testFileManifest = "testdata/success_manifest.golden" | ||
const testFileGo = "testdata/success_go.golden" | ||
|
||
// Prepare in-memory files. | ||
fs := afero.NewMemMapFs() | ||
viper.Set(flagkeys.FileSystem, fs) | ||
readOsFileAndWriteToMemMap(t, testFileManifest, memoryManifestPath, fs) | ||
|
||
// Prepare command. | ||
Root.SetArgs([]string{"go", | ||
"--flag_manifest_path", memoryManifestPath, | ||
"--output_path", memoryOutputPath, | ||
"--package_name", packageName, | ||
}) | ||
|
||
// Run command. | ||
Root.Execute() | ||
|
||
// Compare result. | ||
compareOutput(t, testFileGo, memoryOutputPath, fs) | ||
} | ||
|
||
func TestGenerateReactSuccess(t *testing.T) { | ||
// Constant paths. | ||
const memoryManifestPath = "manifest/path.json" | ||
const memoryOutputPath = "output/path.ts" | ||
const testFileManifest = "testdata/success_manifest.golden" | ||
const testFileReact = "testdata/success_react.golden" | ||
|
||
// Prepare in-memory files. | ||
fs := afero.NewMemMapFs() | ||
viper.Set(flagkeys.FileSystem, fs) | ||
readOsFileAndWriteToMemMap(t, testFileManifest, memoryManifestPath, fs) | ||
|
||
// Prepare command. | ||
Root.SetArgs([]string{"react", | ||
"--flag_manifest_path", memoryManifestPath, | ||
"--output_path", memoryOutputPath, | ||
}) | ||
|
||
// Run command. | ||
Root.Execute() | ||
|
||
// Compare result. | ||
compareOutput(t, testFileReact, memoryOutputPath, fs) | ||
} | ||
|
||
func readOsFileAndWriteToMemMap(t *testing.T, inputPath string, memPath string, memFs afero.Fs) { | ||
data, err := os.ReadFile(inputPath) | ||
if err != nil { | ||
t.Fatalf("error reading file %q: %v", inputPath, err) | ||
} | ||
if err := memFs.MkdirAll(filepath.Dir(memPath), 0660); err != nil { | ||
t.Fatalf("error creating directory %q: %v", filepath.Dir(memPath), err) | ||
} | ||
f, err := memFs.Create(memPath) | ||
if err != nil { | ||
t.Fatalf("error creating file %q: %v", memPath, err) | ||
} | ||
defer f.Close() | ||
writtenBytes, err := f.Write(data) | ||
if err != nil { | ||
t.Fatalf("error writing contents to file %q: %v", memPath, err) | ||
} | ||
if writtenBytes != len(data) { | ||
t.Fatalf("error writing entire file %v: writtenBytes != expectedWrittenBytes", memPath) | ||
} | ||
} | ||
|
||
func compareOutput(t *testing.T, testFile, memoryOutputPath string, fs afero.Fs) { | ||
want, err := os.ReadFile(testFile) | ||
if err != nil { | ||
t.Fatalf("error reading file %q: %v", testFile, err) | ||
|
||
} | ||
got, err := afero.ReadFile(fs, memoryOutputPath) | ||
if err != nil { | ||
t.Fatalf("error reading file %q: %v", memoryOutputPath, err) | ||
} | ||
if diff := cmp.Diff(want, got); diff != "" { | ||
t.Errorf("output mismatch (-want +got):\n%s", diff) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package testpackage | ||
|
||
import ( | ||
"context" | ||
"github.com/open-feature/go-sdk/openfeature" | ||
) | ||
|
||
type BooleanProvider func(ctx context.Context) (bool, error) | ||
type FloatProvider func(ctx context.Context) (float64, error) | ||
type IntProvider func(ctx context.Context) (int64, error) | ||
type StringProvider func(ctx context.Context) (string, error) | ||
|
||
var client *openfeature.Client = nil | ||
// Discount percentage applied to purchases. | ||
var DiscountPercentage = struct { | ||
Value FloatProvider | ||
}{ | ||
Value: func(ctx context.Context) (float64, error) { | ||
return client.FloatValue(ctx, "discountPercentage", 0.15, openfeature.EvaluationContext{}) | ||
}, | ||
} | ||
// Controls whether Feature A is enabled. | ||
var EnableFeatureA = struct { | ||
Value BooleanProvider | ||
}{ | ||
Value: func(ctx context.Context) (bool, error) { | ||
return client.BooleanValue(ctx, "enableFeatureA", false, openfeature.EvaluationContext{}) | ||
}, | ||
} | ||
// The message to use for greeting users. | ||
var GreetingMessage = struct { | ||
Value StringProvider | ||
}{ | ||
Value: func(ctx context.Context) (string, error) { | ||
return client.StringValue(ctx, "greetingMessage", "Hello there!", openfeature.EvaluationContext{}) | ||
}, | ||
} | ||
// Maximum allowed length for usernames. | ||
var UsernameMaxLength = struct { | ||
Value IntProvider | ||
}{ | ||
Value: func(ctx context.Context) (int64, error) { | ||
return client.IntValue(ctx, "usernameMaxLength", 50, openfeature.EvaluationContext{}) | ||
}, | ||
} | ||
|
||
func init() { | ||
client = openfeature.NewClient("testpackage") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"flags": { | ||
"enableFeatureA": { | ||
"flagType": "boolean", | ||
"defaultValue": false, | ||
"description": "Controls whether Feature A is enabled." | ||
}, | ||
"usernameMaxLength": { | ||
"flagType": "integer", | ||
"defaultValue": 50, | ||
"description": "Maximum allowed length for usernames." | ||
}, | ||
"greetingMessage": { | ||
"flagType": "string", | ||
"defaultValue": "Hello there!", | ||
"description": "The message to use for greeting users." | ||
}, | ||
"discountPercentage": { | ||
"flagType": "float", | ||
"defaultValue": 0.15, | ||
"description": "Discount percentage applied to purchases." | ||
}, | ||
"themeCustomization": { | ||
"flagType": "object", | ||
"defaultValue": { | ||
"primaryColor": "#007bff", | ||
"secondaryColor": "#6c757d" | ||
}, | ||
"description": "Allows customization of theme colors." | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
'use client'; | ||
|
||
import { | ||
useBooleanFlagDetails, | ||
useNumberFlagDetails, | ||
useStringFlagDetails, | ||
} from "@openfeature/react-sdk"; | ||
|
||
/** | ||
* Discount percentage applied to purchases. | ||
* | ||
* **Details:** | ||
* - flag key: `discountPercentage` | ||
* - default value: `0.15` | ||
* - type: `number` | ||
*/ | ||
export const useDiscountPercentage = (options: Parameters<typeof useNumberFlagDetails>[2]) => { | ||
return useNumberFlagDetails("discountPercentage", 0.15, options); | ||
}; | ||
|
||
/** | ||
* Controls whether Feature A is enabled. | ||
* | ||
* **Details:** | ||
* - flag key: `enableFeatureA` | ||
* - default value: `false` | ||
* - type: `boolean` | ||
*/ | ||
export const useEnableFeatureA = (options: Parameters<typeof useBooleanFlagDetails>[2]) => { | ||
return useBooleanFlagDetails("enableFeatureA", false, options); | ||
}; | ||
|
||
/** | ||
* The message to use for greeting users. | ||
* | ||
* **Details:** | ||
* - flag key: `greetingMessage` | ||
* - default value: `Hello there!` | ||
* - type: `string` | ||
*/ | ||
export const useGreetingMessage = (options: Parameters<typeof useStringFlagDetails>[2]) => { | ||
return useStringFlagDetails("greetingMessage", "Hello there!", options); | ||
}; | ||
|
||
/** | ||
* Maximum allowed length for usernames. | ||
* | ||
* **Details:** | ||
* - flag key: `usernameMaxLength` | ||
* - default value: `50` | ||
* - type: `number` | ||
*/ | ||
export const useUsernameMaxLength = (options: Parameters<typeof useNumberFlagDetails>[2]) => { | ||
return useNumberFlagDetails("usernameMaxLength", 50, options); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Package filesystem contains the filesystem interface. | ||
package filesystem | ||
|
||
import ( | ||
"codegen/internal/flagkeys" | ||
|
||
"github.com/spf13/afero" | ||
"github.com/spf13/viper" | ||
) | ||
|
||
func FileSystem() afero.Fs { | ||
return viper.Get(flagkeys.FileSystem).(afero.Fs) | ||
} | ||
|
||
func init() { | ||
viper.SetDefault(flagkeys.FileSystem, afero.NewOsFs()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package testutils |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters