Updated tests
This commit is contained in:
46
.github/workflows/integration-tests.yml
vendored
46
.github/workflows/integration-tests.yml
vendored
@@ -11,21 +11,6 @@ jobs:
|
|||||||
name: Integration Tests
|
name: Integration Tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:16-alpine
|
|
||||||
env:
|
|
||||||
POSTGRES_USER: relspec
|
|
||||||
POSTGRES_PASSWORD: relspec_test_password
|
|
||||||
POSTGRES_DB: relspec_test
|
|
||||||
ports:
|
|
||||||
- 5432:5432
|
|
||||||
options: >-
|
|
||||||
--health-cmd pg_isready
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -46,6 +31,29 @@ jobs:
|
|||||||
- name: Download dependencies
|
- name: Download dependencies
|
||||||
run: go mod download
|
run: go mod download
|
||||||
|
|
||||||
|
- name: Start PostgreSQL container
|
||||||
|
run: |
|
||||||
|
docker run -d \
|
||||||
|
--name relspec-test-postgres \
|
||||||
|
-e POSTGRES_USER=relspec \
|
||||||
|
-e POSTGRES_PASSWORD=relspec_test_password \
|
||||||
|
-e POSTGRES_DB=relspec_test \
|
||||||
|
-p 5432:5432 \
|
||||||
|
postgres:16-alpine
|
||||||
|
|
||||||
|
- name: Wait for PostgreSQL to be ready
|
||||||
|
run: |
|
||||||
|
echo "Waiting for PostgreSQL to start..."
|
||||||
|
for i in {1..30}; do
|
||||||
|
if docker exec relspec-test-postgres pg_isready -U relspec -d relspec_test > /dev/null 2>&1; then
|
||||||
|
echo "PostgreSQL is ready!"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo "Waiting... ($i/30)"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
sleep 2
|
||||||
|
|
||||||
- name: Install PostgreSQL client
|
- name: Install PostgreSQL client
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -75,8 +83,14 @@ jobs:
|
|||||||
RELSPEC_TEST_PG_CONN: postgres://relspec:relspec_test_password@localhost:5432/relspec_test
|
RELSPEC_TEST_PG_CONN: postgres://relspec:relspec_test_password@localhost:5432/relspec_test
|
||||||
run: make test-integration
|
run: make test-integration
|
||||||
|
|
||||||
|
- name: Stop PostgreSQL container
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
docker stop relspec-test-postgres || true
|
||||||
|
docker rm relspec-test-postgres || true
|
||||||
|
|
||||||
- name: Summary
|
- name: Summary
|
||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
echo "Integration tests completed."
|
echo "Integration tests completed."
|
||||||
echo "PostgreSQL service was running on localhost:5432"
|
echo "PostgreSQL container has been cleaned up."
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -26,7 +26,7 @@ test: test-unit ## Run all unit tests (alias for test-unit)
|
|||||||
|
|
||||||
test-unit: ## Run unit tests (excludes integration tests)
|
test-unit: ## Run unit tests (excludes integration tests)
|
||||||
@echo "Running unit tests..."
|
@echo "Running unit tests..."
|
||||||
$(GOTEST) -v -race -coverprofile=coverage.out -covermode=atomic $$(go list ./... | grep -v '/tests/integration' | grep -v '/pkg/readers/pgsql')
|
$(GOTEST) -v -race -coverprofile=coverage.out -covermode=atomic $$(go list ./... | grep -v '/tests/integration' | grep -v '/tests/assets' | grep -v '/pkg/readers/pgsql')
|
||||||
|
|
||||||
test-integration: ## Run integration tests (requires RELSPEC_TEST_PG_CONN environment variable)
|
test-integration: ## Run integration tests (requires RELSPEC_TEST_PG_CONN environment variable)
|
||||||
@echo "Running integration tests..."
|
@echo "Running integration tests..."
|
||||||
|
|||||||
@@ -382,6 +382,23 @@ func (r *Reader) isRelationship(tag string) bool {
|
|||||||
return strings.Contains(tag, "bun:\"rel:") || strings.Contains(tag, ",rel:")
|
return strings.Contains(tag, "bun:\"rel:") || strings.Contains(tag, ",rel:")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getRelationType extracts the relationship type from a bun tag
|
||||||
|
func (r *Reader) getRelationType(bunTag string) string {
|
||||||
|
if strings.Contains(bunTag, "rel:has-many") {
|
||||||
|
return "has-many"
|
||||||
|
}
|
||||||
|
if strings.Contains(bunTag, "rel:belongs-to") {
|
||||||
|
return "belongs-to"
|
||||||
|
}
|
||||||
|
if strings.Contains(bunTag, "rel:has-one") {
|
||||||
|
return "has-one"
|
||||||
|
}
|
||||||
|
if strings.Contains(bunTag, "rel:many-to-many") {
|
||||||
|
return "many-to-many"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// parseRelationshipConstraints parses relationship fields to extract foreign key constraints
|
// parseRelationshipConstraints parses relationship fields to extract foreign key constraints
|
||||||
func (r *Reader) parseRelationshipConstraints(table *models.Table, structType *ast.StructType, structMap map[string]*models.Table) {
|
func (r *Reader) parseRelationshipConstraints(table *models.Table, structType *ast.StructType, structMap map[string]*models.Table) {
|
||||||
for _, field := range structType.Fields.List {
|
for _, field := range structType.Fields.List {
|
||||||
@@ -409,27 +426,50 @@ func (r *Reader) parseRelationshipConstraints(table *models.Table, structType *a
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse the join information: join:user_id=id
|
// Parse the join information: join:user_id=id
|
||||||
// This means: referencedTable.user_id = thisTable.id
|
// This means: thisTable.user_id = referencedTable.id
|
||||||
joinInfo := r.parseJoinInfo(bunTag)
|
joinInfo := r.parseJoinInfo(bunTag)
|
||||||
if joinInfo == nil {
|
if joinInfo == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// The FK is on the referenced table
|
// Determine which table gets the FK based on relationship type
|
||||||
|
relType := r.getRelationType(bunTag)
|
||||||
|
|
||||||
|
var fkTable *models.Table
|
||||||
|
var fkColumn, refTable, refColumn string
|
||||||
|
|
||||||
|
if relType == "belongs-to" {
|
||||||
|
// For belongs-to: FK is on the current table
|
||||||
|
// join:user_id=id means table.user_id references referencedTable.id
|
||||||
|
fkTable = table
|
||||||
|
fkColumn = joinInfo.ForeignKey
|
||||||
|
refTable = referencedTable.Name
|
||||||
|
refColumn = joinInfo.ReferencedKey
|
||||||
|
} else if relType == "has-many" {
|
||||||
|
// For has-many: FK is on the referenced table
|
||||||
|
// join:id=user_id means referencedTable.user_id references table.id
|
||||||
|
fkTable = referencedTable
|
||||||
|
fkColumn = joinInfo.ReferencedKey
|
||||||
|
refTable = table.Name
|
||||||
|
refColumn = joinInfo.ForeignKey
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
constraint := &models.Constraint{
|
constraint := &models.Constraint{
|
||||||
Name: fmt.Sprintf("fk_%s_%s", referencedTable.Name, table.Name),
|
Name: fmt.Sprintf("fk_%s_%s", fkTable.Name, refTable),
|
||||||
Type: models.ForeignKeyConstraint,
|
Type: models.ForeignKeyConstraint,
|
||||||
Table: referencedTable.Name,
|
Table: fkTable.Name,
|
||||||
Schema: referencedTable.Schema,
|
Schema: fkTable.Schema,
|
||||||
Columns: []string{joinInfo.ForeignKey},
|
Columns: []string{fkColumn},
|
||||||
ReferencedTable: table.Name,
|
ReferencedTable: refTable,
|
||||||
ReferencedSchema: table.Schema,
|
ReferencedSchema: fkTable.Schema,
|
||||||
ReferencedColumns: []string{joinInfo.ReferencedKey},
|
ReferencedColumns: []string{refColumn},
|
||||||
OnDelete: "NO ACTION", // Bun doesn't specify this in tags
|
OnDelete: "NO ACTION", // Bun doesn't specify this in tags
|
||||||
OnUpdate: "NO ACTION",
|
OnUpdate: "NO ACTION",
|
||||||
}
|
}
|
||||||
|
|
||||||
referencedTable.Constraints[constraint.Name] = constraint
|
fkTable.Constraints[constraint.Name] = constraint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user