public void when_attempting_to_version_a_property_bag() { var originalAddress = "12345 Fake Street"; var subscriber = new SimpleMementoingClass() { Domainees = new List<DomainPropertyBag>() { new DomainPropertyBag(), new DomainPropertyBag() }, ChiefDomainee = new DomainPropertyBag(), Address = originalAddress, FirstName = "If only Customer Objects", LastName = "were ever this simple" }; var mementor = new Mementor(); var newAddress = "Changed Address!"; mementor.PropertyChange(subscriber, () => subscriber.Address); //ohhh typing is a little weak here. subscriber.Address = newAddress; //ahh, note the order matters of course. subscriber.Address.Should().Be(newAddress); mementor.Undo(); //and I cant undo specific changes, just the last one. subscriber.Address.Should().Be(originalAddress); //still, very cool. //In terms of a deployed program, this is tough to implement. //I like the pub-sub design of it, code is superbly clean. }
/// <summary> /// Marks an element index change event. /// </summary> /// <typeparam name="T">The generic type parameter of the collection.</typeparam> /// <param name="mementor">The mementor object.</param> /// <param name="collection">The collection object.</param> /// <param name="element">The element whose index is being changed</param> /// <param name="elementIndex">The index of the element being removed. If not supplied, will retrieve via <see cref="IList{T}.IndexOf"/>.</param> public static void ElementIndexChange <T>(this Mementor mementor, IList <T> collection, T element, int?elementIndex = null) { if (mementor.IsTrackingEnabled) { mementor.MarkEvent(new ElementIndexChangeEvent <T>(collection, element, elementIndex)); } }
/// <summary> /// Marks an element addition event. /// </summary> /// <typeparam name="T">The generic type parameter of the collection.</typeparam> /// <param name="mementor">The mementor object.</param> /// <param name="collection">The collection object.</param> /// <param name="element">The element being added.</param> public static void ElementAdd <T>(this Mementor mementor, IList <T> collection, T element) { if (mementor.IsTrackingEnabled) { mementor.MarkEvent(new ElementAdditionEvent <T>(collection, element)); } }
/// <summary> /// Marks a property change event. /// </summary> /// <param name="mementor">The mementor object.</param> /// <param name="target">The target object.</param> /// <param name="propertyName">The name of the property.</param> /// <param name="previousValue">The value to be restored to when undo. /// If not supplied, will be retrieved directly from the <paramref name="target"/>.</param> public static void PropertyChange(this Mementor mementor, object target, string propertyName, object previousValue = null) { if (mementor.IsTrackingEnabled) { mementor.MarkEvent(new PropertyChangeEvent(target, propertyName, previousValue)); } }
/// <summary> /// Marks a property change event. /// </summary> /// <typeparam name="TProp">The type of the property.</typeparam> /// <param name="mementor">The mementor object.</param> /// <param name="target">The target object.</param> /// <param name="propertySelector">The property selector expression.</param> /// <param name="previousValue">The value to be restored to when undo. /// If not supplied, will be retrieved directly from the <paramref name="target"/>.</param> public static void PropertyChange <TProp>(this Mementor mementor, object target, Expression <Func <TProp> > propertySelector, object previousValue = null) { if (mementor.IsTrackingEnabled) { PropertyChange(mementor, target, propertySelector.Name(), previousValue); } }
public void when_forcing_bad_things_via_expression() { var subscriber = new SimpleMementoingClass(); var mementor = new Mementor(); subscriber.Address = "Changed!"; Assert.Throws<InvalidCastException>(() => mementor.PropertyChange(subscriber, () => mementor.ToString())); //aww duder and the exceptions arn't handled nicely here either, Linq at the wrong thing and get a generic Expression.OhgodohgodohgodException //why not public void PropertyChange<TSubject, TTargetSite>(this TSubject subject, Func<TSubject, TTargetSite> transform...) //would be mementor.PropertyChange(subscriber, sub => sub.SomeProp), would provide some additional typiing on the expression. }
public void when_attempting_to_restore_an_externally_tracked_list() { var mementor = new Mementor(isEnabled: true); var collection = new List<string>(); var item = "hey!"; mementor.ElementAdd(collection, item);//this is an extension method? Oh I see, he didnt want to put custom-list logic on Mementor. Nice. //it also doesnt actually add the element to the list: collection.Add(item); collection.Should().HaveCount(1); mementor.Undo(); //hmm, so it expects the caller to do the Add but it will handle the remove? collection.Should().BeEmpty(); }