Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions ServerCodeExciser/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// In SDK-style projects such as this one, several assembly attributes that were historically
// defined in this file are now automatically added during build and populated with
// values defined in project properties. For details of which attributes are included
// and how to customise this process see: https://aka.ms/assembly-info-properties


// Setting ComVisible to false makes the types in this assembly not visible to COM
// components. If you need to access a type in this assembly from COM, set the ComVisible
// attribute to true on that type.

[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM.

[assembly: Guid("23858a33-edb8-4a1a-81c6-6a7347386704")]

[assembly: InternalsVisibleTo("ServerCodeExciserTest")]
105 changes: 105 additions & 0 deletions ServerCodeExciserTest/AngelscriptSyntaxTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System;
using System.IO;
using Antlr4.Runtime;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UnrealAngelscriptServerCodeExcision;

namespace ServerCodeExciser.Tests
{
[TestClass]
public class AngelscriptSyntaxTests
{
private sealed class ThrowingErrorListener : BaseErrorListener
{
public override void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
throw new InvalidOperationException($"line {line}:{charPositionInLine} {msg}");
}
}

[TestMethod]
[DataRow("mynamespace")]
[DataRow("Nested::mynamespace")]
public void Namespace(string @namespace)
{
ParseScript($"namespace {@namespace}\r\n{{\r\n}}\r\n");
}

[TestMethod]
public void NamedArgumentsFunctionCall()
{
ParseScript("void Func(bool Arg1 = false, int Arg2 = 0) {}\r\nvoid main() { Func(Arg2: 1, Arg1: true); }\r\n");
}

[TestMethod]
[DataRow("")]
[DataRow("final")]
[DataRow("override")]
[DataRow("no_discard")] // UnrealAngelscript
[DataRow("allow_discard")] // UnrealAngelscript
[DataRow("accept_temporary_this")] // UnrealAngelscript
[DataRow("const allow_discard")] // UnrealAngelscript
public void FunctionModifier(string modifier)
{
ParseScript($"bool Func() {modifier}\r\n{{\r\nreturn true;\r\n}}");
}

[TestMethod]
[DataRow("int", "0")]
[DataRow("int8", "0")]
[DataRow("int16", "0")]
[DataRow("int32", "0")]
[DataRow("int64", "0")]
[DataRow("uint", "0")]
[DataRow("uint8", "0")]
[DataRow("uint16", "0")]
[DataRow("uint32", "0")]
[DataRow("uint64", "0")]
[DataRow("float", "0.0f")]
[DataRow("float32", "0.0f")]
[DataRow("float64", "0.0")]
[DataRow("doublt", "0.0")]
[DataRow("bool", "false")]
[DataRow("string", "\"\\0\"")]
[DataRow("string", "\"\\xFFFF\"")]
[DataRow("string", "\"\\uFFFF\"")]
[DataRow("string", "\"\\uFFFFFFFF\"")]
[DataRow("string", "\"\"\"\r\nheredoc string\r\n\"\"\"")] // heredoc: https://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes_strings.html
[DataRow("FName", "n\"MyName\"")] // FName Literals: https://angelscript.hazelight.se/scripting/fname-literals/
[DataRow("string", "f\"Formatted String: {L:0.1f}\"")] // Formatted Strings: https://angelscript.hazelight.se/scripting/format-strings/
public void DataType(string type, string value)
{
ParseScript($"{type} VAR = {value};");
}

[TestMethod]
[DataRow("")]
[DataRow("UCLASS()")]
[DataRow("UCLASS(Abstract)")]
public void UClass(string annotation)
{
ParseScript($"{annotation} class ClassName : BaseClass {{}};");
}

[TestMethod]
[DataRow("")]
[DataRow("UPROPERTY()")]
[DataRow("UPROPERTY(DefaultComponent)")]
[DataRow("UPROPERTY(DefaultComponent,)")]
[DataRow("UPROPERTY(DefaultComponent, RootComponent)")]
public void UProperty(string annotation)
{
ParseScript($"class ClassName : BaseClass\r\n{{\r\n\t{annotation}\r\nDummyType DummyProperty;\r\n}};");
}

private static void ParseScript(string script)
{
var lexer = new UnrealAngelscriptLexer(new AntlrInputStream(script));
var tokenStream = new CommonTokenStream(lexer);
var parser = new UnrealAngelscriptParser(tokenStream);
parser.RemoveErrorListeners();
parser.AddErrorListener(new ThrowingErrorListener());
new UnrealAngelscriptSimpleVisitor(script).VisitChildren(parser.script());
}
}
}
180 changes: 91 additions & 89 deletions ServerCodeExciserTest/ExcisionIntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -1,114 +1,116 @@
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ServerCodeExciser;
using ServerCodeExcisionCommon;
using UnrealAngelscriptServerCodeExcision;

[TestClass]
public class ExcisionIntegrationTests
namespace ServerCodeExciser.Tests
{
private static string DataRootDir = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "..", "..", ".."));

[TestMethod]
public void ExciseAngelscriptCases()
[TestClass]
public class ExcisionIntegrationTests
{
int numTestFailures = 0;
int numTestCases = 0;

// Run for Angelscript
var actual = RunExciserIntegrationTests(
".as",
Path.Combine(DataRootDir, "Problems", "Angelscript"),
Path.Combine(DataRootDir, "Answers", "Angelscript"),
ref numTestFailures,
ref numTestCases);

Assert.AreEqual(EExciserReturnValues.Success, actual);
Assert.AreEqual(0, numTestFailures);
}

