Refactor code structure for improved readability and maintainability; removed redundant code blocks and optimized function calls.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
using System.Text;
|
||||
using StellaOps.Scanner.Analyzers.Lang;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Deno;
|
||||
using StellaOps.Scanner.Core.Contracts;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Deno.Tests.TestUtilities;
|
||||
|
||||
namespace StellaOps.Scanner.Analyzers.Lang.Deno.Tests.Deno;
|
||||
|
||||
public sealed class DenoLanguageAnalyzerRuntimeTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task IngestsRuntimeTraceAndEmitsSignals()
|
||||
{
|
||||
var root = TestPaths.CreateTemporaryDirectory();
|
||||
try
|
||||
{
|
||||
var runtimePath = Path.Combine(root, "deno-runtime.ndjson");
|
||||
var ndjson = new StringBuilder()
|
||||
.AppendLine("{\"type\":\"deno.module.load\",\"ts\":\"2025-11-18T00:00:00Z\",\"module\":{\"normalized\":\"app/main.ts\",\"path_sha256\":\"abc\"},\"reason\":\"dynamic-import\",\"permissions\":[\"fs\"],\"origin\":\"https://deno.land/x/std@0.208.0/http/server.ts\"}")
|
||||
.AppendLine("{\"type\":\"deno.permission.use\",\"ts\":\"2025-11-18T00:00:01Z\",\"permission\":\"net\",\"module\":{\"normalized\":\"app/net.ts\",\"path_sha256\":\"def\"},\"details\":\"permissions.request\"}")
|
||||
.AppendLine("{\"type\":\"deno.wasm.load\",\"ts\":\"2025-11-18T00:00:02Z\",\"module\":{\"normalized\":\"pkg/module.wasm\",\"path_sha256\":\"ghi\"},\"importer\":\"app/main.ts\",\"reason\":\"instantiate\"}")
|
||||
.AppendLine("{\"type\":\"deno.npm.resolution\",\"ts\":\"2025-11-18T00:00:03Z\",\"specifier\":\"npm:chalk@5\",\"package\":\"chalk\",\"version\":\"5.3.0\",\"resolved\":\"file:///cache/chalk\",\"exists\":true}")
|
||||
.ToString();
|
||||
|
||||
await File.WriteAllTextAsync(runtimePath, ndjson);
|
||||
|
||||
var store = new ScanAnalysisStore();
|
||||
var context = new LanguageAnalyzerContext(root, TimeProvider.System, usageHints: null, services: null, analysisStore: store);
|
||||
|
||||
var analyzer = new DenoLanguageAnalyzer();
|
||||
var engine = new LanguageAnalyzerEngine(new[] { analyzer });
|
||||
await engine.AnalyzeAsync(context, CancellationToken.None);
|
||||
|
||||
Assert.True(store.TryGet(ScanAnalysisKeys.DenoRuntimePayload, out AnalyzerObservationPayload runtimePayload));
|
||||
Assert.Equal("deno.runtime.v1", runtimePayload.Kind);
|
||||
Assert.Equal("application/x-ndjson", runtimePayload.MediaType);
|
||||
|
||||
Assert.True(store.TryGet("surface.lang.deno.permissions", out string? permissions));
|
||||
Assert.Equal("fs,net", permissions);
|
||||
Assert.True(store.TryGet("surface.lang.deno.remote_origins", out string? origins));
|
||||
Assert.Equal("https://deno.land/x/std@0.208.0/http/server.ts", origins);
|
||||
Assert.True(store.TryGet("surface.lang.deno.wasm_modules", out string? wasm));
|
||||
Assert.Equal("1", wasm);
|
||||
Assert.True(store.TryGet("surface.lang.deno.npm_modules", out string? npm));
|
||||
Assert.Equal("1", npm);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TestPaths.SafeDelete(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using StellaOps.Scanner.Analyzers.Lang;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Deno.Internal.Runtime;
|
||||
using StellaOps.Scanner.Analyzers.Lang.Deno.Tests.TestUtilities;
|
||||
|
||||
namespace StellaOps.Scanner.Analyzers.Lang.Deno.Tests.Deno;
|
||||
|
||||
public sealed class DenoRuntimeTraceRunnerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task ReturnsFalse_WhenEntrypointEnvMissing()
|
||||
{
|
||||
using var env = new EnvironmentVariableScope("STELLA_DENO_ENTRYPOINT", null);
|
||||
var root = TestPaths.CreateTemporaryDirectory();
|
||||
|
||||
try
|
||||
{
|
||||
var context = new LanguageAnalyzerContext(root, TimeProvider.System);
|
||||
var result = await DenoRuntimeTraceRunner.TryExecuteAsync(context, logger: null, CancellationToken.None);
|
||||
|
||||
Assert.False(result);
|
||||
Assert.False(File.Exists(Path.Combine(root, "deno-runtime.ndjson")));
|
||||
}
|
||||
finally
|
||||
{
|
||||
TestPaths.SafeDelete(root);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReturnsFalse_WhenEntrypointMissing()
|
||||
{
|
||||
var root = TestPaths.CreateTemporaryDirectory();
|
||||
|
||||
try
|
||||
{
|
||||
using var env = new EnvironmentVariableScope("STELLA_DENO_ENTRYPOINT", "app/main.ts");
|
||||
var context = new LanguageAnalyzerContext(root, TimeProvider.System);
|
||||
|
||||
var result = await DenoRuntimeTraceRunner.TryExecuteAsync(context, logger: null, CancellationToken.None);
|
||||
|
||||
Assert.False(result);
|
||||
Assert.False(File.Exists(Path.Combine(root, DenoRuntimeShim.FileName)));
|
||||
Assert.False(File.Exists(Path.Combine(root, "deno-runtime.ndjson")));
|
||||
}
|
||||
finally
|
||||
{
|
||||
TestPaths.SafeDelete(root);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReturnsFalse_WhenDenoBinaryUnavailable()
|
||||
{
|
||||
var root = TestPaths.CreateTemporaryDirectory();
|
||||
|
||||
try
|
||||
{
|
||||
var entrypoint = Path.Combine(root, "main.ts");
|
||||
await File.WriteAllTextAsync(entrypoint, "console.log('hi')");
|
||||
|
||||
using var entryEnv = new EnvironmentVariableScope("STELLA_DENO_ENTRYPOINT", entrypoint);
|
||||
using var binaryEnv = new EnvironmentVariableScope("STELLA_DENO_BINARY", Guid.NewGuid().ToString("N"));
|
||||
|
||||
var context = new LanguageAnalyzerContext(root, TimeProvider.System);
|
||||
var result = await DenoRuntimeTraceRunner.TryExecuteAsync(context, logger: null, CancellationToken.None);
|
||||
|
||||
Assert.False(result);
|
||||
Assert.True(File.Exists(Path.Combine(root, DenoRuntimeShim.FileName)));
|
||||
}
|
||||
finally
|
||||
{
|
||||
TestPaths.SafeDelete(root);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class EnvironmentVariableScope : IDisposable
|
||||
{
|
||||
private readonly string _name;
|
||||
private readonly string? _original;
|
||||
|
||||
public EnvironmentVariableScope(string name, string? value)
|
||||
{
|
||||
_name = name;
|
||||
_original = Environment.GetEnvironmentVariable(name);
|
||||
Environment.SetEnvironmentVariable(name, value);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Environment.SetEnvironmentVariable(_name, _original);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using StellaOps.Scanner.Analyzers.Lang.Node.Internal;
|
||||
|
||||
namespace StellaOps.Scanner.Analyzers.Lang.Node.Tests.Node;
|
||||
|
||||
public sealed class NodeEntrypointTests
|
||||
{
|
||||
[Fact]
|
||||
public void Create_NormalizesConditions_DedupesAndSorts()
|
||||
{
|
||||
var entry = NodeEntrypoint.Create(
|
||||
path: "src/index.js",
|
||||
binName: "cli",
|
||||
mainField: "index.js",
|
||||
moduleField: null,
|
||||
conditions: new[] { "node", "browser", "node" });
|
||||
|
||||
Assert.Equal("browser,node", entry.ConditionSet);
|
||||
Assert.Equal("src/index.js", entry.Path);
|
||||
Assert.Equal("cli", entry.BinName);
|
||||
Assert.Equal("index.js", entry.MainField);
|
||||
Assert.Null(entry.ModuleField);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_AllowsEmptyConditions()
|
||||
{
|
||||
var entry = NodeEntrypoint.Create("src/app.js", null, null, null, Array.Empty<string>());
|
||||
Assert.Equal(string.Empty, entry.ConditionSet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using FluentAssertions;
|
||||
using StellaOps.Scanner.Emit.Reachability;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Scanner.Emit.Tests.Reachability;
|
||||
|
||||
public class ReachabilityLatticeTests
|
||||
{
|
||||
[Fact]
|
||||
public void StaticPath_YieldsConditional()
|
||||
{
|
||||
var result = ReachabilityLattice.Evaluate(new[]
|
||||
{
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.StaticPath, "path1")
|
||||
});
|
||||
|
||||
result.State.Should().Be(ReachabilityState.Conditional);
|
||||
result.Score.Should().Be(0.5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuntimeHit_PromotesReachableAndAddsBonus()
|
||||
{
|
||||
var result = ReachabilityLattice.Evaluate(new[]
|
||||
{
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.StaticPath),
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.RuntimeHit)
|
||||
});
|
||||
|
||||
result.State.Should().Be(ReachabilityState.Reachable);
|
||||
result.Score.Should().Be(0.8);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RuntimeSinkHit_AddsAdditionalBonus()
|
||||
{
|
||||
var result = ReachabilityLattice.Evaluate(new[]
|
||||
{
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.RuntimeHit),
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.RuntimeSinkHit)
|
||||
});
|
||||
|
||||
result.State.Should().Be(ReachabilityState.Reachable);
|
||||
result.Score.Should().Be(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Guard_DemotesWhenNoRuntimeEvidence()
|
||||
{
|
||||
var result = ReachabilityLattice.Evaluate(new[]
|
||||
{
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.StaticPath),
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.Guard)
|
||||
});
|
||||
|
||||
result.State.Should().Be(ReachabilityState.Unknown);
|
||||
result.Score.Should().Be(0.3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Mitigation_SetsUnreachableWhenNoRuntime()
|
||||
{
|
||||
var result = ReachabilityLattice.Evaluate(new[]
|
||||
{
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.StaticPath),
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.Mitigation)
|
||||
});
|
||||
|
||||
result.State.Should().Be(ReachabilityState.Unreachable);
|
||||
result.Score.Should().Be(0.2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OrderIndependentAndRounded()
|
||||
{
|
||||
var shuffled = new[]
|
||||
{
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.Guard),
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.StaticPath),
|
||||
new ReachabilityEvidence(ReachabilityEvidenceKind.RuntimeHit),
|
||||
};
|
||||
|
||||
var result = ReachabilityLattice.Evaluate(shuffled);
|
||||
|
||||
result.State.Should().Be(ReachabilityState.Reachable);
|
||||
result.Score.Should().Be(0.8);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user