Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [0.13.2] - 2024-11-13
## [0.14.0] - 2024-11-15

**New**:
- Added a constructor to *GameObjectPool* that allows to setup a costum instantiator
- Added *PublishSafe* method to *IMessageBrokerService* to allow publishing messages safely in chase of chain subscriptions during publishing of a message

**Changed**:
- *Subscribe* and *Unsubscribe* throw an *InvalidOperationException* when being executed during a message being published

**Fixed**:
- Fixed *ObjectPool* & *PoolService* tests that would block builds sometimes
- CoroutineTests issues running when building released projects

## [0.13.1] - 2024-11-04

Expand Down
115 changes: 69 additions & 46 deletions Runtime/MessageBrokerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,32 @@ public interface IMessageBrokerService
/// Publish a message in the message broker.
/// If there is no object subscribing the message type, nothing will happen
/// </summary>
/// <remarks>
/// Use <see cref="PublishSafe{T}(T)"/> it there are a chain subscriptions during publishing
/// </remarks>
void Publish<T>(T message) where T : IMessage;


/// <summary>
/// Publish a message in the message broker.
/// If there is no object subscribing the message type, nothing will happen
/// </summary>
/// <remarks>
/// This method can be slow and allocated extra memory if there are a lot of subscribers to the <typeparamref name="T"/>.
/// Use <see cref="Publish{T}(T)"/> instead for faster iteration speed IF and ONLY IF there aren't chain subscriptions during publishing
/// </remarks>
void PublishSafe<T>(T message) where T : IMessage;

/// <summary>
/// Subscribes to the message type.
/// Will invoke the <paramref name="action"/> every time the message of the subscribed type is published.
/// </summary>
void Subscribe<T>(Action<T> action) where T : IMessage;

/// <summary>
/// Unsubscribe the <paramref name="action"/> from the message broker.
/// </summary>
void Unsubscribe<T>(Action<T> action) where T : IMessage;


/// <summary>
/// Unsubscribe all actions from the message broker from of the given message type.
/// Unsubscribe the action of <typeparamref name="T"/> from the <paramref name="subscriber"/> in the message broker.
/// If <paramref name="subscriber"/> is null then will unsubscribe from ALL subscribers currently subscribed to <typeparamref name="T"/>
/// </summary>
void Unsubscribe<T>() where T : IMessage;
void Unsubscribe<T>(object subscriber = null) where T : IMessage;

/// <summary>
/// Unsubscribe from all messages.
Expand All @@ -53,7 +62,9 @@ public interface IMessageBrokerService
/// <inheritdoc />
public class MessageBrokerService : IMessageBrokerService
{
private readonly IDictionary<Type, IDictionary<object, IList>> _subscriptions = new Dictionary<Type, IDictionary<object, IList>>();
private readonly IDictionary<Type, IDictionary<object, Delegate>> _subscriptions = new Dictionary<Type, IDictionary<object, Delegate>>();

private (bool, IMessage) _isPublishing;

/// <inheritdoc />
public void Publish<T>(T message) where T : IMessage
Expand All @@ -63,18 +74,35 @@ public void Publish<T>(T message) where T : IMessage
return;
}

var subscriptionCopy = new IList[subscriptionObjects.Count];

_isPublishing = (true, message);

Comment on lines +77 to +78
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Thread-safety concerns with _isPublishing field in Publish<T> method.

The _isPublishing field is accessed without any synchronization, which can cause race conditions in a multi-threaded environment. If multiple threads call Publish simultaneously, the state of _isPublishing may become inconsistent. Consider implementing thread synchronization mechanisms to protect shared state.

Also applies to: 86-87

foreach (var subscription in subscriptionObjects)
{
var action = (Action<T>)subscription.Value;

action(message);
}

_isPublishing = (false, message);
}

/// <inheritdoc />
public void PublishSafe<T>(T message) where T : IMessage
{
if (!_subscriptions.TryGetValue(typeof(T), out var subscriptionObjects))
{
return;
}

var subscriptionCopy = new Delegate[subscriptionObjects.Count];

subscriptionObjects.Values.CopyTo(subscriptionCopy, 0);

for (var i = 0; i < subscriptionCopy.Length; i++)
{
var actions = (List<Action<T>>) subscriptionCopy[i];
var action = (Action<T>)subscriptionCopy[i];

for (var index = 0; index < actions.Count; index++)
{
actions[index](message);
}
action(message);
}
}

