routing

package
v0.0.0-...-b6ec08b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2026 License: CC0-1.0 Imports: 9 Imported by: 0

README

Test Routing Framework

This package provides utilities for testing HTTP route registration in microservices.

Overview

The routing package includes tools to:

  • Validate route registration (method + path)
  • Verify HTTP method support
  • Extract and validate path parameters
  • Compare expected vs. actual routes
  • Generate route expectations from WADL files

Components

RouteValidator

Core validator for route registration verification.

validator := routing.NewRouteValidator(mux)
validator.RegisterRoute("GET", "/bill")
validator.RegisterRoute("POST", "/bill/{id1}/ca/{id2}")

// Assert routes exist
all := validator.AssertAllRoutesExist(expectations)
count := validator.GetRegisteredCount()
HTTPMethodValidator

Validates HTTP method support for routes.

methods := routing.NewHTTPMethodValidator()
methods.AddSupportedMethod("/bill", "GET")
methods.AddSupportedMethod("/bill", "POST")

// Check if method is supported
supported := methods.IsSupportedMethod("/bill", "GET")
PathParameterValidator

Extracts and validates path parameters.

params := routing.NewPathParameterValidator()
params.AddPathPattern("/bill/{id1}/ca/{id2}", []string{"id1", "id2"})

// Extract parameters from path
extracted := params.ExtractParameterNames("/bill/{id1}/ca/{id2}")
// Returns: ["id1", "id2"]
MuxInspector

Inspects HTTP mux for registered routes.

inspector := routing.NewMuxInspector(mux)

// Discover routes by testing patterns
discovered := inspector.DiscoverRoutes(testPaths)

// Test individual routes
status, _ := inspector.TestRequest("GET", "/bill")
matched := inspector.AssertRouteMatchesMethod("GET", "/bill")
TestHelper

Convenience wrapper combining all validators.

helper := routing.NewTestHelper(mux)
helper.RegisterExpectedRoute("GET", "/bill")
helper.RegisterExpectedRoute("POST", "/bill/{id1}/ca/{id2}")

// Get summary
summary := helper.GetSummary(expectations)
RouteTestBuilder

Fluent API for constructing test scenarios.

builder := routing.NewRouteTestBuilder()
builder.
    AddRoutes([]string{"GET", "POST"}, []string{"/bill", "/ca"}).
    WithParameters("/bill/{id1}", []string{"id1"})

expectations, methods, params := builder.Build()

Usage Patterns

Basic Route Testing
func TestBillRoutes(t *testing.T) {
    // Create expected routes
    expectations := []routing.RouteExpectation{
        {Method: "GET", Path: "/bill"},
        {Method: "POST", Path: "/bill/{id1}"},
        {Method: "DELETE", Path: "/bill/{id1}"},
    }
    
    // Create test helper
    helper := routing.NewTestHelper(mux)
    helper.RegisterExpectedRoutes(expectations)
    
    // Verify all routes exist
    all, missing := helper.AssertAllRoutesExist(expectations)
    if !all {
        t.Errorf("Missing routes: %v", missing)
    }
}
Path Parameter Testing
func TestPathParameters(t *testing.T) {
    helper := routing.NewTestHelper(mux)
    
    path := "/bill/{id1}/ca/{id2}"
    expected := []string{"id1", "id2"}
    
    valid := helper.VerifyPathParameters(path, expected)
    if !valid {
        t.Errorf("Path parameters invalid for %s", path)
    }
}
HTTP Method Testing
func TestHTTPMethods(t *testing.T) {
    inspector := routing.NewMuxInspector(mux)
    
    tests := []struct {
        method string
        path   string
        expect bool
    }{
        {"GET", "/bill", true},
        {"POST", "/bill", true},
        {"PATCH", "/bill", false}, // Not supported
    }
    
    for _, test := range tests {
        matched := inspector.AssertRouteMatchesMethod(test.method, test.path)
        if matched != test.expect {
            t.Errorf("%s %s: expected %v, got %v", 
                test.method, test.path, test.expect, matched)
        }
    }
}

Route Expectation Format

Routes are specified as RouteExpectation structs:

type RouteExpectation struct {
    Method string // HTTP method: GET, POST, PUT, DELETE, HEAD
    Path   string // URL path: /bill, /bill/{id1}, /bill/{id1}/ca/{id2}
}

