feat: add stella-callgraph-node for JavaScript/TypeScript call graph extraction
- Implemented a new tool `stella-callgraph-node` that extracts call graphs from JavaScript/TypeScript projects using Babel AST. - Added command-line interface with options for JSON output and help. - Included functionality to analyze project structure, detect functions, and build call graphs. - Created a package.json file for dependency management. feat: introduce stella-callgraph-python for Python call graph extraction - Developed `stella-callgraph-python` to extract call graphs from Python projects using AST analysis. - Implemented command-line interface with options for JSON output and verbose logging. - Added framework detection to identify popular web frameworks and their entry points. - Created an AST analyzer to traverse Python code and extract function definitions and calls. - Included requirements.txt for project dependencies. chore: add framework detection for Python projects - Implemented framework detection logic to identify frameworks like Flask, FastAPI, Django, and others based on project files and import patterns. - Enhanced the AST analyzer to recognize entry points based on decorators and function definitions.
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
using FluentAssertions;
|
||||
using StellaOps.Router.Common.Enums;
|
||||
using StellaOps.Router.Common.Models;
|
||||
using StellaOps.Router.Gateway.State;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Router.Gateway.Tests;
|
||||
|
||||
public sealed class InMemoryRoutingStateTests
|
||||
{
|
||||
[Fact]
|
||||
public void ResolveEndpoint_WhenExactMatch_ReturnsEndpointDescriptor()
|
||||
{
|
||||
var routingState = new InMemoryRoutingState();
|
||||
|
||||
var connection = CreateConnection("conn-1", "inventory", "1.0.0", region: "test");
|
||||
connection.Endpoints[("GET", "/items")] = new EndpointDescriptor
|
||||
{
|
||||
ServiceName = "inventory",
|
||||
Version = "1.0.0",
|
||||
Method = "GET",
|
||||
Path = "/items"
|
||||
};
|
||||
|
||||
routingState.AddConnection(connection);
|
||||
|
||||
var resolved = routingState.ResolveEndpoint("GET", "/items");
|
||||
|
||||
resolved.Should().NotBeNull();
|
||||
resolved!.ServiceName.Should().Be("inventory");
|
||||
resolved.Version.Should().Be("1.0.0");
|
||||
resolved.Method.Should().Be("GET");
|
||||
resolved.Path.Should().Be("/items");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveEndpoint_WhenTemplateMatch_ReturnsEndpointDescriptor()
|
||||
{
|
||||
var routingState = new InMemoryRoutingState();
|
||||
|
||||
var connection = CreateConnection("conn-1", "inventory", "1.0.0", region: "test");
|
||||
connection.Endpoints[("GET", "/items/{sku}")] = new EndpointDescriptor
|
||||
{
|
||||
ServiceName = "inventory",
|
||||
Version = "1.0.0",
|
||||
Method = "GET",
|
||||
Path = "/items/{sku}"
|
||||
};
|
||||
|
||||
routingState.AddConnection(connection);
|
||||
|
||||
var resolved = routingState.ResolveEndpoint("GET", "/items/SKU-001");
|
||||
|
||||
resolved.Should().NotBeNull();
|
||||
resolved!.Path.Should().Be("/items/{sku}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemoveConnection_RemovesEndpointsFromIndex()
|
||||
{
|
||||
var routingState = new InMemoryRoutingState();
|
||||
|
||||
var connection = CreateConnection("conn-1", "inventory", "1.0.0", region: "test");
|
||||
connection.Endpoints[("GET", "/items")] = new EndpointDescriptor
|
||||
{
|
||||
ServiceName = "inventory",
|
||||
Version = "1.0.0",
|
||||
Method = "GET",
|
||||
Path = "/items"
|
||||
};
|
||||
|
||||
routingState.AddConnection(connection);
|
||||
routingState.ResolveEndpoint("GET", "/items").Should().NotBeNull();
|
||||
|
||||
routingState.RemoveConnection("conn-1");
|
||||
|
||||
routingState.ResolveEndpoint("GET", "/items").Should().BeNull();
|
||||
routingState.GetAllConnections().Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetConnectionsFor_FiltersByServiceAndVersion()
|
||||
{
|
||||
var routingState = new InMemoryRoutingState();
|
||||
|
||||
var inventoryV1 = CreateConnection("inv-v1", "inventory", "1.0.0", region: "test");
|
||||
inventoryV1.Endpoints[("GET", "/items")] = new EndpointDescriptor
|
||||
{
|
||||
ServiceName = "inventory",
|
||||
Version = "1.0.0",
|
||||
Method = "GET",
|
||||
Path = "/items"
|
||||
};
|
||||
|
||||
var inventoryV2 = CreateConnection("inv-v2", "inventory", "2.0.0", region: "test");
|
||||
inventoryV2.Endpoints[("GET", "/items")] = new EndpointDescriptor
|
||||
{
|
||||
ServiceName = "inventory",
|
||||
Version = "2.0.0",
|
||||
Method = "GET",
|
||||
Path = "/items"
|
||||
};
|
||||
|
||||
routingState.AddConnection(inventoryV1);
|
||||
routingState.AddConnection(inventoryV2);
|
||||
|
||||
var connections = routingState.GetConnectionsFor(
|
||||
serviceName: "inventory",
|
||||
version: "1.0.0",
|
||||
method: "GET",
|
||||
path: "/items");
|
||||
|
||||
connections.Should().HaveCount(1);
|
||||
connections[0].ConnectionId.Should().Be("inv-v1");
|
||||
}
|
||||
|
||||
private static ConnectionState CreateConnection(
|
||||
string connectionId,
|
||||
string serviceName,
|
||||
string version,
|
||||
string region)
|
||||
{
|
||||
return new ConnectionState
|
||||
{
|
||||
ConnectionId = connectionId,
|
||||
Instance = new InstanceDescriptor
|
||||
{
|
||||
InstanceId = connectionId,
|
||||
ServiceName = serviceName,
|
||||
Version = version,
|
||||
Region = region
|
||||
},
|
||||
Status = InstanceHealthStatus.Healthy,
|
||||
LastHeartbeatUtc = DateTime.UtcNow,
|
||||
TransportType = TransportType.InMemory
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user