Expand All @@ -88,58 +116,51 @@ public void Subscribe<T>(Action<T> action) where T : IMessage
{
throw new ArgumentException("Subscribe static functions to a message is not supported!");
}

if (!_subscriptions.TryGetValue(type, out var subscriptionObjects))
if(_isPublishing.Item1)
{
subscriptionObjects = new Dictionary<object, IList>();
_subscriptions.Add(type, subscriptionObjects);
throw new InvalidOperationException($"Cannot subscribe to {type.Name} message while publishing " +
$"{_isPublishing.Item2.GetType().Name} message. Use {nameof(PublishSafe)} instead!");
Comment on lines +119 to +122
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Exception handling in Subscribe<T> may lead to unexpected behavior.

Throwing an InvalidOperationException when subscribing during publishing may disrupt the application's flow, especially if the caller is not expecting it. Additionally, without thread synchronization, this check may not reliably prevent issues. Consider handling this scenario more gracefully or documenting the behavior clearly.

Comment on lines +121 to +122
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential NullReferenceException in exception messages.

If _isPublishing.Item2 is null, calling _isPublishing.Item2.GetType().Name will throw a NullReferenceException. Ensure that message is not null when setting _isPublishing, or add a null check before accessing GetType().

Apply this diff to add null checks:

+if (_isPublishing.Item2 != null)
+{
    throw new InvalidOperationException($"Cannot subscribe to {type.Name} message while publishing " +
        $"{_isPublishing.Item2.GetType().Name} message. Use {nameof(PublishSafe)} instead!");
+}
+else
+{
+   throw new InvalidOperationException($"Cannot subscribe to {type.Name} message while publishing. Use {nameof(PublishSafe)} instead!");
+}

Also applies to: 148-149

}

if (!subscriptionObjects.TryGetValue(subscriber, out IList actions))
if (!_subscriptions.TryGetValue(type, out var subscriptionObjects))
{
actions = new List<Action<T>>();
subscriptionObjects.Add(subscriber, actions);
subscriptionObjects = new Dictionary<object, Delegate>();
_subscriptions.Add(type, subscriptionObjects);
}

actions.Add(action);
subscriptionObjects[subscriber] = action;
}

/// <inheritdoc />
public void Unsubscribe<T>(Action<T> action) where T : IMessage
public void Unsubscribe<T>(object subscriber = null) where T : IMessage
{
var type = typeof(T);
var subscriber = action.Target;

if (subscriber == null)
{
throw new ArgumentException("Subscribe static functions to a message is not supported!");
}
_subscriptions.Remove(type);

if (!_subscriptions.TryGetValue(type, out var subscriptionObjects) ||
!subscriptionObjects.TryGetValue(subscriber, out var actions))
{
return;
}

actions.Remove(action);

if (actions.Count == 0)
if (_isPublishing.Item1)
{
subscriptionObjects.Remove(subscriber);
throw new InvalidOperationException($"Cannot unsubscribe to {type.Name} message while publishing " +
$"{_isPublishing.Item2.GetType().Name} message. Use {nameof(PublishSafe)} instead!");
}
if (!_subscriptions.TryGetValue(type, out var subscriptionObjects))
{
return;
}

subscriptionObjects.Remove(subscriber);

if (subscriptionObjects.Count == 0)
{
_subscriptions.Remove(type);
}
}

/// <inheritdoc />
public void Unsubscribe<T>() where T : IMessage
{
_subscriptions.Remove(typeof(T));
}

/// <inheritdoc />
public void UnsubscribeAll(object subscriber = null)
{
Expand All @@ -149,12 +170,14 @@ public void UnsubscribeAll(object subscriber = null)
return;
}

