DATAGEODE-302 - Introduce CompositeTypeFilter @FunctionalInterface extending Spring's o.s.core.type.filter.TypeFilter interface.
The SDG CompositeTypeFilter uses the Composite Software Design Pattern to compose multiple TypeFilters as a single, uniform instance of TypeFilter.
This commit is contained in:
@@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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
|
||||||
|
*
|
||||||
|
* https://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.springframework.data.gemfire.support;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
import org.springframework.core.type.filter.TypeFilter;
|
||||||
|
import org.springframework.data.gemfire.util.ArrayUtils;
|
||||||
|
import org.springframework.data.gemfire.util.CollectionUtils;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Spring {@link TypeFilter} implementation using the {@literal Composite Software Design Pattern} to compose multiple
|
||||||
|
* {@link TypeFilter TypeFilters} acting a single instance of {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* @author John Blum
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
* @see <a href="https://en.wikipedia.org/wiki/Composite_pattern">Composite Software Design Pattern</a>
|
||||||
|
* @since 2.4.0
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public interface CompositeTypeFilter extends TypeFilter {
|
||||||
|
|
||||||
|
CompositeTypeFilter ALLOW = (metadataReader, metadataReaderFactory) -> true;
|
||||||
|
CompositeTypeFilter DENY = (metadataReader, metadataReaderFactory) -> false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composes {@literal this} {@link TypeFilter} with the given {@link TypeFilter}
|
||||||
|
* using the {@literal logical AND operator}.
|
||||||
|
*
|
||||||
|
* @param typeFilter {@link TypeFilter} to compose with {@literal this} {@link TypeFilter};
|
||||||
|
* must not be {@literal null}.
|
||||||
|
* @return a composed {@link TypeFilter} consisting of {@literal this} {@link TypeFilter}
|
||||||
|
* and the given {@link TypeFilter}.
|
||||||
|
* @throws IllegalArgumentException if {@link TypeFilter} is {@literal null}.
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
* @see #orThen(TypeFilter)
|
||||||
|
*/
|
||||||
|
default @NonNull CompositeTypeFilter andThen(@NonNull TypeFilter typeFilter) {
|
||||||
|
|
||||||
|
Assert.notNull(typeFilter, "TypeFilter must not be null");
|
||||||
|
|
||||||
|
return (metadataReader, metadataReaderFactory) ->
|
||||||
|
this.match(metadataReader, metadataReaderFactory)
|
||||||
|
&& typeFilter.match(metadataReader, metadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composes the array of {@link TypeFilter TypeFilters} into a {@literal Composite} {@link TypeFilter}
|
||||||
|
* that acts as a single instance of {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* The {@literal Composite} {@link TypeFilter} may be treated as a single instance of {@link TypeFilter}, too,
|
||||||
|
* given {@link CompositeTypeFilter} extends (i.e. "is a") {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* @param array array of {@link TypeFilter TypeFilters} to compose.
|
||||||
|
* @return a {@literal Composite} {@link TypeFilter} composed from the array of {@link TypeFilter TypeFilers}
|
||||||
|
* using the {@literal logical AND operator}; may return {@literal null}.
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
* @see #composeAnd(Iterable)
|
||||||
|
*/
|
||||||
|
static @Nullable TypeFilter composeAnd(@Nullable TypeFilter... array) {
|
||||||
|
return composeAnd(Arrays.asList(ArrayUtils.nullSafeArray(array, TypeFilter.class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composes the {@link Iterable} of {@link TypeFilter TypeFilters} into a {@literal Composite} {@link TypeFilter}
|
||||||
|
* that acts as a single instance of {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* The {@literal Composite} {@link TypeFilter} may be treated as a single instance of {@link TypeFilter}, too,
|
||||||
|
* given {@link CompositeTypeFilter} extends (i.e. "is a") {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* @param iterable {@link Iterable} of {@link TypeFilter TypeFilters} to compose.
|
||||||
|
* @return a {@literal Composite} {@link TypeFilter} composed from the {@link Iterable}
|
||||||
|
* of {@link TypeFilter TypeFilers} using the {@literal logical AND operator}; may return {@literal null}.
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
* @see java.lang.Iterable
|
||||||
|
*/
|
||||||
|
static @Nullable TypeFilter composeAnd(@Nullable Iterable<TypeFilter> iterable) {
|
||||||
|
|
||||||
|
CompositeTypeFilter current = null;
|
||||||
|
|
||||||
|
for (TypeFilter typeFilter : CollectionUtils.nullSafeIterable(iterable)) {
|
||||||
|
if (typeFilter != null) {
|
||||||
|
current = current == null ? of(typeFilter) : current.andThen(typeFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composes the array of {@link TypeFilter TypeFilters} into a {@literal Composite} {@link TypeFilter}
|
||||||
|
* that acts as a single instance of {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* The {@literal Composite} {@link TypeFilter} may be treated as a single instance of {@link TypeFilter}, too,
|
||||||
|
* given {@link CompositeTypeFilter} extends (i.e. "is a") {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* @param array array of {@link TypeFilter TypeFilters} to compose.
|
||||||
|
* @return a {@literal Composite} {@link TypeFilter} composed from the array of {@link TypeFilter TypeFilers}
|
||||||
|
* using the {@literal logical OR operator}; may return {@literal null}.
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
* @see #composeOr(Iterable)
|
||||||
|
*/
|
||||||
|
static @Nullable TypeFilter composeOr(@Nullable TypeFilter... array) {
|
||||||
|
return composeOr(Arrays.asList(ArrayUtils.nullSafeArray(array, TypeFilter.class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composes the {@link Iterable} of {@link TypeFilter TypeFilters} into a {@literal Composite} {@link TypeFilter}
|
||||||
|
* that acts as a single instance of {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* The {@literal Composite} {@link TypeFilter} may be treated as a single instance of {@link TypeFilter}, too,
|
||||||
|
* given {@link CompositeTypeFilter} extends (i.e. "is a") {@link TypeFilter}.
|
||||||
|
*
|
||||||
|
* @param iterable {@link Iterable} of {@link TypeFilter TypeFilters} to compose.
|
||||||
|
* @return a {@literal Composite} {@link TypeFilter} composed from the {@link Iterable}
|
||||||
|
* of {@link TypeFilter TypeFilers} using the {@literal logical OR operator}; may return {@literal null}.
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
* @see java.lang.Iterable
|
||||||
|
*/
|
||||||
|
static @Nullable TypeFilter composeOr(@Nullable Iterable<TypeFilter> iterable) {
|
||||||
|
|
||||||
|
CompositeTypeFilter current = null;
|
||||||
|
|
||||||
|
for (TypeFilter typeFilter : CollectionUtils.nullSafeIterable(iterable)) {
|
||||||
|
if (typeFilter != null) {
|
||||||
|
current = current == null ? of(typeFilter) : current.orThen(typeFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps an existing {@link TypeFilter} in an instance of {@link CompositeTypeFilter}.
|
||||||
|
*
|
||||||
|
* @param typeFilter {@link TypeFilter} to wrap; must not be {@literal null}.
|
||||||
|
* @return a {@link CompositeTypeFilter} wrapping the existing {@link TypeFilter}.
|
||||||
|
* @throws IllegalArgumentException if {@link TypeFilter} is {@literal null}.
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
*/
|
||||||
|
static @NonNull CompositeTypeFilter of(@NonNull TypeFilter typeFilter) {
|
||||||
|
|
||||||
|
Assert.notNull(typeFilter, "TypeFilter to wrap must not be null");
|
||||||
|
|
||||||
|
return (metadataReader, metadataReaderFactory) -> typeFilter.match(metadataReader, metadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Negates the result of {@literal this} {@link TypeFilter TypeFilter's}
|
||||||
|
* {@link #match(MetadataReader, MetadataReaderFactory)} operation.
|
||||||
|
*
|
||||||
|
* @return {@literal this} {@link TypeFilter} negated.
|
||||||
|
* @see org.springframework.data.gemfire.support.CompositeTypeFilter
|
||||||
|
*/
|
||||||
|
default @NonNull CompositeTypeFilter negate() {
|
||||||
|
return (metadataReader, metadataReaderFactory) -> !this.match(metadataReader, metadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composes {@literal this} {@link TypeFilter} with the given {@link TypeFilter}
|
||||||
|
* using the {@literal logical OR operator}.
|
||||||
|
*
|
||||||
|
* @param typeFilter {@link TypeFilter} to compose with {@literal this} {@link TypeFilter};
|
||||||
|
* must not be {@literal null}.
|
||||||
|
* @return a composed {@link TypeFilter} consisting of {@literal this} {@link TypeFilter}
|
||||||
|
* and the given {@link TypeFilter}.
|
||||||
|
* @throws IllegalArgumentException if {@link TypeFilter} is {@literal null}.
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
* @see #andThen(TypeFilter)
|
||||||
|
*/
|
||||||
|
default @NonNull CompositeTypeFilter orThen(@NonNull TypeFilter typeFilter) {
|
||||||
|
|
||||||
|
return (metadataReader, metadataReaderFactory) ->
|
||||||
|
this.match(metadataReader, metadataReaderFactory)
|
||||||
|
|| typeFilter.match(metadataReader, metadataReaderFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,527 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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
|
||||||
|
*
|
||||||
|
* https://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.springframework.data.gemfire.support;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InOrder;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
import org.springframework.core.type.filter.TypeFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit Tests for {@link CompositeTypeFilter}.
|
||||||
|
*
|
||||||
|
* @author John Blum
|
||||||
|
* @see org.junit.Test
|
||||||
|
* @see org.mockito.Mockito
|
||||||
|
* @see org.springframework.core.type.filter.TypeFilter
|
||||||
|
* @see org.springframework.data.gemfire.support.CompositeTypeFilter
|
||||||
|
* @since 2.4.0
|
||||||
|
*/
|
||||||
|
public class CompositeTypeFilterUnitTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void allowTypeFilterMatchReturnsTrue() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.ALLOW.match(mockMetadataReader, mockMetadataReaderFactory)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void denyTypeFilterMatchReturnsFalse() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.DENY.match(mockMetadataReader, mockMetadataReaderFactory)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ofWrapsExistingTypeFilter() {
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilter = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
CompositeTypeFilter compositeTypeFilter = CompositeTypeFilter.of(mockTypeFilter);
|
||||||
|
|
||||||
|
assertThat(compositeTypeFilter).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void ofWithNullTypeFilterThrowsIllegalArgumentException() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
CompositeTypeFilter.of(null);
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException expected) {
|
||||||
|
|
||||||
|
assertThat(expected).hasMessageContaining("TypeFilter to wrap must not be null");
|
||||||
|
assertThat(expected).hasNoCause();
|
||||||
|
|
||||||
|
throw expected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void andThenComposesTrueTrueTypeFilters() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(true).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(true).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilterOne)
|
||||||
|
.andThen(mockTypeFilterTwo)
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(mockTypeFilterOne, mockTypeFilterTwo);
|
||||||
|
|
||||||
|
inOrder.verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
inOrder.verify(mockTypeFilterTwo, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void andThenComposesTrueFalseTypeFilters() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(true).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(false).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilterOne)
|
||||||
|
.andThen(mockTypeFilterTwo)
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isFalse();
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(mockTypeFilterOne, mockTypeFilterTwo);
|
||||||
|
|
||||||
|
inOrder.verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
inOrder.verify(mockTypeFilterTwo, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void andThenComposesFalseTrueTypeFilters() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(false).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(true).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilterOne)
|
||||||
|
.andThen(mockTypeFilterTwo)
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isFalse();
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(mockTypeFilterOne, mockTypeFilterTwo);
|
||||||
|
|
||||||
|
inOrder.verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
inOrder.verify(mockTypeFilterTwo, never()).match(any(), any());
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void andThenComposesFalseFalseTypeFilters() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(false).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(false).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilterOne)
|
||||||
|
.andThen(mockTypeFilterTwo)
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isFalse();
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(mockTypeFilterOne, mockTypeFilterTwo);
|
||||||
|
|
||||||
|
inOrder.verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
inOrder.verify(mockTypeFilterTwo, never()).match(any(), any());
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void negateTrueIsCorrect() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilter = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(true).when(mockTypeFilter).match(any(), any());
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilter)
|
||||||
|
.negate()
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isFalse();
|
||||||
|
|
||||||
|
verify(mockTypeFilter, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verifyNoMoreInteractions(mockTypeFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void negateFalseIsCorrect() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilter = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(false).when(mockTypeFilter).match(any(), any());
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilter)
|
||||||
|
.negate()
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
|
verify(mockTypeFilter, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verifyNoMoreInteractions(mockTypeFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void orThenComposesTrueTrueTypeFilters() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(true).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(true).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilterOne)
|
||||||
|
.orThen(mockTypeFilterTwo)
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(mockTypeFilterOne, mockTypeFilterTwo);
|
||||||
|
|
||||||
|
inOrder.verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
inOrder.verify(mockTypeFilterTwo, never()).match(any(), any());
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void orThenComposesTrueFalseFilters() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(true).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(false).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilterOne)
|
||||||
|
.orThen(mockTypeFilterTwo)
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(mockTypeFilterOne, mockTypeFilterTwo);
|
||||||
|
|
||||||
|
inOrder.verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
inOrder.verify(mockTypeFilterTwo, never()).match(any(), any());
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void orThenComposesFalseTrueFilters() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(false).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(true).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilterOne)
|
||||||
|
.orThen(mockTypeFilterTwo)
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(mockTypeFilterOne, mockTypeFilterTwo);
|
||||||
|
|
||||||
|
inOrder.verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
inOrder.verify(mockTypeFilterTwo, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void orThenComposesFalseFalseFilters() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(false).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(false).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
assertThat(CompositeTypeFilter.of(mockTypeFilterOne)
|
||||||
|
.orThen(mockTypeFilterTwo)
|
||||||
|
.match(mockMetadataReader, mockMetadataReaderFactory))
|
||||||
|
.isFalse();
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(mockTypeFilterOne, mockTypeFilterTwo);
|
||||||
|
|
||||||
|
inOrder.verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
inOrder.verify(mockTypeFilterTwo, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composeAndWithTypeFiltersCallMatchReturnsTrue() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterThree = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(true).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(true).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(true).when(mockTypeFilterThree)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
TypeFilter typeFilter = CompositeTypeFilter.composeAnd(null, mockTypeFilterOne, mockTypeFilterTwo,
|
||||||
|
null, null, mockTypeFilterThree);
|
||||||
|
|
||||||
|
assertThat(typeFilter).isNotNull();
|
||||||
|
assertThat(typeFilter.match(mockMetadataReader, mockMetadataReaderFactory)).isTrue();
|
||||||
|
|
||||||
|
verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verify(mockTypeFilterTwo, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verify(mockTypeFilterThree, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composeAndWithTypeFiltersCallMatchReturnsFalse() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterThree = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(true).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(false).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(true).when(mockTypeFilterThree)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
TypeFilter typeFilter =
|
||||||
|
CompositeTypeFilter.composeAnd(mockTypeFilterOne, mockTypeFilterTwo, mockTypeFilterThree);
|
||||||
|
|
||||||
|
assertThat(typeFilter).isNotNull();
|
||||||
|
assertThat(typeFilter.match(mockMetadataReader, mockMetadataReaderFactory)).isFalse();
|
||||||
|
|
||||||
|
verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verify(mockTypeFilterTwo, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verify(mockTypeFilterThree, never()).match(any(), any());
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composeAndWithEmptyTypeFiltersReturnsNull() {
|
||||||
|
assertThat(CompositeTypeFilter.composeAnd()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composeAndWithNullTypeFiltersIsNullSafeReturnsNull() {
|
||||||
|
assertThat(CompositeTypeFilter.composeAnd((TypeFilter[]) null)).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composeOrWithTypeFiltersCallMatchReturnsTrue() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterThree = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(false).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(true).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(false).when(mockTypeFilterThree)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
TypeFilter typeFilter =
|
||||||
|
CompositeTypeFilter.composeOr(mockTypeFilterOne, null, mockTypeFilterTwo, mockTypeFilterThree, null);
|
||||||
|
|
||||||
|
assertThat(typeFilter).isNotNull();
|
||||||
|
assertThat(typeFilter.match(mockMetadataReader, mockMetadataReaderFactory)).isTrue();
|
||||||
|
|
||||||
|
verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verify(mockTypeFilterTwo, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verify(mockTypeFilterThree, never()).match(any(), any());
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composeOrWithTypeFiltersCallMatchReturnsFalse() throws IOException {
|
||||||
|
|
||||||
|
MetadataReader mockMetadataReader = mock(MetadataReader.class);
|
||||||
|
|
||||||
|
MetadataReaderFactory mockMetadataReaderFactory = mock(MetadataReaderFactory.class);
|
||||||
|
|
||||||
|
TypeFilter mockTypeFilterOne = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterTwo = mock(TypeFilter.class);
|
||||||
|
TypeFilter mockTypeFilterThree = mock(TypeFilter.class);
|
||||||
|
|
||||||
|
doReturn(false).when(mockTypeFilterOne)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(false).when(mockTypeFilterTwo)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
doReturn(false).when(mockTypeFilterThree)
|
||||||
|
.match(any(MetadataReader.class), any(MetadataReaderFactory.class));
|
||||||
|
|
||||||
|
TypeFilter typeFilter =
|
||||||
|
CompositeTypeFilter.composeOr(mockTypeFilterOne, mockTypeFilterTwo, mockTypeFilterThree);
|
||||||
|
|
||||||
|
assertThat(typeFilter).isNotNull();
|
||||||
|
assertThat(typeFilter.match(mockMetadataReader, mockMetadataReaderFactory)).isFalse();
|
||||||
|
|
||||||
|
verify(mockTypeFilterOne, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verify(mockTypeFilterTwo, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
verify(mockTypeFilterThree, times(1))
|
||||||
|
.match(eq(mockMetadataReader), eq(mockMetadataReaderFactory));
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockMetadataReader, mockMetadataReaderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composeOrWithEmptyTypeFiltersReturnsNull() {
|
||||||
|
assertThat(CompositeTypeFilter.composeOr()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void composeOrWithNullTypeFiltersIsNullSafeReturnsNull() {
|
||||||
|
assertThat(CompositeTypeFilter.composeOr((TypeFilter[]) null)).isNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user