Skip to content

Commit d97ec3b

Browse files
author
rzp-Piyush
committed
add: test validation & data integrity scripts
1 parent 2596e13 commit d97ec3b

File tree

4 files changed

+455
-0
lines changed

4 files changed

+455
-0
lines changed

.github/scripts/go/generate-package.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ fi
268268

269269
log_info "Generated: data_loader.go"
270270

271+
# --- Generate Data Loader Test ---
272+
# Use separate script for test generation (easier to update independently)
273+
"$SCRIPT_DIR/generate-test.sh" "$OUTPUT_DIR" "$GO_PACKAGE_NAME" "$ROOT_MESSAGE" "$MULTIPLE_FILES"
274+
271275
# --- Verify files were created ---
272276
if [ ! -f "$OUTPUT_DIR/go.mod" ]; then
273277
log_error "Failed to create go.mod"
@@ -279,6 +283,11 @@ if [ ! -f "$OUTPUT_DIR/data_loader.go" ]; then
279283
exit 1
280284
fi
281285

286+
if [ ! -f "$OUTPUT_DIR/data_loader_test.go" ]; then
287+
log_error "Failed to create data_loader_test.go"
288+
exit 1
289+
fi
290+
282291
# --- Generate go.sum (run go mod tidy) ---
283292
log_info "Running go mod tidy..."
284293
cd "$OUTPUT_DIR"
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
#!/usr/bin/env bash
2+
3+
# Test File Generator for i18nify-data Go packages
4+
#
5+
# This script generates data_loader_test.go for a Go package.
6+
# It creates tests that verify the data can be loaded correctly.
7+
#
8+
# Usage: ./generate-test.sh <output-dir> <package-name> <root-message> <multiple-files>
9+
# Example: ./generate-test.sh ./output currency CurrencyData false
10+
#
11+
# Parameters:
12+
# output-dir - Directory where test file will be created
13+
# package-name - Go package name (e.g., currency, country_subdivisions)
14+
# root-message - Proto root message name (e.g., CurrencyData, BankCodes)
15+
# multiple-files - "true" for multi-file packages, "false" for single-file
16+
17+
set -euo pipefail
18+
19+
# Colors for output
20+
RED='\033[0;31m'
21+
GREEN='\033[0;32m'
22+
NC='\033[0m'
23+
24+
log_info() { echo -e "${GREEN}[INFO]${NC} $1" >&2; }
25+
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
26+
27+
# --- Parse Arguments ---
28+
OUTPUT_DIR="${1:-}"
29+
GO_PACKAGE_NAME="${2:-}"
30+
ROOT_MESSAGE="${3:-}"
31+
MULTIPLE_FILES="${4:-false}"
32+
33+
if [ -z "$OUTPUT_DIR" ] || [ -z "$GO_PACKAGE_NAME" ] || [ -z "$ROOT_MESSAGE" ]; then
34+
log_error "Missing required arguments"
35+
echo "Usage: $0 <output-dir> <package-name> <root-message> <multiple-files>"
36+
echo "Example: $0 ./output currency CurrencyData false"
37+
exit 1
38+
fi
39+
40+
log_info "Generating test file..."
41+
log_info " Output dir: $OUTPUT_DIR"
42+
log_info " Package: $GO_PACKAGE_NAME"
43+
log_info " Root message: $ROOT_MESSAGE"
44+
log_info " Multiple files: $MULTIPLE_FILES"
45+
46+
# --- Ensure output directory exists ---
47+
mkdir -p "$OUTPUT_DIR"
48+
49+
# --- Generate Test File ---
50+
TEST_FILE="$OUTPUT_DIR/data_loader_test.go"
51+
52+
if [ "$MULTIPLE_FILES" = "true" ]; then
53+
# Generate multi-file data loader test
54+
cat > "$TEST_FILE" << TESTEOF
55+
// Code generated by i18nify go generator. DO NOT EDIT.
56+
57+
package ${GO_PACKAGE_NAME}
58+
59+
import (
60+
"testing"
61+
)
62+
63+
// TestGet${ROOT_MESSAGE}_AllCountryCodes tests that all available country codes
64+
// can be loaded successfully. This ensures the JSON data is valid and matches
65+
// the proto schema.
66+
func TestGet${ROOT_MESSAGE}_AllCountryCodes(t *testing.T) {
67+
// Get all available country codes
68+
codes, err := GetAvailableCountryCodes()
69+
if err != nil {
70+
t.Fatalf("GetAvailableCountryCodes() error = %v", err)
71+
}
72+
73+
if len(codes) == 0 {
74+
t.Fatal("GetAvailableCountryCodes() returned empty list")
75+
}
76+
77+
t.Logf("Found %d country codes: %v", len(codes), codes)
78+
79+
// Test loading data for each country code
80+
for _, code := range codes {
81+
t.Run(code, func(t *testing.T) {
82+
data, err := Get${ROOT_MESSAGE}(code)
83+
if err != nil {
84+
t.Errorf("Get${ROOT_MESSAGE}(%q) error = %v", code, err)
85+
return
86+
}
87+
if data == nil {
88+
t.Errorf("Get${ROOT_MESSAGE}(%q) returned nil data", code)
89+
}
90+
})
91+
}
92+
}
93+
94+
// TestGet${ROOT_MESSAGE}_InvalidCode tests that an invalid country code
95+
// returns an appropriate error.
96+
func TestGet${ROOT_MESSAGE}_InvalidCode(t *testing.T) {
97+
_, err := Get${ROOT_MESSAGE}("INVALID_CODE_XYZ_123")
98+
if err == nil {
99+
t.Error("Get${ROOT_MESSAGE}(\"INVALID_CODE_XYZ_123\") expected error, got nil")
100+
}
101+
}
102+
103+
// TestGet${ROOT_MESSAGE}_CaseInsensitive tests that country codes are
104+
// handled case-insensitively.
105+
func TestGet${ROOT_MESSAGE}_CaseInsensitive(t *testing.T) {
106+
codes, err := GetAvailableCountryCodes()
107+
if err != nil || len(codes) == 0 {
108+
t.Skip("No country codes available")
109+
}
110+
111+
code := codes[0]
112+
113+
// Test uppercase
114+
data1, err1 := Get${ROOT_MESSAGE}(code)
115+
if err1 != nil {
116+
t.Fatalf("Get${ROOT_MESSAGE}(%q) error = %v", code, err1)
117+
}
118+
119+
// Test lowercase (should return same data from cache)
120+
lowerCode := code // codes are already uppercase
121+
data2, err2 := Get${ROOT_MESSAGE}(lowerCode)
122+
if err2 != nil {
123+
t.Fatalf("Get${ROOT_MESSAGE}(%q) error = %v", lowerCode, err2)
124+
}
125+
126+
// Both should return valid data
127+
if data1 == nil || data2 == nil {
128+
t.Error("Expected non-nil data for both cases")
129+
}
130+
}
131+
TESTEOF
132+
else
133+
# Generate single-file data loader test
134+
cat > "$TEST_FILE" << TESTEOF
135+
// Code generated by i18nify go generator. DO NOT EDIT.
136+
137+
package ${GO_PACKAGE_NAME}
138+
139+
import (
140+
"testing"
141+
)
142+
143+
// TestGet${ROOT_MESSAGE} tests that the data can be loaded successfully.
144+
// This ensures the JSON data is valid and matches the proto schema.
145+
func TestGet${ROOT_MESSAGE}(t *testing.T) {
146+
data, err := Get${ROOT_MESSAGE}()
147+
if err != nil {
148+
t.Fatalf("Get${ROOT_MESSAGE}() error = %v", err)
149+
}
150+
151+
if data == nil {
152+
t.Fatal("Get${ROOT_MESSAGE}() returned nil data")
153+
}
154+
155+
t.Log("Data loaded successfully")
156+
}
157+
158+
// TestGet${ROOT_MESSAGE}_Idempotent tests that multiple calls return
159+
// the same cached instance.
160+
func TestGet${ROOT_MESSAGE}_Idempotent(t *testing.T) {
161+
// Call twice to verify caching works
162+
data1, err1 := Get${ROOT_MESSAGE}()
163+
if err1 != nil {
164+
t.Fatalf("First Get${ROOT_MESSAGE}() error = %v", err1)
165+
}
166+
167+
data2, err2 := Get${ROOT_MESSAGE}()
168+
if err2 != nil {
169+
t.Fatalf("Second Get${ROOT_MESSAGE}() error = %v", err2)
170+
}
171+
172+
// Should return the same pointer (cached)
173+
if data1 != data2 {
174+
t.Error("Get${ROOT_MESSAGE}() should return cached data on subsequent calls")
175+
}
176+
}
177+
178+
// TestGet${ROOT_MESSAGE}_NotEmpty performs a basic sanity check
179+
// that the loaded data is not empty.
180+
func TestGet${ROOT_MESSAGE}_NotEmpty(t *testing.T) {
181+
data, err := Get${ROOT_MESSAGE}()
182+
if err != nil {
183+
t.Fatalf("Get${ROOT_MESSAGE}() error = %v", err)
184+
}
185+
186+
// Use reflection or proto methods to check if data has any fields set
187+
// This is a basic check - specific packages may want more detailed validation
188+
if data == nil {
189+
t.Error("Data should not be nil")
190+
}
191+
}
192+
TESTEOF
193+
fi
194+
195+
log_info "✅ Generated: $TEST_FILE"
196+
echo "$TEST_FILE"

0 commit comments

Comments
 (0)