@@ -5263,56 +5263,68 @@ public class ModificationCases : IEnumerable
5263
5263
[ Preserve ]
5264
5264
public ModificationCases ( ) { }
5265
5265
5266
+ private static readonly Modification [ ] ModificationAppliesToSingleActionMap =
5267
+ {
5268
+ Modification . AddBinding ,
5269
+ Modification . RemoveBinding ,
5270
+ Modification . ModifyBinding ,
5271
+ Modification . ApplyBindingOverride ,
5272
+ Modification . AddAction ,
5273
+ Modification . RemoveAction ,
5274
+ Modification . ChangeBindingMask ,
5275
+ Modification . AddDevice ,
5276
+ Modification . RemoveDevice ,
5277
+ Modification . AddDeviceGlobally ,
5278
+ Modification . RemoveDeviceGlobally ,
5279
+ // Excludes: AddMap, RemoveMap
5280
+ } ;
5281
+
5282
+ private static readonly Modification [ ] ModificationAppliesToSingletonAction =
5283
+ {
5284
+ Modification . AddBinding ,
5285
+ Modification . RemoveBinding ,
5286
+ Modification . ModifyBinding ,
5287
+ Modification . ApplyBindingOverride ,
5288
+ Modification . AddDeviceGlobally ,
5289
+ Modification . RemoveDeviceGlobally ,
5290
+ } ;
5291
+
5266
5292
public IEnumerator GetEnumerator ( )
5267
5293
{
5268
- bool ModificationAppliesToSingletonAction ( Modification modification )
5294
+ // NOTE: This executes *outside* of our test fixture during test discovery.
5295
+
5296
+ // We cannot directly create the InputAction objects within GetEnumerator() because the underlying
5297
+ // asset object might be invalid by the time the tests are actually run.
5298
+ //
5299
+ // That is, NUnit TestCases are generated once when the Assembly is loaded and will persist until it's unloaded,
5300
+ // meaning they'll never be recreated without a Domain Reload. However, since InputActionAsset is a ScriptableObject,
5301
+ // it could be deleted or otherwise invalidated between test case creation and actual test execution.
5302
+ //
5303
+ // So, instead we'll create a delegate to create the Actions object as the parameter for each test case, allowing
5304
+ // the test case to create an Actions object itself when it actually runs.
5269
5305
{
5270
- switch ( modification )
5306
+ var actionsFromAsset = new Func < IInputActionCollection2 > ( ( ) => new DefaultInputActions ( ) . asset ) ;
5307
+ foreach ( var value in Enum . GetValues ( typeof ( Modification ) ) )
5271
5308
{
5272
- case Modification . AddBinding :
5273
- case Modification . RemoveBinding :
5274
- case Modification . ModifyBinding :
5275
- case Modification . ApplyBindingOverride :
5276
- case Modification . AddDeviceGlobally :
5277
- case Modification . RemoveDeviceGlobally :
5278
- return true ;
5309
+ yield return new TestCaseData ( value , actionsFromAsset ) ;
5279
5310
}
5280
- return false ;
5281
5311
}
5282
5312
5283
- bool ModificationAppliesToSingleActionMap ( Modification modification )
5284
5313
{
5285
- switch ( modification )
5314
+ var actionMap = new Func < IInputActionCollection2 > ( CreateMap ) ;
5315
+ foreach ( var value in Enum . GetValues ( typeof ( Modification ) ) )
5286
5316
{
5287
- case Modification . AddMap :
5288
- case Modification . RemoveMap :
5289
- return false ;
5317
+ if ( ModificationAppliesToSingleActionMap . Contains ( ( Modification ) value ) )
5318
+ yield return new TestCaseData ( value , actionMap ) ;
5290
5319
}
5291
- return true ;
5292
5320
}
5293
5321
5294
- // NOTE: This executes *outside* of our test fixture during test discovery.
5295
-
5296
- // Creates a matrix of all permutations of Modifications combined with assets, maps, and singleton actions.
5297
- foreach ( var func in new Func < IInputActionCollection2 > [ ] { ( ) => new DefaultInputActions ( ) . asset , CreateMap , CreateSingletonAction } )
5298
5322
{
5323
+ var singletonMap = new Func < IInputActionCollection2 > ( CreateSingletonAction ) ;
5299
5324
foreach ( var value in Enum . GetValues ( typeof ( Modification ) ) )
5300
5325
{
5301
- var actions = func ( ) ;
5302
- if ( actions is InputActionMap map )
5303
- {
5304
- if ( map . m_SingletonAction != null )
5305
- {
5306
- if ( ! ModificationAppliesToSingletonAction ( ( Modification ) value ) )
5307
- continue ;
5308
- }
5309
- else if ( ! ModificationAppliesToSingleActionMap ( ( Modification ) value ) )
5310
- {
5311
- continue ;
5312
- }
5313
- }
5314
-
5315
- yield return new TestCaseData ( value , actions ) ;
5326
+ if ( ModificationAppliesToSingletonAction . Contains ( ( Modification ) value ) )
5327
+ yield return new TestCaseData ( value , singletonMap ) ;
5316
5328
}
5317
5329
}
5318
5330
}
@@ -5343,14 +5355,14 @@ private InputActionMap CreateSingletonAction()
5343
5355
[ Test ]
5344
5356
[ Category ( "Actions" ) ]
5345
5357
[ TestCaseSource ( typeof ( ModificationCases ) ) ]
5346
- public void Actions_CanHandleModification ( Modification modification , IInputActionCollection2 actions )
5358
+ public void Actions_CanHandleModification ( Modification modification , Func < IInputActionCollection2 > getActions )
5347
5359
{
5348
5360
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
5349
5361
// Exclude project-wide actions from this test
5350
5362
InputSystem . actions ? . Disable ( ) ;
5351
5363
InputActionState . DestroyAllActionMapStates ( ) ; // Required for `onActionChange` to report correct number of changes
5352
5364
#endif
5353
-
5365
+ var actions = getActions ( ) ;
5354
5366
var gamepad = InputSystem . AddDevice < Gamepad > ( ) ;
5355
5367
5356
5368
if ( modification == Modification . AddDevice || modification == Modification . RemoveDevice )
0 commit comments