Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculation Rewriting Part 2.3: Skill and Item parsing #515

Merged
merged 191 commits into from
Dec 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
191 commits
Select commit Hold shift + click to select a range
ff7513e
Better IParser interfaces: 1. IStringParser
brather1ng Aug 21, 2018
1786019
Better IParser interfaces: 2. ICoreParser, IParser<TParameter>
brather1ng Aug 21, 2018
122204f
Catch ParseException in CoreParser,
brather1ng Aug 21, 2018
839d7fa
Let GivenStatsParser implement IParser
brather1ng Aug 22, 2018
83d703f
Rename "ActiveSkillId" to "MainSkillId" (also related stats)
brather1ng Aug 23, 2018
9e03565
Remove Keyword.Bow
brather1ng Aug 23, 2018
2566ace
Change how keyword conditions work
brather1ng Aug 23, 2018
2c766d2
Add RePoE gem files
brather1ng Aug 23, 2018
fc4fcc4
Move Keyword and SkillDefinition to GameModel project
brather1ng Aug 23, 2018
e099643
Add GameModel.Tests project
brather1ng Aug 23, 2018
37ebcd8
Merge branch 'calculation-mechanics' into calculation-items-skills
brather1ng Aug 23, 2018
fe0ca2f
Add SkillJsonDeserializer
brather1ng Aug 23, 2018
1167e4a
Add constants for used ActiveSkillTypes
brather1ng Aug 24, 2018
7ef4c94
Extend SkillDefinition and SkillJsonDeserializer
brather1ng Aug 24, 2018
1522304
Add base item related and some other fields to skill parsing
brather1ng Aug 24, 2018
428fe72
Finish SkillDefinition and SkillJsonDeserializer
brather1ng Aug 24, 2018
1110e0b
Add (mostly empty) ActiveSkillParser and integration test
brather1ng Aug 25, 2018
7e67543
Encode Tags as doubles in NodeValue without loss
brather1ng Aug 25, 2018
776ebf1
Implement ActiveSkillParser enough to pass the test
brather1ng Aug 25, 2018
2fc355e
Implement conditional values in ActiveSkillParser for Frenzy
brather1ng Aug 25, 2018
5e5e03d
Add proper hit damage source and keyword parsing
brather1ng Aug 26, 2018
4127079
Add parsing for hand/weapon usage
brather1ng Aug 26, 2018
37b8c09
Add parsing for remaining active skill related properties
brather1ng Aug 27, 2018
55acdac
Add base damage parsing
brather1ng Aug 27, 2018
9790959
Add and parse skill number of hits and double hit when dual wielding
brather1ng Aug 28, 2018
99012a3
Parse special stats in one pass instead of one per stat
brather1ng Aug 28, 2018
df6ae98
Move StatTranslation code to GameModel project from WPFSKillTree
brather1ng Aug 28, 2018
fb66b0a
Move StatTranslatorTest to GameModel project from UnitTests
brather1ng Aug 28, 2018
d8bb6f2
Merge branch 'master' into calculation-items-skills
brather1ng Aug 29, 2018
3ef4c3d
Add ModifierSource.Local.Gem for level and attribute requirements
brather1ng Aug 29, 2018
2e1a837
Add UntranslatedStatParser
brather1ng Aug 29, 2018
b34bba0
Move IStatTranslator to GameModel and let StatTranslator implement it
brather1ng Aug 29, 2018
90c9b58
Use UntranslatedStatParser in ActiveSkillParser
brather1ng Aug 29, 2018
ad01353
Add StatTranslationLoader; use SkillDefinition.StatTranslationFile
brather1ng Aug 29, 2018
1ba83f5
Extract keyword and common parsing out of ActiveSkillParser
brather1ng Aug 30, 2018
ca7dd1d
Extract all modifier creation from ActiveSkillParser
brather1ng Aug 30, 2018
219cb47
Add IPartialSkillParser interface for the extracted parsers
brather1ng Aug 30, 2018
0402406
Update data
brather1ng Sep 1, 2018
7acace7
Add new ModDomain and IndexHandlers; fix tests
brather1ng Sep 1, 2018
4b9046f
Update skill tree stat parsing for Delve
brather1ng Sep 5, 2018
18e8e8e
Merge branch 'master' into calculation-items-skills
brather1ng Sep 9, 2018
b0ba443
Fix test broken by parsing update
brather1ng Sep 9, 2018
bcd3a5c
Implement AffectedByMinion*Increases properly with behaviors
brather1ng Sep 11, 2018
e1b9aa8
Add MechanicsTest for AffectedByMinion*Increases
brather1ng Sep 15, 2018
f97c066
Use ChanceToDouble for damage calculations in DataDrivenMechanics
brather1ng Sep 15, 2018
8c4e56a
Add behavior for damage effectiveness
brather1ng Sep 15, 2018
b1bf5a2
Add behavior for level/attribute requirements
brather1ng Sep 21, 2018
707a72b
Parse skill conversion as local stats
brather1ng Sep 21, 2018
a3408a3
Move Skill data class to GameModel
brather1ng Oct 3, 2018
8080097
Add SupportSkillParser
brather1ng Oct 4, 2018
cc52b8e
Add SupportSkillDefinition.AddedKeywords property
brather1ng Oct 8, 2018
8b08726
Refactor ActiveSkillPreParser to also be usable for supports
brather1ng Oct 8, 2018
baca369
Extract translation part from ActiveSkillParser
brather1ng Oct 8, 2018
0f53d35
Extract support mana multiplier parsing
brather1ng Oct 20, 2018
81540b6
Refactor ActiveSkillKeywordParser for usage in SupportSkillParser
brather1ng Oct 20, 2018
421efb7
Reuse ActiveSkillStatParser in SupportSkillParser
brather1ng Oct 20, 2018
d544a77
Integrate SkillDefinition into SkillBuilder classes
brather1ng Oct 20, 2018
297845a
Use GameModel.Skills.SkillDefinitions as data
brather1ng Oct 21, 2018
38a668a
Restrict CombineWith to not increase the number of results,
brather1ng Oct 21, 2018
70e4ee4
Improve integration test performance
brather1ng Oct 21, 2018
7dd5f3b
Add mana reservation to ActiveSkillLevelParser
brather1ng Oct 21, 2018
a51e06e
Only reserve mana for one instance of each skill
brather1ng Nov 5, 2018
aa5db99
Add behavior for ActiveSkillItemSlot and -SocketIndex
brather1ng Nov 5, 2018
448ff1d
Let mana multiplier affect reservation
brather1ng Nov 5, 2018
b664191
Support ManaCostOverride
brather1ng Nov 5, 2018
b2bb2be
Add stats for active skill types, parsed by SkillTypeParser
brather1ng Nov 5, 2018
24e2a29
Parse active skill types added by supports
brather1ng Nov 5, 2018
010df61
Use stats to check for ManaCostIsReservation and ManaCostIsPercentage
brather1ng Nov 5, 2018
6d7e1e1
Support Blood Magic Support
brather1ng Nov 5, 2018
122f73f
Refactor SkillStatParser to not use SkillPreParseResult.HitDamageSource
brather1ng Nov 7, 2018
34c2f16
Refactor SkillKeywordParser to not use SkillPreParseResult.HitDamageS…
brather1ng Nov 7, 2018
ebd8228
Refactor ActiveSkillLevelParser to not use SkillPreParseResult.HitDam…
brather1ng Nov 7, 2018
81be3de
Refactor ActiveSkillGeneralParser to not use SkillPreParseResult.HitD…
brather1ng Nov 7, 2018
914f25f
Move Entity to GameModel from Computation.Common
brather1ng Nov 7, 2018
5ea7040
Add SkillDefinitionExtensions, mainly for skill parts
brather1ng Nov 7, 2018
204b93e
Add SkillStage and MainSkillPart stats
brather1ng Nov 8, 2018
2787df3
Support skill parts in SkillStatParser
brather1ng Nov 8, 2018
47c68a5
Support skill parts in SkillKeywordParser
brather1ng Nov 8, 2018
1022eb3
Support skill parts in ActiveSkillGeneralParser
brather1ng Nov 8, 2018
545dd49
Support skill parts in TranslatingSkillParser
brather1ng Nov 8, 2018
e554fea
Add hit rate based DPS for Blade Vortex
brather1ng Nov 9, 2018
1343470
Add most active skills to SkillDefinitionExtensions
brather1ng Nov 9, 2018
5530077
Move MainSkillPart stat to IStatBuilders
brather1ng Nov 10, 2018
fb304ba
Complete support for most active skills
brather1ng Nov 10, 2018
48cb066
Add support for most support skills
brather1ng Nov 11, 2018
33c1fe7
Add support for most buff skills
brather1ng Nov 12, 2018
2df62d7
Parse buff stats in TranslatingSkillParser
brather1ng Nov 17, 2018
b0305be
Add buff activation to ActiveSkillGeneralParser
brather1ng Nov 17, 2018
541713f
Fix values of QualityBuffStats not being based on quality
brather1ng Nov 18, 2018
1b86d21
Add custom stat translation file and use it for skill stats
brather1ng Nov 21, 2018
303b5d9
Add ModifierSourceOpponentEntityBuilder
brather1ng Nov 22, 2018
f1030cd
Add ActiveSkillItemSlot and -SocketIndex modifiers for supports
brather1ng Nov 22, 2018
d4d9919
Refactor SkillDefinitionExtensions to collection initializer syntax
brather1ng Nov 22, 2018
76078e1
Add concept of "passive" stats to SkillDefinition
brather1ng Nov 24, 2018
cb15558
Fix buff identity in AddStat multiplier not being resolved
brather1ng Nov 24, 2018
2251ec4
Change Skill and Gem ModifierSources to use skillId as SourceName
brather1ng Nov 24, 2018
335d3f4
Add BuildParameters to ICoreBuilder.Build()
brather1ng Nov 25, 2018
7e3dc3f
Add ISkillBuilders.ModifierSourceSkill
brather1ng Nov 25, 2018
97f6439
Parse stats that require ModifierSourceSkill
brather1ng Nov 25, 2018
6e4a607
Parse passive stats in TranslatingSkillParser
brather1ng Nov 25, 2018
2a94955
Add support for Curse Immunity and Hexproof
brather1ng Nov 25, 2018
3824000
Add given stats so Maim and Bleed can only be applied by attacks
brather1ng Nov 25, 2018
be19c10
Restrict ISkillBuilder[Keywords] to one or zero keywords
brather1ng Nov 25, 2018
5ec1d7c
Add BaseAdd, 1, skill.Instances modifiers in ActiveSkillParser
brather1ng Nov 25, 2018
7596747
Add BaseAdd, 1, skill.Instances modifiers in SupportSkillParser
brather1ng Nov 25, 2018
353245e
Add SupportabilityTester to select applicable supports
brather1ng Nov 28, 2018
6ac0fb2
Fix supports adding to CombinedInstances for keywords already present
brather1ng Nov 29, 2018
748ae38
Move Active-/SupportSkillParser creation to CompositionRoot
brather1ng Nov 29, 2018
3e5f40d
Test for successful parsing of skills in SkillParserTest
brather1ng Nov 29, 2018
11cfb4b
Allow not parseable stat lines in skills to fail being parsed; Fix "p…
brather1ng Nov 30, 2018
7a7e87a
Filter null translations from StatTranslator.Translate()
brather1ng Nov 30, 2018
630b71d
Fill NotParseableSkills with those not supposed to be supported yet
brather1ng Nov 30, 2018
62a973e
Add stat_translations/variable_duration_skill
brather1ng Nov 30, 2018
8807607
Fix skill parsing tests that do not require matcher changes
brather1ng Nov 30, 2018
ad4af57
Fix most skill parsing tests
brather1ng Dec 1, 2018
044edb2
Fix remaining skill parsing tests
brather1ng Dec 1, 2018
d378fb4
Add Projectile.Fork stat
brather1ng Dec 1, 2018
3b941ae
Add SecondaryDuration stat
brather1ng Dec 1, 2018
27584ef
Add GameModel.BaseItemDefinition and .Item classes
brather1ng Dec 1, 2018
58e1a86
Add BaseItemDefinitions and -JsonDeserializer (not implemented)
brather1ng Dec 1, 2018
b72d9aa
Implement BaseItemJsonDeserializer
brather1ng Dec 2, 2018
03b07d3
Extend BaseItemJsonDeserializer
brather1ng Dec 2, 2018
3b70692
Update RePoE data
brather1ng Dec 2, 2018
9661dfc
Fix tests after data update
brather1ng Dec 2, 2018
e62edae
Add buff stats from flasks to BaseItemDefinition
brather1ng Dec 2, 2018
20e5ca3
Add ValueObject abstract class
brather1ng Dec 3, 2018
d41b8ae
Fix RePoELoader deleting custom stat translations
brather1ng Dec 5, 2018
d403b21
Fix Far Shot damage scaling
brather1ng Dec 5, 2018
bffd86f
Merge branch 'master' into calculation-items-skills
brather1ng Dec 5, 2018
942ef07
Fix passive modifiers of support gems applying incorrectly
brather1ng Dec 15, 2018
c62f914
Update Computation for 3.5.0 passive tree
brather1ng Dec 15, 2018
6b264f4
Update game data for 3.5.0 (except master crafting)
brather1ng Dec 15, 2018
1d30d6a
Update computation for skills changed in 3.5.0
brather1ng Dec 16, 2018
0f3dbd2
Add a BaseCastTime stat that is used to BaseSet CastRate
brather1ng Dec 16, 2018
3dc889c
Use DamageMultiplier in DataDrivenMechanics
brather1ng Dec 16, 2018
d35f46d
Use Impale in DataDrivenMechanics
brather1ng Dec 16, 2018
580375e
Update SkillUsesHand modifier conditions for 3.5.0
brather1ng Dec 16, 2018
e8540ed
Support Brand skills
brather1ng Dec 16, 2018
c923315
Support Banner skills
brather1ng Dec 16, 2018
0cfa5a9
Support Lancing Steel and Shattering Steel
brather1ng Dec 17, 2018
0ea5315
Support remaining new skills
brather1ng Dec 19, 2018
409b093
Add Flag.FarShot so multiple "Far Shot" modifiers don't stack
brather1ng Dec 19, 2018
81d3411
Update crafting for 3.5.0
brather1ng Dec 21, 2018
28b001c
Remove PropertyMatchers
brather1ng Dec 21, 2018
087a46c
Add RePoE's basE_items.json
brather1ng Dec 21, 2018
08f0779
Add missing ItemClasses and ReleaseStates used by base items
brather1ng Dec 21, 2018
f066368
Update RePoE data to fix a bug with flask stat values
brather1ng Dec 22, 2018
61cf41d
Implement global modifier parsing in ItemParser
brather1ng Dec 22, 2018
5f96243
Change Item to group modifiers by ModLocation
brather1ng Dec 22, 2018
8a02a84
Add ItemParser unit test
brather1ng Dec 22, 2018
97f1da5
Extract not skill related methods out of SkillParserTestUtils
brather1ng Dec 22, 2018
48ac26b
Implement Item Tags parsing in ItemParser
brather1ng Dec 22, 2018
e8dfd5a
Add stat properties for ItemClass, FrameType and Corrupted to IEquipm…
brather1ng Dec 22, 2018
2cf52e4
Parse ItemClass, FrameType and IsCorrupted in ItemParser
brather1ng Dec 22, 2018
40839a8
Add EmptyItemSlotParser that sets ItemClass to Unarmed for MainHand
brather1ng Dec 22, 2018
a90bf9c
Move item and skill parser tests into correct namespaces
brather1ng Dec 22, 2018
a07e14a
Extract modifier building class out of skill and item parsers
brather1ng Dec 22, 2018
3b57b8c
Change SkillPreParseResult.IsMainSkill to condition
brather1ng Dec 22, 2018
53c7638
Parse requirements in ItemParser
brather1ng Dec 22, 2018
ef71a64
Parse buff stats in ItemParser
brather1ng Dec 22, 2018
65f0816
Parse properties in ItemParser
brather1ng Dec 22, 2018
29944c3
Parse quality in ItemParser
brather1ng Dec 23, 2018
ee111a0
Add ModifierLocalityTester.IsLocal()
brather1ng Dec 23, 2018
be8d498
Add ModifierLocalityTester.AffectsProperties()
brather1ng Dec 23, 2018
913aa73
Replace StatLocalityChecker by ModifierLocalityTester
brather1ng Dec 23, 2018
3212c21
Parse local modifiers in ItemParser
brather1ng Dec 23, 2018
1740847
Parse "with this weapon" in ConditionMatchers
brather1ng Dec 24, 2018
abc4461
Prefix local weapon mods with "with this weapon"; add weapon integrat…
brather1ng Dec 24, 2018
dbe08ae
Change IStatBuilder.AsItemProperty to use the ModifierSource's ItemSlot
brather1ng Dec 24, 2018
79aebd8
Parse property modifiers in ItemParser AsItemProperty
brather1ng Dec 24, 2018
70be4cf
Parse level/attribute requirements as properties in ItemParser
brather1ng Dec 24, 2018
bb58db7
Multiply value of global flask mods by flask effect
brather1ng Dec 24, 2018
ca26860
Extract partial parser classes from ItemParser
brather1ng Dec 24, 2018
f432712
Remove non-async CompositionRoot and change Program to initialize whe…
brather1ng Dec 25, 2018
1fd4d58
Add ParseableBaseItems.txt for usage in integration tests
brather1ng Dec 25, 2018
18e619a
Add base item parsing integration test
brather1ng Dec 25, 2018
82776fa
Move XmlUniqueList to GameModel project
brather1ng Dec 25, 2018
4f12100
Fix StatTranslotr.Translate throwing with duplicate stat ids
brather1ng Dec 25, 2018
372d1cd
Add unique item parsing integration test
brather1ng Dec 25, 2018
46f2b59
Support Iron Will Support
brather1ng Dec 25, 2018
17c87d7
Make sure no local modifiers with TotalOverride form are parsed
brather1ng Dec 25, 2018
f69d255
Add passive tree model to GameModel (as simple as required for parsing)
brather1ng Dec 25, 2018
fdff263
Add PassiveNodeParser for passive tree node parsing
brather1ng Dec 25, 2018
7858d60
Add SkilledPassiveNodeParser for enabling/skilling previously parsed …
brather1ng Dec 25, 2018
b1f881d
Add KeystoneStatMatchers to parse keystone modifiers on items
brather1ng Dec 26, 2018
9583731
Support keystone mods on skills
brather1ng Dec 26, 2018
fd68d18
Minor clean-up (mostly formatting and removed unused code)
brather1ng Dec 26, 2018
aa26dd6
Remove unused code from computation interfaces
brather1ng Dec 26, 2018
1e51c76
Document new Computation classes
brather1ng Dec 26, 2018
75f1830
Document some GameModel classes
brather1ng Dec 26, 2018
fe4035d
Add PassivePoints and AscendancyPassivePoints stats
brather1ng Dec 26, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using PoESkillTree.Computation.Common;
using PoESkillTree.Computation.Common.Builders.Entities;
using PoESkillTree.Computation.Common.Builders.Stats;
using PoESkillTree.GameModel;

namespace PoESkillTree.Computation.Builders.Tests.Actions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void HitWithOnBuildsToCorrectResult()
public void HitWithMultipleOnThrows()
{
var damageTypes = new[] { DamageType.Chaos, DamageType.Fire };
var damageTypeBuilder = Mock.Of<IDamageTypeBuilder>(b => b.BuildDamageTypes() == damageTypes);
var damageTypeBuilder = Mock.Of<IDamageTypeBuilder>(b => b.BuildDamageTypes(default) == damageTypes);
var sut = CreateSut();

var result = sut.HitWith(damageTypeBuilder).On.Build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Linq;
using Moq;
using NUnit.Framework;
using PoESkillTree.Computation.Builders.Behaviors;
using PoESkillTree.Computation.Builders.Stats;
using PoESkillTree.Computation.Common;
using PoESkillTree.Utils.Extensions;

namespace PoESkillTree.Computation.Builders.Tests.Behaviors
{
[TestFixture]
public class AffectedByModifiersToOtherStatValueTest
{
[TestCase(true, true)]
[TestCase(true, false)]
[TestCase(false, false)]
public void CalculateReturnsCorrectResult(bool formIsAffected, bool conditionStatValue)
{
var expected = (NodeValue?) 42;
var affectedForm = Form.Increase;
var retrievedForm = formIsAffected ? affectedForm : Form.BaseAdd;

var transformedStat = new Stat("transformed");
var otherStat = new Stat("other");
var conditionStat = new Stat("condition");
var expectedPaths = new (IStat, PathDefinition)[] { (transformedStat, PathDefinition.MainPath) }
.AsEnumerable();
if (formIsAffected && conditionStatValue)
expectedPaths = expectedPaths.Append((otherStat, PathDefinition.MainPath));

var context = Mock.Of<IValueCalculationContext>(c =>
c.GetValues(retrievedForm, expectedPaths) == new[] { expected } &&
c.GetValue(conditionStat, NodeType.Total, PathDefinition.MainPath) == (NodeValue?) conditionStatValue);
var transformedValue = new FunctionalValue(c => c.GetValues(retrievedForm, transformedStat).Sum(), "");
var sut = new AffectedByModifiersToOtherStatValue(transformedStat, otherStat, conditionStat, affectedForm,
transformedValue);

var actual = sut.Calculate(context);

Assert.AreEqual(expected, actual);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using Moq;
using NUnit.Framework;
using PoESkillTree.Computation.Builders.Behaviors;
using PoESkillTree.Computation.Builders.Stats;
using PoESkillTree.Computation.Common;

namespace PoESkillTree.Computation.Builders.Tests.Behaviors
{
[TestFixture]
public class DamageEffectivenessBaseValueTest
{
[TestCase(null, null)]
[TestCase(1.5, 2)]
public void CalculateReturnsCorrectResult(double? baseSetEffectiveness, double? baseAddEffectiveness)
{
var baseSet = (NodeValue?) 2;
var baseAdd = (NodeValue?) 3;
var expected = baseSet * (baseSetEffectiveness ?? 1) + baseAdd * (baseAddEffectiveness ?? 1);

var context = Mock.Of<IValueCalculationContext>(c =>
c.GetValue(TransformedStat, NodeType.BaseSet, PathDefinition.MainPath) == baseSet &&
c.GetValue(TransformedStat, NodeType.BaseAdd, PathDefinition.MainPath) == baseAdd &&
c.GetValue(SetEffectivenessStat, NodeType.Total, PathDefinition.MainPath) ==
(NodeValue?) baseSetEffectiveness &&
c.GetValue(AddEffectivenessStat, NodeType.Total, PathDefinition.MainPath) ==
(NodeValue?) baseAddEffectiveness);
var sut = CreateSut(
c => c.GetValue(TransformedStat, NodeType.BaseSet) + c.GetValue(TransformedStat, NodeType.BaseAdd));

var actual = sut.Calculate(context);

Assert.AreEqual(expected, actual);
}

[Test]
public void CalculateDoesNotTransformOtherForms()
{
var expected = (NodeValue?) 42;
var context = Mock.Of<IValueCalculationContext>(c =>
c.GetValue(TransformedStat, NodeType.Increase, PathDefinition.MainPath) == expected &&
c.GetValue(SetEffectivenessStat, NodeType.Total, PathDefinition.MainPath) == (NodeValue?) 2 &&
c.GetValue(AddEffectivenessStat, NodeType.Total, PathDefinition.MainPath) == (NodeValue?) 2);
var sut = CreateSut(c => c.GetValue(TransformedStat, NodeType.Increase));

var actual = sut.Calculate(context);

Assert.AreEqual(expected, actual);
}

[Test]
public void CalculateDoesNotTransformOtherStats()
{
var expected = (NodeValue?) 42;
var otherStat = new Stat("other");
var context = Mock.Of<IValueCalculationContext>(c =>
c.GetValue(otherStat, NodeType.BaseSet, PathDefinition.MainPath) == expected &&
c.GetValue(SetEffectivenessStat, NodeType.Total, PathDefinition.MainPath) == (NodeValue?) 2 &&
c.GetValue(AddEffectivenessStat, NodeType.Total, PathDefinition.MainPath) == (NodeValue?) 2);
var sut = CreateSut(c => c.GetValue(otherStat, NodeType.BaseSet));

var actual = sut.Calculate(context);

Assert.AreEqual(expected, actual);
}

private static DamageEffectivenessBaseValue CreateSut(Func<IValueCalculationContext, NodeValue?> baseCalculate)
=> new DamageEffectivenessBaseValue(TransformedStat, SetEffectivenessStat, AddEffectivenessStat,
new FunctionalValue(baseCalculate, ""));

private static readonly IStat TransformedStat = new Stat("transformed");
private static readonly IStat SetEffectivenessStat = new Stat("setEffectiveness");
private static readonly IStat AddEffectivenessStat = new Stat("addEffectiveness");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Linq;
using Moq;
using NUnit.Framework;
using PoESkillTree.Computation.Builders.Behaviors;
using PoESkillTree.Computation.Builders.Stats;
using PoESkillTree.Computation.Common;

namespace PoESkillTree.Computation.Builders.Tests.Behaviors
{
[TestFixture]
public class MaximumFormAggregatingValueTest
{
[Test]
public void CalculateReturnsNullWithOnlyNullValues()
{
var sut = CreateSut();
var context = MockContext(null, null);

var actual = sut.Calculate(context);

Assert.IsNull(actual);
}

[TestCase(0, ExpectedResult = 0)]
[TestCase(0, null, 1, 3, 4, 2, ExpectedResult = 4)]
public double CalculateReturnsCorrectResult(params int?[] values)
{
var sut = CreateSut();
var context = MockContext(values);

var actual = sut.Calculate(context);

return actual.Single();
}

[Test]
public void CalculateChecksForSameForm()
{
var transformedValue = new FunctionalValue(c => c.GetValues(Form.BaseSet, Paths).First(), "");
var sut = CreateSut(Stat, Form.More, transformedValue);
var context = MockContext(2, 4);

var actual = sut.Calculate(context);

Assert.AreEqual(2, actual.Single());
}

[Test]
public void CalculateChecksForSameSta()
{
var transformedValue = new FunctionalValue(c => c.GetValues(Form.BaseSet, Paths).First(), "");
var sut = CreateSut(new Stat("a"), Form.BaseSet, transformedValue);
var context = MockContext(2, 4);

var actual = sut.Calculate(context);

Assert.AreEqual(2, actual.Single());
}

[Test]
public void CalculateThrowsIfPathsContainsSameAndDifferentStats()
{
var paths = new[] { (Stat, PathDefinition.MainPath), (new Stat("a"), PathDefinition.MainPath) };
var transformedValue = new FunctionalValue(c => c.GetValues(Form.BaseSet, paths).Single(), "");
var sut = CreateSut(Stat, Form.BaseSet, transformedValue);
var nodeValues = new NodeValue?[0];
var context = Mock.Of<IValueCalculationContext>(c => c.GetValues(Form.BaseSet, paths) == nodeValues);

Assert.Throws<InvalidOperationException>(() => sut.Calculate(context));
}

private static readonly IStat Stat = new Stat("s");

private static readonly (IStat, PathDefinition)[] Paths =
{
(Stat, PathDefinition.MainPath), (Stat, new PathDefinition(new ModifierSource.Local.Given()))
};

private static MaximumFormAggregatingValue CreateSut()
{
var transformedValue = new FunctionalValue(c => c.GetValues(Form.BaseSet, Paths).Single(), "");
return CreateSut(Stat, Form.BaseSet, transformedValue);
}

private static MaximumFormAggregatingValue CreateSut(IStat stat, Form form, IValue transformedValue)
=> new MaximumFormAggregatingValue(stat, form, transformedValue);

private static IValueCalculationContext MockContext(params int?[] values)
{
var nodeValues = values.Select(v => (NodeValue?) v);
return Mock.Of<IValueCalculationContext>(c => c.GetValues(Form.BaseSet, Paths) == nodeValues);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Linq;
using Moq;
using NUnit.Framework;
using PoESkillTree.Computation.Builders.Behaviors;
using PoESkillTree.Computation.Builders.Stats;
using PoESkillTree.Computation.Common;
using PoESkillTree.GameModel.Items;

namespace PoESkillTree.Computation.Builders.Tests.Behaviors
{
[TestFixture]
public class RequirementUncappedSubtotalValueTest
{
[TestCase(-1.0, null, 1.0)]
[TestCase(42.0, 43.0, 41.0, 43.0, 40.0)]
public void CalculateReturnsCorrectResult(params double?[] values)
{
var expected = (NodeValue?) values.Max();
var transformedStat = new Stat("transformed");
var paths = values
.Select((_, i) => new PathDefinition(new ModifierSource.Local.Gem(ItemSlot.Helm, i)))
.ToList();
var contextMock = new Mock<IValueCalculationContext>();
contextMock.Setup(c => c.GetPaths(transformedStat)).Returns(paths);
for (var i = 0; i < paths.Count; i++)
{
var path = paths[i];
contextMock.Setup(c => c.GetValue(transformedStat, NodeType.PathTotal, path))
.Returns((NodeValue?) values[i]);
}
var transformedValue = new FunctionalValue(c => c.GetValues(transformedStat, NodeType.PathTotal).Sum(), "");
var sut = new RequirementUncappedSubtotalValue(transformedStat, transformedValue);

var actual = sut.Calculate(contextMock.Object);

Assert.AreEqual(expected, actual);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using PoESkillTree.Computation.Common;
using PoESkillTree.Computation.Common.Builders.Buffs;
using PoESkillTree.Computation.Common.Builders.Skills;
using PoESkillTree.GameModel;
using PoESkillTree.GameModel.Skills;

namespace PoESkillTree.Computation.Builders.Tests.Buffs
{
Expand All @@ -22,7 +24,7 @@ public void EffectBuildsToCorrectResults()
{
var sut = CreateSut(3);

var stats = sut.Effect.BuildToSingleResult().Stats;
var stats = sut.Effect.BuildToStats();

Assert.That(stats, Has.Exactly(3).Items);
Assert.AreEqual($"b0.EffectOn({default(Entity)})", stats[0].Identity);
Expand All @@ -36,7 +38,7 @@ public void AddStatBuildsToCorrectResult()
var addedStat = StatBuilderUtils.FromIdentity(StatFactory, "s", null);
var sut = CreateSut(3);

var stats = sut.AddStat(addedStat).BuildToSingleResult().Stats;
var stats = sut.AddStat(addedStat).BuildToStats();

Assert.That(stats, Has.Exactly(3).Items);
Assert.AreEqual("s", stats[0].Identity);
Expand All @@ -61,7 +63,7 @@ public void WithBuildsToCorrectResult()
var keyword = KeywordBuilder(1);
var sut = CreateSut(3);

var stats = sut.With(keyword).Effect.BuildToSingleResult().Stats;
var stats = sut.With(keyword).Effect.BuildToStats();

Assert.That(stats, Has.Exactly(2).Items);
Assert.AreEqual($"b0.EffectOn({default(Entity)})", stats[0].Identity);
Expand Down Expand Up @@ -99,7 +101,7 @@ public void WithResolveEffectBuildsToCorrectResult()
var sut = CreateSut(3);

var resolved = (IBuffBuilderCollection) sut.With(unresolved).Resolve(null);
var stats = resolved.Effect.BuildToSingleResult().Stats;
var stats = resolved.Effect.BuildToStats();

Assert.That(stats, Has.Exactly(2).Items);
}
Expand All @@ -125,7 +127,7 @@ public void WithEffectResolveBuildsToCorrectResult()
var sut = CreateSut(3);

var resolved = sut.With(unresolved).Effect.Resolve(null);
var stats = resolved.BuildToSingleResult().Stats;
var stats = resolved.BuildToStats();

Assert.That(stats, Has.Exactly(2).Items);
}
Expand Down
16 changes: 16 additions & 0 deletions PoESkillTree.Computation.Builders.Tests/Buffs/BuffBuilderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
using NUnit.Framework;
using PoESkillTree.Computation.Builders.Buffs;
using PoESkillTree.Computation.Builders.Entities;
using PoESkillTree.Computation.Builders.Resolving;
using PoESkillTree.Computation.Builders.Stats;
using PoESkillTree.Computation.Builders.Tests.Stats;
using PoESkillTree.Computation.Builders.Values;
using PoESkillTree.Computation.Common;
using PoESkillTree.Computation.Common.Builders.Resolving;
using PoESkillTree.GameModel;

namespace PoESkillTree.Computation.Builders.Tests.Buffs
{
Expand Down Expand Up @@ -78,6 +81,19 @@ public void AddStatBuildsToCorrectResultIfNotAsBuffActive()
Assert.AreEqual(expectedValue, actualValue);
}

[Test]
public void AddStatResolveResolvesIdentity()
{
var expectedIdentity = "buff";
var statBuilder = StatBuilderUtils.FromIdentity(StatFactory, "stat", null);
var resolveContext = new ResolveContext(null, null);
var sut = new BuffBuilder(StatFactory, new UnresolvedCoreBuilder<string>("unresolved",
c => CoreBuilder.Create(expectedIdentity)));

var builder = sut.AddStat(statBuilder).Resolve(resolveContext);
var value = builder.BuildToSingleResult().ValueConverter(new ValueBuilderImpl(1));
}

private static BuffBuilder CreateSut() =>
new BuffBuilder(StatFactory, CoreBuilder.Create("test"));

Expand Down
Loading