Skip to content

Commit

Permalink
feat!: create aplib.net alpha release
Browse files Browse the repository at this point in the history
  • Loading branch information
QuakeEye committed Jun 5, 2024
2 parents 923b541 + b0852e1 commit d677fb3
Show file tree
Hide file tree
Showing 73 changed files with 4,992 additions and 1,244 deletions.
43 changes: 14 additions & 29 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,9 @@ csharp_preserve_single_line_statements = true

# Naming rules

dotnet_naming_rule.private_members_with_underscore.severity = warning
dotnet_naming_rule.private_members_with_underscore.symbols = private_fields
dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore

dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.interface_should_begin_with_i.severity = warning
dotnet_naming_rule.interface_should_begin_with_i.symbols = interface
dotnet_naming_rule.interface_should_begin_with_i.style = begin_with_i

dotnet_naming_rule.types_should_be_pascal_case.severity = warning
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
Expand All @@ -219,47 +215,36 @@ dotnet_naming_rule.public_fields_should_be_pascal_case.severity = warning
dotnet_naming_rule.public_fields_should_be_pascal_case.symbols = public_fields
dotnet_naming_rule.public_fields_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.non_public_fields_with_underscore.severity = warning
dotnet_naming_rule.non_public_fields_with_underscore.symbols = non_public_fields
dotnet_naming_rule.non_public_fields_with_underscore.style = prefix_underscore

# Symbol specifications

dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =

dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum, field
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =

dotnet_naming_symbols.classes.applicable_kinds = class, struct, enum
dotnet_naming_symbols.classes.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.classes.required_modifiers =

dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =

dotnet_naming_symbols.public_fields.applicable_kinds = field, property
dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal, protected_internal
dotnet_naming_symbols.public_fields.applicable_kinds = field
dotnet_naming_symbols.public_fields.applicable_accessibilities = public

dotnet_naming_symbols.private_fields.applicable_kinds = field, property
dotnet_naming_symbols.private_fields.applicable_accessibilities = protected, private_protected, private
dotnet_naming_symbols.non_public_fields.applicable_kinds = field
dotnet_naming_symbols.non_public_fields.applicable_accessibilities = private, protected, private_protected, internal, protected_internal

# Naming styles

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.begin_with_i.required_prefix = I
dotnet_naming_style.begin_with_i.capitalization = pascal_case

dotnet_naming_style.prefix_underscore.capitalization = camel_case
dotnet_naming_style.prefix_underscore.required_prefix = _

# Use underscores for private fields
dotnet_naming_rule.private_fields_with_underscore.symbols = private_fields
dotnet_naming_rule.private_fields_with_underscore.style = prefix_underscore
dotnet_naming_rule.private_fields_with_underscore.severity = warning

dotnet_naming_style.prefix_underscore.capitalization = camel_case
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,6 @@ fabric.properties

*.iml
modules.xml

# JetBrains IDE files
**/.idea/
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,4 @@
<ProjectReference Include="..\Aplib.Core\Aplib.Core.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Stubs\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Aplib.Core.Belief;
using Aplib.Core.Desire;
using Aplib.Core.Agents;
using Aplib.Core.Belief.BeliefSets;
using Aplib.Core.Desire.DesireSets;
using Aplib.Core.Desire.Goals;
using Aplib.Core.Intent.Actions;
using Aplib.Core.Intent.Tactics;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Aplib.Core.Belief;
using Aplib.Core.Belief.Beliefs;
using Aplib.Core.Belief.BeliefSets;

namespace Aplib.Core.Tests.Belief;

Expand Down Expand Up @@ -98,7 +99,6 @@ private class TestBeliefSetProperties : BeliefSet
/// Belief that sets Updated to true when UpdateBelief is called.
/// </summary>
public SimpleBelief Belief2 { get; } = new();

}


Expand All @@ -122,7 +122,6 @@ private class TestBeliefSetPrivate : BeliefSet

