google / google/truth

Consider auto-generating assertThat and subject factory for custom subjects

Open
#612 7 comments 1 reaction 0 assignees View on GitHub
P3 type=addition
Dominant language
Java
Stars
2.8k
Forks
275
Avg merge
7m
Merged PRs (30d)
4

Description

Currently a minimal Truth Subject requires four operations: a constructor, an assertion method, and two static methods for accessing the subject: `assertThat` and a subject factory (see [extension page](https://truth.dev/extension)).

Would it be possible to auto-generate these methods and, possibly, accumulate all custom `assertThat` overloads in a single place, to cut down the number or operations the developer has to add to a custom subject, and encourage creating custom `Subject`s even if a single assertion method is needed?

For instance,
```java
@AutoSubject(factoryName = "employees")
public final class EmployeeSubject extends Subject {

private final Employee actual;

// The constructor needs to be public if the class with `assertThat`
// might be outside of its package
public EmployeeSubject(FailureMetadata failureMetadata, @NullableDecl Employee subject) {
super(failureMetadata, subject);
this.actual = subject;
}

// User-defined test assertion SPI below this point

public void hasName(String name) {
check("name()").that(actual.name()).isEqualTo(name);
}
}
```

Will generate these two methods:
```java
// User-defined entry point
public static EmployeeSubject assertThat(@NullableDecl Employee employee) {
return assertAbout(EMPLOYEE_SUBJECT_FACTORY).that(employee);
}

// Static method for getting the subject factory (for use with assertAbout())
public static Subject.Factory employees() {
return EMPLOYEE_SUBJECT_FACTORY;
}

// Boiler-plate Subject.Factory for EmployeeSubject
private static final Subject.Factory EMPLOYEE_SUBJECT_FACTORY =
EmployeeSubject::new;
```

As a new user of Truth, I can't say if such implementations are common enough so that it makes sense to generate them. There are also other considerations:
1. Visibility — if there are subjects for package-private types in several packages, the Truth won't be able to produce a single file with all assertions. What shall it produce in this case — a file per subject, or per package?
2. Discoverability — if Truth produces a single file with all assertions (which might not always work ^), it is trivial to import it knowing its name. But if it generates multiple files, it might be more difficult for the end-user to discover them.

#251, which suggested generating the factory, is likely related.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.