Throw an exception when a sub-function is undefined in SubFunctionPattern.replace

This commit is contained in:
Riccardo Azzolini 2019-08-12 13:44:55 +02:00
parent feb894bacd
commit fbb6cf590d
4 changed files with 55 additions and 6 deletions

View File

@ -29,7 +29,8 @@ public class PatternRule implements Rule {
* @param target the <code>Pattern</code> used to match functions and capture sub-functions.
* @param replacements the list of <code>Pattern</code>s used to construct replacement functions.
* All sub-functions which are referenced within these <code>Pattern</code>s must be captured
* by <code>target</code>.
* by <code>target</code>, otherwise the {@link #execute} method will throw an
* {@link UndefinedSubFunction} exception when constructing the replacement functions.
*/
public PatternRule(
final String ruleName,
@ -51,7 +52,8 @@ public class PatternRule implements Rule {
* @param target the <code>Pattern</code> used to match functions and capture sub-functions.
* @param replacements the <code>Pattern</code>s used to construct replacement functions.
* All sub-functions which are referenced within these <code>Pattern</code>s must be captured
* by <code>target</code>.
* by <code>target</code>, otherwise the {@link #execute} method will throw an
* {@link UndefinedSubFunction} exception when constructing the replacement functions.
*/
public PatternRule(
final String ruleName,
@ -86,6 +88,13 @@ public class PatternRule implements Rule {
return replacements;
}
/**
* @throws UndefinedSubFunctionException if the target pattern matches, but it doesn't capture all of the
* sub-functions required by the replacement patterns.
* This exception will never be thrown for well-formed rules (like the ones
* returned by {@link RulesDsl#makeRules}), in which the target pattern
* correctly captures all sub-functions referenced by the replacement patterns.
*/
@Override
public ObjectArrayList<Function> execute(final Function func) {
return target.match(func)

View File

@ -0,0 +1,26 @@
package it.cavallium.warppi.math.rules.dsl;
/**
* Thrown when a <code>SubFunctionPattern</code> is used to generate a <code>Function</code>, but the named sub-function
* it references is not defined.
*/
public class UndefinedSubFunctionException extends RuntimeException {
private final String subFunctionName;
/**
* Constructs an <code>UndefinedSubFunction</code> instance with the specified sub-function name.
*
* @param subFunctionName the name of the undefined sub-function.
*/
public UndefinedSubFunctionException(final String subFunctionName) {
super("Sub-function '" + subFunctionName + "' is not defined");
this.subFunctionName = subFunctionName;
}
/**
* @return the name of the undefined sub-function.
*/
public String getSubFunctionName() {
return subFunctionName;
}
}

View File

@ -3,6 +3,7 @@ package it.cavallium.warppi.math.rules.dsl.patterns;
import it.cavallium.warppi.math.Function;
import it.cavallium.warppi.math.MathContext;
import it.cavallium.warppi.math.rules.dsl.Pattern;
import it.cavallium.warppi.math.rules.dsl.UndefinedSubFunctionException;
import java.util.Map;
import java.util.Objects;
@ -29,8 +30,16 @@ public class SubFunctionPattern implements Pattern {
return existingSubFunction == null || existingSubFunction.equals(function);
}
/**
* @throws UndefinedSubFunctionException if the <code>subFunctions</code> <code>Map</code> doesn't contain a
* sub-function with the name specified in this
* <code>SubFunctionPattern</code>'s constructor.
*/
@Override
public Function replace(final MathContext mathContext, final Map<String, Function> subFunctions) {
if (!subFunctions.containsKey(name)) {
throw new UndefinedSubFunctionException(name);
}
return subFunctions.get(name);
}

View File

@ -13,10 +13,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import static org.junit.Assert.*;
@ -39,6 +36,14 @@ public class PatternTest {
assertEquals(func, pattern.replace(mathContext, subFunctions.get()));
}
@Test(expected = UndefinedSubFunctionException.class) // TODO assert exception.getSubFunctionName().equals("x")
public void undefinedSubFunction() {
final Pattern pattern = new SubFunctionPattern("x");
final Map<String, Function> subFunctions = Collections.singletonMap("y", new Number(mathContext, 1));
pattern.replace(mathContext, subFunctions);
}
@Test
public void sumPattern() {
final Pattern pattern = new SumPattern(