Skip to content

Commit d4f0806

Browse files
authored
Merge pull request #26 from EmbarkStudios/webbju/refine-unit-tests
Refine language parser support with unit testing.
2 parents ad1a2dd + 45cb9ad commit d4f0806

File tree

7 files changed

+253
-158
lines changed

7 files changed

+253
-158
lines changed

ServerCodeExciser/AssemblyInfo.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Runtime.CompilerServices;
2+
using System.Runtime.InteropServices;
3+
4+
// In SDK-style projects such as this one, several assembly attributes that were historically
5+
// defined in this file are now automatically added during build and populated with
6+
// values defined in project properties. For details of which attributes are included
7+
// and how to customise this process see: https://aka.ms/assembly-info-properties
8+
9+
10+
// Setting ComVisible to false makes the types in this assembly not visible to COM
11+
// components. If you need to access a type in this assembly from COM, set the ComVisible
12+
// attribute to true on that type.
13+
14+
[assembly: ComVisible(false)]
15+
16+
// The following GUID is for the ID of the typelib if this project is exposed to COM.
17+
18+
[assembly: Guid("23858a33-edb8-4a1a-81c6-6a7347386704")]
19+
20+
[assembly: InternalsVisibleTo("ServerCodeExciserTest")]
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using System;
2+
using System.IO;
3+
using Antlr4.Runtime;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
using UnrealAngelscriptServerCodeExcision;
6+
7+
namespace ServerCodeExciser.Tests
8+
{
9+
[TestClass]
10+
public class AngelscriptSyntaxTests
11+
{
12+
private sealed class ThrowingErrorListener : BaseErrorListener
13+
{
14+
public override void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
15+
{
16+
throw new InvalidOperationException($"line {line}:{charPositionInLine} {msg}");
17+
}
18+
}
19+
20+
[TestMethod]
21+
[DataRow("mynamespace")]
22+
[DataRow("Nested::mynamespace")]
23+
public void Namespace(string @namespace)
24+
{
25+
ParseScript($"namespace {@namespace}\r\n{{\r\n}}\r\n");
26+
}
27+
28+
[TestMethod]
29+
public void NamedArgumentsFunctionCall()
30+
{
31+
ParseScript("void Func(bool Arg1 = false, int Arg2 = 0) {}\r\nvoid main() { Func(Arg2: 1, Arg1: true); }\r\n");
32+
}
33+
34+
[TestMethod]
35+
[DataRow("")]
36+
[DataRow("final")]
37+
[DataRow("override")]
38+
[DataRow("no_discard")] // UnrealAngelscript
39+
[DataRow("allow_discard")] // UnrealAngelscript
40+
[DataRow("accept_temporary_this")] // UnrealAngelscript
41+
[DataRow("const allow_discard")] // UnrealAngelscript
42+
public void FunctionModifier(string modifier)
43+
{
44+
ParseScript($"bool Func() {modifier}\r\n{{\r\nreturn true;\r\n}}");
45+
}
46+
47+
[TestMethod]
48+
[DataRow("int", "0")]
49+
[DataRow("int8", "0")]
50+
[DataRow("int16", "0")]
51+
[DataRow("int32", "0")]
52+
[DataRow("int64", "0")]
53+
[DataRow("uint", "0")]
54+
[DataRow("uint8", "0")]
55+
[DataRow("uint16", "0")]
56+
[DataRow("uint32", "0")]
57+
[DataRow("uint64", "0")]
58+
[DataRow("float", "0.0f")]
59+
[DataRow("float32", "0.0f")]
60+
[DataRow("float64", "0.0")]
61+
[DataRow("doublt", "0.0")]
62+
[DataRow("bool", "false")]
63+
[DataRow("string", "\"\\0\"")]
64+
[DataRow("string", "\"\\xFFFF\"")]
65+
[DataRow("string", "\"\\uFFFF\"")]
66+
[DataRow("string", "\"\\uFFFFFFFF\"")]
67+
[DataRow("string", "\"\"\"\r\nheredoc string\r\n\"\"\"")] // heredoc: https://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes_strings.html
68+
[DataRow("FName", "n\"MyName\"")] // FName Literals: https://angelscript.hazelight.se/scripting/fname-literals/
69+
[DataRow("string", "f\"Formatted String: {L:0.1f}\"")] // Formatted Strings: https://angelscript.hazelight.se/scripting/format-strings/
70+
public void DataType(string type, string value)
71+
{
72+
ParseScript($"{type} VAR = {value};");
73+
}
74+
75+
[TestMethod]
76+
[DataRow("")]
77+
[DataRow("UCLASS()")]
78+
[DataRow("UCLASS(Abstract)")]
79+
public void UClass(string annotation)
80+
{
81+
ParseScript($"{annotation} class ClassName : BaseClass {{}};");
82+
}
83+
84+
[TestMethod]
85+
[DataRow("")]
86+
[DataRow("UPROPERTY()")]
87+
[DataRow("UPROPERTY(DefaultComponent)")]
88+
[DataRow("UPROPERTY(DefaultComponent,)")]
89+
[DataRow("UPROPERTY(DefaultComponent, RootComponent)")]
90+
public void UProperty(string annotation)
91+
{
92+
ParseScript($"class ClassName : BaseClass\r\n{{\r\n\t{annotation}\r\nDummyType DummyProperty;\r\n}};");
93+
}
94+
95+
private static void ParseScript(string script)
96+
{
97+
var lexer = new UnrealAngelscriptLexer(new AntlrInputStream(script));
98+
var tokenStream = new CommonTokenStream(lexer);
99+
var parser = new UnrealAngelscriptParser(tokenStream);
100+
parser.RemoveErrorListeners();
101+
parser.AddErrorListener(new ThrowingErrorListener());
102+
new UnrealAngelscriptSimpleVisitor(script).VisitChildren(parser.script());
103+
}
104+
}
105+
}
Lines changed: 91 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,116 @@
11
using System;
22
using System.IO;
33
using Microsoft.VisualStudio.TestTools.UnitTesting;
4-
using ServerCodeExciser;
54
using ServerCodeExcisionCommon;
65
using UnrealAngelscriptServerCodeExcision;
76