Path Parameter Syntax

Path parameters use standard Go mux syntax with braces:

  • Single parameter: /bill/{id1}
  • Multiple parameters: /bill/{id1}/ca/{id2}/bp/{id3}
  • Parameter names are typically numeric: {id1}, {id2}, {id3}

Common Test Patterns

Verify All Routes Count
count, registered, expected := helper.AssertRouteCount(expectations)
if !count {
    t.Errorf("Route count mismatch: got %d, expected %d", registered, expected)
}
Get Test Summary
summary := helper.GetSummary(expectations)
fmt.Printf("Expected: %d, Registered: %d, Missing: %d\n",
    summary.TotalExpected,
    summary.TotalRegistered,
    summary.MissingCount)
Test with Builder
builder := routing.NewRouteTestBuilder()
builder.AddPath("/bill").     // Adds all 4 HTTP verbs
        AddPath("/ca").
        WithParameters("/bill/{id1}", []string{"id1"})

expectations := builder.GetExpectations()

Integration with Service Tests

Each microservice test file uses this framework:

  1. Create RouteExpectation list from WADL expectations
  2. Create TestHelper with service mux
  3. Register expected routes
  4. Assert all routes exist and counts match
  5. Test HTTP methods and path parameters

Example: cmd/Bill/bill_route_registration_test.go

package main

import (
    "testing"
    "github.com/Tylores/egot/test/routing"
)

func TestBillRouteRegistration(t *testing.T) {
    mux := http.NewServeMux()
    registerBillRoutes(mux, &BillHandler{})
    
    expectations := []routing.RouteExpectation{
        {Method: "GET", Path: "/bill"},
        // ... 69 more routes from WADL
    }
    
    helper := routing.NewTestHelper(mux)
    helper.RegisterExpectedRoutes(expectations)
    
    all, missing := helper.AssertAllRoutesExist(expectations)
    if !all {
        t.Fatalf("Missing %d routes", len(missing))
    }
}

Troubleshooting

Routes Not Found
  1. Verify route path matches exactly (case-sensitive)
  2. Check HTTP method is uppercase: GET, POST, PUT, DELETE
  3. Ensure path parameters use correct syntax: {paramName}
Test Failures
  1. Get route summary: fmt.Printf("%v", helper.GetSummary(expectations))
  2. Check for duplicate routes: Use inspector.GetRegisteredRoutes()
  3. Compare expected vs. actual: result := inspector.CompareRoutes(...)
Parameter Issues
  1. Extract parameters: params := helper.ExtractPathParameters(path)
  2. Verify pattern: valid := helper.AssertPathHasParameters(path)
  3. Check parameter names match WADL: expected := []string{"id1", "id2", "id3"}

Testing Checklist

  • All routes from WADL are registered
  • Route count matches WADL resource count
  • HTTP methods match WADL definitions
  • Path parameters are correctly extracted
  • No duplicate routes
  • No unexpected extra routes

See Also

  • WADL_RESTORATION_INDEX.md - Route generation from WADL
  • TEST_ROUTING_GUIDE.md - Comprehensive testing guide
  • Service test files: cmd/<Service>/<Service>_route_registration_test.go

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatRoute

func FormatRoute(route ExtractedRoute) string

FormatRoute formats a route as "METHOD /path".

func FormatRoutes

func FormatRoutes(routes []ExtractedRoute) string

FormatRoutes formats multiple routes, one per line.

func GetMethodsForPath

func GetMethodsForPath(routes []RouteExpectation, path string) []string

GetMethodsForPath returns all methods for a specific path.

func GetPathCount

func GetPathCount(routes []ExtractedRoute) int

GetPathCount returns the count of unique paths (regardless of method).

func GetPathsForMethod

func GetPathsForMethod(routes []RouteExpectation, method string) []string

GetPathsForMethod returns all paths for a specific method.

func GetRouteCount

func GetRouteCount(routes []ExtractedRoute) int

GetRouteCount returns the count of unique routes.

func GroupRoutesByMethod

func GroupRoutesByMethod(routes []RouteExpectation) map[string][]RouteExpectation

GroupRoutesByMethod groups routes by their HTTP method.

