Files
git.stella-ops.org/src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Decompiler.Tests/CodeNormalizerTests.cs
StellaOps Bot 37e11918e0 save progress
2026-01-06 09:42:20 +02:00

202 lines
5.4 KiB
C#

// Copyright (c) StellaOps. All rights reserved.
// Licensed under AGPL-3.0-or-later. See LICENSE in the project root.
using StellaOps.BinaryIndex.Decompiler;
using Xunit;
namespace StellaOps.BinaryIndex.Decompiler.Tests;
[Trait("Category", "Unit")]
public sealed class CodeNormalizerTests
{
private readonly CodeNormalizer _normalizer = new();
[Fact]
public void Normalize_WithWhitespace_NormalizesWhitespace()
{
// Arrange
var code = "int x = 1;";
var options = new NormalizationOptions { NormalizeWhitespace = true };
// Act
var normalized = _normalizer.Normalize(code, options);
// Assert
Assert.DoesNotContain(" ", normalized);
}
[Fact]
public void Normalize_WithVariables_NormalizesVariableNames()
{
// Arrange
var code = "int myVar = 1; int otherVar = myVar;";
var options = new NormalizationOptions { NormalizeVariables = true };
// Act
var normalized = _normalizer.Normalize(code, options);
// Assert
// Original variable names should be replaced with canonical names
Assert.DoesNotContain("myVar", normalized);
Assert.DoesNotContain("otherVar", normalized);
Assert.Contains("var_", normalized);
}
[Fact]
public void Normalize_WithConstants_NormalizesLargeNumbers()
{
// Arrange
var code = "int x = 1234567890;";
var options = new NormalizationOptions { NormalizeConstants = true };
// Act
var normalized = _normalizer.Normalize(code, options);
// Assert
Assert.DoesNotContain("1234567890", normalized);
}
[Fact]
public void Normalize_PreservesKeywords_DoesNotRenameKeywords()
{
// Arrange
var code = "int foo() { return 1; }";
var options = new NormalizationOptions { NormalizeVariables = true };
// Act
var normalized = _normalizer.Normalize(code, options);
// Assert
Assert.Contains("return", normalized);
Assert.Contains("int", normalized);
}
[Fact]
public void Normalize_PreservesStandardLibraryFunctions()
{
// Arrange
var code = "printf(\"hello\"); malloc(100); free(ptr);";
var options = new NormalizationOptions { NormalizeFunctionCalls = true };
// Act
var normalized = _normalizer.Normalize(code, options);
// Assert
Assert.Contains("printf", normalized);
Assert.Contains("malloc", normalized);
Assert.Contains("free", normalized);
}
[Fact]
public void ComputeCanonicalHash_SameCode_ReturnsSameHash()
{
// Arrange
var code1 = "int foo() { return 1; }";
var code2 = "int foo() { return 1; }";
// Act
var hash1 = _normalizer.ComputeCanonicalHash(code1);
var hash2 = _normalizer.ComputeCanonicalHash(code2);
// Assert
Assert.Equal(hash1, hash2);
}
[Fact]
public void ComputeCanonicalHash_DifferentWhitespace_ReturnsSameHash()
{
// Arrange
var code1 = "int foo(){return 1;}";
var code2 = "int foo() { return 1; }";
// Act
var hash1 = _normalizer.ComputeCanonicalHash(code1);
var hash2 = _normalizer.ComputeCanonicalHash(code2);
// Assert
Assert.Equal(hash1, hash2);
}
[Fact]
public void ComputeCanonicalHash_DifferentVariableNames_ReturnsSameHash()
{
// Arrange
var code1 = "int foo(int x) { return x + 1; }";
var code2 = "int foo(int y) { return y + 1; }";
// Act
var hash1 = _normalizer.ComputeCanonicalHash(code1);
var hash2 = _normalizer.ComputeCanonicalHash(code2);
// Assert
Assert.Equal(hash1, hash2);
}
[Fact]
public void ComputeCanonicalHash_DifferentLogic_ReturnsDifferentHash()
{
// Arrange
var code1 = "int foo(int x) { return x + 1; }";
var code2 = "int foo(int x) { return x - 1; }";
// Act
var hash1 = _normalizer.ComputeCanonicalHash(code1);
var hash2 = _normalizer.ComputeCanonicalHash(code2);
// Assert
Assert.NotEqual(hash1, hash2);
}
[Fact]
public void ComputeCanonicalHash_Returns32Bytes()
{
// Arrange
var code = "int foo() { return 1; }";
// Act
var hash = _normalizer.ComputeCanonicalHash(code);
// Assert (SHA256 = 32 bytes)
Assert.Equal(32, hash.Length);
}
[Fact]
public void Normalize_RemovesComments()
{
// Arrange
var code = @"
int foo() {
// This is a comment
return 1; /* inline comment */
}";
var options = NormalizationOptions.Default;
// Act
var normalized = _normalizer.Normalize(code, options);
// Assert
Assert.DoesNotContain("//", normalized);
Assert.DoesNotContain("/*", normalized);
}
[Fact]
public void NormalizeAst_WithParser_NormalizesAstNodes()
{
// Arrange
var parser = new DecompiledCodeParser();
var code = @"
int foo(int myVar) {
return myVar + 1;
}";
var ast = parser.Parse(code);
var options = new NormalizationOptions { NormalizeVariables = true };
// Act
var normalizedAst = _normalizer.NormalizeAst(ast, options);
// Assert
Assert.NotNull(normalizedAst);
Assert.Equal(ast.NodeCount, normalizedAst.NodeCount);
}
}