8-
[TestClass]
9-
public class ExcisionIntegrationTests
7+
namespace ServerCodeExciser.Tests
108
{
11-
private static string DataRootDir = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "..", "..", ".."));
12-
13-
[TestMethod]
14-
public void ExciseAngelscriptCases()
9+
[TestClass]
10+
public class ExcisionIntegrationTests
1511
{
16-
int numTestFailures = 0;
17-
int numTestCases = 0;
18-
19-
// Run for Angelscript
20-
var actual = RunExciserIntegrationTests(
21-
".as",
22-
Path.Combine(DataRootDir, "Problems", "Angelscript"),
23-
Path.Combine(DataRootDir, "Answers", "Angelscript"),
24-
ref numTestFailures,
25-
ref numTestCases);
26-
27-
Assert.AreEqual(EExciserReturnValues.Success, actual);
28-
Assert.AreEqual(0, numTestFailures);
29-
}
30-
31-
[TestMethod]
32-
public void ExciseCommonCases()
33-
{
34-
int numTestFailures = 0;
35-
int numTestCases = 0;
36-
37-
// Run for "common"
38-
var actual = RunExciserIntegrationTests(
39-
".common",
40-
Path.Combine(DataRootDir, "Problems", "Common"),
41-
Path.Combine(DataRootDir, "Answers", "Common"),
42-
ref numTestFailures,
43-
ref numTestCases);
44-
45-
Assert.AreEqual(EExciserReturnValues.Success, actual);
46-
Assert.AreEqual(0, numTestFailures);
47-
}
12+
private static string DataRootDir = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "..", "..", ".."));
4813

