Skip to content

Commit

Permalink
* Breaking changes:
Browse files Browse the repository at this point in the history
    1. Removed the Maven plugin and code generator.
        * The code generator was causing a "split package" issue because code was always being generated into
          the same package.
        * This caused a “split package” error since only one module is allowed to export a package.
    2. Removed the use of native binaries. Colored DIFFs are still supported, but Windows requires the use of
       Windows Terminal (free download in Windows 10, built-in feature in Windows 11).
    3. Improved performance by reducing memory usage and the frequency of GC runs.
    4. Renamed `validateThat()` to `checkIf()`.
    5. Renamed `assertThat()` to `assumeThat()`.
    6. Added support for the built-in `assert` mechanism.
        - Asserts can be used with any type of validator, but are typically used
          with `assumeThat().orElseThrow()` and `checkIf().orElseThrow()`.
    7. Use consistent parameter ordering across the entire API: `(value, name)`
        - Adding contextual information now looks like this: `requireThat().context(value, name)`
    8. Added `Validator.apply(Consumer)` to nest validations, and `Validator.and(Validator)` to combine
       validation results.
    9. Added support for primitive types to avoid boxing when possible.
    10. Dropped the `isOneOf()` and `isNotOneOf()` functionality yet again. I haven't figured out a good
        design for this yet.
    11. Added `ObjectValidator.isX()` methods to downcast to known types.
* Bugfixes:
    * `StringValidator/Verifier.asShort()`, `asInteger()` and `asLong()` were not handling the case where a
      string could not be converted to a number.
    * Validators were only returning the first failure.
  • Loading branch information
