A game about forced loneliness, made by TACStudios
1#if !UNITY_2023_2_OR_NEWER 2using System; 3using System.Collections.Generic; 4using System.Linq; 5using NUnit.Framework; 6using NUnit.Framework.Interfaces; 7using UnityEditor.TestTools.TestRunner.TestRun; 8using UnityEngine; 9using UnityEngine.TestTools; 10 11namespace UnityEditor.TestTools.TestRunner.Api.Analytics 12{ 13 internal static class AnalyticsReporter 14 { 15 private const string VendorKey = "unity.test-framework"; 16 private const string RunFinishedEventName = "runFinished"; 17 private const string AnalyzeTestTreeName = "analyzeTestTree"; 18 19 private static bool isSetUp; 20 private static IDictionary<string, bool> methodsAnalyzed; 21 private static IDictionary<string, bool> typesAnalyzed; 22 23 private static void SetUpIfNeeded() 24 { 25 if (isSetUp) 26 { 27 return; 28 } 29 30 isSetUp = true; 31 EditorAnalytics.RegisterEventWithLimit(RunFinishedEventName, 60, 30, VendorKey); 32 EditorAnalytics.RegisterEventWithLimit(AnalyzeTestTreeName, 3, 30, VendorKey); 33 } 34 35 [InitializeOnLoadMethod] 36 private static void RegisterCallbacks() 37 { 38 ScriptableObject.CreateInstance<TestRunnerApi>().RegisterCallbacks(new AnalyticsTestCallback(ReportRunFinished)); 39 } 40 41 private static void ReportRunFinished(ITestResultAdaptor testResult) 42 { 43 SetUpIfNeeded(); 44 45 var activeRuns = TestJobDataHolder.instance.TestRuns; 46 if (activeRuns.Count == 0) 47 { 48 return; 49 } 50 51 var executionSettings = activeRuns[0].executionSettings; 52 var filter = executionSettings.filters.First(); 53 var runFinishedData = new RunFinishedData 54 { 55 totalTests = testResult.Test.TestCaseCount, 56 numPassedTests = testResult.PassCount, 57 numFailedTests = testResult.FailCount, 58 numInconclusiveTests = testResult.InconclusiveCount, 59 numSkippedTests = testResult.SkipCount, 60 testModeFilter = (int)filter.testMode, 61 targetPlatform = executionSettings.targetPlatform != null ? executionSettings.targetPlatform.ToString() : "editor", 62 runSynchronously = executionSettings.runSynchronously, 63 isCustomRunner = false, 64 isFiltering = executionSettings.filters.Any(f => f.HasAny()), 65 isAutomated = IsCommandLineArgSet("-automated"), 66 isFromCommandLine = IsCommandLineArgSet("-runTests"), 67 totalTestDuration = testResult.Duration, 68 totalRunDuration = (DateTime.Now - Convert.ToDateTime(activeRuns[0].startTime)).TotalSeconds 69 }; 70 71 EditorAnalytics.SendEventWithLimit(RunFinishedEventName, runFinishedData, 1); 72 } 73 74 private static bool IsCommandLineArgSet(string command) 75 { 76 return Environment.GetCommandLineArgs().Any(c => c == command); 77 } 78 79 internal static void AnalyzeTestTreeAndReport(ITest testTree) 80 { 81 SetUpIfNeeded(); 82 83 typesAnalyzed = new Dictionary<string, bool>(); 84 methodsAnalyzed = new Dictionary<string, bool>(); 85 var data = new TestTreeData(); 86 AnalyzeTestTreeNode(testTree, data); 87 EditorAnalytics.SendEventWithLimit(AnalyzeTestTreeName, data, 1); 88 } 89 90 private static void AnalyzeTestTreeNode(ITest node, TestTreeData data) 91 { 92 var attributes = GetAttributes(node).ToArray(); 93 if (attributes.OfType<TestAttribute>().Any()) 94 { 95 data.numTestAttributes++; 96 } 97 if (attributes.OfType<UnityTestAttribute>().Any()) 98 { 99 data.numUnityTestAttributes++; 100 } 101 if (attributes.OfType<CategoryAttribute>().Any()) 102 { 103 data.numCategoryAttributes++; 104 } 105 if (attributes.OfType<TestFixtureAttribute>().Any()) 106 { 107 data.numTestFixtureAttributes++; 108 } 109 if (attributes.OfType<ConditionalIgnoreAttribute>().Any()) 110 { 111 data.numConditionalIgnoreAttributes++; 112 } 113 if (attributes.OfType<UnityPlatformAttribute>().Any()) 114 { 115 data.numUnityPlatformAttributes++; 116 } 117 118 if (node.HasChildren) 119 { 120 foreach (var test in node.Tests) 121 { 122 AnalyzeTestTreeNode(test, data); 123 } 124 } 125 else 126 { 127 data.totalNumberOfTests++; 128 } 129 } 130 131 private static IEnumerable<NUnitAttribute> GetAttributes(ITest node) 132 { 133 if (node.Method != null) 134 { 135 var key = $"{node.MethodName},{node.ClassName}"; 136 if (methodsAnalyzed.ContainsKey(key)) 137 { 138 yield break; 139 } 140 141 methodsAnalyzed[key] = true; 142 foreach (var attribute in (node).Method.GetCustomAttributes<NUnitAttribute>(true)) 143 { 144 yield return attribute; 145 } 146 147 var typeKey = node.Method.TypeInfo.FullName; 148 if (typesAnalyzed.ContainsKey(typeKey)) 149 { 150 yield break; 151 } 152 153 typesAnalyzed[typeKey] = true; 154 foreach (var attribute in node.Method.TypeInfo.GetCustomAttributes<NUnitAttribute>(true)) 155 { 156 yield return attribute; 157 } 158 } 159 } 160 } 161} 162#endif