CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-assertj--assertj-core

Fluent assertion library providing rich assertions for Java tests with expressive failure messages

Pending
Overview
Eval results
Files

conditions.mddocs/

Conditions

Custom conditions and condition combinators for reusable and composable assertions that can be applied to any object type.

Core Imports

import static org.assertj.core.api.Assertions.*;
import org.assertj.core.api.Condition;

Capabilities

Creating Custom Conditions

Define reusable conditions for complex validation logic.

// Condition interface
interface Condition<T> {
    boolean matches(T value)
    String description()
}

// Creating conditions
static <T> Condition<T> condition(Predicate<T> predicate, String description)
static <T> Condition<T> condition(Predicate<T> predicate, String description, Object... args)

// Constructor-based condition creation
class Condition<T> {
    Condition(Predicate<T> predicate, String description)
    Condition(String description, Predicate<T> predicate) // deprecated order
}

Usage examples:

// Simple custom conditions
Condition<String> notBlank = new Condition<>(
    s -> s != null && !s.trim().isEmpty(),
    "not blank"
);

Condition<Integer> positive = new Condition<>(
    n -> n > 0,
    "positive number"
);

Condition<User> adult = new Condition<>(
    user -> user.getAge() >= 18,
    "adult user"
);

// Using conditions in assertions
assertThat("Hello").is(notBlank);
assertThat(42).satisfies(positive);
assertThat(user).has(adult);

Condition Combinators

Combine multiple conditions using logical operators.

// Logical combinators
static <T> Condition<T> allOf(Condition<? super T>... conditions)
static <T> Condition<T> allOf(Iterable<? extends Condition<? super T>> conditions)
static <T> Condition<T> anyOf(Condition<? super T>... conditions)
static <T> Condition<T> anyOf(Iterable<? extends Condition<? super T>> conditions)
static <T> Condition<T> not(Condition<? super T> condition)

// Condition chaining methods
Condition<T> and(Condition<? super T> other)
Condition<T> or(Condition<? super T> other)

Usage examples:

// Define individual conditions
Condition<String> notNull = new Condition<>(Objects::nonNull, "not null");
Condition<String> notEmpty = new Condition<>(s -> !s.isEmpty(), "not empty");
Condition<String> hasLength = new Condition<>(s -> s.length() > 5, "length > 5");

// Combine conditions
Condition<String> validString = allOf(notNull, notEmpty, hasLength);
Condition<String> someValid = anyOf(notEmpty, hasLength);
Condition<String> invalid = not(validString);

// Use combined conditions
assertThat("Hello World").is(validString);
assertThat("Hi").is(someValid);
assertThat("").is(invalid);

// Chaining approach
Condition<Integer> validAge = positive.and(
    new Condition<>(age -> age <= 150, "reasonable age")
);

assertThat(25).satisfies(validAge);

Using Conditions in Assertions

Apply conditions to assertions using various methods.

// Condition assertion methods
ObjectAssert<T> is(Condition<? super T> condition)
ObjectAssert<T> isNot(Condition<? super T> condition)
ObjectAssert<T> has(Condition<? super T> condition)
ObjectAssert<T> doesNotHave(Condition<? super T> condition)
ObjectAssert<T> satisfies(Condition<? super T> condition)
ObjectAssert<T> satisfiesAnyOf(Condition<? super T>... conditions)

// Collection condition methods
IterableAssert<T> are(Condition<? super T> condition)
IterableAssert<T> areNot(Condition<? super T> condition)  
IterableAssert<T> have(Condition<? super T> condition)
IterableAssert<T> doNotHave(Condition<? super T> condition)
IterableAssert<T> areAtLeast(int times, Condition<? super T> condition)
IterableAssert<T> areAtMost(int times, Condition<? super T> condition)
IterableAssert<T> areExactly(int times, Condition<? super T> condition)
IterableAssert<T> haveAtLeast(int times, Condition<? super T> condition)
IterableAssert<T> haveAtMost(int times, Condition<? super T> condition)
IterableAssert<T> haveExactly(int times, Condition<? super T> condition)

Usage examples:

// Single object conditions
User user = new User("Alice", 30, "alice@domain.com");

assertThat(user).is(adult);
assertThat(user).has(validEmail);
assertThat(user).satisfies(allOf(adult, validEmail));

// Collection conditions
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

assertThat(numbers).are(positive);
assertThat(numbers).haveAtLeast(3, new Condition<>(n -> n > 2, "> 2"));
assertThat(numbers).areExactly(2, new Condition<>(n -> n % 2 == 0, "even"));

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Condition<String> shortName = new Condition<>(s -> s.length() <= 5, "short name");

assertThat(names).areAtMost(2, shortName);

Predefined Conditions

Common conditions provided by AssertJ.

// Predefined condition factories
static <T> Condition<T> matching(Predicate<T> predicate, String description)
static <T> Condition<T> not(Condition<? super T> condition)

// Collection-specific conditions
static <T> Condition<Iterable<? extends T>> hasSize(int expectedSize)
static <T> Condition<T[]> hasSize(int expectedSize)

Usage examples:

// Using predefined conditions
List<String> items = Arrays.asList("one", "two", "three");

assertThat(items).has(hasSize(3));
assertThat(new String[]{"a", "b"}).has(hasSize(2));

Advanced Condition Patterns