cowwoc committed Feb 12, 2024
1 parent d85f0b9 commit ce0cafe
Show file tree
Hide file tree
Showing 449 changed files with 41,338 additions and 28,617 deletions.
44 changes: 3 additions & 41 deletions LICENSE-3RD-PARTY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,68 +3,30 @@
* [jcommander](https://jcommander.org)
* [core](https://github.com/cowwoc/pouch/core/)
* [annotations](https://github.com/cowwoc/requirements.java/annotations/)
* [code_generator](https://github.com/cowwoc/requirements.java/code_generator/)
* [guava](https://github.com/cowwoc/requirements.java/guava/)
* [java](https://github.com/cowwoc/requirements.java/java/)
* [natives](https://github.com/cowwoc/requirements.java/natives/)
* [javaparser-core](https://github.com/javaparser/javaparser-core)
* [FindBugs-jsr305](http://findbugs.sourceforge.net/)
* [error-prone annotations](https://errorprone.info/error_prone_annotations)
* [Guava InternalFutureFailureAccess and InternalFutures](https://github.com/google/guava/failureaccess)
* [Guava: Google Core Libraries for Java](https://github.com/google/guava)
* [Guava ListenableFuture only](https://github.com/google/guava/listenablefuture)
* [Google Guice - Core Library](https://github.com/google/guice/guice)
* [J2ObjC Annotations](https://github.com/google/j2objc/)
* [java-diff-utils](https://github.com/java-diff-utils/java-diff-utils/java-diff-utils)
* javax.inject
* [Apache Commons Lang](http://commons.apache.org/proper/commons-lang/)
* [Commons Math](http://commons.apache.org/proper/commons-math/)
* [Maven Artifact](https://maven.apache.org/ref/3.9.0/maven-artifact/)
* [Maven Builder Support](https://maven.apache.org/ref/3.9.0/maven-builder-support/)
* [Maven Core](https://maven.apache.org/ref/3.9.0/maven-core/)
* [Maven Model](https://maven.apache.org/ref/3.9.0/maven-model/)
* [Maven Model Builder](https://maven.apache.org/ref/3.9.0/maven-model-builder/)
* [Maven Plugin API](https://maven.apache.org/ref/3.9.0/maven-plugin-api/)
* [Maven Repository Metadata Model](https://maven.apache.org/ref/3.9.0/maven-repository-metadata/)
* [Maven Artifact Resolver Provider](https://maven.apache.org/ref/3.9.0/maven-resolver-provider/)
* [Maven Settings](https://maven.apache.org/ref/3.9.0/maven-settings/)
* [Maven Settings Builder](https://maven.apache.org/ref/3.9.0/maven-settings-builder/)
* [Maven Plugin Tools Java Annotations](https://maven.apache.org/plugin-tools/maven-plugin-annotations)
* [Maven Artifact Resolver API](https://maven.apache.org/resolver/maven-resolver-api/)
* [Maven Artifact Resolver Implementation](https://maven.apache.org/resolver/maven-resolver-impl/)
* [Maven Artifact Resolver Named Locks](https://maven.apache.org/resolver/maven-resolver-named-locks/)
* [Maven Artifact Resolver SPI](https://maven.apache.org/resolver/maven-resolver-spi/)
* [Maven Artifact Resolver Utilities](https://maven.apache.org/resolver/maven-resolver-util/)
* [Apache Maven Shared Utils](https://maven.apache.org/shared/maven-shared-utils/)
* [Plexus Cipher: encryption/decryption Component](https://codehaus-plexus.github.io/plexus-cipher/)
* [Plexus Classworlds](http://codehaus-plexus.github.io/plexus-classworlds/)
* [Plexus :: Component Annotations](http://codehaus-plexus.github.io/plexus-containers/plexus-component-annotations/)
* [Plexus Interpolation API](http://codehaus-plexus.github.io/plexus-interpolation/)
* [Plexus Security Dispatcher Component](https://codehaus-plexus.github.io/plexus-sec-dispatcher/)
* [Plexus Common Utilities](http://codehaus-plexus.github.io/plexus-utils/)
* [Byte Buddy (without dependencies)](https://bytebuddy.net/byte-buddy)
* [Apache Commons Math](http://commons.apache.org/proper/commons-math/)
* [AssertJ Core](https://assertj.github.io/doc/#assertj-core)
* [testng](https://testng.org)
* [Mojo Executor](https://mojo-executor.github.io/mojo-executor/mojo-executor/)
* Common Development And Distribution License (CDDL) + GPL, version 2.0, with
classpath exception:
* [javax.annotation API](http://jcp.org/en/jsr/detail?id=250)
* Eclipse Public License (EPL), Version 1.0:
* [Logback Classic Module](http://logback.qos.ch/logback-classic)
* [Logback Core Module](http://logback.qos.ch/logback-core)
* Eclipse Public License, Version 1.0:
* [org.eclipse.sisu.inject](http://www.eclipse.org/sisu/org.eclipse.sisu.inject/)
* [org.eclipse.sisu.plexus](http://www.eclipse.org/sisu/org.eclipse.sisu.plexus/)
* GNU General Public License (GPL), version 2, with the Classpath exception:
* [JMH Core](http://openjdk.java.net/projects/code-tools/jmh/jmh-core/)
* [JMH Generators: Annotation Processors](http://openjdk.java.net/projects/code-tools/jmh/jmh-generator-annprocess/)
* GNU Lesser General Public License (LGPL):
* [Logback Classic Module](http://logback.qos.ch/logback-classic)
* [Logback Core Module](http://logback.qos.ch/logback-core)
* [javaparser-core](https://github.com/javaparser/javaparser-core)
* MIT License:
* [JOpt Simple](http://jopt-simple.github.io/jopt-simple)
* [Checker Qual](https://checkerframework.org/)
* [SLF4J API Module](http://www.slf4j.org)
* [SLF4J Simple Binding](http://www.slf4j.org)
* [jquery](http://webjars.org)
* Public Domain:
* [AOP alliance](http://aopalliance.sourceforge.net)
164 changes: 90 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.cowwoc.requirements/java/badge.svg)](https://search.maven.org/search?q=g:com.github.cowwoc.requirements)
[![build-status](../../workflows/Build/badge.svg)](../../actions?query=workflow%3ABuild)

# <img src="wiki/checklist.svg" width=64 height=64 alt="checklist"> Fluent API for Design Contracts
# <img src="docs/checklist.svg" width=64 height=64 alt="checklist"> Fluent API for Design Contracts

[![API](https://img.shields.io/badge/api_docs-5B45D5.svg)](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/)
[![Changelog](https://img.shields.io/badge/changelog-A345D5.svg)](wiki/Changelog.md)
[![API](https://img.shields.io/badge/api_docs-5B45D5.svg)](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/)
[![Changelog](https://img.shields.io/badge/changelog-A345D5.svg)](docs/Changelog.md)
[![js](https://img.shields.io/badge/other%20languages-js-457FD5.svg)](../../../requirements.js)

A [fluent API](https://en.m.wikipedia.org/wiki/Fluent_interface) for enforcing
[design contracts](https://en.wikipedia.org/wiki/Design_by_contract) with
A [fluent API](https://en.m.wikipedia.org/docs/Fluent_interface) for enforcing
[design contracts](https://en.wikipedia.org/docs/Design_by_contract) with
[automatic message generation](wiki/Features.md#automatic-message-generation):

✔️ Easy to use
Expand All @@ -19,109 +19,125 @@ To get started, add this Maven dependency:

```xml
<dependency>
<groupId>com.github.cowwoc.requirements</groupId>
<artifactId>java</artifactId>
<version>8.0.10</version>
<groupId>com.github.cowwoc.requirements</groupId>
<artifactId>java</artifactId>
<version>9.0.0</version>
</dependency>
```

and this Maven plugin:
You can learn about the API by using your IDE's auto-complete feature.
The main entry points are:

```xml
<plugin>
<groupId>com.github.cowwoc.requirements</groupId>
<artifactId>maven_plugin</artifactId>
<version>8.0.10</version>
<executions>
<execution>
<goals>
<!-- Generate API classes -->
<goal>generate-api</goal>
<!-- Optional: enable colored diffs -->
<goal>unpack</goal>
</goals>
</execution>
</executions>
</plugin>
```
* [requireThat(value, name)](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultJavaValidators.html#requireThat(T,java.lang.String))
* [assumeThat(value, name)](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultJavaValidators.html#assumeThat(T,java.lang.String))
* [checkIfThat(value, name)](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultJavaValidators.html#checkIf(T,java.lang.String))
* [JavaValidators](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/JavaValidators.html)

The contents of the API classes depend on which [modules](wiki/Supported_Libraries.md) are enabled.
The first three methods use a global configuration, while `JavaValidators` allows you to create a local configuration.

## Sample Code
See the [API documentation](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/) for more details.

## Usage Example

```java
import static com.github.cowwoc.requirements.DefaultRequirements.requireThat;
import static com.github.cowwoc.requirements.java.DefaultJavaValidators.assumeThat;
import static com.github.cowwoc.requirements.java.DefaultJavaValidators.checkIf;
import static com.github.cowwoc.requirements.java.DefaultJavaValidators.requireThat;

public final class Credentials
public final class HelloWorldTest
{
public Credentials(String username, String password)
{
this.username = requireThat(username, "username").isTrimmed().isNotEmpty().getActual();
this.password = requireThat(password, "password").isTrimmed().length().isBetween(18, 30).getActual();
}
public static void main(String[] args)
{
// Preconditions
requireThat(args, "args").length().isPositive();

// Class invariants or method postconditions
assert assumeThat("args[0]", args[0]).isEqualTo("world").elseThrow();

// Return multiple validation failures at once
List<String> messages = checkIf(args, "args").isEmpty().
and(checkIf("args[0]", args[0]).isEqualTo("planet")).
elseGetMessages();
StringJoiner joiner = new StringJoiner("\n\n");
for (String message : messages)
joiner.add(message);
System.out.println("Multiple failures\n" + joiner.toString());
}
}
```

Failures would trigger the following kind of exceptions:
Failure messages look like this:

```java
java.lang.NullPointerException: username may not be null
```
java.lang.NullPointerException: args may not be null
java.lang.IllegalArgumentException: args.length() must be positive
args.length(): 0
java.lang.IllegalArgumentException: password may not contain leading or trailing whitespace.
Actual: " Dumbl4dor4 "
java.lang.AssertionError: args[0] must be equal to "world"
args[0]: "planet"
java.lang.IllegalArgumentException: password must contain [18, 30) characters.
Actual: 15
Multiple failures
-----------------
args must be empty.
args : ["world"]
args.length: 1
args[0] must be equal to "planet".
args[0]: "world"
```

## Features

* [Automatic message generation](wiki/Features.md#automatic-message-generation)
* [Diffs provided whenever possible](wiki/Features.md#diffs-provided-whenever-possible)
* [Clean stack-traces](wiki/Features.md#clean-stack-traces)
* [Assertion support](wiki/Features.md#assertion-support)
* [Multiple validation errors](wiki/Features.md#multiple-validation-errors)
* [Grouping nested requirements](wiki/Features.md#grouping-nested-requirements)
* [String diff](wiki/Features.md#string-diff)
* [Fast... very fast!](wiki/Performance.md)
This library offers the following features:

* [Automatic message generation](docs/Features.md#automatic-message-generation) for validation failures
* [Diffs provided whenever possible](docs/Features.md#diffs-provided-whenever-possible) to highlight the differences between expected and actual values
* [Clean stack-traces](docs/Features.md#clean-stack-traces) that remove unnecessary frames
* [Zero overhead when assertions are disabled](docs/Features.md#assertion-support) for better performance
* [Multiple validation failures](docs/Features.md#multiple-validation-failures) that report all the errors at once
* [Nested validations](docs/Features.md#nested-validations) that allow you to validate complex objects
* [String diff](docs/Features.md#string-diff) that shows the differences between two strings
* [Fast... very fast!](docs/Performance.md) compared to other validation libraries

## Getting Started

The best way to learn about the API is using your IDE's auto-complete engine.
There are seven entry points you can navigate from:
The main entry points you should be aware of are:

The API has 7 entry points:
* [requireThat(value, name)](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultJavaValidators.html#requireThat(T,java.lang.String))
* [assumeThat(value, name)](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultJavaValidators.html#assumeThat(T,java.lang.String))
* [checkIfThat(value, name)](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultJavaValidators.html#checkIf(T,java.lang.String))
* [JavaValidators](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/JavaValidators.html)

* [requireThat(value, name)](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultRequirements.html#requireThat(T,java.lang.String))
* [validateThat(value, name)](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultRequirements.html#validateThat(T,java.lang.String))
* [assertThat(Consumer)](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultRequirements.html#assertThat(java.util.function.Consumer))
* [assertThatAndReturn(Function)](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/DefaultRequirements.html#assertThatAndReturn(java.util.function.Function))
* [Requirements](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/com.github.cowwoc.requirements/com/github/cowwoc/requirements/Requirements.html)
* [GlobalRequirements](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/com.github.cowwoc.requirements.java/com/github/cowwoc/requirements/java/GlobalRequirements.html)
* [ThreadRequirements](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/com.github.cowwoc.requirements.java/com/github/cowwoc/requirements/java/ThreadRequirements.html)
The three static methods share a global configuration.
`JavaValidators` contains a local configuration, which is useful if you want to use different configuration at
once.

The first four methods are designed to be statically imported from `DefaultRequirements`.
See the [API documentation](https://cowwoc.github.io/requirements.java/9.0.0/docs/api/) for more details.

See the [API documentation](https://cowwoc.github.io/requirements.java/8.0.10/docs/api/) for more details.
## Performance Tips

## Best practices

* Use `requireThat()` to verify pre-conditions of public APIs.
* Use `assertThat()` to verify object invariants and method post-conditions.
This results in excellent performance when assertions are disabled.
Have your cake and eat it too!
* Prefer `assertThat()` to `assert`. It has a slightly higher overhead, but most applications fail to catch or
log `AssertionError` that is thrown by `assert`, leading to silent failures.
* Use `requireThat()` to verify the preconditions of public APIs.
* Use `assert assumeThat()` to verify class invariants, method post-conditions, and the preconditions of
private methods.
The JVM will remove these checks if assertions are disabled.
* Use `checkIf()` to return multiple failures at once.
* Use `checkIf().elseGetMessages()` to return failures without throwing an exception.
This is the best-performing approach, ideal for web services.
* You can omit parameter names, but it is better to include them for clarity of failure messages.

## 3rd-party libraries and tools
## Third-party libraries and tools

Enhanced support is available for the following 3rd-party libraries and tools:
This library supports the following 3rd-party libraries and tools:

* [guava](wiki/Supported_Libraries.md)
* [IntelliJ IDEA](wiki/Supported_Tools.md)
* [guava](docs/Supported_Libraries.md)
* [IntelliJ IDEA](docs/Supported_Tools.md)

## Licenses

* Code licensed under the [Apache License, Version 2.0](LICENSE)
* [Third party licenses](LICENSE-3RD-PARTY.md)
* Icons made by Flat Icons from www.flaticon.com is licensed by CC 3.0 BY
* This library is licensed under the [Apache License, Version 2.0](LICENSE)
* See [Third party licenses](LICENSE-3RD-PARTY.md) for the licenses of the dependencies
* Icons made by Flat Icons from www.flaticon.com are licensed by CC 3.0 BY
7 changes: 4 additions & 3 deletions annotations/pom.xml → annotation/pom.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.cowwoc.requirements</groupId>
<artifactId>root</artifactId>
<version>8.0.11-SNAPSHOT</version>
<version>9.0.0-SNAPSHOT</version>
</parent>
<artifactId>annotations</artifactId>
<artifactId>annotation</artifactId>
<packaging>jar</packaging>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
* Copyright 2019 Gili Tzabari.
* Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
*/
/**
* Annotations used by the library.
*/
module com.github.cowwoc.requirements.annotation
{
exports com.github.cowwoc.requirements.annotation;
/*
* Copyright 2019 Gili Tzabari.
* Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
*/
/**
* Annotations used by the library.
*/
module com.github.cowwoc.requirements.annotation
{
exports com.github.cowwoc.requirements.annotation;
}
20 changes: 20 additions & 0 deletions benchmark/assertj/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.cowwoc.requirements</groupId>
<artifactId>benchmark</artifactId>
<version>9.0.0-SNAPSHOT</version>
</parent>
<artifactId>benchmark.assertj</artifactId>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.25.3</version>
</dependency>
</dependencies>
</project>
Loading

0 comments on commit ce0cafe

Please sign in to comment.