<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using EPS.Dynamic;
using EPS.Utility;
using FakeItEasy;
using Ploeh.AutoFixture;
using Xunit;

namespace EPS.Concurrency.Tests.Unit
{
	public abstract class IDurableJobQueueTest<T, TQueue, TQueuePoison>
		where T: IDurableJobQueue<TQueue, TQueuePoison>
	{
		protected Fixture fixture = new Fixture();
		protected readonly Func<T> jobStorageFactory;
		protected readonly Func<TQueue, TQueuePoison> poisonConverter;

		public IDurableJobQueueTest(Func<T> jobStorageFactory, Func<TQueue, TQueuePoison> poisonConverter)
		{
			this.jobStorageFactory = () =>
			{
				var instance = jobStorageFactory();
				ClearAllQueues(instance);
				return instance;
			};
			this.poisonConverter = poisonConverter;
		}

		protected void ClearAllQueues(IDurableJobQueue<TQueue, TQueuePoison> storage)
		{
			SlideItemsToPending(storage);
			Assert.Empty(storage.GetQueued());

			foreach (var item in storage.GetPending())
			{
				storage.Complete(item);				
			}
			Assert.Empty(storage.GetPending());				

			foreach (var item in storage.GetPoisoned())
			{
				storage.Delete(item);				
			}
			Assert.Empty(storage.GetPoisoned());
		}

		protected List<TQueue> SlideItemsToPending(IDurableJobQueue<TQueue, TQueuePoison> jobStorage)
		{
			List<TQueue> items = new List<TQueue>();
			while (true)
			{
				TQueue item = jobStorage.TransitionNextQueuedItemToPending();

				if (typeof(TQueue).IsValueType)
				{
					if (default(TQueue).Equals(item))
						break;
				}
				else
				{
					if (object.Equals(null, item))
						break;
				}

				items.Add(item);
			}

			return items;
		}

		[Fact]
		public void Queue_DoesNotThrow_NonNullItem()
		{
			var storage = jobStorageFactory();
			Assert.DoesNotThrow(() => storage.Queue(fixture.CreateAnonymous<TQueue>()));
		}

		[Fact]
		public void Queue_ThrowsOnNullItemForReferenceTypes()
		{
			var storage = jobStorageFactory();

			if (typeof(TQueue).IsValueType)
				return;

			var item = (null as object).Cast<TQueue>();
			Assert.Throws<ArgumentNullException>(() => storage.Queue(item));
		}

		[Fact]
		public void Queue_DoesNotModifyPendingList()
		{
			var storage = jobStorageFactory();
			storage.Queue(fixture.CreateAnonymous<TQueue>());

			Assert.Empty(storage.GetPending());
		}

		[Fact]
		public void Queue_DoesNotModifyPoisonedList()
		{
			var storage = jobStorageFactory();
			storage.Queue(fixture.CreateAnonymous<TQueue>());

			Assert.Empty(storage.GetPoisoned());
		}

		[Fact]
		public void TransitionNextQueuedItemToPending_PreservesOrderingInPendingList()
		{
			var storage = jobStorageFactory();

			var items = fixture.CreateMany<TQueue>(15).ToList();
			foreach (var item in items)
			{
				storage.Queue(item);
				storage.TransitionNextQueuedItemToPending();
			}

			Assert.True(items.SequenceEqual(storage.GetPending(), GenericEqualityComparer<TQueue>.ByAllMembers()));
		}

		[Fact]
		public void TransitionNextQueuedItemToPending_ProperlyRemovesItemFromQueuedList()
		{
			var storage = jobStorageFactory();

			var items = fixture.CreateMany<TQueue>(15).ToList();
			foreach (var item in items)
			{
				storage.Queue(item);
				storage.TransitionNextQueuedItemToPending();
			}

			Assert.Empty(storage.GetQueued());
		}

		[Fact]
		public void TransitionNextQueuedItemToPending_DoesNotModifyPoisonedList()
		{
			var storage = jobStorageFactory();

			var items = fixture.CreateMany<TQueue>(15).ToList();
			foreach (var item in items)
			{
				storage.Queue(item);
				storage.TransitionNextQueuedItemToPending();
			}

			Assert.Empty(storage.GetPoisoned());
		}

		[Fact]
		public void TransitionNextQueuedItemToPending_ReturnsNullOnEmptyQueueList()
		{
			var storage = jobStorageFactory();

			Assert.Null(storage.TransitionNextQueuedItemToPending());
		}<commit_msg>fixed bug when the job type is a value type<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using EPS.Dynamic;
using EPS.Utility;
using FakeItEasy;
using Ploeh.AutoFixture;
using Xunit;

namespace EPS.Concurrency.Tests.Unit
{
	public abstract class IDurableJobQueueTest<T, TQueue, TQueuePoison>
		where T: IDurableJobQueue<TQueue, TQueuePoison>
	{
		protected Fixture fixture = new Fixture();
		protected readonly Func<T> jobStorageFactory;
		protected readonly Func<TQueue, TQueuePoison> poisonConverter;

		public IDurableJobQueueTest(Func<T> jobStorageFactory, Func<TQueue, TQueuePoison> poisonConverter)
		{
			this.jobStorageFactory = () =>
			{
				var instance = jobStorageFactory();
				ClearAllQueues(instance);
				return instance;
			};
			this.poisonConverter = poisonConverter;
		}

		protected void ClearAllQueues(IDurableJobQueue<TQueue, TQueuePoison> storage)
		{
			SlideItemsToPending(storage);
			Assert.Empty(storage.GetQueued());

			foreach (var item in storage.GetPending())
			{
				storage.Complete(item);				
			}
			Assert.Empty(storage.GetPending());				

			foreach (var item in storage.GetPoisoned())
			{
				storage.Delete(item);				
			}
			Assert.Empty(storage.GetPoisoned());
		}

		protected List<TQueue> SlideItemsToPending(IDurableJobQueue<TQueue, TQueuePoison> jobStorage)
		{
			List<TQueue> items = new List<TQueue>();
			while (true)
			{
				TQueue item = jobStorage.TransitionNextQueuedItemToPending();

				if (typeof(TQueue).IsValueType)
				{
					if (default(TQueue).Equals(item))
						break;
				}
				else
				{
					if (object.Equals(null, item))
						break;
				}

				items.Add(item);
			}

			return items;
		}

		[Fact]
		public void Queue_DoesNotThrow_NonNullItem()
		{
			var storage = jobStorageFactory();
			Assert.DoesNotThrow(() => storage.Queue(fixture.CreateAnonymous<TQueue>()));
		}

		[Fact]
		public void Queue_ThrowsOnNullItemForReferenceTypes()
		{
			var storage = jobStorageFactory();

			if (typeof(TQueue).IsValueType)
				return;

			var item = (null as object).Cast<TQueue>();
			Assert.Throws<ArgumentNullException>(() => storage.Queue(item));
		}

		[Fact]
		public void Queue_DoesNotModifyPendingList()
		{
			var storage = jobStorageFactory();
			storage.Queue(fixture.CreateAnonymous<TQueue>());

			Assert.Empty(storage.GetPending());
		}

		[Fact]
		public void Queue_DoesNotModifyPoisonedList()
		{
			var storage = jobStorageFactory();
			storage.Queue(fixture.CreateAnonymous<TQueue>());

			Assert.Empty(storage.GetPoisoned());
		}

		[Fact]
		public void TransitionNextQueuedItemToPending_PreservesOrderingInPendingList()
		{
			var storage = jobStorageFactory();

			var items = fixture.CreateMany<TQueue>(15).ToList();
			foreach (var item in items)
			{
				storage.Queue(item);
				storage.TransitionNextQueuedItemToPending();
			}

			Assert.True(items.SequenceEqual(storage.GetPending(), GenericEqualityComparer<TQueue>.ByAllMembers()));
		}

		[Fact]
		public void TransitionNextQueuedItemToPending_ProperlyRemovesItemFromQueuedList()
		{
			var storage = jobStorageFactory();

			var items = fixture.CreateMany<TQueue>(15).ToList();
			foreach (var item in items)
			{
				storage.Queue(item);
				storage.TransitionNextQueuedItemToPending();
			}

			Assert.Empty(storage.GetQueued());
		}

		[Fact]
		public void TransitionNextQueuedItemToPending_DoesNotModifyPoisonedList()
		{
			var storage = jobStorageFactory();

			var items = fixture.CreateMany<TQueue>(15).ToList();
			foreach (var item in items)
			{
				storage.Queue(item);
				storage.TransitionNextQueuedItemToPending();
			}

			Assert.Empty(storage.GetPoisoned());
		}

		[Fact]
		public void TransitionNextQueuedItemToPending_ReturnsDefaultOnEmptyQueueList()
		{
			var storage = jobStorageFactory();
			Assert.Equal(default(TQueue), storage.TransitionNextQueuedItemToPending());
		}
{'fraction_non_alphanumeric': 0.11423755186721991, 'fraction_numerical': 0.0015560165975103733, 'mean_word_length': 4.282876712328767, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7243123', 'n_tokens_mistral': 2950, 'n_tokens_neox': 2439, 'n_words': 434}