Skip to content

Commit 33ccf32

Browse files
authored
Merge pull request #905 from PlayEveryWare/feat/more-unit-tests
More Unit Tests
2 parents c0be867 + a802960 commit 33ccf32

File tree

18 files changed

+520
-17
lines changed

18 files changed

+520
-17
lines changed

Assets/Tests/PlayMode/Extensions/AuthScopeFlagsExtensionsTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,19 @@ public static void CustomMappings_Exists()
4747
{
4848
CustomMappings_Exist(AuthScopeFlagsExtensions.CustomMappings);
4949
}
50+
51+
/// <summary>
52+
/// Guarantees that the TryParse method works for all the valid strings
53+
/// that can be parsed, and that parsing of an invalid string is handled
54+
/// correctly.
55+
/// </summary>
56+
[Test]
57+
public static void Test_TryParse()
58+
{
59+
Test_TryParse(
60+
AuthScopeFlagsExtensions.CustomMappings,
61+
AuthScopeFlagsExtensions.TryParse
62+
);
63+
}
5064
}
5165
}

Assets/Tests/PlayMode/Extensions/CustomMappedEnumTestBase.cs

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ namespace PlayEveryWare.EpicOnlineServices.Tests.Extensions
3030

3131
public class CustomMappedEnumTestBase<TEnum> where TEnum : struct, Enum
3232
{
33+
// Define a delegate that matches the signature of a TryParse method
34+
protected delegate bool TryParseDelegate(IList<string> input, out TEnum result);
35+
3336
/// <summary>
3437
/// Helper function that retrieves an IEnumerable of all the values
3538
/// defined within the indicated enum.
@@ -63,10 +66,10 @@ protected static void AllValues_HaveDescription(
6366
// exception because it can signal to the developer that the
6467
// custom mapping is out of date with the definition of the enum
6568
// it is mapped against.
66-
Assert.DoesNotThrow(() => getDescriptionFn(enumValue),
67-
$"The extension class for the enum {typeof(TEnum).Name} " +
68-
$"does not have a switch clause providing a description " +
69-
$"text for the enum value \"{enumValue}\".");
69+
Assert.DoesNotThrow(() => getDescriptionFn(enumValue),
70+
$"The extension class for the enum {typeof(TEnum).Name} " +
71+
$"does not have a switch clause providing a description " +
72+
$"text for the enum value \"{enumValue}\".");
7073
}
7174
}
7275