Complex condition scenarios and patterns.

// Condition composition
static <T> Condition<T> describedAs(String description, Condition<T> condition)

// Verbose conditions with detailed error messages
class VerboseCondition<T> extends Condition<T> {
    VerboseCondition(Predicate<T> predicate, String description)
}

Usage examples:

// Domain-specific conditions
Condition<Order> validOrder = new Condition<>(order -> 
    order != null && 
    order.getCustomer() != null && 
    !order.getItems().isEmpty() && 
    order.getTotal().compareTo(BigDecimal.ZERO) > 0,
    "valid order"
);

Condition<Product> inStock = new Condition<>(product ->
    product.getQuantity() > 0,
    "in stock"
);

Condition<Product> affordable = new Condition<>(product ->
    product.getPrice().compareTo(new BigDecimal("100")) <= 0,
    "affordable (≤ $100)"
);

// Complex business rules
Condition<Order> eligibleForDiscount = allOf(
    validOrder,
    new Condition<>(order -> order.getTotal().compareTo(new BigDecimal("50")) >= 0, "minimum $50"),
    new Condition<>(order -> order.getCustomer().isPremium(), "premium customer")
);

assertThat(order).satisfies(eligibleForDiscount);

// Collection with complex conditions
List<Product> products = getProducts();

assertThat(products)
    .haveAtLeast(5, inStock)
    .haveAtMost(10, affordable)
    .areNot(new Condition<>(Product::isDiscontinued, "discontinued"));

Condition Error Messages

Customizing condition error messages and descriptions.

// Custom error message formatting
Condition<T> describedAs(String description)
Condition<T> as(String description)

// Error message with parameters
static <T> Condition<T> condition(Predicate<T> predicate, String description, Object... args)

Usage examples:

// Descriptive conditions with context
Condition<String> validUsername = new Condition<>(
    username -> username.matches("[a-zA-Z0-9_]{3,20}"),
    "valid username (3-20 alphanumeric characters or underscore)"
);

Condition<Integer> inRange = new Condition<>(
    value -> value >= 1 && value <= 100,
    "in range [1, 100]"
);

// Parameterized descriptions
Condition<String> hasMinLength(int minLength) {
    return new Condition<>(
        s -> s.length() >= minLength,
        "has minimum length of %d characters",
        minLength
    );
}

// Usage with better error messages
assertThat("ab").satisfies(hasMinLength(3));
// Error: Expecting <"ab"> to satisfy: <has minimum length of 3 characters>

assertThat("user!").satisfies(validUsername);
// Error: Expecting <"user!"> to satisfy: <valid username (3-20 alphanumeric characters or underscore)>

Condition Utilities and Helpers

Utility methods for working with conditions.

// Condition testing
boolean matches(T value)
String description()

// Condition factories for common scenarios  
static <T> Condition<T> anyOf(Collection<? extends Condition<? super T>> conditions)
static <T> Condition<T> allOf(Collection<? extends Condition<? super T>> conditions)

Usage examples:

// Testing conditions directly
Condition<String> emailFormat = new Condition<>(
    email -> email.contains("@") && email.contains("."),
    "valid email format"
);

String testEmail = "user@domain.com";
boolean isValid = emailFormat.matches(testEmail);
System.out.println("Email valid: " + isValid);
System.out.println("Condition: " + emailFormat.description());

// Building condition collections
List<Condition<User>> userValidations = Arrays.asList(
    new Condition<>(u -> u.getName() != null, "has name"),
    new Condition<>(u -> u.getAge() >= 0, "non-negative age"),
    new Condition<>(u -> u.getEmail().contains("@"), "valid email")
);

Condition<User> allUserValidations = allOf(userValidations);
assertThat(user).satisfies(allUserValidations);

// Conditional validation based on type
Condition<Object> typeSpecific = new Condition<>(obj -> {
    if (obj instanceof String) {
        return !((String) obj).isEmpty();
    } else if (obj instanceof Number) {
        return ((Number) obj).doubleValue() >= 0;
    }
    return true;
}, "type-specific validation");

Types

// Core condition interface
interface Condition<T> {
    boolean matches(T value);
    String description();
    
    // Default combination methods
    default Condition<T> and(Condition<? super T> other) {
        return allOf(this, other);
    }
    
    default Condition<T> or(Condition<? super T> other) {
        return anyOf(this, other);  
    }
}

// Predicate interface for condition logic
interface Predicate<T> {
    boolean test(T t);
    
    // Default combination methods
    default Predicate<T> and(Predicate<? super T> other);
    default Predicate<T> or(Predicate<? super T> other);
    default Predicate<T> negate();
}

// Condition implementation classes
abstract class Join<T> extends Condition<T> {
    // Base class for condition combinators
}

class AllOf<T> extends Join<T> {
    // AND combination of conditions
}

class AnyOf<T> extends Join<T> {
    // OR combination of conditions  
}

class Not<T> extends Condition<T> {
    // Negation of a condition
}

class VerboseCondition<T> extends Condition<T> {
    // Condition with enhanced error reporting
}

Install with Tessl CLI

npx tessl i tessl/maven-org-assertj--assertj-core

docs

advanced.md

basic-assertions.md

collections.md

conditions.md

dates-times.md

exceptions.md

index.md

soft-assertions.md

strings.md

tile.json