using System; using System.Collections; using System.Collections.Generic; using System.Linq; using SabreTools.IO.Extensions; using Xunit; namespace SabreTools.IO.Test.Extensions { public class EnumerableExtensionsTests { [Fact] public void SafeEnumerateEmptyTest() { var source = Enumerable.Empty(); var safe = source.SafeEnumerate(); var list = safe.ToList(); Assert.Empty(list); } [Fact] public void SafeEnumerateNoErrorTest() { var source = new List { "a", "ab", "abc" }; var safe = source.SafeEnumerate(); var list = safe.ToList(); Assert.Equal(3, list.Count); } [Fact] public void SafeEnumerateErrorMidTest() { var source = new List { "a", "ab", "abc" }; var wrapper = new ErrorEnumerable(source); var safe = wrapper.SafeEnumerate(); var list = safe.ToList(); Assert.Equal(2, list.Count); } [Fact] public void SafeEnumerateErrorLastTest() { var source = new List { "a", "ab", "abc", "abcd" }; var wrapper = new ErrorEnumerable(source); var safe = wrapper.SafeEnumerate(); var list = safe.ToList(); Assert.Equal(2, list.Count); } /// /// Fake enumerable that uses /// private class ErrorEnumerable : IEnumerable { /// /// Enumerator to use during enumeration /// private readonly ErrorEnumerator _enumerator; public ErrorEnumerable(IEnumerable source) { _enumerator = new ErrorEnumerator(source); } /// public IEnumerator GetEnumerator() => _enumerator; /// IEnumerator IEnumerable.GetEnumerator() => _enumerator; } /// /// Fake enumerator that throws an exception every other item while moving to the next item /// private class ErrorEnumerator : IEnumerator { /// public string Current { get { if (_index == -1) throw new InvalidOperationException(); return _enumerator.Current; } } /// object IEnumerator.Current => Current; /// /// Enumerator from the source enumerable /// private readonly IEnumerator _enumerator; /// /// Enumerators start before the data /// private int _index = -1; public ErrorEnumerator(IEnumerable source) { _enumerator = source.GetEnumerator(); } /// public void Dispose() { } /// public bool MoveNext() { // Move to the next item, if possible bool moved = _enumerator.MoveNext(); if (!moved) return false; // Get the next real item _index++; // Every other move, throw an exception if (_index % 2 == 1) throw new Exception("Access issue for this item in the enumerable"); return true; } /// public void Reset() { _enumerator.Reset(); _index = -1; } } } }