func GroupRoutesByPath

func GroupRoutesByPath(routes []ExtractedRoute) map[string][]string

GroupRoutesByPath groups routes by their path. Returns map: path -> []methods

func ValidateRoutes

func ValidateRoutes(routes []ExtractedRoute) (bool, []string)

ValidateRoutes checks for common issues in extracted routes. Returns (valid bool, errors []string)

Types

type ComparisonResult

type ComparisonResult struct {
	Total         int
	Registered    int
	MissingCount  int
	ExtraCount    int
	Routes        []string
	MissingRoutes []string
	ExtraRoutes   []string
}

ComparisonResult holds the result of comparing expected vs actual routes.

type ExtractedRoute

type ExtractedRoute struct {
	Method string // HTTP method (GET, POST, PUT, DELETE)
	Path   string // URL path
}

ExtractedRoute represents an extracted route from WADL.

func DeduplicateRoutes

func DeduplicateRoutes(routes []ExtractedRoute) []ExtractedRoute

DeduplicateRoutes removes duplicate routes.

func SortRoutes

func SortRoutes(routes []ExtractedRoute) []ExtractedRoute

SortRoutes sorts routes for consistent output. Sorts by: method (alphabetically), then path (alphabetically).

type HTTPMethodTestCase

type HTTPMethodTestCase struct {
	Method            string
	Path              string
	ExpectedSupported bool
	Description       string
}

HTTPMethodTestCase represents a test case for HTTP method verification.

func GenerateHTTPMethodTestCases

func GenerateHTTPMethodTestCases(routes []RouteExpectation) []HTTPMethodTestCase

GenerateHTTPMethodTestCases creates test cases from route expectations.

type HTTPMethodValidator

type HTTPMethodValidator struct {
	// contains filtered or unexported fields
}

HTTPMethodValidator validates HTTP method support for routes.

func NewHTTPMethodValidator

func NewHTTPMethodValidator() *HTTPMethodValidator

NewHTTPMethodValidator creates a new HTTPMethodValidator.

func (*HTTPMethodValidator) AddSupportedMethod

func (hmv *HTTPMethodValidator) AddSupportedMethod(path, method string)

AddSupportedMethod marks a method as supported for a path.

func (*HTTPMethodValidator) GetSupportedMethods

func (hmv *HTTPMethodValidator) GetSupportedMethods(path string) []string

GetSupportedMethods returns all supported methods for a path.

func (*HTTPMethodValidator) IsSupportedMethod

func (hmv *HTTPMethodValidator) IsSupportedMethod(path, method string) bool

IsSupportedMethod checks if a method is supported for a path.

type MuxInspector

type MuxInspector struct {
	// contains filtered or unexported fields
}

MuxInspector provides utilities for inspecting HTTP mux route registrations.

func NewMuxInspector

func NewMuxInspector(mux *http.ServeMux) *MuxInspector

NewMuxInspector creates a new MuxInspector for analyzing a mux.

func (*MuxInspector) AssertRouteMatchesMethod

func (mi *MuxInspector) AssertRouteMatchesMethod(method, path string) bool

AssertRouteMatchesMethod verifies that a route is registered for a specific method. Returns true if the route matches the method.

func (*MuxInspector) AssertUnsupportedMethod

func (mi *MuxInspector) AssertUnsupportedMethod(method, path string) bool

AssertUnsupportedMethod verifies that a method is NOT supported (should return 405 or similar). Returns true if the method is not supported.

func (*MuxInspector) CompareRoutes

func (mi *MuxInspector) CompareRoutes(expectations []RouteExpectation, testPaths []string) ComparisonResult

CompareRoutes compares expected routes vs discovered routes.

func (*MuxInspector) DiscoverRoutes

func (mi *MuxInspector) DiscoverRoutes(testPaths []string) []RouteInfo

DiscoverRoutes attempts to discover registered routes by testing common patterns. This is a heuristic approach since ServeMux doesn't expose registered routes directly. Returns a list of discovered routes.

func (*MuxInspector) GetRegisteredCount

func (mi *MuxInspector) GetRegisteredCount() int

GetRegisteredCount returns the number of discovered routes.

func (*MuxInspector) GetRegisteredRoutes