@@ -84,9 +87,58 @@ protected static void CustomMappings_Exist(
8487
foreach (TEnum enumValue in GetEnumValues())
8588
{
8689
Assert.IsTrue(customMappings.ContainsValue(enumValue),
87-
$"The extension class for the enum {typeof(TEnum).Name} " +
88-
$"does not have a custom mapping defined for the enum " +
89-
$"value \"{enumValue}\".");
90+
$"The extension class for the enum {typeof(TEnum).Name} " +
91+
$"does not have a custom mapping defined for the enum " +
92+
$"value \"{enumValue}\".");
93+
}
94+
}
95+
96+
/// <summary>
97+
/// Checks to make sure that the TryParse extension method for the
98+
/// indicated enum is functioning properly.
99+
/// </summary>
100+
/// <param name="customMappings">
101+
/// The dictionary that provides mapping from custom string values to
102+
/// specific values within the enum.
103+
/// </param>
104+
/// <param name="tryParseFunc">
105+
/// The extension method used to try and parse a string into an enum
106+
/// value.
107+
/// </param>
108+
protected static void Test_TryParse(
109+
Dictionary<string, TEnum> customMappings,
110+
TryParseDelegate tryParseFunc
111+
)
112+
{
113+
// Reuse the variables for whether parse was successful and what the
114+
// parsed value was.
115+
bool parsed = false;
116+
TEnum parsedValue = default;
117+
118+
// test that an incorrect string will result in the TryParse method
119+
// functioning as expected
120+
const string INVALID_MAPPING = "ASDFASDFASDFASDF";
121+
parsed = tryParseFunc(new List<string>() { INVALID_MAPPING }, out parsedValue);
122+
123+
// Assert that the parsing failed (as expected)
124+
Assert.IsFalse(parsed);
125+
126+
// Assert that in the case of a failed parse, the default value is
127+
// set.
128+
Assert.AreEqual(parsedValue, default(TEnum));
129+
130+
// Test each of the custom mappings for accurate parsing.
131+
foreach (string customMapping in customMappings.Keys)
132+
{
133+
parsed = tryParseFunc(new List<string>() { customMapping }, out parsedValue);
134+
Assert.IsTrue(parsed);
135+
Assert.AreEqual(parsedValue, customMappings[customMapping]);
136+
137+
// Convert custom mapped to string, and test that that parsing works
138+
string stringValue = parsedValue.ToString();
139+
parsed = tryParseFunc(new List<string>() { stringValue }, out TEnum reparsedValue);
140+
Assert.IsTrue(parsed);
141+
Assert.AreEqual(reparsedValue, parsedValue);
90142
}
91143
}
92144
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright (c) 2024 PlayEveryWare
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
namespace PlayEveryWare.EpicOnlineServices.Tests.Extensions
24+
{
25+
using NUnit.Framework;
26+
using System;
27+
using System.IO;
28+
using PlayEveryWare.EpicOnlineServices.Extensions;
29+
using System.Collections.Generic;
30+
31+
[TestFixture]
32+
public class FileInfoExtensionsTests
33+
{
34+
private string tempDir;
35+
36+
[SetUp]
37+
public void SetUp()
38+
{
39+
tempDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())).FullName;
40+
}
41+
42+
[TearDown]
43+
public void TearDown()
44+
{
45+
if (Directory.Exists(tempDir))
46+
{
47+
Directory.Delete(tempDir, true);
48+
}
49+
}
50+
51+
private FileInfo CreateFile(string fileName, string content = null)
52+
{
53+
string filePath = Path.Combine(tempDir, fileName);
54+
if (content != null)
55+
{
56+
File.WriteAllText(filePath, content);
57+
}
58+
59+
return new FileInfo(filePath);
60+
}
61+
62+
private void AssertSemanticEquality(string content1, string content2, bool expected,
63+
bool createFirstFile = true, bool createSecondFile = true)
64+
{
65+
FileInfo fileInfo1 = createFirstFile ? CreateFile("file1.txt", content1) : CreateFile("nonexistent1.txt");
66+
FileInfo fileInfo2 = createSecondFile ? CreateFile("file2.txt", content2) : CreateFile("nonexistent2.txt");
67+
68+
bool result = fileInfo1.AreContentsSemanticallyEqual(fileInfo2);
69+
Assert.AreEqual(expected, result,
70+
$"Expected files with content \"{content1}\" and \"{content2}\" to be semantically {(expected ? "equal" : "not equal")}.");
71+
}
72+
73+
[Test]
74+
public void ComputeSHA_CorrectlyComputesSHAOfFile()
75+
{
76+
Dictionary<string, string> hashToContents = new()
77+
{
78+
{ "0a0a9f2a6772942557ab5355d76af442f8f65e01", "Hello, World!" },
79+
// Test a string that is only slightly different
80+
{ "907d14fb3af2b0d4f18c2d46abe8aedce17367bd", "Hello, World" },
81+
{ "9be35056f6abcc721f8514f526d865f08fa88403", "So long, and thanks for all the fish!" }
82+
};
83+
84+
foreach (string hash in hashToContents.Keys)
85+
{
86+
Assert.AreEqual(
87+
hash,
88+
CreateFile(hashToContents[hash], hashToContents[hash]).ComputeSHA(),
89+
"The computed SHA should match the expected SHA."
90+
);
91+
}
92+
}
93+
94+
[TestCase("Same content", "Same content", true)]
95+
[TestCase("Content A", "Content B", false)]
96+
[TestCase("Short", "Longer content", false)]
97+
[TestCase(null, null, true, false, false)] // Neither file exists
98+
[TestCase("Some content", null, false, true, false)] // One file exists, other does not
99+
[TestCase("Some content", "Some content", true, true, true)] // Same file path
100+
public void AreContentsSemanticallyEqual_VariousScenarios_ReturnsExpected(string content1, string content2,
101+
bool expected, bool createFirstFile = true, bool createSecondFile = true)
102+
{
103+
AssertSemanticEquality(content1, content2, expected, createFirstFile, createSecondFile);
104+
}
105+
}
106+
}