[TestMethod]
public void ExciseCommonCases()
{
int numTestFailures = 0;
int numTestCases = 0;

// Run for "common"
var actual = RunExciserIntegrationTests(
".common",
Path.Combine(DataRootDir, "Problems", "Common"),
Path.Combine(DataRootDir, "Answers", "Common"),
ref numTestFailures,
ref numTestCases);

Assert.AreEqual(EExciserReturnValues.Success, actual);
Assert.AreEqual(0, numTestFailures);
}
private static string DataRootDir = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "..", "..", ".."));

private static EExciserReturnValues RunExciserIntegrationTests(string fileExtension, string inputPath, string outputPath, ref int numTestFailures, ref int numTestCases)
{
// Clean up earlier answers.
if (Directory.Exists(outputPath))
[TestMethod]
public void ExciseAngelscriptCases()
{
Directory.Delete(outputPath, true);
int numTestFailures = 0;
int numTestCases = 0;

// Run for Angelscript
var actual = RunExciserIntegrationTests(
".as",
Path.Combine(DataRootDir, "Problems", "Angelscript"),
Path.Combine(DataRootDir, "Answers", "Angelscript"),
ref numTestFailures,
ref numTestCases);

Assert.AreEqual(EExciserReturnValues.Success, actual);
Assert.AreEqual(0, numTestFailures);
}

string searchPattern = "*." + fileExtension.TrimStart('.');
Console.WriteLine($"Running integration tests for {searchPattern} files...");

EExciserReturnValues returnCode;
try
{
var excisionParams = new ServerCodeExcisionParameters
{
OutputPath = outputPath,
ShouldOutputUntouchedFiles = true,
FullExcisionRegexString = @"FullExcise1/.*",
ExciseAllFunctionsRegexString = @"AllFunctionExcise1/.*|||AllFunctionExcise2/.*",
StrictMode = true,
DontSkip = true,
};
excisionParams.InputPaths.Add(inputPath);

var angelscriptServerCodeExciser = new ServerCodeExcisionProcessor(excisionParams);
returnCode = angelscriptServerCodeExciser.ExciseServerCode(searchPattern, new UnrealAngelscriptServerCodeExcisionLanguage());
Console.WriteLine($"ExciseServerCode for {searchPattern} files returned: {returnCode}");
}
catch (Exception)
[TestMethod]
public void ExciseCommonCases()
{
throw;
int numTestFailures = 0;
int numTestCases = 0;

// Run for "common"
var actual = RunExciserIntegrationTests(
".common",
Path.Combine(DataRootDir, "Problems", "Common"),
Path.Combine(DataRootDir, "Answers", "Common"),
ref numTestFailures,
ref numTestCases);

Assert.AreEqual(EExciserReturnValues.Success, actual);
Assert.AreEqual(0, numTestFailures);
}

foreach (var answerFilePath in Directory.EnumerateFiles(outputPath, searchPattern, SearchOption.AllDirectories))
private static EExciserReturnValues RunExciserIntegrationTests(string fileExtension, string inputPath, string outputPath, ref int numTestFailures, ref int numTestCases)
{
numTestCases++;

var solutionFilePath = Path.Combine(inputPath, Path.GetRelativePath(outputPath, answerFilePath)) + ".solution";
// Clean up earlier answers.
if (Directory.Exists(outputPath))
{
Directory.Delete(outputPath, true);
}

var fileName = Path.GetFileName(answerFilePath);
var answer = File.ReadAllText(answerFilePath);
var solution = File.ReadAllText(solutionFilePath);
string searchPattern = "*." + fileExtension.TrimStart('.');
Console.WriteLine($"Running integration tests for {searchPattern} files...");

if (answer == solution)
EExciserReturnValues returnCode;
try
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(fileName + " passed!");
Console.ForegroundColor = ConsoleColor.Gray;
var excisionParams = new ServerCodeExcisionParameters
{
OutputPath = outputPath,
ShouldOutputUntouchedFiles = true,
FullExcisionRegexString = @"FullExcise1/.*",
ExciseAllFunctionsRegexString = @"AllFunctionExcise1/.*|||AllFunctionExcise2/.*",
StrictMode = true,
DontSkip = true,
};
excisionParams.InputPaths.Add(inputPath);

var angelscriptServerCodeExciser = new ServerCodeExcisionProcessor(excisionParams);
returnCode = angelscriptServerCodeExciser.ExciseServerCode(searchPattern, new UnrealAngelscriptServerCodeExcisionLanguage());
Console.WriteLine($"ExciseServerCode for {searchPattern} files returned: {returnCode}");
}
else
catch (Exception)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.WriteLine(fileName + " failed!");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("--- Expected: ---");
Console.WriteLine(solution);
Console.WriteLine("--- Actual: ---");
Console.WriteLine(answer);
numTestFailures++;
throw;
}
}

return returnCode;
foreach (var answerFilePath in Directory.EnumerateFiles(outputPath, searchPattern, SearchOption.AllDirectories))
{
numTestCases++;

var solutionFilePath = Path.Combine(inputPath, Path.GetRelativePath(outputPath, answerFilePath)) + ".solution";

var fileName = Path.GetFileName(answerFilePath);
var answer = File.ReadAllText(answerFilePath);
var solution = File.ReadAllText(solutionFilePath);

if (answer == solution)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(fileName + " passed!");
Console.ForegroundColor = ConsoleColor.Gray;
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.WriteLine(fileName + " failed!");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("--- Expected: ---");
Console.WriteLine(solution);
Console.WriteLine("--- Actual: ---");
Console.WriteLine(answer);
numTestFailures++;
}
}

return returnCode;
}
}
}
27 changes: 0 additions & 27 deletions ServerCodeExciserTest/Problems/Angelscript/DatatypesTest.as

This file was deleted.

This file was deleted.

Loading
Loading