| /* |
| * 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.sis.filter; |
| |
| import static org.apache.sis.util.privy.Constants.MILLISECONDS_PER_DAY; |
| |
| // Test dependencies |
| import org.junit.jupiter.api.Test; |
| import static org.junit.jupiter.api.Assertions.*; |
| import org.apache.sis.test.TestCase; |
| import org.apache.sis.test.TestUtilities; |
| import static org.apache.sis.test.Assertions.assertSerializedEquals; |
| |
| // Specific to the geoapi-3.1 and geoapi-4.0 branches: |
| import org.opengis.feature.Feature; |
| import org.opengis.filter.FilterFactory; |
| import org.opengis.filter.TemporalOperator; |
| import org.opengis.filter.TemporalOperatorName; |
| |
| |
| /** |
| * Tests {@link TemporalFilter} implementations. |
| * |
| * @author Johann Sorel (Geomatys) |
| * @author Martin Desruisseaux (Geomatys) |
| */ |
| public final class TemporalFilterTest extends TestCase { |
| /** |
| * The factory to use for creating the objects to test. |
| */ |
| private final FilterFactory<Feature,Object,Object> factory; |
| |
| /** |
| * The filter to test. This field shall be assigned by each {@code testFoo()} method by invoking |
| * a {@link #factory} method with {@link #expression1} and {@link #expression2} in arguments. |
| */ |
| private TemporalOperator<Feature> filter; |
| |
| /** |
| * The expression to test. They are the arguments to be given to {@link #factory} method. |
| * Each expression will return a period made of {@link PeriodLiteral#begin} and {@link PeriodLiteral#end}. |
| */ |
| private final PeriodLiteral expression1, expression2; |
| |
| /** |
| * Creates a new test case. |
| */ |
| public TemporalFilterTest() { |
| factory = DefaultFilterFactory.forFeatures(); |
| expression1 = new PeriodLiteral(); |
| expression2 = new PeriodLiteral(); |
| expression1.begin = expression2.begin = TestUtilities.date("2000-01-01 09:00:00").getTime(); |
| expression1.end = expression2.end = TestUtilities.date("2000-01-05 10:00:00").getTime(); |
| } |
| |
| /** |
| * Performs some validation on newly created filter. |
| * The {@link #filter} field must be initialized before this method is invoked. |
| * |
| * @param name expected filter name. |
| */ |
| private void validate(final TemporalOperatorName name) { |
| assertInstanceOf(TemporalFilter.class, filter); |
| assertEquals(name, filter.getOperatorType()); |
| final var operands = filter.getExpressions(); |
| assertEquals(2, operands.size()); |
| assertSame(expression1, operands.get(0)); |
| assertSame(expression2, operands.get(1)); |
| assertSerializedEquals(filter); |
| } |
| |
| /** |
| * Evaluates the filter with a null resource. |
| * This is okay if all filter operands are literal. |
| */ |
| private boolean evaluate() { |
| return filter.test(null); |
| } |
| |
| /** |
| * Tests "TEquals" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testEquals() { |
| filter = factory.tequals(expression1, expression2); |
| validate(TemporalOperatorName.EQUALS); |
| assertTrue(evaluate()); |
| |
| // Break the "self.end = other.end" condition. |
| expression1.end++; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "Before" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testBefore() { |
| filter = factory.before(expression1, expression2); |
| validate(TemporalOperatorName.BEFORE); |
| assertFalse(evaluate()); |
| |
| // Move before expression 2. |
| expression1.begin -= 10 * MILLISECONDS_PER_DAY; |
| expression1.end -= 10 * MILLISECONDS_PER_DAY; |
| assertTrue(evaluate()); |
| |
| // Break the "self.end < other.begin" condition. |
| expression1.end = expression2.begin; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "After" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testAfter() { |
| filter = factory.after(expression1, expression2); |
| validate(TemporalOperatorName.AFTER); |
| assertFalse(evaluate()); |
| |
| // Move after expression 2. |
| expression1.begin += 10 * MILLISECONDS_PER_DAY; |
| expression1.end += 10 * MILLISECONDS_PER_DAY; |
| assertTrue(evaluate()); |
| |
| // Break the "self.begin > other.end" condition. |
| expression1.begin = expression2.end; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "Begins" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testBegins() { |
| filter = factory.begins(expression1, expression2); |
| validate(TemporalOperatorName.BEGINS); |
| assertFalse(evaluate()); |
| |
| // End before ending of expression 2. |
| expression1.end--; |
| assertTrue(evaluate()); |
| |
| // Break the "self.begin = other.begin" condition. |
| expression1.begin++; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "Ends" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testEnds() { |
| filter = factory.ends(expression1, expression2); |
| validate(TemporalOperatorName.ENDS); |
| assertFalse(evaluate()); |
| |
| // Begin after beginning of expression 2. |
| expression1.begin++; |
| assertTrue(evaluate()); |
| |
| // Break the "self.end = other.end" condition. |
| expression1.end--; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "BegunBy" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testBegunBy() { |
| filter = factory.begunBy(expression1, expression2); |
| validate(TemporalOperatorName.BEGUN_BY); |
| assertFalse(evaluate()); |
| |
| // End after ending of expression 2. |
| expression1.end++; |
| assertTrue(evaluate()); |
| |
| // Break the "self.begin = other.begin" condition. |
| expression1.begin--; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "EndedBy" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testEndedBy() { |
| filter = factory.endedBy(expression1, expression2); |
| validate(TemporalOperatorName.ENDED_BY); |
| assertFalse(evaluate()); |
| |
| // Begin before beginning of expression 2. |
| expression1.begin--; |
| assertTrue(evaluate()); |
| |
| // Break the "self.end = other.end" condition. |
| expression1.end++; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "Meets" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testMeets() { |
| filter = factory.meets(expression1, expression2); |
| validate(TemporalOperatorName.MEETS); |
| assertFalse(evaluate()); |
| |
| // Move before expression 2. |
| expression1.begin -= 10 * MILLISECONDS_PER_DAY; |
| expression1.end -= 10 * MILLISECONDS_PER_DAY; |
| assertFalse(evaluate()); |
| |
| // Met the "self.end = other.begin" condition. |
| expression1.end = expression2.begin; |
| assertTrue(evaluate()); |
| } |
| |
| /** |
| * Tests "MetBy" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testMetBy() { |
| filter = factory.metBy(expression1, expression2); |
| validate(TemporalOperatorName.MET_BY); |
| assertFalse(evaluate()); |
| |
| // Move after expression 2. |
| expression1.begin += 10 * MILLISECONDS_PER_DAY; |
| expression1.end += 10 * MILLISECONDS_PER_DAY; |
| assertFalse(evaluate()); |
| |
| // Met the "self.begin = other.end" condition. |
| expression1.begin = expression2.end; |
| assertTrue(evaluate()); |
| } |
| |
| /** |
| * Tests "During" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testDuring() { |
| filter = factory.during(expression1, expression2); |
| validate(TemporalOperatorName.DURING); |
| assertFalse(evaluate()); |
| |
| // Shrink inside expression 2. |
| expression1.begin++; |
| expression1.end--; |
| assertTrue(evaluate()); |
| |
| // Break the "self.end < other.end" condition. |
| expression1.end += 2; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "TContains" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testContains() { |
| filter = factory.tcontains(expression1, expression2); |
| validate(TemporalOperatorName.CONTAINS); |
| assertFalse(evaluate()); |
| |
| // Expand to encompass expression 2. |
| expression1.begin--; |
| expression1.end++; |
| assertTrue(evaluate()); |
| |
| // Break the "self.end > other.end" condition. |
| expression1.end -= 2; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "TOverlaps" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testOverlaps() { |
| filter = factory.toverlaps(expression1, expression2); |
| validate(TemporalOperatorName.OVERLAPS); |
| assertFalse(evaluate()); |
| |
| // Translate to overlap left part of expression 2. |
| expression1.begin--; |
| expression1.end--; |
| assertTrue(evaluate()); |
| |
| // Break the "self.end < other.end" condition. |
| expression1.end += 2; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "OverlappedBy" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testOverlappedBy() { |
| filter = factory.overlappedBy(expression1, expression2); |
| validate(TemporalOperatorName.OVERLAPPED_BY); |
| assertFalse(evaluate()); |
| |
| // Translate to overlap right part of expression 2. |
| expression1.begin++; |
| expression1.end++; |
| assertTrue(evaluate()); |
| |
| // Break the "self.end > other.end" condition. |
| expression1.end -= 2; |
| assertFalse(evaluate()); |
| } |
| |
| /** |
| * Tests "AnyInteracts" (construction, evaluation, serialization, equality). |
| */ |
| @Test |
| public void testAnyInteracts() { |
| filter = factory.anyInteracts(expression1, expression2); |
| validate(TemporalOperatorName.ANY_INTERACTS); |
| assertTrue(evaluate()); |
| expression1.begin++; |
| assertTrue(evaluate()); |
| expression1.begin -= 2; |
| assertTrue(evaluate()); |
| expression1.end += 2; |
| assertTrue(evaluate()); |
| } |
| } |