-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(#3): add support for java's Serializable
- Loading branch information
Showing
5 changed files
with
147 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
.../java/io/github/goatfryed/assert_baseline/serializable/SerializableBaselineAssertion.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package io.github.goatfryed.assert_baseline.serializable; | ||
|
||
import io.github.goatfryed.assert_baseline.core.AbstractBaselineAssertion; | ||
import io.github.goatfryed.assert_baseline.core.BaselineAssertionAdapter; | ||
import io.github.goatfryed.assert_baseline.core.BaselineContext; | ||
import org.assertj.core.api.Assert; | ||
import org.assertj.core.api.ObjectAssert; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.io.IOException; | ||
import java.io.ObjectInputStream; | ||
import java.io.ObjectOutputStream; | ||
import java.util.function.Consumer; | ||
import java.util.function.Function; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
public class SerializableBaselineAssertion<ACTUAL> extends AbstractBaselineAssertion<SerializableBaselineAssertion<ACTUAL>,ACTUAL> { | ||
|
||
private Function<ObjectAssert<ACTUAL>, Assert<?,?>> assertConfig = assertion -> assertion; | ||
|
||
public SerializableBaselineAssertion(ACTUAL actual) { | ||
super(actual, SerializableBaselineAssertion.class); | ||
} | ||
|
||
/** | ||
* This is the same as just calling<br> | ||
* <code> | ||
* serializableAssertion.satisfies(it -> assertThat(it)...) | ||
* </code><br> | ||
* It's only implemented as a convenience method in line with our general pattern | ||
*/ | ||
public SerializableBaselineAssertion<ACTUAL> serializableSatisfies(Consumer<ObjectAssert<ACTUAL>> assertion) { | ||
assertion.accept(assertThat(actual)); | ||
return myself; | ||
} | ||
|
||
/** | ||
* This yields control of the {@link Assert} to the user.<br> | ||
* Note that whatever assertion is returned gets called with <code>isEqualTo(baselineObject)</code>. | ||
*/ | ||
public SerializableBaselineAssertion<ACTUAL> usingSerializableComparator(Function<ObjectAssert<ACTUAL>, Assert<?,?>> assertConfig) { | ||
this.assertConfig = assertConfig; | ||
return myself; | ||
} | ||
|
||
@Override | ||
protected @NotNull BaselineAssertionAdapter getAssertionAdapter() { | ||
return new Adapter(); | ||
} | ||
|
||
class Adapter implements BaselineAssertionAdapter { | ||
@Override | ||
public void writeActual(BaselineContext.ActualOutput output, BaselineContext context) { | ||
try (var oos = new ObjectOutputStream(output.outputStream())) { | ||
oos.writeObject(actual); | ||
} catch (IOException e) { | ||
throw new AssertionError("failed to serialize actual", e); | ||
} | ||
} | ||
|
||
@Override | ||
public void assertEquals(BaselineContext.BaselineInput baseline, BaselineContext context) { | ||
try (var ois = new ObjectInputStream(baseline.getInputStream())) { | ||
var baselineObject = ois.readObject(); | ||
assertConfig.apply(assertThat(actual)) | ||
.isEqualTo(baselineObject); | ||
} catch (IOException e) { | ||
throw new AssertionError("failed to read baseline", e); | ||
} catch (ClassNotFoundException e) { | ||
throw new AssertionError("baseline class does not exist. This indicates that you changed class definition and need to recreate the baseline.", e); | ||
} | ||
} | ||
} | ||
|
||
} |
8 changes: 8 additions & 0 deletions
8
src/test/java/io/github/goatfryed/assert_baseline/serializable/Foo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package io.github.goatfryed.assert_baseline.serializable; | ||
|
||
import java.io.Serializable; | ||
|
||
public record Foo(String foo, Bar fooBar) implements Serializable { | ||
|
||
public record Bar(String prop1, String prop2) implements Serializable { } | ||
} |
60 changes: 60 additions & 0 deletions
60
...a/io/github/goatfryed/assert_baseline/serializable/SerializableBaselineAssertionTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package io.github.goatfryed.assert_baseline.serializable; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import java.io.File; | ||
import java.nio.file.Path; | ||
|
||
import static io.github.goatfryed.assert_baseline.BaselineAssertions.assertThatSerializable; | ||
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; | ||
|
||
class SerializableBaselineAssertionTest { | ||
|
||
public final static String BASE_PATH = "serializable/object.%s.json"; | ||
public final static String ALTERED_PATH = BASE_PATH.formatted("altered"); | ||
public final static String ACTUAL_PATH = BASE_PATH.formatted("actual"); | ||
public final static String BASELINE_PATH = BASE_PATH.formatted("baseline"); | ||
public final static Path RESOURCE_ROOT = Path.of("src/test/resources"); | ||
public final static File ACTUAL_FILE = RESOURCE_ROOT.resolve(ACTUAL_PATH).toFile(); | ||
public final static File ALTERED_FILE = RESOURCE_ROOT.resolve(ALTERED_PATH).toFile(); | ||
public final static File BASELINE_FILE = RESOURCE_ROOT.resolve(BASELINE_PATH).toFile(); | ||
|
||
@Test | ||
void itPassesSameContent() { | ||
var foo = new Foo("chucky", new Foo.Bar("chuck","norris")); | ||
|
||
assertThatSerializable(foo) | ||
.isEqualToBaseline(BASELINE_PATH); | ||
} | ||
|
||
@Test | ||
void itFailsContentViolations() { | ||
var foo = new Foo("chucky", new Foo.Bar("chuck","the murder puppet")); | ||
|
||
assertThatCode(() -> | ||
assertThatSerializable(foo) | ||
.isEqualToBaseline(BASELINE_PATH) | ||
).hasMessageContaining("expected: Foo[foo=chucky, fooBar=Bar[prop1=chuck, prop2=norris]]"); | ||
} | ||
|
||
@Test | ||
void itPassesAllowedDifferences() { | ||
var foo = new Foo("chucky", new Foo.Bar("chuck","the murder puppet")); | ||
|
||
assertThatSerializable(foo) | ||
.usingSerializableComparator(assertion -> assertion | ||
.usingRecursiveComparison() | ||
.ignoringFields("foo", "fooBar.prop2") | ||
).isEqualToBaseline(BASELINE_PATH); | ||
} | ||
|
||
@Test | ||
void itInteropsWithAssertJ() { | ||
var foo = new Foo("chucky", new Foo.Bar("chuck","norris")); | ||
|
||
assertThatSerializable(foo) | ||
.serializableSatisfies(assertion -> assertion | ||
.hasFieldOrProperty("fooBar") | ||
); | ||
} | ||
} |
Binary file not shown.