using Upsilon.BaseTypes; using Upsilon.BaseTypes.Number; using Upsilon.Evaluator; using Xunit; namespace UpsilonTests { public class FunctionTests { [Fact] public void BasicFunctionTest() { const string input = @" function testFunc () a = 100 end a = 50 testFunc() "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); Assert.True(script.Scope.TryGet("testFunc", out var func)); Assert.IsType(func); Assert.True(script.Scope.TryGet("a", out var a)); Assert.Equal(100, (long)(NumberLong)a); } [Fact] public void ParameterTest() { const string input = @" function testFunc (var1) a = var1 end a = 50 testFunc(100) "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); Assert.True(script.Scope.TryGet("testFunc", out var func)); Assert.IsType(func); Assert.True(script.Scope.TryGet("a", out var a)); Assert.Equal(100, (long)(NumberLong)a); } [Fact] public void ParameterBindTest() { const string input = @" function testFunc (var1) var1 == true end testFunc(100) "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Single(script.Diagnostics.Messages); Assert.True(script.Scope.TryGet("testFunc", out var func)); Assert.IsType(func); } [Fact] public void BindUnusedFunctions() { const string input = @" function testFunc (var1) var1 == true end "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); Assert.True(script.Scope.TryGet("testFunc", out var func)); var castType = Assert.IsType(func); Assert.NotNull(castType.Block); } [Fact] public void ReturnFromFunction() { const string input = @" function testFunc () return 5 end a = testFunc() "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); Assert.True(script.Scope.TryGet("a", out var result)); Assert.Equal(5, (long)(NumberLong)result); } [Fact] public void ReturnFromFunctionOnce() { const string input = @" function testFunc () return 5 return 10 end a = testFunc() "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); Assert.True(script.Scope.TryGet("a", out var result)); Assert.Equal(5, (long)(NumberLong)result); } [Fact] public void ReturnFromFunctionNested() { const string input = @" function testFunc () if true then return 5 end return 10 end a = testFunc() "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); Assert.True(script.Scope.TryGet("a", out var result)); Assert.Equal(5, (long)(NumberLong)result); } [Fact] public void ReturnFromScriptAsFunction() { const string input = @" a = 100 return 60 a = 87 "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); var result = script.Evaluate(); Assert.Empty(script.Diagnostics.Messages); Assert.Equal(60, (long)(NumberLong)result); } [Fact] public void ReturnFromCSharpCall() { const string input = @" function testFunc () return 100 end "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); var result = script.EvaluateFunction("testFunc"); Assert.Empty(script.Diagnostics.Messages); Assert.Equal(100, (long)result); } [Fact] public void ReturnFromCSharpCallWithParameter() { const string input = @" function testFunc (b) if b then return 100 else return 50 end end "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); var result = script.EvaluateFunction("testFunc", new object[] {true}); Assert.Empty(script.Diagnostics.Messages); Assert.Equal(100, (long)result); var result2 = script.EvaluateFunction("testFunc", new object[] {false}); Assert.Empty(script.Diagnostics.Messages); Assert.Equal(50, (long)result2); } [Fact] public void ReturnFromCSharpCallWithParameters() { const string input = @" function add (a, b) return a + b end "; var script = new Script(input); Assert.Empty(script.Diagnostics.Messages); var result = script.EvaluateFunction("add", new object[] {400, 128}); Assert.Empty(script.Diagnostics.Messages); Assert.Equal(528, (long)result); } } }