Assets/Tests/PlayMode/Extensions/FileInfoExtensionsTests.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Tests/PlayMode/Extensions/IntegratedPlatformManagementFlagsExtensionsTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,19 @@ public static void CustomMappings_Exists()
4747
{
4848
CustomMappings_Exist(IntegratedPlatformManagementFlagsExtensions.CustomMappings);
4949
}
50+
51+
/// <summary>
52+
/// Guarantees that the TryParse method works for all the valid strings
53+
/// that can be parsed, and that parsing of an invalid string is handled
54+
/// correctly.
55+
/// </summary>
56+
[Test]
57+
public static void Test_TryParse()
58+
{
59+
Test_TryParse(
60+
IntegratedPlatformManagementFlagsExtensions.CustomMappings,
61+
IntegratedPlatformManagementFlagsExtensions.TryParse
62+
);
63+
}
5064
}
5165
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright (c) 2024 PlayEveryWare
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
namespace PlayEveryWare.EpicOnlineServices.Tests.Extensions
24+
{
25+
using NUnit.Framework;
26+
using PlayEveryWare.EpicOnlineServices.Extensions;
27+
using System.Collections.Generic;
28+
using System.Linq;
29+
30+
[TestFixture]
31+
public class ListExtensionsTests
32+
{
33+
/// <summary>
34+
/// Test to verify that the Shuffle method changes the order of elements in the list.
35+
/// </summary>
36+
[Test]
37+
public void Shuffle_ChangesOrderOfElements()
38+
{
39+
// Arrange
40+
List<int> originalList = Enumerable.Range(1, 100).ToList();
41+
List<int> shuffledList = new(originalList);
42+
43+
// Act
44+
shuffledList.Shuffle();
45+
46+
// Assert
47+
Assert.AreNotEqual(originalList, shuffledList,
48+
"The shuffled list should not be in the same order as the original list.");
49+
Assert.AreEqual(originalList.Count, shuffledList.Count,
50+
"The shuffled list should have the same number of elements as the original list.");
51+
Assert.IsTrue(originalList.All(shuffledList.Contains),
52+
"The shuffled list should contain all elements from the original list.");
53+
}
54+
55+
/// <summary>
56+
/// Test to verify that the Shuffle method does not lose any elements.
57+
/// </summary>
58+
[Test]
59+
public void Shuffle_DoesNotLoseElements()
60+
{
61+
// Arrange
62+
List<int> originalList = new()
63+
{
64+
1,
65+
2,
66+
3,
67+
4,
68+
5
69+
};
70+
List<int> shuffledList = new(originalList);
71+
72+
// Act
73+
shuffledList.Shuffle();
74+
75+
// Assert
76+
CollectionAssert.AreEquivalent(originalList, shuffledList,
77+
"The shuffled list should contain the same elements as the original list.");
78+
}
79+
80+
/// <summary>
81+
/// Test to verify that shuffling an empty list does not throw an exception.
82+
/// </summary>
83+
[Test]
84+
public void Shuffle_EmptyList_NoException()
85+
{
86+
// Arrange
87+
List<int> emptyList = new();
88+
89+
// Act & Assert
90+
Assert.DoesNotThrow(() => emptyList.Shuffle(), "Shuffling an empty list should not throw an exception.");
91+
}
92+
93+
/// <summary>
94+
/// Test to verify that shuffling a single-element list does not change its order.
95+
/// </summary>
96+
[Test]
97+
public void Shuffle_SingleElementList_NoChange()
98+
{
99+
// Arrange
100+
List<int> singleElementList = new() { 42 };
101+
102+
// Act
103+
singleElementList.Shuffle();
104+
105+
// Assert
106+
Assert.AreEqual(1, singleElementList.Count,
107+
"A single-element list should still have one element after shuffling.");
108+
Assert.AreEqual(42, singleElementList[0], "A single-element list should remain unchanged after shuffling.");
109+
}
110+
}
111+
}

Assets/Tests/PlayMode/Extensions/ListExtensionsTests.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Tests/PlayMode/Extensions/PlatformFlagsExtensionsTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,19 @@ public static void CustomMappings_Exists()
4747
{
4848
CustomMappings_Exist(PlatformFlagsExtensions.CustomMappings);
4949
}
50+
51+
/// <summary>
52+
/// Guarantees that the TryParse method works for all the valid strings
53+
/// that can be parsed, and that parsing of an invalid string is handled
54+
/// correctly.
55+
/// </summary>
56+
[Test]
57+
public static void Test_TryParse()
58+
{
59+
Test_TryParse(
60+
PlatformFlagsExtensions.CustomMappings,
61+
PlatformFlagsExtensions.TryParse
62+
);
63+
}
5064
}
5165
}

0 commit comments

Comments
 (0)