<commit_before>﻿namespace Cheet.Core.Tests
{
    using FakeItEasy;
    using NUnit.Framework;
    using System;
    using System.Linq;
    using System.Linq.Expressions;

    public interface ITestCallbacks<T>
    {
        void Done();
        void Done(string str, T[] seq);
    }

    [TestFixture]
    public class CheetTests
    {
        private Cheet cheet;
        private ITestCallbacks<TestKey> callbacks;

        [SetUp]
        public void SetUp()
        {
            cheet = new Cheet();
            callbacks = A.Fake<ITestCallbacks<TestKey>>();
        }

        [Test]
        public void Sequences_can_be_registered_without_specifying_callbacks()
        {
            // Given
            cheet.Register("a b c");

            // When
            cheet.SendSequence("a b c");

            // Then
            // Nothing bad happens.
        }

        [Test]
        public void Sequences_can_be_registered_with_parameterless_done_callback()
        {
            // Given
            cheet.Register("a b c", () => callbacks.Done());

            // When
            cheet.SendSequence("a b c");

            // Then
            A.CallTo(() => callbacks.Done()).MustHaveHappened();
        }

        [TestCase("a b c")]
        [TestCase("x y a b c")]
        [TestCase("a b c 1 2")]
        [TestCase("x y a b c 1 2")]
        public void Done_callback_invoked_when_sequence_done(string sequence)
        {
            // Given
            cheet.Register("a b c", (str, seq) => callbacks.Done(str, seq));

            // When
            cheet.SendSequence(sequence);

            // Then
            A.CallTo(() => callbacks.Done("a b c", A<TestKey[]>.That.Matches(Keys.For("a b c")))).MustHaveHappened();
        }

        [TestCase("a b")]
        [TestCase("a b d")]
        [TestCase("a a b b c c")]
        public void Done_callback_not_invoked_if_sequence_incomplete_or_missed(string sequence)
        {
            // Given
            cheet.Register("a b c", (str, seq) => callbacks.Done(str, seq));

            // When
            cheet.SendSequence(sequence);

            // Then
            A.CallTo(() => callbacks.Done(null, null)).WithAnyArguments().MustNotHaveHappened();
        }
    }

    public class TestKey
    {
        private readonly string keyName;

        public TestKey(string keyName)
        {
            this.keyName = keyName;
        }

        // ReSharper disable once CSharpWarnings::CS0659
        public override bool Equals(object obj)
        {
            var otherKey = obj as TestKey;
            return otherKey != null && keyName.Equals(otherKey.keyName);
        }
    }

    internal static class Keys
    {
        internal static Expression<Func<TestKey[], bool>> For(string sequence)
        {
            var expectedKeys = sequence.Split(' ').Select(k => new TestKey(k));
            return actualKeys => expectedKeys.SequenceEqual(actualKeys);
        }
    }

    internal class Cheet : Cheet<TestKey>
    {
        internal void SendSequence(string sequence)
        {
            var keyNames = sequence.Split(' ');
            foreach (var keyName in keyNames)
            {
                OnKeyDown(GetKey(keyName));
            }
        }

        protected override TestKey GetKey(string keyName)
        {
            return new TestKey(keyName);
        }
    }
}<commit_msg>Add test for multiple completions.<commit_after>﻿namespace Cheet.Core.Tests
{
    using FakeItEasy;
    using NUnit.Framework;
    using System;
    using System.Linq;
    using System.Linq.Expressions;

    public interface ITestCallbacks<T>
    {
        void Done();
        void Done(string str, T[] seq);
    }

    [TestFixture]
    public class CheetTests
    {
        private Cheet cheet;
        private ITestCallbacks<TestKey> callbacks;

        [SetUp]
        public void SetUp()
        {
            cheet = new Cheet();
            callbacks = A.Fake<ITestCallbacks<TestKey>>();
        }

        [Test]
        public void Sequences_can_be_registered_without_specifying_callbacks()
        {
            // Given
            cheet.Register("a b c");

            // When
            cheet.SendSequence("a b c");

            // Then
            // Nothing bad happens.
        }

        [Test]
        public void Sequences_can_be_registered_with_parameterless_done_callback()
        {
            // Given
            cheet.Register("a b c", () => callbacks.Done());

            // When
            cheet.SendSequence("a b c");

            // Then
            A.CallTo(() => callbacks.Done()).MustHaveHappened();
        }

        [TestCase("a b c")]
        [TestCase("x y a b c")]
        [TestCase("a b c 1 2")]
        [TestCase("x y a b c 1 2")]
        public void Done_callback_invoked_when_sequence_done(string sequence)
        {
            // Given
            cheet.Register("a b c", (str, seq) => callbacks.Done(str, seq));

            // When
            cheet.SendSequence(sequence);

            // Then
            A.CallTo(DoneCallbackFor("a b c")).MustHaveHappened();
        }

        [TestCase("a b")]
        [TestCase("a b d")]
        [TestCase("a a b b c c")]
        public void Done_callback_not_invoked_if_sequence_incomplete_or_missed(string sequence)
        {
            // Given
            cheet.Register("a b c", (str, seq) => callbacks.Done(str, seq));

            // When
            cheet.SendSequence(sequence);

            // Then
            A.CallTo(DoneCallbackFor("a b c")).WithAnyArguments().MustNotHaveHappened();
        }

        [TestCase("a b c a b c", 2)]
        [TestCase("1 2 a b c 3 4 a b c 5 6", 2)]
        [TestCase("a b c a b c a b c", 3)]
        public void Can_complete_sequences_multiple_times(string sequence, int numberOfCompletions)
        {
            // Given
            cheet.Register("a b c", (str, seq) => callbacks.Done(str, seq));

            // When
            cheet.SendSequence(sequence);

            // Then
            A.CallTo(DoneCallbackFor("a b c")).MustHaveHappened(Repeated.Exactly.Times(numberOfCompletions));
        }

        private Expression<Action> DoneCallbackFor(string sequence)
        {
            return () => callbacks.Done(sequence, A<TestKey[]>.That.Matches(Keys.For(sequence)));
        }
    }

    public class TestKey
    {
        private readonly string keyName;

        public TestKey(string keyName)
        {
            this.keyName = keyName;
        }

        // ReSharper disable once CSharpWarnings::CS0659
        public override bool Equals(object obj)
        {
            var otherKey = obj as TestKey;
            return otherKey != null && keyName.Equals(otherKey.keyName);
        }
    }

    internal static class Keys
    {
        internal static Expression<Func<TestKey[], bool>> For(string sequence)
        {
            var expectedKeys = sequence.Split(' ').Select(k => new TestKey(k));
            return actualKeys => expectedKeys.SequenceEqual(actualKeys);
        }
    }

    internal class Cheet : Cheet<TestKey>
    {
        internal void SendSequence(string sequence)
        {
            var keyNames = sequence.Split(' ');
            foreach (var keyName in keyNames)
            {
                OnKeyDown(GetKey(keyName));
            }
        }

        protected override TestKey GetKey(string keyName)
        {
            return new TestKey(keyName);
        }
    }
}
{'fraction_non_alphanumeric': 0.1062946138870863, 'fraction_numerical': 0.003244646333549643, 'mean_word_length': 1.5207719986915276, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4202536', 'n_tokens_mistral': 2257, 'n_tokens_neox': 2077, 'n_words': 493}