Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(#3793): Fix Expect #3795

Merged
merged 9 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 54 additions & 4 deletions eo-runtime/src/main/java/org/eolang/Expect.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,13 @@ public static Expect<Phi> at(final Phi phi, final String attr) {
public <R> Expect<R> that(final Function<T, R> fun) {
return new Expect<>(
this.subject,
() -> fun.apply(this.sup.get())
() -> {
try {
return fun.apply(this.sup.get());
} catch (final ExFailure ex) {
throw new ExThat(ex.getMessage(), ex);
}
}
);
}

Expand All @@ -96,9 +102,19 @@ public Expect<T> otherwise(final String message) {
() -> {
try {
return this.sup.get();
} catch (final ExFailure ex) {
} catch (final ExMust ex) {
throw new ExFailure(
String.format(
"%s %s %s",
this.subject,
ex.getMessage(),
message
),
ex
);
} catch (final ExThat ex) {
throw new ExFailure(
String.format("%s %s %s", this.subject, ex.getMessage(), message),
message,
ex
);
}
Expand All @@ -117,7 +133,7 @@ public Expect<T> must(final Function<T, Boolean> fun) {
() -> {
final T ret = this.sup.get();
if (!fun.apply(ret)) {
throw new ExFailure(
throw new ExMust(
String.format("(%s)", ret)
);
}
Expand All @@ -135,4 +151,38 @@ public T it() {
return this.sup.get();
}

/**
* This exception is used to enhance the error message
* in the {@link Expect#otherwise(String)} method.
*
* @since 0.51
*/
private static class ExMust extends ExFailure {
/**
* Ctor.
* @param cause Exception cause
* @param args Arguments for {@link String#format(String, Object...)}
*/
ExMust(final String cause, final Object... args) {
super(String.format(cause, args));
}
}

/**
* This exception is used to enhance the error message
* in the {@link Expect#otherwise(String)} method.
*
* @since 0.51
*/
private static class ExThat extends ExFailure {
/**
* Ctor.
* @param cause Exception cause
* @param args Arguments for {@link String#format(String, Object...)}
*/
ExThat(final String cause, final Object... args) {
super(String.format(cause, args));
}
}

}
68 changes: 63 additions & 5 deletions eo-runtime/src/test/java/org/eolang/ExpectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
final class ExpectTest {

@Test
void buildsAndChecks() {
void buildsAndChecksWithoutErrors() {
MatcherAssert.assertThat(
"passes through and throws correctly",
"Passes checks",
new Expect<>("something", () -> 42)
.must(i -> i > 0)
.otherwise("must be positive")
Expand All @@ -50,9 +50,9 @@ void buildsAndChecks() {
}

@Test
void failsWithCorrectTrace() {
void failsWithCorrectTraceWithOneError() {
MatcherAssert.assertThat(
"error message is correct",
"Throw error in first 'must'. Error message is correct",
Assertions.assertThrows(
ExFailure.class,
() -> new Expect<>("a number", () -> 42)
Expand All @@ -61,7 +61,65 @@ void failsWithCorrectTrace() {
.it(),
"fails on check"
).getMessage(),
Matchers.containsString("negative")
Matchers.equalTo("a number (42) must be negative")
);
}

@Test
void failsWithCorrectTraceWithTwoErrors() {
MatcherAssert.assertThat(
"Throw error in first 'must'. Not add error about second 'must'",
Assertions.assertThrows(
ExFailure.class,
() -> new Expect<>("a number", () -> 42.2)
.must(i -> i < 0)
.otherwise("must be negative")
.must(i -> i % 1 == 0)
.otherwise("must be an integer")
.it(),
"fails only for first 'must'"
).getMessage(),
Matchers.equalTo("a number (42.2) must be negative")
);
}

@Test
void failsWithCorrectTraceWithOneOkAndOneError() {
MatcherAssert.assertThat(
"Throw error in second 'must'. First 'must' passes check",
Assertions.assertThrows(
ExFailure.class,
() -> new Expect<>("a number", () -> 42.2)
.must(i -> i > 0)
.otherwise("must be positive")
.must(i -> i % 1 == 0)
.otherwise("must be an integer")
.it(),
"fails on checking integer"
).getMessage(),
Matchers.equalTo("a number (42.2) must be an integer")
);
}

@Test
void failsWithCorrectTraceWithExFailureInThat() {
MatcherAssert.assertThat(
"Take error message from 'otherwise', not from original error",
Assertions.assertThrows(
ExFailure.class,
() -> new Expect<>("something", () -> 42.2)
.must(i -> i > 0)
.otherwise("must be positive")
.that(
i -> {
throw new ExFailure("some error");
}
)
.otherwise("something went wrong")
.it(),
"fails on 'that'"
).getMessage(),
Matchers.equalTo("something went wrong")
);
}
}
Loading