Просмотр исходного кода

Ix: Split unit tests into separate classes

akarnokd 7 лет назад
Родитель
Сommit
364099d4d4
45 измененных файлов с 2380 добавлено и 1888 удалено
  1. 88 0
      Ix.NET/Source/System.Interactive.Tests/BufferTest.cs
  2. 89 0
      Ix.NET/Source/System.Interactive.Tests/CaseTest.cs
  3. 3 184
      Ix.NET/Source/System.Interactive.Tests/CatchTest.cs
  4. 3 15
      Ix.NET/Source/System.Interactive.Tests/ConcatTest.cs
  5. 119 0
      Ix.NET/Source/System.Interactive.Tests/CreateTest.cs
  6. 53 0
      Ix.NET/Source/System.Interactive.Tests/DeferTest.cs
  7. 52 0
      Ix.NET/Source/System.Interactive.Tests/DistinctTest.cs
  8. 42 0
      Ix.NET/Source/System.Interactive.Tests/DistinctUntilChangedTest.cs
  9. 103 0
      Ix.NET/Source/System.Interactive.Tests/DoTest.cs
  10. 38 0
      Ix.NET/Source/System.Interactive.Tests/DoWhileTest.cs
  11. 43 0
      Ix.NET/Source/System.Interactive.Tests/ExpandTest.cs
  12. 86 0
      Ix.NET/Source/System.Interactive.Tests/FinallyTest.cs
  13. 40 0
      Ix.NET/Source/System.Interactive.Tests/ForEachTest.cs
  14. 27 0
      Ix.NET/Source/System.Interactive.Tests/ForTest.cs
  15. 30 0
      Ix.NET/Source/System.Interactive.Tests/GenerateTest.cs
  16. 30 0
      Ix.NET/Source/System.Interactive.Tests/HideTest.cs
  17. 49 0
      Ix.NET/Source/System.Interactive.Tests/IfTest.cs
  18. 29 0
      Ix.NET/Source/System.Interactive.Tests/IgnoreElementsTest.cs
  19. 33 0
      Ix.NET/Source/System.Interactive.Tests/IsEmptyTest.cs
  20. 36 0
      Ix.NET/Source/System.Interactive.Tests/MaxByTest.cs
  21. 36 0
      Ix.NET/Source/System.Interactive.Tests/MaxTest.cs
  22. 273 0
      Ix.NET/Source/System.Interactive.Tests/MemoizeTest.cs
  23. 38 0
      Ix.NET/Source/System.Interactive.Tests/MinByTest.cs
  24. 36 0
      Ix.NET/Source/System.Interactive.Tests/MinTest.cs
  25. 86 0
      Ix.NET/Source/System.Interactive.Tests/OnErrorResumeNextTest.cs
  26. 284 0
      Ix.NET/Source/System.Interactive.Tests/PublishTest.cs
  27. 1 1
      Ix.NET/Source/System.Interactive.Tests/QueryableParityTest.cs
  28. 55 0
      Ix.NET/Source/System.Interactive.Tests/RepeatTest.cs
  29. 55 0
      Ix.NET/Source/System.Interactive.Tests/RetryTest.cs
  30. 21 0
      Ix.NET/Source/System.Interactive.Tests/ReturnTest.cs
  31. 36 0
      Ix.NET/Source/System.Interactive.Tests/ScanTest.cs
  32. 27 0
      Ix.NET/Source/System.Interactive.Tests/SelectManyTest.cs
  33. 125 0
      Ix.NET/Source/System.Interactive.Tests/ShareTest.cs
  34. 58 0
      Ix.NET/Source/System.Interactive.Tests/SkipLastTest.cs
  35. 38 0
      Ix.NET/Source/System.Interactive.Tests/StartWithTest.cs
  36. 73 0
      Ix.NET/Source/System.Interactive.Tests/TakeLastTest.cs
  37. 0 119
      Ix.NET/Source/System.Interactive.Tests/Tests.Aggregates.cs
  38. 0 628
      Ix.NET/Source/System.Interactive.Tests/Tests.Buffering.cs
  39. 0 292
      Ix.NET/Source/System.Interactive.Tests/Tests.Creation.cs
  40. 0 181
      Ix.NET/Source/System.Interactive.Tests/Tests.Imperative.cs
  41. 0 467
      Ix.NET/Source/System.Interactive.Tests/Tests.Single.cs
  42. 1 1
      Ix.NET/Source/System.Interactive.Tests/Tests.cs
  43. 31 0
      Ix.NET/Source/System.Interactive.Tests/ThrowTest.cs
  44. 75 0
      Ix.NET/Source/System.Interactive.Tests/UsingTest.cs
  45. 38 0
      Ix.NET/Source/System.Interactive.Tests/WhileTest.cs

+ 88 - 0
Ix.NET/Source/System.Interactive.Tests/BufferTest.cs

@@ -0,0 +1,88 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class BufferTest : Tests
+    {
+        [Fact]
+        public void Buffer_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Buffer<int>(null, 5));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Buffer<int>(null, 5, 3));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Buffer<int>(new[] { 1 }, 0));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Buffer<int>(new[] { 1 }, 5, 0));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Buffer<int>(new[] { 1 }, 0, 3));
+        }
+
+        [Fact]
+        public void Buffer1()
+        {
+            var rng = Enumerable.Range(0, 10);
+
+            var res = rng.Buffer(3).ToList();
+            Assert.Equal(4, res.Count);
+
+            Assert.True(res[0].SequenceEqual(new[] { 0, 1, 2 }));
+            Assert.True(res[1].SequenceEqual(new[] { 3, 4, 5 }));
+            Assert.True(res[2].SequenceEqual(new[] { 6, 7, 8 }));
+            Assert.True(res[3].SequenceEqual(new[] { 9 }));
+        }
+
+        [Fact]
+        public void Buffer2()
+        {
+            var rng = Enumerable.Range(0, 10);
+
+            var res = rng.Buffer(5).ToList();
+            Assert.Equal(2, res.Count);
+
+            Assert.True(res[0].SequenceEqual(new[] { 0, 1, 2, 3, 4 }));
+            Assert.True(res[1].SequenceEqual(new[] { 5, 6, 7, 8, 9 }));
+        }
+
+        [Fact]
+        public void Buffer3()
+        {
+            var rng = Enumerable.Empty<int>();
+
+            var res = rng.Buffer(5).ToList();
+            Assert.Empty(res);
+        }
+
+        [Fact]
+        public void Buffer4()
+        {
+            var rng = Enumerable.Range(0, 10);
+
+            var res = rng.Buffer(3, 2).ToList();
+            Assert.Equal(5, res.Count);
+
+            Assert.True(res[0].SequenceEqual(new[] { 0, 1, 2 }));
+            Assert.True(res[1].SequenceEqual(new[] { 2, 3, 4 }));
+            Assert.True(res[2].SequenceEqual(new[] { 4, 5, 6 }));
+            Assert.True(res[3].SequenceEqual(new[] { 6, 7, 8 }));
+            Assert.True(res[4].SequenceEqual(new[] { 8, 9 }));
+        }
+
+        [Fact]
+        public void Buffer5()
+        {
+            var rng = Enumerable.Range(0, 10);
+
+            var res = rng.Buffer(3, 4).ToList();
+            Assert.Equal(3, res.Count);
+
+            Assert.True(res[0].SequenceEqual(new[] { 0, 1, 2 }));
+            Assert.True(res[1].SequenceEqual(new[] { 4, 5, 6 }));
+            Assert.True(res[2].SequenceEqual(new[] { 8, 9 }));
+        }
+    }
+}

+ 89 - 0
Ix.NET/Source/System.Interactive.Tests/CaseTest.cs

@@ -0,0 +1,89 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class CaseTest : Tests
+    {
+        [Fact]
+        public void Case_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(null, new Dictionary<int, IEnumerable<int>>()));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(() => 1, null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(null, new Dictionary<int, IEnumerable<int>>(), new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(() => 1, null, new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(() => 1, new Dictionary<int, IEnumerable<int>>(), null));
+        }
+
+        [Fact]
+        public void Case1()
+        {
+            var x = 1;
+            var d = 'd';
+            var res = EnumerableEx.Case<int, char>(() => x, new Dictionary<int, IEnumerable<char>>
+            {
+                { 0, new[] { 'a' } },
+                { 1, new[] { 'b' } },
+                { 2, new[] { 'c' } },
+                { 3, EnumerableEx.Defer(() => new[] { d }) },
+            });
+
+            Assert.Equal('b', res.Single());
+            Assert.Equal('b', res.Single());
+
+            x = 0;
+            Assert.Equal('a', res.Single());
+
+            x = 2;
+            Assert.Equal('c', res.Single());
+
+            x = 3;
+            Assert.Equal('d', res.Single());
+
+            d = 'e';
+            Assert.Equal('e', res.Single());
+
+            x = 4;
+            Assert.True(res.IsEmpty());
+        }
+
+        [Fact]
+        public void Case2()
+        {
+            var x = 1;
+            var d = 'd';
+            var res = EnumerableEx.Case<int, char>(() => x, new Dictionary<int, IEnumerable<char>>
+            {
+                { 0, new[] { 'a' } },
+                { 1, new[] { 'b' } },
+                { 2, new[] { 'c' } },
+                { 3, EnumerableEx.Defer(() => new[] { d }) },
+            }, new[] { 'z' });
+
+            Assert.Equal('b', res.Single());
+            Assert.Equal('b', res.Single());
+
+            x = 0;
+            Assert.Equal('a', res.Single());
+
+            x = 2;
+            Assert.Equal('c', res.Single());
+
+            x = 3;
+            Assert.Equal('d', res.Single());
+
+            d = 'e';
+            Assert.Equal('e', res.Single());
+
+            x = 4;
+            Assert.Equal('z', res.Single());
+        }
+    }
+}

+ 3 - 184
Ix.NET/Source/System.Interactive.Tests/Tests.Exceptions.cs → Ix.NET/Source/System.Interactive.Tests/CatchTest.cs

@@ -1,14 +1,16 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
+
 using System;
 using System.Collections.Generic;
+using System.Text;
 using System.Linq;
 using Xunit;
 
 namespace Tests
 {
-    public partial class Tests
+    public class CatchTest : Tests
     {
         [Fact]
         public void Catch_Arguments()
@@ -204,188 +206,5 @@ namespace Tests
             HasNext(e, 3);
             AssertThrows<MyException>(() => e.MoveNext(), ex => ex == e3);
         }
-
-        [Fact]
-        public void Finally_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Finally<int>(null, () => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Finally<int>(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void Finally1()
-        {
-            var done = false;
-
-            var xs = Enumerable.Range(0, 2).Finally(() => done = true);
-            Assert.False(done);
-
-            var e = xs.GetEnumerator();
-            Assert.False(done);
-
-            HasNext(e, 0);
-            Assert.False(done);
-
-            HasNext(e, 1);
-            Assert.False(done);
-
-            NoNext(e);
-            Assert.True(done);
-        }
-
-        [Fact]
-        public void Finally2()
-        {
-            var done = false;
-
-            var xs = Enumerable.Range(0, 2).Finally(() => done = true);
-            Assert.False(done);
-
-            var e = xs.GetEnumerator();
-            Assert.False(done);
-
-            HasNext(e, 0);
-            Assert.False(done);
-
-            e.Dispose();
-            Assert.True(done);
-        }
-
-        [Fact]
-        public void Finally3()
-        {
-            var done = false;
-
-            var ex = new MyException();
-            var xs = EnumerableEx.Throw<int>(ex).Finally(() => done = true);
-            Assert.False(done);
-
-            var e = xs.GetEnumerator();
-            Assert.False(done);
-
-            try
-            {
-                HasNext(e, 0);
-                Assert.True(false);
-            }
-            catch (MyException ex_)
-            {
-                Assert.Same(ex, ex_);
-            }
-
-            Assert.True(done);
-        }
-
-        [Fact]
-        public void OnErrorResumeNext_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.OnErrorResumeNext<int>(null, new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.OnErrorResumeNext<int>(new[] { 1 }, null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.OnErrorResumeNext<int>(default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.OnErrorResumeNext<int>(default(IEnumerable<IEnumerable<int>>)));
-        }
-
-        [Fact]
-        public void OnErrorResumeNext1()
-        {
-            var xs = new[] { 1, 2 };
-            var ys = new[] { 3, 4 };
-
-            var res = xs.OnErrorResumeNext(ys);
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4 }));
-        }
-
-        [Fact]
-        public void OnErrorResumeNext2()
-        {
-            var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
-            var ys = new[] { 3, 4 };
-
-            var res = xs.OnErrorResumeNext(ys);
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4 }));
-        }
-
-        [Fact]
-        public void OnErrorResumeNext3()
-        {
-            var xs = new[] { 1, 2 };
-            var ys = new[] { 3, 4 };
-            var zs = new[] { 5, 6 };
-
-            var res = EnumerableEx.OnErrorResumeNext(xs, ys, zs);
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4, 5, 6 }));
-        }
-
-        [Fact]
-        public void OnErrorResumeNext4()
-        {
-            var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
-            var ys = new[] { 3, 4 };
-            var zs = new[] { 5, 6 };
-
-            var res = EnumerableEx.OnErrorResumeNext(xs, ys, zs);
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4, 5, 6 }));
-        }
-
-        [Fact]
-        public void OnErrorResumeNext5()
-        {
-            var xs = new[] { 1, 2 };
-            var ys = new[] { 3, 4 };
-
-            var res = new[] { xs, ys }.OnErrorResumeNext();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4 }));
-        }
-
-        [Fact]
-        public void OnErrorResumeNext6()
-        {
-            var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
-            var ys = new[] { 3, 4 };
-
-            var res = new[] { xs, ys }.OnErrorResumeNext();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4 }));
-        }
-
-        [Fact]
-        public void Retry_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Retry<int>(null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Retry<int>(null, 5));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Retry<int>(new[] { 1 }, -1));
-        }
-
-        [Fact]
-        public void Retry1()
-        {
-            var xs = Enumerable.Range(0, 10);
-
-            var res = xs.Retry();
-            Assert.True(Enumerable.SequenceEqual(res, xs));
-        }
-
-        [Fact]
-        public void Retry2()
-        {
-            var xs = Enumerable.Range(0, 10);
-
-            var res = xs.Retry(2);
-            Assert.True(Enumerable.SequenceEqual(res, xs));
-        }
-
-        [Fact]
-        public void Retry3()
-        {
-            var ex = new MyException();
-            var xs = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex));
-
-            var res = xs.Retry(2);
-            var e = res.GetEnumerator();
-            HasNext(e, 0);
-            HasNext(e, 1);
-            HasNext(e, 0);
-            HasNext(e, 1);
-            AssertThrows<MyException>(() => e.MoveNext(), ex_ => ex == ex_);
-        }
     }
 }

