Improvements to countif implementation in preparation for sumif
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@734243 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e7c33d1d66
commit
9c05b68576
@ -24,6 +24,7 @@ import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
|||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.EvaluationException;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||||
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
import org.apache.poi.hssf.record.formula.eval.RefEval;
|
||||||
@ -214,6 +215,24 @@ public final class Countif implements Function {
|
|||||||
return _operator.evaluate(testValue - _value);
|
return _operator.evaluate(testValue - _value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static final class ErrorMatcher implements I_MatchPredicate {
|
||||||
|
|
||||||
|
private final int _value;
|
||||||
|
private final CmpOp _operator;
|
||||||
|
|
||||||
|
public ErrorMatcher(int errorCode, CmpOp operator) {
|
||||||
|
_value = errorCode;
|
||||||
|
_operator = operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(Eval x) {
|
||||||
|
if(x instanceof ErrorEval) {
|
||||||
|
int testValue = ((ErrorEval)x).getErrorCode();
|
||||||
|
return _operator.evaluate(testValue - _value);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
private static final class StringMatcher implements I_MatchPredicate {
|
private static final class StringMatcher implements I_MatchPredicate {
|
||||||
|
|
||||||
private final String _value;
|
private final String _value;
|
||||||
@ -322,7 +341,7 @@ public final class Countif implements Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
|
public Eval evaluate(Eval[] args, int srcRowIndex, short srcColumnIndex) {
|
||||||
switch(args.length) {
|
switch(args.length) {
|
||||||
case 2:
|
case 2:
|
||||||
// expected
|
// expected
|
||||||
@ -333,40 +352,35 @@ public final class Countif implements Function {
|
|||||||
return ErrorEval.VALUE_INVALID;
|
return ErrorEval.VALUE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
Eval criteriaArg = args[1];
|
I_MatchPredicate mp = createCriteriaPredicate(args[1], srcRowIndex, srcColumnIndex);
|
||||||
if(criteriaArg instanceof RefEval) {
|
if(mp == null) {
|
||||||
// criteria is not a literal value, but a cell reference
|
|
||||||
// for example COUNTIF(B2:D4, E1)
|
|
||||||
RefEval re = (RefEval)criteriaArg;
|
|
||||||
criteriaArg = re.getInnerValueEval();
|
|
||||||
} else {
|
|
||||||
// other non literal tokens such as function calls, have been fully evaluated
|
|
||||||
// for example COUNTIF(B2:D4, COLUMN(E1))
|
|
||||||
}
|
|
||||||
if(criteriaArg instanceof BlankEval) {
|
|
||||||
// If the criteria arg is a reference to a blank cell, countif always returns zero.
|
// If the criteria arg is a reference to a blank cell, countif always returns zero.
|
||||||
return NumberEval.ZERO;
|
return NumberEval.ZERO;
|
||||||
}
|
}
|
||||||
I_MatchPredicate mp = createCriteriaPredicate(criteriaArg);
|
double result = countMatchingCellsInArea(args[0], mp);
|
||||||
return countMatchingCellsInArea(args[0], mp);
|
return new NumberEval(result);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return the number of evaluated cells in the range that match the specified criteria
|
* @return the number of evaluated cells in the range that match the specified criteria
|
||||||
*/
|
*/
|
||||||
private Eval countMatchingCellsInArea(Eval rangeArg, I_MatchPredicate criteriaPredicate) {
|
private double countMatchingCellsInArea(Eval rangeArg, I_MatchPredicate criteriaPredicate) {
|
||||||
|
|
||||||
int result;
|
|
||||||
if (rangeArg instanceof RefEval) {
|
if (rangeArg instanceof RefEval) {
|
||||||
result = CountUtils.countMatchingCell((RefEval) rangeArg, criteriaPredicate);
|
return CountUtils.countMatchingCell((RefEval) rangeArg, criteriaPredicate);
|
||||||
} else if (rangeArg instanceof AreaEval) {
|
} else if (rangeArg instanceof AreaEval) {
|
||||||
result = CountUtils.countMatchingCellsInArea((AreaEval) rangeArg, criteriaPredicate);
|
return CountUtils.countMatchingCellsInArea((AreaEval) rangeArg, criteriaPredicate);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Bad range arg type (" + rangeArg.getClass().getName() + ")");
|
throw new IllegalArgumentException("Bad range arg type (" + rangeArg.getClass().getName() + ")");
|
||||||
}
|
}
|
||||||
return new NumberEval(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ static I_MatchPredicate createCriteriaPredicate(Eval evaluatedCriteriaArg) {
|
/**
|
||||||
|
* Creates a criteria predicate object for the supplied criteria arg
|
||||||
|
* @return <code>null</code> if the arg evaluates to blank.
|
||||||
|
*/
|
||||||
|
/* package */ static I_MatchPredicate createCriteriaPredicate(Eval arg, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
|
||||||
|
Eval evaluatedCriteriaArg = evaluateCriteriaArg(arg, srcRowIndex, srcColumnIndex);
|
||||||
|
|
||||||
if(evaluatedCriteriaArg instanceof NumberEval) {
|
if(evaluatedCriteriaArg instanceof NumberEval) {
|
||||||
return new NumberMatcher(((NumberEval)evaluatedCriteriaArg).getNumberValue(), CmpOp.OP_NONE);
|
return new NumberMatcher(((NumberEval)evaluatedCriteriaArg).getNumberValue(), CmpOp.OP_NONE);
|
||||||
@ -378,10 +392,27 @@ public final class Countif implements Function {
|
|||||||
if(evaluatedCriteriaArg instanceof StringEval) {
|
if(evaluatedCriteriaArg instanceof StringEval) {
|
||||||
return createGeneralMatchPredicate((StringEval)evaluatedCriteriaArg);
|
return createGeneralMatchPredicate((StringEval)evaluatedCriteriaArg);
|
||||||
}
|
}
|
||||||
|
if(evaluatedCriteriaArg instanceof ErrorEval) {
|
||||||
|
return new ErrorMatcher(((ErrorEval)evaluatedCriteriaArg).getErrorCode(), CmpOp.OP_NONE);
|
||||||
|
}
|
||||||
|
if(evaluatedCriteriaArg == BlankEval.INSTANCE) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
throw new RuntimeException("Unexpected type for criteria ("
|
throw new RuntimeException("Unexpected type for criteria ("
|
||||||
+ evaluatedCriteriaArg.getClass().getName() + ")");
|
+ evaluatedCriteriaArg.getClass().getName() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the de-referenced criteria arg (possibly {@link ErrorEval})
|
||||||
|
*/
|
||||||
|
private static Eval evaluateCriteriaArg(Eval arg, int srcRowIndex, int srcColumnIndex) {
|
||||||
|
try {
|
||||||
|
return OperandResolver.getSingleValue(arg, srcRowIndex, (short)srcColumnIndex);
|
||||||
|
} catch (EvaluationException e) {
|
||||||
|
return e.getErrorEval();
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* When the second argument is a string, many things are possible
|
* When the second argument is a string, many things are possible
|
||||||
*/
|
*/
|
||||||
@ -399,10 +430,28 @@ public final class Countif implements Function {
|
|||||||
if(doubleVal != null) {
|
if(doubleVal != null) {
|
||||||
return new NumberMatcher(doubleVal.doubleValue(), operator);
|
return new NumberMatcher(doubleVal.doubleValue(), operator);
|
||||||
}
|
}
|
||||||
|
ErrorEval ee = parseError(value);
|
||||||
|
if (ee != null) {
|
||||||
|
return new ErrorMatcher(ee.getErrorCode(), operator);
|
||||||
|
}
|
||||||
|
|
||||||
//else - just a plain string with no interpretation.
|
//else - just a plain string with no interpretation.
|
||||||
return new StringMatcher(value, operator);
|
return new StringMatcher(value, operator);
|
||||||
}
|
}
|
||||||
|
private static ErrorEval parseError(String value) {
|
||||||
|
if (value.length() < 4 || value.charAt(0) != '#') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value.equals("#NULL!")) return ErrorEval.NULL_INTERSECTION;
|
||||||
|
if (value.equals("#DIV/0!")) return ErrorEval.DIV_ZERO;
|
||||||
|
if (value.equals("#VALUE!")) return ErrorEval.VALUE_INVALID;
|
||||||
|
if (value.equals("#REF!")) return ErrorEval.REF_INVALID;
|
||||||
|
if (value.equals("#NAME?")) return ErrorEval.NAME_INVALID;
|
||||||
|
if (value.equals("#NUM!")) return ErrorEval.NUM_ERROR;
|
||||||
|
if (value.equals("#N/A")) return ErrorEval.NA;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Boolean literals ('TRUE', 'FALSE') treated similarly but NOT same as numbers.
|
* Boolean literals ('TRUE', 'FALSE') treated similarly but NOT same as numbers.
|
||||||
*/
|
*/
|
||||||
|
@ -24,8 +24,10 @@ import org.apache.poi.hssf.HSSFTestDataSamples;
|
|||||||
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
import org.apache.poi.hssf.record.formula.eval.AreaEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
import org.apache.poi.hssf.record.formula.eval.BlankEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
import org.apache.poi.hssf.record.formula.eval.BoolEval;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.Eval;
|
import org.apache.poi.hssf.record.formula.eval.Eval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
import org.apache.poi.hssf.record.formula.eval.NumberEval;
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.OperandResolver;
|
||||||
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
import org.apache.poi.hssf.record.formula.eval.StringEval;
|
||||||
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
import org.apache.poi.hssf.record.formula.eval.ValueEval;
|
||||||
import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
|
import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
|
||||||
@ -43,6 +45,8 @@ import org.apache.poi.ss.usermodel.CellValue;
|
|||||||
*/
|
*/
|
||||||
public final class TestCountFuncs extends TestCase {
|
public final class TestCountFuncs extends TestCase {
|
||||||
|
|
||||||
|
private static final String NULL = null;
|
||||||
|
|
||||||
public void testCountA() {
|
public void testCountA() {
|
||||||
|
|
||||||
Eval[] args;
|
Eval[] args;
|
||||||
@ -142,89 +146,159 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
assertEquals(expected, result, 0);
|
assertEquals(expected, result, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCountIfEmptyStringCriteria() {
|
private static I_MatchPredicate createCriteriaPredicate(Eval ev) {
|
||||||
|
return Countif.createCriteriaPredicate(ev, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the criteria arg is mostly handled by {@link OperandResolver#getSingleValue(Eval, int, short)}
|
||||||
|
*/
|
||||||
|
public void testCountifAreaCriteria() {
|
||||||
|
int srcColIx = 2; // anything but column A
|
||||||
|
|
||||||
|
ValueEval v0 = new NumberEval(2.0);
|
||||||
|
ValueEval v1 = new StringEval("abc");
|
||||||
|
ValueEval v2 = ErrorEval.DIV_ZERO;
|
||||||
|
|
||||||
|
AreaEval ev = EvalFactory.createAreaEval("A10:A12", new ValueEval[] { v0, v1, v2, });
|
||||||
|
|
||||||
|
I_MatchPredicate mp;
|
||||||
|
mp = Countif.createCriteriaPredicate(ev, 9, srcColIx);
|
||||||
|
confirmPredicate(true, mp, srcColIx);
|
||||||
|
confirmPredicate(false, mp, "abc");
|
||||||
|
confirmPredicate(false, mp, ErrorEval.DIV_ZERO);
|
||||||
|
|
||||||
|
mp = Countif.createCriteriaPredicate(ev, 10, srcColIx);
|
||||||
|
confirmPredicate(false, mp, srcColIx);
|
||||||
|
confirmPredicate(true, mp, "abc");
|
||||||
|
confirmPredicate(false, mp, ErrorEval.DIV_ZERO);
|
||||||
|
|
||||||
|
mp = Countif.createCriteriaPredicate(ev, 11, srcColIx);
|
||||||
|
confirmPredicate(false, mp, srcColIx);
|
||||||
|
confirmPredicate(false, mp, "abc");
|
||||||
|
confirmPredicate(true, mp, ErrorEval.DIV_ZERO);
|
||||||
|
confirmPredicate(false, mp, ErrorEval.VALUE_INVALID);
|
||||||
|
|
||||||
|
// tricky: indexing outside of A10:A12
|
||||||
|
// even this #VALUE! error gets used by COUNTIF as valid criteria
|
||||||
|
mp = Countif.createCriteriaPredicate(ev, 12, srcColIx);
|
||||||
|
confirmPredicate(false, mp, srcColIx);
|
||||||
|
confirmPredicate(false, mp, "abc");
|
||||||
|
confirmPredicate(false, mp, ErrorEval.DIV_ZERO);
|
||||||
|
confirmPredicate(true, mp, ErrorEval.VALUE_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCountifEmptyStringCriteria() {
|
||||||
I_MatchPredicate mp;
|
I_MatchPredicate mp;
|
||||||
|
|
||||||
// pred '=' matches blank cell but not empty string
|
// pred '=' matches blank cell but not empty string
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("="));
|
mp = createCriteriaPredicate(new StringEval("="));
|
||||||
confirmPredicate(false, mp, "");
|
confirmPredicate(false, mp, "");
|
||||||
confirmPredicate(true, mp, null);
|
confirmPredicate(true, mp, NULL);
|
||||||
|
|
||||||
// pred '' matches both blank cell but not empty string
|
// pred '' matches both blank cell but not empty string
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval(""));
|
mp = createCriteriaPredicate(new StringEval(""));
|
||||||
confirmPredicate(true, mp, "");
|
confirmPredicate(true, mp, "");
|
||||||
confirmPredicate(true, mp, null);
|
confirmPredicate(true, mp, NULL);
|
||||||
|
|
||||||
// pred '<>' matches empty string but not blank cell
|
// pred '<>' matches empty string but not blank cell
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("<>"));
|
mp = createCriteriaPredicate(new StringEval("<>"));
|
||||||
confirmPredicate(false, mp, null);
|
confirmPredicate(false, mp, NULL);
|
||||||
confirmPredicate(true, mp, "");
|
confirmPredicate(true, mp, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCountifComparisons() {
|
public void testCountifComparisons() {
|
||||||
I_MatchPredicate mp;
|
I_MatchPredicate mp;
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval(">5"));
|
mp = createCriteriaPredicate(new StringEval(">5"));
|
||||||
confirmPredicate(false, mp, 4);
|
confirmPredicate(false, mp, 4);
|
||||||
confirmPredicate(false, mp, 5);
|
confirmPredicate(false, mp, 5);
|
||||||
confirmPredicate(true, mp, 6);
|
confirmPredicate(true, mp, 6);
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("<=5"));
|
mp = createCriteriaPredicate(new StringEval("<=5"));
|
||||||
confirmPredicate(true, mp, 4);
|
confirmPredicate(true, mp, 4);
|
||||||
confirmPredicate(true, mp, 5);
|
confirmPredicate(true, mp, 5);
|
||||||
confirmPredicate(false, mp, 6);
|
confirmPredicate(false, mp, 6);
|
||||||
confirmPredicate(true, mp, "4.9");
|
confirmPredicate(true, mp, "4.9");
|
||||||
confirmPredicate(false, mp, "4.9t");
|
confirmPredicate(false, mp, "4.9t");
|
||||||
confirmPredicate(false, mp, "5.1");
|
confirmPredicate(false, mp, "5.1");
|
||||||
confirmPredicate(false, mp, null);
|
confirmPredicate(false, mp, NULL);
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("=abc"));
|
mp = createCriteriaPredicate(new StringEval("=abc"));
|
||||||
confirmPredicate(true, mp, "abc");
|
confirmPredicate(true, mp, "abc");
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("=42"));
|
mp = createCriteriaPredicate(new StringEval("=42"));
|
||||||
confirmPredicate(false, mp, 41);
|
confirmPredicate(false, mp, 41);
|
||||||
confirmPredicate(true, mp, 42);
|
confirmPredicate(true, mp, 42);
|
||||||
confirmPredicate(true, mp, "42");
|
confirmPredicate(true, mp, "42");
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval(">abc"));
|
mp = createCriteriaPredicate(new StringEval(">abc"));
|
||||||
confirmPredicate(false, mp, 4);
|
confirmPredicate(false, mp, 4);
|
||||||
confirmPredicate(false, mp, "abc");
|
confirmPredicate(false, mp, "abc");
|
||||||
confirmPredicate(true, mp, "abd");
|
confirmPredicate(true, mp, "abd");
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval(">4t3"));
|
mp = createCriteriaPredicate(new StringEval(">4t3"));
|
||||||
confirmPredicate(false, mp, 4);
|
confirmPredicate(false, mp, 4);
|
||||||
confirmPredicate(false, mp, 500);
|
confirmPredicate(false, mp, 500);
|
||||||
confirmPredicate(true, mp, "500");
|
confirmPredicate(true, mp, "500");
|
||||||
confirmPredicate(true, mp, "4t4");
|
confirmPredicate(true, mp, "4t4");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the criteria arg value can be an error code (the error does not
|
||||||
|
* propagate to the COUNTIF result).
|
||||||
|
*/
|
||||||
|
public void testCountifErrorCriteria() {
|
||||||
|
I_MatchPredicate mp;
|
||||||
|
|
||||||
|
mp = createCriteriaPredicate(new StringEval("#REF!"));
|
||||||
|
confirmPredicate(false, mp, 4);
|
||||||
|
confirmPredicate(false, mp, "#REF!");
|
||||||
|
confirmPredicate(true, mp, ErrorEval.REF_INVALID);
|
||||||
|
|
||||||
|
mp = createCriteriaPredicate(new StringEval("<#VALUE!"));
|
||||||
|
confirmPredicate(false, mp, 4);
|
||||||
|
confirmPredicate(false, mp, "#DIV/0!");
|
||||||
|
confirmPredicate(false, mp, "#REF!");
|
||||||
|
confirmPredicate(true, mp, ErrorEval.DIV_ZERO);
|
||||||
|
confirmPredicate(false, mp, ErrorEval.REF_INVALID);
|
||||||
|
|
||||||
|
// not quite an error literal, should be treated as plain text
|
||||||
|
mp = createCriteriaPredicate(new StringEval("<=#REF!a"));
|
||||||
|
confirmPredicate(false, mp, 4);
|
||||||
|
confirmPredicate(true, mp, "#DIV/0!");
|
||||||
|
confirmPredicate(true, mp, "#REF!");
|
||||||
|
confirmPredicate(false, mp, ErrorEval.DIV_ZERO);
|
||||||
|
confirmPredicate(false, mp, ErrorEval.REF_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
public void testWildCards() {
|
public void testWildCards() {
|
||||||
I_MatchPredicate mp;
|
I_MatchPredicate mp;
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("a*b"));
|
mp = createCriteriaPredicate(new StringEval("a*b"));
|
||||||
confirmPredicate(false, mp, "abc");
|
confirmPredicate(false, mp, "abc");
|
||||||
confirmPredicate(true, mp, "ab");
|
confirmPredicate(true, mp, "ab");
|
||||||
confirmPredicate(true, mp, "axxb");
|
confirmPredicate(true, mp, "axxb");
|
||||||
confirmPredicate(false, mp, "xab");
|
confirmPredicate(false, mp, "xab");
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("a?b"));
|
mp = createCriteriaPredicate(new StringEval("a?b"));
|
||||||
confirmPredicate(false, mp, "abc");
|
confirmPredicate(false, mp, "abc");
|
||||||
confirmPredicate(false, mp, "ab");
|
confirmPredicate(false, mp, "ab");
|
||||||
confirmPredicate(false, mp, "axxb");
|
confirmPredicate(false, mp, "axxb");
|
||||||
confirmPredicate(false, mp, "xab");
|
confirmPredicate(false, mp, "xab");
|
||||||
confirmPredicate(true, mp, "axb");
|
confirmPredicate(true, mp, "axb");
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("a~?"));
|
mp = createCriteriaPredicate(new StringEval("a~?"));
|
||||||
confirmPredicate(false, mp, "a~a");
|
confirmPredicate(false, mp, "a~a");
|
||||||
confirmPredicate(false, mp, "a~?");
|
confirmPredicate(false, mp, "a~?");
|
||||||
confirmPredicate(true, mp, "a?");
|
confirmPredicate(true, mp, "a?");
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("~*a"));
|
mp = createCriteriaPredicate(new StringEval("~*a"));
|
||||||
confirmPredicate(false, mp, "~aa");
|
confirmPredicate(false, mp, "~aa");
|
||||||
confirmPredicate(false, mp, "~*a");
|
confirmPredicate(false, mp, "~*a");
|
||||||
confirmPredicate(true, mp, "*a");
|
confirmPredicate(true, mp, "*a");
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("12?12"));
|
mp = createCriteriaPredicate(new StringEval("12?12"));
|
||||||
confirmPredicate(false, mp, 12812);
|
confirmPredicate(false, mp, 12812);
|
||||||
confirmPredicate(true, mp, "12812");
|
confirmPredicate(true, mp, "12812");
|
||||||
confirmPredicate(false, mp, "128812");
|
confirmPredicate(false, mp, "128812");
|
||||||
@ -233,18 +307,18 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
I_MatchPredicate mp;
|
I_MatchPredicate mp;
|
||||||
|
|
||||||
// make sure special reg-ex chars are treated like normal chars
|
// make sure special reg-ex chars are treated like normal chars
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("a.b"));
|
mp = createCriteriaPredicate(new StringEval("a.b"));
|
||||||
confirmPredicate(false, mp, "aab");
|
confirmPredicate(false, mp, "aab");
|
||||||
confirmPredicate(true, mp, "a.b");
|
confirmPredicate(true, mp, "a.b");
|
||||||
|
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval("a~b"));
|
mp = createCriteriaPredicate(new StringEval("a~b"));
|
||||||
confirmPredicate(false, mp, "ab");
|
confirmPredicate(false, mp, "ab");
|
||||||
confirmPredicate(false, mp, "axb");
|
confirmPredicate(false, mp, "axb");
|
||||||
confirmPredicate(false, mp, "a~~b");
|
confirmPredicate(false, mp, "a~~b");
|
||||||
confirmPredicate(true, mp, "a~b");
|
confirmPredicate(true, mp, "a~b");
|
||||||
|
|
||||||
mp = Countif.createCriteriaPredicate(new StringEval(">a*b"));
|
mp = createCriteriaPredicate(new StringEval(">a*b"));
|
||||||
confirmPredicate(false, mp, "a(b");
|
confirmPredicate(false, mp, "a(b");
|
||||||
confirmPredicate(true, mp, "aab");
|
confirmPredicate(true, mp, "aab");
|
||||||
confirmPredicate(false, mp, "a*a");
|
confirmPredicate(false, mp, "a*a");
|
||||||
@ -258,6 +332,9 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
Eval ev = value == null ? (Eval)BlankEval.INSTANCE : new StringEval(value);
|
Eval ev = value == null ? (Eval)BlankEval.INSTANCE : new StringEval(value);
|
||||||
assertEquals(expectedResult, matchPredicate.matches(ev));
|
assertEquals(expectedResult, matchPredicate.matches(ev));
|
||||||
}
|
}
|
||||||
|
private static void confirmPredicate(boolean expectedResult, I_MatchPredicate matchPredicate, ErrorEval value) {
|
||||||
|
assertEquals(expectedResult, matchPredicate.matches(value));
|
||||||
|
}
|
||||||
|
|
||||||
public void testCountifFromSpreadsheet() {
|
public void testCountifFromSpreadsheet() {
|
||||||
final String FILE_NAME = "countifExamples.xls";
|
final String FILE_NAME = "countifExamples.xls";
|
||||||
|
Loading…
Reference in New Issue
Block a user