001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *     http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.gbif.api.model.predicate;
015
016import org.gbif.api.model.occurrence.search.OccurrenceSearchParameter;
017
018import java.util.UUID;
019
020import org.junit.jupiter.api.Test;
021
022import static org.hamcrest.CoreMatchers.both;
023import static org.hamcrest.CoreMatchers.equalTo;
024import static org.hamcrest.CoreMatchers.not;
025import static org.hamcrest.MatcherAssert.assertThat;
026import static org.junit.jupiter.api.Assertions.assertThrows;
027import static org.mockito.Mockito.mock;
028
029public class SimplePredicateTest {
030
031  private static final OccurrenceSearchParameter TEST_KEY =
032      OccurrenceSearchParameter.CATALOG_NUMBER;
033  private static final String TEST_VALUE = "bar";
034  private static final OccurrenceSearchParameter COMP_PARAM = OccurrenceSearchParameter.ELEVATION;
035  private static final String COMP_VALUE = "100";
036
037  @Test
038  public void testEmptyConstructor() {
039    assertThrows(IllegalArgumentException.class, () -> new EqualsPredicate<>(TEST_KEY, "", false));
040  }
041
042  @Test
043  public void testEquals() {
044    SimplePredicate<OccurrenceSearchParameter> ep1 =
045        new EqualsPredicate<>(TEST_KEY, TEST_VALUE, false);
046    SimplePredicate<OccurrenceSearchParameter> ep2 =
047        new EqualsPredicate<>(TEST_KEY, TEST_VALUE, false);
048
049    SimplePredicate<OccurrenceSearchParameter> lp1 =
050        new LikePredicate<>(TEST_KEY, TEST_VALUE, true);
051    SimplePredicate<OccurrenceSearchParameter> lp2 =
052        new LikePredicate<>(TEST_KEY, TEST_VALUE, true);
053
054    SimplePredicate<OccurrenceSearchParameter> gt1 =
055        new GreaterThanPredicate<>(COMP_PARAM, COMP_VALUE);
056    SimplePredicate<OccurrenceSearchParameter> gt2 =
057        new GreaterThanPredicate<>(COMP_PARAM, COMP_VALUE);
058
059    SimplePredicate<OccurrenceSearchParameter> lt1 =
060        new LessThanPredicate<>(COMP_PARAM, COMP_VALUE);
061    SimplePredicate<OccurrenceSearchParameter> lt2 =
062        new LessThanPredicate<>(COMP_PARAM, COMP_VALUE);
063
064    SimplePredicate<OccurrenceSearchParameter> gte1 =
065        new GreaterThanOrEqualsPredicate<>(COMP_PARAM, COMP_VALUE);
066    SimplePredicate<OccurrenceSearchParameter> gte2 =
067        new GreaterThanOrEqualsPredicate<>(COMP_PARAM, COMP_VALUE);
068
069    SimplePredicate<OccurrenceSearchParameter> lte1 =
070        new LessThanOrEqualsPredicate<>(COMP_PARAM, COMP_VALUE);
071    SimplePredicate<OccurrenceSearchParameter> lte2 =
072        new LessThanOrEqualsPredicate<>(COMP_PARAM, COMP_VALUE);
073
074    // All of them are equal to themselves
075    assertThat(ep1, equalTo(ep1));
076    assertThat(gt1, equalTo(gt1));
077    assertThat(lt1, equalTo(lt1));
078
079    // But unequal among themselves
080    assertThat(ep1, both(not(equalTo(gt1))).and(not(equalTo(lt1))));
081    assertThat(gt1, both(not(equalTo(ep1))).and(not(equalTo(lt1))));
082    assertThat(lt1, both(not(equalTo(ep1))).and(not(equalTo(gt1))));
083
084    // And certainly unequal to any other Predicate
085    assertThat(ep1, not(equalTo(mock(Predicate.class))));
086
087    // But they are equal to their twins
088    assertThat(ep1, equalTo(ep2));
089    assertThat(lp1, equalTo(lp2));
090    assertThat(gt1, equalTo(gt2));
091    assertThat(lt1, equalTo(lt2));
092    assertThat(gte1, equalTo(gte2));
093    assertThat(lte1, equalTo(lte2));
094
095    ep2 = new EqualsPredicate<>(TEST_KEY, "FOOBAR", false);
096    assertThat(ep1, not(equalTo(ep2)));
097  }
098
099  @Test
100  public void testGoodDoubleValue() {
101    new EqualsPredicate<>(OccurrenceSearchParameter.DECIMAL_LATITUDE, "32", false);
102    new EqualsPredicate<>(OccurrenceSearchParameter.DECIMAL_LATITUDE, "32.032", false);
103    new EqualsPredicate<>(OccurrenceSearchParameter.ELEVATION, "-10,5.5", false);
104    new EqualsPredicate<>(OccurrenceSearchParameter.ELEVATION, "*,200", false);
105    new EqualsPredicate<>(OccurrenceSearchParameter.ELEVATION, "100,*", false);
106  }
107
108  @Test
109  public void testGoodEnumValue() {
110    new EqualsPredicate<>(OccurrenceSearchParameter.BASIS_OF_RECORD, "PRESERVED_SPECIMEN", false);
111  }
112
113  @Test
114  public void testHashcode() {
115    SimplePredicate<OccurrenceSearchParameter> sp1 =
116        new EqualsPredicate<>(TEST_KEY, TEST_VALUE, false);
117    SimplePredicate<OccurrenceSearchParameter> sp2 =
118        new EqualsPredicate<>(TEST_KEY, TEST_VALUE, false);
119    SimplePredicate<OccurrenceSearchParameter> sp3 =
120        new LessThanPredicate<>(COMP_PARAM, COMP_VALUE);
121    SimplePredicate<OccurrenceSearchParameter> sp4 =
122        new GreaterThanPredicate<>(COMP_PARAM, COMP_VALUE);
123
124    assertThat(sp1.hashCode(), equalTo(sp2.hashCode()));
125    assertThat(sp1.hashCode(), not(equalTo(sp3.hashCode())));
126    assertThat(sp3.hashCode(), equalTo(sp4.hashCode()));
127  }
128
129  @Test
130  public void testNullConstructor() {
131    assertThrows(NullPointerException.class, () -> new EqualsPredicate<>(null, null, false));
132  }
133
134  @Test
135  public void testOnlyEqualsAllowed() {
136    assertThrows(
137        IllegalArgumentException.class,
138        () ->
139            new LessThanPredicate<>(
140                OccurrenceSearchParameter.DATASET_KEY, UUID.randomUUID().toString()));
141  }
142
143  @Test
144  public void testSimplePredicateConstruction() {
145    SimplePredicate<OccurrenceSearchParameter> p =
146        new EqualsPredicate<>(TEST_KEY, TEST_VALUE, false);
147    assertThat(p.getKey(), equalTo(TEST_KEY));
148    assertThat(p.getValue(), equalTo(TEST_VALUE));
149  }
150
151  @Test
152  public void testWrongDoubleValue() {
153    assertThrows(
154        IllegalArgumentException.class,
155        () -> new EqualsPredicate<>(OccurrenceSearchParameter.DECIMAL_LATITUDE, "32..312", false));
156  }
157
158  @Test
159  public void testWrongEnumValue() {
160    assertThrows(
161        IllegalArgumentException.class,
162        () -> new EqualsPredicate<>(OccurrenceSearchParameter.BASIS_OF_RECORD, "Specimen", false));
163  }
164
165  @Test
166  public void testWrongDoubleValue2() {
167    assertThrows(
168        IllegalArgumentException.class,
169        () -> new EqualsPredicate<>(OccurrenceSearchParameter.ELEVATION, "0.6s", false));
170  }
171
172  @Test
173  public void testWrongUuidValue() {
174    assertThrows(
175        IllegalArgumentException.class,
176        () ->
177            new EqualsPredicate<>(
178                OccurrenceSearchParameter.DATASET_KEY, "133-4312-443-2-43-32432423-", false));
179  }
180
181  @Test
182  public void testGeometryEquals() {
183    assertThrows(
184        IllegalArgumentException.class,
185        () ->
186            new EqualsPredicate<>(
187                OccurrenceSearchParameter.GEOMETRY,
188                "POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))",
189                false));
190  }
191}