Skip to content

Commit ab98fa0

Browse files
committed
fix: add integration tests using python
1 parent 1c8c51e commit ab98fa0

22 files changed

+1945
-18
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,18 @@ jobs:
3232
- name: Download dependencies
3333
run: make deps
3434

35-
- name: Run tests
35+
- name: Run unit tests
3636
run: make test
3737

3838
- name: Generate coverage report
3939
run: make coverage
4040

41+
- name: Install uv
42+
uses: astral-sh/setup-uv@v3
43+
44+
- name: Run integration tests
45+
run: make test-integration
46+
4147
- name: Upload coverage to Codecov
4248
uses: codecov/codecov-action@v3
4349
with:

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
build/
22
ai/
33
**/*-test-*/
4+
**/__pycache__/
5+
**/*.pyc

Makefile

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ GOFMT=$(GOCMD) fmt
2020
GO_FILES=$(shell find . -name '*.go' -not -path "./vendor/*")
2121

2222
.PHONY: all build clean test coverage deps fmt lint vet help install uninstall dev
23+
.PHONY: test-integration test-schema test-sheet test-project test-merge test-parallel
2324

2425
all: clean build test ## Run clean, build, and test
2526

@@ -32,12 +33,23 @@ clean: ## Clean build directory
3233
@echo "Cleaning..."
3334
@rm -rf $(BUILD_DIR)
3435
@rm -rf $(COVERAGE_DIR)
36+
@rm -rf tests/.venv
37+
@rm -rf tests/.pytest_cache
38+
@rm -rf tests/__pycache__
39+
@find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
40+
@find . -type f -name "*.pyc" -delete 2>/dev/null || true
3541
$(GOCLEAN)
3642

37-
test: ## Run tests
38-
@echo "Running tests..."
43+
test: ## Run unit tests
44+
@echo "Running unit tests..."
3945
$(GOTEST) -v ./...
4046

47+
test-integration: ## Run integration tests
48+
@echo "Running integration tests..."
49+
@cd tests && uv run pytest
50+
51+
test-all: test test-integration ## Run both unit and integration tests
52+
4153
coverage: ## Generate test coverage report
4254
@echo "Generating coverage report..."
4355
@mkdir -p $(COVERAGE_DIR)

internal/command/apply.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func (c *ApplyCommand) Run(cmd *cobra.Command, args []string) error {
106106
if err != nil {
107107
return err
108108
}
109-
if !quiet {
109+
if !quiet && format != "json" {
110110
printer.Info(fmt.Sprintf("Applying .env file: %s", envOrSheetName))
111111
}
112112
} else if standalone {
@@ -115,7 +115,7 @@ func (c *ApplyCommand) Run(cmd *cobra.Command, args []string) error {
115115
if err != nil {
116116
return err
117117
}
118-
if !quiet {
118+
if !quiet && format != "json" {
119119
printer.Info(fmt.Sprintf("Applying standalone config sheet: %s", envOrSheetName))
120120
}
121121
} else {
@@ -124,14 +124,17 @@ func (c *ApplyCommand) Run(cmd *cobra.Command, args []string) error {
124124
if err != nil {
125125
return err
126126
}
127-
if !quiet {
127+
if !quiet && format != "json" {
128128
printer.Info(fmt.Sprintf("Applying environment '%s'", envOrSheetName))
129129
}
130130
}
131131

132132
if dryRun {
133133
// Show what would be applied
134-
printer.Info("Environment variables that would be applied:")
134+
// Only show info message for non-JSON formats
135+
if format != "json" && !quiet {
136+
printer.Info("Environment variables that would be applied:")
137+
}
135138
switch format {
136139
case "env":
137140
return printer.PrintEnvironmentExport(values)

internal/command/sheet.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,14 @@ func (c *SheetCommand) runExport(cmd *cobra.Command, args []string) error {
328328
}
329329

330330
format, _ := cmd.Flags().GetString("format")
331-
printer := output.NewPrinter(output.FormatTable, false)
331+
// Create printer with appropriate format for values export
332+
var printerFormat output.Format
333+
if format == "json" {
334+
printerFormat = output.FormatJSON
335+
} else {
336+
printerFormat = output.FormatTable
337+
}
338+
printer := output.NewPrinter(printerFormat, false)
332339

333340
sheetName := args[0]
334341
cs, err := manager.ConfigSheets.Get(sheetName)

internal/entities/schema.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ func (sm *SchemaManager) Update(nameOrUUID string, updater func(*Schema) error)
142142
// GetByReference loads a schema by reference, handling local:// and remote:// prefixes
143143
func (sm *SchemaManager) GetByReference(schemaRef string) (*Schema, error) {
144144
switch {
145+
case strings.HasPrefix(schemaRef, "#/schemas/"):
146+
// JSON Pointer style reference: #/schemas/{uuid}
147+
uuid := strings.TrimPrefix(schemaRef, "#/schemas/")
148+
return sm.GetByID(uuid)
149+
145150
case strings.HasPrefix(schemaRef, "local://"):
146151
// Local schema reference: local://schema-name
147152
schemaName := strings.TrimPrefix(schemaRef, "local://")

internal/entities/validator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func (v *Validator) ValidateConfigSheet(sheet *ConfigSheet) error {
218218

219219
if sheet.Schema.IsReference() {
220220
// Load referenced schema
221-
schema, err = v.manager.Schemas.Get(sheet.Schema.Ref)
221+
schema, err = v.manager.Schemas.GetByReference(sheet.Schema.Ref)
222222
if err != nil {
223223
return fmt.Errorf("failed to load referenced schema: %w", err)
224224
}

internal/parser/schema.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,16 @@ func (p *SchemaParser) ParseFile(path string) (*SchemaData, error) {
5757
return nil, fmt.Errorf("failed to read file: %w", err)
5858
}
5959

60-
var schemaObj entities.Schema
60+
// Use a temporary struct for unmarshaling that matches the file structure
61+
var fileData struct {
62+
Description string `json:"description" yaml:"description"`
63+
Variables []entities.Variable `json:"variables" yaml:"variables"`
64+
Extends []string `json:"extends" yaml:"extends"`
65+
}
6166

6267
// Try YAML first, then JSON, then dotenv as fallback
63-
if err := yaml.Unmarshal(data, &schemaObj); err != nil {
64-
if err := json.Unmarshal(data, &schemaObj); err != nil {
68+
if err := yaml.Unmarshal(data, &fileData); err != nil {
69+
if err := json.Unmarshal(data, &fileData); err != nil {
6570
// Try parsing as dotenv file as fallback
6671
dotenvParser := NewAnnotatedDotEnvParser()
6772
_, schema, parseErr := dotenvParser.ParseFile(path)
@@ -77,17 +82,19 @@ func (p *SchemaParser) ParseFile(path string) (*SchemaData, error) {
7782
Extends: nil,
7883
}, nil
7984
}
85+
// JSON parsing succeeded
8086
return &SchemaData{
81-
Description: schemaObj.Description,
82-
Variables: schemaObj.Variables,
83-
Extends: schemaObj.Extends,
87+
Description: fileData.Description,
88+
Variables: fileData.Variables,
89+
Extends: fileData.Extends,
8490
}, nil
8591
}
8692

93+
// YAML parsing succeeded
8794
return &SchemaData{
88-
Description: schemaObj.Description,
89-
Variables: schemaObj.Variables,
90-
Extends: schemaObj.Extends,
95+
Description: fileData.Description,
96+
Variables: fileData.Variables,
97+
Extends: fileData.Extends,
9198
}, nil
9299
}
93100

0 commit comments

Comments
 (0)