if (_isPublishing.Item1)
{
throw new InvalidOperationException($"Cannot unsubscribe from {subscriber} message while publishing " +
$"{_isPublishing.Item2.GetType().Name} message. Use {nameof(PublishSafe)} instead!");
}
foreach (var subscriptionObjects in _subscriptions.Values)
{
if (subscriptionObjects.ContainsKey(subscriber))
{
subscriptionObjects.Remove(subscriber);
}
subscriptionObjects.Remove(subscriber);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion Tests/Editor/EditMode/InstallerTest.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System;
using GameLovers.Services;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The using directive for GameLovers.Services has been removed and replaced with a new using directive for GameLoversEditor.Services.Tests. Please verify if this change is intentional and aligns with the desired namespace for the test class.

- using GameLovers.Services;
+ using GameLoversEditor.Services.Tests;

using NUnit.Framework;

// ReSharper disable once CheckNamespace

namespace GameLovers.Services.Tests
namespace GameLoversEditor.Services.Tests
{
public class InstallerTest
{
Expand Down
42 changes: 34 additions & 8 deletions Tests/Editor/EditMode/MessageBrokerServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,35 @@ public void Subscribe_Publish_Successfully()
{
_messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall);
_messageBroker.Publish(_messageType1);
_messageBroker.PublishSafe(_messageType1);

Comment on lines +41 to 42

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

Consider adding a comment or documentation to explain the purpose and behavior of the PublishSafe method.

_subscriber.Received().MockMessageCall(_messageType1);
_subscriber.Received(2).MockMessageCall(_messageType1);
}

[Test]
Comment on lines +41 to +46

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The addition of the PublishSafe method to the IMessageBrokerService interface and the modification of the behavior of the Subscribe and Unsubscribe methods seem appropriate. However, it would be helpful to have more context about the changes made in these methods.

public void Subscribe_MultipleSubscriptionSameType_ReplacePreviousSubscription()
{
_messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall);
_messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall2);
_messageBroker.Publish(_messageType1);
_messageBroker.PublishSafe(_messageType1);

_subscriber.DidNotReceive().MockMessageCall(_messageType1);
_subscriber.Received(2).MockMessageCall2(_messageType1);
}
Comment on lines +47 to +56

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The changes made to test multiple subscriptions and chain subscriptions are reasonable. However, it would be beneficial to have more information about the specific issues related to CoroutineTests that were fixed.


[Test]
public void Publish_ChainSubscribe_Successfully()
{
// TODO: Test
Assert.True(true);
Comment on lines +58 to +62
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Missing test implementation for chain subscriptions

This test is crucial as chain subscriptions are a key feature mentioned in the PR objectives, specifically for the new PublishSafe method. The current placeholder doesn't verify this important functionality.

Would you like me to help implement this test? Here's what we should verify:

  1. Chain subscription scenario where publishing a message triggers another subscription
  2. Verify that PublishSafe handles this scenario correctly
  3. Compare behavior between Publish and PublishSafe methods in chain subscription scenarios

}
Comment on lines +59 to 63

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The placeholder test method Publish_ChainSubscribe_Successfully does not contain any assertions or meaningful test logic. It should either be removed or implemented with relevant test cases.


[Test]
public void Publish_WithoutSubscription_DoesNothing()
{
_messageBroker.Publish(_messageType1);
_messageBroker.PublishSafe(_messageType1);

_subscriber.DidNotReceive().MockMessageCall(_messageType1);
}
Expand All @@ -54,22 +75,24 @@ public void Publish_WithoutSubscription_DoesNothing()
public void Unsubscribe_Successfully()
{
_messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall);
_messageBroker.Unsubscribe<MessageType1>(_subscriber.MockMessageCall);
_messageBroker.Unsubscribe<MessageType1>(_subscriber);
_messageBroker.Publish(_messageType1);
_messageBroker.PublishSafe(_messageType1);

_subscriber.DidNotReceive().MockMessageCall(_messageType1);
}
Comment on lines +78 to 83

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The changes made to test the successful unsubscribe operation and removing all subscriptions of the same type are appropriate.


[Test]
public void UnsubscribeWithAction_KeepsSubscriptionSameType_Successfully()
public void UnsubscribeWithAction_MultipleSubscriptionSameType_RemoveAllScriptionsOfSameType()
{
_messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall);
_messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall2);
_messageBroker.Unsubscribe<MessageType1>(_subscriber.MockMessageCall);
_messageBroker.Unsubscribe<MessageType1>(_subscriber);
_messageBroker.Publish(_messageType1);
_messageBroker.PublishSafe(_messageType1);

_subscriber.DidNotReceive().MockMessageCall(_messageType1);
_subscriber.Received().MockMessageCall2(_messageType1);
_subscriber.DidNotReceive().MockMessageCall2(_messageType1);
Comment on lines +86 to +95

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The modifications to test the behavior of unsubscribing with multiple subscriptions of the same type and publishing messages after unsubscribing are valid.

}

[Test]
Expand All @@ -79,9 +102,10 @@ public void UnsubscribeWithoutAction_KeepsSubscriptionDifferentType_Successfully
_messageBroker.Subscribe<MessageType2>(_subscriber.MockMessageAlternativeCall);
_messageBroker.Unsubscribe<MessageType1>();
_messageBroker.Publish(_messageType2);
_messageBroker.PublishSafe(_messageType2);

