Skip to content

Commit

Permalink
Merge pull request #77 from cs-util-com/feature/UnityTestingImprovements
Browse files Browse the repository at this point in the history
Feature/unity testing improvements
  • Loading branch information
cs-util authored Mar 20, 2022
2 parents 7ea2dcd + 9833321 commit 03ffa9d
Show file tree
Hide file tree
Showing 36 changed files with 199 additions and 36 deletions.
7 changes: 6 additions & 1 deletion CsCore/CsCore.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ACCESSOR_DECLARATION_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/CASE_BLOCK_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INITIALIZER_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INITIALIZER_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/OTHER_BRACES/@EntryValue">END_OF_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ELSE_ON_NEW_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FINALLY_ON_NEW_LINE/@EntryValue">False</s:Boolean>
Expand Down Expand Up @@ -44,4 +45,8 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue">False</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">254</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_OBJECT_AND_COLLECTION_INITIALIZER_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_TERNARY_EXPR_STYLE/@EntryValue">WRAP_IF_LONG</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_TERNARY_EXPR_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using com.csutil.http;
using System.Net.Http;
using System.Collections.Generic;
using UnityEditor;

namespace com.csutil.editor {

[InitializeOnLoad]
public class LatestCsCoreVersionChecker {

static LatestCsCoreVersionChecker() {
CheckForLatestVersion().LogOnError();
}

public static async Task CheckForLatestVersion() {
do {
await Task.Delay(3000); // Wait at least 3sec before starting
} while (!(await InternetStateManager.Instance(null).HasInetAsync)); // Wait until internet awailable

var installedPackages = await GetInstalledPackagesFromPackageManager();
await CheckForUpdates(installedPackages, "https://raw.githubusercontent.com/cs-util-com/cscore/master/CsCore/PlainNetClassLib/src/Plugins/package.json");
await CheckForUpdates(installedPackages, "https://raw.githubusercontent.com/cs-util-com/cscore/master/CsCore/CsCoreUnity/Plugins/package.json");
}

private static async Task CheckForUpdates(List<UnityEditor.PackageManager.PackageInfo> installedPackages, string urlToLoadPackageJsonFrom) {
var request = new UriRestRequest(new Uri(urlToLoadPackageJsonFrom)).Send(HttpMethod.Get);
var latestPackageJson = await request.GetResult<PackageJson>();

var localPackageJson = installedPackages.SingleOrDefault(localPackage => localPackage.name == latestPackageJson.name);
if (localPackageJson != null) {
var localVersion = Version.Parse(localPackageJson.version);
var remoteVersion = Version.Parse(latestPackageJson.version);
bool isLocalLibUpToDate = localVersion >= remoteVersion;
if (!isLocalLibUpToDate) {
Log.w($"UPDATE AVAILABLE: Use the Unity package manager to update {localPackageJson.name} from your v{localVersion} to latest v{remoteVersion}");
}
} else {
Log.i($"{latestPackageJson.name.ToUpperInvariant()} was not included via package manager, this is NOT recommended! See https://github.com/cs-util-com/cscore#install-cscore-into-your-unity-project");
}
}

private static async Task<List<UnityEditor.PackageManager.PackageInfo>> GetInstalledPackagesFromPackageManager() {
var installedPackagesRequest = UnityEditor.PackageManager.Client.List();
while (!installedPackagesRequest.IsCompleted) { await TaskV2.Delay(50); }
if (installedPackagesRequest.Status != UnityEditor.PackageManager.StatusCode.Success) {
throw new InvalidOperationException("Could not receive installed packages successfully from Unity package manager");
}
return installedPackagesRequest.Result.ToList();
}

private class PackageJson {

public string name { get; set; }
public string version { get; set; }
public string displayName { get; set; }
public string description { get; set; }
public string unity { get; set; }
public string license { get; set; }
public Author author { get; set; }
public Dependencies dependencies { get; set; }

public class Author {
public string name { get; set; }
public string url { get; set; }
}

public class Dependencies {
[JsonProperty("com.unity.nuget.newtonsoft-json")]
public string ComUnityNugetNewtonsoftJson { get; set; }
}

}

}

}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ public override DirectoryEntry GetOrAddAppDataFolder(string appDataSubfolderName

public override DirectoryEntry GetCurrentDirectory() {
if (isWindows || isMacOs || isLinux || isUnityEditor) {
var assetFolder = new DirectoryInfo(Application.dataPath);
var appDataPath = new DirectoryInfo(Application.dataPath);
if (isUnityEditor) {
// Return "/Assets/TestApplicationData" to protect the rest of the Assets folder:
return assetFolder.GetChildDir("TestApplicationData").CreateV2().ToRootDirectoryEntry();
// Return "/TestApplicationData" to protect the rest of the Unity project folders:
return appDataPath.Parent.GetChildDir("TestApplicationData").CreateV2().ToRootDirectoryEntry();
}
// On Windows, Linux and MacOS it makes sense to return the install folder:
return assetFolder.ToRootDirectoryEntry();
return appDataPath.ToRootDirectoryEntry();
}
// On all other platforms there is no install folder so return the normal GetPersistentDataPath:
return GetPersistentDataPath().ToRootDirectoryEntry();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class Config {
public bool openExternallyOnAssertFail = true;
public int screenshotQuality = 70;
public int screenshotUpscaleFactor = 1;
public double maxAllowedDiff = 0.0005;
public double maxAllowedDiff = 0.0003;
public string customErrorMessage = "";
/// <summary> Any of the ImageMagick.ErrorMetric enum entry names </summary>
public string errorMetric = "MeanSquared";
Expand Down Expand Up @@ -57,19 +57,25 @@ private IEnumerator AssertNoVisualRegressionCoroutine(string id, StackTrace stac
if (id.IsNullOrEmpty()) { throw new ArgumentNullException("Invalid ID passed"); }

var idFolder = GetFolderFor(id);
var oldImg = idFolder.GetChild(id + ".regression.jpg");
var newImg = idFolder.GetChild(id + ".jpg");
var backup = idFolder.GetChild(id + ".jpg.backup");
var oldImg = idFolder.GetChild("Regression.jpg");
var newImg = idFolder.GetChild("Latest.jpg");
var backup = idFolder.GetChild("Previous.jpg.backup");

Config config = LoadConfigFor(id);
Config config = LoadConfigFor(idFolder);

yield return new WaitForEndOfFrame();
Texture2D screenShot = ScreenCapture.CaptureScreenshotAsTexture(config.screenshotUpscaleFactor);
// Texture2D screenShot = Camera.allCameras.CaptureScreenshot(); // Does not capture UI
try {
Texture2D screenShot = ScreenCapture.CaptureScreenshotAsTexture(config.screenshotUpscaleFactor);
// Texture2D screenShot = Camera.allCameras.CaptureScreenshot(); // Does not capture UI

if (newImg.Exists) { newImg.CopyToV2(backup, replaceExisting: true); }
screenShot.SaveToJpgFile(newImg, config.screenshotQuality);
screenShot.Destroy();
if (newImg.Exists) { newImg.CopyToV2(backup, replaceExisting: true); }
screenShot.SaveToJpgFile(newImg, config.screenshotQuality);
screenShot.Destroy();
}
catch (Exception e) {
Log.w("Could NOT capture screensot: \n" + e);
yield break;
}

try {
var diffImg = CalculateDiffImage(oldImg, newImg, config.maxAllowedDiff, config.errorMetric);
Expand Down Expand Up @@ -106,13 +112,13 @@ private static void HandleException(Config config, FileEntry imgToOpen, Error ex
}
}

private Config LoadConfigFor(string id) {
var configFile = GetFolderFor(id).GetChild(configFileName);
private Config LoadConfigFor(DirectoryEntry folder) {
var configFile = folder.GetChild(configFileName);
Config config = this.config;
if (configFile.IsNotNullAndExists()) {
config = configFile.LoadAs<Config>();
} else {
GetFolderFor(id).GetChild(configFileName + ".example.txt").SaveAsJson(config, asPrettyString: true);
folder.GetChild(configFileName + ".example.txt").SaveAsJson(config, asPrettyString: true);
}
return config;
}
Expand Down
2 changes: 1 addition & 1 deletion CsCore/CsCoreUnity/Plugins/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.csutil.cscore.unity",
"version": "1.5.6",
"version": "1.5.7",
"displayName": "cscore Unity",
"description": "cscore is a minimal-footprint library providing commonly used helpers & patterns for your C# projects.",
"unity": "2018.1",
Expand Down
2 changes: 1 addition & 1 deletion CsCore/PlainNetClassLib/PlainNetClassLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>com.csutil.cscore</PackageId>
<!-- https://www.nuget.org/packages/com.csutil.cscore -->
<Version>1.5.6</Version>
<Version>1.5.7</Version>
<Authors>csutil.com</Authors>
<Company>csutil.com</Company>
<Product>cscore</Product>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public static Action<S> AsThrottledDebounce<S>(this Action<S> self, double delay
return (value) => debounced(null, value);
}

public static Action AsThrottledDebounce(this Action self, double delayInMs) {
EventHandler<object> onChangedHandler = (_, args) => self();
EventHandler<object> debounced = onChangedHandler.AsThrottledDebounce(delayInMs);
return () => debounced(null, EventArgs.Empty);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public static FileEntry Compare(this MagickImage self, FileEntry imgFile, ErrorM
oldImg.LoadFromFileEntry(imgFile);

double diffValue = self.CompareV2(oldImg, errorMetric, out MagickImage imgWithDifferences);
// Log.d($"Visual difference of current scene VS image '{imgFile.Name}' is: {diffValue}");
var diffDetected = diffValue > maxAllowedDiff;
// Log.d($"Visual difference of current scene VS image '{imgFile.Name}' is: {diffValue} vs {maxAllowedDiff} (max allowed diff)");
FileEntry diffFile = imgFile.Parent.GetChild(imgFile.NameWithoutExtension + ".diff" + imgFile.ExtensionWithDot);
imgWithDifferences.SaveToFileEntry(diffFile);
imgWithDifferences.Dispose();
Expand Down
2 changes: 1 addition & 1 deletion CsCore/PlainNetClassLib/src/Plugins/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.csutil.cscore",
"version": "1.5.6",
"version": "1.5.7",
"displayName": "cscore",
"description": "cscore is a minimal-footprint library providing commonly used helpers & patterns for your C# projects.",
"unity": "2018.1",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using com.csutil.model.immutable;
using com.csutil.ui;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
Expand All @@ -11,6 +12,8 @@ public class Ui3_DataStore : UnitTestMono {

public override IEnumerator RunTest() {

var uiRoot = RootCanvas.GetOrAddRootCanvas().gameObject;

// Create an immutable datastore that will contain the data model in this example:
var log = Middlewares.NewLoggingMiddleware<MyDataModel3>();
IDataStore<MyDataModel3> store = new DataStore<MyDataModel3>(MainReducer, new MyDataModel3(), log);
Expand All @@ -19,7 +22,7 @@ public override IEnumerator RunTest() {
// Create a presenter that connectes the model with the view (the Unity UI):
var currentUserPresenter = new MyUserUi3();
// Set the target view by loading it from a prefab and setting the root GO:
currentUserPresenter.targetView = gameObject.GetViewStack().ShowView("MyUserUi1");
currentUserPresenter.targetView = uiRoot.GetViewStack().ShowView("MyUserUi1");
// Connect the model changes with the presenter:
currentUserPresenter.ListenToStoreUpdates(store, state => state.currentUser);

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ private async Task RunVisualRegressionErrorExample() {
// Now load MyUserModelv2 which creates a slightly different UI compared to MyUserModelv1:
gameObject.AddChild(await NewUiFor<MyUserModelv2>());
await assertVisually.AssertNoVisualChange("UserUiScreen");
Toast.Show("Now a visual assertion error should show in the console");
Toast.Show("See visual assertion error in the console");

}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.csutil.cscore.unity.tests",
"version": "1.5.6",
"version": "1.5.7",
"displayName": "cscore Unity Tests",
"description": "cscore is a minimal-footprint library providing commonly used helpers & patterns for your C# projects.",
"unity": "2018.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public IEnumerator Ui7_Snackbars() {
yield return UnitTestMono.RunTest<Ui7_Snackbars>(new GameObject());
}

[UnityTest]
public IEnumerator Ui8_LogConsole() {
yield return UnitTestMono.RunTest<Ui8_LogConsole>(new GameObject());
}
//[UnityTest]
//public IEnumerator Ui8_LogConsole() {
// yield return UnitTestMono.RunTest<Ui8_LogConsole>(new GameObject());
//}

[UnityTest]
public IEnumerator Ui9_AwaitDialog() {
Expand Down
5 changes: 0 additions & 5 deletions CsCore/UnityTests/Assets/TestApplicationData/.gitignore

This file was deleted.

7 changes: 7 additions & 0 deletions CsCore/UnityTests/TestApplicationData/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Regression.jpg
Latest.jpg
Latest.diff.jpg
Previous.jpg.backup

*.example.txt
CachedAssetDependencyGraph.bin
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ public class EventHandlerTests {

[Fact]
public async Task ThrottledDebounceExample1() {
int counter = 0;
Action action = () => { Interlocked.Increment(ref counter); };
// Make the action throttled / debounced:
action = action.AsThrottledDebounce(delayInMs: 50);

// Call it multiple times with less then 50ms between the calls:
action(); // The first call will always be passed through
action(); // This one will be delayed and never called because its canceled by the next call:
action(); // This one will be delayed and never called because its canceled by the next call:
action(); // This will be delayed for 50ms and then triggered because no additional call follows after it

// Wait a little bit until the action was triggered at least 2 times:
for (int i = 0; i < 50; i++) { await TaskV2.Delay(200); if (counter >= 2) { break; } }
Assert.Equal(2, counter);
}

[Fact]
public async Task ThrottledDebounceExample2() {
int counter = 0;
bool allWereGood = true;
Action<string> action = (myStringParam) => {
Expand Down
2 changes: 1 addition & 1 deletion CsCore/xUnitTests/src/Plugins/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.csutil.cscore.tests",
"version": "1.5.6",
"version": "1.5.7",
"displayName": "cscore Tests",
"description": "cscore is a minimal-footprint library providing commonly used helpers & patterns for your C# projects.",
"unity": "2018.1",
Expand Down

0 comments on commit 03ffa9d

Please sign in to comment.