diff --git a/main/SS/Formula/Eval/OperandResolver.cs b/main/SS/Formula/Eval/OperandResolver.cs
index 58fab3914..992f2dbe1 100644
--- a/main/SS/Formula/Eval/OperandResolver.cs
+++ b/main/SS/Formula/Eval/OperandResolver.cs
@@ -30,9 +30,9 @@ public class OperandResolver
{
// Based on regular expression defined in JavaDoc at {@link java.lang.Double#valueOf}
// modified to remove support for NaN, Infinity, Hexadecimal support and floating type suffixes
- private const string Digits = "\\d+";
- private const string Exp = "[eE][+-]?" + Digits;
- private const string fpRegex =
+ private const String Digits = "\\d+";
+ private const String Exp = "[eE][+-]?" + Digits;
+ private const String fpRegex =
("[\\x00-\\x20]*" +
"[+-]?(" +
"(((" + Digits + "(\\.)?(" + Digits + "?)(" + Exp + ")?)|" +
@@ -58,21 +58,21 @@ private OperandResolver()
public static ValueEval GetSingleValue(ValueEval arg, int srcCellRow, int srcCellCol)
{
ValueEval result;
- if (arg is RefEval rev)
+ if (arg is RefEval)
{
- result = ChooseSingleElementFromRef(rev);
+ result = ChooseSingleElementFromRef((RefEval)arg);
}
- else if (arg is AreaEval aev)
+ else if (arg is AreaEval)
{
- result = ChooseSingleElementFromArea(aev, srcCellRow, srcCellCol);
+ result = ChooseSingleElementFromArea((AreaEval)arg, srcCellRow, srcCellCol);
}
else
{
result = arg;
}
- if (result is ErrorEval eva)
+ if (result is ErrorEval)
{
- throw new EvaluationException(eva);
+ throw new EvaluationException((ErrorEval)result);
}
return result;
}
@@ -126,9 +126,9 @@ public static ValueEval ChooseSingleElementFromArea(AreaEval ae,
{
ValueEval result = ChooseSingleElementFromAreaInternal(ae, srcCellRow, srcCellCol);
- if (result is ErrorEval eva)
+ if (result is ErrorEval)
{
- throw new EvaluationException(eva);
+ throw new EvaluationException((ErrorEval)result);
}
return result;
@@ -236,14 +236,14 @@ public static double CoerceValueToDouble(ValueEval ev)
{
return 0.0;
}
- if (ev is NumericValueEval nve)
+ if (ev is NumericValueEval)
{
// this also handles bools
- return nve.NumberValue;
+ return ((NumericValueEval)ev).NumberValue;
}
- if (ev is StringEval sev)
+ if (ev is StringEval)
{
- double dd = ParseDouble(sev.StringValue);
+ double dd = ParseDouble(((StringEval)ev).StringValue);
if (double.IsNaN(dd))
{
throw EvaluationException.InvalidValue();
@@ -269,29 +269,64 @@ public static double CoerceValueToDouble(ValueEval ev)
* @param text
* @return null if the specified text cannot be Parsed as a number
*/
- public static double ParseDouble(string pText)
+ public static double ParseDouble(String pText)
{
- try
- {
- double ret = double.Parse(pText, CultureInfo.CurrentCulture);
- if (double.IsInfinity(ret))
- return double.NaN;
- return ret;
- }
- catch
+ //if (Regex.Match(fpRegex, pText).Success)
+ try
+ {
+ double ret = double.Parse(pText, CultureInfo.CurrentCulture);
+ if (double.IsInfinity(ret))
+ return double.NaN;
+ return ret;
+ }
+ catch
+ {
+ return Double.NaN;
+ }
+ //else
{
- return double.NaN;
+ //return Double.NaN;
}
+ //String text = pText.Trim();
+ //if (text.Length < 1)
+ //{
+ // return double.NaN;
+ //}
+ //bool isPositive = true;
+ //if (text[0] == '-')
+ //{
+ // isPositive = false;
+ // text = text.Substring(1).Trim();
+ //}
+
+ //if (text.Length == 0 || !Char.IsDigit(text[0]))
+ //{
+ // // avoid using Exception to tell when string is not a number
+ // return double.NaN;
+ //}
+ //// TODO - support notation like '1E3' (==1000)
+
+ //double val;
+ //try
+ //{
+ // val = double.Parse(text);
+ //}
+ //catch
+ //{
+ // return double.NaN;
+ //}
+ //return isPositive ? +val : -val;
}
/**
* @param ve must be a NumberEval, StringEval, BoolEval, or BlankEval
* @return the Converted string value. never null
*/
- public static string CoerceValueToString(ValueEval ve)
+ public static String CoerceValueToString(ValueEval ve)
{
- if (ve is StringValueEval sve)
+ if (ve is StringValueEval)
{
+ StringValueEval sve = (StringValueEval)ve;
return sve.StringValue;
}
@@ -301,12 +336,11 @@ public static string CoerceValueToString(ValueEval ve)
}
throw new ArgumentException("Unexpected eval class (" + ve.GetType().Name + ")");
}
-
/**
- * @return null to represent blank values
- * @throws EvaluationException if ve is an ErrorEval, or if a string value cannot be converted
- */
- public static bool? CoerceValueToBoolean(ValueEval ve, bool stringsAreBlanks)
+ * @return null to represent blank values
+ * @throws EvaluationException if ve is an ErrorEval, or if a string value cannot be converted
+ */
+ public static Boolean? CoerceValueToBoolean(ValueEval ve, bool stringsAreBlanks)
{
if (ve == null || ve == BlankEval.instance)
@@ -314,18 +348,18 @@ public static string CoerceValueToString(ValueEval ve)
// TODO - remove 've == null' condition once AreaEval is fixed
return null;
}
- if (ve is BoolEval be)
+ if (ve is BoolEval)
{
- return be.BooleanValue;
+ return ((BoolEval)ve).BooleanValue;
}
- if (ve is StringEval se)
+ if (ve is StringEval)
{
if (stringsAreBlanks)
{
return null;
}
- string str = se.StringValue;
+ String str = ((StringEval)ve).StringValue;
if (str.Equals("true", StringComparison.OrdinalIgnoreCase))
{
return true;
@@ -338,31 +372,32 @@ public static string CoerceValueToString(ValueEval ve)
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
- if(ve is NumericValueEval ne)
+ if (ve is NumericValueEval)
{
+ NumericValueEval ne = (NumericValueEval)ve;
double d = ne.NumberValue;
- if(double.IsNaN(d))
+ if (Double.IsNaN(d))
{
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
return d != 0;
}
- if (ve is ErrorEval ee)
+ if (ve is ErrorEval)
{
- throw new EvaluationException(ee);
+ throw new EvaluationException((ErrorEval)ve);
}
throw new InvalidOperationException("Unexpected eval (" + ve.GetType().Name + ")");
}
-
/**
- * Retrieves a single value from an area evaluation utilizing the 2D indices of the cell
- * within its own area reference to index the value in the area evaluation.
- *
- * @param ae area reference after evaluation
- * @param cell the source cell of the formula that contains its 2D indices
- * @return a NumberEval, StringEval, BoolEval or BlankEval. or ErrorEval
- * Never null.
- */
+ * Retrieves a single value from an area evaluation utilizing the 2D indices of the cell
+ * within its own area reference to index the value in the area evaluation.
+ *
+ * @param ae area reference after evaluation
+ * @param cell the source cell of the formula that contains its 2D indices
+ * @return a NumberEval, StringEval, BoolEval or BlankEval. or ErrorEval
+ * Never null.
+ */
+
public static ValueEval GetElementFromArray(AreaEval ae, IEvaluationCell cell)
{
CellRangeAddress range = cell.ArrayFormulaRange;
diff --git a/main/SS/Formula/Eval/StringEval.cs b/main/SS/Formula/Eval/StringEval.cs
index 85688b585..ef776c3ee 100644
--- a/main/SS/Formula/Eval/StringEval.cs
+++ b/main/SS/Formula/Eval/StringEval.cs
@@ -30,23 +30,27 @@ public class StringEval : StringValueEval
{
public static readonly StringEval EMPTY_INSTANCE = new StringEval("");
- private readonly string value;
+ private String value;
public StringEval(Ptg ptg):this(((StringPtg)ptg).Value)
{
}
- public StringEval(string value)
+ public StringEval(String value)
{
- this.value = value ?? throw new ArgumentException("value must not be null");
+ if (value == null)
+ {
+ throw new ArgumentException("value must not be null");
+ }
+ this.value = value;
}
- public string StringValue
+ public String StringValue
{
get { return value; }
}
- public override string ToString()
+ public override String ToString()
{
StringBuilder sb = new StringBuilder(64);
sb.Append(GetType().Name).Append(" [");
diff --git a/main/SS/Formula/Functions/Text/Exact.cs b/main/SS/Formula/Functions/Text/Exact.cs
index 40d132ea0..d91100f6f 100644
--- a/main/SS/Formula/Functions/Text/Exact.cs
+++ b/main/SS/Formula/Functions/Text/Exact.cs
@@ -38,8 +38,8 @@ public override ValueEval EvaluateFunc(ValueEval[] args, int srcCellRow, int src
return ErrorEval.VALUE_INVALID;
}
- string s0 = EvaluateStringArg(args[0], srcCellRow, srcCellCol);
- string s1 = EvaluateStringArg(args[1], srcCellRow, srcCellCol);
+ String s0 = EvaluateStringArg(args[0], srcCellRow, srcCellCol);
+ String s1 = EvaluateStringArg(args[1], srcCellRow, srcCellCol);
return BoolEval.ValueOf(s0.Equals(s1));
}
}
diff --git a/main/SS/Formula/Functions/Text/Text.cs b/main/SS/Formula/Functions/Text/Text.cs
index c57efa56f..d172c3543 100644
--- a/main/SS/Formula/Functions/Text/Text.cs
+++ b/main/SS/Formula/Functions/Text/Text.cs
@@ -14,99 +14,122 @@ namespace NPOI.SS.Formula.Functions
*/
public class Text : Fixed2ArgFunction
{
- public static DataFormatter Formatter { get; set; } = new();
-
- ///
- /// An implementation of the TEXT function
- /// TEXT returns a number value formatted with the given number formatting string.
- /// This function is not a complete implementation of the Excel function, but
- /// handles most of the common cases. All work is passed down to
- /// to be done, as this works much the same as the
- /// display focused work that does.
- ///
- ///
- ///
- ///
- ///
- ///
+ public static DataFormatter Formatter = new DataFormatter();
public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1)
{
- ValueEval valueEval;
-
+ if (arg0 is StringEval) return arg0;
+
+ double s0;
+ String s1;
try
{
- ValueEval valueVe = OperandResolver.GetSingleValue(arg0, srcRowIndex, srcColumnIndex);
- ValueEval formatVe = OperandResolver.GetSingleValue(arg1, srcRowIndex, srcColumnIndex);
-
- try
- {
- double valueDouble = double.NaN;
- string evaluated = null;
-
- if (valueVe == BlankEval.instance)
- {
- valueDouble = 0.0;
- }
- else if (valueVe is BoolEval boolEval)
- {
- evaluated = boolEval.StringValue;
- }
- else if (valueVe is NumericValueEval numericEval)
- {
- valueDouble = numericEval.NumberValue;
-
- }
- else if (valueVe is StringEval stringEval)
- {
- evaluated = stringEval.StringValue;
- valueDouble = OperandResolver.ParseDouble(evaluated);
- }
-
- if(!double.IsNaN(valueDouble))
- {
- string format = FormatPatternValueEval2String(formatVe);
- evaluated = Formatter.FormatRawCellContents(valueDouble, -1, format);
- }
-
- valueEval = new StringEval(evaluated);
- }
- catch(Exception)
- {
- valueEval = ErrorEval.VALUE_INVALID;
- }
+ s0 = TextFunction.EvaluateDoubleArg(arg0, srcRowIndex, srcColumnIndex);
+ s1 = TextFunction.EvaluateStringArg(arg1, srcRowIndex, srcColumnIndex);
}
- catch(EvaluationException e)
+ catch (EvaluationException e)
{
- valueEval = e.GetErrorEval();
+ return e.GetErrorEval();
}
-
- return valueEval;
- }
-
- ///
- /// Using it instead of in order to handle booleans differently.
- ///
- ///
- /// Pattern value eval formatted to string
- ///
- private string FormatPatternValueEval2String(ValueEval ve)
- {
- string format;
-
- if (ve is not BoolEval && ve is StringValueEval sve)
- {
- format = sve.StringValue;
- }
- else if (ve == BlankEval.instance)
+ try
{
- format = "";
+ // Ask DataFormatter to handle the String for us
+ String formattedStr = Formatter.FormatRawCellContents(s0, -1, s1);
+ return new StringEval(formattedStr);
}
- else
+ catch
{
- throw new ArgumentException("Unexpected eval class (" + ve.GetType().Name + ")");
+ return ErrorEval.VALUE_INVALID;
}
-
- return format;
+ //if (Regex.Match(s1, "[y|m|M|d|s|h]+").Success)
+ //{
+ // //may be datetime string
+ // ValueEval result = TryParseDateTime(s0, s1);
+ // if (result != ErrorEval.VALUE_INVALID)
+ // return result;
+ //}
+ ////The regular expression needs ^ and $.
+ //if (Regex.Match(s1, @"^[\d,\#,\.,\$,\,]+$").Success)
+ //{
+ // //TODO: simulate DecimalFormat class in java.
+ // FormatBase formatter = new DecimalFormat(s1);
+ // return new StringEval(formatter.Format(s0, CultureInfo.CurrentCulture));
+ //}
+ //else if (s1.IndexOf("/", StringComparison.Ordinal) == s1.LastIndexOf("/", StringComparison.Ordinal) && s1.IndexOf("/", StringComparison.Ordinal) >= 0 && !s1.Contains("-"))
+ //{
+ // double wholePart = Math.Floor(s0);
+ // double decPart = s0 - wholePart;
+ // if (wholePart * decPart == 0)
+ // {
+ // return new StringEval("0");
+ // }
+ // String[] parts = s1.Split(' ');
+ // String[] fractParts;
+ // if (parts.Length == 2)
+ // {
+ // fractParts = parts[1].Split('/');
+ // }
+ // else
+ // {
+ // fractParts = s1.Split('/');
+ // }
+
+ // if (fractParts.Length == 2)
+ // {
+ // double minVal = 1.0;
+ // double currDenom = Math.Pow(10, fractParts[1].Length) - 1d;
+ // double currNeum = 0;
+ // for (int i = (int)(Math.Pow(10, fractParts[1].Length) - 1d); i > 0; i--)
+ // {
+ // for (int i2 = (int)(Math.Pow(10, fractParts[1].Length) - 1d); i2 > 0; i2--)
+ // {
+ // if (minVal >= Math.Abs((double)i2 / (double)i - decPart))
+ // {
+ // currDenom = i;
+ // currNeum = i2;
+ // minVal = Math.Abs((double)i2 / (double)i - decPart);
+ // }
+ // }
+ // }
+ // FormatBase neumFormatter = new DecimalFormat(fractParts[0]);
+ // FormatBase denomFormatter = new DecimalFormat(fractParts[1]);
+ // if (parts.Length == 2)
+ // {
+ // FormatBase wholeFormatter = new DecimalFormat(parts[0]);
+ // String result = wholeFormatter.Format(wholePart, CultureInfo.CurrentCulture) + " " + neumFormatter.Format(currNeum, CultureInfo.CurrentCulture) + "/" + denomFormatter.Format(currDenom, CultureInfo.CurrentCulture);
+ // return new StringEval(result);
+ // }
+ // else
+ // {
+ // String result = neumFormatter.Format(currNeum + (currDenom * wholePart), CultureInfo.CurrentCulture) + "/" + denomFormatter.Format(currDenom, CultureInfo.CurrentCulture);
+ // return new StringEval(result);
+ // }
+ // }
+ // else
+ // {
+ // return ErrorEval.VALUE_INVALID;
+ // }
+ //}
+ //else
+ //{
+ // return TryParseDateTime(s0, s1);
+ //}
}
+ //private ValueEval TryParseDateTime(double s0, string s1)
+ //{
+ // try
+ // {
+ // FormatBase dateFormatter = new SimpleDateFormat(s1);
+ // //first month of java Gregorian Calendar month field is 0
+ // DateTime dt = new DateTime(1899, 12, 30, 0, 0, 0);
+ // dt = dt.AddDays((int)Math.Floor(s0));
+ // double dayFraction = s0 - Math.Floor(s0);
+ // dt = dt.AddMilliseconds((int)Math.Round(dayFraction * 24 * 60 * 60 * 1000));
+ // return new StringEval(dateFormatter.Format(dt, CultureInfo.CurrentCulture));
+ // }
+ // catch (Exception)
+ // {
+ // return ErrorEval.VALUE_INVALID;
+ // }
+ //}
}
}
diff --git a/main/SS/Formula/Functions/Text/TextFunction.cs b/main/SS/Formula/Functions/Text/TextFunction.cs
index 6489614de..bbbd0f264 100644
--- a/main/SS/Formula/Functions/Text/TextFunction.cs
+++ b/main/SS/Formula/Functions/Text/TextFunction.cs
@@ -36,10 +36,10 @@ public override ValueEval EvaluateFunc(ValueEval[] args, int srcCellRow, int src
{
return ErrorEval.VALUE_INVALID;
}
- string arg = EvaluateStringArg(args[0], srcCellRow, srcCellCol);
+ String arg = EvaluateStringArg(args[0], srcCellRow, srcCellCol);
return Evaluate(arg);
}
- public abstract ValueEval Evaluate(string arg);
+ public abstract ValueEval Evaluate(String arg);
}
/**
@@ -47,9 +47,10 @@ public override ValueEval EvaluateFunc(ValueEval[] args, int srcCellRow, int src
*/
public abstract class TextFunction : Function
{
- protected static string EMPTY_STRING = "";
- public static string EvaluateStringArg(ValueEval eval, int srcRow, int srcCol)
+ protected static String EMPTY_STRING = "";
+
+ public static String EvaluateStringArg(ValueEval eval, int srcRow, int srcCol)
{
ValueEval ve = OperandResolver.GetSingleValue(eval, srcRow, srcCol);
return OperandResolver.CoerceValueToString(ve);
@@ -77,7 +78,8 @@ public ValueEval Evaluate(ValueEval[] args, int srcCellRow, int srcCellCol)
}
internal static bool IsPrintable(char c)
{
- return c >= 32;
+ int charCode = (int)c;
+ return charCode >= 32;
}
public abstract ValueEval EvaluateFunc(ValueEval[] args, int srcCellRow, int srcCellCol);
diff --git a/main/SS/UserModel/DataFormatter.cs b/main/SS/UserModel/DataFormatter.cs
index c9ebe1daf..3f1e340d7 100644
--- a/main/SS/UserModel/DataFormatter.cs
+++ b/main/SS/UserModel/DataFormatter.cs
@@ -947,10 +947,10 @@ public string FormatRawCellContents(double value, int formatIndex, string format
{
FormatBase dateFormat = GetFormat(value, formatIndex, formatString);
- if (dateFormat is ExcelStyleDateFormatter excelStyleDateFormat)
+ if (dateFormat is ExcelStyleDateFormatter)
{
// Hint about the raw excel value
- excelStyleDateFormat.SetDateToBeFormatted(value);
+ ((ExcelStyleDateFormatter)dateFormat).SetDateToBeFormatted(value);
}
DateTime d = DateUtil.GetJavaDate(value, use1904Windowing);
@@ -982,15 +982,10 @@ public string FormatRawCellContents(double value, int formatIndex, string format
}
else
{
- var parsed = decimal.Parse(textValue, currentCulture);
- result = numberFormat.Format(parsed);
+ result = numberFormat.Format(decimal.Parse(textValue));
}
-
- // If they requested a non-abbreviated Scientific format,
- // and there's an E## (but not E-##), add the missing '+' for E+##
- string fslc = formatString.ToLower(currentCulture);
- if((fslc.Contains("general") || fslc.Contains("e+0")) &&
- result.Contains("E") && !result.Contains("E-"))
+ // Complete scientific notation by adding the missing +.
+ if (result.Contains("E") && !result.Contains("E-"))
{
result = result.Replace("E", "E+");
}
diff --git a/testcases/main/SS/Formula/Functions/TestText.cs b/testcases/main/SS/Formula/Functions/TestText.cs
index d7793d765..65cc5b280 100644
--- a/testcases/main/SS/Formula/Functions/TestText.cs
+++ b/testcases/main/SS/Formula/Functions/TestText.cs
@@ -24,8 +24,6 @@ namespace TestCases.SS.Formula.Functions
using NPOI.SS.Util;
using NPOI.SS.Formula.Functions;
using System.Globalization;
- using System.Collections.Generic;
- using NPOI.SS.UserModel;
/**
* Test case for TEXT()
@@ -35,44 +33,28 @@ namespace TestCases.SS.Formula.Functions
[TestFixture]
public class TestText
{
- private readonly List EXCEL_ERRORS = new(11) {
- ErrorEval.NULL_INTERSECTION,
- ErrorEval.DIV_ZERO,
- ErrorEval.VALUE_INVALID,
- ErrorEval.REF_INVALID,
- ErrorEval.NAME_INVALID,
- ErrorEval.NUM_ERROR,
- ErrorEval.NA
- };
-
- private readonly CultureInfo _currentCulture = CultureInfo.InvariantCulture;
-
- [OneTimeSetUp]
- public void SetUp()
- {
- Text.Formatter = new DataFormatter(_currentCulture);
- }
-
//private static TextFunction T = null;
[Test]
public void TestTextWithStringFirstArg()
{
+
ValueEval strArg = new StringEval("abc");
ValueEval formatArg = new StringEval("abc");
ValueEval[] args = { strArg, formatArg };
- ValueEval result = TextFunction.TEXT.Evaluate(args, -1, -1);
- Assert.AreEqual(strArg.ToString(), result.ToString());
+ ValueEval result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
+ Assert.AreEqual(strArg, result);
}
-
[Test]
- public void TestTextWithDecimalFormatSecondArg()
+ public void TestTextWithDeciamlFormatSecondArg()
{
ValueEval numArg = new NumberEval(321321.321);
ValueEval formatArg = new StringEval("#,###.00000");
ValueEval[] args = { numArg, formatArg };
- ValueEval result = TextFunction.TEXT.Evaluate(args, -1, -1);
-
- NumberFormatInfo fs = _currentCulture.NumberFormat;
+ ValueEval result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
+ //char groupSeparator = new DecimalFormatSymbols(Locale.GetDefault()).GetGroupingSeparator();
+ //char decimalSeparator = new DecimalFormatSymbols(Locale.GetDefault()).GetDecimalSeparator();
+
+ NumberFormatInfo fs = CultureInfo.GetCultureInfo("en-US").NumberFormat;
string groupSeparator = fs.NumberGroupSeparator;
string decimalSeparator = fs.NumberDecimalSeparator; ;
@@ -88,227 +70,71 @@ public void TestTextWithDecimalFormatSecondArg()
formatArg = new StringEval("$#.#");
args[1] = formatArg;
- result = TextFunction.TEXT.Evaluate(args, -1, -1);
+ result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
testResult = new StringEval("$321" + decimalSeparator + "3");
Assert.AreEqual(testResult.ToString(), result.ToString());
}
-
[Test]
public void TestTextWithFractionFormatSecondArg()
{
+
ValueEval numArg = new NumberEval(321.321);
ValueEval formatArg = new StringEval("# #/#");
ValueEval[] args = { numArg, formatArg };
- ValueEval result = TextFunction.TEXT.Evaluate(args, -1, -1);
+ ValueEval result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
ValueEval testResult = new StringEval("321 1/3");
- Assert.AreEqual(testResult.ToString(), result.ToString());
+ Assert.AreEqual(testResult.ToString(), result.ToString()); //this bug is caused by DecimalFormat
formatArg = new StringEval("# #/##");
args[1] = formatArg;
- result = TextFunction.TEXT.Evaluate(args, -1, -1);
+ result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
testResult = new StringEval("321 26/81");
Assert.AreEqual(testResult.ToString(), result.ToString());
formatArg = new StringEval("#/##");
args[1] = formatArg;
- result = TextFunction.TEXT.Evaluate(args, -1, -1);
+ result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
testResult = new StringEval("26027/81");
Assert.AreEqual(testResult.ToString(), result.ToString());
}
-
[Test]
public void TestTextWithDateFormatSecondArg()
{
+ // Test with Java style M=Month
+ System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
ValueEval numArg = new NumberEval(321.321);
ValueEval formatArg = new StringEval("dd:MM:yyyy hh:mm:ss");
ValueEval[] args = { numArg, formatArg };
- ValueEval result = TextFunction.TEXT.Evaluate(args, -1, -1);
+ ValueEval result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
ValueEval testResult = new StringEval("16:11:1900 07:42:14");
Assert.AreEqual(testResult.ToString(), result.ToString());
// Excel also supports "m before h is month"
formatArg = new StringEval("dd:mm:yyyy hh:mm:ss");
args[1] = formatArg;
- result = TextFunction.TEXT.Evaluate(args, -1, -1);
+ result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
testResult = new StringEval("16:11:1900 07:42:14");
- Assert.AreEqual(testResult.ToString(), result.ToString());
+ //Assert.AreEqual(testResult.ToString(), result.ToString());
// this line is intended to compute how "November" would look like in the current locale
- string november = new SimpleDateFormat("MMMM").Format(new DateTime(2010, 11, 15), CultureInfo.CurrentCulture);
+ String november = new SimpleDateFormat("MMMM").Format(new DateTime(2010, 11, 15), CultureInfo.CurrentCulture);
// Again with Java style
formatArg = new StringEval("MMMM dd, yyyy");
args[1] = formatArg;
-
- result = TextFunction.TEXT.Evaluate(args, -1, -1);
+ //fix error in non-en Culture
+ NPOI.SS.Formula.Functions.Text.Formatter = new NPOI.SS.UserModel.DataFormatter(CultureInfo.CurrentCulture);
+ result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
testResult = new StringEval(november + " 16, 1900");
Assert.AreEqual(testResult.ToString(), result.ToString());
// And Excel style
formatArg = new StringEval("mmmm dd, yyyy");
args[1] = formatArg;
- result = TextFunction.TEXT.Evaluate(args, -1, -1);
+ result = TextFunction.TEXT.Evaluate(args, -1, (short)-1);
testResult = new StringEval(november + " 16, 1900");
Assert.AreEqual(testResult.ToString(), result.ToString());
}
-
- [Test]
- public void TestTextWithISODateTimeFormatSecondArg()
- {
- ValueEval numArg = new NumberEval(321.321);
- ValueEval formatArg = new StringEval("yyyy-mm-ddThh:MM:ss");
- ValueEval[] args = { numArg, formatArg };
- ValueEval result = TextFunction.TEXT.Evaluate(args, -1, -1);
- ValueEval testResult = new StringEval("1900-11-16T07:42:14");
- Assert.AreEqual(testResult.ToString(), result.ToString());
-
- // test milliseconds
- formatArg = new StringEval("yyyy-mm-ddThh:MM:ss.000");
- args[1] = formatArg;
- result = TextFunction.TEXT.Evaluate(args, -1, -1);
- testResult = new StringEval("1900-11-16T07:42:14.400");
- Assert.AreEqual(testResult.ToString(), result.ToString());
- }
-
- // Test cases from the workbook attached to the bug 67475 which were OK
-
- [Test]
- public void TestTextVariousValidNumberFormats()
- {
- // negative values: 3 decimals
- Testtext(new NumberEval(-123456.789012345), new StringEval("#0.000"), "-123456.789");
- // no decimals
- Testtext(new NumberEval(-123456.789012345), new StringEval("000000"), "-123457");
- // common format - more digits
- Testtext(new NumberEval(-123456.789012345), new StringEval("00.0000"), "-123456.7890");
- // common format - less digits
- Testtext(new NumberEval(-12.78), new StringEval("00000.000000"), "-00012.780000");
- // half up
- Testtext(new NumberEval(-0.56789012375), new StringEval("#0.0000000000"), "-0.5678901238");
- // half up
- Testtext(new NumberEval(-0.56789012385), new StringEval("#0.0000000000"), "-0.5678901239");
- // positive values: 3 decimals
- Testtext(new NumberEval(123456.789012345), new StringEval("#0.000"), "123456.789");
- // no decimals
- Testtext(new NumberEval(123456.789012345), new StringEval("000000"), "123457");
- // common format - more digits
- Testtext(new NumberEval(123456.789012345), new StringEval("00.0000"), "123456.7890");
- // common format - less digits
- Testtext(new NumberEval(12.78), new StringEval("00000.000000"), "00012.780000");
- // half up
- Testtext(new NumberEval(0.56789012375), new StringEval("#0.0000000000"), "0.5678901238");
- // half up
- Testtext(new NumberEval(0.56789012385), new StringEval("#0.0000000000"), "0.5678901239");
- }
-
- [Test]
- public void testTextBlankTreatedAsZero()
- {
- Testtext(BlankEval.instance, new StringEval("#0.000"), "0.000");
- }
-
- [Test]
- public void testTextStrangeFormat()
- {
- // number 0
- Testtext(new NumberEval(-123456.789012345), new NumberEval(0), "-123457");
- // negative number with few zeros
- Testtext(new NumberEval(-123456.789012345), new NumberEval(-0.0001), "--123456.7891");
- // format starts with "."
- Testtext(new NumberEval(0.0123), new StringEval(".000"), ".012");
- // one zero negative
- Testtext(new NumberEval(1001.202), new NumberEval(-8808), "-8810018");
- // format contains 0
- Testtext(new NumberEval(43368.0), new NumberEval(909), "9433689");
- }
-
- [Test]
- public void TestTextErrorAsFormat()
- {
- foreach(ErrorEval errorEval in EXCEL_ERRORS)
- {
- Testtext(new NumberEval(3.14), errorEval, errorEval);
- Testtext(BoolEval.TRUE, errorEval, errorEval);
- Testtext(BoolEval.FALSE, errorEval, errorEval);
- }
- }
-
- [Test]
- public void TestTextErrorAsValue()
- {
- foreach(ErrorEval errorEval in EXCEL_ERRORS)
- {
- Testtext(errorEval, new StringEval("#0.000"), errorEval);
- Testtext(errorEval, new StringEval("yyyymmmdd"), errorEval);
- }
- }
-
- // Test cases from the workbook attached to the bug 67475 which were failing and are fixed by the patch
-
- [Test]
- public void TestTextEmptyStringWithDateFormat()
- {
- Testtext(new StringEval(""), new StringEval("yyyymmmdd"), "");
- }
-
- [Test]
- public void TestTextAnyTextWithDateFormat()
- {
- Testtext(new StringEval("anyText"), new StringEval("yyyymmmdd"), "anyText");
- }
-
- [Test]
- public void TestTextBooleanWithDateFormat()
- {
- Testtext(BoolEval.TRUE, new StringEval("yyyymmmdd"), BoolEval.TRUE.StringValue);
- Testtext(BoolEval.FALSE, new StringEval("yyyymmmdd"), BoolEval.FALSE.StringValue);
- }
-
- [Test]
- public void TestTextNumberWithBooleanFormat()
- {
- Testtext(new NumberEval(43368), BoolEval.TRUE, ErrorEval.VALUE_INVALID);
- Testtext(new NumberEval(43368), BoolEval.FALSE, ErrorEval.VALUE_INVALID);
-
- Testtext(new NumberEval(3.14), BoolEval.TRUE, ErrorEval.VALUE_INVALID);
- Testtext(new NumberEval(3.14), BoolEval.FALSE, ErrorEval.VALUE_INVALID);
- }
-
- [Test]
- public void TestTextEmptyStringWithNumberFormat()
- {
- Testtext(new StringEval(""), new StringEval("#0.000"), "");
- }
-
- [Test]
- public void TestTextAnyTextWithNumberFormat()
- {
- Testtext(new StringEval("anyText"), new StringEval("#0.000"), "anyText");
- }
-
- [Test]
- public void TestTextBooleanWithNumberFormat()
- {
- Testtext(BoolEval.TRUE, new StringEval("#0.000"), BoolEval.TRUE.StringValue);
- Testtext(BoolEval.FALSE, new StringEval("#0.000"), BoolEval.FALSE.StringValue);
- }
-
- private static void Testtext(ValueEval valueArg, ValueEval formatArg, string expectedResult)
- {
- ValueEval[] args = { valueArg, formatArg };
- ValueEval result = TextFunction.TEXT.Evaluate(args, -1, -1);
-
- Assert.IsTrue(result is StringEval, "Expected StringEval got " + result.GetType().Name);
- Assert.AreEqual(expectedResult, ((StringEval) result).StringValue);
- }
-
- private static void Testtext(ValueEval valueArg, ValueEval formatArg, ErrorEval expectedResult)
- {
- ValueEval[] args = { valueArg, formatArg };
- ValueEval result = TextFunction.TEXT.Evaluate(args, -1, -1);
-
- Assert.IsTrue(result is ErrorEval, "Expected ErrorEval got " + result.GetType().Name);
- Assert.AreEqual(expectedResult, result);
- }
}
+
}
\ No newline at end of file