blob: 22f21cd7d743b5dbe1bd834a6a38b06a894dfe45 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.uima.fit.util;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.Function;
import org.apache.uima.UIMAFramework;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.fit.util.AnnotationPredicateTestData.RelativePosition;
import org.apache.uima.resource.metadata.TypeSystemDescription;
import org.apache.uima.util.CasCreationUtils;
import org.assertj.core.api.AutoCloseableSoftAssertions;
public class SelectionAssert {
public static void assertSelection(RelativePosition aCondition, RelativeAnnotationPredicate aPredicate,
List<TestCase> aTestCases)
throws Exception {
CAS cas = CasCreationUtils.createCas((TypeSystemDescription) null, null, null);
Type type = cas.getAnnotationType();
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
for (TestCase testCase : aTestCases) {
cas.reset();
// Create annotations
AnnotationFS x = cas.createAnnotation(type, 0, 0);
AnnotationFS y = cas.createAnnotation(type, 0, 0);
// Position the annotations according to the test data
testCase.getTest().apply((beginA, endA, beginB, endB) -> {
FSUtil.setFeature(x, CAS.FEATURE_BASE_NAME_BEGIN, beginA);
FSUtil.setFeature(x, CAS.FEATURE_BASE_NAME_END, endA);
FSUtil.setFeature(y, CAS.FEATURE_BASE_NAME_BEGIN, beginB);
FSUtil.setFeature(y, CAS.FEATURE_BASE_NAME_END, endB);
cas.addFsToIndexes(x);
cas.addFsToIndexes(y);
return true;
});
softly.assertThat(aPredicate.apply(cas, type, x, y)).as(testCase.getDescription())
.isEqualTo(testCase.getValidPositions().contains(aCondition));
}
}
}
public static void assertSelectionIsEqualOnRandomData(TypeByContextSelector aExpected, TypeByContextSelector aActual)
throws Exception {
final int ITERATIONS = 30;
final int TYPES = 5;
TypeSystemDescription tsd = UIMAFramework.getResourceSpecifierFactory().createTypeSystemDescription();
Map<String, Type> types = new LinkedHashMap<>();
for (int i = 0; i < TYPES; i++) {
String typeName = "test.Type" + (i + 1);
tsd.addType(typeName, "", CAS.TYPE_NAME_ANNOTATION);
types.put(typeName, null);
}
CAS randomCas = CasCreationUtils.createCas(tsd, null, null, null);
for (String typeName : types.keySet()) {
types.put(typeName, randomCas.getTypeSystem().getType(typeName));
}
System.out.print("Iteration: ");
try {
Iterator<Type> ti = types.values().iterator();
Type type1 = ti.next();
Type type2 = ti.next();
for (int i = 0; i < ITERATIONS; i++) {
if (i % 10 == 0) {
System.out.print(i);
}
else {
System.out.print(".");
}
initRandomCas(randomCas, 3 * i, 0, types.values().toArray(new Type[types.size()]));
for (AnnotationFS context : randomCas.getAnnotationIndex(type1)) {
List<AnnotationFS> expected = aExpected.select(randomCas, type2, context);
List<AnnotationFS> actual = aActual.select(randomCas, type2, context);
assertThat(actual)
.as("Selected [%s] with context [%s]@[%d..%d]", type2.getShortName(),
type1.getShortName(), context.getBegin(), context.getEnd())
.containsExactlyElementsOf(expected);
}
}
System.out.print(ITERATIONS);
}
finally {
System.out.println();
}
}
private static void initRandomCas(CAS aCas, int aSize, int aMinimumWidth, Type... aTypes) {
Random rnd = new Random();
List<Type> types = new ArrayList<>(asList(aTypes));
// Shuffle the types
for (int n = 0; n < 10; n++) {
Type t = types.remove(rnd.nextInt(types.size()));
types.add(t);
}
// Randomly generate annotations
for (int n = 0; n < aSize; n++) {
for (Type t : types) {
int begin = rnd.nextInt(100);
int end = begin + rnd.nextInt(30) + aMinimumWidth;
aCas.addFsToIndexes(aCas.createAnnotation(t, begin, end));
}
}
}
@FunctionalInterface
public static interface RelativeAnnotationPredicate {
boolean apply(CAS cas, Type type, AnnotationFS x, AnnotationFS y);
}
@FunctionalInterface
public static interface TypeByContextSelector {
List<AnnotationFS> select(CAS aCas, Type aType, AnnotationFS aContext);
}
@FunctionalInterface
public static interface RelativePositionPredicate {
boolean apply(int beginA, int endA, int beginB, int endB);
}
public static class TestCase {
private final String description;
private final Function<RelativePositionPredicate, Boolean> predicate;
private final List<RelativePosition> validPositions;
public TestCase(String aDescription, Function<RelativePositionPredicate, Boolean> aPredicate, List<RelativePosition> aValidPositions) {
description = aDescription;
predicate = aPredicate;
validPositions = aValidPositions;
}
public String getDescription() {
return description;
}
public Function<RelativePositionPredicate, Boolean> getTest() {
return predicate;
}
public List<RelativePosition> getValidPositions() {
return validPositions;
}
}
}