1   /* Contributed in the public domain.
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.utils;
18  
19  import org.junit.jupiter.api.Assertions;
20  import org.junit.jupiter.api.BeforeAll;
21  import org.junit.jupiter.api.BeforeEach;
22  import org.junit.jupiter.api.Test;
23  import org.orekit.Utils;
24  import org.orekit.errors.OrekitException;
25  import org.orekit.errors.OrekitMessages;
26  import org.orekit.errors.TimeStampedCacheException;
27  import org.orekit.time.AbsoluteDate;
28  
29  import java.util.Arrays;
30  import java.util.Collections;
31  import java.util.List;
32  
33  /**
34   * Unit tests for {@link SortedListTrimmer}.
35   *
36   * @author Evan Ward
37   */
38  public class SortedListTrimmerTest {
39  
40      /**
41       * arbitrary date
42       */
43      private static final AbsoluteDate date = AbsoluteDate.CCSDS_EPOCH;
44  
45      /**
46       * set Orekit data for useful debugging messages from dates.
47       */
48      @BeforeAll
49      public static void setUpBefore() {
50          Utils.setDataRoot("regular-data");
51      }
52  
53      /**
54       * data provided to {@link #trimmer}
55       */
56      private List<AbsoluteDate> data;
57  
58      /**
59       * subject under test
60       */
61      private SortedListTrimmer trimmer;
62  
63      /**
64       * create {@link #trimmer} and {@link #data} with neighborsSize = 3
65       */
66      @BeforeEach
67      public void setUp() {
68          data = Arrays.asList(date, date.shiftedBy(1), date.shiftedBy(2),
69                               date.shiftedBy(3), date.shiftedBy(4),
70                               date.shiftedBy(5));
71          trimmer = new SortedListTrimmer(3);
72      }
73  
74      /**
75       * check
76       * {@link SortedListTrimmer#getNeighborsSubList(AbsoluteDate, List)}
77       */
78      @Test
79      public void testGetNeighborsSubList() {
80          // exception for neighborsSize > data.size()
81          try {
82              new SortedListTrimmer(data.size() + 1).getNeighborsSubList(date, data);
83              Assertions.fail("Expected Exception");
84          } catch (OrekitException e) {
85              Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, e.getSpecifier());
86          }
87  
88          // exception for non-positive neighborsSize
89          try {
90              new SortedListTrimmer(0);
91              Assertions.fail("Expected Exception");
92          } catch (IllegalArgumentException e) {
93              // expected
94          }
95  
96          // exception for null data
97          try {
98              new SortedListTrimmer(1).getNeighborsSubList(date, null);
99              Assertions.fail("Expected Exception");
100         } catch (NullPointerException e) {
101             // expected
102         }
103 
104         // exception for zero data
105         try {
106             new SortedListTrimmer(1).getNeighborsSubList(date, Collections.emptyList());
107             Assertions.fail("Expected Exception");
108         } catch (OrekitException e) {
109             Assertions.assertEquals(OrekitMessages.NOT_ENOUGH_DATA, e.getSpecifier());
110         }
111     }
112 
113     /**
114      * check {@link SortedListTrimmer#getNeighborsSubList(AbsoluteDate, List)} at a
115      * series of different dates designed to test all logic paths.
116      */
117     @Test
118     public void testGetNeighbors() {
119         // setup
120         int size = data.size();
121 
122         // actions + verify
123 
124         // before fist data
125         try {
126             trimmer.getNeighborsSubList(data.get(0).shiftedBy(-1), data);
127             Assertions.fail("Expected Exception");
128         } catch (TimeStampedCacheException e) {
129             // expected
130             Assertions.assertEquals(OrekitMessages.UNABLE_TO_GENERATE_NEW_DATA_BEFORE, e.getSpecifier());
131         }
132 
133         // on fist date
134         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(0), data).toArray(),
135                                      data.subList(0, 3).toArray());
136         // between fist and second date
137         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(0).shiftedBy(0.5), data).toArray(),
138                                      data.subList(0, 3).toArray());
139         // in the middle on a date
140         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(2), data).toArray(),
141                                      data.subList(1, 4).toArray());
142         // in the middle between dates
143         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(2).shiftedBy(0.5), data).toArray(),
144                                      data.subList(1, 4).toArray());
145         // just before last date
146         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(size - 1).shiftedBy(-0.5), data).toArray(),
147                                      data.subList(size - 3, size).toArray());
148         // on last date
149         Assertions.assertArrayEquals(trimmer.getNeighborsSubList(data.get(size - 1), data).toArray(),
150                                      data.subList(size - 3, size).toArray());
151 
152         // after last date
153         AbsoluteDate central = data.get(size - 1).shiftedBy(1);
154         try {
155             trimmer.getNeighborsSubList(central, data);
156             Assertions.fail("Expected Exception");
157         } catch (TimeStampedCacheException e) {
158             // expected
159            Assertions.assertEquals(OrekitMessages.UNABLE_TO_GENERATE_NEW_DATA_AFTER, e.getSpecifier());
160         }
161     }
162 
163     /** Check findIndex(...) returns results on a half closed interval. */
164     @Test
165     public void testGetNeighborsSingle() {
166         // setup
167         trimmer = new SortedListTrimmer(1);
168         int size = data.size();
169 
170         // actions + verify
171         // on fist date
172         Assertions.assertArrayEquals(
173                 trimmer.getNeighborsSubList(data.get(0), data).toArray(),
174                 data.subList(0, 1).toArray());
175         // between fist and second date
176         Assertions.assertArrayEquals(
177                 trimmer.getNeighborsSubList(data.get(0).shiftedBy(0.5), data).toArray(),
178                 data.subList(0, 1).toArray());
179         // in the middle on a date
180         Assertions.assertArrayEquals(
181                 trimmer.getNeighborsSubList(data.get(2), data).toArray(),
182                 data.subList(2, 3).toArray());
183         // in the middle between dates
184         Assertions.assertArrayEquals(
185                 trimmer.getNeighborsSubList(data.get(2).shiftedBy(0.1), data).toArray(),
186                 data.subList(2, 3).toArray());
187         // just before last date
188         Assertions.assertArrayEquals(
189                 trimmer.getNeighborsSubList(data.get(size - 1).shiftedBy(-0.1), data).toArray(),
190                 data.subList(size - 2, size - 1).toArray());
191         // on last date
192         Assertions.assertArrayEquals(
193                 trimmer.getNeighborsSubList(data.get(size - 1), data).toArray(),
194                 data.subList(size - 1, size).toArray());
195     }
196 
197     /**
198      * check {@link ImmutableTimeStampedCache#getMaxNeighborsSize()}
199      */
200     @Test
201     public void testGetNeighborsSize() {
202         Assertions.assertEquals(trimmer.getNeighborsSize(), 3);
203     }
204 
205     @Test
206     public void testNonLinear() {
207         final List<AbsoluteDate> nonLinearCache = Arrays.asList(date.shiftedBy(10),
208                                                                 date.shiftedBy(14),
209                                                                 date.shiftedBy(18),
210                                                                 date.shiftedBy(23),
211                                                                 date.shiftedBy(30),
212                                                                 date.shiftedBy(36),
213                                                                 date.shiftedBy(45),
214                                                                 date.shiftedBy(55),
215                                                                 date.shiftedBy(67),
216                                                                 date.shiftedBy(90),
217                                                                 date.shiftedBy(118));
218         for (double dt = 10; dt < 118; dt += 0.01) {
219             checkNeighbors(new SortedListTrimmer(2), nonLinearCache, dt);
220         }
221     }
222 
223     private void checkNeighbors(final SortedListTrimmer nonLinearTrimmer,
224                                 final List<AbsoluteDate> nonLinearCache,
225                                 final double offset) {
226         List<AbsoluteDate> s = nonLinearTrimmer.getNeighborsSubList(date.shiftedBy(offset), nonLinearCache);
227         Assertions.assertEquals(2, s.size());
228         Assertions.assertTrue(s.get(0).durationFrom(date) <= offset);
229         Assertions.assertTrue(s.get(1).durationFrom(date) >  offset);
230     }
231 
232 }