<commit_before>using System;
using NUnit.Framework;
using Regalo.Core;
using Regalo.ObjectCompare;

namespace Regalo.Testing
{
    public class ScenarioAssert<TEntity, THandler, TCommand> : IScenarioAssert<TEntity, THandler, TCommand> 
        where TEntity : AggregateRoot, new()
    {
        private readonly TEntity _entity;
        private readonly THandler _handler;
        private readonly TCommand _command;
        private readonly TestingMessageHandlerContext<TEntity> _context;
        private readonly object[] _expected;

        public ScenarioAssert(TEntity entity, THandler handler, TCommand command, TestingMessageHandlerContext<TEntity> context, object[] expected)
        {
            if (context == null) throw new ArgumentNullException("context");

            _entity = entity;
            _handler = handler;
            _command = command;
            _context = context;
            _expected = expected;
        }

        public void Assert()
        {
            /*
             * Plan is to invoke the command on the handler and retrieve the actual
             * events from the repository and eventbus, and compare both with the
             * expected events list passed-in using Regalo.Object compare.
             */

            ((dynamic)_handler).Handle(_command);

            var eventsStoredToEventStore = _context.GetGeneratedEvents();

            var comparer = new ObjectComparer()
                .Ignore<Event, Guid?>(x => x.ParentVersion);

            ObjectComparisonResult result = comparer.AreEqual(_expected, eventsStoredToEventStore);
            if (!result.AreEqual)
            {
                throw new AssertionException("Actual events did not match expected events. " + result.InequalityReason);
            }
        }
    }
}<commit_msg>ScenarioAssert made more reliable with better errors when commands don't match supplied handler.<commit_after>using System;
using System.Reflection;
using NUnit.Framework;
using Regalo.Core;
using Regalo.ObjectCompare;

namespace Regalo.Testing
{
    public class ScenarioAssert<TEntity, THandler, TCommand> : IScenarioAssert<TEntity, THandler, TCommand> 
        where TEntity : AggregateRoot, new()
    {
        private readonly TEntity _entity;
        private readonly THandler _handler;
        private readonly TCommand _command;
        private readonly TestingMessageHandlerContext<TEntity> _context;
        private readonly object[] _expected;

        public ScenarioAssert(TEntity entity, THandler handler, TCommand command, TestingMessageHandlerContext<TEntity> context, object[] expected)
        {
            if (context == null) throw new ArgumentNullException("context");

            _entity = entity;
            _handler = handler;
            _command = command;
            _context = context;
            _expected = expected;
        }

        public void Assert()
        {
            /*
             * Plan is to invoke the command on the handler and retrieve the actual
             * events from the repository and eventbus, and compare both with the
             * expected events list passed-in using Regalo.Object compare.
             */

            InvokeHandler();

            var eventsStoredToEventStore = _context.GetGeneratedEvents();

            var comparer = new ObjectComparer()
                .Ignore<Event, Guid?>(x => x.ParentVersion);

            ObjectComparisonResult result = comparer.AreEqual(_expected, eventsStoredToEventStore);
            if (!result.AreEqual)
            {
                throw new AssertionException("Actual events did not match expected events. " + result.InequalityReason);
            }
        }

        private void InvokeHandler()
        {
            Type handlerType = _handler.GetType();
            Type commandType = _command.GetType();

            var handleMethod = handlerType.GetMethod("Handle", BindingFlags.Public | BindingFlags.Instance, null, new[] { commandType }, null);

            if (handleMethod == null)
            {
                throw new InvalidOperationException(
                    string.Format("Handler is of type {0} and has no public Handle({1}) method. "
                                  + "Since often there may be multiple classes representing a message with the same name, be sure to check the "
                                  + "handler handles the message in the assembly and namespace you are expecting.",
                                  handlerType,
                                  commandType));
            }

            handleMethod.Invoke(_handler, new object[] { _command });
        }
    }
}
{'fraction_non_alphanumeric': 0.07127476313522825, 'fraction_numerical': 0.0004306632213608958, 'mean_word_length': 2.125841184387618, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4205652', 'n_tokens_mistral': 1099, 'n_tokens_neox': 1065, 'n_words': 346}