+ 3 - 15
Ix.NET/Source/System.Interactive.Tests/Tests.Multiple.cs → Ix.NET/Source/System.Interactive.Tests/ConcatTest.cs

@@ -1,14 +1,16 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the Apache 2.0 License.
 // See the LICENSE file in the project root for more information. 
+
 using System;
 using System.Collections.Generic;
+using System.Text;
 using System.Linq;
 using Xunit;
 
 namespace Tests
 {
-    public partial class Tests
+    public class ConcatTest : Tests
     {
         [Fact]
         public void Concat_Arguments()
@@ -57,19 +59,5 @@ namespace Tests
 
             Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4, 5 }));
         }
-
-        [Fact]
-        public void SelectMany_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.SelectMany<int, int>(null, new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.SelectMany<int, int>(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void SelectMany()
-        {
-            var res = new[] { 1, 2 }.SelectMany(new[] { 'a', 'b', 'c' }).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 'a', 'b', 'c', 'a', 'b', 'c' }));
-        }
     }
 }

+ 119 - 0
Ix.NET/Source/System.Interactive.Tests/CreateTest.cs

@@ -0,0 +1,119 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+using System.Collections;
+using System.Threading;
+
+namespace Tests
+{
+    public class CreateTest : Tests
+    {
+        [Fact]
+        public void Create_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Create<int>(default));
+        }
+
+        [Fact]
+        public void Create1()
+        {
+            var hot = false;
+            var res = EnumerableEx.Create<int>(() =>
+            {
+                hot = true;
+                return MyEnumerator();
+            });
+
+            Assert.False(hot);
+
+            var e = res.GetEnumerator();
+            Assert.True(hot);
+
+            HasNext(e, 1);
+            HasNext(e, 2);
+            NoNext(e);
+
+            hot = false;
+            var f = ((IEnumerable)res).GetEnumerator();
+            Assert.True(hot);
+        }
+
+        [Fact]
+        public void CreateYield()
+        {
+            SynchronizationContext.SetSynchronizationContext(null);
+
+            var xs = EnumerableEx.Create<int>(async yield =>
+            {
+                var i = 0;
+                while (i < 10)
+                {
+                    await yield.Return(i++);
+                }
+            });
+
+            var j = 0;
+            foreach (var elem in xs)
+            {
+                Assert.Equal(j, elem);
+                j++;
+            }
+
+            Assert.Equal(10, j);
+        }
+
+        [Fact]
+        public void CreateYieldBreak()
+        {
+            SynchronizationContext.SetSynchronizationContext(null);
+
+            var xs = EnumerableEx.Create<int>(async yield =>
+            {
+                var i = 0;
+                while (true)
+                {
+                    if (i == 10)
+                    {
+                        await yield.Break();
+                        return;
+                    }
+
+                    await yield.Return(i++);
+                }
+            });
+
+            var j = 0;
+            foreach (var elem in xs)
+            {
+                Assert.Equal(elem, j);
+                j++;
+            }
+
+            Assert.Equal(10, j);
+        }
+
+        [Fact]
+        public void YielderNoReset()
+        {
+            var xs = EnumerableEx.Create<int>(async yield =>
+            {
+                await yield.Break();
+            });
+
+            AssertThrows<NotSupportedException>(() => xs.GetEnumerator().Reset());
+        }
+
+
+        private static IEnumerator<int> MyEnumerator()
+        {
+            yield return 1;
+            yield return 2;
+        }
+    }
+}

+ 53 - 0
Ix.NET/Source/System.Interactive.Tests/DeferTest.cs

@@ -0,0 +1,53 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class DeferTest : Tests
+    {
+        [Fact]
+        public void Defer_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Defer<int>(null));
+        }
+
+        [Fact]
+        public void Defer1()
+        {
+            var i = 0;
+            var n = 5;
+            var xs = EnumerableEx.Defer(() =>
+            {
+                i++;
+                return Enumerable.Range(0, n);
+            });
+
+            Assert.Equal(0, i);
+
+            Assert.True(Enumerable.SequenceEqual(xs, Enumerable.Range(0, n)));
+            Assert.Equal(1, i);
+
+            n = 3;
+            Assert.True(Enumerable.SequenceEqual(xs, Enumerable.Range(0, n)));
+            Assert.Equal(2, i);
+        }
+
+        [Fact]
+        public void Defer2()
+        {
+            var xs = EnumerableEx.Defer<int>(() =>
+            {
+                throw new MyException();
+            });
+
+            AssertThrows<MyException>(() => xs.GetEnumerator().MoveNext());
+        }
+    }
+}

+ 52 - 0
Ix.NET/Source/System.Interactive.Tests/DistinctTest.cs

@@ -0,0 +1,52 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class DistinctTest : Tests
+    {
+        [Fact]
+        public void Distinct_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(null, _ => _));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(new[] { 1 }, null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(null, _ => _, EqualityComparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(new[] { 1 }, null, EqualityComparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(new[] { 1 }, _ => _, null));
+        }
+
+        [Fact]
+        public void Distinct1()
+        {
+            var res = Enumerable.Range(0, 10).Distinct(x => x % 5).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, Enumerable.Range(0, 5)));
+        }
+
+        [Fact]
+        public void Distinct2()
+        {
+            var res = Enumerable.Range(0, 10).Distinct(x => x % 5, new MyEqualityComparer()).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 0, 1 }));
+        }
+
+        private class MyEqualityComparer : IEqualityComparer<int>
+        {
+            public bool Equals(int x, int y)
+            {
+                return x % 2 == y % 2;
+            }
+
+            public int GetHashCode(int obj)
+            {
+                return EqualityComparer<int>.Default.GetHashCode(obj % 2);
+            }
+        }
+    }
+}

+ 42 - 0
Ix.NET/Source/System.Interactive.Tests/DistinctUntilChangedTest.cs

@@ -0,0 +1,42 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class DistinctUntilChangedTest : Tests
+    {
+        [Fact]
+        public void DistinctUntilChanged_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int>(null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int>(null, EqualityComparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int>(new[] { 1 }, null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(null, _ => _));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(new[] { 1 }, null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(null, _ => _, EqualityComparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(new[] { 1 }, null, EqualityComparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(new[] { 1 }, _ => _, null));
+        }
+
+        [Fact]
+        public void DistinctUntilChanged1()
+        {
+            var res = new[] { 1, 2, 2, 3, 3, 3, 2, 2, 1 }.DistinctUntilChanged().ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 2, 1 }));
+        }
+
+        [Fact]
+        public void DistinctUntilChanged2()
+        {
+            var res = new[] { 1, 1, 2, 3, 4, 5, 5, 6, 7 }.DistinctUntilChanged(x => x / 2).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 4, 6 }));
+        }
+    }
+}

+ 103 - 0
Ix.NET/Source/System.Interactive.Tests/DoTest.cs

@@ -0,0 +1,103 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class DoTest : Tests
+    {
+        [Fact]
+        public void Do_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, _ => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, _ => { }, () => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, _ => { }, _ => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, _ => { }, _ => { }, () => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default(Action<int>)));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default, () => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, _ => { }, default(Action)));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default, _ => { }, () => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, _ => { }, default, () => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, _ => { }, _ => { }, default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default, _ => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, _ => { }, default(Action<Exception>)));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, new MyObserver()));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default(IObserver<int>)));
+        }
+
+        [Fact]
+        public void Do1()
+        {
+            var n = 0;
+            Enumerable.Range(0, 10).Do(x => n += x).ForEach(_ => { });
+            Assert.Equal(45, n);
+        }
+
+        [Fact]
+        public void Do2()
+        {
+            var n = 0;
+            Enumerable.Range(0, 10).Do(x => n += x, () => n *= 2).ForEach(_ => { });
+            Assert.Equal(90, n);
+        }
+
+        [Fact]
+        public void Do3()
+        {
+            var ex = new MyException();
+            var ok = false;
+            AssertThrows<MyException>(() =>
+                EnumerableEx.Throw<int>(ex).Do(x => { Assert.True(false); }, e => { Assert.Equal(ex, e); ok = true; }).ForEach(_ => { })
+            );
+            Assert.True(ok);
+        }
+
+        [Fact]
+        public void Do4()
+        {
+            var obs = new MyObserver();
+            Enumerable.Range(0, 10).Do(obs).ForEach(_ => { });
+
+            Assert.True(obs.Done);
+            Assert.Equal(45, obs.Sum);
+        }
+
+        private class MyObserver : IObserver<int>
+        {
+            public int Sum;
+            public bool Done;
+
+            public void OnCompleted()
+            {
+                Done = true;
+            }
+
+            public void OnError(Exception error)
+            {
+                throw new NotImplementedException();
+            }
+
+            public void OnNext(int value)
+            {
+                Sum += value;
+            }
+        }
+
+        [Fact]
+        public void Do5()
+        {
+            var sum = 0;
+            var done = false;
+            Enumerable.Range(0, 10).Do(x => sum += x, ex => { throw ex; }, () => done = true).ForEach(_ => { });
+
+            Assert.True(done);
+            Assert.Equal(45, sum);
+        }
+    }
+}

+ 38 - 0
Ix.NET/Source/System.Interactive.Tests/DoWhileTest.cs

@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class DoWhileTest : Tests
+    {
+        [Fact]
+        public void DoWhile_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DoWhile<int>(new[] { 1 }, null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.DoWhile<int>(null, () => true));
+        }
+
+        [Fact]
+        public void DoWhile1()
+        {
+            var x = 5;
+            var res = EnumerableEx.DoWhile(EnumerableEx.Defer(() => new[] { x }).Do(_ => x--), () => x > 0).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 5, 4, 3, 2, 1 }));
+        }
+
+        [Fact]
+        public void DoWhile2()
+        {
+            var x = 0;
+            var res = EnumerableEx.DoWhile(EnumerableEx.Defer(() => new[] { x }).Do(_ => x--), () => x > 0).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 0 }));
+        }
+    }
+}

+ 43 - 0
Ix.NET/Source/System.Interactive.Tests/ExpandTest.cs

@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class ExpandTest : Tests
+    {
+        [Fact]
+        public void Expand_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Expand<int>(null, _ => new[] { _ }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Expand<int>(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void Expand1()
+        {
+            var res = new[] { 0 }.Expand(x => new[] { x + 1 }).Take(10).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, Enumerable.Range(0, 10)));
+        }
+
+        [Fact]
+        public void Expand2()
+        {
+            var res = new[] { 3 }.Expand(x => Enumerable.Range(0, x)).ToList();
+            var exp = new[] {
+                3,
+                0, 1, 2,
+                0,
+                0, 1,
+                0
+            };
+            Assert.True(Enumerable.SequenceEqual(res, exp));
+        }
+    }
+}

+ 86 - 0
Ix.NET/Source/System.Interactive.Tests/FinallyTest.cs

