save progress
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user