using System; using System.Collections; using System.Collections.Generic; using Upsilon; using Upsilon.BaseTypes.UserData; using Xunit; namespace UpsilonTests.GeneralTests { public class CoroutineTests { [Fact] public void BasicCoroutineTest() { const string input = @" coroutine testCoroutine() yield 5 yield 1000 yield ""test"" yield nil end "; var coroutine = Executor.EvaluateFunctionCoroutine(input, "testCoroutine"); var count = 0; while (coroutine.MoveNext()) { var value = coroutine.Current; switch (count) { case 0: Assert.Equal(5L, value); break; case 1: Assert.Equal(1000L, value); break; case 2: Assert.Equal("test", value); break; case 3: Assert.Null(value); break; } count++; } Assert.Equal(4, count); } [Fact] public void EmptyCoroutineTest() { const string input = @" coroutine testCoroutine() end "; var coroutine = Executor.EvaluateFunctionCoroutine(input, "testCoroutine"); var count = 0; while (coroutine.MoveNext()) { count++; } Assert.Equal(0, count); } [Fact] public void NestedCoroutineTest() { const string input = @" coroutine testCoroutine() for i = 0, 9 do yield nil end end "; var coroutine = Executor.EvaluateFunctionCoroutine(input, "testCoroutine"); var count = 0; var objArray = new List(); while (coroutine.MoveNext()) { objArray.Add(coroutine.Current); count++; } Assert.Equal(10, count); Assert.All(objArray, Assert.Null); } [Theory] [InlineData(9)] [InlineData(20)] [InlineData(2)] public void FunctionNestedCoroutine(int max) { var input = @" coroutine lowerCoroutine(number max) for i = 0, max do yield nil end end coroutine testCoroutine() yield lowerCoroutine(" + max + @") end "; var coroutine = Executor.EvaluateFunctionCoroutine(input, "testCoroutine"); var count = 0; var objArray = new List(); while (coroutine.MoveNext()) { objArray.Add(coroutine.Current); count++; } Assert.Equal(max + 1, count); Assert.All(objArray, Assert.Null); } [Fact] public void CoroutineReturnTest() { const string input = @" coroutine testCoroutine() yield 5 yield 1000 return yield ""test"" yield nil end "; var coroutine = Executor.EvaluateFunctionCoroutine(input, "testCoroutine"); var count = 0; while (coroutine.MoveNext()) { var value = coroutine.Current; switch (count) { case 0: Assert.Equal(5L, value); break; case 1: Assert.Equal(1000L, value); break; } count++; } Assert.Equal(2, count); } public class TestClass { public IEnumerator TestCoroutine() { yield return 5L; yield return 1000L; } } [Fact] public void CSharpCoroutineCallTest() { UserDataTypeHandler.LoadType(); const string input = @" coroutine testCoroutine(enumerator) yield enumerator.TestCoroutine() end "; var coroutine = Executor.EvaluateFunctionCoroutine(input, "testCoroutine", new[] {new TestClass()}); var count = 0; while (coroutine.MoveNext()) { var value = coroutine.Current; switch (count) { case 0: Assert.Equal(5L, value); break; case 1: Assert.Equal(1000L, value); break; } count++; } Assert.Equal(2, count); } } }