_subscriber.DidNotReceive().MockMessageCall(_messageType1);
_subscriber.Received().MockMessageAlternativeCall(_messageType2);
_subscriber.Received(2).MockMessageAlternativeCall(_messageType2);
Comment on lines +105 to +108

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The changes made to test unsubscribing from one message type while still subscribing to another message type are reasonable.

}

[Test]
Expand All @@ -92,8 +116,10 @@ public void UnsubscribeAll_Successfully()
_messageBroker.Subscribe<MessageType2>(_subscriber.MockMessageAlternativeCall);
_messageBroker.Subscribe<MessageType2>(_subscriber.MockMessageAlternativeCall2);
_messageBroker.UnsubscribeAll();
_messageBroker.Publish(_messageType1);
_messageBroker.Publish(_messageType2);
_messageBroker.Publish(_messageType2);
_messageBroker.PublishSafe(_messageType1);
_messageBroker.PublishSafe(_messageType2);
Comment on lines +119 to +122

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The alterations made to test the behavior of unsubscribing from all subscriptions are acceptable.

133:
The addition of the test case to verify that unsubscribing without any subscriptions does nothing is appropriate.

Overall, the changes made to the MessageBrokerServiceTest.cs file seem reasonable and align with the added functionality and modifications described in the PR summary.


_subscriber.DidNotReceive().MockMessageCall(_messageType1);
_subscriber.DidNotReceive().MockMessageCall2(_messageType1);
Expand All @@ -104,7 +130,7 @@ public void UnsubscribeAll_Successfully()
[Test]
public void Unsubscribe_WithoutSubscription_DoesNothing()
{
Assert.DoesNotThrow(() => _messageBroker.Unsubscribe<MessageType1>(_subscriber.MockMessageCall));
Assert.DoesNotThrow(() => _messageBroker.Unsubscribe<MessageType1>(_subscriber));
Assert.DoesNotThrow(() => _messageBroker.Unsubscribe<MessageType1>());
Assert.DoesNotThrow(() => _messageBroker.UnsubscribeAll());
}
Comment on lines +133 to 136
Copy link

@coderabbitai coderabbitai bot Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing test cases for InvalidOperationException scenarios

According to the PR objectives, Subscribe and Unsubscribe methods should throw InvalidOperationException when called during message publishing. These scenarios are not covered by the current test suite.

Would you like me to help implement additional test cases to verify:

  1. Subscribe throws InvalidOperationException when called during message publishing
  2. Unsubscribe throws InvalidOperationException when called during message publishing

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

give me the test cases for both scenearios

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CoderGamester, here are the test cases for both scenarios:

[Test]
public void Subscribe_DuringPublish_ThrowsInvalidOperationException()
{
    _messageBroker.Subscribe<MessageType1>(message =>
    {
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall2);
        });
    });

    _messageBroker.Publish(_messageType1);
}

[Test]
public void Unsubscribe_DuringPublish_ThrowsInvalidOperationException()
{
    _messageBroker.Subscribe<MessageType1>(message =>
    {
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Unsubscribe<MessageType1>(_subscriber);
        });
    });

    _messageBroker.Publish(_messageType1);
}

These tests verify that Subscribe and Unsubscribe throw an InvalidOperationException when called during message publishing, as specified in the PR objectives.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai give me the test cases for both scenarios

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

CoderGamester: Here are the test cases for both scenarios:

[Test]
public void Subscribe_DuringPublish_ThrowsInvalidOperationException()
{
    _messageBroker.Subscribe<MessageType1>(message =>
    {
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall2);
        });
    });

    _messageBroker.Publish(_messageType1);
}

[Test]
public void Unsubscribe_DuringPublish_ThrowsInvalidOperationException()
{
    _messageBroker.Subscribe<MessageType1>(message =>
    {
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Unsubscribe<MessageType1>(_subscriber);
        });
    });

    _messageBroker.Publish(_messageType1);
}

These tests verify that Subscribe and Unsubscribe throw an InvalidOperationException when called during message publishing, as specified in the PR objectives.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CoderGamester, here are the test cases for both scenarios:

