Skip to content

Commit f159a49

Browse files
committed
Tmp
1 parent 55fe8ef commit f159a49

File tree

3 files changed

+50
-80
lines changed

3 files changed

+50
-80
lines changed

src/Components/Components/src/ComponentSubscriptionKey.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Diagnostics;
45
using Microsoft.AspNetCore.Components.Rendering;
56

67
namespace Microsoft.AspNetCore.Components.Infrastructure;
78

8-
// TODO: Add debugger display to show the component state component type and property name.
9+
[DebuggerDisplay("{GetDebuggerDisplay(),nq}")]
910
internal readonly struct ComponentSubscriptionKey(ComponentState subscriber, string propertyName) : IEquatable<ComponentSubscriptionKey>
1011
{
1112
public ComponentState Subscriber { get; } = subscriber;
@@ -20,4 +21,7 @@ public override bool Equals(object? obj)
2021

2122
public override int GetHashCode()
2223
=> HashCode.Combine(Subscriber, PropertyName);
24+
25+
private string GetDebuggerDisplay()
26+
=> $"{Subscriber.Component.GetType().Name}.{PropertyName}";
2327
}

src/Components/Components/test/PersistentState/ComponentStatePersistenceManagerTest.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,51 @@ public async Task PersistStateAsync_InvokesAllCallbacksEvenIfACallbackIsRemovedA
353353
Assert.Equal(4, executionSequence.Count);
354354
}
355355

356+
[Fact]
357+
public async Task RestoreStateAsync_ValidatesOnlySupportUpdatesWhenRestoreContextValueUpdate()
358+
{
359+
var store = new TestStore([]);
360+
361+
var persistenceManager = new ComponentStatePersistenceManager(
362+
NullLogger<ComponentStatePersistenceManager>.Instance,
363+
CreateServiceProvider());
364+
365+
// First restore should work (initialize state)
366+
await persistenceManager.RestoreStateAsync(store, RestoreContext.InitialValue);
367+
368+
// Second restore with non-ValueUpdate context should throw
369+
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() =>
370+
persistenceManager.RestoreStateAsync(store, RestoreContext.InitialValue));
371+
372+
Assert.Equal("State already initialized.", exception.Message);
373+
}
374+
375+
[Fact]
376+
public async Task RestoreStateAsync_ValidatesRegisteredUpdateCallbacksAreInvokedOnValueUpdates()
377+
{
378+
var store = new TestStore([]);
379+
380+
var persistenceManager = new ComponentStatePersistenceManager(
381+
NullLogger<ComponentStatePersistenceManager>.Instance,
382+
CreateServiceProvider());
383+
384+
var callbackInvoked = false;
385+
386+
// First restore to initialize state
387+
await persistenceManager.RestoreStateAsync(store, RestoreContext.InitialValue);
388+
389+
// Register a callback for value updates through the state object
390+
var options = new RestoreOptions { RestoreBehavior = RestoreBehavior.Default, AllowUpdates = true };
391+
persistenceManager.State.RegisterOnRestoring(() => { callbackInvoked = true; }, options);
392+
// RegisterOnRestoring will invoke the callback immediately, so we reset it
393+
callbackInvoked = false;
394+
395+
// Second restore with ValueUpdate context should invoke callbacks
396+
await persistenceManager.RestoreStateAsync(store, RestoreContext.ValueUpdate);
397+
398+
Assert.True(callbackInvoked);
399+
}
400+
356401
private class TestRenderer : Renderer
357402
{
358403
public TestRenderer() : base(new ServiceCollection().BuildServiceProvider(), NullLoggerFactory.Instance)

src/Components/Components/test/PersistentState/PersistentComponentStateTest.cs

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -284,83 +284,4 @@ public void RegisterOnRestoring_SubscriptionCanBeDisposed()
284284
// Assert
285285
Assert.Empty(callbacks);
286286
}
287-
288-
[Fact]
289-
public async Task ComponentStatePersistenceManagerRestoreStateAsync_ValidatesOnlySupportUpdatesWhenRestoreContextValueUpdate()
290-
{
291-
// Arrange
292-
var store = Mock.Of<IPersistentComponentStateStore>();
293-
Mock.Get(store)
294-
.Setup(s => s.GetPersistedStateAsync())
295-
.ReturnsAsync(new Dictionary<string, byte[]>());
296-
297-
var persistenceManager = new ComponentStatePersistenceManager(
298-
NullLogger<ComponentStatePersistenceManager>.Instance,
299-
CreateServiceProvider());
300-
301-
// Act & Assert
302-
// First restore should work (initialize state)
303-
await persistenceManager.RestoreStateAsync(store, RestoreContext.InitialValue);
304-
305-
// Second restore with non-ValueUpdate context should throw
306-
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() =>
307-
persistenceManager.RestoreStateAsync(store, RestoreContext.InitialValue));
308-
309-
Assert.Equal("State already initialized.", exception.Message);
310-
}
311-
312-
[Fact]
313-
public async Task ComponentStatePersistenceManagerRestoreStateAsync_ValidatesRegisteredUpdateCallbacksAreInvokedOnValueUpdates()
314-
{
315-
// Arrange
316-
var store = Mock.Of<IPersistentComponentStateStore>();
317-
Mock.Get(store)
318-
.Setup(s => s.GetPersistedStateAsync())
319-
.ReturnsAsync(new Dictionary<string, byte[]>());
320-
321-
var persistenceManager = new ComponentStatePersistenceManager(
322-
NullLogger<ComponentStatePersistenceManager>.Instance,
323-
CreateServiceProvider());
324-
325-
var callbackInvoked = false;
326-
327-
// Act
328-
// First restore to initialize state
329-
await persistenceManager.RestoreStateAsync(store, RestoreContext.InitialValue);
330-
331-
// Register a callback for value updates through the state object
332-
var options = new RestoreOptions { RestoreBehavior = RestoreBehavior.Default, AllowUpdates = true };
333-
persistenceManager.State.RegisterOnRestoring(() => { callbackInvoked = true; }, options);
334-
335-
// Second restore with ValueUpdate context should invoke callbacks
336-
await persistenceManager.RestoreStateAsync(store, RestoreContext.ValueUpdate);
337-
338-
// Assert
339-
Assert.True(callbackInvoked);
340-
}
341-
342-
private static IServiceProvider CreateServiceProvider()
343-
{
344-
return new ServiceCollection()
345-
.AddScoped(sp => new TestStore(new Dictionary<string, byte[]>()))
346-
.BuildServiceProvider();
347-
}
348-
349-
private sealed class TestStore(IDictionary<string, byte[]> data) : IPersistentComponentStateStore
350-
{
351-
private readonly IDictionary<string, byte[]> _data = data;
352-
353-
public Task<IDictionary<string, byte[]>> GetPersistedStateAsync()
354-
=> Task.FromResult(_data);
355-
356-
public Task PersistStateAsync(IReadOnlyDictionary<string, byte[]> state)
357-
{
358-
foreach (var (key, value) in state)
359-
{
360-
_data[key] = value;
361-
}
362-
363-
return Task.CompletedTask;
364-
}
365-
}
366287
}

0 commit comments

Comments
 (0)