func (mi *MuxInspector) GetRegisteredRoutes() []RouteInfo

GetRegisteredRoutes returns all discovered registered routes.

func (*MuxInspector) TestPathWithParameters

func (mi *MuxInspector) TestPathWithParameters(method, pathPattern string, paramValues map[string]string) (int, error)

TestPathWithParameters tests a path with actual parameter values. Example: "/bill/{id1}" becomes "/bill/123"

func (*MuxInspector) TestRequest

func (mi *MuxInspector) TestRequest(method, path string) (int, error)

TestRequest performs an HTTP request and returns matched status.

func (*MuxInspector) TestRoute

func (mi *MuxInspector) TestRoute(method, path string) bool

TestRoute attempts to match a route and returns whether it matched.

func (*MuxInspector) VerifyRoutesRegistered

func (mi *MuxInspector) VerifyRoutesRegistered(expectations []RouteExpectation, testPaths []string) (bool, []string, []string)

VerifyRoutesRegistered checks if all expected routes are registered. Returns (allRegistered bool, missing []string, registered []string)

type ParameterizedPathTester

type ParameterizedPathTester struct {
	// contains filtered or unexported fields
}

ParameterizedPathTester helps test paths with parameters.

func NewParameterizedPathTester

func NewParameterizedPathTester(mux *http.ServeMux) *ParameterizedPathTester

NewParameterizedPathTester creates a new ParameterizedPathTester.

func (*ParameterizedPathTester) TestPathPattern

func (ppt *ParameterizedPathTester) TestPathPattern(method, pathPattern string, paramSets []map[string]string) (bool, []PathTestResult)

TestPathPattern tests a path pattern with multiple parameter sets. Returns (allMatched bool, results []PathTestResult)

type PathParameterValidator

type PathParameterValidator struct {
	// contains filtered or unexported fields
}

PathParameterValidator validates path parameters.

func NewPathParameterValidator

func NewPathParameterValidator() *PathParameterValidator

NewPathParameterValidator creates a new PathParameterValidator.

func (*PathParameterValidator) AddPathPattern

func (ppv *PathParameterValidator) AddPathPattern(path string, paramNames []string)

AddPathPattern registers a path pattern with its parameter names. Example: "/bill/{id1}/ca/{id2}" with ["id1", "id2"]

func (*PathParameterValidator) ExtractParameterNames

func (ppv *PathParameterValidator) ExtractParameterNames(path string) []string

ExtractParameterNames extracts parameter names from a path. Example: "/bill/{id1}/ca/{id2}" returns ["id1", "id2"]

func (*PathParameterValidator) GetPathParameters

func (ppv *PathParameterValidator) GetPathParameters(path string) []string

GetPathParameters returns registered parameters for a path.

func (*PathParameterValidator) HasPathParameters

func (ppv *PathParameterValidator) HasPathParameters(path string) bool

HasPathParameters checks if a path has parameters.

func (*PathParameterValidator) VerifyPathPattern

func (ppv *PathParameterValidator) VerifyPathPattern(path string) (bool, []string)

VerifyPathPattern checks if a path matches the expected pattern.

type PathTestResult

type PathTestResult struct {
	Index   int
	Path    string
	Params  map[string]string
	Matched bool
}

PathTestResult holds the result of a single parametrized path test.

type RequestLogger

type RequestLogger struct {
	// contains filtered or unexported fields
}

RequestLogger provides detailed logging of HTTP requests for debugging.

func NewRequestLogger

func NewRequestLogger(output io.Writer) *RequestLogger

NewRequestLogger creates a new RequestLogger.

func (*RequestLogger) LogRequest

func (rl *RequestLogger) LogRequest(req *http.Request, response *http.Response)

LogRequest logs details about an HTTP request.

type RouteExpectation

type RouteExpectation struct {
	Method string // HTTP method (GET, POST, PUT, DELETE, etc.)
	Path   string // URL path (e.g., "/bill", "/bill/{id1}")
}

RouteExpectation represents an expected HTTP route.

func ExtractRoutesToExpectations

func ExtractRoutesToExpectations(routes []ExtractedRoute) []RouteExpectation

ExtractRoutesToExpectations converts extracted routes to RouteExpectation format.

func LoadTestData

