@@ -5223,56 +5223,68 @@ public class ModificationCases : IEnumerable
5223
5223
[ Preserve ]
5224
5224
public ModificationCases ( ) { }
5225
5225
5226
+ private static readonly Modification [ ] ModificationAppliesToSingleActionMap =
5227
+ {
5228
+ Modification . AddBinding ,
5229
+ Modification . RemoveBinding ,
5230
+ Modification . ModifyBinding ,
5231
+ Modification . ApplyBindingOverride ,
5232
+ Modification . AddAction ,
5233
+ Modification . RemoveAction ,
5234
+ Modification . ChangeBindingMask ,
5235
+ Modification . AddDevice ,
5236
+ Modification . RemoveDevice ,
5237
+ Modification . AddDeviceGlobally ,
5238
+ Modification . RemoveDeviceGlobally ,
5239
+ // Excludes: AddMap, RemoveMap
5240
+ } ;
5241
+
5242
+ private static readonly Modification [ ] ModificationAppliesToSingletonAction =
5243
+ {
5244
+ Modification . AddBinding ,
5245
+ Modification . RemoveBinding ,
5246
+ Modification . ModifyBinding ,
5247
+ Modification . ApplyBindingOverride ,
5248
+ Modification . AddDeviceGlobally ,
5249
+ Modification . RemoveDeviceGlobally ,
5250
+ } ;
5251
+
5226
5252
public IEnumerator GetEnumerator ( )
5227
5253
{
5228
- bool ModificationAppliesToSingletonAction ( Modification modification )
5254
+ // NOTE: This executes *outside* of our test fixture during test discovery.
5255
+
5256
+ // We cannot directly create the InputAction objects within GetEnumerator() because the underlying
5257
+ // asset object might be invalid by the time the tests are actually run.
5258
+ //
5259
+ // That is, NUnit TestCases are generated once when the Assembly is loaded and will persist until it's unloaded,
5260
+ // meaning they'll never be recreated without a Domain Reload. However, since InputActionAsset is a ScriptableObject,
5261
+ // it could be deleted or otherwise invalidated between test case creation and actual test execution.
5262
+ //
5263
+ // So, instead we'll create a delegate to create the Actions object as the parameter for each test case, allowing
5264
+ // the test case to create an Actions object itself when it actually runs.
5229
5265
{
5230
- switch ( modification )
5266
+ var actionsFromAsset = new Func < IInputActionCollection2 > ( ( ) => new DefaultInputActions ( ) . asset ) ;
5267
+ foreach ( var value in Enum . GetValues ( typeof ( Modification ) ) )
5231
5268
{
5232
- case Modification . AddBinding :
5233
- case Modification . RemoveBinding :
5234
- case Modification . ModifyBinding :
5235
- case Modification . ApplyBindingOverride :
5236
- case Modification . AddDeviceGlobally :
5237
- case Modification . RemoveDeviceGlobally :
5238
- return true ;
5269
+ yield return new TestCaseData ( value , actionsFromAsset ) ;
5239
5270
}
5240
- return false ;
5241
5271
}
5242
5272
5243
- bool ModificationAppliesToSingleActionMap ( Modification modification )
5244
5273
{
5245
- switch ( modification )
5274
+ var actionMap = new Func < IInputActionCollection2 > ( CreateMap ) ;
5275
+ foreach ( var value in Enum . GetValues ( typeof ( Modification ) ) )
5246
5276
{
5247
- case Modification . AddMap :
5248
- case Modification . RemoveMap :
5249
- return false ;
5277
+ if ( ModificationAppliesToSingleActionMap . Contains ( ( Modification ) value ) )
5278
+ yield return new TestCaseData ( value , actionMap ) ;
5250
5279
}
5251
- return true ;
5252
5280
}
5253
5281
5254
- // NOTE: This executes *outside* of our test fixture during test discovery.
5255
-
5256
- // Creates a matrix of all permutations of Modifications combined with assets, maps, and singleton actions.
5257
- foreach ( var func in new Func < IInputActionCollection2 > [ ] { ( ) => new DefaultInputActions ( ) . asset , CreateMap , CreateSingletonAction } )
5258
5282
{
5283
+ var singletonMap = new Func < IInputActionCollection2 > ( CreateSingletonAction ) ;
5259
5284
foreach ( var value in Enum . GetValues ( typeof ( Modification ) ) )
5260
5285
{
5261
- var actions = func ( ) ;
5262
- if ( actions is InputActionMap map )
5263
- {
5264
- if ( map . m_SingletonAction != null )
5265
- {
5266
- if ( ! ModificationAppliesToSingletonAction ( ( Modification ) value ) )
5267
- continue ;
5268
- }
5269
- else if ( ! ModificationAppliesToSingleActionMap ( ( Modification ) value ) )
5270
- {
5271
- continue ;
5272
- }
5273
- }
5274
-
5275
- yield return new TestCaseData ( value , actions ) ;
5286
+ if ( ModificationAppliesToSingletonAction . Contains ( ( Modification ) value ) )
5287
+ yield return new TestCaseData ( value , singletonMap ) ;
5276
5288
}
5277
5289
}
5278
5290
}
@@ -5303,14 +5315,14 @@ private InputActionMap CreateSingletonAction()
5303
5315
[ Test ]
5304
5316
[ Category ( "Actions" ) ]
5305
5317
[ TestCaseSource ( typeof ( ModificationCases ) ) ]
5306
- public void Actions_CanHandleModification ( Modification modification , IInputActionCollection2 actions )
5318
+ public void Actions_CanHandleModification ( Modification modification , Func < IInputActionCollection2 > getActions )
5307
5319
{
5308
5320
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
5309
5321
// Exclude project-wide actions from this test
5310
5322
InputSystem . actions ? . Disable ( ) ;
5311
5323
InputActionState . DestroyAllActionMapStates ( ) ; // Required for `onActionChange` to report correct number of changes
5312
5324
#endif
5313
-
5325
+ var actions = getActions ( ) ;
5314
5326
var gamepad = InputSystem . AddDevice < Gamepad > ( ) ;
5315
5327
5316
5328
if ( modification == Modification . AddDevice || modification == Modification . RemoveDevice )
0 commit comments