49-
private static EExciserReturnValues RunExciserIntegrationTests(string fileExtension, string inputPath, string outputPath, ref int numTestFailures, ref int numTestCases)
50-
{
51-
// Clean up earlier answers.
52-
if (Directory.Exists(outputPath))
14+
[TestMethod]
15+
public void ExciseAngelscriptCases()
5316
{
54-
Directory.Delete(outputPath, true);
17+
int numTestFailures = 0;
18+
int numTestCases = 0;
19+
20+
// Run for Angelscript
21+
var actual = RunExciserIntegrationTests(
22+
".as",
23+
Path.Combine(DataRootDir, "Problems", "Angelscript"),
24+
Path.Combine(DataRootDir, "Answers", "Angelscript"),
25+
ref numTestFailures,
26+
ref numTestCases);
27+
28+
Assert.AreEqual(EExciserReturnValues.Success, actual);
29+
Assert.AreEqual(0, numTestFailures);
5530
}
5631

57-
string searchPattern = "*." + fileExtension.TrimStart('.');
58-
Console.WriteLine($"Running integration tests for {searchPattern} files...");
59-
60-
EExciserReturnValues returnCode;
61-
try
62-
{
63-
var excisionParams = new ServerCodeExcisionParameters
64-
{
65-
OutputPath = outputPath,
66-
ShouldOutputUntouchedFiles = true,
67-
FullExcisionRegexString = @"FullExcise1/.*",
68-
ExciseAllFunctionsRegexString = @"AllFunctionExcise1/.*|||AllFunctionExcise2/.*",
69-
StrictMode = true,
70-
DontSkip = true,
71-
};
72-
excisionParams.InputPaths.Add(inputPath);
73-
74-
var angelscriptServerCodeExciser = new ServerCodeExcisionProcessor(excisionParams);
75-
returnCode = angelscriptServerCodeExciser.ExciseServerCode(searchPattern, new UnrealAngelscriptServerCodeExcisionLanguage());
76-
Console.WriteLine($"ExciseServerCode for {searchPattern} files returned: {returnCode}");
77-
}
78-
catch (Exception)
32+
[TestMethod]
33+
public void ExciseCommonCases()
7934
{
80-
throw;
35+
int numTestFailures = 0;
36+
int numTestCases = 0;
37+
38+
// Run for "common"
39+
var actual = RunExciserIntegrationTests(
40+
".common",
41+
Path.Combine(DataRootDir, "Problems", "Common"),
42+
Path.Combine(DataRootDir, "Answers", "Common"),
43+
ref numTestFailures,
44+
ref numTestCases);
45+
46+
Assert.AreEqual(EExciserReturnValues.Success, actual);
47+
Assert.AreEqual(0, numTestFailures);
8148
}
8249

83-
foreach (var answerFilePath in Directory.EnumerateFiles(outputPath, searchPattern, SearchOption.AllDirectories))
50+
private static EExciserReturnValues RunExciserIntegrationTests(string fileExtension, string inputPath, string outputPath, ref int numTestFailures, ref int numTestCases)
8451
{
85-
numTestCases++;
86-
87-
var solutionFilePath = Path.Combine(inputPath, Path.GetRelativePath(outputPath, answerFilePath)) + ".solution";
52+
// Clean up earlier answers.
53+
if (Directory.Exists(outputPath))
54+
{
55+
Directory.Delete(outputPath, true);
56+
}
8857

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

93-
if (answer == solution)
61+
EExciserReturnValues returnCode;
62+
try
9463
{
95-
Console.ForegroundColor = ConsoleColor.Green;
96-
Console.WriteLine(fileName + " passed!");
97-
Console.ForegroundColor = ConsoleColor.Gray;
64+
var excisionParams = new ServerCodeExcisionParameters
65+
{
66+
OutputPath = outputPath,
67+
ShouldOutputUntouchedFiles = true,
68+
FullExcisionRegexString = @"FullExcise1/.*",
69+
ExciseAllFunctionsRegexString = @"AllFunctionExcise1/.*|||AllFunctionExcise2/.*",
70+
StrictMode = true,
71+
DontSkip = true,
72+
};
73+
excisionParams.InputPaths.Add(inputPath);
74+
75+
var angelscriptServerCodeExciser = new ServerCodeExcisionProcessor(excisionParams);
76+
returnCode = angelscriptServerCodeExciser.ExciseServerCode(searchPattern, new UnrealAngelscriptServerCodeExcisionLanguage());
77+
Console.WriteLine($"ExciseServerCode for {searchPattern} files returned: {returnCode}");
9878
}
99-
else
79+
catch (Exception)
10080
{
101-
Console.ForegroundColor = ConsoleColor.Red;
102-
Console.Error.WriteLine(fileName + " failed!");
103-
Console.ForegroundColor = ConsoleColor.Gray;
104-
Console.WriteLine("--- Expected: ---");
105-
Console.WriteLine(solution);
106-
Console.WriteLine("--- Actual: ---");
107-
Console.WriteLine(answer);
108-
numTestFailures++;
81+
throw;
10982
}
110-
}
11183

112-
return returnCode;
84+
foreach (var answerFilePath in Directory.EnumerateFiles(outputPath, searchPattern, SearchOption.AllDirectories))
85+
{
86+
numTestCases++;
87+
88+
var solutionFilePath = Path.Combine(inputPath, Path.GetRelativePath(outputPath, answerFilePath)) + ".solution";
89+
90+
var fileName = Path.GetFileName(answerFilePath);
91+
var answer = File.ReadAllText(answerFilePath);
92+
var solution = File.ReadAllText(solutionFilePath);
93+
94+
if (answer == solution)
95+
{
96+
Console.ForegroundColor = ConsoleColor.Green;
97+
Console.WriteLine(fileName + " passed!");
98+
Console.ForegroundColor = ConsoleColor.Gray;
99+
}
100+
else
101+
{
102+
Console.ForegroundColor = ConsoleColor.Red;
103+
Console.Error.WriteLine(fileName + " failed!");
104+
Console.ForegroundColor = ConsoleColor.Gray;
105+
Console.WriteLine("--- Expected: ---");
106+
Console.WriteLine(solution);
107+
Console.WriteLine("--- Actual: ---");
108+
Console.WriteLine(answer);
109+
numTestFailures++;
110+
}
111+
}
112+
113+
return returnCode;
114+
}
113115
}
114116
}

ServerCodeExciserTest/Problems/Angelscript/DatatypesTest.as

Lines changed: 0 additions & 27 deletions
This file was deleted.

ServerCodeExciserTest/Problems/Angelscript/DatatypesTest.as.solution

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)