暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

TestSettingsDeserializer.cs 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using UnityEditor.TestTools.TestRunner.Api;
  6. using UnityEngine;
  7. using UnityEngine.TestRunner.NUnitExtensions.Runner;
  8. namespace UnityEditor.TestTools.TestRunner
  9. {
  10. /// <summary>
  11. /// Handles deserialization of TestSettings from a provided json file path.
  12. /// </summary>
  13. internal class TestSettingsDeserializer : ITestSettingsDeserializer
  14. {
  15. private static readonly SettingsMap[] s_SettingsMapping =
  16. {
  17. new SettingsMap<ScriptingImplementation>("scriptingBackend", (settings, value) => settings.scriptingBackend = value),
  18. new SettingsMap<string>("architecture", (settings, value) => settings.Architecture = value),
  19. new SettingsMap<ApiCompatibilityLevel>("apiProfile", (settings, value) => settings.apiProfile = value),
  20. new SettingsMap<bool>("appleEnableAutomaticSigning", (settings, value) => settings.appleEnableAutomaticSigning = value),
  21. new SettingsMap<string>("appleDeveloperTeamID", (settings, value) => settings.appleDeveloperTeamID = value),
  22. new SettingsMap<ProvisioningProfileType>("iOSManualProvisioningProfileType", (settings, value) => settings.iOSManualProvisioningProfileType = value),
  23. new SettingsMap<string>("iOSManualProvisioningProfileID", (settings, value) => settings.iOSManualProvisioningProfileID = value),
  24. new SettingsMap<string>("iOSTargetSDK", (settings, value) => settings.iOSTargetSDK = value),
  25. new SettingsMap<ProvisioningProfileType>("tvOSManualProvisioningProfileType", (settings, value) => settings.tvOSManualProvisioningProfileType = value),
  26. new SettingsMap<string>("tvOSManualProvisioningProfileID", (settings, value) => settings.tvOSManualProvisioningProfileID = value),
  27. new SettingsMap<string>("tvOSTargetSDK", (settings, value) => settings.tvOSTargetSDK = value),
  28. new SettingsMap<string>("playerGraphicsAPI", (settings, value) =>
  29. {
  30. settings.autoGraphicsAPIs = false;
  31. settings.playerGraphicsAPIs = new[] {value};
  32. }),
  33. new SettingsMap<bool>("androidBuildAppBundle", (settings, value) =>
  34. {
  35. settings.androidBuildAppBundle = value;
  36. }),
  37. new SettingsMap<List<object>>("ignoreTests", (settings, list) =>
  38. {
  39. settings.ignoreTests = list.Select(item =>
  40. {
  41. var dictionary = (Dictionary<string, object>)item;
  42. if (dictionary.ContainsKey("test") && dictionary.ContainsKey("ignoreComment"))
  43. {
  44. return new IgnoreTest()
  45. {
  46. test = dictionary["test"] as string,
  47. ignoreComment = dictionary["ignoreComment"] as string
  48. };
  49. }
  50. throw new Exception("Wrong format for ignore test. Expected \"test\" and \"ignoreComment\".");
  51. }).ToArray();
  52. }),
  53. new SettingsMap<Dictionary<string, object>>("featureFlags", (settings, dictionary) =>
  54. {
  55. var converted = dictionary.ToDictionary(pair => pair.Key, pair => (bool)pair.Value);
  56. var featureFlags = new FeatureFlags();
  57. if (converted.ContainsKey("fileCleanUpCheck"))
  58. {
  59. featureFlags.fileCleanUpCheck = converted["fileCleanUpCheck"];
  60. }
  61. if (converted.ContainsKey("strictDomainReload"))
  62. {
  63. featureFlags.strictDomainReload = converted["strictDomainReload"];
  64. }
  65. if (converted.ContainsKey("requiresSplashScreen"))
  66. {
  67. featureFlags.requiresSplashScreen = converted["requiresSplashScreen"];
  68. }
  69. if (converted.ContainsKey("disableNestedEnumeratorBugfix"))
  70. {
  71. featureFlags.disableNestedEnumeratorBugfix = converted["disableNestedEnumeratorBugfix"];
  72. }
  73. settings.featureFlags = featureFlags;
  74. }),
  75. #if UNITY_2023_2_OR_NEWER
  76. new SettingsMap<WebGLClientBrowserType>("webGLClientBrowserType", (settings, value) => settings.webGLClientBrowserType = value),
  77. new SettingsMap<string>("webGLClientBrowserPath", (settings, value) => settings.webGLClientBrowserPath = value),
  78. #endif
  79. };
  80. private readonly Func<ITestSettings> m_TestSettingsFactory;
  81. public TestSettingsDeserializer(Func<ITestSettings> testSettingsFactory)
  82. {
  83. m_TestSettingsFactory = testSettingsFactory;
  84. }
  85. public ITestSettings GetSettingsFromJsonFile(string jsonFilePath)
  86. {
  87. var text = File.ReadAllText(jsonFilePath);
  88. var settingsDictionary = Json.Deserialize(text) as Dictionary<string, object>;
  89. var testSettings = m_TestSettingsFactory();
  90. if (settingsDictionary == null)
  91. {
  92. return testSettings;
  93. }
  94. foreach (var settingsMap in s_SettingsMapping)
  95. {
  96. if (!settingsDictionary.ContainsKey(settingsMap.Key))
  97. {
  98. continue;
  99. }
  100. if (settingsMap.Type.IsEnum)
  101. {
  102. SetEnumValue(settingsMap.Key, settingsDictionary[settingsMap.Key], settingsMap.Type, value => settingsMap.ApplyToSettings(testSettings, value));
  103. }
  104. else
  105. {
  106. SetValue(settingsMap.Key, settingsDictionary[settingsMap.Key], settingsMap.Type, value => settingsMap.ApplyToSettings(testSettings, value));
  107. }
  108. }
  109. return testSettings;
  110. }
  111. private abstract class SettingsMap
  112. {
  113. public string Key { get; }
  114. public Type Type { get; }
  115. protected SettingsMap(string key, Type type)
  116. {
  117. Key = key;
  118. Type = type;
  119. }
  120. public abstract void ApplyToSettings(ITestSettings settings, object value);
  121. }
  122. private class SettingsMap<T> : SettingsMap
  123. {
  124. private Action<ITestSettings, T> m_Setter;
  125. public SettingsMap(string key, Action<ITestSettings, T> setter) : base(key, typeof(T))
  126. {
  127. m_Setter = setter;
  128. }
  129. public override void ApplyToSettings(ITestSettings settings, object value)
  130. {
  131. m_Setter(settings, (T)value);
  132. }
  133. }
  134. private static void SetEnumValue(string key, object value, Type type, Action<object> setter)
  135. {
  136. object enumValue;
  137. if (TryGetEnum(value as string, type, out enumValue))
  138. {
  139. setter(enumValue);
  140. return;
  141. }
  142. var acceptedValues = string.Join(", ", Enum.GetValues(type).OfType<object>().Select(val => val.ToString()).ToArray());
  143. Debug.LogFormat("Could not convert '{0}' argument '{1}' to a valid {2}. Accepted values: {3}.", key, value, type.Name, acceptedValues);
  144. }
  145. private static bool TryGetEnum(string value, Type type, out object enumValue)
  146. {
  147. try
  148. {
  149. enumValue = Enum.Parse(type, value, true);
  150. return true;
  151. }
  152. catch (Exception)
  153. {
  154. enumValue = null;
  155. return false;
  156. }
  157. }
  158. private static void SetValue(string key, object value, Type type, Action<object> setter)
  159. {
  160. if (type.IsInstanceOfType(value))
  161. {
  162. setter(value);
  163. return;
  164. }
  165. Debug.LogFormat("Could not convert '{0}' argument '{1}' to a valid {2}.", key, value, type.Name);
  166. }
  167. }
  168. }