/** * Formats nicer error messages for the junit output */ private static double InvokeInternal(Function target, ValueEval[] args, int srcCellRow, int srcCellCol) { ValueEval evalResult; try { evalResult = target.Evaluate(args, srcCellRow, srcCellCol); } catch (NotImplementedException e) { throw new NumericEvalEx("Not implemented:" + e.Message); } if (evalResult == null) { throw new NumericEvalEx("Result object was null"); } if (evalResult is ErrorEval) { ErrorEval ee = (ErrorEval)evalResult; throw new NumericEvalEx(FormatErrorMessage(ee)); } if (!(evalResult is NumericValueEval)) { throw new NumericEvalEx("Result object type (" + evalResult.GetType().Name + ") is1 invalid. Expected implementor of (" + typeof(NumericValueEval).Name + ")"); } NumericValueEval result = (NumericValueEval)evalResult; return(result.NumberValue); }
/** * Determines a <c>double</c> value for the specified <c>ValueEval</c>. * @param IsScalarProduct <c>false</c> for SUMPRODUCTs over area refs. * @throws EvalEx if <c>ve</c> represents an error value. * <p/> * Note - string values and empty cells are interpreted differently depending on * <c>isScalarProduct</c>. For scalar products, if any term Is blank or a string, the * error (#VALUE!) Is raised. For area (sum)products, if any term Is blank or a string, the * result Is zero. */ private static double GetProductTerm(ValueEval ve, bool IsScalarProduct) { if (ve is BlankEval || ve == null) { // TODO - shouldn't BlankEval.INSTANCE be used always instead of null? // null seems to occur when the blank cell Is part of an area ref (but not reliably) if (IsScalarProduct) { throw new EvaluationException(ErrorEval.VALUE_INVALID); } return(0); } if (ve is ErrorEval) { throw new EvaluationException((ErrorEval)ve); } if (ve is StringEval) { if (IsScalarProduct) { throw new EvaluationException(ErrorEval.VALUE_INVALID); } // Note for area SUMPRODUCTs, string values are interpreted as zero // even if they would Parse as valid numeric values return(0); } if (ve is NumericValueEval) { NumericValueEval nve = (NumericValueEval)ve; return(nve.NumberValue); } throw new RuntimeException("Unexpected value eval class (" + ve.GetType().Name + ")"); }
private static double EvaluateMatchTypeArg(ValueEval arg, int srcCellRow, int srcCellCol) { ValueEval match_type = OperandResolver.GetSingleValue(arg, srcCellRow, srcCellCol); if (match_type is ErrorEval) { throw new EvaluationException((ErrorEval)match_type); } if (match_type is NumericValueEval) { NumericValueEval ne = (NumericValueEval)match_type; return(ne.NumberValue); } if (match_type is StringEval) { StringEval se = (StringEval)match_type; double d = OperandResolver.ParseDouble(se.StringValue); if (double.IsNaN(d)) { // plain string throw new EvaluationException(ErrorEval.VALUE_INVALID); } // if the string Parses as a number, it Is OK return(d); } throw new Exception("Unexpected match_type type (" + match_type.GetType().Name + ")"); }
private static void ConfirmDouble(double expected, ValueEval actualEval) { if (!(actualEval is NumericValueEval)) { throw new AssertionException("Expected numeric result"); } NumericValueEval nve = (NumericValueEval)actualEval; Assert.AreEqual(expected, nve.NumberValue, 0); }
private static void ConfirmInt(int expected, ValueEval actualEval) { if (!(actualEval is NumericValueEval)) { Assert.Fail("Expected numeric result but had " + actualEval); } NumericValueEval nve = (NumericValueEval)actualEval; Assert.AreEqual(expected, nve.NumberValue, 0); }
private static void ConfirmInt(int expected, ValueEval actualEval) { if (!(typeof(NumericValueEval).IsInstanceOfType(actualEval))) { Assert.Fail("Expected numeric result"); } NumericValueEval nve = (NumericValueEval)actualEval; Assert.AreEqual(expected, Convert.ToInt32(nve.NumberValue)); }
/** * Resolves the last (optional) parameter (<b>range_lookup</b>) to the VLOOKUP and HLOOKUP functions. * @param rangeLookupArg * @param srcCellRow * @param srcCellCol * @return * @throws EvaluationException */ public static bool ResolveRangeLookupArg(ValueEval rangeLookupArg, int srcCellRow, int srcCellCol) { ValueEval valEval = OperandResolver.GetSingleValue(rangeLookupArg, srcCellRow, srcCellCol); if (valEval == MissingArgEval.instance) { // Tricky: // forth arg exists but is not supplied: "=VLOOKUP(A1,A2:A4,2,)" return(false); } if (valEval is BlankEval) { // Tricky: // fourth arg supplied but Evaluates to blank // this does not Get the default value return(false); } if (valEval is BoolEval) { // Happy day flow BoolEval boolEval = (BoolEval)valEval; return(boolEval.BooleanValue); } if (valEval is StringEval) { String stringValue = ((StringEval)valEval).StringValue; if (stringValue.Length < 1) { // More trickiness: // Empty string Is not the same as BlankEval. It causes #VALUE! error throw EvaluationException.InvalidValue(); } // TODO move parseBoolean to OperandResolver bool?b = Countif.ParseBoolean(stringValue); if (b != null) { // string Converted to bool OK return(b == true ? true : false); } //// Even more trickiness: //// Note - even if the StringEval represents a number value (for example "1"), //// Excel does not resolve it to a bool. throw EvaluationException.InvalidValue(); //// This Is in contrast to the code below,, where NumberEvals values (for //// example 0.01) *do* resolve to equivalent bool values. } if (valEval is NumericValueEval) { NumericValueEval nve = (NumericValueEval)valEval; // zero Is FALSE, everything else Is TRUE return(0.0 != nve.NumberValue); } throw new Exception("Unexpected eval type (" + valEval.GetType().Name + ")"); }
/** * @return <c>null</c> 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) { // TODO - remove 've == null' condition once AreaEval is fixed return(null); } if (ve is BoolEval) { return(((BoolEval)ve).BooleanValue); } if (ve is StringEval) { if (stringsAreBlanks) { return(null); } String str = ((StringEval)ve).StringValue; if (str.Equals("true", StringComparison.OrdinalIgnoreCase)) { return(true); } if (str.Equals("false", StringComparison.OrdinalIgnoreCase)) { return(false); } // else - string cannot be converted to boolean throw new EvaluationException(ErrorEval.VALUE_INVALID); } if (ve is NumericValueEval) { NumericValueEval ne = (NumericValueEval)ve; double d = ne.NumberValue; if (Double.IsNaN(d)) { throw new EvaluationException(ErrorEval.VALUE_INVALID); } return(d != 0); } if (ve is ErrorEval) { throw new EvaluationException((ErrorEval)ve); } throw new InvalidOperationException("Unexpected eval (" + ve.GetType().Name + ")"); }