@@ -0,0 +1,86 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class FinallyTest : Tests
+    {
+        [Fact]
+        public void Finally_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Finally<int>(null, () => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Finally<int>(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void Finally1()
+        {
+            var done = false;
+
+            var xs = Enumerable.Range(0, 2).Finally(() => done = true);
+            Assert.False(done);
+
+            var e = xs.GetEnumerator();
+            Assert.False(done);
+
+            HasNext(e, 0);
+            Assert.False(done);
+
+            HasNext(e, 1);
+            Assert.False(done);
+
+            NoNext(e);
+            Assert.True(done);
+        }
+
+        [Fact]
+        public void Finally2()
+        {
+            var done = false;
+
+            var xs = Enumerable.Range(0, 2).Finally(() => done = true);
+            Assert.False(done);
+
+            var e = xs.GetEnumerator();
+            Assert.False(done);
+
+            HasNext(e, 0);
+            Assert.False(done);
+
+            e.Dispose();
+            Assert.True(done);
+        }
+
+        [Fact]
+        public void Finally3()
+        {
+            var done = false;
+
+            var ex = new MyException();
+            var xs = EnumerableEx.Throw<int>(ex).Finally(() => done = true);
+            Assert.False(done);
+
+            var e = xs.GetEnumerator();
+            Assert.False(done);
+
+            try
+            {
+                HasNext(e, 0);
+                Assert.True(false);
+            }
+            catch (MyException ex_)
+            {
+                Assert.Same(ex, ex_);
+            }
+
+            Assert.True(done);
+        }
+    }
+}

+ 40 - 0
Ix.NET/Source/System.Interactive.Tests/ForEachTest.cs

@@ -0,0 +1,40 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class ForEachTest : Tests
+    {
+        [Fact]
+        public void ForEach_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.ForEach<int>(null, x => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.ForEach<int>(new[] { 1 }, default(Action<int>)));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.ForEach<int>(null, (x, i) => { }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.ForEach<int>(new[] { 1 }, default(Action<int, int>)));
+        }
+
+        [Fact]
+        public void ForEach1()
+        {
+            var n = 0;
+            Enumerable.Range(5, 3).ForEach(x => n += x);
+            Assert.Equal(5 + 6 + 7, n);
+        }
+
+        [Fact]
+        public void ForEach2()
+        {
+            var n = 0;
+            Enumerable.Range(5, 3).ForEach((x, i) => n += x * i);
+            Assert.Equal(5 * 0 + 6 * 1 + 7 * 2, n);
+        }
+    }
+}

+ 27 - 0
Ix.NET/Source/System.Interactive.Tests/ForTest.cs

@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class ForTest : Tests
+    {
+        [Fact]
+        public void For_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.For<int, int>(null, x => new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.For<int, int>(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void For()
+        {
+            var res = EnumerableEx.For(new[] { 1, 2, 3 }, x => Enumerable.Range(0, x)).ToList();
+            Assert.True(res.SequenceEqual(new[] { 0, 0, 1, 0, 1, 2 }));
+        }
+    }
+}

+ 30 - 0
Ix.NET/Source/System.Interactive.Tests/GenerateTest.cs

@@ -0,0 +1,30 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class GenerateTest : Tests
+    {
+        [Fact]
+        public void Generate_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Generate<int, int>(0, null, _ => _, _ => _));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Generate<int, int>(0, _ => true, null, _ => _));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Generate<int, int>(0, _ => true, _ => _, null));
+        }
+
+        [Fact]
+        public void Generate()
+        {
+            var res = EnumerableEx.Generate(0, x => x < 5, x => x + 1, x => x * x).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 0, 1, 4, 9, 16 }));
+        }
+    }
+}

+ 30 - 0
Ix.NET/Source/System.Interactive.Tests/HideTest.cs

@@ -0,0 +1,30 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class HideTest : Tests
+    {
+        [Fact]
+        public void Hide_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Hide<int>(null));
+        }
+
+        [Fact]
+        public void Hide()
+        {
+            var xs = new List<int> { 1, 2, 3 };
+            var ys = xs.Hide();
+            Assert.False(ys is List<int>);
+            Assert.True(xs.SequenceEqual(ys));
+        }
+    }
+}

+ 49 - 0
Ix.NET/Source/System.Interactive.Tests/IfTest.cs

@@ -0,0 +1,49 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class IfTest : Tests
+    {
+        [Fact]
+        public void If_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(null, new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(() => true, null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(null, new[] { 1 }, new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(() => true, null, new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(() => true, new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void If1()
+        {
+            var x = 5;
+            var res = EnumerableEx.If(() => x > 0, new[] { +1 }, new[] { -1 });
+
+            Assert.Equal(+1, res.Single());
+
+            x = -x;
+            Assert.Equal(-1, res.Single());
+        }
+
+        [Fact]
+        public void If2()
+        {
+            var x = 5;
+            var res = EnumerableEx.If(() => x > 0, new[] { +1 });
+
+            Assert.Equal(+1, res.Single());
+
+            x = -x;
+            Assert.True(res.IsEmpty());
+        }
+    }
+}

+ 29 - 0
Ix.NET/Source/System.Interactive.Tests/IgnoreElementsTest.cs

@@ -0,0 +1,29 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class IgnoreElementsTest : Tests
+    {
+        [Fact]
+        public void IgnoreElements_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.IgnoreElements<int>(null));
+        }
+
+        [Fact]
+        public void IgnoreElements()
+        {
+            var n = 0;
+            Enumerable.Range(0, 10).Do(_ => n++).IgnoreElements().Take(5).ForEach(_ => { });
+            Assert.Equal(10, n);
+        }
+    }
+}

+ 33 - 0
Ix.NET/Source/System.Interactive.Tests/IsEmptyTest.cs

@@ -0,0 +1,33 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class IsEmptyTest : Tests
+    {
+        [Fact]
+        public void IsEmtpy_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.IsEmpty<int>(null));
+        }
+
+        [Fact]
+        public void IsEmpty_Empty()
+        {
+            Assert.True(Enumerable.Empty<int>().IsEmpty());
+        }
+
+        [Fact]
+        public void IsEmpty_NonEmpty()
+        {
+            Assert.False(new[] { 1 }.IsEmpty());
+        }
+    }
+}

+ 36 - 0
Ix.NET/Source/System.Interactive.Tests/MaxByTest.cs

@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class MaxByTest : Tests
+    {
+        [Fact]
+        public void MaxBy_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(null, (int x) => x));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(new[] { 1 }, default(Func<int, int>)));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(null, (int x) => x, Comparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(new[] { 1 }, default, Comparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(new[] { 1 }, (int x) => x, null));
+        }
+
+        [Fact]
+        public void MaxBy()
+        {
+            var res = new[] { 2, 5, 0, 7, 4, 3, 6, 2, 1 }.MaxBy(x => x % 3);
+            Assert.True(res.SequenceEqual(new[] { 2, 5, 2 }));
+        }
+
+        [Fact]
+        public void MaxBy_Empty()
+        {
+            AssertThrows<InvalidOperationException>(() => Enumerable.Empty<int>().MaxBy(x => x));
+        }
+    }
+}

+ 36 - 0
Ix.NET/Source/System.Interactive.Tests/MaxTest.cs

@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class MaxTest : Tests
+    {
+        [Fact]
+        public void Max_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Max(null, Comparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Max(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void Max()
+        {
+            Assert.Equal(5, new[] { 2, 5, 3, 7 }.Max(new Mod7Comparer()));
+        }
+
+        private class Mod7Comparer : IComparer<int>
+        {
+            public int Compare(int x, int y)
+            {
+                return Comparer<int>.Default.Compare(x % 7, y % 7);
+            }
+        }
+    }
+}

+ 273 - 0
Ix.NET/Source/System.Interactive.Tests/MemoizeTest.cs

@@ -0,0 +1,273 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+using System.Collections;
+
+namespace Tests
+{
+    public class MemoizeTest : Tests
+    {
+        [Fact]
+        public void Memoize_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int>(null));
+        }
+
+        [Fact]
+        public void MemoizeLimited_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int>(null, 2));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int>(new[] { 1 }, 0));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int>(new[] { 1 }, -1));
+        }
+
+        [Fact]
+        public void Memoize0()
+        {
+            var n = 0;
+            var rng = Tick(i => n += i).Memoize();
+
+            var e1 = rng.GetEnumerator();
+            var e2 = rng.GetEnumerator();
+
+            HasNext(e1, 0);
+            Assert.Equal(0, n);
+
+            HasNext(e1, 1);
+            Assert.Equal(1, n);
+
+            HasNext(e1, 2);
+            Assert.Equal(3, n);
+            HasNext(e2, 0);
+            Assert.Equal(3, n);
+
+            HasNext(e1, 3);
+            Assert.Equal(6, n);
+            HasNext(e2, 1);
+            Assert.Equal(6, n);
+
+            HasNext(e2, 2);
+            Assert.Equal(6, n);
+            HasNext(e2, 3);
+            Assert.Equal(6, n);
+
+            HasNext(e2, 4);
+            Assert.Equal(10, n);
+            HasNext(e1, 4);
+            Assert.Equal(10, n);
+        }
+
+        [Fact]
+        public void Memoize1()
+        {
+            var rng = Enumerable.Range(0, 5).Memoize();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            HasNext(e1, 3);
+            HasNext(e1, 4);
+            NoNext(e1);
+        }
+
+        [Fact]
+        public void Memoize2()
+        {
+            var rng = Enumerable.Range(0, 5).Memoize();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            HasNext(e1, 3);
+            HasNext(e1, 4);
+            NoNext(e1);
+
+            var e2 = rng.GetEnumerator();
+            HasNext(e2, 0);
+            HasNext(e2, 1);
+            HasNext(e2, 2);
+            HasNext(e2, 3);
+            HasNext(e2, 4);
+            NoNext(e2);
+        }
+
+        [Fact]
+        public void Memoize3()
+        {
+            var rng = Enumerable.Range(0, 5).Memoize();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+
+            var e2 = rng.GetEnumerator();
+            HasNext(e1, 3);
+            HasNext(e2, 0);
+            HasNext(e2, 1);
+            HasNext(e1, 4);
+            HasNext(e2, 2);
+            NoNext(e1);
+
+            HasNext(e2, 3);
+            HasNext(e2, 4);
+            NoNext(e2);
+        }
+
+        [Fact]
+        public void Memoize4()
+        {
+            var rng = Enumerable.Range(0, 5).Memoize(2);
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+
+            var e2 = rng.GetEnumerator();
+            HasNext(e2, 0);
+            HasNext(e2, 1);
+            HasNext(e2, 2);
+
+            var e3 = rng.GetEnumerator();
+            AssertThrows<InvalidOperationException>(() => e3.MoveNext());
+        }
+
+        [Fact]
+        public void Memoize6()
+        {
+            var ex = new MyException();
+            var rng = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex)).Memoize();
+
+            var e1 = rng.GetEnumerator();
+            var e2 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            AssertThrows<MyException>(() => e1.MoveNext());
+
+            HasNext(e2, 0);
+            HasNext(e2, 1);
+            AssertThrows<MyException>(() => e2.MoveNext());
+        }
+
+        [Fact]
+        public void Memoize7()
+        {
+            var rng = Enumerable.Range(0, 5).Memoize();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            e1.Dispose();
+
+            var e2 = rng.GetEnumerator();
+            HasNext(e2, 0);
+            HasNext(e2, 1);
+            e2.Dispose();
+
+            var e3 = rng.GetEnumerator();
+            HasNext(e3, 0);
+            HasNext(e3, 1);
+            HasNext(e3, 2);
+            HasNext(e3, 3);
+            HasNext(e3, 4);
+            NoNext(e3);
+        }
+
+        [Fact]
+        public void Memoize8()
+        {
+            var rng = Enumerable.Range(0, 5).Memoize();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+
+            rng.Dispose();
+            AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
+            AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
+            AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
+        }
+
+        [Fact]
+        public void Memoize9()
+        {
+            var rng = Enumerable.Range(0, 5).Memoize();
+
+            var e1 = ((IEnumerable)rng).GetEnumerator();
+            Assert.True(e1.MoveNext());
+            Assert.Equal(0, (int)e1.Current);
+        }
+
+        [Fact]
+        public void Memoize10()
+        {
+            var rnd = Rand().Take(1000).Memoize();
+            Assert.True(rnd.Zip(rnd, (l, r) => l == r).All(x => x));
+        }
+
+        [Fact]
+        public void MemoizeLambda_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(null, xs => xs));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void MemoizeLambda()
+        {
+            var n = 0;
+            var res = Enumerable.Range(0, 10).Do(_ => n++).Memoize(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
+            Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
+            Assert.Equal(4, n);
+        }
+
+        [Fact]
+        public void MemoizeLimitedLambda_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(null, 2, xs => xs));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, 2, null));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, 0, xs => xs));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, -1, xs => xs));
+        }
+
+        [Fact]
+        public void MemoizeLimitedLambda()
+        {
+            var n = 0;
+            var res = Enumerable.Range(0, 10).Do(_ => n++).Memoize(2, xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
+            Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
+            Assert.Equal(4, n);
+        }
+
+        private static readonly Random Random = new Random();
+
+        private static IEnumerable<int> Rand()
+        {
+            while (true)
+            {
+                yield return Random.Next();
+            }
+        }
+
+        private static IEnumerable<int> Tick(Action<int> t)
+        {
+            var i = 0;
+            while (true)
+            {
+                t(i);
+                yield return i++;
+            }
+        }
+    }
+}

+ 38 - 0
Ix.NET/Source/System.Interactive.Tests/MinByTest.cs

@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class MinByTest : Tests
+    {
+        [Fact]
+        public void MinBy_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(null, (int x) => x));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(new[] { 1 }, default(Func<int, int>)));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(null, (int x) => x, Comparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(new[] { 1 }, default, Comparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(new[] { 1 }, (int x) => x, null));
+        }
+
+        [Fact]
+        public void MinBy()
+        {
+            var res = new[] { 2, 5, 0, 7, 4, 3, 6, 2, 1 }.MinBy(x => x % 3);
+            Assert.True(res.SequenceEqual(new[] { 0, 3, 6 }));
+        }
+
+        [Fact]
+        public void MinBy_Empty()
+        {
+            AssertThrows<InvalidOperationException>(() => Enumerable.Empty<int>().MinBy(x => x));
+        }
+    }
+}