func LoadTestData(fileName string) ([]RouteExpectation, error)

LoadTestData loads route expectations from a JSON test data file.

func LoadTestDataByServiceName

func LoadTestDataByServiceName(serviceName string) ([]RouteExpectation, error)

LoadTestDataByServiceName loads test data using service name. Handles special naming conventions.

type RouteInfo

type RouteInfo struct {
	Method  string
	Path    string
	Handler http.Handler
	Matched bool // Whether a test request matched this route
}

RouteInfo contains information about a registered route.

type RouteTestBuilder

type RouteTestBuilder struct {
	// contains filtered or unexported fields
}

RouteTestBuilder helps construct complex route test scenarios.

func NewRouteTestBuilder

func NewRouteTestBuilder() *RouteTestBuilder

NewRouteTestBuilder creates a new RouteTestBuilder.

func (*RouteTestBuilder) AddPath

func (rtb *RouteTestBuilder) AddPath(path string) *RouteTestBuilder

AddPath adds all HTTP methods for a path.

func (*RouteTestBuilder) AddRoute

func (rtb *RouteTestBuilder) AddRoute(method, path string) *RouteTestBuilder

AddRoute adds a single route to the builder.

func (*RouteTestBuilder) AddRoutes

func (rtb *RouteTestBuilder) AddRoutes(methods []string, paths []string) *RouteTestBuilder

AddRoutes adds multiple routes with the same methods.

func (*RouteTestBuilder) Build

func (rtb *RouteTestBuilder) Build() ([]RouteExpectation, map[string][]string, map[string][]string)

Build returns the constructed expectations and metadata.

func (*RouteTestBuilder) Count

func (rtb *RouteTestBuilder) Count() int

Count returns the total number of routes.

func (*RouteTestBuilder) GetExpectations

func (rtb *RouteTestBuilder) GetExpectations() []RouteExpectation

GetExpectations returns the expectations slice.

func (*RouteTestBuilder) WithParameters

func (rtb *RouteTestBuilder) WithParameters(path string, paramNames []string) *RouteTestBuilder

WithParameters associates parameter names with a path.

type RouteValidator

type RouteValidator struct {
	// contains filtered or unexported fields
}

RouteValidator provides methods for validating route registration.

func NewRouteValidator

func NewRouteValidator(mux *http.ServeMux) *RouteValidator

NewRouteValidator creates a new RouteValidator for a given mux.

func (*RouteValidator) AssertAllRoutesExist

func (rv *RouteValidator) AssertAllRoutesExist(expectations []RouteExpectation) []string

AssertAllRoutesExist checks if all expected routes are registered. Returns a list of missing routes, or empty slice if all exist.

func (*RouteValidator) AssertRouteExists

func (rv *RouteValidator) AssertRouteExists(method, path string) bool

AssertRouteExists checks if a route is registered. Returns true if the route exists, false otherwise.

func (*RouteValidator) GetAllRoutes

func (rv *RouteValidator) GetAllRoutes() []string

GetAllRoutes returns a list of all registered routes.

func (*RouteValidator) GetExpectedCount

func (rv *RouteValidator) GetExpectedCount() int

GetExpectedCount returns the total number of expected routes from last verification.

func (*RouteValidator) GetRegisteredCount

func (rv *RouteValidator) GetRegisteredCount() int

GetRegisteredCount returns the total number of registered routes.

func (*RouteValidator) HasDuplicates

func (rv *RouteValidator) HasDuplicates() bool

HasDuplicates checks if there are any duplicate routes. Returns true if duplicates found.

func (*RouteValidator) RegisterRoute

func (rv *RouteValidator) RegisterRoute(method, path string)

RegisterRoute marks a route as expected to be registered. This is typically called during test setup to populate expected routes.

func (*RouteValidator) VerifyRouteCount

func (rv *RouteValidator) VerifyRouteCount(expectations []RouteExpectation) (bool, int, int)

VerifyRouteCount ensures the number of registered routes matches expectations. Returns (matches bool, registered int, expected int)

type TestHelper

type TestHelper struct {
	// contains filtered or unexported fields
}

TestHelper provides common utility functions for route testing.

func NewTestHelper

func NewTestHelper(mux *http.ServeMux) *TestHelper

