Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Added Deno analyzer with comprehensive metadata and evidence structure. - Created a detailed implementation plan for Sprint 130 focusing on Deno analyzer. - Introduced AdvisoryAiGuardrailOptions for managing guardrail configurations. - Developed GuardrailPhraseLoader for loading blocked phrases from JSON files. - Implemented tests for AdvisoryGuardrailOptions binding and phrase loading. - Enhanced telemetry for Advisory AI with metrics tracking. - Added VexObservationProjectionService for querying VEX observations. - Created extensive tests for VexObservationProjectionService functionality. - Introduced Ruby language analyzer with tests for simple and complex workspaces. - Added Ruby application fixtures for testing purposes.
90 lines
3.9 KiB
C#
90 lines
3.9 KiB
C#
using System.Text.Json;
|
|
using StellaOps.Scanner.Analyzers.Lang;
|
|
using StellaOps.Scanner.Analyzers.Lang.Ruby;
|
|
using StellaOps.Scanner.Analyzers.Lang.Tests.Harness;
|
|
using StellaOps.Scanner.Analyzers.Lang.Tests.TestUtilities;
|
|
using StellaOps.Scanner.Core.Contracts;
|
|
|
|
namespace StellaOps.Scanner.Analyzers.Lang.Ruby.Tests;
|
|
|
|
public sealed class RubyLanguageAnalyzerTests
|
|
{
|
|
[Fact]
|
|
public async Task SimpleWorkspaceProducesDeterministicOutputAsync()
|
|
{
|
|
var fixturePath = TestPaths.ResolveFixture("lang", "ruby", "simple-app");
|
|
var goldenPath = Path.Combine(fixturePath, "expected.json");
|
|
var analyzers = new ILanguageAnalyzer[] { new RubyLanguageAnalyzer() };
|
|
|
|
await LanguageAnalyzerTestHarness.AssertDeterministicAsync(
|
|
fixturePath,
|
|
goldenPath,
|
|
analyzers,
|
|
TestContext.Current.CancellationToken);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task AnalyzerEmitsObservationPayloadWithSummaryAsync()
|
|
{
|
|
var fixturePath = TestPaths.ResolveFixture("lang", "ruby", "simple-app");
|
|
var store = new ScanAnalysisStore();
|
|
var analyzers = new ILanguageAnalyzer[] { new RubyLanguageAnalyzer() };
|
|
var engine = new LanguageAnalyzerEngine(analyzers);
|
|
var context = new LanguageAnalyzerContext(
|
|
fixturePath,
|
|
TimeProvider.System,
|
|
usageHints: null,
|
|
services: null,
|
|
analysisStore: store);
|
|
|
|
var result = await engine.AnalyzeAsync(context, TestContext.Current.CancellationToken);
|
|
var snapshots = result.ToSnapshots();
|
|
|
|
var summary = Assert.Single(snapshots, snapshot => snapshot.Type == "ruby-observation");
|
|
Assert.Equal("Ruby Observation Summary", summary.Name);
|
|
Assert.Equal("observation::ruby", summary.ComponentKey);
|
|
Assert.True(summary.Metadata.TryGetValue("ruby.observation.packages", out var packageCount));
|
|
Assert.Equal("11", packageCount);
|
|
Assert.Equal("3", summary.Metadata["ruby.observation.runtime_edges"]);
|
|
Assert.Equal("true", summary.Metadata["ruby.observation.capability.exec"]);
|
|
Assert.Equal("true", summary.Metadata["ruby.observation.capability.net"]);
|
|
Assert.Equal("true", summary.Metadata["ruby.observation.capability.serialization"]);
|
|
Assert.Equal("2.4.22", summary.Metadata["ruby.observation.bundler_version"]);
|
|
|
|
Assert.True(store.TryGet(ScanAnalysisKeys.RubyObservationPayload, out AnalyzerObservationPayload payload));
|
|
Assert.Equal("ruby", payload.AnalyzerId);
|
|
Assert.Equal("ruby.observation", payload.Kind);
|
|
Assert.Equal("application/json", payload.MediaType);
|
|
Assert.NotNull(payload.Metadata);
|
|
Assert.Equal("11", payload.Metadata!["ruby.observation.packages"]);
|
|
|
|
using var document = JsonDocument.Parse(payload.Content.ToArray());
|
|
var root = document.RootElement;
|
|
var packages = root.GetProperty("packages");
|
|
Assert.Equal(11, packages.GetArrayLength());
|
|
|
|
var runtimeEdges = root.GetProperty("runtimeEdges");
|
|
Assert.True(runtimeEdges.GetArrayLength() >= 1);
|
|
|
|
var capabilities = root.GetProperty("capabilities");
|
|
Assert.True(capabilities.GetProperty("usesExec").GetBoolean());
|
|
Assert.True(capabilities.GetProperty("usesNetwork").GetBoolean());
|
|
Assert.True(capabilities.GetProperty("usesSerialization").GetBoolean());
|
|
Assert.Equal("2.4.22", root.GetProperty("bundledWith").GetString());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ComplexWorkspaceProducesDeterministicOutputAsync()
|
|
{
|
|
var fixturePath = TestPaths.ResolveFixture("lang", "ruby", "complex-app");
|
|
var goldenPath = Path.Combine(fixturePath, "expected.json");
|
|
var analyzers = new ILanguageAnalyzer[] { new RubyLanguageAnalyzer() };
|
|
|
|
await LanguageAnalyzerTestHarness.AssertDeterministicAsync(
|
|
fixturePath,
|
|
goldenPath,
|
|
analyzers,
|
|
TestContext.Current.CancellationToken);
|
|
}
|
|
}
|