Skip to content

Commit 34e5a6f

Browse files
committed
Used a specific exception for intermediate modifiable operations in streams
1 parent 35e81ed commit 34e5a6f

File tree

8 files changed

+175
-62
lines changed

8 files changed

+175
-62
lines changed

utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/UtExecutionResult.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,17 @@ class TimeoutException(s: String) : Exception(s)
4646
data class UtTimeoutException(override val exception: TimeoutException) : UtExecutionFailure()
4747

4848
/**
49-
* Represents an exception that occurs during consuming a stream. Stores it in [innerException].
49+
* Represents an exception that occurs during consuming a stream.
50+
* [innerException] stores original exception (if possible), null if [UtStreamConsumingException] was constructed by the engine.
5051
*/
51-
data class UtStreamConsumingException(val innerException: Exception) : RuntimeException() {
52-
override fun toString(): String = innerException.toString()
52+
data class UtStreamConsumingException(private val innerException: Exception?) : RuntimeException() {
53+
/**
54+
* Returns the original exception [innerException] if possible, and any [RuntimeException] otherwise.
55+
*/
56+
val innerExceptionOrAny: Throwable
57+
get() = innerException ?: RuntimeException("Unknown runtime exception during consuming stream")
58+
59+
override fun toString(): String = innerExceptionOrAny.toString()
5360
}
5461

5562
/**

utbot-framework-test/src/test/kotlin/org/utbot/examples/stream/StreamsAsMethodResultExampleTest.kt

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import org.utbot.testcheckers.eq
88
import org.utbot.tests.infrastructure.CodeGeneration
99
import org.utbot.tests.infrastructure.FullWithAssumptions
1010
import org.utbot.tests.infrastructure.UtValueTestCaseChecker
11+
import org.utbot.tests.infrastructure.isException
1112
import kotlin.streams.toList
1213

1314
// TODO 1 instruction is always uncovered https://github.com/UnitTestBot/UTBotJava/issues/193
@@ -39,7 +40,7 @@ class StreamsAsMethodResultExampleTest : UtValueTestCaseChecker(
3940
eq(3),
4041
{ c, r -> c.isEmpty() && c == r.getOrThrow().toList() },
4142
{ c, r -> c.isNotEmpty() && c.none { it == null } && c.toIntArray().contentEquals(r.getOrThrow().toArray()) },
42-
{ c, r -> c.isNotEmpty() && c.any { it == null } && r.isNPE() },
43+
{ c, r -> c.isNotEmpty() && c.any { it == null } && r.isException<UtStreamConsumingException>() },
4344
coverage = FullWithAssumptions(assumeCallsNumber = 2)
4445
)
4546
}
@@ -51,7 +52,7 @@ class StreamsAsMethodResultExampleTest : UtValueTestCaseChecker(
5152
eq(3),
5253
{ c, r -> c.isEmpty() && c == r.getOrThrow().toList() },
5354
{ c, r -> c.isNotEmpty() && c.none { it == null } && c.map { it.toLong() }.toLongArray().contentEquals(r.getOrThrow().toArray()) },
54-
{ c, r -> c.isNotEmpty() && c.any { it == null } && r.isNPE() },
55+
{ c, r -> c.isNotEmpty() && c.any { it == null } && r.isException<UtStreamConsumingException>() },
5556
coverage = FullWithAssumptions(assumeCallsNumber = 2)
5657
)
5758
}
@@ -63,21 +64,8 @@ class StreamsAsMethodResultExampleTest : UtValueTestCaseChecker(
6364
eq(3),
6465
{ c, r -> c.isEmpty() && c == r.getOrThrow().toList() },
6566
{ c, r -> c.isNotEmpty() && c.none { it == null } && c.map { it.toDouble() }.toDoubleArray().contentEquals(r.getOrThrow().toArray()) },
66-
{ c, r -> c.isNotEmpty() && c.any { it == null } && r.isNPE() },
67+
{ c, r -> c.isNotEmpty() && c.any { it == null } && r.isException<UtStreamConsumingException>() },
6768
coverage = FullWithAssumptions(assumeCallsNumber = 2)
6869
)
6970
}
70-
71-
/**
72-
* Checks the result in [NullPointerException] from the engine or
73-
* [UtStreamConsumingException] with [NullPointerException] from concrete execution.
74-
*/
75-
private fun Result<*>.isNPE(): Boolean =
76-
exceptionOrNull()?.let {
77-
if (it is UtStreamConsumingException) {
78-
return@let it.innerException is NullPointerException
79-
}
80-
81-
return@let it is NullPointerException
82-
} ?: false
8371
}

