first commit

This commit is contained in:
Kirill Chikalin
2024-11-16 13:20:07 +03:00
commit a3072a3693
538 changed files with 108153 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
using AssetStoreTools.Validator.Data;
using System;
using System.Linq;
using UnityEngine;
namespace AssetStoreTools.Validator.TestDefinitions
{
internal class AutomatedTest : ValidationTest
{
public AutomatedTest(ValidationTestScriptableObject source) : base(source) { }
public override void Run(ValidationTestConfig config)
{
Type testClass;
if (TestScript == null || (testClass = TestScript.GetClass()) == null)
{
Debug.LogError($"Cannot run test {Title} - Test Script class was not found");
return;
}
if (!testClass.GetInterfaces().Contains(typeof(ITestScript)))
{
Debug.LogError($"Cannot run test {Title} - Test Script class is not derived from {nameof(ITestScript)}");
return;
}
var testMethod = testClass.GetMethod("Run");
if (testMethod == null)
{
Debug.LogError($"Cannot run test {Title} - Run() method was not found");
return;
}
try
{
Result = (TestResult)testMethod.Invoke(Activator.CreateInstance(testClass), new[] { config });
}
catch (Exception e)
{
var result = new TestResult() { Result = TestResult.ResultStatus.Undefined };
result.AddMessage("An exception was caught when running this test case. See Console for more details");
Debug.LogError($"An exception was caught when running validation for test case '{Title}'\n{e.InnerException}");
Result = result;
}
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b284048af6fef0d49b8c3a37f7083d04
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Test Definitions/AutomatedTest.cs
uploadId: 681981

View File

@@ -0,0 +1,9 @@
using AssetStoreTools.Validator.Data;
namespace AssetStoreTools.Validator.TestDefinitions
{
internal interface ITestScript
{
TestResult Run(ValidationTestConfig config);
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 839ef1f3e773ab347b66932d3f810aec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Test Definitions/ITestScript.cs
uploadId: 681981

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d62652f91f698904ea662c6ab252ea59
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
#if UNITY_ASTOOLS_DEVELOPMENT
using UnityEngine;
#endif
namespace AssetStoreTools.Validator.TestDefinitions
{
#if UNITY_ASTOOLS_DEVELOPMENT
[CreateAssetMenu(fileName = "AutomatedTest", menuName = "Asset Store Validator/Automated Test")]
#endif
internal class AutomatedTestScriptableObject : ValidationTestScriptableObject { }
}

View File

@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: d813ff809ae82f643bf975031305d541
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Test Definitions/Scriptable
Objects/AutomatedTestScriptableObject.cs
uploadId: 681981

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7cd52466a2239344d90c3043b7afc1e4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,181 @@
using UnityEditor;
using UnityEngine;
using System.Linq;
using AssetStoreTools.Validator.Utility;
using AssetStoreTools.Validator.Data;
namespace AssetStoreTools.Validator.TestDefinitions
{
[CustomEditor(typeof(ValidationTestScriptableObject), true)]
internal class ValidationTestScriptableObjectInspector : UnityEditor.Editor
{
private enum FilterSeverity
{
Warning,
Fail
}
private enum FilterType
{
UseFilter,
ExcludeFilter
}
private ValidationTestScriptableObject _data;
private ValidationTestScriptableObject[] _allObjects;
private SerializedProperty _script;
private SerializedProperty _testScript;
private SerializedProperty _category;
private SerializedProperty _failFilterProperty;
private SerializedProperty _isInclusiveProperty;
private SerializedProperty _appliesToSubCategories;
private SerializedProperty _categoryFilter;
private bool _hadChanges;
private void OnEnable()
{
if (target == null) return;
_data = target as ValidationTestScriptableObject;
_script = serializedObject.FindProperty("m_Script");
_testScript = serializedObject.FindProperty(nameof(ValidationTestScriptableObject.TestScript));
_category = serializedObject.FindProperty(nameof(ValidationTestScriptableObject.CategoryInfo));
_failFilterProperty = _category.FindPropertyRelative(nameof(ValidationTestScriptableObject.CategoryInfo.IsFailFilter));
_isInclusiveProperty = _category.FindPropertyRelative(nameof(ValidationTestScriptableObject.CategoryInfo.IsInclusiveFilter));
_appliesToSubCategories = _category.FindPropertyRelative(nameof(ValidationTestScriptableObject.CategoryInfo.AppliesToSubCategories));
_categoryFilter = _category.FindPropertyRelative(nameof(ValidationTestScriptableObject.CategoryInfo.Filter));
_allObjects = ValidatorUtility.GetAutomatedTestCases(ValidatorUtility.SortType.Id);
_hadChanges = false;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.LabelField(GetInspectorTitle(), new GUIStyle(EditorStyles.centeredGreyMiniLabel) {fontSize = 24}, GUILayout.MinHeight(50));
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.PropertyField(_script);
EditorGUI.BeginChangeCheck();
// ID field
EditorGUILayout.IntField("Test Id", _data.Id);
if (!ValidateID())
EditorGUILayout.HelpBox("ID is already in use", MessageType.Warning);
EditorGUI.EndDisabledGroup();
// Other fields
_data.Title = EditorGUILayout.TextField("Title", _data.Title);
if (string.IsNullOrEmpty(_data.Title))
EditorGUILayout.HelpBox("Title cannot be empty", MessageType.Warning);
EditorGUILayout.LabelField("Description");
GUIStyle myTextAreaStyle = new GUIStyle(EditorStyles.textArea) { wordWrap = true };
_data.Description = EditorGUILayout.TextArea(_data.Description, myTextAreaStyle);
EditorGUILayout.PropertyField(_testScript);
if (_testScript.objectReferenceValue != null)
{
var generatedScriptType = (_testScript.objectReferenceValue as MonoScript).GetClass();
if (generatedScriptType == null || !generatedScriptType.GetInterfaces().Contains(typeof(ITestScript)))
EditorGUILayout.HelpBox($"Test Script does not derive from {nameof(ITestScript)}. Test execution will fail", MessageType.Warning);
}
else if (!string.IsNullOrEmpty(_data.Title))
{
var generatedScriptName = GenerateTestScriptName();
EditorGUILayout.LabelField($"Proposed script name: <i>{generatedScriptName}.cs</i>", new GUIStyle("Label") { richText = true });
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Generate Test Method Script", GUILayout.MaxWidth(200f)))
{
var generatedScript = ValidatorUtility.GenerateTestScript(generatedScriptName);
_testScript.objectReferenceValue = generatedScript;
}
EditorGUILayout.EndHorizontal();
}
// Category Filter Options
EditorGUILayout.Space(30);
var filterSeverity = (FilterSeverity)EditorGUILayout.EnumPopup("Fail Type", _failFilterProperty.boolValue ? FilterSeverity.Fail : FilterSeverity.Warning);
_failFilterProperty.boolValue = filterSeverity == FilterSeverity.Fail ? true : false;
var filterType = (FilterType)EditorGUILayout.EnumPopup("Filtering rule", _isInclusiveProperty.boolValue ? FilterType.UseFilter : FilterType.ExcludeFilter);
_isInclusiveProperty.boolValue = filterType == FilterType.UseFilter ? true : false;
EditorGUILayout.PropertyField(_appliesToSubCategories);
EditorGUILayout.Space(10);
EditorGUILayout.BeginHorizontal(GUI.skin.FindStyle("HelpBox"));
EditorGUILayout.LabelField(GetFilterDescription(_failFilterProperty.boolValue, _isInclusiveProperty.boolValue), new GUIStyle(GUI.skin.label) { wordWrap = true, richText = true });
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space(10);
EditorGUILayout.PropertyField(_categoryFilter);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(target);
_hadChanges = true;
}
_hadChanges = serializedObject.ApplyModifiedProperties() || _hadChanges;
}
private string GetInspectorTitle()
{
switch (_data)
{
case AutomatedTestScriptableObject _:
return "Automated Test";
default:
return "Miscellaneous Test";
}
}
private string GenerateTestScriptName()
{
var name = _data.Title.Replace(" ", "");
return name;
}
private string GetFilterDescription(bool isFailFilter, bool isInclusive)
{
string text = $"When a <i>{TestResult.ResultStatus.VariableSeverityIssue}</i> result type is returned from the test method:\n\n";
if(isFailFilter)
{
if(isInclusive)
return text + "• <b>Categories IN the filter</b> will result in a <color=red>FAIL</color>.\n• <b>Categories NOT in the filter</b> will result in a <color=yellow>WARNING</color>";
else
return text + "• <b>Categories NOT in the filter</b> will result in a <color=red>FAIL</color>.\n• <b>Categories IN the filter</b> will result in a <color=yellow>WARNING</color>";
}
else
{
if (isInclusive)
return text + "• <b>Categories IN the filter</b> will result in a <color=yellow>WARNING</color>.\n• <b>Categories NOT in the filter</b> will result in a <color=red>FAIL</color>";
else
return text + "• <b>Categories NOT in the filter</b> will result in a <color=yellow>WARNING</color>.\n• <b>Categories IN the filter</b> will result in a <color=red>FAIL</color>";
}
}
private bool ValidateID()
{
return !_allObjects.Any(x => x.Id == _data.Id && x != _data);
}
private void OnDisable()
{
if (!_hadChanges) return;
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
}

View File

@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 06d76b0e6df91eb43ac956f883c4a2da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Test Definitions/Scriptable
Objects/Editor/ValidationTestScriptableObjectInspector.cs
uploadId: 681981

View File

@@ -0,0 +1,33 @@
using AssetStoreTools.Validator.Categories;
using AssetStoreTools.Validator.Utility;
using UnityEditor;
using UnityEngine;
namespace AssetStoreTools.Validator.TestDefinitions
{
internal abstract class ValidationTestScriptableObject : ScriptableObject
{
[SerializeField, HideInInspector]
private bool HasBeenInitialized;
public int Id;
public string Title;
public string Description;
public ValidatorCategory CategoryInfo;
public MonoScript TestScript;
private void OnEnable()
{
// To do: maybe replace with Custom Inspector
if (HasBeenInitialized)
return;
var existingTestCases = ValidatorUtility.GetAutomatedTestCases(ValidatorUtility.SortType.Id);
if (existingTestCases.Length > 0)
Id = existingTestCases[existingTestCases.Length - 1].Id + 1;
else
Id = 1;
HasBeenInitialized = true;
}
}
}

View File

@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 11c2422f057b75a458e184d169a00eb6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Test Definitions/Scriptable
Objects/ValidationTestScriptableObject.cs
uploadId: 681981

View File

@@ -0,0 +1,36 @@
using AssetStoreTools.Validator.Categories;
using AssetStoreTools.Validator.Data;
using UnityEditor;
namespace AssetStoreTools.Validator.TestDefinitions
{
internal abstract class ValidationTest
{
public int Id;
public string Title;
public string Description;
public MonoScript TestScript;
public ValidatorCategory CategoryInfo;
public TestResult Result;
protected ValidationTest(ValidationTestScriptableObject source)
{
Id = source.Id;
Title = source.Title;
Description = source.Description;
TestScript = source.TestScript;
CategoryInfo = source.CategoryInfo;
Result = new TestResult();
}
public abstract void Run(ValidationTestConfig config);
public string Slugify(string value)
{
string newValue = value.Replace(' ', '-').ToLower();
return newValue;
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 095d629656748914bb6202598876fdf4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Test Definitions/ValidationTest.cs
uploadId: 681981

View File

@@ -0,0 +1,7 @@
namespace AssetStoreTools.Validator.TestDefinitions
{
public class ValidationTestConfig
{
public string[] ValidationPaths;
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 42aa5ee716f3fc340a5055b4c42a0b55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Test Definitions/ValidationTestConfig.cs
uploadId: 681981