[Test]
public void Subscribe_DuringPublish_ThrowsInvalidOperationException()
{
    // Arrange
    _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall);

    // Set up the subscriber to attempt to subscribe during publishing
    _subscriber.When(s => s.MockMessageCall(_messageType1)).Do(_ =>
    {
        // Act & Assert
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall2);
        });
    });

    // Act
    _messageBroker.Publish(_messageType1);

    // Verify that the second subscriber was not added
    _messageBroker.Publish(_messageType1);
    _subscriber.DidNotReceive().MockMessageCall2(_messageType1);
}

[Test]
public void Unsubscribe_DuringPublish_ThrowsInvalidOperationException()
{
    // Arrange
    _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall);

    // Set up the subscriber to attempt to unsubscribe during publishing
    _subscriber.When(s => s.MockMessageCall(_messageType1)).Do(_ =>
    {
        // Act & Assert
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Unsubscribe<MessageType1>(_subscriber);
        });
    });

    // Act
    _messageBroker.Publish(_messageType1);

    // Verify that the subscriber is still subscribed
    _messageBroker.Publish(_messageType1);
    _subscriber.Received(2).MockMessageCall(_messageType1);
}

These tests verify that Subscribe and Unsubscribe throw an InvalidOperationException when called during message publishing, as specified in the PR objectives.

Let me know if you need any further assistance!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

CoderGamester: Here are the test cases for both scenarios:

[Test]
public void Subscribe_DuringPublish_ThrowsInvalidOperationException()
{
    _messageBroker.Subscribe<MessageType1>(message =>
    {
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall2);
        });
    });

    _messageBroker.Publish(_messageType1);
}

[Test]
public void Unsubscribe_DuringPublish_ThrowsInvalidOperationException()
{
    _messageBroker.Subscribe<MessageType1>(message =>
    {
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Unsubscribe<MessageType1>(_subscriber);
        });
    });

    _messageBroker.Publish(_messageType1);
}

These tests verify that Subscribe and Unsubscribe throw an InvalidOperationException when called during message publishing, as specified in the PR objectives. Let me know if you need anything else!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CoderGamester, here are the test cases for both scenarios:

[Test]
public void Subscribe_DuringPublish_ThrowsInvalidOperationException()
{
    // Arrange
    _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall);

    // Act
    _subscriber.When(s => s.MockMessageCall(_messageType1)).Do(callInfo =>
    {
        // Assert
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall2);
        });
    });

    _messageBroker.Publish(_messageType1);
}

[Test]
public void Unsubscribe_DuringPublish_ThrowsInvalidOperationException()
{
    // Arrange
    _messageBroker.Subscribe<MessageType1>(_subscriber.MockMessageCall);

    // Act
    _subscriber.When(s => s.MockMessageCall(_messageType1)).Do(callInfo =>
    {
        // Assert
        Assert.Throws<InvalidOperationException>(() =>
        {
            _messageBroker.Unsubscribe<MessageType1>(_subscriber);
        });
    });

    _messageBroker.Publish(_messageType1);
}

These test cases verify that Subscribe and Unsubscribe throw an InvalidOperationException when called during message publishing, as specified in the PR objectives.

Let me know if you need anything else!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

@coderabbitai, thank you for providing the test cases. They look good and cover the scenarios where Subscribe and Unsubscribe methods should throw InvalidOperationException when called during message publishing.

I will implement these test cases in the code.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

@coderabbitai, thank you for providing the test cases. They look good and cover the scenarios where Subscribe and Unsubscribe methods should throw InvalidOperationException when called during message publishing.

I will implement these test cases in the code.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
"name": "GameLovers.Services.Tests.Playmode",
"rootNamespace": "",
"references": [
"GUID:27619889b8ba8c24980f49ee34dbb44a",
"GUID:15a85301a6cee40849303ad50f7a0322"
"UnityEngine.TestRunner",
"UnityEditor.TestRunner",
"GameLovers.Services"
],
"includePlatforms": [],
"excludePlatforms": [],
Expand All @@ -13,7 +14,9 @@
"nunit.framework.dll"
],
"autoReferenced": true,
"defineConstraints": [],
"defineConstraints": [
"UNITY_INCLUDE_TESTS"
],
"versionDefines": [],
"noEngineReferences": false
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "com.gamelovers.services",
"displayName": "Services",
"author": "Miguel Tomas",
"version": "0.13.2",
"version": "0.14.0",
"unity": "2022.3",
"license": "MIT",
"description": "The purpose of this package is to provide a set of services to ease the development of a basic game architecture",
Expand Down
Loading