utbot-framework/src/main/java/org/utbot/engine/overrides/stream/UtDoubleStream.java

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.jetbrains.annotations.NotNull;
44
import org.utbot.engine.overrides.collections.RangeModifiableUnlimitedArray;
55
import org.utbot.engine.overrides.collections.UtGenericStorage;
6+
import org.utbot.framework.plugin.api.*;
67

78
import java.util.DoubleSummaryStatistics;
89
import java.util.NoSuchElementException;
@@ -122,8 +123,13 @@ public DoubleStream filter(DoublePredicate predicate) {
122123
int j = 0;
123124
for (int i = 0; i < size; i++) {
124125
double element = elementData.get(i);
125-
if (predicate.test(element)) {
126-
filtered[j++] = element;
126+
127+
try {
128+
if (predicate.test(element)) {
129+
filtered[j++] = element;
130+
}
131+
} catch (Exception e) {
132+
throw new UtStreamConsumingException(e);
127133
}
128134
}
129135

@@ -137,7 +143,11 @@ public DoubleStream map(DoubleUnaryOperator mapper) {
137143
int size = elementData.end;
138144
Double[] mapped = new Double[size];
139145
for (int i = 0; i < size; i++) {
140-
mapped[i] = mapper.applyAsDouble(elementData.get(i));
146+
try {
147+
mapped[i] = mapper.applyAsDouble(elementData.get(i));
148+
} catch (Exception e) {
149+
throw new UtStreamConsumingException(e);
150+
}
141151
}
142152

143153
return new UtDoubleStream(mapped, size);
@@ -153,7 +163,11 @@ public <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
153163
int size = elementData.end;
154164
Object[] mapped = new Object[size];
155165
for (int i = 0; i < size; i++) {
156-
mapped[i] = mapper.apply(elementData.get(i));
166+
try {
167+
mapped[i] = mapper.apply(elementData.get(i));
168+
} catch (Exception e) {
169+
throw new UtStreamConsumingException(e);
170+
}
157171
}
158172

159173
return new UtStream<>((U[]) mapped, size);
@@ -166,7 +180,11 @@ public IntStream mapToInt(DoubleToIntFunction mapper) {
166180
int size = elementData.end;
167181
Integer[] mapped = new Integer[size];
168182
for (int i = 0; i < size; i++) {
169-
mapped[i] = mapper.applyAsInt(elementData.get(i));
183+
try {
184+
mapped[i] = mapper.applyAsInt(elementData.get(i));
185+
} catch (Exception e) {
186+
throw new UtStreamConsumingException(e);
187+
}
170188
}
171189

172190
return new UtIntStream(mapped, size);
@@ -179,7 +197,11 @@ public LongStream mapToLong(DoubleToLongFunction mapper) {
179197
int size = elementData.end;
180198
Long[] mapped = new Long[size];
181199
for (int i = 0; i < size; i++) {
182-
mapped[i] = mapper.applyAsLong(elementData.get(i));
200+
try {
201+
mapped[i] = mapper.applyAsLong(elementData.get(i));
202+
} catch (Exception e) {
203+
throw new UtStreamConsumingException(e);
204+
}
183205
}
184206

185207
return new UtLongStream(mapped, size);
@@ -256,7 +278,11 @@ public DoubleStream peek(DoubleConsumer action) {
256278

257279
int size = elementData.end;
258280
for (int i = 0; i < size; i++) {
259-
action.accept(elementData.get(i));
281+
try {
282+
action.accept(elementData.get(i));
283+
} catch (Exception e) {
284+
throw new UtStreamConsumingException(e);
285+
}
260286
}
261287

262288
// returned stream should be opened, so we "reopen" this stream to return it
@@ -315,13 +341,16 @@ public DoubleStream skip(long n) {
315341
@SuppressWarnings("ResultOfMethodCallIgnored")
316342
@Override
317343
public void forEach(DoubleConsumer action) {
318-
peek(action);
344+
try {
345+
peek(action);
346+
} catch (UtStreamConsumingException e) {
347+
// Since this is a terminal operation, we should throw an original exception
348+
}
319349
}
320350

321-
@SuppressWarnings("ResultOfMethodCallIgnored")
322351
@Override
323352
public void forEachOrdered(DoubleConsumer action) {
324-
peek(action);
353+
forEach(action);
325354
}
326355

327356
@Override

utbot-framework/src/main/java/org/utbot/engine/overrides/stream/UtIntStream.java

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.jetbrains.annotations.NotNull;
44
import org.utbot.engine.overrides.collections.RangeModifiableUnlimitedArray;
55
import org.utbot.engine.overrides.collections.UtGenericStorage;
6+
import org.utbot.framework.plugin.api.*;
67

78
import java.util.IntSummaryStatistics;
89
import java.util.NoSuchElementException;
@@ -123,8 +124,13 @@ public IntStream filter(IntPredicate predicate) {
123124
int j = 0;
124125
for (int i = 0; i < size; i++) {
125126
int element = elementData.get(i);
126-
if (predicate.test(element)) {
127-
filtered[j++] = element;
127+
128+
try {
129+
if (predicate.test(element)) {
130+
filtered[j++] = element;
131+
}
132+
} catch (Exception e) {
133+
throw new UtStreamConsumingException(e);
128134
}
129135
}
130136

@@ -138,7 +144,11 @@ public IntStream map(IntUnaryOperator mapper) {
138144
int size = elementData.end;
139145
Integer[] mapped = new Integer[size];
140146
for (int i = 0; i < size; i++) {
141-
mapped[i] = mapper.applyAsInt(elementData.get(i));
147+
try {
148+
mapped[i] = mapper.applyAsInt(elementData.get(i));
149+
} catch (Exception e) {
150+
throw new UtStreamConsumingException(e);
151+
}
142152
}
143153

144154
return new UtIntStream(mapped, size);
@@ -154,7 +164,11 @@ public <U> Stream<U> mapToObj(IntFunction<? extends U> mapper) {
154164
int size = elementData.end;
155165
U[] mapped = (U[]) new Object[size];
156166
for (int i = 0; i < size; i++) {
157-
mapped[i] = mapper.apply(elementData.get(i));
167+
try {
168+
mapped[i] = mapper.apply(elementData.get(i));
169+
} catch (Exception e) {
170+
throw new UtStreamConsumingException(e);
171+
}
158172
}
159173

160174
return new UtStream<>(mapped, size);
@@ -167,7 +181,11 @@ public LongStream mapToLong(IntToLongFunction mapper) {
167181
int size = elementData.end;
168182
Long[] mapped = new Long[size];
169183
for (int i = 0; i < size; i++) {
170-
mapped[i] = mapper.applyAsLong(elementData.get(i));
184+
try {
185+
mapped[i] = mapper.applyAsLong(elementData.get(i));
186+
} catch (Exception e) {
187+
throw new UtStreamConsumingException(e);
188+
}
171189
}
172190

173191
return new UtLongStream(mapped, size);
@@ -180,7 +198,11 @@ public DoubleStream mapToDouble(IntToDoubleFunction mapper) {
180198
int size = elementData.end;
181199
Double[] mapped = new Double[size];
182200
for (int i = 0; i < size; i++) {
183-
mapped[i] = mapper.applyAsDouble(elementData.get(i));
201+
try {
202+
mapped[i] = mapper.applyAsDouble(elementData.get(i));
203+
} catch (Exception e) {
204+
throw new UtStreamConsumingException(e);
205+
}
184206
}
185207

186208
return new UtDoubleStream(mapped, size);
@@ -257,7 +279,11 @@ public IntStream peek(IntConsumer action) {
257279

258280
int size = elementData.end;
259281
for (int i = 0; i < size; i++) {
260-
action.accept(elementData.get(i));
282+
try {
283+
action.accept(elementData.get(i));
284+
} catch (Exception e) {
285+
throw new UtStreamConsumingException(e);
286+
}
261287
}
262288

263289
// returned stream should be opened, so we "reopen" this stream to return it
@@ -316,13 +342,16 @@ public IntStream skip(long n) {
316342
@SuppressWarnings("ResultOfMethodCallIgnored")
317343
@Override
318344
public void forEach(IntConsumer action) {
319-
peek(action);
345+
try {
346+
peek(action);
347+
} catch (UtStreamConsumingException e) {
348+
// Since this is a terminal operation, we should throw an original exception
349+
}
320350
}
321351

322-
@SuppressWarnings("ResultOfMethodCallIgnored")
323352
@Override
324353
public void forEachOrdered(IntConsumer action) {
325-
peek(action);
354+
forEach(action);
326355
}
327356

328357
@Override

utbot-framework/src/main/java/org/utbot/engine/overrides/stream/UtLongStream.java

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.jetbrains.annotations.NotNull;
44
import org.utbot.engine.overrides.collections.RangeModifiableUnlimitedArray;
55
import org.utbot.engine.overrides.collections.UtGenericStorage;
6+
import org.utbot.framework.plugin.api.*;
67

78
import java.util.LongSummaryStatistics;
89
import java.util.NoSuchElementException;
@@ -123,8 +124,13 @@ public LongStream filter(LongPredicate predicate) {
123124
int j = 0;
124125
for (int i = 0; i < size; i++) {
125126
long element = elementData.get(i);
126-
if (predicate.test(element)) {
127-
filtered[j++] = element;
127+
128+
try {
129+
if (predicate.test(element)) {
130+
filtered[j++] = element;
131+
}
132+
} catch (Exception e) {
133+
throw new UtStreamConsumingException(e);
128134
}
129135
}
130136

@@ -138,7 +144,11 @@ public LongStream map(LongUnaryOperator mapper) {
138144
int size = elementData.end;
139145
Long[] mapped = new Long[size];
140146
for (int i = 0; i < size; i++) {
141-
mapped[i] = mapper.applyAsLong(elementData.get(i));
147+
try {
148+
mapped[i] = mapper.applyAsLong(elementData.get(i));
149+
} catch (Exception e) {
150+
throw new UtStreamConsumingException(e);
151+
}
142152
}
143153

144154
return new UtLongStream(mapped, size);
@@ -154,7 +164,11 @@ public <U> Stream<U> mapToObj(LongFunction<? extends U> mapper) {
154164
int size = elementData.end;
155165
Object[] mapped = new Object[size];
156166
for (int i = 0; i < size; i++) {
157-
mapped[i] = mapper.apply(elementData.get(i));
167+
try {
168+
mapped[i] = mapper.apply(elementData.get(i));
169+
} catch (Exception e) {
170+
throw new UtStreamConsumingException(e);
171+
}
158172
}
159173

160174
return new UtStream<>((U[]) mapped, size);
@@ -167,7 +181,11 @@ public IntStream mapToInt(LongToIntFunction mapper) {
167181
int size = elementData.end;
168182
Integer[] mapped = new Integer[size];
169183
for (int i = 0; i < size; i++) {
170-
mapped[i] = mapper.applyAsInt(elementData.get(i));
184+
try {
185+
mapped[i] = mapper.applyAsInt(elementData.get(i));
186+
} catch (Exception e) {
187+
throw new UtStreamConsumingException(e);
188+
}
171189
}
172190

173191
return new UtIntStream(mapped, size);
@@ -180,7 +198,11 @@ public DoubleStream mapToDouble(LongToDoubleFunction mapper) {
180198
int size = elementData.end;
181199
Double[] mapped = new Double[size];
182200
for (int i = 0; i < size; i++) {
183-
mapped[i] = mapper.applyAsDouble(elementData.get(i));
201+
try {
202+
mapped[i] = mapper.applyAsDouble(elementData.get(i));
203+
} catch (Exception e) {
204+
throw new UtStreamConsumingException(e);
205+
}
184206
}
185207

186208
return new UtDoubleStream(mapped, size);
@@ -257,7 +279,11 @@ public LongStream peek(LongConsumer action) {
257279

258280
int size = elementData.end;
259281
for (int i = 0; i < size; i++) {
260-
action.accept(elementData.get(i));
282+
try {
283+
action.accept(elementData.get(i));
284+
} catch (Exception e) {
285+
throw new UtStreamConsumingException(e);
286+
}
261287
}
262288

263289
// returned stream should be opened, so we "reopen" this stream to return it
@@ -316,13 +342,16 @@ public LongStream skip(long n) {
316342
@SuppressWarnings("ResultOfMethodCallIgnored")
317343
@Override
318344
public void forEach(LongConsumer action) {
319-
peek(action);
345+
try {
346+
peek(action);
347+
} catch (UtStreamConsumingException e) {
348+
// Since this is a terminal operation, we should throw an original exception
349+
}
320350
}
321351

322-
@SuppressWarnings("ResultOfMethodCallIgnored")
323352
@Override
324353
public void forEachOrdered(LongConsumer action) {
325-
peek(action);
354+
forEach(action);
326355
}
327356

328357
@Override

0 commit comments

Comments
 (0)