+ 36 - 0
Ix.NET/Source/System.Interactive.Tests/MinTest.cs

@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class MinTest : Tests
+    {
+        [Fact]
+        public void Min_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Min(null, Comparer<int>.Default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Min(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void Min()
+        {
+            Assert.Equal(3, new[] { 5, 3, 7 }.Min(new Mod3Comparer()));
+        }
+
+        private class Mod3Comparer : IComparer<int>
+        {
+            public int Compare(int x, int y)
+            {
+                return Comparer<int>.Default.Compare(x % 3, y % 3);
+            }
+        }
+    }
+}

+ 86 - 0
Ix.NET/Source/System.Interactive.Tests/OnErrorResumeNextTest.cs

@@ -0,0 +1,86 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class OnErrorResumeNextTest : Tests
+    {
+        [Fact]
+        public void OnErrorResumeNext_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.OnErrorResumeNext<int>(null, new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.OnErrorResumeNext<int>(new[] { 1 }, null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.OnErrorResumeNext<int>(default));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.OnErrorResumeNext<int>(default(IEnumerable<IEnumerable<int>>)));
+        }
+
+        [Fact]
+        public void OnErrorResumeNext1()
+        {
+            var xs = new[] { 1, 2 };
+            var ys = new[] { 3, 4 };
+
+            var res = xs.OnErrorResumeNext(ys);
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4 }));
+        }
+
+        [Fact]
+        public void OnErrorResumeNext2()
+        {
+            var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
+            var ys = new[] { 3, 4 };
+
+            var res = xs.OnErrorResumeNext(ys);
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4 }));
+        }
+
+        [Fact]
+        public void OnErrorResumeNext3()
+        {
+            var xs = new[] { 1, 2 };
+            var ys = new[] { 3, 4 };
+            var zs = new[] { 5, 6 };
+
+            var res = EnumerableEx.OnErrorResumeNext(xs, ys, zs);
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4, 5, 6 }));
+        }
+
+        [Fact]
+        public void OnErrorResumeNext4()
+        {
+            var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
+            var ys = new[] { 3, 4 };
+            var zs = new[] { 5, 6 };
+
+            var res = EnumerableEx.OnErrorResumeNext(xs, ys, zs);
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4, 5, 6 }));
+        }
+
+        [Fact]
+        public void OnErrorResumeNext5()
+        {
+            var xs = new[] { 1, 2 };
+            var ys = new[] { 3, 4 };
+
+            var res = new[] { xs, ys }.OnErrorResumeNext();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4 }));
+        }
+
+        [Fact]
+        public void OnErrorResumeNext6()
+        {
+            var xs = new[] { 1, 2 }.Concat(EnumerableEx.Throw<int>(new MyException()));
+            var ys = new[] { 3, 4 };
+
+            var res = new[] { xs, ys }.OnErrorResumeNext();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 4 }));
+        }
+    }
+}

+ 284 - 0
Ix.NET/Source/System.Interactive.Tests/PublishTest.cs

@@ -0,0 +1,284 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+using System.Collections;
+
+namespace Tests
+{
+    public class PublishTest : Tests
+    {
+        [Fact]
+        public void Publish_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int>(null));
+        }
+
+        [Fact]
+        public void Publish0()
+        {
+            var n = 0;
+            var rng = Tick(i => n += i).Publish();
+
+            var e1 = rng.GetEnumerator();
+            var e2 = rng.GetEnumerator();
+
+            HasNext(e1, 0);
+            Assert.Equal(0, n);
+
+            HasNext(e1, 1);
+            Assert.Equal(1, n);
+
+            HasNext(e1, 2);
+            Assert.Equal(3, n);
+            HasNext(e2, 0);
+            Assert.Equal(3, n);
+
+            HasNext(e1, 3);
+            Assert.Equal(6, n);
+            HasNext(e2, 1);
+            Assert.Equal(6, n);
+
+            HasNext(e2, 2);
+            Assert.Equal(6, n);
+            HasNext(e2, 3);
+            Assert.Equal(6, n);
+
+            HasNext(e2, 4);
+            Assert.Equal(10, n);
+            HasNext(e1, 4);
+            Assert.Equal(10, n);
+        }
+
+        [Fact]
+        public void Publish1()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            HasNext(e1, 3);
+            HasNext(e1, 4);
+            NoNext(e1);
+        }
+
+        [Fact]
+        public void Publish2()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = rng.GetEnumerator();
+            var e2 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e2, 0);
+            HasNext(e1, 1);
+            HasNext(e2, 1);
+            HasNext(e1, 2);
+            HasNext(e2, 2);
+            HasNext(e1, 3);
+            HasNext(e2, 3);
+            HasNext(e1, 4);
+            HasNext(e2, 4);
+            NoNext(e1);
+            NoNext(e2);
+        }
+
+        [Fact]
+        public void Publish3()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = rng.GetEnumerator();
+            var e2 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            HasNext(e1, 3);
+            HasNext(e1, 4);
+            HasNext(e2, 0);
+            HasNext(e2, 1);
+            HasNext(e2, 2);
+            HasNext(e2, 3);
+            HasNext(e2, 4);
+            NoNext(e1);
+            NoNext(e2);
+        }
+
+        [Fact]
+        public void Publish4()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            var e2 = rng.GetEnumerator();
+            HasNext(e1, 3);
+            HasNext(e1, 4);
+            HasNext(e2, 3);
+            HasNext(e2, 4);
+            NoNext(e1);
+            NoNext(e2);
+        }
+
+        [Fact]
+        public void Publish5()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            e1.Dispose();
+
+            var e2 = rng.GetEnumerator();
+            HasNext(e2, 3);
+            HasNext(e2, 4);
+            NoNext(e2);
+        }
+
+        [Fact]
+        public void Publish6()
+        {
+            var ex = new MyException();
+            var rng = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex)).Publish();
+
+            var e1 = rng.GetEnumerator();
+            var e2 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            AssertThrows<MyException>(() => e1.MoveNext());
+
+            HasNext(e2, 0);
+            HasNext(e2, 1);
+            AssertThrows<MyException>(() => e2.MoveNext());
+        }
+
+        [Fact]
+        public void Publish7()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+
+            var e2 = rng.GetEnumerator();
+            HasNext(e2, 3);
+            HasNext(e2, 4);
+            NoNext(e2);
+
+            HasNext(e1, 3);
+            HasNext(e1, 4);
+            NoNext(e2);
+
+            var e3 = rng.GetEnumerator();
+            NoNext(e3);
+        }
+
+        [Fact]
+        public void Publish8()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+
+            rng.Dispose();
+            AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
+            AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
+            AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
+        }
+
+        [Fact]
+        public void Publish9()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = ((IEnumerable)rng).GetEnumerator();
+            Assert.True(e1.MoveNext());
+            Assert.Equal(0, (int)e1.Current);
+        }
+
+        [Fact]
+        public void Publish10()
+        {
+            var rnd = Rand().Take(1000).Publish();
+            Assert.True(rnd.Zip(rnd, (l, r) => l == r).All(x => x));
+        }
+
+        [Fact]
+        public void Publish11()
+        {
+            var rng = Enumerable.Range(0, 5).Publish();
+
+            var e1 = rng.GetEnumerator();
+            var e2 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            e1.Dispose();
+
+            HasNext(e2, 0);
+            HasNext(e2, 1);
+            e2.Dispose();
+
+            var e3 = rng.GetEnumerator();
+            HasNext(e3, 3);
+            HasNext(e3, 4);
+            NoNext(e3);
+        }
+
+        [Fact]
+        public void PublishLambda_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int, int>(null, xs => xs));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int, int>(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void PublishLambda()
+        {
+            var n = 0;
+            var res = Enumerable.Range(0, 10).Do(_ => n++).Publish(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
+            Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
+            Assert.Equal(4, n);
+        }
+
+        private static readonly Random Random = new Random();
+
+        private static IEnumerable<int> Rand()
+        {
+            while (true)
+            {
+                yield return Random.Next();
+            }
+        }
+
+        private static IEnumerable<int> Tick(Action<int> t)
+        {
+            var i = 0;
+            while (true)
+            {
+                t(i);
+                yield return i++;
+            }
+        }
+    }
+
+    internal class MyException : Exception
+    {
+    }
+}

+ 1 - 1
Ix.NET/Source/System.Interactive.Tests/Tests.Qbservable.cs → Ix.NET/Source/System.Interactive.Tests/QueryableParityTest.cs

@@ -12,7 +12,7 @@ using Xunit;
 
 namespace Tests
 {
-    public partial class Tests
+    public class QueryableParity : Tests
     {
         [Fact]
         public void Queryable_Enumerable_Parity()

+ 55 - 0
Ix.NET/Source/System.Interactive.Tests/RepeatTest.cs

@@ -0,0 +1,55 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class RepeatTest : Tests
+    {
+        [Fact]
+        public void RepeatElementInfinite()
+        {
+            var xs = EnumerableEx.Repeat(42).Take(1000);
+            Assert.True(xs.All(x => x == 42));
+            Assert.True(xs.Count() == 1000);
+        }
+
+        [Fact]
+        public void RepeatSequence_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Repeat<int>(null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Repeat<int>(null, 5));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Repeat<int>(new[] { 1 }, -1));
+        }
+
+        [Fact]
+        public void RepeatSequence1()
+        {
+            var i = 0;
+            var xs = new[] { 1, 2 }.Do(_ => i++).Repeat();
+
+            var res = xs.Take(10).ToList();
+            Assert.Equal(10, res.Count);
+            Assert.True(res.Buffer(2).Select(b => b.Sum()).All(x => x == 3));
+            Assert.Equal(10, i);
+        }
+
+        [Fact]
+        public void RepeatSequence2()
+        {
+            var i = 0;
+            var xs = new[] { 1, 2 }.Do(_ => i++).Repeat(5);
+
+            var res = xs.ToList();
+            Assert.Equal(10, res.Count);
+            Assert.True(res.Buffer(2).Select(b => b.Sum()).All(x => x == 3));
+            Assert.Equal(10, i);
+        }
+    }
+}

+ 55 - 0
Ix.NET/Source/System.Interactive.Tests/RetryTest.cs

@@ -0,0 +1,55 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class RetryTest : Tests
+    {
+
+        [Fact]
+        public void Retry_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Retry<int>(null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Retry<int>(null, 5));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Retry<int>(new[] { 1 }, -1));
+        }
+
+        [Fact]
+        public void Retry1()
+        {
+            var xs = Enumerable.Range(0, 10);
+
+            var res = xs.Retry();
+            Assert.True(Enumerable.SequenceEqual(res, xs));
+        }
+
+        [Fact]
+        public void Retry2()
+        {
+            var xs = Enumerable.Range(0, 10);
+
+            var res = xs.Retry(2);
+            Assert.True(Enumerable.SequenceEqual(res, xs));
+        }
+
+        [Fact]
+        public void Retry3()
+        {
+            var ex = new MyException();
+            var xs = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex));
+
+            var res = xs.Retry(2);
+            var e = res.GetEnumerator();
+            HasNext(e, 0);
+            HasNext(e, 1);
+            HasNext(e, 0);
+            HasNext(e, 1);
+            AssertThrows<MyException>(() => e.MoveNext(), ex_ => ex == ex_);
+        }
+    }
+}

+ 21 - 0
Ix.NET/Source/System.Interactive.Tests/ReturnTest.cs

@@ -0,0 +1,21 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class ReturnTest : Tests
+    {
+        [Fact]
+        public void Return()
+        {
+            Assert.Equal(42, EnumerableEx.Return(42).Single());
+        }
+    }
+}

+ 36 - 0
Ix.NET/Source/System.Interactive.Tests/ScanTest.cs

@@ -0,0 +1,36 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class ScanTest : Tests
+    {
+        [Fact]
+        public void Scan_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Scan<int>(null, (x, y) => x + y));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Scan<int>(new[] { 1 }, null));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Scan<int, int>(null, 0, (x, y) => x + y));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Scan<int, int>(new[] { 1 }, 0, null));
+        }
+
+        [Fact]
+        public void Scan1()
+        {
+            var res = Enumerable.Range(0, 5).Scan((n, x) => n + x).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 3, 6, 10 }));
+        }
+
+        [Fact]
+        public void Scan2()
+        {
+            var res = Enumerable.Range(0, 5).Scan(10, (n, x) => n - x).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 10, 9, 7, 4, 0 }));
+        }
+    }
+}

+ 27 - 0
Ix.NET/Source/System.Interactive.Tests/SelectManyTest.cs

@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class SelectManyTest : Tests
+    {
+        [Fact]
+        public void SelectMany_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.SelectMany<int, int>(null, new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.SelectMany<int, int>(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void SelectMany()
+        {
+            var res = new[] { 1, 2 }.SelectMany(new[] { 'a', 'b', 'c' }).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 'a', 'b', 'c', 'a', 'b', 'c' }));
+        }
+    }
+}

+ 125 - 0
Ix.NET/Source/System.Interactive.Tests/ShareTest.cs

