Skip to content

Commit

Permalink
Merge branch 'release/1.3.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins committed May 2, 2022
2 parents 9f697e3 + 52cec26 commit db5c862
Show file tree
Hide file tree
Showing 56 changed files with 713 additions and 211 deletions.
40 changes: 33 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- This file is auto generated during release from readme/README.md -->

[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.2.3&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-bom/1.2.3/jar)
[![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.2.3&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-core/1.2.3)
[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.3.0&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-bom/1.3.0/jar)
[![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.3.0&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-core/1.3.0)
[![Coverage Status](https://coveralls.io/repos/github/skuzzle/snapshot-tests/badge.svg?branch=main)](https://coveralls.io/github/skuzzle/snapshot-tests?branch=main)
[![Twitter Follow](https://img.shields.io/twitter/follow/skuzzleOSS.svg?style=social)](https://twitter.com/skuzzleOSS)

Expand All @@ -17,7 +17,7 @@ Read more about snapshot testing in this accompanying [blog post](https://simon.
### Latest Maven Central coordinates

Please check out the GitHub release page to find Maven & Gradle coordinates for the latest
release [1.2.3](https://github.com/skuzzle/snapshot-tests/releases/tag/v1.2.3)
release [1.3.0](https://github.com/skuzzle/snapshot-tests/releases/tag/v1.3.0)

## Quick start
_(assumes using `snapshot-tests-jackson` artifact)_
Expand Down Expand Up @@ -150,16 +150,42 @@ result for different parameters).
Check out the `SnapshotNaming` interface for more options regarding snapshot naming.

### Dealing with random values
A common source of problems are random values within the snapshot data such as dates or generated ids. This framework
comes with no means to resolve those issues. Instead you should design your code up front so that such randomness can
easily be mocked away. For example:
A common source of problems are random values within the snapshot data such as dates or generated ids. Generally, you
should design your code up front so that such randomness can easily be mocked away. For example:
* Instead of using `LocalDateTime.now()` make your code use a shared `Clock` instance that is replacible in tests and
use `LocalDateTime.now(clock)`
* More generally put: If your code uses random values in any place, consider to use a strategy interface instead which
can be replaced with a deterministic mock during testing.
* As a last resort, you can implement some normalization. Either post-process your actual test result before taking the
snapshot or implement a `SnapshotSerializer` which does the normalization. You could also implement
`StructralAssertions` in a way that it ignores such random values during comparison.
`StructralAssertions` in a way that it ignores such random values during comparison.

**New**
The latest version of this library comes with a very simple (and experimental) abstraction for customizing the
structural comparison. You can use json-path resp. xpath expressions to customize the comparison on a per-node basis.

XML example:

```java
snapshot.assertThat(someObjext)
.as(XmlSnapshot.inferJaxbContext()
.withComparisonRules(rules -> rules
.pathAt("/person/address/city/text()").ignore()
.pathAt("/person/date/text()").mustMatch(Pattern.compile("\\d{4}-\\d{2}-\\d{2}"))))
.matchesSnapshotStructure()
```

JSON example:

```java
snapshot.assertThat(someObjext)
.as(JsonSnapshot.withDefaultObjectMapper()
.withComparisonRules(rules -> rules
.pathAt("address.city").ignore()
.pathAt("date").mustMatch(Pattern.compile("\\d{4}-\\d{2}-\\d{2}"))))
.matchesSnapshotStructure();
```


### Changing the snapshot directory
By default, snapshots are stored in a directory structure according to their test-class's package name relative to
Expand Down
62 changes: 34 additions & 28 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,118 +1,124 @@
_Note:_ When running your tests with this version for the first time, you will see that your snapshot files are being
changed because we introduced a new header field. You can and safely check in these changes into your SCM.

* Fix a regression introduced with `1.2.2` where the framework ends up in unrecoverable condition after a snapshot test failed
* Remove Target `ElementType.METHOD` from `@EnableSnapshotTests`
* [#9](https://github.com/skuzzle/snapshot-tests/issues/9): Do not allow null snapshots anymore
* [#24](https://github.com/skuzzle/snapshot-tests/issues/24): Only create snapshot directory if necessary
* Simple API to specify custom rules using XPath for XML comparison
* Change: Custom json matchers are only tested against the new actual result and not against the persisted snapshot anymore
* Add convenience method `TestFile.asText()` which defaults to use UTF-8 as file encoding

### Experimental
* Fix: object traversal failed on primitive arrays
* Fix: serious bug in `ObjectMemberAction.replaceConsistently`
* Add: new simpler overload of `ObjectMemberAction.replaceConsistently`
* Add: new package for string normalization

Maven Central coordinates for this release:

## BOM Artifact
Manages the versions of all modules in case you are using multiple in your project

[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.2.3&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-bom/1.2.3/jar)
[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.3.0&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-bom/1.3.0/jar)

```xml
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-bom</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
```

```
testImplementation(platform("de.skuzzle.test:snapshot-tests-bom:1.2.3"))
testImplementation(platform("de.skuzzle.test:snapshot-tests-bom:1.3.0"))
```

## Artifacts
If you only need text based snapshots:

[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.2.3&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-core/1.2.3/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.2.3&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-core/1.2.3)
[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.3.0&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-core/1.3.0/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.3.0&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-core/1.3.0)

```xml
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-core</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
```

```
testImplementation 'de.skuzzle.test:snapshot-tests-core:1.2.3'
testImplementation("de.skuzzle.test:snapshot-tests-core:1.2.3")
testImplementation 'de.skuzzle.test:snapshot-tests-core:1.3.0'
testImplementation("de.skuzzle.test:snapshot-tests-core:1.3.0")
```

If you need json based snapshots (includes `-core`):

[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.2.3&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-jackson/1.2.3/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.2.3&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-jackson/1.2.3)
[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.3.0&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-jackson/1.3.0/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.3.0&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-jackson/1.3.0)

```xml
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-jackson</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
```

```
testImplementation 'de.skuzzle.test:snapshot-tests-jackson:1.2.3'
testImplementation("de.skuzzle.test:snapshot-tests-jackson:1.2.3")
testImplementation 'de.skuzzle.test:snapshot-tests-jackson:1.3.0'
testImplementation("de.skuzzle.test:snapshot-tests-jackson:1.3.0")
```

If you need xml based snapshots (includes `-core`):

[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.2.3&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-jaxb/1.2.3/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.2.3&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-jaxb/1.2.3)
[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.3.0&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-jaxb/1.3.0/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.3.0&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-jaxb/1.3.0)

```xml
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-jaxb</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
```

```
testImplementation 'de.skuzzle.test:snapshot-tests-jaxb:1.2.3'
testImplementation("de.skuzzle.test:snapshot-tests-jaxb:1.2.3")
testImplementation 'de.skuzzle.test:snapshot-tests-jaxb:1.3.0'
testImplementation("de.skuzzle.test:snapshot-tests-jaxb:1.3.0")
```

## Experimental
Directory Params

[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.2.3&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-directory-params/1.2.3/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.2.3&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-directory-params/1.2.3)
[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.3.0&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-directory-params/1.3.0/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.3.0&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-directory-params/1.3.0)

```xml
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-directory-params</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
```

```
testImplementation 'de.skuzzle.test:snapshot-tests-directory-params:1.2.3'
testImplementation("de.skuzzle.test:snapshot-tests-directory-params:1.2.3")
testImplementation 'de.skuzzle.test:snapshot-tests-directory-params:1.3.0'
testImplementation("de.skuzzle.test:snapshot-tests-directory-params:1.3.0")
```

Object normalization

[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.2.3&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-normalize/1.2.3/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.2.3&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-normalize/1.2.3)
[![Maven Central](https://img.shields.io/static/v1?label=MavenCentral&message=1.3.0&color=blue)](https://search.maven.org/artifact/de.skuzzle.test/snapshot-tests-normalize/1.3.0/jar) [![JavaDoc](https://img.shields.io/static/v1?label=JavaDoc&message=1.3.0&color=orange)](http://www.javadoc.io/doc/de.skuzzle.test/snapshot-tests-normalize/1.3.0)

```xml
<dependency>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-normalize</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
```

```
testImplementation 'de.skuzzle.test:snapshot-tests-normalize:1.2.3'
testImplementation("de.skuzzle.test:snapshot-tests-normalize:1.2.3")
testImplementation 'de.skuzzle.test:snapshot-tests-normalize:1.3.0'
testImplementation("de.skuzzle.test:snapshot-tests-normalize:1.3.0")
```
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-parent</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
<packaging>pom</packaging>

<name>Snapshot Tests Parent</name>
Expand Down
34 changes: 30 additions & 4 deletions readme/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,42 @@ result for different parameters).
Check out the `SnapshotNaming` interface for more options regarding snapshot naming.

### Dealing with random values
A common source of problems are random values within the snapshot data such as dates or generated ids. This framework
comes with no means to resolve those issues. Instead you should design your code up front so that such randomness can
easily be mocked away. For example:
A common source of problems are random values within the snapshot data such as dates or generated ids. Generally, you
should design your code up front so that such randomness can easily be mocked away. For example:
* Instead of using `LocalDateTime.now()` make your code use a shared `Clock` instance that is replacible in tests and
use `LocalDateTime.now(clock)`
* More generally put: If your code uses random values in any place, consider to use a strategy interface instead which
can be replaced with a deterministic mock during testing.
* As a last resort, you can implement some normalization. Either post-process your actual test result before taking the
snapshot or implement a `SnapshotSerializer` which does the normalization. You could also implement
`StructralAssertions` in a way that it ignores such random values during comparison.
`StructralAssertions` in a way that it ignores such random values during comparison.

**New**
The latest version of this library comes with a very simple (and experimental) abstraction for customizing the
structural comparison. You can use json-path resp. xpath expressions to customize the comparison on a per-node basis.

XML example:

```java
snapshot.assertThat(someObjext)
.as(XmlSnapshot.inferJaxbContext()
.withComparisonRules(rules -> rules
.pathAt("/person/address/city/text()").ignore()
.pathAt("/person/date/text()").mustMatch(Pattern.compile("\\d{4}-\\d{2}-\\d{2}"))))
.matchesSnapshotStructure()
```

JSON example:

```java
snapshot.assertThat(someObjext)
.as(JsonSnapshot.withDefaultObjectMapper()
.withComparisonRules(rules -> rules
.pathAt("address.city").ignore()
.pathAt("date").mustMatch(Pattern.compile("\\d{4}-\\d{2}-\\d{2}"))))
.matchesSnapshotStructure();
```


### Changing the snapshot directory
By default, snapshots are stored in a directory structure according to their test-class's package name relative to
Expand Down
16 changes: 11 additions & 5 deletions readme/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
_Note:_ When running your tests with this version for the first time, you will see that your snapshot files are being
changed because we introduced a new header field. You can and safely check in these changes into your SCM.

* Fix a regression introduced with `1.2.2` where the framework ends up in unrecoverable condition after a snapshot test failed
* Remove Target `ElementType.METHOD` from `@EnableSnapshotTests`
* [#9](https://github.com/skuzzle/snapshot-tests/issues/9): Do not allow null snapshots anymore
* [#24](https://github.com/skuzzle/snapshot-tests/issues/24): Only create snapshot directory if necessary
* Simple API to specify custom rules using XPath for XML comparison
* Change: Custom json matchers are only tested against the new actual result and not against the persisted snapshot anymore
* Add convenience method `TestFile.asText()` which defaults to use UTF-8 as file encoding

### Experimental
* Fix: object traversal failed on primitive arrays
* Fix: serious bug in `ObjectMemberAction.replaceConsistently`
* Add: new simpler overload of `ObjectMemberAction.replaceConsistently`
* Add: new package for string normalization

Maven Central coordinates for this release:

Expand Down
2 changes: 1 addition & 1 deletion snapshot-tests-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-parent</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
</parent>

<artifactId>snapshot-tests-bom</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion snapshot-tests-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-parent</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
</parent>

<artifactId>snapshot-tests-common</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion snapshot-tests-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>de.skuzzle.test</groupId>
<artifactId>snapshot-tests-parent</artifactId>
<version>1.2.3</version>
<version>1.3.0</version>
</parent>

<artifactId>snapshot-tests-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package de.skuzzle.test.snapshots;

import java.util.function.Predicate;
import java.util.regex.Pattern;

import org.apiguardian.api.API;
import org.apiguardian.api.API.Status;

/**
* Builder for customizing how snapshot files are compared against the actual test result.
*
* @author Simon Taddiken
* @since 1.2.0
*/
@API(status = Status.EXPERIMENTAL, since = "1.3.0")
public interface ComparisonRuleBuilder {

/**
* Specify the path for which to apply the custom comparison rule.
*
* @param path The dot separated path.
* @return A DSL Object for specifying how to compare values rooted at that path.
*/
ChooseMatcher pathAt(String path);

/**
* Allows to choose the comparison for the value.
*
* @author Simon Taddiken
*/
@API(status = Status.EXPERIMENTAL, since = "1.3.0")
public interface ChooseMatcher {

/**
* Ignores values during comparison.
*
* @return DSL object for specifying further rules.
*/
ComparisonRuleBuilder ignore();

/**
* String representation of the value must match the given regex.
*
* @param regex The regex.
* @return DSL object for specifying further rules.
*/
ComparisonRuleBuilder mustMatch(Pattern regex);

/**
* The value must match the given predicate.
* <p>
* The values which will be passed to the given predicate are highly provider
* specific. Consult the documentation of your {@link StructuredDataProvider}
* implementation.
*
* @param predicate The predicate.
* @return DSL object for specifying further rules.
*/
ComparisonRuleBuilder mustMatch(Predicate<? super Object> predicate);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
*
* <pre>
* &#64;ParameterizedTest
* &#64;Values(string = { "string1", "string2" })
* &#64;Values(strings = { "string1", "string2" })
* void testSomething(String parameter, Snapshot snapshot) throws Exception {
* Object actual = ...
*
Expand Down
Loading

0 comments on commit db5c862

Please sign in to comment.