using System.Collections.Specialized;
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Engineering;
using XFEEDToolBox.Core.Presentation;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Data;
namespace XFEEDToolBox.Test;
[TestFixture]
public class LiveCollectionTests
{
[Test] public void UnchangedSnapshotsProduceNoRowOrCollectionNotifications()
{
var list=new LiveCollection<MaterialLiveRow,MaterialStock,string>(x=>x.Key,x=>new(x));
var value=new MaterialStock("iron","Iron","Raw",1,10,300);list.Apply([value]);
var row=list[0];var structures=0;var properties=new List<string>();
list.CollectionChanged+=(_,_)=>structures++;row.PropertyChanged+=(_,e)=>properties.Add(e.PropertyName!);
list.Apply([value with{}]);
Check.Equal(0,structures);Check.Equal(0,properties.Count);Check.That(ReferenceEquals(row,list[0]));
}
[Test] public void QuantityUpdateOnlyNotifiesQuantityAndDerivedDetail()
{
var list=new LiveCollection<MaterialLiveRow,MaterialStock,string>(x=>x.Key,x=>new(x));
var iron=new MaterialStock("iron","Iron","Raw",1,10,300);var nickel=new MaterialStock("nickel","Nickel","Raw",1,20,300);list.Apply([iron,nickel]);
var first=list[0];var second=list[1];var structures=0;var properties=new List<string>();var otherChanges=0;
list.CollectionChanged+=(_,_)=>structures++;first.PropertyChanged+=(_,e)=>properties.Add(e.PropertyName!);second.PropertyChanged+=(_,_)=>otherChanges++;
list.Apply([iron with{Owned=11},nickel]);
Check.Equal(0,structures);Check.Equal(0,otherChanges);Check.That(properties.Order().SequenceEqual(new[]{"Detail","FillPercent","Owned","Quantity"}));Check.Equal("11 / 300",first.Quantity);Check.That(ReferenceEquals(first,list[0])&&ReferenceEquals(second,list[1]));
}
[Test] public void PriceUpdateKeepsRowAndDoesNotNotifyNameOrOtherPrices()
{
var list=new LiveCollection<MarketLiveRow,MarketRow,(long,string)>(x=>(x.Station.MarketId,x.Quote.Commodity),x=>new(x));
var source=new MarketRow(Check.Station(1),Check.Quote(1,"gold",100,90));list.Apply([source]);
var properties=new List<string>();list[0].PropertyChanged+=(_,e)=>properties.Add(e.PropertyName!);
list.Apply([source with{Quote=source.Quote with{BuyPrice=101}}]);Check.That(properties.SequenceEqual(new[]{"Buy"}));
}
[Test] public void ExplicitSortMovesExistingRowsWithoutResetOrReplacement()
{
var list=new LiveCollection<InventoryLiveRow,InventoryItem,string>(x=>x.Key,x=>new(x));
var a=new InventoryItem("a","A",1);var b=new InventoryItem("b","B",2);list.Apply([a,b]);var first=list[0];var second=list[1];var actions=new List<NotifyCollectionChangedAction>();
list.CollectionChanged+=(_,e)=>actions.Add(e.Action);list.Apply([b,a],reorder:false);Check.That(ReferenceEquals(first,list[0]));Check.Equal(0,actions.Count);
list.Apply([b,a],reorder:true);Check.That(ReferenceEquals(second,list[0])&&ReferenceEquals(first,list[1]));Check.That(actions.SequenceEqual(new[]{NotifyCollectionChangedAction.Move}));
}
[Test] public void AddingAndRemovingItemsPreservesSurvivingRow()
{
var list=new LiveCollection<InventoryLiveRow,InventoryItem,string>(x=>x.Key,x=>new(x));var a=new InventoryItem("a","A",1);var b=new InventoryItem("b","B",2);list.Apply([a,b]);var keep=list[1];var actions=new List<NotifyCollectionChangedAction>();
list.CollectionChanged+=(_,e)=>actions.Add(e.Action);list.Apply([b,new("c","C",3)]);Check.That(ReferenceEquals(keep,list[0]));Check.That(!actions.Contains(NotifyCollectionChangedAction.Reset));
}
[Test] public async Task MarketDefaultOrderingDoesNotJumpWhenOnlyTimestampChanges()
{
using var temp=new TemporaryDirectory();var db=temp.Repository();var time=DateTimeOffset.UtcNow.AddMinutes(-3);
var a=Check.Station(1);var b=Check.Station(2);
await db.SaveSnapshotAsync(new(a,[Check.Quote(1,"gold",100,90)],time,DataSource.Journal));await db.SaveSnapshotAsync(new(b,[Check.Quote(2,"gold",110,95)],time.AddMinutes(1),DataSource.Journal));
var before=db.Search("",null).Select(x=>x.Station.MarketId).ToArray();
await db.SaveSnapshotAsync(new(a,[Check.Quote(1,"gold",101,90)],time.AddMinutes(2),DataSource.Journal));
Check.That(before.SequenceEqual(db.Search("",null).Select(x=>x.Station.MarketId)));
Check.Equal(1L,db.Search("",null,sort:MarketSort.Newest)[0].Station.MarketId);
}
}
using System.Collections.Specialized;
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Engineering;
using XFEEDToolBox.Core.Presentation;
using XFEEDToolBox.Core.Models;
using XFEEDToolBox.Core.Data;
namespace XFEEDToolBox.Test;
[TestFixture]
public class LiveCollectionTests
{
[Test] public void UnchangedSnapshotsProduceNoRowOrCollectionNotifications()
{
var list=new LiveCollection<MaterialLiveRow,MaterialStock,string>(x=>x.Key,x=>new(x));
var value=new MaterialStock("iron","Iron","Raw",1,10,300);list.Apply([value]);
var row=list[0];var structures=0;var properties=new List<string>();
list.CollectionChanged+=(_,_)=>structures++;row.PropertyChanged+=(_,e)=>properties.Add(e.PropertyName!);
list.Apply([value with{}]);
Check.Equal(0,structures);Check.Equal(0,properties.Count);Check.That(ReferenceEquals(row,list[0]));
}
[Test] public void QuantityUpdateOnlyNotifiesQuantityAndDerivedDetail()
{
var list=new LiveCollection<MaterialLiveRow,MaterialStock,string>(x=>x.Key,x=>new(x));
var iron=new MaterialStock("iron","Iron","Raw",1,10,300);var nickel=new MaterialStock("nickel","Nickel","Raw",1,20,300);list.Apply([iron,nickel]);
var first=list[0];var second=list[1];var structures=0;var properties=new List<string>();var otherChanges=0;
list.CollectionChanged+=(_,_)=>structures++;first.PropertyChanged+=(_,e)=>properties.Add(e.PropertyName!);second.PropertyChanged+=(_,_)=>otherChanges++;
list.Apply([iron with{Owned=11},nickel]);
Check.Equal(0,structures);Check.Equal(0,otherChanges);Check.That(properties.Order().SequenceEqual(new[]{"Detail","FillPercent","Owned","Quantity"}));Check.Equal("11 / 300",first.Quantity);Check.That(ReferenceEquals(first,list[0])&&ReferenceEquals(second,list[1]));
}
[Test] public void PriceUpdateKeepsRowAndDoesNotNotifyNameOrOtherPrices()
{
var list=new LiveCollection<MarketLiveRow,MarketRow,(long,string)>(x=>(x.Station.MarketId,x.Quote.Commodity),x=>new(x));
var source=new MarketRow(Check.Station(1),Check.Quote(1,"gold",100,90));list.Apply([source]);
var properties=new List<string>();list[0].PropertyChanged+=(_,e)=>properties.Add(e.PropertyName!);
list.Apply([source with{Quote=source.Quote with{BuyPrice=101}}]);Check.That(properties.SequenceEqual(new[]{"Buy"}));
}
[Test] public void ExplicitSortMovesExistingRowsWithoutResetOrReplacement()
{
var list=new LiveCollection<InventoryLiveRow,InventoryItem,string>(x=>x.Key,x=>new(x));
var a=new InventoryItem("a","A",1);var b=new InventoryItem("b","B",2);list.Apply([a,b]);var first=list[0];var second=list[1];var actions=new List<NotifyCollectionChangedAction>();
list.CollectionChanged+=(_,e)=>actions.Add(e.Action);list.Apply([b,a],reorder:false);Check.That(ReferenceEquals(first,list[0]));Check.Equal(0,actions.Count);
list.Apply([b,a],reorder:true);Check.That(ReferenceEquals(second,list[0])&&ReferenceEquals(first,list[1]));Check.That(actions.SequenceEqual(new[]{NotifyCollectionChangedAction.Move}));
}
[Test] public void AddingAndRemovingItemsPreservesSurvivingRow()
{
var list=new LiveCollection<InventoryLiveRow,InventoryItem,string>(x=>x.Key,x=>new(x));var a=new InventoryItem("a","A",1);var b=new InventoryItem("b","B",2);list.Apply([a,b]);var keep=list[1];var actions=new List<NotifyCollectionChangedAction>();
list.CollectionChanged+=(_,e)=>actions.Add(e.Action);list.Apply([b,new("c","C",3)]);Check.That(ReferenceEquals(keep,list[0]));Check.That(!actions.Contains(NotifyCollectionChangedAction.Reset));
}
[Test] public async Task MarketDefaultOrderingDoesNotJumpWhenOnlyTimestampChanges()
{
using var temp=new TemporaryDirectory();var db=temp.Repository();var time=DateTimeOffset.UtcNow.AddMinutes(-3);
var a=Check.Station(1);var b=Check.Station(2);
await db.SaveSnapshotAsync(new(a,[Check.Quote(1,"gold",100,90)],time,DataSource.Journal));await db.SaveSnapshotAsync(new(b,[Check.Quote(2,"gold",110,95)],time.AddMinutes(1),DataSource.Journal));
var before=db.Search("",null).Select(x=>x.Station.MarketId).ToArray();
await db.SaveSnapshotAsync(new(a,[Check.Quote(1,"gold",101,90)],time.AddMinutes(2),DataSource.Journal));
Check.That(before.SequenceEqual(db.Search("",null).Select(x=>x.Station.MarketId)));
Check.Equal(1L,db.Search("",null,sort:MarketSort.Newest)[0].Station.MarketId);
}
}