@@ -0,0 +1,125 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+using System.Collections;
+
+namespace Tests
+{
+    public class ShareTest : Tests
+    {
+        [Fact]
+        public void Share_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int>(null));
+        }
+
+        [Fact]
+        public void Share1()
+        {
+            var rng = Enumerable.Range(0, 5).Share();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+            HasNext(e1, 3);
+            HasNext(e1, 4);
+            NoNext(e1);
+        }
+
+        [Fact]
+        public void Share2()
+        {
+            var rng = Enumerable.Range(0, 5).Share();
+
+            var e1 = rng.GetEnumerator();
+            var e2 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e2, 1);
+            HasNext(e1, 2);
+            HasNext(e2, 3);
+            HasNext(e1, 4);
+            NoNext(e2);
+            NoNext(e1);
+        }
+
+        [Fact]
+        public void Share3()
+        {
+            var rng = Enumerable.Range(0, 5).Share();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+
+            var e2 = rng.GetEnumerator();
+            HasNext(e2, 3);
+            HasNext(e2, 4);
+            NoNext(e2);
+            NoNext(e1);
+        }
+
+        [Fact]
+        public void Share4()
+        {
+            var rng = Enumerable.Range(0, 5).Share();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+
+            e1.Dispose();
+            Assert.False(e1.MoveNext());
+        }
+
+        [Fact]
+        public void Share5()
+        {
+            var rng = Enumerable.Range(0, 5).Share();
+
+            var e1 = rng.GetEnumerator();
+            HasNext(e1, 0);
+            HasNext(e1, 1);
+            HasNext(e1, 2);
+
+            rng.Dispose();
+            AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
+            AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
+            AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
+        }
+
+        [Fact]
+        public void Share6()
+        {
+            var rng = Enumerable.Range(0, 5).Share();
+
+            var e1 = ((IEnumerable)rng).GetEnumerator();
+            Assert.True(e1.MoveNext());
+            Assert.Equal(0, (int)e1.Current);
+        }
+
+        [Fact]
+        public void ShareLambda_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int, int>(null, xs => xs));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int, int>(new[] { 1 }, null));
+        }
+
+        [Fact]
+        public void ShareLambda()
+        {
+            var n = 0;
+            var res = Enumerable.Range(0, 10).Do(_ => n++).Share(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
+            Assert.True(res.SequenceEqual(new[] { 0 + 1, 2 + 3, 4 + 5, 6 + 7 }));
+            Assert.Equal(8, n);
+        }
+    }
+}

+ 58 - 0
Ix.NET/Source/System.Interactive.Tests/SkipLastTest.cs

@@ -0,0 +1,58 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class SkipLastTest : Tests
+    {
+        [Fact]
+        public void SkipLast_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.SkipLast<int>(null, 5));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.SkipLast<int>(new[] { 1 }, -1));
+        }
+
+        [Fact]
+        public void SkipLast_Empty()
+        {
+            var e = Enumerable.Empty<int>();
+#if NETCOREAPP2_1 || WINDOWS_UWP
+            var r = EnumerableEx.SkipLast(e, 1).ToList();
+#else
+            var r = e.SkipLast(1).ToList();
+#endif
+            Assert.True(Enumerable.SequenceEqual(r, e));
+        }
+
+        [Fact]
+        public void SkipLast_All()
+        {
+            var e = Enumerable.Range(0, 5);
+#if NETCOREAPP2_1 || WINDOWS_UWP
+            var r = EnumerableEx.SkipLast(e, 0).ToList();
+#else
+            var r = e.SkipLast(0).ToList();
+#endif
+            Assert.True(Enumerable.SequenceEqual(r, e));
+        }
+
+        [Fact]
+        public void SkipLast_Part()
+        {
+            var e = Enumerable.Range(0, 5);
+#if NETCOREAPP2_1 || WINDOWS_UWP
+            var r = EnumerableEx.SkipLast(e, 3).ToList();
+#else
+            var r = e.SkipLast(3).ToList();
+#endif
+            Assert.True(Enumerable.SequenceEqual(r, e.Take(2)));
+        }
+    }
+}

+ 38 - 0
Ix.NET/Source/System.Interactive.Tests/StartWithTest.cs

@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class StartWithTest : Tests
+    {
+        [Fact]
+        public void StartWith_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.StartWith<int>(null, 5));
+        }
+
+        [Fact]
+        public void StartWith1()
+        {
+            var e = Enumerable.Range(1, 5);
+            var r = e.StartWith(0).ToList();
+            Assert.True(Enumerable.SequenceEqual(r, Enumerable.Range(0, 6)));
+        }
+
+        [Fact]
+        public void StartWith2()
+        {
+            var oops = false;
+            var e = Enumerable.Range(1, 5).Do(_ => oops = true);
+            var r = e.StartWith(0).Take(1).ToList();
+            Assert.False(oops);
+        }
+    }
+}

+ 73 - 0
Ix.NET/Source/System.Interactive.Tests/TakeLastTest.cs

@@ -0,0 +1,73 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class TakeLastTest : Tests
+    {
+        [Fact]
+        public void TakeLast_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.TakeLast<int>(null, 5));
+            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.TakeLast<int>(new[] { 1 }, -1));
+        }
+
+        [Fact]
+        public void TakeLast_TakeZero()
+        {
+            var e = Enumerable.Range(1, 5);
+#if NETCOREAPP2_1 || WINDOWS_UWP
+            var r = EnumerableEx.TakeLast(e, 0).ToList();
+#else
+            var r = e.TakeLast(0).ToList();
+#endif
+            Assert.True(Enumerable.SequenceEqual(r, Enumerable.Empty<int>()));
+        }
+
+        [Fact]
+        public void TakeLast_Empty()
+        {
+            var e = Enumerable.Empty<int>();
+
+#if NETCOREAPP2_1 || WINDOWS_UWP
+            var r = EnumerableEx.TakeLast(e, 1).ToList();
+#else
+            var r = e.TakeLast(1).ToList();
+#endif
+            Assert.True(Enumerable.SequenceEqual(r, e));
+        }
+
+        [Fact]
+        public void TakeLast_All()
+        {
+            var e = Enumerable.Range(0, 5);
+
+#if NETCOREAPP2_1 || WINDOWS_UWP
+            var r = EnumerableEx.TakeLast(e, 5).ToList();
+#else
+            var r = e.TakeLast(5).ToList();
+#endif
+
+            Assert.True(Enumerable.SequenceEqual(r, e));
+        }
+
+        [Fact]
+        public void TakeLast_Part()
+        {
+            var e = Enumerable.Range(0, 5);
+#if NETCOREAPP2_1 || WINDOWS_UWP
+            var r = EnumerableEx.TakeLast(e, 3).ToList();
+#else
+            var r = e.TakeLast(3).ToList();
+#endif
+            Assert.True(Enumerable.SequenceEqual(r, e.Skip(2)));
+        }
+    }
+}

+ 0 - 119
Ix.NET/Source/System.Interactive.Tests/Tests.Aggregates.cs

@@ -1,119 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the Apache 2.0 License.
-// See the LICENSE file in the project root for more information. 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-
-namespace Tests
-{
-    public partial class Tests
-    {
-        [Fact]
-        public void IsEmtpy_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.IsEmpty<int>(null));
-        }
-
-        [Fact]
-        public void IsEmpty_Empty()
-        {
-            Assert.True(Enumerable.Empty<int>().IsEmpty());
-        }
-
-        [Fact]
-        public void IsEmpty_NonEmpty()
-        {
-            Assert.False(new[] { 1 }.IsEmpty());
-        }
-
-        [Fact]
-        public void Min_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Min(null, Comparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Min(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void Min()
-        {
-            Assert.Equal(3, new[] { 5, 3, 7 }.Min(new Mod3Comparer()));
-        }
-
-        private class Mod3Comparer : IComparer<int>
-        {
-            public int Compare(int x, int y)
-            {
-                return Comparer<int>.Default.Compare(x % 3, y % 3);
-            }
-        }
-
-        [Fact]
-        public void MinBy_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(null, (int x) => x));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(new[] { 1 }, default(Func<int, int>)));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(null, (int x) => x, Comparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(new[] { 1 }, default, Comparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MinBy(new[] { 1 }, (int x) => x, null));
-        }
-
-        [Fact]
-        public void MinBy()
-        {
-            var res = new[] { 2, 5, 0, 7, 4, 3, 6, 2, 1 }.MinBy(x => x % 3);
-            Assert.True(res.SequenceEqual(new[] { 0, 3, 6 }));
-        }
-
-        [Fact]
-        public void MinBy_Empty()
-        {
-            AssertThrows<InvalidOperationException>(() => Enumerable.Empty<int>().MinBy(x => x));
-        }
-
-        [Fact]
-        public void Max_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Max(null, Comparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Max(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void Max()
-        {
-            Assert.Equal(5, new[] { 2, 5, 3, 7 }.Max(new Mod7Comparer()));
-        }
-
-        private class Mod7Comparer : IComparer<int>
-        {
-            public int Compare(int x, int y)
-            {
-                return Comparer<int>.Default.Compare(x % 7, y % 7);
-            }
-        }
-
-        [Fact]
-        public void MaxBy_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(null, (int x) => x));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(new[] { 1 }, default(Func<int, int>)));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(null, (int x) => x, Comparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(new[] { 1 }, default, Comparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.MaxBy(new[] { 1 }, (int x) => x, null));
-        }
-
-        [Fact]
-        public void MaxBy()
-        {
-            var res = new[] { 2, 5, 0, 7, 4, 3, 6, 2, 1 }.MaxBy(x => x % 3);
-            Assert.True(res.SequenceEqual(new[] { 2, 5, 2 }));
-        }
-
-        [Fact]
-        public void MaxBy_Empty()
-        {
-            AssertThrows<InvalidOperationException>(() => Enumerable.Empty<int>().MaxBy(x => x));
-        }
-    }
-}

+ 0 - 628
Ix.NET/Source/System.Interactive.Tests/Tests.Buffering.cs

