diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/Text.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/Text.cs index 4bec9d0..0da3a1a 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/Text.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/CalcEngine/Functions/Text.cs @@ -78,12 +78,15 @@ } static object Left(List p) { + var str = (string)p[0]; var n = 1; if (p.Count > 1) { n = (int)p[1]; } - return ((string)p[0]).Substring(0, n); + if (n >= str.Length) return str; + + return str.Substring(0, n); } static object Len(List p) { @@ -95,7 +98,14 @@ } static object Mid(List p) { - return ((string)p[0]).Substring((int)p[1] - 1, (int)p[2]); + var str = (string)p[0]; + var start = (int)p[1] - 1; + var length = (int)p[2]; + if (start > str.Length - 1) + return String.Empty; + if (start + length > str.Length - 1) + return str.Substring(start); + return str.Substring(start, length); } static object Proper(List p) { @@ -129,13 +139,16 @@ } static object Right(List p) { + var str = (string)p[0]; var n = 1; if (p.Count > 1) { n = (int)p[1]; } - var s = (string)p[0]; - return s.Substring(s.Length - n); + + if (n >= str.Length) return str; + + return str.Substring(str.Length - n); } static object Search(List p) { diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/ClosedXML_Tests.csproj b/ClosedXML/ClosedXML/ClosedXML_Tests/ClosedXML_Tests.csproj index 2c0741b..3872960 100644 --- a/ClosedXML/ClosedXML/ClosedXML_Tests/ClosedXML_Tests.csproj +++ b/ClosedXML/ClosedXML/ClosedXML_Tests/ClosedXML_Tests.csproj @@ -114,6 +114,7 @@ + diff --git a/ClosedXML/ClosedXML/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs b/ClosedXML/ClosedXML/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs new file mode 100644 index 0000000..ebb55e9 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML_Tests/Excel/CalcEngine/TextTests.cs @@ -0,0 +1,96 @@ +using System; +using ClosedXML.Excel; +using NUnit.Framework; + +namespace ClosedXML_Tests.Excel.CalcEngine +{ + [TestFixture] + public class TextTests + { + [Test] + public void Left_Default() + { + Object actual = XLWorkbook.EvaluateExpr(@"Left(""ABC"")"); + Assert.AreEqual("A", actual); + } + + [Test] + public void Left_Value() + { + Object actual = XLWorkbook.EvaluateExpr(@"Left(""ABC"", 2)"); + Assert.AreEqual("AB", actual); + } + + [Test] + public void Left_BiggerThanLength() + { + Object actual = XLWorkbook.EvaluateExpr(@"Left(""ABC"", 5)"); + Assert.AreEqual("ABC", actual); + } + + [Test] + public void Left_Empty() + { + Object actual = XLWorkbook.EvaluateExpr(@"Left("""")"); + Assert.AreEqual("", actual); + } + + [Test] + public void Right_Default() + { + Object actual = XLWorkbook.EvaluateExpr(@"Right(""ABC"")"); + Assert.AreEqual("C", actual); + } + + [Test] + public void Right_Value() + { + Object actual = XLWorkbook.EvaluateExpr(@"Right(""ABC"", 2)"); + Assert.AreEqual("BC", actual); + } + + [Test] + public void Right_BiggerThanLength() + { + Object actual = XLWorkbook.EvaluateExpr(@"Right(""ABC"", 5)"); + Assert.AreEqual("ABC", actual); + } + + [Test] + public void Right_Empty() + { + Object actual = XLWorkbook.EvaluateExpr(@"Right("""")"); + Assert.AreEqual("", actual); + } + + + + [Test] + public void Mid_Value() + { + Object actual = XLWorkbook.EvaluateExpr(@"Mid(""ABC"", 2, 2)"); + Assert.AreEqual("BC", actual); + } + + [Test] + public void Mid_BiggerThanLength() + { + Object actual = XLWorkbook.EvaluateExpr(@"Mid(""ABC"", 1, 5)"); + Assert.AreEqual("ABC", actual); + } + + [Test] + public void Mid_StartAfter() + { + Object actual = XLWorkbook.EvaluateExpr(@"Mid(""ABC"", 5, 5)"); + Assert.AreEqual("", actual); + } + + [Test] + public void Mid_Empty() + { + Object actual = XLWorkbook.EvaluateExpr(@"Mid("""", 1, 1)"); + Assert.AreEqual("", actual); + } + } +} \ No newline at end of file