-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
473 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,259 @@ | ||
namespace Lib9c.Tests.Action.Summon | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Data; | ||
using System.Linq; | ||
using Lib9c.Tests.Fixtures.TableCSV.Summon; | ||
using Libplanet.Action.State; | ||
using Libplanet.Crypto; | ||
using Libplanet.Types.Assets; | ||
using Nekoyume; | ||
using Nekoyume.Action; | ||
using Nekoyume.Action.Exceptions; | ||
using Nekoyume.Model.Item; | ||
using Nekoyume.Model.State; | ||
using Nekoyume.TableData.Summon; | ||
using Xunit; | ||
using static SerializeKeys; | ||
|
||
public class RuneSummonTest | ||
{ | ||
private readonly Address _agentAddress; | ||
private readonly Address _avatarAddress; | ||
private readonly AvatarState _avatarState; | ||
private readonly Currency _currency; | ||
private TableSheets _tableSheets; | ||
private IAccount _initialState; | ||
|
||
public RuneSummonTest() | ||
{ | ||
var sheets = TableSheetsImporter.ImportSheets(); | ||
_tableSheets = new TableSheets(sheets); | ||
var privateKey = new PrivateKey(); | ||
_agentAddress = privateKey.PublicKey.Address; | ||
var agentState = new AgentState(_agentAddress); | ||
|
||
_avatarAddress = _agentAddress.Derive("avatar"); | ||
_avatarState = new AvatarState( | ||
_avatarAddress, | ||
_agentAddress, | ||
0, | ||
_tableSheets.GetAvatarSheets(), | ||
new GameConfigState(), | ||
default | ||
); | ||
|
||
agentState.avatarAddresses.Add(0, _avatarAddress); | ||
|
||
#pragma warning disable CS0618 | ||
// Use of obsolete method Currency.Legacy(): https://github.com/planetarium/lib9c/discussions/1319 | ||
_currency = Currency.Legacy("NCG", 2, null); | ||
#pragma warning restore CS0618 | ||
var gold = new GoldCurrencyState(_currency); | ||
|
||
var context = new ActionContext(); | ||
_initialState = new Account(MockState.Empty) | ||
.SetState(_agentAddress, agentState.Serialize()) | ||
.SetState(_avatarAddress, _avatarState.Serialize()) | ||
.SetState(GoldCurrencyState.Address, gold.Serialize()) | ||
.MintAsset(context, GoldCurrencyState.Address, gold.Currency * 100000000000) | ||
.TransferAsset( | ||
context, | ||
Addresses.GoldCurrency, | ||
_agentAddress, | ||
gold.Currency * 1000 | ||
); | ||
|
||
Assert.Equal( | ||
gold.Currency * 99999999000, | ||
_initialState.GetBalance(Addresses.GoldCurrency, gold.Currency) | ||
); | ||
Assert.Equal( | ||
gold.Currency * 1000, | ||
_initialState.GetBalance(_agentAddress, gold.Currency) | ||
); | ||
|
||
foreach (var (key, value) in sheets) | ||
{ | ||
_initialState = | ||
_initialState.SetState(Addresses.TableSheet.Derive(key), value.Serialize()); | ||
} | ||
} | ||
|
||
[Theory] | ||
[InlineData(20001)] | ||
[InlineData(20002)] | ||
public void CumulativeRatio(int groupId) | ||
{ | ||
var sheet = _tableSheets.SummonSheet; | ||
var targetRow = sheet.OrderedList.First(r => r.GroupId == groupId); | ||
|
||
for (var i = 1; i <= SummonSheet.Row.MaxRecipeCount; i++) | ||
{ | ||
var sum = 0; | ||
for (var j = 0; j < i; j++) | ||
{ | ||
if (j < targetRow.Recipes.Count) | ||
{ | ||
sum += targetRow.Recipes[j].Item2; | ||
} | ||
} | ||
|
||
Assert.Equal(sum, targetRow.CumulativeRatio(i)); | ||
} | ||
} | ||
|
||
[Theory] | ||
// success first group | ||
[InlineData(20001, 1, 800201, 1, 1, new[] { 10610000 }, null)] | ||
[InlineData(20001, 2, 800201, 2, 54, new[] { 10620000, 10630000 }, null)] | ||
// success second group | ||
[InlineData(20002, 1, 600201, 1, 1, new[] { 10620001 }, null)] | ||
[InlineData(20002, 2, 600201, 2, 4, new[] { 10620001, 10630001 }, null)] | ||
// Nine plus zero | ||
[InlineData( | ||
20001, | ||
9, | ||
800201, | ||
9, | ||
0, | ||
new[] { 10610000, 10610000, 10610000, 10610000, 10610000, 10610000, 10620000, 10620000, 10620000 }, | ||
null | ||
)] | ||
[InlineData( | ||
20002, | ||
9, | ||
600201, | ||
9, | ||
0, | ||
new[] { 10620001, 10620001, 10620001, 10620001, 10620001, 10630001, 10630001, 10630001, 10630001 }, | ||
null | ||
)] | ||
// Ten plus one | ||
[InlineData( | ||
20001, | ||
10, | ||
800201, | ||
10, | ||
0, | ||
new[] { 10610000, 10610000, 10610000, 10610000, 10610000, 10610000, 10610000, 10610000, 10620000, 10620000, 10620000 }, | ||
null | ||
)] | ||
[InlineData( | ||
20002, | ||
10, | ||
600201, | ||
10, | ||
0, | ||
new[] { 10620001, 10620001, 10620001, 10620001, 10620001, 10620001, 10630001, 10620001, 10630001, 10630001, 10630001 }, | ||
null | ||
)] | ||
// fail by invalid group | ||
[InlineData(100003, 1, null, 0, 0, new int[] { }, typeof(RowNotInTableException))] | ||
// fail by not enough material | ||
[InlineData(20001, 1, 800201, 0, 0, new int[] { }, typeof(NotEnoughMaterialException))] | ||
[InlineData(20001, 2, 800201, 0, 0, new int[] { }, typeof(NotEnoughMaterialException))] | ||
// Fail by exceeding summon limit | ||
[InlineData(20001, 11, 800201, 22, 1, new int[] { }, typeof(InvalidSummonCountException))] | ||
// 15 recipes | ||
[InlineData(20002, 1, 600201, 1, 5341, new[] { 10650006 }, null)] | ||
public void Execute( | ||
int groupId, | ||
int summonCount, | ||
int? materialId, | ||
int materialCount, | ||
int seed, | ||
int[] expectedEquipmentId, | ||
Type expectedExc | ||
) | ||
{ | ||
var random = new TestRandom(seed); | ||
var state = _initialState; | ||
state = state.SetState( | ||
Addresses.TableSheet.Derive(nameof(SummonSheet)), | ||
_tableSheets.SummonSheet.Serialize() | ||
); | ||
|
||
if (!(materialId is null)) | ||
{ | ||
var materialSheet = _tableSheets.MaterialItemSheet; | ||
var material = materialSheet.OrderedList.FirstOrDefault(m => m.Id == materialId); | ||
_avatarState.inventory.AddItem( | ||
ItemFactory.CreateItem(material, random), | ||
materialCount * _tableSheets.SummonSheet[groupId].CostMaterialCount | ||
); | ||
state = state | ||
.SetState(_avatarAddress, _avatarState.SerializeV2()) | ||
.SetState( | ||
_avatarAddress.Derive(LegacyInventoryKey), | ||
_avatarState.inventory.Serialize() | ||
) | ||
.SetState( | ||
_avatarAddress.Derive(LegacyWorldInformationKey), | ||
_avatarState.worldInformation.Serialize() | ||
) | ||
.SetState( | ||
_avatarAddress.Derive(LegacyQuestListKey), | ||
_avatarState.questList.Serialize() | ||
) | ||
; | ||
} | ||
|
||
var action = new RuneSummon | ||
{ | ||
AvatarAddress = _avatarAddress, | ||
GroupId = groupId, | ||
SummonCount = summonCount, | ||
}; | ||
|
||
if (expectedExc == null) | ||
{ | ||
// Success | ||
var ctx = new ActionContext | ||
{ | ||
PreviousState = state, | ||
Signer = _agentAddress, | ||
BlockIndex = 1, | ||
}; | ||
ctx.SetRandom(random); | ||
var nextState = action.Execute(ctx); | ||
|
||
var equipments = nextState.GetAvatarStateV2(_avatarAddress).inventory.Equipments | ||
.ToList(); | ||
Assert.Equal(expectedEquipmentId.Length, equipments.Count); | ||
|
||
var checkedEquipments = new List<Guid>(); | ||
foreach (var equipmentId in expectedEquipmentId) | ||
{ | ||
var resultEquipment = equipments.First(e => | ||
e.Id == equipmentId && !checkedEquipments.Contains(e.ItemId) | ||
); | ||
|
||
checkedEquipments.Add(resultEquipment.ItemId); | ||
Assert.NotNull(resultEquipment); | ||
Assert.Equal(1, resultEquipment.RequiredBlockIndex); | ||
Assert.True(resultEquipment.optionCountFromCombination > 0); | ||
} | ||
|
||
nextState.GetAvatarStateV2(_avatarAddress).inventory | ||
.TryGetItem((int)materialId!, out var resultMaterial); | ||
Assert.Equal(0, resultMaterial?.count ?? 0); | ||
} | ||
else | ||
{ | ||
// Failure | ||
Assert.Throws(expectedExc, () => | ||
{ | ||
action.Execute(new ActionContext | ||
{ | ||
PreviousState = state, | ||
Signer = _agentAddress, | ||
BlockIndex = 1, | ||
RandomSeed = random.Seed, | ||
}); | ||
}); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using Libplanet.Crypto; | ||
|
||
namespace Lib9c.Abstractions; | ||
Check failure on line 3 in Lib9c.Abstractions/IRuneSummonV1.cs GitHub Actions / build-for-unity
Check failure on line 3 in Lib9c.Abstractions/IRuneSummonV1.cs GitHub Actions / build-for-unity
Check failure on line 3 in Lib9c.Abstractions/IRuneSummonV1.cs GitHub Actions / build-for-unity
|
||
|
||
public interface IRuneSummonV1 | ||
{ | ||
Address AvatarAddress { get; } | ||
int GroupId { get; } | ||
|
||
int SummonCount { get; } | ||
} |
Oops, something went wrong.