@@ -1,628 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the Apache 2.0 License.
-// See the LICENSE file in the project root for more information. 
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-
-namespace Tests
-{
-    public partial class Tests
-    {
-        [Fact]
-        public void Share_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int>(null));
-        }
-
-        [Fact]
-        public void Share1()
-        {
-            var rng = Enumerable.Range(0, 5).Share();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            HasNext(e1, 3);
-            HasNext(e1, 4);
-            NoNext(e1);
-        }
-
-        [Fact]
-        public void Share2()
-        {
-            var rng = Enumerable.Range(0, 5).Share();
-
-            var e1 = rng.GetEnumerator();
-            var e2 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e2, 1);
-            HasNext(e1, 2);
-            HasNext(e2, 3);
-            HasNext(e1, 4);
-            NoNext(e2);
-            NoNext(e1);
-        }
-
-        [Fact]
-        public void Share3()
-        {
-            var rng = Enumerable.Range(0, 5).Share();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-
-            var e2 = rng.GetEnumerator();
-            HasNext(e2, 3);
-            HasNext(e2, 4);
-            NoNext(e2);
-            NoNext(e1);
-        }
-
-        [Fact]
-        public void Share4()
-        {
-            var rng = Enumerable.Range(0, 5).Share();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-
-            e1.Dispose();
-            Assert.False(e1.MoveNext());
-        }
-
-        [Fact]
-        public void Share5()
-        {
-            var rng = Enumerable.Range(0, 5).Share();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-
-            rng.Dispose();
-            AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
-            AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
-            AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
-        }
-
-        [Fact]
-        public void Share6()
-        {
-            var rng = Enumerable.Range(0, 5).Share();
-
-            var e1 = ((IEnumerable)rng).GetEnumerator();
-            Assert.True(e1.MoveNext());
-            Assert.Equal(0, (int)e1.Current);
-        }
-
-        [Fact]
-        public void Publish_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int>(null));
-        }
-
-        [Fact]
-        public void Publish0()
-        {
-            var n = 0;
-            var rng = Tick(i => n += i).Publish();
-
-            var e1 = rng.GetEnumerator();
-            var e2 = rng.GetEnumerator();
-
-            HasNext(e1, 0);
-            Assert.Equal(0, n);
-
-            HasNext(e1, 1);
-            Assert.Equal(1, n);
-
-            HasNext(e1, 2);
-            Assert.Equal(3, n);
-            HasNext(e2, 0);
-            Assert.Equal(3, n);
-
-            HasNext(e1, 3);
-            Assert.Equal(6, n);
-            HasNext(e2, 1);
-            Assert.Equal(6, n);
-
-            HasNext(e2, 2);
-            Assert.Equal(6, n);
-            HasNext(e2, 3);
-            Assert.Equal(6, n);
-
-            HasNext(e2, 4);
-            Assert.Equal(10, n);
-            HasNext(e1, 4);
-            Assert.Equal(10, n);
-        }
-
-        private static IEnumerable<int> Tick(Action<int> t)
-        {
-            var i = 0;
-            while (true)
-            {
-                t(i);
-                yield return i++;
-            }
-        }
-
-        [Fact]
-        public void Publish1()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            HasNext(e1, 3);
-            HasNext(e1, 4);
-            NoNext(e1);
-        }
-
-        [Fact]
-        public void Publish2()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = rng.GetEnumerator();
-            var e2 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e2, 0);
-            HasNext(e1, 1);
-            HasNext(e2, 1);
-            HasNext(e1, 2);
-            HasNext(e2, 2);
-            HasNext(e1, 3);
-            HasNext(e2, 3);
-            HasNext(e1, 4);
-            HasNext(e2, 4);
-            NoNext(e1);
-            NoNext(e2);
-        }
-
-        [Fact]
-        public void Publish3()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = rng.GetEnumerator();
-            var e2 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            HasNext(e1, 3);
-            HasNext(e1, 4);
-            HasNext(e2, 0);
-            HasNext(e2, 1);
-            HasNext(e2, 2);
-            HasNext(e2, 3);
-            HasNext(e2, 4);
-            NoNext(e1);
-            NoNext(e2);
-        }
-
-        [Fact]
-        public void Publish4()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            var e2 = rng.GetEnumerator();
-            HasNext(e1, 3);
-            HasNext(e1, 4);
-            HasNext(e2, 3);
-            HasNext(e2, 4);
-            NoNext(e1);
-            NoNext(e2);
-        }
-
-        [Fact]
-        public void Publish5()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            e1.Dispose();
-
-            var e2 = rng.GetEnumerator();
-            HasNext(e2, 3);
-            HasNext(e2, 4);
-            NoNext(e2);
-        }
-
-        [Fact]
-        public void Publish6()
-        {
-            var ex = new MyException();
-            var rng = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex)).Publish();
-
-            var e1 = rng.GetEnumerator();
-            var e2 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            AssertThrows<MyException>(() => e1.MoveNext());
-
-            HasNext(e2, 0);
-            HasNext(e2, 1);
-            AssertThrows<MyException>(() => e2.MoveNext());
-        }
-
-        private class MyException : Exception
-        {
-        }
-
-        [Fact]
-        public void Publish7()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-
-            var e2 = rng.GetEnumerator();
-            HasNext(e2, 3);
-            HasNext(e2, 4);
-            NoNext(e2);
-
-            HasNext(e1, 3);
-            HasNext(e1, 4);
-            NoNext(e2);
-
-            var e3 = rng.GetEnumerator();
-            NoNext(e3);
-        }
-
-        [Fact]
-        public void Publish8()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-
-            rng.Dispose();
-            AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
-            AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
-            AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
-        }
-
-        [Fact]
-        public void Publish9()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = ((IEnumerable)rng).GetEnumerator();
-            Assert.True(e1.MoveNext());
-            Assert.Equal(0, (int)e1.Current);
-        }
-
-        [Fact]
-        public void Publish10()
-        {
-            var rnd = Rand().Take(1000).Publish();
-            Assert.True(rnd.Zip(rnd, (l, r) => l == r).All(x => x));
-        }
-
-        [Fact]
-        public void Memoize_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int>(null));
-        }
-
-        [Fact]
-        public void MemoizeLimited_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int>(null, 2));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int>(new[] { 1 }, 0));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int>(new[] { 1 }, -1));
-        }
-
-        [Fact]
-        public void Memoize0()
-        {
-            var n = 0;
-            var rng = Tick(i => n += i).Memoize();
-
-            var e1 = rng.GetEnumerator();
-            var e2 = rng.GetEnumerator();
-
-            HasNext(e1, 0);
-            Assert.Equal(0, n);
-
-            HasNext(e1, 1);
-            Assert.Equal(1, n);
-
-            HasNext(e1, 2);
-            Assert.Equal(3, n);
-            HasNext(e2, 0);
-            Assert.Equal(3, n);
-
-            HasNext(e1, 3);
-            Assert.Equal(6, n);
-            HasNext(e2, 1);
-            Assert.Equal(6, n);
-
-            HasNext(e2, 2);
-            Assert.Equal(6, n);
-            HasNext(e2, 3);
-            Assert.Equal(6, n);
-
-            HasNext(e2, 4);
-            Assert.Equal(10, n);
-            HasNext(e1, 4);
-            Assert.Equal(10, n);
-        }
-
-        [Fact]
-        public void Publish11()
-        {
-            var rng = Enumerable.Range(0, 5).Publish();
-
-            var e1 = rng.GetEnumerator();
-            var e2 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            e1.Dispose();
-
-            HasNext(e2, 0);
-            HasNext(e2, 1);
-            e2.Dispose();
-
-            var e3 = rng.GetEnumerator();
-            HasNext(e3, 3);
-            HasNext(e3, 4);
-            NoNext(e3);
-        }
-
-        [Fact]
-        public void Memoize1()
-        {
-            var rng = Enumerable.Range(0, 5).Memoize();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            HasNext(e1, 3);
-            HasNext(e1, 4);
-            NoNext(e1);
-        }
-
-        [Fact]
-        public void Memoize2()
-        {
-            var rng = Enumerable.Range(0, 5).Memoize();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            HasNext(e1, 3);
-            HasNext(e1, 4);
-            NoNext(e1);
-
-            var e2 = rng.GetEnumerator();
-            HasNext(e2, 0);
-            HasNext(e2, 1);
-            HasNext(e2, 2);
-            HasNext(e2, 3);
-            HasNext(e2, 4);
-            NoNext(e2);
-        }
-
-        [Fact]
-        public void Memoize3()
-        {
-            var rng = Enumerable.Range(0, 5).Memoize();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-
-            var e2 = rng.GetEnumerator();
-            HasNext(e1, 3);
-            HasNext(e2, 0);
-            HasNext(e2, 1);
-            HasNext(e1, 4);
-            HasNext(e2, 2);
-            NoNext(e1);
-
-            HasNext(e2, 3);
-            HasNext(e2, 4);
-            NoNext(e2);
-        }
-
-        [Fact]
-        public void Memoize4()
-        {
-            var rng = Enumerable.Range(0, 5).Memoize(2);
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-
-            var e2 = rng.GetEnumerator();
-            HasNext(e2, 0);
-            HasNext(e2, 1);
-            HasNext(e2, 2);
-
-            var e3 = rng.GetEnumerator();
-            AssertThrows<InvalidOperationException>(() => e3.MoveNext());
-        }
-
-        [Fact]
-        public void Memoize6()
-        {
-            var ex = new MyException();
-            var rng = Enumerable.Range(0, 2).Concat(EnumerableEx.Throw<int>(ex)).Memoize();
-
-            var e1 = rng.GetEnumerator();
-            var e2 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            AssertThrows<MyException>(() => e1.MoveNext());
-
-            HasNext(e2, 0);
-            HasNext(e2, 1);
-            AssertThrows<MyException>(() => e2.MoveNext());
-        }
-
-        [Fact]
-        public void Memoize7()
-        {
-            var rng = Enumerable.Range(0, 5).Memoize();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-            e1.Dispose();
-
-            var e2 = rng.GetEnumerator();
-            HasNext(e2, 0);
-            HasNext(e2, 1);
-            e2.Dispose();
-
-            var e3 = rng.GetEnumerator();
-            HasNext(e3, 0);
-            HasNext(e3, 1);
-            HasNext(e3, 2);
-            HasNext(e3, 3);
-            HasNext(e3, 4);
-            NoNext(e3);
-        }
-
-        [Fact]
-        public void Memoize8()
-        {
-            var rng = Enumerable.Range(0, 5).Memoize();
-
-            var e1 = rng.GetEnumerator();
-            HasNext(e1, 0);
-            HasNext(e1, 1);
-            HasNext(e1, 2);
-
-            rng.Dispose();
-            AssertThrows<ObjectDisposedException>(() => e1.MoveNext());
-            AssertThrows<ObjectDisposedException>(() => rng.GetEnumerator());
-            AssertThrows<ObjectDisposedException>(() => ((IEnumerable)rng).GetEnumerator());
-        }
-
-        [Fact]
-        public void Memoize9()
-        {
-            var rng = Enumerable.Range(0, 5).Memoize();
-
-            var e1 = ((IEnumerable)rng).GetEnumerator();
-            Assert.True(e1.MoveNext());
-            Assert.Equal(0, (int)e1.Current);
-        }
-
-        [Fact]
-        public void Memoize10()
-        {
-            var rnd = Rand().Take(1000).Memoize();
-            Assert.True(rnd.Zip(rnd, (l, r) => l == r).All(x => x));
-        }
-
-        private static readonly Random Random = new Random();
-
-        private static IEnumerable<int> Rand()
-        {
-            while (true)
-            {
-                yield return Random.Next();
-            }
-        }
-
-        [Fact]
-        public void ShareLambda_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int, int>(null, xs => xs));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Share<int, int>(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void ShareLambda()
-        {
-            var n = 0;
-            var res = Enumerable.Range(0, 10).Do(_ => n++).Share(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
-            Assert.True(res.SequenceEqual(new[] { 0 + 1, 2 + 3, 4 + 5, 6 + 7 }));
-            Assert.Equal(8, n);
-        }
-
-        [Fact]
-        public void PublishLambda_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int, int>(null, xs => xs));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Publish<int, int>(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void PublishLambda()
-        {
-            var n = 0;
-            var res = Enumerable.Range(0, 10).Do(_ => n++).Publish(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
-            Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
-            Assert.Equal(4, n);
-        }
-
-        [Fact]
-        public void MemoizeLambda_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(null, xs => xs));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void MemoizeLambda()
-        {
-            var n = 0;
-            var res = Enumerable.Range(0, 10).Do(_ => n++).Memoize(xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
-            Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
-            Assert.Equal(4, n);
-        }
-
-        [Fact]
-        public void MemoizeLimitedLambda_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(null, 2, xs => xs));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, 2, null));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, 0, xs => xs));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Memoize<int, int>(new[] { 1 }, -1, xs => xs));
-        }
-
-        [Fact]
-        public void MemoizeLimitedLambda()
-        {
-            var n = 0;
-            var res = Enumerable.Range(0, 10).Do(_ => n++).Memoize(2, xs => xs.Zip(xs, (l, r) => l + r).Take(4)).ToList();
-            Assert.True(res.SequenceEqual(Enumerable.Range(0, 4).Select(x => x * 2)));
-            Assert.Equal(4, n);
-        }
-    }
-}

+ 0 - 292
Ix.NET/Source/System.Interactive.Tests/Tests.Creation.cs