NewTestHelper creates a new TestHelper for a given mux.

func (*TestHelper) AssertAllRoutesExist

func (th *TestHelper) AssertAllRoutesExist(expectations []RouteExpectation) (bool, []string)

AssertAllRoutesExist verifies all expected routes are registered. Returns (allExist bool, missingRoutes []string)

func (*TestHelper) AssertMethodSupported

func (th *TestHelper) AssertMethodSupported(method, path string) bool

AssertMethodSupported verifies a specific HTTP method is supported for a path.

func (*TestHelper) AssertPathHasParameters

func (th *TestHelper) AssertPathHasParameters(path string) bool

AssertPathHasParameters checks if a path has parameter placeholders.

func (*TestHelper) AssertRouteCount

func (th *TestHelper) AssertRouteCount(expectations []RouteExpectation) (bool, int, int)

AssertRouteCount verifies the count of registered routes matches expectations. Returns (matches bool, registered int, expected int)

func (*TestHelper) ExtractPathParameters

func (th *TestHelper) ExtractPathParameters(path string) []string

ExtractPathParameters extracts parameter names from a path.

func (*TestHelper) GetSummary

func (th *TestHelper) GetSummary(expectations []RouteExpectation) TestSummary

GetSummary returns a test summary for all routes.

func (*TestHelper) RegisterExpectedRoute

func (th *TestHelper) RegisterExpectedRoute(method, path string)

RegisterExpectedRoute adds an expected route to the test helper.

func (*TestHelper) RegisterExpectedRoutes

func (th *TestHelper) RegisterExpectedRoutes(expectations []RouteExpectation)

RegisterExpectedRoutes adds multiple expected routes at once.

func (*TestHelper) VerifyPathParameters

func (th *TestHelper) VerifyPathParameters(path string, expectedParams []string) bool

VerifyPathParameters checks if a path has the expected parameters. Returns (valid bool, expectedParams []string)

type TestSummary

type TestSummary struct {
	TotalExpected   int
	TotalRegistered int
	MissingCount    int
	Routes          []string
	Missing         []string
}

TestSummary holds summary information about route testing.

func (TestSummary) String

func (ts TestSummary) String() string

String returns a formatted string representation of the summary.

type UnsupportedMethodTestCase

type UnsupportedMethodTestCase struct {
	Method      string
	Path        string
	Description string
}

UnsupportedMethodTestCase represents a test for unsupported methods.

func GenerateUnsupportedMethodTestCases

func GenerateUnsupportedMethodTestCases(routes []RouteExpectation) []UnsupportedMethodTestCase

GenerateUnsupportedMethodTestCases creates negative test cases.

type WADLApplication

type WADLApplication struct {
	XMLName   xml.Name       `xml:"application"`
	Resources []WADLResource `xml:"resources>resource"`
}

WADLApplication is the root WADL element.

type WADLExtractor

type WADLExtractor struct {
	// contains filtered or unexported fields
}

WADLExtractor extracts routes from WADL files.

func NewWADLExtractor

func NewWADLExtractor(wadlDir string) *WADLExtractor

NewWADLExtractor creates a new WADLExtractor for a wadl directory.

func (*WADLExtractor) ExtractRoutesFromFile

func (we *WADLExtractor) ExtractRoutesFromFile(fileName string) ([]ExtractedRoute, error)

ExtractRoutesFromFile extracts routes from a single WADL file.

func (*WADLExtractor) ExtractRoutesFromServiceWADL

func (we *WADLExtractor) ExtractRoutesFromServiceWADL(serviceName string) ([]ExtractedRoute, error)

ExtractRoutesFromServiceWADL extracts routes for a specific service. Service name is used to find the WADL file (e.g., "Bill" -> "bill.wadl").

type WADLMethod

type WADLMethod struct {
	ID   string `xml:"id,attr"`
	Name string `xml:"name,attr"`
}

WADLMethod represents a WADL method element.

type WADLResource

type WADLResource struct {
	ID         string         `xml:"id,attr"`
	Path       string         `xml:"path,attr"`
	SamplePath string         `xml:"samplePath,attr"`
	Methods    []WADLMethod   `xml:"method"`
	Resources  []WADLResource `xml:"resource"`
}

WADLResource represents a WADL resource element.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL