baseline: OpenMU upstream b5a0961 (fresh source)

This commit is contained in:
Acentech Dev
2026-07-14 19:00:35 +03:00
parent 450402e47d
commit 36fc125d5c
11968 changed files with 748705 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
// <copyright file="AttributeDefinitionTests.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.AttributeSystem.Tests;
/// <summary>
/// Tests for the <see cref="AttributeDefinition"/>.
/// </summary>
[TestFixture]
public class AttributeDefinitionTests
{
/// <summary>
/// Tests if different instances with the same id are treated as being equal.
/// </summary>
[Test]
public void Equality()
{
var attributeId = new Guid("86A31E67-8696-43C5-A9FE-CA85E1E07017");
var definition1 = new AttributeDefinition(attributeId, "foo", "bar");
var definition2 = new AttributeDefinition(attributeId, "test", "123");
Assert.That(definition1 == definition2, Is.True);
Assert.That(definition1, Is.EqualTo(definition2));
Assert.That(definition1.GetHashCode(), Is.EqualTo(definition2.GetHashCode()));
}
}

View File

@@ -0,0 +1,118 @@
// <copyright file="AttributeRelationshipElementTests.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.AttributeSystem.Tests;
/// <summary>
/// Tests for the <see cref="AttributeRelationshipElement"/>.
/// </summary>
[TestFixture]
public class AttributeRelationshipElementTests
{
/// <summary>
/// Tests if a relationship between two elements with the <see cref="InputOperator.Add"/> is handled correctly.
/// Both element values should be summed up, and according to the <see cref="InputOperator.Add"/> the inputOperand should be added on top.
/// </summary>
[Test]
public void InputOperatorAdd()
{
const int element1Value = 1;
const int element2Value = 2;
const int inputOperand = 10;
var element1 = new SimpleElement { Value = element1Value };
var element2 = new SimpleElement { Value = element2Value };
var operandElement = new ConstantElement(inputOperand);
var relationshipElement = new AttributeRelationshipElement(new[] { element1, element2 }, operandElement, InputOperator.Add);
Assert.That(relationshipElement.Value, Is.EqualTo(element1Value + element2Value + inputOperand));
}
/// <summary>
/// Tests if a relationship between two elements with the <see cref="InputOperator.Multiply"/> is handled correctly.
/// Both element values should be summed up, and according to the <see cref="InputOperator.Multiply"/> the sum should be multiplied with the inputOperand.
/// </summary>
[Test]
public void InputOperatorMultiply()
{
const int element1Value = 1;
const int element2Value = 2;
const int inputOperand = 10;
var element1 = new SimpleElement { Value = element1Value };
var element2 = new SimpleElement { Value = element2Value };
var operandElement = new ConstantElement(inputOperand);
var relationshipElement = new AttributeRelationshipElement(new[] { element1, element2 }, operandElement, InputOperator.Multiply);
Assert.That(relationshipElement.Value, Is.EqualTo((element1Value + element2Value) * inputOperand));
}
/// <summary>
/// Tests if a relationship between two elements with the <see cref="InputOperator.Exponentiate"/> is handled correctly.
/// Both element values should be summed up, and according to the <see cref="InputOperator.Exponentiate"/> the sum should be raised by the power of inputOperand.
/// </summary>
[Test]
public void InputOperatorPower()
{
const int element1Value = 1;
const int element2Value = 2;
const int inputOperand = 10;
var element1 = new SimpleElement { Value = element1Value };
var element2 = new SimpleElement { Value = element2Value };
var operandElement = new ConstantElement(inputOperand);
var relationshipElement = new AttributeRelationshipElement(new[] { element1, element2 }, operandElement, InputOperator.Exponentiate);
Assert.That(relationshipElement.Value, Is.EqualTo(Math.Pow(element1Value + element2Value, inputOperand)));
}
/// <summary>
/// Tests if a relationship between two elements with the <see cref="InputOperator.ExponentiateByAttribute"/> is handled correctly.
/// Both element values should be summed up, and according to the <see cref="InputOperator.ExponentiateByAttribute"/> the input operand should be raised by the power of the sum.
/// </summary>
[Test]
public void InputOperatorPowerByAttribute()
{
const int element1Value = 1;
const int element2Value = 2;
const int inputOperand = 10;
var element1 = new SimpleElement { Value = element1Value };
var element2 = new SimpleElement { Value = element2Value };
var operandElement = new ConstantElement(inputOperand);
var relationshipElement = new AttributeRelationshipElement(new[] { element1, element2 }, operandElement, InputOperator.ExponentiateByAttribute);
Assert.That(relationshipElement.Value, Is.EqualTo(Math.Pow(inputOperand, element1Value + element2Value)));
}
/// <summary>
/// Tests if the <see cref="AttributeRelationshipElement.Value"/> is updated correctly when one of the elements value changed.
/// </summary>
[Test]
public void ValueChangesWhenElementChanges()
{
const int element1Value = 1;
const int element2Value = 2;
const int inputOperand = 10;
var element1 = new SimpleElement { Value = element1Value };
var element2 = new SimpleElement { Value = element2Value };
var operandElement = new ConstantElement(inputOperand);
var relationshipElement = new AttributeRelationshipElement(new[] { element1, element2 }, operandElement, InputOperator.Add);
Assert.That(relationshipElement.Value, Is.EqualTo(element1Value + element2Value + inputOperand));
const int element1NewValue = 2;
element1.Value = element1NewValue;
Assert.That(relationshipElement.Value, Is.EqualTo(element1NewValue + element2Value + inputOperand));
}
/// <summary>
/// Tests if the <see cref="SimpleElement.ValueChanged"/> is called when one of the elements value changed.
/// </summary>
[Test]
public void ValueChangedEventWhenElementChanges()
{
const int element1Value = 1;
const int element2Value = 2;
const int inputOperand = 10;
var element1 = new SimpleElement { Value = element1Value };
var element2 = new SimpleElement { Value = element2Value };
var operandElement = new ConstantElement(inputOperand);
var relationshipElement = new AttributeRelationshipElement(new[] { element1, element2 }, operandElement, InputOperator.Add);
var eventCalled = false;
relationshipElement.ValueChanged += (sender, e) => eventCalled = true;
element1.Value = 2;
Assert.That(eventCalled, Is.True);
}
}

View File

@@ -0,0 +1,295 @@
// <copyright file="AttributeSystemTests.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.AttributeSystem.Tests;
/// <summary>
/// Tests for the <see cref="AttributeSystem"/>.
/// </summary>
[TestFixture]
public class AttributeSystemTests
{
private readonly AttributeDefinition _attributeA = new(Guid.NewGuid(), "A", "The A attribute");
private readonly AttributeDefinition _attributeB = new(Guid.NewGuid(), "B", "The B attribute");
private readonly AttributeDefinition _attributeC = new(Guid.NewGuid(), "C", "The C attribute");
private readonly AttributeDefinition _attributeD = new(Guid.NewGuid(), "D", "The D attribute");
private readonly AttributeDefinition _attributeAplusB = new(Guid.NewGuid(), "A+B", "The A+B attribute");
private readonly AttributeDefinition _attributeAtimesB = new(Guid.NewGuid(), "A*B", "The A*B attribute");
private readonly AttributeDefinition _attributeAchained = new(Guid.NewGuid(), "A'", "The chained A attribute");
private List<IAttribute> _statAttributes = null!;
private List<IAttribute> _baseAttributes = null!;
private List<AttributeRelationship> _relationShips = null!;
/// <summary>
/// Setups each test case.
/// </summary>
[SetUp]
public void Setup()
{
this._statAttributes = new List<IAttribute>();
this._baseAttributes = new List<IAttribute>();
this._relationShips = new List<AttributeRelationship>();
}
/// <summary>
/// Tests if a <see cref="StatAttribute"/> is added correctly and it's value is returned.
/// </summary>
[Test]
public void StatAttributeValue()
{
const int attributeAValue = 1234;
this._statAttributes.Add(new StatAttribute(this._attributeA, attributeAValue));
var system = this.CreateAttributeSystem();
var value = system[this._attributeA];
Assert.That(value, Is.EqualTo(attributeAValue));
}
/// <summary>
/// Tests if a attribute is added correctly and it's value is returned.
/// </summary>
[Test]
public void BaseAttributeValue()
{
const int attributeAValue = 9999;
this._baseAttributes.Add(new ConstValueAttribute(attributeAValue, this._attributeA));
var system = this.CreateAttributeSystem();
var value = system[this._attributeA];
Assert.That(value, Is.EqualTo(attributeAValue));
}
/// <summary>
/// Tests if a <see cref="AttributeRelationship"/> is added correctly and the combined (in this case a chained) attribute does return the right value.
/// </summary>
[Test]
public void ChainedAttribute()
{
const int attributeAValue = 1234;
this._statAttributes.Add(new StatAttribute(this._attributeA, attributeAValue));
this._relationShips.Add(new AttributeRelationship(this._attributeAchained, 1, this._attributeA));
var system = this.CreateAttributeSystem();
var value = system[this._attributeAchained];
Assert.That(value, Is.EqualTo(attributeAValue));
}
/// <summary>
/// Tests if a <see cref="AttributeRelationship"/> is added correctly and the multiplied attribute does return the right multiplied value.
/// </summary>
[Test]
public void MultipliedAttribute()
{
const int attributeAValue = 1234;
const int multiplier = 3;
this._statAttributes.Add(new StatAttribute(this._attributeA, attributeAValue));
this._relationShips.Add(new AttributeRelationship(this._attributeAchained, multiplier, this._attributeA));
var system = this.CreateAttributeSystem();
var value = system[this._attributeAchained];
Assert.That(value, Is.EqualTo(attributeAValue * multiplier));
}
/// <summary>
/// Tests if a combination of <see cref="AttributeRelationship"/>s is added and handled correctly.
/// Two attributes are combined to one target attribute.
/// It tests if the resulting value is calculated correctly.
/// </summary>
[Test]
public void CombinedRelationship()
{
const int attributeAValue = 1234;
const int attributeBValue = 4938;
const int attributeBMultiplier = 2;
this._statAttributes.Add(new StatAttribute(this._attributeA, attributeAValue));
this._statAttributes.Add(new StatAttribute(this._attributeB, attributeBValue));
this._relationShips.Add(new AttributeRelationship(this._attributeAplusB, 1, this._attributeA));
this._relationShips.Add(new AttributeRelationship(this._attributeAplusB, attributeBMultiplier, this._attributeB));
var system = this.CreateAttributeSystem();
var value = system[this._attributeAplusB];
Assert.That(value, Is.EqualTo(attributeAValue + (attributeBValue * attributeBMultiplier)));
}
/// <summary>
/// Tests if a combination of <see cref="AttributeRelationship"/>s is added and handled correctly.
/// Two attributes are combined to one target attribute.
/// It tests if the resulting value is calculated correctly after one of the depending attributes changed their value.
/// </summary>
[Test]
public void CombinedRelationshipChangedValue()
{
const int attributeAValue = 1234;
const int attributeBValue = 4938;
const int attributeBMultiplier = 2;
var statAttributeA = new StatAttribute(this._attributeA, attributeAValue);
this._statAttributes.Add(statAttributeA);
this._statAttributes.Add(new StatAttribute(this._attributeB, attributeBValue));
this._relationShips.Add(new AttributeRelationship(this._attributeAplusB, 1, this._attributeA));
this._relationShips.Add(new AttributeRelationship(this._attributeAplusB, attributeBMultiplier, this._attributeB));
var system = this.CreateAttributeSystem();
const int attributeAnewValue = 1000;
statAttributeA.Value = attributeAnewValue;
var value = system[this._attributeAplusB];
Assert.That(value, Is.EqualTo(attributeAnewValue + (attributeBValue * attributeBMultiplier)));
}
/// <summary>
/// Tests if adding additional elements results in a updated correct value.
/// </summary>
[Test]
public void CombinedRelationshipAddedElement()
{
const int attributeAValue = 1234;
const int attributeBValue = 4938;
const int attributeBMultiplier = 2;
var statAttributeA = new StatAttribute(this._attributeA, attributeAValue);
this._statAttributes.Add(statAttributeA);
this._statAttributes.Add(new StatAttribute(this._attributeB, attributeBValue));
this._relationShips.Add(new AttributeRelationship(this._attributeAplusB, 1, this._attributeA));
this._relationShips.Add(new AttributeRelationship(this._attributeAplusB, attributeBMultiplier, this._attributeB));
var system = this.CreateAttributeSystem();
const int addedAttributeValue = 10;
system.AddElement(new ConstValueAttribute(addedAttributeValue, this._attributeAplusB), this._attributeAplusB);
var value = system[this._attributeAplusB];
Assert.That(value, Is.EqualTo(attributeAValue + (attributeBValue * attributeBMultiplier) + addedAttributeValue));
}
/// <summary>
/// Tests if using another attribute as operand results in a correct value.
/// </summary>
[Test]
public void MultipliedAttributes()
{
const int attributeAValue = 1234;
const int attributeBValue = 2;
var statAttributeA = new StatAttribute(this._attributeA, attributeAValue);
var statAttributeB = new StatAttribute(this._attributeB, attributeBValue);
this._statAttributes.Add(statAttributeA);
this._statAttributes.Add(statAttributeB);
this._relationShips.Add(new AttributeRelationship(this._attributeAtimesB, this._attributeB, this._attributeA));
var system = this.CreateAttributeSystem();
var value = system[this._attributeAtimesB];
Assert.That(value, Is.EqualTo(attributeAValue * attributeBValue));
}
/// <summary>
/// Tests if using another attribute as operand results in a correct value.
/// </summary>
[TestCase(true, 2)]
[TestCase(false, 0)]
public void ConditionalAttributes(bool conditionMet, float expected)
{
const int bonusValue = 2;
var targetAttribute = this._attributeAplusB;
var bonusIfConditionMet = new StatAttribute(this._attributeB, bonusValue);
var conditionalAttribute = new StatAttribute(this._attributeC, conditionMet ? 1 : 0);
this._statAttributes.Add(bonusIfConditionMet);
this._statAttributes.Add(conditionalAttribute);
this._relationShips.Add(new AttributeRelationship(targetAttribute, conditionalAttribute.Definition, bonusIfConditionMet.Definition));
var system = this.CreateAttributeSystem();
var value = system[targetAttribute];
Assert.That(value, Is.EqualTo(expected));
}
/// <summary>
/// Tests the use case of multiplying a base value with a conditional bonus multiplier.
/// This is how Stats.DefenseIncreaseWithEquippedShield is intended to work.
/// </summary>
[TestCase(true, 105)]
[TestCase(false, 100)]
public void ConditionalAttributes_Multiply(bool conditionMet, float expected)
{
const float bonusMultiplier = 0.05f;
const float baseValue = 100f;
var targetAttribute = this._attributeAplusB;
var baseAttribute = new StatAttribute(this._attributeA, baseValue);
var bonusIfConditionMet = new StatAttribute(this._attributeB, bonusMultiplier);
var conditionalAttribute = new StatAttribute(this._attributeC, conditionMet ? 1 : 0);
var tempAttribute = this._attributeD;
this._statAttributes.Add(baseAttribute);
this._statAttributes.Add(bonusIfConditionMet);
this._statAttributes.Add(conditionalAttribute);
// First, we copy our base value to the target
this._relationShips.Add(new AttributeRelationship(targetAttribute, 1, baseAttribute.Definition));
// Then, we calculate the bonus into a temporary attribute, depending on the condition
this._relationShips.Add(new AttributeRelationship(tempAttribute, conditionalAttribute.Definition, bonusIfConditionMet.Definition));
// Finally, we apply the temporary attribute as multiplier for the base value and add it to the target
this._relationShips.Add(new AttributeRelationship(targetAttribute, tempAttribute, baseAttribute.Definition));
var system = this.CreateAttributeSystem();
var value = system[targetAttribute];
Assert.That(value, Is.EqualTo(expected));
}
/// <summary>
/// Tests if a changed maximum value of an attribute is considered when requesting it from the AttributeSystem.
/// </summary>
[Test]
public void MaximumValueIsRespectedFromStoredDefinition()
{
// Create an attribute definition with a maximum value
var attackSpeedDefinition = new AttributeDefinition(Guid.NewGuid(), "AttackSpeed", "Attack speed attribute")
{
MaximumValue = 300,
};
// Add a stat attribute with a very high value (exceeding the maximum)
const int highValue = 5000;
this._statAttributes.Add(new StatAttribute(attackSpeedDefinition, highValue));
var system = this.CreateAttributeSystem();
// Create a different instance of the attribute definition (simulating what happens when
// the definition is retrieved from a different source, like a database)
var differentInstanceOfDefinition = new AttributeDefinition(attackSpeedDefinition.Id, "AttackSpeed", "Attack speed attribute");
// The system should return the maximum value from the stored definition, not exceed it
var value = system[differentInstanceOfDefinition];
Assert.That(value, Is.EqualTo(300));
}
/// <summary>
/// Tests if a changed maximum value is respected for a ComposableAttribute when requesting it from the AttributeSystem.
/// </summary>
[Test]
public void MaximumValueIsRespectedFromStoredDefinitionForComposableAttribute()
{
// Create an attribute definition with a maximum value
var attackSpeedDefinition = new AttributeDefinition(Guid.NewGuid(), "AttackSpeed", "Attack speed attribute")
{
MaximumValue = 300,
};
// Add a base attribute which will create a ComposableAttribute
const int highValue = 5000;
this._baseAttributes.Add(new ConstValueAttribute(highValue, attackSpeedDefinition));
var system = this.CreateAttributeSystem();
// Create a different instance of the attribute definition
var differentInstanceOfDefinition = new AttributeDefinition(attackSpeedDefinition.Id, "AttackSpeed", "Attack speed attribute");
// The system should return the maximum value from the stored definition, not exceed it
var value = system[differentInstanceOfDefinition];
Assert.That(value, Is.EqualTo(300));
}
/// <summary>
/// Creates the attribute system for testing, initialized with <see cref="_statAttributes"/>, <see cref="_baseAttributes"/> and <see cref="_relationShips"/>.
/// </summary>
/// <returns>The created attribute system, initialized with <see cref="_statAttributes"/>, <see cref="_baseAttributes"/> and <see cref="_relationShips"/>.</returns>
private AttributeSystem CreateAttributeSystem()
{
return new(this._statAttributes, this._baseAttributes, this._relationShips);
}
}

View File

@@ -0,0 +1,198 @@
// <copyright file="ComposableAttributeTests.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.AttributeSystem.Tests;
/// <summary>
/// Tests for the <see cref="ComposableAttribute"/>.
/// </summary>
[TestFixture]
public class ComposableAttributeTests
{
private ComposableAttribute _composableAttribute = null!;
/// <summary>
/// Sets up each test case.
/// </summary>
[SetUp]
public void Setup()
{
var attributeDefinition = new AttributeDefinition(new Guid("52263EA9-F309-475D-B10B-352D3BFD7650"), "Test attribute", "Test attribute");
this._composableAttribute = new ComposableAttribute(attributeDefinition);
}
/// <summary>
/// Tests if the value is 0 after creation.
/// </summary>
[Test]
public void ValueIsNullAfterCreation()
{
Assert.That(this._composableAttribute.Value, Is.EqualTo(0));
}
/// <summary>
/// Tests if the value is updated after adding an element.
/// </summary>
[Test]
public void ValueAfterAddedElement()
{
var element = new ConstantElement(4711);
this._composableAttribute.AddElement(element);
Assert.That(this._composableAttribute.Value, Is.EqualTo(element.Value));
}
/// <summary>
/// Tests if the value of multiple elements is combined in <see cref="ComposableAttribute.Value"/> by using <see cref="AggregateType.AddRaw"/>.
/// </summary>
[Test]
public void ValueOfMultipleRawElements()
{
var element1 = new ConstantElement(3000);
var element2 = new ConstantElement(5000);
this._composableAttribute.AddElement(element1);
this._composableAttribute.AddElement(element2);
Assert.That(this._composableAttribute.Value, Is.EqualTo(element1.Value + element2.Value));
}
/// <summary>
/// Tests if the value of multiple elements is combined in <see cref="ComposableAttribute.Value"/>
/// by using <see cref="AggregateType.AddRaw"/> in the first element and
/// by using <see cref="AggregateType.Multiplicate"/> in the second element.
/// </summary>
[Test]
public void ValueWithRawAndMultiplierElements()
{
var element1 = new ConstantElement(3000);
var element2 = new SimpleElement { Value = 5, AggregateType = AggregateType.Multiplicate };
this._composableAttribute.AddElement(element1);
this._composableAttribute.AddElement(element2);
Assert.That(this._composableAttribute.Value, Is.EqualTo(element1.Value * element2.Value));
}
/// <summary>
/// Tests if the value of multiple elements is combined in <see cref="ComposableAttribute.Value"/>
/// by using <see cref="AggregateType.AddRaw"/> in the first element,
/// by using <see cref="AggregateType.Multiplicate"/> in the second element and
/// by using <see cref="AggregateType.AddFinal"/> in the last element.
/// </summary>
[Test]
public void ValueWithRawMultiplierAndFinalElements()
{
var element1 = new ConstantElement(3000);
var element2 = new SimpleElement { Value = 5, AggregateType = AggregateType.Multiplicate };
var element3 = new SimpleElement { Value = 1000, AggregateType = AggregateType.AddFinal };
this._composableAttribute.AddElement(element1);
this._composableAttribute.AddElement(element2);
this._composableAttribute.AddElement(element3);
Assert.That(this._composableAttribute.Value, Is.EqualTo((element1.Value * element2.Value) + element3.Value));
}
/// <summary>
/// Tests if the value of multiple elements is combined in <see cref="ComposableAttribute.Value"/>
/// by using one <see cref="AggregateType.AddRaw"/> element and
/// by using several <see cref="AggregateType.Maximum"/> elements.
/// </summary>
[Test]
public void ValueWithRawAndMultipleMaximumElements()
{
var element1 = new ConstantElement(3000);
var element2 = new SimpleElement { Value = 5, AggregateType = AggregateType.Maximum };
var element3 = new SimpleElement { Value = 1000, AggregateType = AggregateType.Maximum };
this._composableAttribute.AddElement(element1);
this._composableAttribute.AddElement(element2);
this._composableAttribute.AddElement(element3);
Assert.That(this._composableAttribute.Value, Is.EqualTo(element1.Value + Math.Max(element2.Value, element3.Value)));
}
/// <summary>
/// Tests if the value of multiple elements is combined in <see cref="ComposableAttribute.Value"/>
/// by using <see cref="AggregateType.Multiplicate"/> elements exclusively.
/// A <see cref="AggregateType.AddRaw"/> element of value 1 should be assumed.
/// </summary>
[Test]
public void ValueWithMultiplierElementsOnly()
{
var element1 = new SimpleElement { Value = 5, AggregateType = AggregateType.Multiplicate };
var element2 = new SimpleElement { Value = 1000, AggregateType = AggregateType.Multiplicate };
this._composableAttribute.AddElement(element1);
this._composableAttribute.AddElement(element2);
Assert.That(this._composableAttribute.Value, Is.EqualTo(element1.Value * element2.Value));
}
/// <summary>
/// Tests if the value of multiple elements is combined in <see cref="ComposableAttribute.Value"/>
/// by using <see cref="AggregateType.Multiplicate"/> in the first element and
/// by using <see cref="AggregateType.AddFinal"/> in the second element.
/// </summary>
[Test]
public void ValueWithMultiplierAndFinalElements()
{
var element1 = new SimpleElement { Value = 5, AggregateType = AggregateType.Multiplicate };
var element2 = new SimpleElement { Value = 1000, AggregateType = AggregateType.AddFinal };
this._composableAttribute.AddElement(element1);
this._composableAttribute.AddElement(element2);
Assert.That(this._composableAttribute.Value, Is.EqualTo(1000));
}
/// <summary>
/// Tests if the updated correctly after an element got removed.
/// </summary>
[Test]
public void ValueCorrectAfterElementRemoved()
{
var element1 = new ConstantElement(3000);
var element2 = new SimpleElement { Value = 5, AggregateType = AggregateType.Multiplicate };
var element3 = new SimpleElement { Value = 1000, AggregateType = AggregateType.AddFinal };
this._composableAttribute.AddElement(element1);
this._composableAttribute.AddElement(element2);
this._composableAttribute.AddElement(element3);
Assert.That(this._composableAttribute.Value, Is.EqualTo((element1.Value * element2.Value) + element3.Value));
this._composableAttribute.RemoveElement(element2);
Assert.That(this._composableAttribute.Value, Is.EqualTo(element1.Value + element3.Value));
}
/// <summary>
/// Tests if the <see cref="BaseAttribute.ValueChanged"/> is called when the depending element value changed.
/// </summary>
[Test]
public void ValueChangedEvent()
{
var element = new SimpleElement { Value = 5 };
this._composableAttribute.AddElement(element);
var eventCalled = false;
this._composableAttribute.ValueChanged += (_, _) => eventCalled = true;
element.Value = 6;
Assert.That(eventCalled, Is.True);
}
/// <summary>
/// Tests if the <see cref="BaseAttribute.ValueChanged"/> is called when a new depending element was added.
/// </summary>
[Test]
public void ValueChangedEventWhenElementAdded()
{
var element = new SimpleElement { Value = 5 };
bool eventCalled = false;
this._composableAttribute.ValueChanged += (_, _) => eventCalled = true;
this._composableAttribute.AddElement(element);
Assert.That(eventCalled, Is.True);
}
/// <summary>
/// Tests if the <see cref="BaseAttribute.ValueChanged"/> is called when a new depending element was removed.
/// </summary>
[Test]
public void ValueChangedEventWhenElementRemoved()
{
var element = new SimpleElement { Value = 5 };
this._composableAttribute.AddElement(element);
bool eventCalled = false;
this._composableAttribute.ValueChanged += (_, _) => eventCalled = true;
this._composableAttribute.RemoveElement(element);
Assert.That(eventCalled, Is.True);
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="ConstValueAttributeTests.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.AttributeSystem.Tests;
/// <summary>
/// Tests for the <see cref="ConstValueAttribute"/>.
/// </summary>
[TestFixture]
public class ConstValueAttributeTests
{
/// <summary>
/// Tests if the value of the attribute is as defined in the constructor.
/// </summary>
[Test]
public void ValueAsDefined()
{
const int constantValue = 999;
var element = new ConstValueAttribute(constantValue, new AttributeDefinition());
Assert.That(element.Value, Is.EqualTo(constantValue));
}
/// <summary>
/// Tests if the <see cref="ConstValueAttribute.AggregateType"/> is <see cref="AggregateType.AddRaw"/>.
/// </summary>
[Test]
public void AggregateTypeIsRaw()
{
var element = new ConstValueAttribute(999, new AttributeDefinition());
Assert.That(element.AggregateType, Is.EqualTo(AggregateType.AddRaw));
}
}

View File

@@ -0,0 +1,34 @@
// <copyright file="ConstantElementTests.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.AttributeSystem.Tests;
/// <summary>
/// Tests for the <see cref="ConstantElement"/>.
/// </summary>
[TestFixture]
public class ConstantElementTests
{
/// <summary>
/// Tests if the value of the element is as defined in the constructor.
/// </summary>
[Test]
public void ValueAsDefined()
{
const int constantValue = 999;
var element = new ConstantElement(constantValue);
Assert.That(element.Value, Is.EqualTo(constantValue));
}
/// <summary>
/// Tests if the <see cref="ConstantElement.AggregateType"/> is <see cref="AggregateType.AddRaw"/>.
/// </summary>
[Test]
public void AggregateTypeIsRaw()
{
const int constantValue = 999;
var element = new ConstantElement(constantValue);
Assert.That(element.AggregateType, Is.EqualTo(AggregateType.AddRaw));
}
}

View File

@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable;CS4014;VSTHRD110;VSTHRD100</WarningsAsErrors>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>bin\Debug\MUnique.OpenMU.AttributeSystem.Tests.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>bin\Release\MUnique.OpenMU.AttributeSystem.Tests.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\src\SharedAssemblyInfo.cs" Link="Properties\SharedAssemblyInfo.cs" />
<Compile Include="..\..\src\SharedGlobalUsings.cs" Link="SharedGlobalUsings.cs" />
<Compile Include="..\SharedTestUsings.cs" Link="SharedTestUsings.cs" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\src\stylecop.json" Link="stylecop.json" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\src\.editorconfig" Link=".editorconfig" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NUnit" />
<PackageReference Include="NUnit3TestAdapter" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\AttributeSystem\MUnique.OpenMU.AttributeSystem.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
// <copyright file="AssemblyInfo.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
using System.Reflection;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MUnique.OpenMU.AttributeSystem.Test")]

View File

@@ -0,0 +1,61 @@
// <copyright file="SimpleElementTests.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.AttributeSystem.Tests;
/// <summary>
/// Tests for the <see cref="SimpleElement"/>.
/// </summary>
[TestFixture]
public class SimpleElementTests
{
/// <summary>
/// Tests if the value is 0 after creation.
/// </summary>
[Test]
public void ValueIsNullAfterCreation()
{
var element = new SimpleElement();
Assert.That(element.Value, Is.EqualTo(0));
}
/// <summary>
/// Tests if the value returns the same as what has been set before.
/// </summary>
[Test]
public void ValueIsSet()
{
const int elementValue = 4711;
var element = new SimpleElement { Value = elementValue };
Assert.That(element.Value, Is.EqualTo(elementValue));
}
/// <summary>
/// Tests if the <see cref="SimpleElement.ValueChanged"/> is called when the <see cref="SimpleElement.Value"/> has been changed.
/// </summary>
[Test]
public void ValueChangedEventWhenValueChanges()
{
var element = new SimpleElement();
bool eventCalled = false;
element.ValueChanged += (sender, e) => eventCalled = true;
element.Value = 6;
Assert.That(eventCalled, Is.True);
}
/// <summary>
/// Tests if the <see cref="SimpleElement.ValueChanged"/> is called when the <see cref="SimpleElement.AggregateType"/> has been changed.
/// </summary>
[Test]
public void ValueChangedEventWhenAggregateTypeChanges()
{
var element = new SimpleElement { Value = 0 };
bool eventCalled = false;
element.ValueChanged += (sender, e) => eventCalled = true;
element.AggregateType = AggregateType.AddFinal;
Assert.That(eventCalled, Is.True);
}
}