@@ -1,292 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the Apache 2.0 License.
-// See the LICENSE file in the project root for more information. 
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using Xunit;
-
-namespace Tests
-{
-    public partial class Tests
-    {
-        [Fact]
-        public void Create_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Create<int>(default));
-        }
-
-        [Fact]
-        public void Create1()
-        {
-            var hot = false;
-            var res = EnumerableEx.Create<int>(() =>
-            {
-                hot = true;
-                return MyEnumerator();
-            });
-
-            Assert.False(hot);
-
-            var e = res.GetEnumerator();
-            Assert.True(hot);
-
-            HasNext(e, 1);
-            HasNext(e, 2);
-            NoNext(e);
-
-            hot = false;
-            var f = ((IEnumerable)res).GetEnumerator();
-            Assert.True(hot);
-        }
-
-        [Fact]
-        public void CreateYield()
-        {
-            SynchronizationContext.SetSynchronizationContext(null);
-
-            var xs = EnumerableEx.Create<int>(async yield =>
-            {
-                var i = 0;
-                while (i < 10)
-                {
-                    await yield.Return(i++);
-                }
-            });
-
-            var j = 0;
-            foreach (var elem in xs)
-            {
-                Assert.Equal(j, elem);
-                j++;
-            }
-
-            Assert.Equal(10, j);
-        }
-
-        [Fact]
-        public void CreateYieldBreak()
-        {
-            SynchronizationContext.SetSynchronizationContext(null);
-
-            var xs = EnumerableEx.Create<int>(async yield =>
-            {
-                var i = 0;
-                while (true)
-                {
-                    if (i == 10)
-                    {
-                        await yield.Break();
-                        return;
-                    }
-
-                    await yield.Return(i++);
-                }
-            });
-
-            var j = 0;
-            foreach (var elem in xs)
-            {
-                Assert.Equal(elem, j);
-                j++;
-            }
-
-            Assert.Equal(10, j);
-        }
-
-        [Fact]
-        public void YielderNoReset()
-        {
-            var xs = EnumerableEx.Create<int>(async yield =>
-            {
-                await yield.Break();
-            });
-
-            AssertThrows<NotSupportedException>(() => xs.GetEnumerator().Reset());
-        }
-
-
-        private static IEnumerator<int> MyEnumerator()
-        {
-            yield return 1;
-            yield return 2;
-        }
-
-        [Fact]
-        public void Return()
-        {
-            Assert.Equal(42, EnumerableEx.Return(42).Single());
-        }
-
-        [Fact]
-        public void Throw_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Throw<int>(null));
-        }
-
-        [Fact]
-        public void Throw()
-        {
-            var ex = new MyException();
-            var xs = EnumerableEx.Throw<int>(ex);
-
-            var e = xs.GetEnumerator();
-            AssertThrows<MyException>(() => e.MoveNext());
-        }
-
-        [Fact]
-        public void Defer_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Defer<int>(null));
-        }
-
-        [Fact]
-        public void Defer1()
-        {
-            var i = 0;
-            var n = 5;
-            var xs = EnumerableEx.Defer(() =>
-            {
-                i++;
-                return Enumerable.Range(0, n);
-            });
-
-            Assert.Equal(0, i);
-
-            Assert.True(Enumerable.SequenceEqual(xs, Enumerable.Range(0, n)));
-            Assert.Equal(1, i);
-
-            n = 3;
-            Assert.True(Enumerable.SequenceEqual(xs, Enumerable.Range(0, n)));
-            Assert.Equal(2, i);
-        }
-
-        [Fact]
-        public void Defer2()
-        {
-            var xs = EnumerableEx.Defer<int>(() =>
-            {
-                throw new MyException();
-            });
-
-            AssertThrows<MyException>(() => xs.GetEnumerator().MoveNext());
-        }
-
-        [Fact]
-        public void Generate_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Generate<int, int>(0, null, _ => _, _ => _));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Generate<int, int>(0, _ => true, null, _ => _));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Generate<int, int>(0, _ => true, _ => _, null));
-        }
-
-        [Fact]
-        public void Generate()
-        {
-            var res = EnumerableEx.Generate(0, x => x < 5, x => x + 1, x => x * x).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 0, 1, 4, 9, 16 }));
-        }
-
-        [Fact]
-        public void Using_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Using<int, MyDisposable>(null, d => new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Using<int, MyDisposable>(() => new MyDisposable(), null));
-        }
-
-        [Fact]
-        public void Using1()
-        {
-            var d = default(MyDisposable);
-
-            var xs = EnumerableEx.Using(() => d = new MyDisposable(), d_ => new[] { 1 });
-            Assert.Null(d);
-
-            var d1 = default(MyDisposable);
-            xs.ForEach(_ => { d1 = d; Assert.NotNull(d1); Assert.False(d1.Done); });
-            Assert.True(d1.Done);
-
-            var d2 = default(MyDisposable);
-            xs.ForEach(_ => { d2 = d; Assert.NotNull(d2); Assert.False(d2.Done); });
-            Assert.True(d2.Done);
-
-            Assert.NotSame(d1, d2);
-        }
-
-        [Fact]
-        public void Using2()
-        {
-            var d = default(MyDisposable);
-
-            var xs = EnumerableEx.Using(() => d = new MyDisposable(), d_ => EnumerableEx.Throw<int>(new MyException()));
-            Assert.Null(d);
-
-            AssertThrows<MyException>(() => xs.ForEach(_ => { }));
-            Assert.True(d.Done);
-        }
-
-        [Fact]
-        public void Using3()
-        {
-            var d = default(MyDisposable);
-
-            var xs = EnumerableEx.Using<int, MyDisposable>(() => d = new MyDisposable(), d_ => { throw new MyException(); });
-            Assert.Null(d);
-
-            AssertThrows<MyException>(() => xs.ForEach(_ => { }));
-            Assert.True(d.Done);
-        }
-
-        private class MyDisposable : IDisposable
-        {
-            public bool Done;
-
-            public void Dispose()
-            {
-                Done = true;
-            }
-        }
-
-        [Fact]
-        public void RepeatElementInfinite()
-        {
-            var xs = EnumerableEx.Repeat(42).Take(1000);
-            Assert.True(xs.All(x => x == 42));
-            Assert.True(xs.Count() == 1000);
-        }
-
-        [Fact]
-        public void RepeatSequence_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Repeat<int>(null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Repeat<int>(null, 5));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Repeat<int>(new[] { 1 }, -1));
-        }
-
-        [Fact]
-        public void RepeatSequence1()
-        {
-            var i = 0;
-            var xs = new[] { 1, 2 }.Do(_ => i++).Repeat();
-
-            var res = xs.Take(10).ToList();
-            Assert.Equal(10, res.Count);
-            Assert.True(res.Buffer(2).Select(b => b.Sum()).All(x => x == 3));
-            Assert.Equal(10, i);
-        }
-
-        [Fact]
-        public void RepeatSequence2()
-        {
-            var i = 0;
-            var xs = new[] { 1, 2 }.Do(_ => i++).Repeat(5);
-
-            var res = xs.ToList();
-            Assert.Equal(10, res.Count);
-            Assert.True(res.Buffer(2).Select(b => b.Sum()).All(x => x == 3));
-            Assert.Equal(10, i);
-        }
-    }
-}

+ 0 - 181
Ix.NET/Source/System.Interactive.Tests/Tests.Imperative.cs

