next() {
175 | return date -> date.plus(isForward() ? amount : 0 - amount, unit);
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/src/main/java/com/ginsberg/timestream/LocalDateTimeStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import java.time.Duration;
28 | import java.time.LocalDateTime;
29 | import java.time.temporal.ChronoUnit;
30 | import java.util.Objects;
31 | import java.util.function.UnaryOperator;
32 |
33 | /**
34 | * A builder that creates a stream of LocalDateTime objects.
35 | *
36 | *
37 | * {@code
38 | * // Print all of the LocalDateTimes between now and a day from now, every other minute.
39 | * LocalDateTimeStream
40 | * .fromNow()
41 | * .to(1, ChronoUnit.DAYS)
42 | * .every(2, ChronoUnit.MINUTES)
43 | * .stream()
44 | * .forEach(System.out::println);
45 | * }
46 | *
47 | *
48 | * @author Todd Ginsberg (todd@ginsberg.com)
49 | */
50 | public class LocalDateTimeStream extends AbstractComparableStream {
51 | private long amount = 1;
52 | private ChronoUnit unit = ChronoUnit.SECONDS;
53 |
54 | private LocalDateTimeStream(final LocalDateTime from) {
55 | super(from);
56 | }
57 |
58 | /**
59 | * Create a LocalDateTimeStream, starting at LocalDateTime.now().
60 | *
61 | * @return A non-null LocalDateTimeStream.
62 | */
63 | public static LocalDateTimeStream fromNow() {
64 | return new LocalDateTimeStream(LocalDateTime.now());
65 | }
66 |
67 | /**
68 | * Create a LocalDateTimeStream, starting at the given LocalDateTime.
69 | *
70 | * @param from A non-null LocalDateTime to begin the stream with.
71 | * @return A non-null LocalDateTimeStream.
72 | */
73 | public static LocalDateTimeStream from(final LocalDateTime from) {
74 | return new LocalDateTimeStream(from);
75 | }
76 |
77 | /**
78 | * Set the inclusive end point of the stream, using an absolute LocalDateTime.
79 | *
80 | * @param to A nullable LocalDateTime to end the stream with (null means infinite).
81 | * @return A non-null LocalDateTimeStream.
82 | */
83 | public LocalDateTimeStream to(final LocalDateTime to) {
84 | setTo(to);
85 | return this;
86 | }
87 |
88 | /**
89 | * Set the inclusive end point of the stream, using a relative duration.
90 | *
91 | * @param amount The number of units to use when calculating the duration of the stream. May be negative.
92 | * @param unit The non-null unit the amount is denominated in. May not be null.
93 | * @return A non-null LocalDateTimeStream.
94 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
95 | * @see ChronoUnit
96 | */
97 | public LocalDateTimeStream to(int amount,
98 | final ChronoUnit unit) {
99 | Objects.requireNonNull(unit);
100 | setTo(getFrom().plus(amount, unit));
101 | return this;
102 | }
103 |
104 | /**
105 | * Set the exclusive end point of the stream, using an absolute LocalDateTime.
106 | *
107 | * @param until A nullable LocalDateTime to end the stream before (null means infinite).
108 | * @return A non-null LocalDateTimeStream.
109 | */
110 | public LocalDateTimeStream until(final LocalDateTime until) {
111 | setUntil(until);
112 | return this;
113 | }
114 |
115 | /**
116 | * Set the exclusive end point of the stream, using a relative duration.
117 | *
118 | * @param amount The number of units to use when calculating the duration of the stream. May be negative.
119 | * @param unit The non-null unit the amount is denominated in.
120 | * @return A non-null LocalDateTimeStream.
121 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
122 | * @see ChronoUnit
123 | */
124 | public LocalDateTimeStream until(int amount,
125 | final ChronoUnit unit) {
126 | Objects.requireNonNull(unit);
127 | setUntil(getFrom().plus(amount, unit));
128 | return this;
129 | }
130 |
131 | /**
132 | * Set the duration between successive elements produced by the stream. The default
133 | * for this builder is 1 Second.
134 | *
135 | * @param amount The number of units to use when calculating the next element of the stream.
136 | * @param unit The non-null unit the amount is denominated in.
137 | * @return A non-null LocalDateTimeStream.
138 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
139 | * @see ChronoUnit
140 | */
141 | public LocalDateTimeStream every(int amount,
142 | final ChronoUnit unit) {
143 | Objects.requireNonNull(unit);
144 | this.amount = Math.abs(amount);
145 | this.unit = unit;
146 | if (this.amount == 0) {
147 | throw new IllegalArgumentException("Amount must be non-zero");
148 | }
149 | return this;
150 | }
151 |
152 | /**
153 | * Set the duration between successive elements produced by the stream. The default
154 | * for this builder is 1 Second.
155 | *
156 | * @param duration The interval to use when calculating the next element of the stream.
157 | * @return A non-null LocalDateTimeStream.
158 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
159 | * @see ChronoUnit
160 | */
161 | public LocalDateTimeStream every(final Duration duration) {
162 | Objects.requireNonNull(unit);
163 | this.unit = ChronoUnit.SECONDS;
164 | this.amount = Math.abs(duration.get(this.unit));
165 | if (this.amount == 0) {
166 | throw new IllegalArgumentException("Effective amount must be non-zero (Duration resolves to zero duration)");
167 | }
168 | return this;
169 | }
170 |
171 | @Override
172 | UnaryOperator next() {
173 | return date -> date.plus(isForward() ? amount : 0 - amount, unit);
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/main/java/com/ginsberg/timestream/TakeWhile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import java.util.Spliterator;
28 | import java.util.Spliterators;
29 | import java.util.function.Consumer;
30 | import java.util.function.Predicate;
31 |
32 | /**
33 | * Implementation of TakeWhile, which makes most of this library possible.
34 | *
35 | * This behavior (along with the complementary dropWhile) is coming
36 | * in JDK 9, but since I need it now, here it is.
37 | *
38 | * @param Type that the predicate and spliterator handle.
39 | * @see java.util.Spliterators.AbstractSpliterator
40 | * @author Todd Ginsberg (todd@ginsberg.com)
41 | */
42 | public class TakeWhile extends Spliterators.AbstractSpliterator {
43 |
44 | private final Spliterator spliterator;
45 | private final Predicate super T> predicate;
46 | private boolean hasEnded = false;
47 |
48 | public static TakeWhile of(final Spliterator spliterator,
49 | final Predicate super T> predicate) {
50 | return new TakeWhile<>(spliterator, predicate);
51 | }
52 |
53 | private TakeWhile(final Spliterator spliterator,
54 | final Predicate super T> predicate) {
55 | super(spliterator.estimateSize(), 0);
56 | this.spliterator = spliterator;
57 | this.predicate = predicate;
58 | }
59 |
60 | @Override
61 | public boolean tryAdvance(final Consumer super T> consumer) {
62 | if (!hasEnded) {
63 | final boolean hadNext = spliterator.tryAdvance(e -> {
64 | if (predicate.test(e)) {
65 | consumer.accept(e);
66 | } else {
67 | hasEnded = true;
68 | }
69 | });
70 | return hadNext && !hasEnded;
71 | }
72 | return false;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/ginsberg/timestream/YearMonthStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import java.time.Period;
28 | import java.time.YearMonth;
29 | import java.time.temporal.ChronoUnit;
30 | import java.util.Objects;
31 | import java.util.function.UnaryOperator;
32 |
33 | /**
34 | * A builder that creates a stream of YearMonth objects.
35 | *
36 | *
37 | * {@code
38 | * // Print all of the YearMonths between now and a year from now, every other month.
39 | * YearMonthStream
40 | * .fromNow()
41 | * .to(1, ChronoUnit.YEARS)
42 | * .every(2, ChronoUnit.MONTHS)
43 | * .stream()
44 | * .forEach(System.out::println);
45 | * }
46 | *
47 | *
48 | * @author Todd Ginsberg (todd@ginsberg.com)
49 | */
50 | public class YearMonthStream extends AbstractComparableStream {
51 | private long amount = 1;
52 | private ChronoUnit unit = ChronoUnit.MONTHS;
53 |
54 | private YearMonthStream(final YearMonth from) {
55 | super(from);
56 | }
57 |
58 | /**
59 | * Create a YearMonthStream, starting at YearMonth.now().
60 | *
61 | * @return A non-null YearMonthStream.
62 | */
63 | public static YearMonthStream fromNow() {
64 | return new YearMonthStream(YearMonth.now());
65 | }
66 |
67 | /**
68 | * Create a YearMonthStream, starting at the given YearMonth.
69 | *
70 | * @param from A non-null YearMonth to begin the stream with.
71 | * @return A non-null YearMonthStream.
72 | */
73 | public static YearMonthStream from(final YearMonth from) {
74 | return new YearMonthStream(from);
75 | }
76 |
77 | /**
78 | * Set the inclusive end point of the stream, using an absolute YearMonth.
79 | *
80 | * @param to A nullable YearMonth to end the stream with (null means infinite).
81 | * @return A non-null YearMonthStream.
82 | */
83 | public YearMonthStream to(final YearMonth to) {
84 | setTo(to);
85 | return this;
86 | }
87 |
88 | /**
89 | * Set the inclusive end point of the stream, using a relative duration.
90 | *
91 | * @param amount The number of units to use when calculating the duration of the stream. May be negative.
92 | * @param unit The non-null unit the amount is denominated in. May not be null.
93 | * @return A non-null YearMonthStream.
94 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
95 | * @see ChronoUnit
96 | */
97 | public YearMonthStream to(int amount,
98 | final ChronoUnit unit) {
99 | Objects.requireNonNull(unit);
100 | setTo(getFrom().plus(amount, unit));
101 | return this;
102 | }
103 |
104 | /**
105 | * Set the exclusive end point of the stream, using an absolute YearMonth.
106 | *
107 | * @param until A nullable YearMonth to end the stream before (null means infinite).
108 | * @return A non-null YearMonthStream.
109 | */
110 | public YearMonthStream until(final YearMonth until) {
111 | setUntil(until);
112 | return this;
113 | }
114 |
115 | /**
116 | * Set the exclusive end point of the stream, using a relative duration.
117 | *
118 | * @param amount The number of units to use when calculating the duration of the stream. May be negative.
119 | * @param unit The non-null unit the amount is denominated in.
120 | * @return A non-null YearMonthStream.
121 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
122 | * @see ChronoUnit
123 | */
124 | public YearMonthStream until(int amount,
125 | final ChronoUnit unit) {
126 | Objects.requireNonNull(unit);
127 | setUntil(getFrom().plus(amount, unit));
128 | return this;
129 | }
130 |
131 | /**
132 | * Set the duration between successive elements produced by the stream. The default
133 | * for this builder is 1 Month.
134 | *
135 | * @param amount The number of units to use when calculating the next element of the stream.
136 | * @param unit The non-null unit the amount is denominated in.
137 | * @return A non-null YearMonthStream.
138 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
139 | * @see ChronoUnit
140 | */
141 | public YearMonthStream every(int amount,
142 | final ChronoUnit unit) {
143 | Objects.requireNonNull(unit);
144 | this.amount = Math.abs(amount);
145 | this.unit = unit;
146 | YearMonth.now().plus(0, unit); // Fail fast test
147 | if (this.amount == 0) {
148 | throw new IllegalArgumentException("Amount must be non-zero");
149 | }
150 | return this;
151 | }
152 |
153 | /**
154 | * Set the duration between successive elements produced by the stream. The default
155 | * for this builder is 1 Month.
156 | *
157 | * @return A non-null YearMonthStream.
158 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
159 | * @see ChronoUnit
160 | */
161 | public YearMonthStream every(final Period period) {
162 | Objects.requireNonNull(unit);
163 | this.unit = ChronoUnit.MONTHS;
164 | this.amount = Math.abs(period.get(this.unit));
165 | YearMonth.now().plus(0, unit); // Fail fast test
166 | if (this.amount == 0) {
167 | throw new IllegalArgumentException("Effective amount must be non-zero (Period resolves to zero duration)");
168 | }
169 | return this;
170 | }
171 |
172 | @Override
173 | UnaryOperator next() {
174 | return date -> date.plus(isForward() ? amount : 0 - amount, unit);
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/src/main/java/com/ginsberg/timestream/ZonedDateTimeStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import java.time.Duration;
28 | import java.time.ZonedDateTime;
29 | import java.time.temporal.ChronoUnit;
30 | import java.util.Objects;
31 | import java.util.function.UnaryOperator;
32 |
33 | /**
34 | * A builder that creates a stream of ZonedDateTime objects.
35 | *
36 | *
37 | * {@code
38 | * // Print all of the ZonedDateTimes between now and a day from now, every other minute.
39 | * ZonedDateTimeStream
40 | * .fromNow()
41 | * .to(1, ChronoUnit.DAYS)
42 | * .every(2, ChronoUnit.MINUTES)
43 | * .stream()
44 | * .forEach(System.out::println);
45 | * }
46 | *
47 | *
48 | * @author Todd Ginsberg (todd@ginsberg.com)
49 | */
50 | public class ZonedDateTimeStream extends AbstractComparableStream {
51 | private long amount = 1;
52 | private ChronoUnit unit = ChronoUnit.SECONDS;
53 |
54 | private ZonedDateTimeStream(final ZonedDateTime from) {
55 | super(from);
56 | }
57 |
58 | /**
59 | * Create a ZonedDateTimeStream, starting at ZonedDateTime.now().
60 | *
61 | * @return A non-null ZonedDateTimeStream.
62 | */
63 | public static ZonedDateTimeStream fromNow() {
64 | return new ZonedDateTimeStream(ZonedDateTime.now());
65 | }
66 |
67 | /**
68 | * Create a ZonedDateTimeStream, starting at the given ZonedDateTime.
69 | *
70 | * @param from A non-null ZonedDateTime to begin the stream with.
71 | * @return A non-null ZonedDateTimeStream.
72 | */
73 | public static ZonedDateTimeStream from(final ZonedDateTime from) {
74 | return new ZonedDateTimeStream(from);
75 | }
76 |
77 | /**
78 | * Set the inclusive end point of the stream, using an absolute ZonedDateTime.
79 | *
80 | * @param to A nullable ZonedDateTime to end the stream with (null means infinite).
81 | * @return A non-null ZonedDateTimeStream.
82 | */
83 | public ZonedDateTimeStream to(final ZonedDateTime to) {
84 | setTo(to);
85 | return this;
86 | }
87 |
88 | /**
89 | * Set the inclusive end point of the stream, using a relative duration.
90 | *
91 | * @param amount The number of units to use when calculating the duration of the stream. May be negative.
92 | * @param unit The non-null unit the amount is denominated in. May not be null.
93 | * @return A non-null ZonedDateTimeStream.
94 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
95 | * @see ChronoUnit
96 | */
97 | public ZonedDateTimeStream to(int amount,
98 | final ChronoUnit unit) {
99 | Objects.requireNonNull(unit);
100 | setTo(getFrom().plus(amount, unit));
101 | return this;
102 | }
103 |
104 | /**
105 | * Set the exclusive end point of the stream, using an absolute ZonedDateTime.
106 | *
107 | * @param until A nullable ZonedDateTime to end the stream before (null means infinite).
108 | * @return A non-null ZonedDateTimeStream.
109 | */
110 | public ZonedDateTimeStream until(final ZonedDateTime until) {
111 | setUntil(until);
112 | return this;
113 | }
114 |
115 | /**
116 | * Set the exclusive end point of the stream, using a relative duration.
117 | *
118 | * @param amount The number of units to use when calculating the duration of the stream. May be negative.
119 | * @param unit The non-null unit the amount is denominated in.
120 | * @return A non-null ZonedDateTimeStream.
121 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
122 | * @see ChronoUnit
123 | */
124 | public ZonedDateTimeStream until(int amount,
125 | final ChronoUnit unit) {
126 | Objects.requireNonNull(unit);
127 | setUntil(getFrom().plus(amount, unit));
128 | return this;
129 | }
130 |
131 | /**
132 | * Set the duration between successive elements produced by the stream. The default
133 | * for this builder is 1 Second.
134 | *
135 | * @param amount The number of units to use when calculating the next element of the stream.
136 | * @param unit The non-null unit the amount is denominated in.
137 | * @return A non-null ZonedDateTimeStream.
138 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
139 | * @see ChronoUnit
140 | */
141 | public ZonedDateTimeStream every(int amount,
142 | final ChronoUnit unit) {
143 | Objects.requireNonNull(unit);
144 | this.amount = Math.abs(amount);
145 | this.unit = unit;
146 | if (this.amount == 0) {
147 | throw new IllegalArgumentException("Amount must be non-zero");
148 | }
149 | return this;
150 | }
151 |
152 | /**
153 | * Set the duration between successive elements produced by the stream. The default
154 | * for this builder is 1 Second.
155 | *
156 | * @return A non-null ZonedDateTimeStream.
157 | * @throws java.time.temporal.UnsupportedTemporalTypeException if the unit is not supported.
158 | * @see ChronoUnit
159 | */
160 | public ZonedDateTimeStream every(final Duration duration) {
161 | Objects.requireNonNull(unit);
162 | this.unit = ChronoUnit.SECONDS;
163 | this.amount = Math.abs(duration.get(this.unit));
164 | if (this.amount == 0) {
165 | throw new IllegalArgumentException("Effective amount must be non-zero (Duration resolves to zero duration)");
166 | }
167 | return this;
168 | }
169 |
170 | @Override
171 | UnaryOperator next() {
172 | return date -> date.plus(isForward() ? amount : 0 - amount, unit);
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/src/test/java/com/ginsberg/timestream/LocalDateStreamTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import org.assertj.core.util.Sets;
28 | import org.junit.Test;
29 |
30 | import java.time.LocalDate;
31 | import java.time.Period;
32 | import java.time.temporal.ChronoUnit;
33 | import java.util.Set;
34 | import java.util.stream.Stream;
35 |
36 | import static com.ginsberg.timestream.util.Assertions.expectingChronoUnitException;
37 | import static com.ginsberg.timestream.util.Assertions.notExpectingChronoUnitException;
38 | import static org.assertj.core.api.Assertions.assertThat;
39 |
40 | public class LocalDateStreamTest {
41 |
42 | private final LocalDate now = LocalDate.now();
43 | private final Set validChronoUnits = Sets.newLinkedHashSet(ChronoUnit.DAYS, ChronoUnit.WEEKS,
44 | ChronoUnit.MONTHS, ChronoUnit.YEARS, ChronoUnit.DECADES, ChronoUnit.CENTURIES,
45 | ChronoUnit.ERAS, ChronoUnit.MILLENNIA);
46 |
47 | @Test
48 | public void stopsBeforeUntilDateGivenByChronoUnits() {
49 | final Stream stream = LocalDateStream
50 | .from(now)
51 | .until(2, ChronoUnit.DAYS)
52 | .stream();
53 | assertThat(stream)
54 | .isNotNull()
55 | .containsExactly(now, now.plusDays(1));
56 | }
57 |
58 | @Test
59 | public void stopsBeforeUntilDateGivenByLocalDate() {
60 | final Stream stream = LocalDateStream
61 | .from(now)
62 | .until(now.plusDays(2))
63 | .stream();
64 | assertThat(stream)
65 | .isNotNull()
66 | .containsExactly(now, now.plusDays(1));
67 | }
68 |
69 | @Test
70 | public void stopsOnToDateGivenByChronoUnits() {
71 | final Stream stream = LocalDateStream
72 | .from(now)
73 | .to(2, ChronoUnit.DAYS)
74 | .stream();
75 | assertThat(stream)
76 | .isNotNull()
77 | .containsExactly(now, now.plusDays(1), now.plusDays(2));
78 | }
79 |
80 | @Test
81 | public void stopsOnToDateGivenByLocalDate() {
82 | final Stream stream = LocalDateStream
83 | .from(now)
84 | .to(now.plusDays(2))
85 | .stream();
86 | assertThat(stream)
87 | .isNotNull()
88 | .containsExactly(now, now.plusDays(1), now.plusDays(2));
89 | }
90 |
91 | @Test
92 | public void stopsBeforeToWhenEveryIsAfterEndDate() {
93 | final Stream stream = LocalDateStream
94 | .from(now)
95 | .to(3, ChronoUnit.DAYS)
96 | .every(2, ChronoUnit.DAYS)
97 | .stream();
98 | assertThat(stream)
99 | .isNotNull()
100 | .containsExactly(now, now.plusDays(2));
101 | }
102 |
103 | @Test
104 | public void negativeEveryUnitStillGoesForward() {
105 | final Stream stream = LocalDateStream
106 | .from(now)
107 | .to(3, ChronoUnit.DAYS)
108 | .every(-2, ChronoUnit.DAYS)
109 | .stream();
110 | assertThat(stream)
111 | .isNotNull()
112 | .containsExactly(now, now.plusDays(2));
113 | }
114 |
115 | @Test
116 | public void negativeEveryPeriodStillGoesForward() {
117 | final Stream stream = LocalDateStream
118 | .from(now)
119 | .to(3, ChronoUnit.DAYS)
120 | .every(Period.parse("-P2D"))
121 | .stream();
122 | assertThat(stream)
123 | .isNotNull()
124 | .containsExactly(now, now.plusDays(2));
125 | }
126 |
127 | @Test
128 | public void positiveEveryUnitStillGoesBackward() {
129 | final Stream stream = LocalDateStream
130 | .from(now)
131 | .to(-3, ChronoUnit.DAYS)
132 | .every(2, ChronoUnit.DAYS)
133 | .stream();
134 | assertThat(stream)
135 | .isNotNull()
136 | .containsExactly(now, now.minusDays(2));
137 | }
138 |
139 | @Test
140 | public void positiveEveryPeriodStillGoesBackward() {
141 | final Stream stream = LocalDateStream
142 | .from(now)
143 | .to(-3, ChronoUnit.DAYS)
144 | .every(Period.parse("P2D"))
145 | .stream();
146 | assertThat(stream)
147 | .isNotNull()
148 | .containsExactly(now, now.minusDays(2));
149 | }
150 |
151 | @Test
152 | public void identicalFromAndToCreateOnePointStream() {
153 | final Stream stream = LocalDateStream
154 | .from(now)
155 | .to(now)
156 | .stream();
157 | assertThat(stream)
158 | .isNotNull()
159 | .containsExactly(now);
160 | }
161 |
162 | @Test
163 | public void noToDateRunsForever() {
164 | // No real way to test that a stream never ends so we will just make sure that this generates a lot of iterations.
165 | final int iterations = 1_000_000;
166 | final Stream stream = LocalDateStream
167 | .from(now)
168 | .stream()
169 | .limit(iterations);
170 | assertThat(stream)
171 | .isNotNull()
172 | .endsWith(now.plus(iterations - 1, ChronoUnit.DAYS))
173 | .hasSize(iterations);
174 | }
175 |
176 | @Test
177 | public void toBeforeFromRunsBackThroughTime() {
178 | final Stream stream = LocalDateStream
179 | .from(now)
180 | .to(-2, ChronoUnit.DAYS)
181 | .stream();
182 | assertThat(stream)
183 | .isNotNull()
184 | .containsExactly(now, now.minusDays(1), now.minusDays(2));
185 | }
186 |
187 | @Test
188 | public void stopsBeforeToWhenEveryPeriodIsAfterEndDate() {
189 | final Period period = Period.parse("P15D");
190 | final Stream stream = LocalDateStream
191 | .from(now)
192 | .until(now.plusDays(30))
193 | .every(period)
194 | .stream();
195 | assertThat(stream)
196 | .isNotNull()
197 | .containsExactly(now, now.plusDays(15));
198 | }
199 |
200 | @Test(expected = NullPointerException.class)
201 | public void mustHaveFromDate() {
202 | LocalDateStream.from(null);
203 | }
204 |
205 | @Test(expected = NullPointerException.class)
206 | public void toByUnitsMustHaveUnit() {
207 | LocalDateStream.fromNow().to(1, null);
208 | }
209 |
210 | @Test(expected = NullPointerException.class)
211 | public void untilByUnitsMustHaveUnit() {
212 | LocalDateStream.fromNow().until(1, null);
213 | }
214 |
215 | @Test(expected = NullPointerException.class)
216 | public void everyMustHavePeriod() {
217 | LocalDateStream.fromNow().every(null);
218 | }
219 |
220 | @Test(expected = IllegalArgumentException.class)
221 | public void everyMustHaveNonZeroAmount() {
222 | LocalDateStream.fromNow().every(0, ChronoUnit.DAYS);
223 | }
224 |
225 | @Test(expected = IllegalArgumentException.class)
226 | public void everyMustHaveNonZeroAmountFromPeriod() {
227 | LocalDateStream.fromNow().every(Period.parse("P0D"));
228 | }
229 |
230 | @Test
231 | public void everyWithInvalidChronoUnitFailsFast() {
232 | expectingChronoUnitException(u -> LocalDateStream.fromNow().every(1, u), validChronoUnits);
233 | }
234 |
235 | @Test
236 | public void everyWithValidChronoUnit() {
237 | notExpectingChronoUnitException(u -> LocalDateStream.fromNow().every(1, u), validChronoUnits);
238 | }
239 |
240 | @Test
241 | public void toWithInvalidChronoUnitFailsFast() {
242 | expectingChronoUnitException(u -> LocalDateStream.fromNow().to(0, u), validChronoUnits);
243 | }
244 |
245 | @Test
246 | public void toWithValidChronoUnit() {
247 | notExpectingChronoUnitException(u -> LocalDateStream.fromNow().to(0, u), validChronoUnits);
248 | }
249 |
250 | @Test
251 | public void untilWithInvalidChronoUnitFailsFast() {
252 | expectingChronoUnitException(u -> LocalDateStream.fromNow().until(0, u), validChronoUnits);
253 | }
254 |
255 | @Test
256 | public void untilWithValidChronoUnit() {
257 | notExpectingChronoUnitException(u -> LocalDateStream.fromNow().until(0, u), validChronoUnits);
258 | }
259 | }
--------------------------------------------------------------------------------
/src/test/java/com/ginsberg/timestream/LocalDateTimeStreamTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import org.junit.Test;
28 |
29 | import java.time.Duration;
30 | import java.time.LocalDateTime;
31 | import java.time.temporal.ChronoUnit;
32 | import java.util.stream.Stream;
33 |
34 | import static org.assertj.core.api.Assertions.assertThat;
35 |
36 | public class LocalDateTimeStreamTest {
37 |
38 | final LocalDateTime now = LocalDateTime.now();
39 |
40 | @Test
41 | public void stopsBeforeUntilDateGivenByChronoUnits() {
42 | final Stream stream = LocalDateTimeStream
43 | .from(now)
44 | .until(2, ChronoUnit.SECONDS)
45 | .stream();
46 | assertThat(stream)
47 | .isNotNull()
48 | .containsExactly(now, now.plusSeconds(1));
49 | }
50 |
51 | @Test
52 | public void stopsBeforeUntilDateGivenByLocalDateTime() {
53 | final Stream stream = LocalDateTimeStream
54 | .from(now)
55 | .until(now.plusSeconds(2))
56 | .stream();
57 | assertThat(stream)
58 | .isNotNull()
59 | .containsExactly(now, now.plusSeconds(1));
60 | }
61 |
62 | @Test
63 | public void stopsOnToDateGivenByChronoUnits() {
64 | final Stream stream = LocalDateTimeStream
65 | .from(now)
66 | .to(2, ChronoUnit.SECONDS)
67 | .stream();
68 | assertThat(stream)
69 | .isNotNull()
70 | .containsExactly(now, now.plusSeconds(1), now.plusSeconds(2));
71 | }
72 |
73 | @Test
74 | public void stopsOnToDateGivenByLocalDateTime() {
75 | final Stream stream = LocalDateTimeStream
76 | .from(now)
77 | .to(now.plusSeconds(2))
78 | .stream();
79 | assertThat(stream)
80 | .isNotNull()
81 | .containsExactly(now, now.plusSeconds(1), now.plusSeconds(2));
82 | }
83 |
84 | @Test
85 | public void stopsBeforeToWhenEveryIsAfterEndDate() {
86 | final Stream stream = LocalDateTimeStream
87 | .from(now)
88 | .to(3, ChronoUnit.SECONDS)
89 | .every(2, ChronoUnit.SECONDS)
90 | .stream();
91 | assertThat(stream)
92 | .isNotNull()
93 | .containsExactly(now, now.plusSeconds(2));
94 | }
95 |
96 | @Test
97 | public void identicalFromAndToCreateOnePointStream() {
98 | final Stream stream = LocalDateTimeStream
99 | .from(now)
100 | .to(now)
101 | .stream();
102 | assertThat(stream)
103 | .isNotNull()
104 | .containsExactly(now);
105 | }
106 |
107 | @Test
108 | public void noToDateRunsForever() {
109 | // No real way to test that a stream never ends so we will just make sure that this generates a lot of iterations.
110 | final int iterations = 1_000_000;
111 | final Stream stream = LocalDateTimeStream
112 | .from(now)
113 | .stream()
114 | .limit(iterations);
115 | assertThat(stream)
116 | .isNotNull()
117 | .endsWith(now.plus(iterations - 1, ChronoUnit.SECONDS))
118 | .hasSize(iterations);
119 | }
120 |
121 | @Test
122 | public void toBeforeFromRunsBackThroughTime() {
123 | final Stream stream = LocalDateTimeStream
124 | .from(now)
125 | .to(-2, ChronoUnit.SECONDS)
126 | .stream();
127 | assertThat(stream)
128 | .isNotNull()
129 | .containsExactly(now, now.minusSeconds(1), now.minusSeconds(2));
130 | }
131 |
132 | @Test
133 | public void stopsBeforeToWhenEveryDurationIsAfterEndDate() {
134 | final Duration duration = Duration.parse("PT2S");
135 | final Stream stream = LocalDateTimeStream
136 | .from(now)
137 | .to(3, ChronoUnit.SECONDS)
138 | .every(duration)
139 | .stream();
140 | assertThat(stream)
141 | .isNotNull()
142 | .containsExactly(now, now.plusSeconds(2));
143 | }
144 |
145 | @Test
146 | public void positiveEveryUnitStillGoesBackward() {
147 | final Stream stream = LocalDateTimeStream
148 | .from(now)
149 | .to(-3, ChronoUnit.SECONDS)
150 | .every(2, ChronoUnit.SECONDS)
151 | .stream();
152 | assertThat(stream)
153 | .isNotNull()
154 | .containsExactly(now, now.minusSeconds(2));
155 | }
156 |
157 | @Test
158 | public void positiveEveryDurationStillGoesBackward() {
159 | final Stream stream = LocalDateTimeStream
160 | .from(now)
161 | .to(-3, ChronoUnit.SECONDS)
162 | .every(Duration.parse("PT2S"))
163 | .stream();
164 | assertThat(stream)
165 | .isNotNull()
166 | .containsExactly(now, now.minusSeconds(2));
167 | }
168 |
169 | @Test
170 | public void negativeEveryUnitStillGoesForward() {
171 | final Stream stream = LocalDateTimeStream
172 | .from(now)
173 | .to(3, ChronoUnit.SECONDS)
174 | .every(-2, ChronoUnit.SECONDS)
175 | .stream();
176 | assertThat(stream)
177 | .isNotNull()
178 | .containsExactly(now, now.plusSeconds(2));
179 | }
180 |
181 | @Test
182 | public void negativeEveryDurationStillGoesForward() {
183 | final Stream stream = LocalDateTimeStream
184 | .from(now)
185 | .to(3, ChronoUnit.SECONDS)
186 | .every(Duration.parse("-PT2S"))
187 | .stream();
188 | assertThat(stream)
189 | .isNotNull()
190 | .containsExactly(now, now.plusSeconds(2));
191 | }
192 |
193 | @Test(expected = NullPointerException.class)
194 | public void mustHaveFromDate() {
195 | LocalDateTimeStream.from(null);
196 | }
197 |
198 | @Test(expected = NullPointerException.class)
199 | public void toByUnitsMustHaveUnit() {
200 | LocalDateTimeStream.fromNow().to(1, null);
201 | }
202 |
203 | @Test(expected = NullPointerException.class)
204 | public void untilByUnitsMustHaveUnit() {
205 | LocalDateTimeStream.fromNow().until(1, null);
206 | }
207 |
208 | @Test(expected = NullPointerException.class)
209 | public void everyMustHaveDuration() {
210 | LocalDateTimeStream.fromNow().every(null);
211 | }
212 |
213 | @Test(expected = IllegalArgumentException.class)
214 | public void everyMustHaveNonZeroAmount() {
215 | LocalDateTimeStream.fromNow().every(0, ChronoUnit.SECONDS);
216 | }
217 |
218 | @Test(expected = IllegalArgumentException.class)
219 | public void everyMustHaveNonZeroAmountFromPeriod() {
220 | LocalDateTimeStream.fromNow().every(Duration.parse("PT0S"));
221 | }
222 | }
--------------------------------------------------------------------------------
/src/test/java/com/ginsberg/timestream/TakeWhileTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import org.junit.Test;
28 |
29 | import java.util.Arrays;
30 | import java.util.Collections;
31 | import java.util.stream.Stream;
32 | import java.util.stream.StreamSupport;
33 |
34 | import static org.assertj.core.api.Assertions.assertThat;
35 |
36 | public class TakeWhileTest {
37 |
38 | @Test
39 | public void stopsWhenPredicateReturnsFirstFalse() {
40 | final Stream realStream = Arrays.asList("A", "B", "A", "B").stream();
41 | final TakeWhile takeWhile = TakeWhile.of(realStream.spliterator(), s -> s.equalsIgnoreCase("A"));
42 | final Stream limitedStream = StreamSupport.stream(takeWhile, false);
43 | assertThat(limitedStream).containsExactly("A");
44 | }
45 |
46 | @Test
47 | public void doesNotFailWithEmptyStream() {
48 | final Stream realStream = Collections.emptyList().stream();
49 | final TakeWhile takeWhile = TakeWhile.of(realStream.spliterator(), s -> true);
50 | final Stream limitedStream = StreamSupport.stream(takeWhile, false);
51 | assertThat(limitedStream).isEmpty();
52 | }
53 |
54 | @Test
55 | public void streamRunsOutBeforePredicateReturnsFalse() {
56 | final Stream realStream = Arrays.asList("A", "B", "C", "D").stream();
57 | final TakeWhile takeWhile = TakeWhile.of(realStream.spliterator(), s -> !s.equalsIgnoreCase("E"));
58 | final Stream limitedStream = StreamSupport.stream(takeWhile, false);
59 | assertThat(limitedStream).containsExactly("A", "B", "C", "D");
60 | }
61 | }
--------------------------------------------------------------------------------
/src/test/java/com/ginsberg/timestream/YearMonthStreamTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import org.assertj.core.util.Sets;
28 | import org.junit.Test;
29 |
30 | import java.time.Period;
31 | import java.time.YearMonth;
32 | import java.time.temporal.ChronoUnit;
33 | import java.util.Set;
34 | import java.util.stream.Stream;
35 |
36 | import static com.ginsberg.timestream.util.Assertions.expectingChronoUnitException;
37 | import static com.ginsberg.timestream.util.Assertions.notExpectingChronoUnitException;
38 | import static org.assertj.core.api.Assertions.assertThat;
39 |
40 | public class YearMonthStreamTest {
41 |
42 | final YearMonth now = YearMonth.now();
43 | private final Set validChronoUnits = Sets.newLinkedHashSet(ChronoUnit.MONTHS, ChronoUnit.YEARS,
44 | ChronoUnit.DECADES, ChronoUnit.CENTURIES, ChronoUnit.ERAS, ChronoUnit.MILLENNIA);
45 |
46 | @Test
47 | public void stopsBeforeUntilDateGivenByChronoUnits() {
48 | final Stream stream = YearMonthStream
49 | .from(now)
50 | .until(2, ChronoUnit.MONTHS)
51 | .stream();
52 | assertThat(stream)
53 | .isNotNull()
54 | .containsExactly(now, now.plusMonths(1));
55 | }
56 |
57 | @Test
58 | public void stopsBeforeUntilDateGivenByYearMonth() {
59 | final Stream stream = YearMonthStream
60 | .from(now)
61 | .until(now.plusMonths(2))
62 | .stream();
63 | assertThat(stream)
64 | .isNotNull()
65 | .containsExactly(now, now.plusMonths(1));
66 | }
67 |
68 | @Test
69 | public void stopsOnToDateGivenByChronoUnits() {
70 | final Stream stream = YearMonthStream
71 | .from(now)
72 | .to(2, ChronoUnit.MONTHS)
73 | .stream();
74 | assertThat(stream)
75 | .isNotNull()
76 | .containsExactly(now, now.plusMonths(1), now.plusMonths(2));
77 | }
78 |
79 | @Test
80 | public void stopsOnToDateGivenByYearMonth() {
81 | final Stream stream = YearMonthStream
82 | .from(now)
83 | .to(now.plusMonths(2))
84 | .stream();
85 | assertThat(stream)
86 | .isNotNull()
87 | .containsExactly(now, now.plusMonths(1), now.plusMonths(2));
88 | }
89 |
90 | @Test
91 | public void stopsBeforeToWhenEveryIsAfterEndDate() {
92 | final Stream stream = YearMonthStream
93 | .from(now)
94 | .to(3, ChronoUnit.MONTHS)
95 | .every(2, ChronoUnit.MONTHS)
96 | .stream();
97 | assertThat(stream)
98 | .isNotNull()
99 | .containsExactly(now, now.plusMonths(2));
100 | }
101 |
102 | @Test
103 | public void negativeEveryUnitStillGoesForward() {
104 | final Stream stream = YearMonthStream
105 | .from(now)
106 | .to(3, ChronoUnit.MONTHS)
107 | .every(-2, ChronoUnit.MONTHS)
108 | .stream();
109 | assertThat(stream)
110 | .isNotNull()
111 | .containsExactly(now, now.plusMonths(2));
112 | }
113 |
114 |
115 | @Test
116 | public void negativeEveryPeriodStillGoesForward() {
117 | final Stream stream = YearMonthStream
118 | .from(now)
119 | .to(3, ChronoUnit.MONTHS)
120 | .every(Period.parse("-P2M"))
121 | .stream();
122 | assertThat(stream)
123 | .isNotNull()
124 | .containsExactly(now, now.plusMonths(2));
125 | }
126 |
127 | @Test
128 | public void positiveEveryUnitStillGoesBackward() {
129 | final Stream stream = YearMonthStream
130 | .from(now)
131 | .to(-3, ChronoUnit.MONTHS)
132 | .every(2, ChronoUnit.MONTHS)
133 | .stream();
134 | assertThat(stream)
135 | .isNotNull()
136 | .containsExactly(now, now.minusMonths(2));
137 | }
138 |
139 | @Test
140 | public void positiveEveryPeriodStillGoesBackward() {
141 | final Stream stream = YearMonthStream
142 | .from(now)
143 | .to(-3, ChronoUnit.MONTHS)
144 | .every(Period.parse("P2M"))
145 | .stream();
146 | assertThat(stream)
147 | .isNotNull()
148 | .containsExactly(now, now.minusMonths(2));
149 | }
150 |
151 | @Test
152 | public void identicalFromAndToCreateOnePointStream() {
153 | final Stream stream = YearMonthStream
154 | .from(now)
155 | .to(now)
156 | .stream();
157 | assertThat(stream)
158 | .isNotNull()
159 | .containsExactly(now);
160 | }
161 |
162 | @Test
163 | public void noToDateRunsForever() {
164 | // No real way to test that a stream never ends so we will just make sure that this generates a lot of iterations.
165 | final int iterations = 1_000_000;
166 | final Stream stream = YearMonthStream
167 | .from(now)
168 | .stream()
169 | .limit(iterations);
170 | assertThat(stream)
171 | .isNotNull()
172 | .endsWith(now.plus(iterations - 1, ChronoUnit.MONTHS))
173 | .hasSize(iterations);
174 | }
175 |
176 | @Test
177 | public void toBeforeFromRunsBackThroughTime() {
178 | final Stream stream = YearMonthStream
179 | .from(now)
180 | .to(-2, ChronoUnit.MONTHS)
181 | .stream();
182 | assertThat(stream)
183 | .isNotNull()
184 | .containsExactly(now, now.minusMonths(1), now.minusMonths(2));
185 | }
186 |
187 | @Test
188 | public void stopsBeforeToWhenEveryDurationIsAfterEndDate() {
189 | final Period period = Period.parse("P2M");
190 | final Stream stream = YearMonthStream
191 | .from(now)
192 | .to(3, ChronoUnit.MONTHS)
193 | .every(period)
194 | .stream();
195 | assertThat(stream)
196 | .isNotNull()
197 | .containsExactly(now, now.plusMonths(2));
198 | }
199 |
200 | @Test(expected = NullPointerException.class)
201 | public void mustHaveFromDate() {
202 | YearMonthStream.from(null);
203 | }
204 |
205 | @Test(expected = NullPointerException.class)
206 | public void toByUnitsMustHaveUnit() {
207 | YearMonthStream.fromNow().to(1, null);
208 | }
209 |
210 | @Test(expected = NullPointerException.class)
211 | public void untilByUnitsMustHaveUnit() {
212 | YearMonthStream.fromNow().until(1, null);
213 | }
214 |
215 | @Test(expected = NullPointerException.class)
216 | public void everyMustHavePeriod() {
217 | YearMonthStream.fromNow().every(null);
218 | }
219 |
220 | @Test(expected = IllegalArgumentException.class)
221 | public void everyMustHaveNonZeroAmount() {
222 | YearMonthStream.fromNow().every(0, ChronoUnit.MONTHS);
223 | }
224 |
225 | @Test(expected = IllegalArgumentException.class)
226 | public void everyMustHaveNonZeroAmountFromPeriod() {
227 | YearMonthStream.fromNow().every(Period.parse("P1W"));
228 | }
229 |
230 | @Test
231 | public void everyWithInvalidChronoUnitFailsFast() {
232 | expectingChronoUnitException(u -> YearMonthStream.fromNow().every(1, u), validChronoUnits);
233 | }
234 |
235 | @Test
236 | public void everyWithValidChronoUnit() {
237 | notExpectingChronoUnitException(u -> YearMonthStream.fromNow().every(1, u), validChronoUnits);
238 | }
239 |
240 | @Test
241 | public void toWithInvalidChronoUnitFailsFast() {
242 | expectingChronoUnitException(u -> YearMonthStream.fromNow().to(0, u), validChronoUnits);
243 | }
244 |
245 | @Test
246 | public void toWithValidChronoUnit() {
247 | notExpectingChronoUnitException(u -> YearMonthStream.fromNow().to(0, u), validChronoUnits);
248 | }
249 |
250 | @Test
251 | public void untilWithInvalidChronoUnitFailsFast() {
252 | expectingChronoUnitException(u -> YearMonthStream.fromNow().until(0, u), validChronoUnits);
253 | }
254 |
255 | @Test
256 | public void untilWithValidChronoUnit() {
257 | notExpectingChronoUnitException(u -> YearMonthStream.fromNow().until(0, u), validChronoUnits);
258 | }
259 |
260 | }
--------------------------------------------------------------------------------
/src/test/java/com/ginsberg/timestream/ZonedDateTimeStreamTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream;
26 |
27 | import org.junit.Test;
28 |
29 | import java.time.Duration;
30 | import java.time.ZonedDateTime;
31 | import java.time.temporal.ChronoUnit;
32 | import java.util.stream.Stream;
33 |
34 | import static org.assertj.core.api.Assertions.assertThat;
35 |
36 | public class ZonedDateTimeStreamTest {
37 |
38 | final ZonedDateTime now = ZonedDateTime.now();
39 |
40 | @Test
41 | public void stopsBeforeUntilDateGivenByChronoUnits() {
42 | final Stream stream = ZonedDateTimeStream
43 | .from(now)
44 | .until(2, ChronoUnit.SECONDS)
45 | .stream();
46 | assertThat(stream)
47 | .isNotNull()
48 | .containsExactly(now, now.plusSeconds(1));
49 | }
50 |
51 | @Test
52 | public void stopsBeforeUntilDateGivenByZonedDateTime() {
53 | final Stream stream = ZonedDateTimeStream
54 | .from(now)
55 | .until(now.plusSeconds(2))
56 | .stream();
57 | assertThat(stream)
58 | .isNotNull()
59 | .containsExactly(now, now.plusSeconds(1));
60 | }
61 |
62 | @Test
63 | public void stopsOnToDateGivenByChronoUnits() {
64 | final Stream stream = ZonedDateTimeStream
65 | .from(now)
66 | .to(2, ChronoUnit.SECONDS)
67 | .stream();
68 | assertThat(stream)
69 | .isNotNull()
70 | .containsExactly(now, now.plusSeconds(1), now.plusSeconds(2));
71 | }
72 |
73 | @Test
74 | public void stopsOnToDateGivenByZonedDateTime() {
75 | final Stream stream = ZonedDateTimeStream
76 | .from(now)
77 | .to(now.plusSeconds(2))
78 | .stream();
79 | assertThat(stream)
80 | .isNotNull()
81 | .containsExactly(now, now.plusSeconds(1), now.plusSeconds(2));
82 | }
83 |
84 | @Test
85 | public void stopsBeforeToWhenEveryIsAfterEndDate() {
86 | final Stream stream = ZonedDateTimeStream
87 | .from(now)
88 | .to(3, ChronoUnit.SECONDS)
89 | .every(2, ChronoUnit.SECONDS)
90 | .stream();
91 | assertThat(stream)
92 | .isNotNull()
93 | .containsExactly(now, now.plusSeconds(2));
94 | }
95 |
96 | @Test
97 | public void identicalFromAndToCreateOnePointStream() {
98 | final Stream stream = ZonedDateTimeStream
99 | .from(now)
100 | .to(now)
101 | .stream();
102 | assertThat(stream)
103 | .isNotNull()
104 | .containsExactly(now);
105 | }
106 |
107 | @Test
108 | public void noToDateRunsForever() {
109 | // No real way to test that a stream never ends so we will just make sure that this generates a lot of iterations.
110 | final int iterations = 1_000_000;
111 | final Stream stream = ZonedDateTimeStream
112 | .from(now)
113 | .stream()
114 | .limit(iterations);
115 | assertThat(stream)
116 | .isNotNull()
117 | .endsWith(now.plus(iterations - 1, ChronoUnit.SECONDS))
118 | .hasSize(iterations);
119 | }
120 |
121 | @Test
122 | public void toBeforeFromRunsBackThroughTime() {
123 | final Stream stream = ZonedDateTimeStream
124 | .from(now)
125 | .to(-2, ChronoUnit.SECONDS)
126 | .stream();
127 | assertThat(stream)
128 | .isNotNull()
129 | .containsExactly(now, now.minusSeconds(1), now.minusSeconds(2));
130 | }
131 |
132 | @Test
133 | public void stopsBeforeToWhenEveryDurationIsAfterEndDate() {
134 | final Duration duration = Duration.parse("PT2S");
135 | final Stream stream = ZonedDateTimeStream
136 | .from(now)
137 | .to(3, ChronoUnit.SECONDS)
138 | .every(duration)
139 | .stream();
140 | assertThat(stream)
141 | .isNotNull()
142 | .containsExactly(now, now.plusSeconds(2));
143 | }
144 |
145 | @Test
146 | public void positiveEveryUnitStillGoesBackward() {
147 | final Stream stream = ZonedDateTimeStream
148 | .from(now)
149 | .to(-3, ChronoUnit.SECONDS)
150 | .every(2, ChronoUnit.SECONDS)
151 | .stream();
152 | assertThat(stream)
153 | .isNotNull()
154 | .containsExactly(now, now.minusSeconds(2));
155 | }
156 |
157 | @Test
158 | public void positiveEveryDurationStillGoesBackward() {
159 | final Stream stream = ZonedDateTimeStream
160 | .from(now)
161 | .to(-3, ChronoUnit.SECONDS)
162 | .every(Duration.parse("PT2S"))
163 | .stream();
164 | assertThat(stream)
165 | .isNotNull()
166 | .containsExactly(now, now.minusSeconds(2));
167 | }
168 |
169 | @Test
170 | public void negativeEveryUnitStillGoesForward() {
171 | final Stream stream = ZonedDateTimeStream
172 | .from(now)
173 | .to(3, ChronoUnit.SECONDS)
174 | .every(-2, ChronoUnit.SECONDS)
175 | .stream();
176 | assertThat(stream)
177 | .isNotNull()
178 | .containsExactly(now, now.plusSeconds(2));
179 | }
180 |
181 | @Test
182 | public void negativeEveryDurationStillGoesForward() {
183 | final Stream stream = ZonedDateTimeStream
184 | .from(now)
185 | .to(3, ChronoUnit.SECONDS)
186 | .every(Duration.parse("-PT2S"))
187 | .stream();
188 | assertThat(stream)
189 | .isNotNull()
190 | .containsExactly(now, now.plusSeconds(2));
191 | }
192 |
193 | @Test(expected = NullPointerException.class)
194 | public void mustHaveFromDate() {
195 | ZonedDateTimeStream.from(null);
196 | }
197 |
198 | @Test(expected = NullPointerException.class)
199 | public void toByUnitsMustHaveUnit() {
200 | ZonedDateTimeStream.fromNow().to(1, null);
201 | }
202 |
203 | @Test(expected = NullPointerException.class)
204 | public void untilByUnitsMustHaveUnit() {
205 | ZonedDateTimeStream.fromNow().until(1, null);
206 | }
207 |
208 | @Test(expected = NullPointerException.class)
209 | public void everyMustHavePeriod() {
210 | ZonedDateTimeStream.fromNow().every(null);
211 | }
212 |
213 | @Test(expected = IllegalArgumentException.class)
214 | public void everyMustHaveNonZeroAmount() {
215 | ZonedDateTimeStream.fromNow().every(0, ChronoUnit.SECONDS);
216 | }
217 |
218 | @Test(expected = IllegalArgumentException.class)
219 | public void everyMustHaveNonZeroAmountFromPeriod() {
220 | ZonedDateTimeStream.fromNow().every(Duration.parse("PT0S"));
221 | }
222 | }
--------------------------------------------------------------------------------
/src/test/java/com/ginsberg/timestream/util/Assertions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * MIT License
3 | *
4 | * Copyright (c) 2016 Todd Ginsberg
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 |
25 | package com.ginsberg.timestream.util;
26 |
27 | import java.time.temporal.ChronoUnit;
28 | import java.time.temporal.UnsupportedTemporalTypeException;
29 | import java.util.Arrays;
30 | import java.util.Collection;
31 | import java.util.function.Consumer;
32 |
33 | import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
34 |
35 | public abstract class Assertions {
36 |
37 | public static void expectingChronoUnitException(final Consumer consumer, final Collection validUnits) {
38 | Arrays.stream(ChronoUnit.values())
39 | .filter(u -> !validUnits.contains(u))
40 | .forEach(u -> assertThatExceptionOfType(UnsupportedTemporalTypeException.class).isThrownBy(
41 | () -> consumer.accept(u)
42 | ));
43 | }
44 |
45 | public static void notExpectingChronoUnitException(final Consumer consumer, final Collection validUnits) {
46 | validUnits.stream().forEach(consumer);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------