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, (short)-1); //char groupSeparator = new DecimalFormatSymbols(Locale.GetDefault()).GetGroupingSeparator(); //char decimalSeparator = new DecimalFormatSymbols(Locale.GetDefault()).GetDecimalSeparator(); System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.InstalledUICulture; string groupSeparator = ci.NumberFormat.NumberGroupSeparator; string decimalSeparator = ci.NumberFormat.NumberDecimalSeparator;; ValueEval testResult = new StringEval("321" + groupSeparator + "321" + decimalSeparator + "32100"); Assert.AreEqual(testResult.ToString(), result.ToString()); numArg = new NumberEval(321.321); formatArg = new StringEval("00000.00000"); args[0] = numArg; args[1] = formatArg; result = TextFunction.TEXT.Evaluate(args, -1, (short)-1); testResult = new StringEval("00321" + decimalSeparator + "32100"); Assert.AreEqual(testResult.ToString(), result.ToString()); formatArg = new StringEval("$#.#"); args[1] = formatArg; result = TextFunction.TEXT.Evaluate(args, -1, (short)-1); testResult = new StringEval("$321" + decimalSeparator + "3"); Assert.AreEqual(testResult.ToString(), result.ToString()); }
private static void ConfirmValue(String msg, String number1, String expected) { ValueEval result = invokeValue(number1); Assert.AreEqual(typeof(StringEval), result.GetType(), "Had: " + result.ToString()); Assert.AreEqual(expected, ((StringEval)result).StringValue, msg); }
/** * Invocation when not expecting an error result */ private static NumberEval invokeNormal(ValueEval[] args) { ValueEval ev = invoke(args); if (ev is ErrorEval) { throw new AssertionException("Normal Evaluation failed with error code: " + ev.ToString()); } return((NumberEval)ev); }
public void TestTextWithDateFormatSecondArg() { 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, (short)-1); ValueEval testResult = new StringEval("16:11:1900 07:42:14"); 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)); formatArg = new StringEval("MMMM dd, yyyy"); args[1] = formatArg; result = TextFunction.TEXT.Evaluate(args, -1, (short)-1); testResult = new StringEval(november + " 16, 1900"); Assert.AreEqual(testResult.ToString(), result.ToString()); }
public void TestTextWithDateFormatSecondArg() { // Test with Java style M=Month CultureShim.SetCurrentCulture("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, (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, (short)-1); testResult = new StringEval("16:11:1900 07:42:14"); //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); // Again with Java style formatArg = new StringEval("MMMM dd, yyyy"); args[1] = formatArg; //fix error in non-en Culture Npoi.Core.SS.Formula.Functions.Text.Formatter = new Npoi.Core.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, (short)-1); testResult = new StringEval(november + " 16, 1900"); Assert.AreEqual(testResult.ToString(), result.ToString()); }
public void TestBackAndForth() { for (int i = -512; i < 512; i++) { ValueEval result = invokeValue(i.ToString()); Assert.AreEqual(typeof(StringEval), result.GetType(), "Had: " + result.ToString()); ValueEval back = invokeBack(((StringEval)result).StringValue); Assert.AreEqual(typeof(NumberEval), back.GetType(), "Had: " + back.ToString()); Assert.AreEqual(i.ToString(), ((NumberEval)back).StringValue); } }
public void TestTextWithFractionFormatSecondArg() { ValueEval numArg = new NumberEval(321.321); ValueEval formatArg = new StringEval("# #/#"); ValueEval[] args = { numArg, formatArg }; ValueEval result = TextFunction.TEXT.Evaluate(args, -1, (short)-1); ValueEval testResult = new StringEval("321 1/3"); Assert.AreEqual(testResult.ToString(), result.ToString()); //this bug is caused by DecimalFormat formatArg = new StringEval("# #/##"); args[1] = formatArg; 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, (short)-1); testResult = new StringEval("26027/81"); Assert.AreEqual(testResult.ToString(), result.ToString()); }
// visibility raised for testing /* package */ public ValueEval EvaluateFormula(OperationEvaluationContext ec, Ptg[] ptgs) { string dbgIndentStr = ""; // always init. to non-null just for defensive avoiding NPE if (dbgEvaluationOutputForNextEval) { // first evaluation call when ouput is desired, so iit. this evaluator instance dbgEvaluationOutputIndent = 1; dbgEvaluationOutputForNextEval = false; } if (dbgEvaluationOutputIndent > 0) { // init. indent string to needed spaces (create as substring vom very long space-only string; // limit indendation for deep recursions) dbgIndentStr = " "; dbgIndentStr = dbgIndentStr.Substring(0, Math.Min(dbgIndentStr.Length, dbgEvaluationOutputIndent * 2)); EVAL_LOG.Log(POILogger.WARN, dbgIndentStr + "- evaluateFormula('" + ec.GetRefEvaluatorForCurrentSheet().SheetNameRange + "'/" + new CellReference(ec.RowIndex, ec.ColumnIndex).FormatAsString() + "): " + Arrays.ToString(ptgs).Replace("\\Qorg.apache.poi.ss.formula.ptg.\\E", "")); dbgEvaluationOutputIndent++; } Stack <ValueEval> stack = new Stack <ValueEval>(); for (int i = 0, iSize = ptgs.Length; i < iSize; i++) { // since we don't know how To handle these yet :( Ptg ptg = ptgs[i]; if (dbgEvaluationOutputIndent > 0) { EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + " * ptg " + i + ": " + ptg.ToString()); } if (ptg is AttrPtg) { AttrPtg attrPtg = (AttrPtg)ptg; if (attrPtg.IsSum) { // Excel prefers To encode 'SUM()' as a tAttr Token, but this evaluator // expects the equivalent function Token //byte nArgs = 1; // tAttrSum always Has 1 parameter ptg = FuncVarPtg.SUM;//.Create("SUM", nArgs); } if (attrPtg.IsOptimizedChoose) { ValueEval arg0 = stack.Pop(); int[] jumpTable = attrPtg.JumpTable; int dist; int nChoices = jumpTable.Length; try { int switchIndex = Choose.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex); if (switchIndex < 1 || switchIndex > nChoices) { stack.Push(ErrorEval.VALUE_INVALID); dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE) } else { dist = jumpTable[switchIndex - 1]; } } catch (EvaluationException e) { stack.Push(e.GetErrorEval()); dist = attrPtg.ChooseFuncOffset + 4; // +4 for tFuncFar(CHOOSE) } // Encoded dist for tAttrChoose includes size of jump table, but // countTokensToBeSkipped() does not (it counts whole tokens). dist -= nChoices * 2 + 2; // subtract jump table size i += CountTokensToBeSkipped(ptgs, i, dist); continue; } if (attrPtg.IsOptimizedIf) { ValueEval arg0 = stack.Pop(); bool evaluatedPredicate; try { evaluatedPredicate = If.EvaluateFirstArg(arg0, ec.RowIndex, ec.ColumnIndex); } catch (EvaluationException e) { stack.Push(e.GetErrorEval()); int dist = attrPtg.Data; i += CountTokensToBeSkipped(ptgs, i, dist); attrPtg = (AttrPtg)ptgs[i]; dist = attrPtg.Data + 1; i += CountTokensToBeSkipped(ptgs, i, dist); continue; } if (evaluatedPredicate) { // nothing to skip - true param folows } else { int dist = attrPtg.Data; i += CountTokensToBeSkipped(ptgs, i, dist); Ptg nextPtg = ptgs[i + 1]; if (ptgs[i] is AttrPtg && nextPtg is FuncVarPtg && // in order to verify that there is no third param, we need to check // if we really have the IF next or some other FuncVarPtg as third param, e.g. ROW()/COLUMN()! ((FuncVarPtg)nextPtg).FunctionIndex == FunctionMetadataRegistry.FUNCTION_INDEX_IF) { // this is an if statement without a false param (as opposed to MissingArgPtg as the false param) i++; stack.Push(BoolEval.FALSE); } } continue; } if (attrPtg.IsSkip) { int dist = attrPtg.Data + 1; i += CountTokensToBeSkipped(ptgs, i, dist); if (stack.Peek() == MissingArgEval.instance) { stack.Pop(); stack.Push(BlankEval.instance); } continue; } } if (ptg is ControlPtg) { // skip Parentheses, Attr, etc continue; } if (ptg is MemFuncPtg || ptg is MemAreaPtg) { // can ignore, rest of Tokens for this expression are in OK RPN order continue; } if (ptg is MemErrPtg) { continue; } ValueEval opResult; if (ptg is OperationPtg) { OperationPtg optg = (OperationPtg)ptg; if (optg is UnionPtg) { continue; } int numops = optg.NumberOfOperands; ValueEval[] ops = new ValueEval[numops]; // storing the ops in reverse order since they are popping for (int j = numops - 1; j >= 0; j--) { ValueEval p = (ValueEval)stack.Pop(); ops[j] = p; } // logDebug("Invoke " + operation + " (nAgs=" + numops + ")"); opResult = OperationEvaluatorFactory.Evaluate(optg, ops, ec); } else { opResult = GetEvalForPtg(ptg, ec); } if (opResult == null) { throw new Exception("Evaluation result must not be null"); } // logDebug("push " + opResult); stack.Push(opResult); if (dbgEvaluationOutputIndent > 0) { EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + " = " + opResult.ToString()); } } ValueEval value = ((ValueEval)stack.Pop()); if (stack.Count != 0) { throw new InvalidOperationException("evaluation stack not empty"); } ValueEval result = DereferenceResult(value, ec.RowIndex, ec.ColumnIndex); if (dbgEvaluationOutputIndent > 0) { EVAL_LOG.Log(POILogger.INFO, dbgIndentStr + "finshed eval of " + new CellReference(ec.RowIndex, ec.ColumnIndex).FormatAsString() + ": " + result.ToString()); dbgEvaluationOutputIndent--; if (dbgEvaluationOutputIndent == 1) { // this evaluation is done, reset indent to stop logging dbgEvaluationOutputIndent = -1; } } // if return(result); }