@@ -1,181 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the Apache 2.0 License.
-// See the LICENSE file in the project root for more information. 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-
-namespace Tests
-{
-    public partial class Tests
-    {
-        [Fact]
-        public void While_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.While<int>(null, new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.While<int>(() => true, null));
-        }
-
-        [Fact]
-        public void While1()
-        {
-            var x = 5;
-            var res = EnumerableEx.While(() => x > 0, EnumerableEx.Defer(() => new[] { x }).Do(_ => x--)).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 5, 4, 3, 2, 1 }));
-        }
-
-        [Fact]
-        public void While2()
-        {
-            var x = 0;
-            var res = EnumerableEx.While(() => x > 0, EnumerableEx.Defer(() => new[] { x }).Do(_ => x--)).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new int[0]));
-        }
-
-        [Fact]
-        public void DoWhile_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DoWhile<int>(new[] { 1 }, null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DoWhile<int>(null, () => true));
-        }
-
-        [Fact]
-        public void DoWhile1()
-        {
-            var x = 5;
-            var res = EnumerableEx.DoWhile(EnumerableEx.Defer(() => new[] { x }).Do(_ => x--), () => x > 0).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 5, 4, 3, 2, 1 }));
-        }
-
-        [Fact]
-        public void DoWhile2()
-        {
-            var x = 0;
-            var res = EnumerableEx.DoWhile(EnumerableEx.Defer(() => new[] { x }).Do(_ => x--), () => x > 0).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 0 }));
-        }
-
-        [Fact]
-        public void If_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(null, new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(() => true, null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(null, new[] { 1 }, new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(() => true, null, new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.If<int>(() => true, new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void If1()
-        {
-            var x = 5;
-            var res = EnumerableEx.If(() => x > 0, new[] { +1 }, new[] { -1 });
-
-            Assert.Equal(+1, res.Single());
-
-            x = -x;
-            Assert.Equal(-1, res.Single());
-        }
-
-        [Fact]
-        public void If2()
-        {
-            var x = 5;
-            var res = EnumerableEx.If(() => x > 0, new[] { +1 });
-
-            Assert.Equal(+1, res.Single());
-
-            x = -x;
-            Assert.True(res.IsEmpty());
-        }
-
-        [Fact]
-        public void Case_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(null, new Dictionary<int, IEnumerable<int>>()));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(() => 1, null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(null, new Dictionary<int, IEnumerable<int>>(), new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(() => 1, null, new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Case<int, int>(() => 1, new Dictionary<int, IEnumerable<int>>(), null));
-        }
-
-        [Fact]
-        public void Case1()
-        {
-            var x = 1;
-            var d = 'd';
-            var res = EnumerableEx.Case<int, char>(() => x, new Dictionary<int, IEnumerable<char>>
-            {
-                { 0, new[] { 'a' } },
-                { 1, new[] { 'b' } },
-                { 2, new[] { 'c' } },
-                { 3, EnumerableEx.Defer(() => new[] { d }) },
-            });
-
-            Assert.Equal('b', res.Single());
-            Assert.Equal('b', res.Single());
-
-            x = 0;
-            Assert.Equal('a', res.Single());
-
-            x = 2;
-            Assert.Equal('c', res.Single());
-
-            x = 3;
-            Assert.Equal('d', res.Single());
-
-            d = 'e';
-            Assert.Equal('e', res.Single());
-
-            x = 4;
-            Assert.True(res.IsEmpty());
-        }
-
-        [Fact]
-        public void Case2()
-        {
-            var x = 1;
-            var d = 'd';
-            var res = EnumerableEx.Case<int, char>(() => x, new Dictionary<int, IEnumerable<char>>
-            {
-                { 0, new[] { 'a' } },
-                { 1, new[] { 'b' } },
-                { 2, new[] { 'c' } },
-                { 3, EnumerableEx.Defer(() => new[] { d }) },
-            }, new[] { 'z' });
-
-            Assert.Equal('b', res.Single());
-            Assert.Equal('b', res.Single());
-
-            x = 0;
-            Assert.Equal('a', res.Single());
-
-            x = 2;
-            Assert.Equal('c', res.Single());
-
-            x = 3;
-            Assert.Equal('d', res.Single());
-
-            d = 'e';
-            Assert.Equal('e', res.Single());
-
-            x = 4;
-            Assert.Equal('z', res.Single());
-        }
-
-        [Fact]
-        public void For_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.For<int, int>(null, x => new[] { 1 }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.For<int, int>(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void For()
-        {
-            var res = EnumerableEx.For(new[] { 1, 2, 3 }, x => Enumerable.Range(0, x)).ToList();
-            Assert.True(res.SequenceEqual(new[] { 0, 0, 1, 0, 1, 2 }));
-        }
-    }
-}

+ 0 - 467
Ix.NET/Source/System.Interactive.Tests/Tests.Single.cs

@@ -1,467 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the Apache 2.0 License.
-// See the LICENSE file in the project root for more information. 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Xunit;
-
-namespace Tests
-{
-    public partial class Tests
-    {
-        [Fact]
-        public void Hide_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Hide<int>(null));
-        }
-
-        [Fact]
-        public void Hide()
-        {
-            var xs = new List<int> { 1, 2, 3 };
-            var ys = xs.Hide();
-            Assert.False(ys is List<int>);
-            Assert.True(xs.SequenceEqual(ys));
-        }
-
-        [Fact]
-        public void ForEach_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.ForEach<int>(null, x => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.ForEach<int>(new[] { 1 }, default(Action<int>)));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.ForEach<int>(null, (x, i) => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.ForEach<int>(new[] { 1 }, default(Action<int, int>)));
-        }
-
-        [Fact]
-        public void ForEach1()
-        {
-            var n = 0;
-            Enumerable.Range(5, 3).ForEach(x => n += x);
-            Assert.Equal(5 + 6 + 7, n);
-        }
-
-        [Fact]
-        public void ForEach2()
-        {
-            var n = 0;
-            Enumerable.Range(5, 3).ForEach((x, i) => n += x * i);
-            Assert.Equal(5 * 0 + 6 * 1 + 7 * 2, n);
-        }
-
-        [Fact]
-        public void Buffer_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Buffer<int>(null, 5));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Buffer<int>(null, 5, 3));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Buffer<int>(new[] { 1 }, 0));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Buffer<int>(new[] { 1 }, 5, 0));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.Buffer<int>(new[] { 1 }, 0, 3));
-        }
-
-        [Fact]
-        public void Buffer1()
-        {
-            var rng = Enumerable.Range(0, 10);
-
-            var res = rng.Buffer(3).ToList();
-            Assert.Equal(4, res.Count);
-
-            Assert.True(res[0].SequenceEqual(new[] { 0, 1, 2 }));
-            Assert.True(res[1].SequenceEqual(new[] { 3, 4, 5 }));
-            Assert.True(res[2].SequenceEqual(new[] { 6, 7, 8 }));
-            Assert.True(res[3].SequenceEqual(new[] { 9 }));
-        }
-
-        [Fact]
-        public void Buffer2()
-        {
-            var rng = Enumerable.Range(0, 10);
-
-            var res = rng.Buffer(5).ToList();
-            Assert.Equal(2, res.Count);
-
-            Assert.True(res[0].SequenceEqual(new[] { 0, 1, 2, 3, 4 }));
-            Assert.True(res[1].SequenceEqual(new[] { 5, 6, 7, 8, 9 }));
-        }
-
-        [Fact]
-        public void Buffer3()
-        {
-            var rng = Enumerable.Empty<int>();
-
-            var res = rng.Buffer(5).ToList();
-            Assert.Empty(res);
-        }
-
-        [Fact]
-        public void Buffer4()
-        {
-            var rng = Enumerable.Range(0, 10);
-
-            var res = rng.Buffer(3, 2).ToList();
-            Assert.Equal(5, res.Count);
-
-            Assert.True(res[0].SequenceEqual(new[] { 0, 1, 2 }));
-            Assert.True(res[1].SequenceEqual(new[] { 2, 3, 4 }));
-            Assert.True(res[2].SequenceEqual(new[] { 4, 5, 6 }));
-            Assert.True(res[3].SequenceEqual(new[] { 6, 7, 8 }));
-            Assert.True(res[4].SequenceEqual(new[] { 8, 9 }));
-        }
-
-        [Fact]
-        public void Buffer5()
-        {
-            var rng = Enumerable.Range(0, 10);
-
-            var res = rng.Buffer(3, 4).ToList();
-            Assert.Equal(3, res.Count);
-
-            Assert.True(res[0].SequenceEqual(new[] { 0, 1, 2 }));
-            Assert.True(res[1].SequenceEqual(new[] { 4, 5, 6 }));
-            Assert.True(res[2].SequenceEqual(new[] { 8, 9 }));
-        }
-
-        [Fact]
-        public void Do_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, _ => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, _ => { }, () => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, _ => { }, _ => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, _ => { }, _ => { }, () => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default(Action<int>)));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default, () => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, _ => { }, default(Action)));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default, _ => { }, () => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, _ => { }, default, () => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, _ => { }, _ => { }, default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default, _ => { }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, _ => { }, default(Action<Exception>)));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(null, new MyObserver()));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Do<int>(new[] { 1 }, default(IObserver<int>)));
-        }
-
-        [Fact]
-        public void Do1()
-        {
-            var n = 0;
-            Enumerable.Range(0, 10).Do(x => n += x).ForEach(_ => { });
-            Assert.Equal(45, n);
-        }
-
-        [Fact]
-        public void Do2()
-        {
-            var n = 0;
-            Enumerable.Range(0, 10).Do(x => n += x, () => n *= 2).ForEach(_ => { });
-            Assert.Equal(90, n);
-        }
-
-        [Fact]
-        public void Do3()
-        {
-            var ex = new MyException();
-            var ok = false;
-            AssertThrows<MyException>(() =>
-                EnumerableEx.Throw<int>(ex).Do(x => { Assert.True(false); }, e => { Assert.Equal(ex, e); ok = true; }).ForEach(_ => { })
-            );
-            Assert.True(ok);
-        }
-
-        [Fact]
-        public void Do4()
-        {
-            var obs = new MyObserver();
-            Enumerable.Range(0, 10).Do(obs).ForEach(_ => { });
-
-            Assert.True(obs.Done);
-            Assert.Equal(45, obs.Sum);
-        }
-
-        private class MyObserver : IObserver<int>
-        {
-            public int Sum;
-            public bool Done;
-
-            public void OnCompleted()
-            {
-                Done = true;
-            }
-
-            public void OnError(Exception error)
-            {
-                throw new NotImplementedException();
-            }
-
-            public void OnNext(int value)
-            {
-                Sum += value;
-            }
-        }
-
-        [Fact]
-        public void Do5()
-        {
-            var sum = 0;
-            var done = false;
-            Enumerable.Range(0, 10).Do(x => sum += x, ex => { throw ex; }, () => done = true).ForEach(_ => { });
-
-            Assert.True(done);
-            Assert.Equal(45, sum);
-        }
-
-        [Fact]
-        public void StartWith_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.StartWith<int>(null, 5));
-        }
-
-        [Fact]
-        public void StartWith1()
-        {
-            var e = Enumerable.Range(1, 5);
-            var r = e.StartWith(0).ToList();
-            Assert.True(Enumerable.SequenceEqual(r, Enumerable.Range(0, 6)));
-        }
-
-        [Fact]
-        public void StartWith2()
-        {
-            var oops = false;
-            var e = Enumerable.Range(1, 5).Do(_ => oops = true);
-            var r = e.StartWith(0).Take(1).ToList();
-            Assert.False(oops);
-        }
-
-        [Fact]
-        public void Expand_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Expand<int>(null, _ => new[] { _ }));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Expand<int>(new[] { 1 }, null));
-        }
-
-        [Fact]
-        public void Expand1()
-        {
-            var res = new[] { 0 }.Expand(x => new[] { x + 1 }).Take(10).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, Enumerable.Range(0, 10)));
-        }
-
-        [Fact]
-        public void Expand2()
-        {
-            var res = new[] { 3 }.Expand(x => Enumerable.Range(0, x)).ToList();
-            var exp = new[] {
-                3,
-                0, 1, 2,
-                0,
-                0, 1,
-                0
-            };
-            Assert.True(Enumerable.SequenceEqual(res, exp));
-        }
-
-        [Fact]
-        public void Distinct_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(null, _ => _));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(new[] { 1 }, null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(null, _ => _, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(new[] { 1 }, null, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Distinct<int, int>(new[] { 1 }, _ => _, null));
-        }
-
-        [Fact]
-        public void Distinct1()
-        {
-            var res = Enumerable.Range(0, 10).Distinct(x => x % 5).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, Enumerable.Range(0, 5)));
-        }
-
-        [Fact]
-        public void Distinct2()
-        {
-            var res = Enumerable.Range(0, 10).Distinct(x => x % 5, new MyEqualityComparer()).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 0, 1 }));
-        }
-
-        private class MyEqualityComparer : IEqualityComparer<int>
-        {
-            public bool Equals(int x, int y)
-            {
-                return x % 2 == y % 2;
-            }
-
-            public int GetHashCode(int obj)
-            {
-                return EqualityComparer<int>.Default.GetHashCode(obj % 2);
-            }
-        }
-
-        [Fact]
-        public void DistinctUntilChanged_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int>(null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int>(null, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int>(new[] { 1 }, null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(null, _ => _));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(new[] { 1 }, null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(null, _ => _, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(new[] { 1 }, null, EqualityComparer<int>.Default));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.DistinctUntilChanged<int, int>(new[] { 1 }, _ => _, null));
-        }
-
-        [Fact]
-        public void DistinctUntilChanged1()
-        {
-            var res = new[] { 1, 2, 2, 3, 3, 3, 2, 2, 1 }.DistinctUntilChanged().ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 3, 2, 1 }));
-        }
-
-        [Fact]
-        public void DistinctUntilChanged2()
-        {
-            var res = new[] { 1, 1, 2, 3, 4, 5, 5, 6, 7 }.DistinctUntilChanged(x => x / 2).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 2, 4, 6 }));
-        }
-
-        [Fact]
-        public void IgnoreElements_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.IgnoreElements<int>(null));
-        }
-
-        [Fact]
-        public void IgnoreElements()
-        {
-            var n = 0;
-            Enumerable.Range(0, 10).Do(_ => n++).IgnoreElements().Take(5).ForEach(_ => { });
-            Assert.Equal(10, n);
-        }
-
-        [Fact]
-        public void TakeLast_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.TakeLast<int>(null, 5));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.TakeLast<int>(new[] { 1 }, -1));
-        }
-
-        [Fact]
-        public void TakeLast_TakeZero()
-        {
-            var e = Enumerable.Range(1, 5);
-#if NETCOREAPP2_1 || WINDOWS_UWP
-            var r = EnumerableEx.TakeLast(e, 0).ToList();
-#else
-            var r = e.TakeLast(0).ToList();
-#endif
-            Assert.True(Enumerable.SequenceEqual(r, Enumerable.Empty<int>()));
-        }
-
-        [Fact]
-        public void TakeLast_Empty()
-        {
-            var e = Enumerable.Empty<int>();
-
-#if NETCOREAPP2_1 || WINDOWS_UWP
-            var r = EnumerableEx.TakeLast(e, 1).ToList();
-#else
-            var r = e.TakeLast(1).ToList();
-#endif
-            Assert.True(Enumerable.SequenceEqual(r, e));
-        }
-
-        [Fact]
-        public void TakeLast_All()
-        {
-            var e = Enumerable.Range(0, 5);
-
-#if NETCOREAPP2_1 || WINDOWS_UWP
-            var r = EnumerableEx.TakeLast(e, 5).ToList();
-#else
-            var r = e.TakeLast(5).ToList();
-#endif
-
-            Assert.True(Enumerable.SequenceEqual(r, e));
-        }
-
-        [Fact]
-        public void TakeLast_Part()
-        {
-            var e = Enumerable.Range(0, 5);
-#if NETCOREAPP2_1 || WINDOWS_UWP
-            var r = EnumerableEx.TakeLast(e, 3).ToList();
-#else
-            var r = e.TakeLast(3).ToList();
-#endif
-            Assert.True(Enumerable.SequenceEqual(r, e.Skip(2)));
-        }
-
-        [Fact]
-        public void SkipLast_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.SkipLast<int>(null, 5));
-            AssertThrows<ArgumentOutOfRangeException>(() => EnumerableEx.SkipLast<int>(new[] { 1 }, -1));
-        }
-
-        [Fact]
-        public void SkipLast_Empty()
-        {
-            var e = Enumerable.Empty<int>();
-#if NETCOREAPP2_1 || WINDOWS_UWP
-            var r = EnumerableEx.SkipLast(e, 1).ToList();
-#else
-            var r = e.SkipLast(1).ToList();
-#endif
-            Assert.True(Enumerable.SequenceEqual(r, e));
-        }
-
-        [Fact]
-        public void SkipLast_All()
-        {
-            var e = Enumerable.Range(0, 5);
-#if NETCOREAPP2_1 || WINDOWS_UWP
-            var r = EnumerableEx.SkipLast(e, 0).ToList();
-#else
-            var r = e.SkipLast(0).ToList();
-#endif
-            Assert.True(Enumerable.SequenceEqual(r, e));
-        }
-
-        [Fact]
-        public void SkipLast_Part()
-        {
-            var e = Enumerable.Range(0, 5);
-#if NETCOREAPP2_1 || WINDOWS_UWP
-            var r = EnumerableEx.SkipLast(e, 3).ToList();
-#else
-            var r = e.SkipLast(3).ToList();
-#endif
-            Assert.True(Enumerable.SequenceEqual(r, e.Take(2)));
-        }
-
-        [Fact]
-        public void Scan_Arguments()
-        {
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Scan<int>(null, (x, y) => x + y));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Scan<int>(new[] { 1 }, null));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Scan<int, int>(null, 0, (x, y) => x + y));
-            AssertThrows<ArgumentNullException>(() => EnumerableEx.Scan<int, int>(new[] { 1 }, 0, null));
-        }
-
-        [Fact]
-        public void Scan1()
-        {
-            var res = Enumerable.Range(0, 5).Scan((n, x) => n + x).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 1, 3, 6, 10 }));
-        }
-
-        [Fact]
-        public void Scan2()
-        {
-            var res = Enumerable.Range(0, 5).Scan(10, (n, x) => n - x).ToList();
-            Assert.True(Enumerable.SequenceEqual(res, new[] { 10, 9, 7, 4, 0 }));
-        }
-    }
-}

+ 1 - 1
Ix.NET/Source/System.Interactive.Tests/Tests.cs

@@ -9,7 +9,7 @@ using Xunit;
 namespace Tests
 {
 
-    public partial class Tests
+    public class Tests
     {
 #pragma warning disable xUnit1013 // Public method should be marked as test
         public void AssertThrows<E>(Action a)

+ 31 - 0
Ix.NET/Source/System.Interactive.Tests/ThrowTest.cs

@@ -0,0 +1,31 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class ThrowTest : Tests
+    {
+        [Fact]
+        public void Throw_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Throw<int>(null));
+        }
+
+        [Fact]
+        public void Throw()
+        {
+            var ex = new MyException();
+            var xs = EnumerableEx.Throw<int>(ex);
+
+            var e = xs.GetEnumerator();
+            AssertThrows<MyException>(() => e.MoveNext());
+        }
+    }
+}

+ 75 - 0
Ix.NET/Source/System.Interactive.Tests/UsingTest.cs

@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class UsingTest : Tests
+    {
+        [Fact]
+        public void Using_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Using<int, MyDisposable>(null, d => new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.Using<int, MyDisposable>(() => new MyDisposable(), null));
+        }
+
+        [Fact]
+        public void Using1()
+        {
+            var d = default(MyDisposable);
+
+            var xs = EnumerableEx.Using(() => d = new MyDisposable(), d_ => new[] { 1 });
+            Assert.Null(d);
+
+            var d1 = default(MyDisposable);
+            xs.ForEach(_ => { d1 = d; Assert.NotNull(d1); Assert.False(d1.Done); });
+            Assert.True(d1.Done);
+
+            var d2 = default(MyDisposable);
+            xs.ForEach(_ => { d2 = d; Assert.NotNull(d2); Assert.False(d2.Done); });
+            Assert.True(d2.Done);
+
+            Assert.NotSame(d1, d2);
+        }
+
+        [Fact]
+        public void Using2()
+        {
+            var d = default(MyDisposable);
+
+            var xs = EnumerableEx.Using(() => d = new MyDisposable(), d_ => EnumerableEx.Throw<int>(new MyException()));
+            Assert.Null(d);
+
+            AssertThrows<MyException>(() => xs.ForEach(_ => { }));
+            Assert.True(d.Done);
+        }
+
+        [Fact]
+        public void Using3()
+        {
+            var d = default(MyDisposable);
+
+            var xs = EnumerableEx.Using<int, MyDisposable>(() => d = new MyDisposable(), d_ => { throw new MyException(); });
+            Assert.Null(d);
+
+            AssertThrows<MyException>(() => xs.ForEach(_ => { }));
+            Assert.True(d.Done);
+        }
+
+        private class MyDisposable : IDisposable
+        {
+            public bool Done;
+
+            public void Dispose()
+            {
+                Done = true;
+            }
+        }
+    }
+}

+ 38 - 0
Ix.NET/Source/System.Interactive.Tests/WhileTest.cs

@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using Xunit;
+
+namespace Tests
+{
+    public class WhileTest : Tests
+    {
+        [Fact]
+        public void While_Arguments()
+        {
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.While<int>(null, new[] { 1 }));
+            AssertThrows<ArgumentNullException>(() => EnumerableEx.While<int>(() => true, null));
+        }
+
+        [Fact]
+        public void While1()
+        {
+            var x = 5;
+            var res = EnumerableEx.While(() => x > 0, EnumerableEx.Defer(() => new[] { x }).Do(_ => x--)).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new[] { 5, 4, 3, 2, 1 }));
+        }
+
+        [Fact]
+        public void While2()
+        {
+            var x = 0;
+            var res = EnumerableEx.While(() => x > 0, EnumerableEx.Defer(() => new[] { x }).Do(_ => x--)).ToList();
+            Assert.True(Enumerable.SequenceEqual(res, new int[0]));
+        }
+    }
+}