/// <inheritdoc cref="_belief2"/>
public SimpleBelief Belief2 => _belief2;

}

/// <summary>
Expand Down
269 changes: 269 additions & 0 deletions Aplib.Core.Tests/Belief/BeliefTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
using Aplib.Core.Belief.Beliefs;
using FluentAssertions;
using Moq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Aplib.Core.Tests.Belief;

/// <summary>
/// Describes a set of tests for the <see cref="Belief{TReference,TObservation}" /> class.
/// </summary>
public class BeliefTests
{
// For testing a C# bug, see `Belief_ConstructedWithAValueTypeViaAnInterface_IsRejected`
private struct MyEnumerable : IEnumerable<int>
{
private readonly int _number;

private const int _max = 3;

public MyEnumerable(int number) => _number = number;

public IEnumerator<int> GetEnumerator()
{
for (int i = 0; i < _max; i++)
{
yield return _number;
}
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class TestBelief : Belief<object, object>
{
public object Reference => _reference;

public Func<object, object> GetObservationFromReference => _getObservationFromReference;

public Func<bool> ShouldUpdate => _shouldUpdate;

public TestBelief
(
Metadata metadata,
object reference,
Func<object, object> getObservationFromReference,
Func<bool> shouldUpdate
)
: base(metadata, reference, getObservationFromReference, shouldUpdate)
{
}

public TestBelief(object reference, Func<object, object> getObservationFromReference, Func<bool> shouldUpdate)
: base(reference, getObservationFromReference, shouldUpdate)
{
}

public TestBelief(Metadata metadata, object reference, Func<object, object> getObservationFromReference)
: base(metadata, reference, getObservationFromReference)
{
}

public TestBelief(object reference, Func<object, object> getObservationFromReference)
: base(reference, getObservationFromReference)
{
}
}

[Fact]
public void Belief_WhenConstructed_HasExpectedData()
{
// Arrange
Metadata metadata = It.IsAny<Metadata>();
object reference = new Mock<object>().Object;
Func<object, object> getObservationFromReference = new Mock<Func<object, object>>().Object;
Func<bool> shouldUpdate = It.IsAny<Func<bool>>();

// Act
TestBelief belief = new(metadata, reference, getObservationFromReference, shouldUpdate);

// Assert
belief.Metadata.Should().Be(metadata);
belief.Reference.Should().Be(reference);
belief.GetObservationFromReference.Should().Be(getObservationFromReference);
((object)belief.ShouldUpdate).Should().Be(shouldUpdate);
}

[Fact]
public void Belief_WithoutMetadata_HasExpectedData()
{
// Arrange
object reference = new Mock<object>().Object;
Func<object, object> getObservationFromReference = new Mock<Func<object, object>>().Object;
Func<bool> shouldUpdate = It.IsAny<Func<bool>>();

// Act
TestBelief belief = new(reference, getObservationFromReference, shouldUpdate);

// Assert
belief.Metadata.Id.Should().NotBeEmpty();
belief.Metadata.Name.Should().BeNull();
belief.Metadata.Description.Should().BeNull();
belief.Reference.Should().Be(reference);
belief.GetObservationFromReference.Should().Be(getObservationFromReference);
((object)belief.ShouldUpdate).Should().Be(shouldUpdate);
}

[Fact]
public void Belief_WithoutShouldUpdate_HasExpectedData()
{
// Arrange
Metadata metadata = It.IsAny<Metadata>();
object reference = new Mock<object>().Object;
Func<object, object> getObservationFromReference = new Mock<Func<object, object>>().Object;

// Act
TestBelief belief = new(metadata, reference, getObservationFromReference);

// Assert
belief.Metadata.Should().Be(metadata);
belief.Reference.Should().Be(reference);
belief.GetObservationFromReference.Should().Be(getObservationFromReference);
belief.ShouldUpdate().Should().BeTrue();
}

[Fact]
public void Belief_WithoutMetadataWithoutShouldUpdate_HasExpectedData()
{
// Arrange
object reference = new Mock<object>().Object;
Func<object, object> getObservationFromReference = new Mock<Func<object, object>>().Object;

// Act
TestBelief belief = new(reference, getObservationFromReference);

// Assert
belief.Metadata.Id.Should().NotBeEmpty();
belief.Metadata.Name.Should().BeNull();
belief.Metadata.Description.Should().BeNull();
belief.Reference.Should().Be(reference);
belief.GetObservationFromReference.Should().Be(getObservationFromReference);
belief.ShouldUpdate().Should().BeTrue();
}

/// <summary>
/// Given a Belief instance,
/// When it is assigned to a variable of its observation type,
/// Then it is implicitly converted to its observation type.
/// </summary>
[Fact]
public void Belief_AssignedToObservationType_IsCorrectlyImplicitlyConvertedToObservationType()
{
// Arrange
// ReSharper disable once ConvertToConstant.Local
string def = "def";

// Observation: Get the first letter.
Belief<string, char> belief = new(def, reference => reference[0]);

// Act, Assert
Assert.Equal(belief.Observation, belief);
}

/// <summary>
/// Given a reference that is actually a value type, hidden behind an interface,
/// When a new Belief is constructed from this reference,
/// The constructor throws an ArgumentException.
/// </summary>
[Fact]
public void Belief_ConstructedWithAValueTypeViaAnInterface_IsRejected()
{
// Arrange
MyEnumerable value = new(1);
const string paramName = "reference";

// ReSharper disable once ConvertToLocalFunction
Action construction = () =>
{
// The bug is the fact that we can get around the constraint that `TReference` should be a reference type.
_ = new Belief<IEnumerable<int>, List<int>>(value, values => values.ToList());
};

// Act, Assert
Assert.Throws<ArgumentException>(paramName, construction);
}

/// <summary>
/// Given a reference,
/// When a new Belief is constructed,
/// Then the observation is also initialized.
/// </summary>
[Fact]
public void Belief_DuringConstruction_UpdatesTheObservation()
{
// Arrange
// ReSharper disable once ConvertToConstant.Local
string def = "def";

// Act
Belief<string, string> belief = new(def, str => str);

// Assert
Assert.Equal(def, belief.Observation);
}

/// <summary>
/// Given a Belief instance with a reference,
/// When the reference is assigned to and UpdateBelief is called,
/// Then the observation is not updated.
/// </summary>
[Fact]
public void UpdateBelief_ReferenceIsAssignedTo_DoesNotUpdateObservation()
{
// Arrange
string def = "def";
Belief<string, string> belief = new(def, reference => reference, () => true);

// Act
def = "abc";
belief.UpdateBelief();

// Assert
Assert.NotEqual(def, belief.Observation);
}

/// <summary>
/// Given a Belief instance with an shouldUpdate condition that is not satisfied,
/// When UpdateBelief is called,
/// Then the observation is not updated.
/// </summary>
[Fact]
public void UpdateBelief_ShouldUpdateConditionIsNotSatisfied_DoesNotUpdateObservation()
{
// Arrange
List<int> list = [];
Belief<List<int>, int> belief = new(list, reference => reference.Count, () => false);

// Act
list.Add(420);
belief.UpdateBelief();

// Assert
Assert.NotEqual(list.Count, belief);
Assert.NotEqual(list.Count, belief.Observation);
}

/// <summary>
/// Given a Belief instance with an shouldUpdate condition that is satisfied,
/// When UpdateBelief is called,
/// Then the observation is updated.
/// </summary>
[Fact]
public void UpdateBelief_ShouldUpdateConditionIsSatisfied_UpdatesObservation()
{
// Arrange
List<int> list = [];
Belief<List<int>, int> belief = new(list, reference => reference.Count, () => true);

// Act
list.Add(69);
belief.UpdateBelief();

// Assert
Assert.Equal(list.Count, belief);
Assert.Equal(list.Count, belief.Observation);
}
}
Loading

0 comments on commit d677fb3

Please sign in to comment.